LoginSignup
37
28

More than 5 years have passed since last update.

ディープ・ラーニングで新元号予想してみた: GengoAN — 元号のGAN —

Last updated at Posted at 2019-03-31

UNADJUSTEDNONRAW_thumb_2a5a2.jpg

ついに今日の午前11時半に新元号が発表されますね。

とりあえず PyTorch によるディープ・ラーニング (深層学習) で元号の予想を作ってみました。今までされていない予想方法がないかなと思って、 視覚的・見た目 を予想することにしました。既にされている人がいたらすみません。

方法

機械学習の、深層学習、ディープ・ラーニングの方法の一つ、敵対的生成ネットワーク (GAN) の DCGAN を用いて、元号を 見た目 視点で予想することにします。 字面 (じづら) というやつです。

テキスト情報・文字情報ではなく、元号の画像を用意して、GANで、それっぽいものをたくさん生成してみるというものです。

コードは aidiary (@sylvan5) さんの記事 PyTorch (12) Generative Adversarial Networks (MNIST) - 人工知能に関する断創録 をほとんど写しました。ありがとうございました。主に変更した部分を下で解説しました。

入力「元号」画像生成

sources.png

TeX を用いました。

  1. rubyでTeXファイルを生成して
  2. TeXからPDF (dvipdfmx)
  3. PDFからPNG (ImageMagick)

の手順で作りました。rubyからTeXファイルを作るコードは

にあります。

  • 元号は少ないので、画像を回転をランダムに100回かけて増やしました。
    • TeXで \rotatebox{度数法の角度}{文字列} とすれば回転できます。
  • 4文字の元号は省きました。たぶん次も2文字になるでしょうから。(244個)
  • 24644 枚のPNGファイルを作成しました。

PyTorch によるディープ・ラーニングのコード

コードは aidiary (@sylvan5) さんの記事 PyTorch (12) Generative Adversarial Networks (MNIST) - 人工知能に関する断創録 をほとんど写したのですが、これは MNIST という28×28の画像の集合のためのものなので、サイズを合わせる必要があります。

線形なネットワークの後に、"たたみ込み" 層が2段になっていて、ここで ConvTranspose2d (PyTorch のドキュメントへのリンク) により、どかんどかんとサイズが大きくなっていきます。ConvTranspose2d クラスは中では F.conv_transpose2d 関数が使われています。

transposed convolution と言ったり、deconvolution と言ったりします。いわゆる「たたみ込み」の逆のことをするのです。たたみ込みは小さくなりますが、transposed convolution はその反対なので、小さいサイズから大きなサイズが出てきますね。使われるカーネルやストライドやパディングは、全く同じ概念です。それを逆に (行列の言葉で言えば「転置」にして) 使うだけです。

  • カーネルのサイズ ($k$とおきます)
  • ストライド(ずらしていく幅) ($s$とおきます)
  • パディング ($p$とおきます)

によって、この層を通った後の各ユニットのサイズが決まります。
今は kernel サイズ$k$は4、ストライド$s$は2、パディング$p$は1にしているので、最初の入力サイズを 8×8 (縦横8ピクセルずつ) にします。横のサイズを $w$, 縦のサイズを $w$ とおくことにします。

そうすると、まず

\begin{align}
  & (w - 1)\times s - 2 \times p + k \\
= & (8-1)\times 2 - 2 \times 1 + 4 \\
= & 16
\end{align}

となり1辺が16ピクセルの出力が出てきて、次に

$$ (16-1)\times 2 - 2 \times 1 + 4 = 32$$

となるので、最後に 32×32の画像ができあがるというわけです。

class Generator(nn.Module):

    def __init__(self):
        super(Generator, self).__init__()

        self.fc = nn.Sequential(
            nn.Linear(62, 1024),
            nn.BatchNorm1d(1024),
            nn.ReLU(),
            nn.Linear(1024, 128 * 8 * 8),
            nn.BatchNorm1d(128 * 8 * 8),
            nn.ReLU(),
        )

        self.deconv = nn.Sequential(
            nn.ConvTranspose2d(128, 64, kernel_size=4, stride=2, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.ConvTranspose2d(64, 1, kernel_size=4, stride=2, padding=1),
            nn.Sigmoid(),
        )

        initialize_weights(self)

    def forward(self, input):
        x = self.fc(input)
        x = x.view(-1, 128, 8, 8)
        x = self.deconv(x)
        return x

この変更を discriminator にも行います。

また、64×64版も同様に、サイズに合わせたネットワークの変更を行います。

結果: 32×32

はじめは、縦横32ピクセルずつの画像でやりました。

コードはGoogle Colaboratory のノートをご覧ください。

32-epoch.png
32-epoch2.png

epoch 51 ぐらいまでくると結構見えてきますね! でもちょっと見えにくいので解像度を上げてみました。

結果: 64×64

見えにくいのでもうちょっと時間をかけて、縦横64ピクセルの画像を作りました。

これもGoogle Colaboratory のノート を置いております。

epoch 1

epoch_001.png

epoch 16

epoch_016.png

epoch 26

epoch_026.png

epoch 41

epoch_041.png

epoch 51

epoch_051.png

まとめ

ここから皆様の心の目で、新元号の字面を見いだして下さい。

妻と心の目で見たところ、

底、風、民、顧、天、筆、鳳、亀、実

のような感じの漢字が見えました。

  • 天筆 (てんぴつ)
  • 鳳民 (ほうみん)
  • 風鳳 (ふうほう)
  • 天亀 (てんがめ) (店があるww)
  • 実底 (じってい)

とかどうですか?!

では。Happy deep learning.

追記

当然ながら、外れましたね。
「和」はこれまで19回も出てきたので見えないこともありませんが、「令」は初登場ですので、この生成画像からは見えてきません。(むしろこのネットワークではそれが正常)

37
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
28