前提・実現したいこと
初めて質問させていただきます。拙いところがあるかもしれませんがご理解ください。
私は、DCGANでMNIST手書き数字のようなものを生成しようとしています。
発生している問題・エラーメッセージ
以前は成功していたのですが、どこかのコードを弄ってしまったのか現在はうまく生成できなくなってしまいました...
具体的には下のような生成結果になります。
ミニバッチ数256で5000イテレーションほど学習した結果です。
橙: Discriminator 青: Generatorです。
以前は2000~2750イテレーションほどでこれくらいのresultを出していました。
ソースコード
Generator
python
1class Generator(tf.keras.Model): 2 def __init__(self, input_shape): 3 super().__init__() 4 5 parm = int(input_shape[1] / 4) 6 7 noise_shape = (100,) 8 9 self.dens1 = kl.Dense(parm*parm*128, input_shape=noise_shape) 10 self.bn1 = kl.BatchNormalization() 11 self.act1 = kl.Activation(tf.nn.tanh) 12 13 self.re = kl.Reshape((parm,parm,128), input_shape=(128*parm*parm,)) 14 self.ups1 = kl.UpSampling2D((2,2)) 15 16 self.conv1 = kl.Conv2D(64, 5, padding="same", activation="tanh") 17 self.ups2 = kl.UpSampling2D((2,2)) 18 self.conv2 = kl.Conv2D(1, 5, padding="same", activation="tanh") 19 20 def call(self, x): 21 22 d1 = self.act1(self.bn1(self.dens1(x))) 23 d2 = self.ups1(self.re(d1)) 24 d3 = self.ups2(self.conv1(d2)) 25 d4 = self.conv2(d3) 26 27 return d4
Discriminator
python
1class Discriminator(tf.keras.Model): 2 def __init__(self, input_shape): 3 super().__init__() 4 5 input_shape = input_shape[1:4] 6 7 self.conv1 = kl.Conv2D(64, 5, strides=2, padding="same", activation="tanh", input_shape=input_shape) 8 9 self.conv2 = kl.Conv2D(128, 5, strides=2, padding="same", activation="tanh") 10 11 self.flt = kl.Flatten() 12 13 self.dens1 = kl.Dense(1024, activation="tanh") 14 self.dens2 = kl.Dense(1, activation="sigmoid") 15 16 def call(self, x): 17 18 d1 = self.conv1(x) 19 d2 = self.conv2(d1) 20 d3 = self.dens1(self.flt(d2)) 21 d4 = self.dens2(d3) 22 23 return d4
最適化アルゴリズムはAdamで、損失関数はBinaryCrossentropyです。
Train(主な部分のみ)
python
1 h_batch = int(batch_size / 2) 2 real_y = np.ones((h_batch, 1)) # Discriminatorラベル(本物データ) 3 fake_y = np.zeros((h_batch, 1)) # Discriminatorラベル(偽物データ) 4 valid_y = np.array([1] * batch_size) # Generatorラベル 5 6 # 学習 7 for ite in range(iteration): 8 9 # 生成画像取得 10 noise = np.random.normal(0, 1, (h_batch, 100)) # 入力データ作成 11 gen_imgs = self.generator.predict(noise) 12 13 # 学習データピックアップ 14 idx = np.random.randint(0, tr_images.shape[0], h_batch) 15 imgs = tr_images[idx] 16 17 # Discriminator 学習 18 self.discriminator.trainable = True # Discriminator学習有効 19 d_loss_real = self.discriminator.train_on_batch(imgs, real_y) # 本物データに対する学習 20 d_loss_fake = self.discriminator.train_on_batch(gen_imgs, fake_y) # 偽物データに対する学習 21 d_loss = 0.5 * np.add(d_loss_real, d_loss_fake) # 平均損失値 22 23 noise = np.random.normal(0, 1, (batch_size, 100)) # 入力データ作成 24 25 # Generator 学習 26 self.model.discriminator.trainable = False # Discriminator学習無効 27 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処理で行っています。
あなたの回答
tips
プレビュー