mnistから画像をダウンロードして学習データとして使用し、数値の画像を作成するGANのプログラムについての質問です。
コードはGoogle Colaboratory上で実行しており、Google Colaboratory上の環境は以下です。
・CUDA:Ver10.1.243
・cudnn:7.6.5
・tensorflow-2.2.0rc3
・Keras:2.3.1
・ハードウェアアクセラレータ:GPU
実行したコードは以下です。
### -*-coding:utf-8-*-
from __future__ import print_function, division
from keras.datasets import mnist
from keras.layers import Input, Dense, Reshape, Flatten, Dropout
from keras.layers import BatchNormalization, Activation, ZeroPadding2D
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.convolutional import UpSampling2D, Conv2D
from keras.models import Sequential, Model
from keras.optimizers import Adam
import matplotlib.pyplot as plt
import sys
import numpy as np
# GANで使う処理をまとめたデータクラス
class GAN():
# コンストラクタ
def __init__(self):
#mnistデータ用の入力データサイズ
self.img_rows = 28
self.img_cols = 28
self.channels = 1
self.img_shape = (self.img_rows, self.img_cols, self.channels)
# 潜在変数の次元数
self.z_dim = 100
optimizer = Adam(0.0002, 0.5)
# discriminatorモデル
self.discriminator = self.build_discriminator()
self.discriminator.compile(loss='binary_crossentropy',
optimizer=optimizer,
metrics=['accuracy'])
# Generatorモデル
self.generator = self.build_generator()
self.combined = self.build_combined1()
self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)
def build_generator(self):
noise_shape = (self.z_dim,)
model = Sequential()
model.add(Dense(256, input_shape=noise_shape))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(1024))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
# Discriminatorへの入力になるため、Discriminatorの入力に次元数を合わせる
model.add(Dense(np.prod(self.img_shape), activation='tanh'))
model.add(Reshape(self.img_shape))
model.summary()
return model
def build_discriminator(self):
img_shape = (self.img_rows, self.img_cols, self.channels)
model = Sequential()
model.add(Flatten(input_shape=img_shape))
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(256))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(1, activation='sigmoid'))
model.summary()
return model
def build_combined1(self):
self.discriminator.trainable = False
model = Sequential([self.generator, self.discriminator])
return model
def train(self, epochs, batch_size=128, save_interval=50):
# nb_samples, 28, 28)の白黒画像
# nb_samples:trainなら60000画像
(X_train, _), (_, _) = mnist.load_data()
# normalize
X_train = (X_train.astype(np.float32) - 127.5) / 127.5
X_train = np.expand_dims(X_train, axis=3)
half_batch = int(batch_size / 2)
# 画像枚数 / バッチサイズ で、バッチ数を取得
num_batches = int(X_train.shape[0] / half_batch)
print('Number of batches:', num_batches)
for epoch in range(epochs):
for iteration in range(num_batches):
# ---------------------
# Discriminator learning
# ---------------------
# pickup images (half-batch size) from generator
noise = np.random.normal(0, 1, (half_batch, self.z_dim))
gen_imgs = self.generator.predict(noise)
# pickup images (half-batch size) from dataset
# 学習用データから、0~60000の乱数を、half_batch数分取得
idx = np.random.randint(0, X_train.shape[0], half_batch)
# バッチ数分の画像データを取得
imgs = X_train[idx]
# learn discriminator
# learning discriminator with real-data and fake-data seperately
# リアルデータなら1
# Generatorからのデータなら0
d_loss_real = self.discriminator.train_on_batch(imgs, np.ones((half_batch, 1)))
d_loss_fake = self.discriminator.train_on_batch(gen_imgs, np.zeros((half_batch, 1)))
# average each loss
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# ---------------------
# Generator learning
# ---------------------
noise = np.random.normal(0, 1, (batch_size, self.z_dim))
# make label (gen data: 1)
valid_y = np.array([1] * batch_size)
# Train the generator
g_loss = self.combined.train_on_batch(noise, valid_y)
# progress
print ("epoch:%d, iter:%d, [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, iteration, d_loss[0], 100*d_loss[1], g_loss))
# save images
if epoch % save_interval == 0:
self.save_imgs(epoch)
def save_imgs(self, epoch):
# row,col
r, c = 5, 5
noise = np.random.normal(0, 1, (r * c, self.z_dim))
gen_imgs = self.generator.predict(noise)
# rescale [-1, 1] to [0, 1]
gen_imgs = 0.5 * gen_imgs + 0.5
fig, axs = plt.subplots(r, c)
cnt = 0
# 1画像ずつ、subplot用の枠に入れていく
for i in range(r):
for j in range(c):
axs[i,j].imshow(gen_imgs[cnt, :,:,0], cmap='gray')
axs[i,j].axis('off')
cnt += 1
fig.savefig("images/mnist_%d.png" % epoch)
plt.close()
if __name__ == '__main__':
gan = GAN()
gan.train(epochs=30000, batch_size=32, save_interval=1)
上記のコードを実行すると、d_loss_real = self.discriminator.train_on_batch(imgs, np.ones((half_batch, 1)))の
当たりで、下記のエラーが発生します。
FailedPreconditionError: Error while reading resource variable _AnonymousVar37 from Container: localhost. This could mean that the variable was uninitialized. Not found: Resource localhost/_AnonymousVar37/N10tensorflow3VarE does not exist.
[[node mul_21/ReadVariableOp (defined at /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3009) ]] [Op:__inference_keras_scratch_graph_1851]
上記コードは、Kerasのバージョンが2.1.3、Tensorflowがtensorflow-gpu 1.14.0のときはエラーなく動いていたのですが、
バージョン変更するとエラーが発生して途中で止まってしまいます。※1
エラーの原因、改善方法等分かる方がおられましたら宜しくお願い致します。
※前回質問時からの変更点。
・調査して分かったことがあったため、タイトルを「Google Colaboratory上でGANを実行するとFailedPreconditionErrorが発生する」から
「KerasとTensorflowのバージョンを変更するとエラーが発生する」に変更しました。
・KerasとTensorflowのバージョンによってエラー発生有無が変わることが分かったため、※1部分の説明を修正しました。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
check解決した方法
0
Google Colaboratory上でGPUを動かしたかったので最新のTensorflowとKerasで動く方法を知りたかったのですが、Tensorflow-gpu 1.15.0、Keras 2.1.3にすることで、動かすことができたので解決済と致します。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.19%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる