13. 13
モデルを保存するには
1. tf.train.Saverオブジェクトを生成
2. 保存したいステップの時にsave
2017/6/29
Singularity Copyright 2016 Singularity Inc. All rights reserved
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(init)
for i in range(1000):
#step数とイテレーション数を合わせる
step = i + 1
(訓練・割愛)
if step % 100 == 0:
saver.save(sess, ‘models/my_model’, global_step = step)
models直下にmy_modelという名前で 名前の後に何step目のモデルかを付与
95. 95
誤差、訓練
2017/6/29
Singularity Copyright 2016 Singularity Inc. All rights reserved
#誤差
with tf.variable_scope('loss'):
loss = tf.reduce_mean(tf.squared_difference(q_target, q_val))
with tf.variable_scope('train'):
global_step = tf.Variable(0, trainable=False, name="global_step")
#訓練するのはqネットワークだけ
opt =tf.train. RMSPropOptimizer(FLAGS.learning_rate)
train_step=opt.minimize(loss, var_list=q_vars, global_step=global_step)
minimizeメソッドは引数var_listを指定することでその重みだけを学習してくれる
論文の通りRMSProp
96. 96
targetのアップデート
2017/6/29
Singularity Copyright 2016 Singularity Inc. All rights reserved
with tf.variable_scope('update'):
#targetネットワークをアップデート
update_op = [target_vars[i].assign(q_vars[i]) for i in range(len(q_vars))]
forループで回して全ての重みをアサインする
97. 97
シミュレーション初期化
2017/6/29
Singularity Copyright 2016 Singularity Inc. All rights reserved
iteration = 0
for _ in range(FLAGS.num_episode):
#初期状態の環境を取得
obs = env.reset()
last_obs = obs
#最初の何ステップかは何もしない(初期状態をランダムにするため)
for _ in range(random.randint(0, NO_ACTION_STEP)):
last_obs = obs
obs, _, _, _ = env.step(0)
env.reset()で初期化、env.stepで実行
env.stepの返り値は、次の状態(画面)、得られた報酬、終了したかどうか、メタ情報
119. 119
敵対的生成ネットワーク(GAN)
GANの利点・欠点
• 利点
• 欠点
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
• GANでは、識別モデルと生成モデルとして具体的なネットワークに限定していないため、様々
なモデルを組み合わせることができる。
• 学習データと直接比較するのではなく、識別モデルの評価を介して生成するため、学習データ
を生成モデルがそのまま丸覚えすることを避けられる。
• 明示的な𝑃𝑔(生成モデルからの出力分布)が最初は存在しないため、識別モデルは生成モデ
ルとシンクロさせて訓練する必要がある。
⇒識別モデルを更新せずに生成モデルだけを訓練すると、
生成モデルが入力ノイズzの多くを学習データxと同じ値に収束させてしまうなど、
同期タイミングが難しい
120. 120
Deep Convolutional GANとは
敵対的生成ネットワーク(GAN)を踏まえたうえで、
Deep Convolutional GANとは何?
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
121. 121
Deep Convolutional GANとは
DCGAN(Deep Convolutional Generative Adversarial Nets)は、GAN
に対して畳み込みニューラルネットワークを適用して、うまく学習が成立
するよう提案されたベストプラクティス。
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
z 生成データ
G(z)=x
学習データ
セット
学習データ
x
入力データxが学習
データである確率
※zはn次元の一様分布に従うランダム変数
Dは学習データである確率を最大化するように学習する。
Generator(生成モデル)とDiscriminator(識別モデル)に、
畳み込みニューラルネットワーク(CNN)を適用。
⇒CNNは画像関連を中心に大きな成功を収めているモデ
ルであり、画像を生成するのであればGANにも適用すれ
ばうまくいくはず!
122. 122
Deep Convolutional GANとは
DCGANのアーキテクチャ
① プーリング層はやめる
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
fractionally-strided convolution(分数的にスト
ライドする畳み込み)を使いアップサンプリングする
⇒transposed convolution,deconvolutionと呼ば
れることもある
一般的なCNNだが、プーリング層はおかない
ダウンサンプリングは、ストライド2の畳み込みで行
う
123. 123
Deep Convolutional GANとは
DCGANのアーキテクチャ
fractionally-strided convolution
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
元の特徴マップ(3×3)
アップサンプリング後の
画像・特徴マップ(5×5)
元となる特徴マップをパディングして拡大してから、カーネル(フィルタ)を適用。
124. 124
Deep Convolutional GANとは
DCGANのアーキテクチャ
② 全結合層は取り除き、global average poolingに置き換える
discriminatorから全結合層を除去
代わりにglobal average poolingにする
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
一つの特徴マップに一つのクラスを対応させ分類することで、モデルの安定性が
増し過学習を防ぐ効果がある。
(ただし、収束が遅くなる傾向があるため注意が必要)
125. 125
Deep Convolutional GANとは
DCGANのアーキテクチャ
③ Batch Normalizationを使用する
generatorとdiscriminatorの両方に適用
ただし、generatorの出力層と、discriminatorの入力層には適用しない
⇒画像そのものを正規化することになるため、
適用するとネットワークが不安定になる
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
各層でのデータ分布を正規化することで、
学習速度の向上、パラメータの初期値依存の
軽減、および過学習を防ぐ効果がある
126. 126
Deep Convolutional GANとは
DCGANのアーキテクチャ
④ 活性化関数
generator
• 出力層にTanh
• それ以外の層はすべてReLU
discriminatorでは、
• すべての層でLeaky ReLU
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
Leaky ReLUは、x≦0の領域がaxとなる。
ReLUでは、 x≦0の領域で勾配が0になり学習が進まなくなるが、Leaky ReLUは勾配が0に
ならないため、この問題を回避できる。(DCGANでは、a=0.2で定義している)
また、discriminatorの入力画像である学習画像・生成画像の各ピクセルの値域は-1~1であ
り、ReLUだとx≦0の領域がすべて0になってしまうため、Leaky ReLUの方が適している。
128. 128
DCGANの実装
使用ライブラリ
• TensorFlow 1.2
Googleが提供しているオープンソースのディープラーニングライブラリ。
• Numpy 1.12.0
Pythonにおける数値計算用の拡張モジュール。
• Scipy 0.19.0
高度な科学計算を行うためのライブラリ。
使用データセット
• CIFAR-10 python version
ラベル付けされたサイズが32×32のカラー画像。
ラベルは、飛行機・自動車・鳥・猫・鹿・犬・カエル・馬・船・トラックの10クラス。
Pythonで扱いやすいようにpickle化されたものを使用する。
学習データ50000件、テストデータ10000件が格納されている。
【ダウンロードサイト】
https://www.cs.toronto.edu/~kriz/cifar.html
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
129. 129
• 学習回数は25epoch、バッチサイズを128で学習する。
• 入力、出力の画像サイズは32×32とする。
• Generatorの入力ノイズの次元数を100とする。
• Adamオプティマイザの学習率は0.0002、モーメンタムを0.5
flags = tf.app.flagsflags.DEFINE_integer("epoch", 25, "Epoch to train.")
flags.DEFINE_integer("batch_size", 128, "The size of batch images.")
flags.DEFINE_float("learning_rate", 0.0002, "Learning rate of for adam.")
flags.DEFINE_float("beta1", 0.5, "Momentum term of adam.")
flags.DEFINE_integer("input_height", 32, "The size of image to use.")
flags.DEFINE_integer("input_width", 32, "The size of image to use.")
flags.DEFINE_integer("output_height", 32, "The size of the output images to produce.")
flags.DEFINE_integer("output_width", 32, "The size of the output images to produce.")
flags.DEFINE_integer("c_dim", 3, "Dimension of image color.")
flags.DEFINE_integer("z_dim", 100, "Dimension of sample noise.")
FLAGS = flags.FLAGS
定数部分
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
130. 130
def load_cifar10(self):
data = np.empty((0,32*32*3))
for i in range(1,6):
fname = os.path.join(self.input_dir, "%s%d" % ("data_batch_", i))
with open(fname, 'rb') as f:
cifar_dict = pickle.load(f, encoding='latin-1’)
data = np.vstack((data, cifar_dict['data’]))
# オリジナル画像は(chanel:3, row:32, column:32)のフラット形式
# リシェイプ後、(row:32, column:32, chanel:3)に次元を入れ替える
data = data.reshape(len(data), 3, 32, 32).transpose(0, 2, 3, 1)
return np.array(data) / 127.5 - 1.
CIFAR-10の読み込み
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
CIFAR-10の学習データファイルは下記5ファイルに
分割されているため、すべて読み込んで配列に連結する。
data_batch_1
data_batch_2
data_batch_3
data_batch_4
data_batch_5
Generatorの出力層の活性化関数はtanh(-1~1)を使用するため、
画像データの各ピクセル値を0~255から-1~1の範囲に変換する。
138. 138
# 訓練時に更新する変数取得
t_vars = tf.trainable_variables()
d_vars = [var for var in t_vars if 'd_' in var.name]
g_vars = [var for var in t_vars if 'g_' in var.name]
# discriminatorの学習
self.d_optim = tf.train.AdamOptimizer(self.learning_rate, beta1=self.beta1)
.minimize(self.d_loss, var_list=d_vars, global_step=self.global_step)
# generatorの学習
self.g_optim = tf.train.AdamOptimizer(self.learning_rate, beta1=self.beta1)
.minimize(self.g_loss, var_list=g_vars)
モデルの構築(3)
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
学習時に更新対象の変数(重み、バイアス)を、
Discriminator・Generatorそれぞれで取得しておく。
Adam手法で誤差の最小化を行う。
Discriminator・Generatorそれぞれで更新対象の変数を指定しておく。
学習率は両方同じで0.0002とした。
144. 144
# 1epoch毎にサンプル画像生成
samples = self.sess.run(self.sampler, feed_dict={self.z_sample: sample_z})
self.save_images(samples, [8, 8],
'./{}/train_{:02d}.png'.format(config.sample_dir, epoch+last_epoch+1))
print("[Generato Sample Images]")
# モデルの保存
if not os.path.exists(self.checkpoint_dir):
os.makedirs(self.checkpoint_dir)
self.saver.save(self.sess, os.path.join(self.checkpoint_dir, 'DCGAN.model’),
global_step=epoch+last_epoch+1)
学習(4)
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
確認のため1epoch毎にサンプルを64画像生成する。
生成した画像を8×8にマージして1枚の画像ファイル
を出力する。
1epoch毎にチェックポイントファイルを生成。
145. 145
DCGANの実行結果
学習結果1
2017/6/29
C8Lab Copyright 2017 C8Lab Inc. All rights reserved
After 1 epoch After 10 epoch After 20 epoch
全体的にぼやけていて、何の画像
か識別できない。
ぼやけてはいるが、ある程度何の
画像か認識できるようになった。
輪郭がシャープになった。
165. 165
many to one
必要なのは最終ステップの出力のみ
例:1行ずつ画像を読み込んで行って、その画像のクラス分類
2017/6/29
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
入力1 入力2 入力3
中間1 中間2 中間2
出力3
166. 166
many to one実装
ポイントはtf.nn.dynamic_rnnの出力の最終時系列のデータだけを引っ
張ってくること
2017/6/29
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Tensor操作になるのでちょっと手間
168. 168
プログラム作成
インポートなど
2017/6/29
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#-*- coding:utf-8 -*-
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
#mnistデータを格納したオブジェクトを呼び出す
mnist = input_data.read_data_sets("data/", one_hot=True)
169. 169
プログラム作成
モデル構築(入力データ整形)
2017/6/29
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#入力データ整形
num_seq = 28
num_input = 28
x = tf.placeholder(tf.float32, [None, 784])
input = tf.reshape(x, [-1, num_seq, num_input])
dynamic_rnnへの入力は[バッチサイズ, sequenceサイズ, 入力長]
tf.reshapeで整形 ※num_seq* num_input=784にするように
170. 170
プログラム作成
モデル構築(rnn cell作成)
2017/6/29
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#ユニット数128個のLSTMセル
#三段に積む
stacked_cells = []
for i in range(3):
stacked_cells.append(tf.nn.rnn_cell.LSTMCell(num_units=128))
cell = tf.nn.rnn_cell.MultiRNNCell(cells=stacked_cells)
171. 171
プログラム作成
モデル構築(dynamic_rnn構築、最終時間のみのスライス)
2017/6/29
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#dynamic_rnn構築
outputs, states = tf.nn.dynamic_rnn(cell=cell, inputs=input, dtype=tf.float32,
time_major=False)
#シーケンス軸のランクを最初に来るように入れ替え
#type_major=Trueにしていれば必要ない
outputs = tf.transpose(outputs,[1, 0, 2])
#最後のシーケンスのデータのみスライス
last_output = tf.gather(outputs, int(outputs.get_shape()[0]) -1)
Last_outputは最終時間における[バッチサイズ, 出力長]となり、
いつものニューラルネットワークと同じ!!
172. 172
プログラム作成
モデル構築(出力層)
2017/6/29
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#出力層
w = tf.Variable(tf.truncated_normal([128,10], stddev=0.1))
b = tf.Variable(tf.zeros([10]))
out = tf.nn.softmax(tf.matmul(last_output, w ) + b)
以前書いたものと同じ。以降、lossや評価、実行も全て他のプログラムと同じ
RNNなので計算時間もかかる上に、収束も遅い。