オブジェクト指向の練習を兼ねて、CNNをクラスで実装したいと考えています。
python
1import tensorflow as tf 2import numpy as np 3from dataset.mnist import load_mnist 4 5(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True) 6 7class 畳み込み層: 8 def __init__(self, f枚数1, f枚数2): 9 self.フィルター1 = tf.Variable(tf.truncated_normal([5,5,1,f枚数1], 10 stddev=0.1)) 11 self.バイアス1 = tf.Variable(tf.constant(0.1, shape=[f枚数1])) 12 13 self.フィルター2 = tf.Variable(tf.truncated_normal([5,5,f枚数1, f枚数2], 14 stddev=0.1)) 15 self.バイアス2 = tf.Variable(tf.constant(0.1, shape=[f枚数2])) 16 17 def 伝達処理(self, 入力値): 18 """引数の入力値には、tf.placeholderの4次元配列を渡す""" 19 20 f1, b1 = self.フィルター1, self.バイアス1 21 f2, b2 = self.フィルター2, self.バイアス2 22 23 コンバート1 = tf.nn.conv2d(入力値, f1, strides=[1,1,1,1], 24 padding="SAME") 25 活性化1 = tf.nn.relu(コンバート1 + b1) 26 27 プーリング1 = tf.nn.max_pool(活性化1, ksize=[1,2,2,1], 28 strides=[1,2,2,1], padding="SAME") 29 30 コンバート2 = tf.nn.conv2d(プーリング1, f2, strides=[1,1,1,1], 31 padding="SAME") 32 活性化2 = tf.nn.relu(コンバート2 + b2) 33 プーリング2 = tf.nn.max_pool(活性化2, ksize=[1,2,2,1], 34 strides=[1,2,2,1], padding="SAME") 35 36 return プーリング2 37 38class 全結合層(畳み込み層): 39 def __init__(self, 入力数, 中間数, 出力数): 40 41 self.重み1 = tf.Variable(tf.truncated_normal \ 42 ([入力数, 中間数], 43 stddev=tf.sqrt(2.0 / 入力数))) 44 45 self.バイアス1 = tf.Variable(tf.truncated_normal \ 46 ([中間数], stddev=0.1)) 47 48 self.重み2 = tf.Variable(tf.truncated_normal \ 49 ([中間数, 出力数], 50 stddev=tf.sqrt(2.0 / 中間数))) 51 52 self.バイアス2 = tf.Variable(tf.truncated_normal \ 53 ([出力数], stddev=0.1)) 54 55 def 伝達処理(self, f枚数1, f枚数2, 入力値): 56 """引数の入力値には、tf.placeholderの4次元配列を渡す 57 変数[畳出力値]で畳み込み層の出力結果を受け取り 58 全結合の伝達処理をする""" 59 60 畳出力値 = 畳み込み層(f枚数1, f枚数2).伝達処理(入力値) 61 行サイズ = tf.size(畳出力値[0]) 62 全結合 = tf.reshape(畳出力値, [-1, 行サイズ]) 63 64 w1 , b1 = self.重み1, self.バイアス1 65 w2 , b2 = self.重み2, self.バイアス2 66 67 一層目 = tf.matmul(全結合, w1) + b1 68 活性化1 = tf.nn.relu(一層目) 69 ドロップアウト1 = tf.nn.dropout(活性化1, self.キープ率) 70 71 二層目 = tf.matmul(ドロップアウト1, w2) + b2 72 活性化2 = tf.nn.relu(二層目) 73 出力層 = tf.nn.softmax(活性化2) 74 75 return 出力層 76 77 def 欠損関数(self, 入力値, 正解ラベル): 78 """交差エントロピーを使用 79 tf.clip_by_valueで出力がnanにならないように対策""" 80 81 出力値 = self.伝達処理(32, 64, 入力値) 82 欠損値バッチ = -tf.reduce_sum(正解ラベル * tf.log(tf.clip_by_value\ 83 (出力値, 1e-10, 1.0)), 84 axis=1) 85 交差エントロピー = tf.reduce_mean(欠損値バッチ) 86 return 交差エントロピー 87 88 def 正解率(self, 入力値, 正解ラベル): 89 出力値 = self.伝達処理(32, 64, 入力値) 90 真理値判定 = tf.equal(tf.argmax(出力値, 1), tf.argmax(正解ラベル, 1)) 91 正解率 = tf.reduce_mean(tf.cast(真理値判定, tf.float32)) 92 return 正解率 93 94 def 確率的勾配下降(self, 入力値, 正解ラベル): 95 欠損値 = self.欠損関数(入力値, 正解ラベル) 96 勾配下降 = tf.train.AdamOptimizer(0.01). minimize(欠損値) 97 return 勾配下降 98 99 def 学習処理(self, f枚数1, f枚数2): 100 with tf.Session() as セッション: 101 セッション.run(tf.global_variables_initializer()) 102 103 画像サイズ = tf.placeholder(tf.float32, [None, 784]) 104 正解サイズ = tf.placeholder(tf.float32, [None, 10]) 105 入力値 = tf.reshape(画像サイズ, [-1, 28, 28 ,1]) 106 107 self.キープ率 = tf.placeholder(tf.float32) 108 109 i = 0 110 for _ in range(10000): 111 i += 1 112 バッチ番号 = np.random.choice(60000, 50) 113 k入力バッチ = x_train[バッチ番号] 114 k正解バッチ = t_train[バッチ番号] 115 n = セッション.run(self.確率的勾配下降(入力値, 正解サイズ), 116 feed_dict={画像サイズ:k入力バッチ, 117 正解サイズ:k正解バッチ, 118 self.キープ率:0.5}) 119 120 if i == 100: 121 print(n) 122 123 124net = 全結合層(3136,1024,10) 125net.学習処理(32, 64)
自分に判りやすいように、畳み込み層と全結合層を分けて書いています
このコードを実行するとtf.global_variables_initializer()で初期化出来ていないという趣旨のエラーが出ます
それともインスタンス変数で初期化するのはあまり望ましくない事なのでしょうか?
わかる方いらしたらよろしくお願いします><
追記
結構前の質問ですが、自分のしたい感じの事が出来たので、一応追記しておきます。
python
1mport tensorflow as tf 2import numpy as np 3import モデル 4import 関数 5from dataset.mnist import load_mnist 6 7class mnist: 8 def __init__(self,入力形状, 正解形状, f枚数, 中間数, 学習率): 9 self.セッション = tf.Session() 10 self.入力ホルダ = tf.placeholder(tf.float32, 入力形状) 11 self.正解ホルダ = tf.placeholder(tf.float32, 正解形状) 12 self.キープ率 = tf.placeholder(tf.float32) 13 14 """畳み込み層のパラメーター""" 15 self.f1 = tf.Variable(tf.truncated_normal([3, 3, 1, f枚数], 16 stddev=0.01)) 17 self.fb1 = tf.Variable(tf.truncated_normal([f枚数], 18 stddev=0.01)) 19 self.f2 = tf.Variable(tf.truncated_normal([3, 3, f枚数, f枚数], 20 stddev=0.01)) 21 self.fb2 = tf.Variable(tf.truncated_normal([f枚数], 22 stddev=0.01)) 23 24 self.畳み込み出力 = モデル.cnn_batch_relu(self.入力ホルダ, 25 self.f1, self.fb1, 26 self.f2, self.fb2) 27 28 """全結合層のパラメーター""" 29 入力数 = tf.size(self.畳み込み出力[0]) 30 全結合 = tf.reshape(self.畳み込み出力, [-1, 入力数]) 31 出力数 = 正解形状[1] 32 33 self.重み1 = \ 34 tf.Variable(tf.truncated_normal([入力数,中間数], 35 stddev=tf.sqrt(2.0 / tf.cast(入力数, tf.float32)))) 36 self.バイアス1 = tf.Variable(tf.truncated_normal([中間数],stddev=0.01)) 37 38 self.重み2 = \ 39 tf.Variable(tf.truncated_normal([中間数, 出力数], 40 stddev= 0.01)) 41 self.バイアス2 = tf.Variable(tf.truncated_normal([出力数], stddev=0.01)) 42 43 self.出力層 = モデル.fcn_batch_relu(self.重み1, self.バイアス1, 44 self.重み2, self.バイアス2, 45 全結合, self.キープ率) 46 47 self.欠損値 = 関数.二乗和誤差(self.出力層, self.正解ホルダ) 48 self.勾配下降 = \ 49 tf.train.GradientDescentOptimizer(学習率).minimize(self.欠損値) 50 self.セッション.run(tf.global_variables_initializer()) 51 52 def 出力層run(self, 入力値, キープ率): 53 return self.セッション.run(self.出力層, 54 feed_dict={self.入力ホルダ:入力値, 55 self.キープ率:キープ率}) 56 57 58 def 欠損値run(self, 入力値, 正解ラベル, キープ率): 59 return self.セッション.run(self.欠損値, 60 feed_dict={self.入力ホルダ:入力値, 61 self.正解ホルダ:正解ラベル, 62 self.キープ率:キープ率}) 63 64 def 正解率run(self, 入力値, 正解ラベル, キープ率): 65 出力層 = self.出力層run(入力値, キープ率) 66 正解率 = 関数.分類正解率(出力層, 正解ラベル) 67 return self.セッション.run(正解率, 68 feed_dict={self.入力ホルダ:入力値, 69 self.正解ホルダ:正解ラベル, 70 self.キープ率:キープ率}) 71 72 def 勾配下降run(self, 入力値, 正解ラベル, キープ率): 73 self.セッション.run(self.勾配下降, 74 feed_dict={self.入力ホルダ:入力値, 75 self.正解ホルダ:正解ラベル, 76 self.キープ率:キープ率}) 77 78 79(入力値, 正解ラベル), (t入力値, t正解ラベル) = load_mnist(flatten=True, 80normalize=False, one_hot_label=True) 81 82network = mnist([None, 28, 28, 1], [None, 10], 50, 2024, 0.0001) 83 84入力値 = 入力値.reshape(60000, 28, 28, 1) 85t入力値 = t入力値.reshape(10000, 28, 28, 1) 86学習回数 = 50000 87バッチsize = 100 88 89for _ in range(学習回数): 90 ミニバッチ = np.random.choice(60000, バッチsize) 91 入力ミニバッチ = 入力値[ミニバッチ] 92 正解ミニバッチ = 正解ラベル[ミニバッチ] 93 network.勾配下降run(入力ミニバッチ, 正解ミニバッチ, 0.5) 94 95 if _%200 == 0: 96 欠損値リスト = [] 97 正解率リスト = [] 98 start = 0 99 end = 1001 100 for i in range(10): 101 欠損値 = network.欠損値run(t入力値[start:end], 102 t正解ラベル[start:end], 103 1.0) 104 105 正解率 = network.正解率run(t入力値[start:end], 106 t正解ラベル[start:end], 107 1.0) 108 109 欠損値リスト.append(欠損値) 110 正解率リスト.append(正解率) 111 start += 1000 112 end += 1000 113 114 print(len(欠損値リスト)) 115 print(len(正解率リスト)) 116 print(_, "欠損値", np.sum(欠損値リスト) / 10) 117 print(_, "正解率", np.mean(正解率リスト))
インスタンス変数にtf.Sessionとtf.global_variables_initializerを置く事で、前回のエラーを回避しつつ、session.runもうまく起動する事が出来ました。
回答2件
あなたの回答
tips
プレビュー