質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.21%

[DCGAN]求めているResultにならない

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 495

himazin331

score 0

前提・実現したいこと

初めて質問させていただきます。拙いところがあるかもしれませんがご理解ください。

私は、DCGANでMNIST手書き数字のようなものを生成しようとしています。

発生している問題・エラーメッセージ

以前は成功していたのですが、どこかのコードを弄ってしまったのか現在はうまく生成できなくなってしまいました...
具体的には下のような生成結果になります。
ミニバッチ数2565000イテレーションほど学習した結果です。
result
loss graph
橙: Discriminator 青: Generatorです。

2000~2750イテレーションでの結果はこんな感じです。
2000~2750iter時点のresult(現在)

以前は2000~2750イテレーションほどでこれくらいのresultを出していました。
2000~2750iter時点のresult(以前)

ソースコード

Generator
class Generator(tf.keras.Model):
    def __init__(self, input_shape):
        super().__init__()

        parm = int(input_shape[1] / 4)

        noise_shape = (100,)

        self.dens1 = kl.Dense(parm*parm*128, input_shape=noise_shape)
        self.bn1 = kl.BatchNormalization()
        self.act1 = kl.Activation(tf.nn.tanh)

        self.re = kl.Reshape((parm,parm,128), input_shape=(128*parm*parm,))
        self.ups1 = kl.UpSampling2D((2,2))

        self.conv1 = kl.Conv2D(64, 5, padding="same", activation="tanh")
        self.ups2 = kl.UpSampling2D((2,2))
        self.conv2 = kl.Conv2D(1, 5, padding="same", activation="tanh")

    def call(self, x):

        d1 = self.act1(self.bn1(self.dens1(x)))
        d2 = self.ups1(self.re(d1))
        d3 = self.ups2(self.conv1(d2))
        d4 = self.conv2(d3)

        return d4
Discriminator
class Discriminator(tf.keras.Model):
    def __init__(self, input_shape):
        super().__init__()

        input_shape = input_shape[1:4]

        self.conv1 = kl.Conv2D(64, 5, strides=2, padding="same", activation="tanh", input_shape=input_shape)

        self.conv2 = kl.Conv2D(128, 5, strides=2, padding="same", activation="tanh")

        self.flt = kl.Flatten()

        self.dens1 = kl.Dense(1024, activation="tanh")
        self.dens2 = kl.Dense(1, activation="sigmoid")

    def call(self, x):    

        d1 = self.conv1(x)
        d2 = self.conv2(d1)
        d3 = self.dens1(self.flt(d2))
        d4 = self.dens2(d3)

        return d4

最適化アルゴリズムはAdamで、損失関数はBinaryCrossentropyです。

Train(主な部分のみ)
        h_batch = int(batch_size / 2)
        real_y = np.ones((h_batch, 1)) # Discriminatorラベル(本物データ)
        fake_y = np.zeros((h_batch, 1)) # Discriminatorラベル(偽物データ)
        valid_y = np.array([1] * batch_size) # Generatorラベル

        # 学習
        for ite in range(iteration):

            # 生成画像取得
            noise = np.random.normal(0, 1, (h_batch, 100)) # 入力データ作成
            gen_imgs = self.generator.predict(noise)

            # 学習データピックアップ
            idx = np.random.randint(0, tr_images.shape[0], h_batch)
            imgs = tr_images[idx]

            # Discriminator 学習
            self.discriminator.trainable = True # Discriminator学習有効
            d_loss_real = self.discriminator.train_on_batch(imgs, real_y)   # 本物データに対する学習
            d_loss_fake = self.discriminator.train_on_batch(gen_imgs, fake_y) # 偽物データに対する学習
            d_loss = 0.5 * np.add(d_loss_real, d_loss_fake) # 平均損失値

            noise = np.random.normal(0, 1, (batch_size, 100)) # 入力データ作成

            # Generator 学習
            self.model.discriminator.trainable = False # Discriminator学習無効
            g_loss = self.model.train_on_batch(noise, valid_y)

詳細はGitHubリポジトリを見てもらえればと思います...

この実装でおかしいところがあれば教えていただきたいです。

試したこと

DiscriminatorやGeneratorの活性化関数をLeakyReLUにした
DiscriminatorやGeneratorの活性化関数をReLUにした
DiscriminatorのConvolutionを増やした
DiscriminatorのDenseを増やした
DiscriminatorのConvolutionやDenseのハイパーパラメータを弄った
GeneratorのConvolutionを増やした
GeneratorのDenseを増やした
GeneratorのConvolutionのハイパーパラメータを弄った

これらをやってみましたが、変わらないどころか悪化しました。

補足情報(FW/ツールのバージョンなど)

Tensorflow 2.2.0
numpy 1.18.1

CPU: i9 9900K
GPU: RTX2080ti
RAM: 8GB x 2

学習はGPU処理で行っています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る