質問するログイン新規登録

回答編集履歴

1

動いたコードを追加しました

2020/01/13 19:17

投稿

takahiro_tt
takahiro_tt

スコア9

answer CHANGED
@@ -11,6 +11,297 @@
11
11
 
12
12
  の変更に加えて、
13
13
  学習率の部分を1e-4 から1e-5 に小さくしたらそれらしい動きになりました
14
+
15
+ ```python
16
+
17
+ # -*- coding: utf-8 -*-
18
+
19
+ import cv2
20
+ import random
21
+ import numpy as np
22
+ import sys, os
23
+ import tensorflow as tf
24
+ import tensorflow.python.platform
25
+ import tensorflow.compat.v1 as tf # FLAGS = tf.app.flags.FLAGSの解決
26
+
27
+ # 識別ラベルの数(今回は京:0,薫:1,Shinya:2なので、3)[自分とその他で2つ(まずは)]
28
+ NUM_CLASSES = 2
29
+
30
+ # 学習する時の画像のサイズ(px) 初期28
31
+ IMAGE_SIZE = 28
32
+
33
+ # 画像の次元数(28* 28*カラー(?))
34
+ IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3
35
+
36
+ # 学習に必要なデータのpathや学習の規模を設定
37
+ # パラメタの設定、デフォルト値やヘルプ画面の説明文を登録できるTensorFlow組み込み関数
38
+ #FLAGS = tf.app.flags.FLAGS
39
+
40
+ flags = tf.app.flags
41
+ FLAGS = flags.FLAGS
42
+
43
+ # 学習用データ
44
+ flags.DEFINE_string('train', 'C:/Users/?????/Anaconda3/envs/opencvtest001/workspace2/dir/train/data.txt', 'File name of train data')
45
+
46
+ # 検証用テストデータ
47
+ flags.DEFINE_string('test', 'C:/Users/?????/Anaconda3/envs/opencvtest001/workspace2/dir/test/data.txt', 'File name of test data')
48
+
49
+ # データを置いてあるフォルダ
50
+ flags.DEFINE_string('train_dir', 'C:/Users/?????/Anaconda3/envs/opencvtest001/workspace2/dir/data2', 'Directory to put the training data.')
51
+
52
+ # データ学習訓練の試行回数
53
+ flags.DEFINE_integer('max_steps', 100, 'Number of steps to run trainer.')
54
+
55
+ # 1回の学習で何枚の画像を使うか
56
+ flags.DEFINE_integer('batch_size', 30, 'Batch size Must divide evenly into the dataset sizes.')
57
+
58
+ # 学習率、小さすぎると学習が進まないし、大きすぎても誤差が収束しなかったり発散したりしてダメとか
59
+ flags.DEFINE_float('learning_keep_prob', 1e-5, 'Initial learning keep_prob.') #学習率を小さくしても変化なし
60
+
61
+
62
+ ####
63
+ ### ここに学習モデル処理を追記します
64
+
65
+ def inference(images_placeholder, keep_prob):
66
+ # 重みを標準偏差0.1の正規分布で初期化する
67
+ def weight_variable(shape):
68
+ initial = tf.truncated_normal(shape, stddev=0.1)
69
+ return tf.Variable(initial)
70
+
71
+ # バイアスを標準偏差0.1の正規分布で初期化する
72
+ def bias_variable(shape):
73
+ initial = tf.constant(0.1, shape=shape)
74
+ return tf.Variable(initial)
75
+
76
+ # 畳み込み層を作成する
77
+ def conv2d(x, W):
78
+ return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
79
+
80
+ # プーリング層を作成する
81
+ def max_pool_2x2(x):
82
+ return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
83
+ strides=[1, 2, 2, 1], padding='SAME')
84
+ # ベクトル形式で入力されてきた画像データを28px * 28pxの画像に戻す(?)。
85
+
86
+ # 今回はカラー画像なので3(モノクロだと1)
87
+ x_image = tf.reshape(images_placeholder, [-1, IMAGE_SIZE, IMAGE_SIZE, 3])
88
+
89
+ # 畳み込み層第1レイヤーを作成
90
+ with tf.name_scope('conv1') as scope:
91
+
92
+ W_conv1 = weight_variable([5, 5, 3, 32])
93
+
94
+ # バイアスの数値を代入
95
+ b_conv1 = bias_variable([32])
96
+
97
+ h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
98
+
99
+ # プーリング層1の作成
100
+
101
+ with tf.name_scope('pool1') as scope:
102
+ h_pool1 = max_pool_2x2(h_conv1)
103
+
104
+ # 畳み込み層第2レイヤーの作成
105
+ with tf.name_scope('conv2') as scope:
106
+ # 第一レイヤーでの出力を第2レイヤー入力にしてもう一度フィルタリング実施。
107
+ # 64個の特徴を検出する。inputが32なのはなんで?(教えて欲しい)
108
+ W_conv2 = weight_variable([5, 5, 32, 64])
109
+
110
+ # バイアスの数値を代入(第一レイヤーと同じ)
111
+ b_conv2 = bias_variable([64])
112
+
113
+ # 検出した特徴の整理(第一レイヤーと同じ)
114
+ h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
115
+
116
+ # プーリング層2の作成(ブーリング層1と同じ)
117
+ with tf.name_scope('pool2') as scope:
118
+ h_pool2 = max_pool_2x2(h_conv2)
119
+
120
+ # 全結合層1の作成
121
+ with tf.name_scope('fc1') as scope:
122
+ W_fc1 = weight_variable([7*7*64, 1024])
123
+ b_fc1 = bias_variable([1024])
124
+ # 画像の解析を結果をベクトルへ変換
125
+ h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
126
+
127
+ # 第一、第二と同じく、検出した特徴を活性化させている
128
+ h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
129
+
130
+ # dropoutの設定
131
+ h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
132
+
133
+ # 全結合層2の作成(読み出しレイヤー)
134
+ with tf.name_scope('fc2') as scope:
135
+ W_fc2 = weight_variable([1024, NUM_CLASSES])
136
+ b_fc2 = bias_variable([NUM_CLASSES])
137
+
138
+ # ソフトマックス関数による正規化(活性化関数)
139
+ #変更してシグモイド関数
140
+ # ここまでのニューラルネットワークの出力を各ラベルの確率へ変換する
141
+
142
+ with tf.name_scope('sigmoid') as scope:
143
+ y_conv=tf.nn.sigmoid(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
144
+
145
+ # 各ラベルの確率(のようなもの?)を返す
146
+ return y_conv
147
+
148
+ # 予測結果と正解にどれくらい「誤差」があったかを算出する
149
+ # logitsは計算結果: float - [batch_size, NUM_CLASSES]
150
+ # labelsは正解ラベル: int32 - [batch_size, NUM_CLASSES]
151
+ def loss(logits, labels):
152
+ # 交差エントロピーの計算
153
+ cross_entropy = -tf.reduce_sum(labels*tf.log(tf.clip_by_value(logits,1e-10,1.0)))
154
+
155
+ # TensorBoardで表示するよう指定
156
+ tf.summary.scalar("cross_entropy", cross_entropy)
157
+
158
+ # 誤差の率の値(cross_entropy)を返す
159
+ return cross_entropy
160
+
161
+ # 誤差(loss)を元に誤差逆伝播を用いて設計した学習モデルを訓練する
162
+
163
+ def training(loss, learning_keep_prob):
164
+ #この関数がその当たりの全てをやってくれる様
165
+ train_step = tf.train.AdamOptimizer(learning_keep_prob).minimize(loss)
166
+ return train_step
167
+
168
+ # inferenceで学習モデルが出した予測結果の正解率を算出する
169
+ def accuracy(logits, labels):
170
+ # 予測ラベルと正解ラベルが等しいか比べる。同じ値であればTrueが返される
171
+
172
+ correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1))
173
+
174
+ # booleanのcorrect_predictionをfloatに直して正解率の算出
175
+ # false:0,true:1に変換して計算する
176
+ accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
177
+
178
+ # TensorBoardで表示する様設定
179
+ tf.summary.scalar("accuracy", accuracy)
180
+ return accuracy
181
+
182
+ ####
183
+ if __name__ == '__main__':
184
+
185
+ f = open(FLAGS.train, 'r')
186
+ # データを入れる配列
187
+ train_image = []
188
+ train_label = []
189
+
190
+ for line in f:
191
+ # 改行を除いてスペース区切りにする
192
+ line = line.rstrip()
193
+ l = line.split()
194
+
195
+ # データを読み込んで28x28に縮小
196
+ # img_path = "C:/Users/hogehoge/Desktop/"
197
+ img = cv2.imread(l[0])
198
+ img = cv2.resize(img, (IMAGE_SIZE, IMAGE_SIZE))
199
+
200
+ # 一列にした後、0-1のfloat値にする
201
+ train_image.append(img.flatten().astype(np.float32)/255.0)
202
+
203
+ # ラベルを1-of-k方式で用意する
204
+ tmp = np.zeros(NUM_CLASSES)
205
+ tmp[int(l[1])] = 1
206
+ train_label.append(tmp)
207
+
208
+ # numpy形式に変換
209
+ train_image = np.asarray(train_image)
210
+ train_label = np.asarray(train_label)
211
+ f.close()
212
+
213
+ f = open(FLAGS.test, 'r')
214
+ test_image = []
215
+ test_label = []
216
+ for line in f:
217
+ line = line.rstrip()
218
+ l = line.split()
219
+ img = cv2.imread(l[0])
220
+ img = cv2.resize(img, (IMAGE_SIZE, IMAGE_SIZE))
221
+ test_image.append(img.flatten().astype(np.float32)/255.0)
222
+ tmp = np.zeros(NUM_CLASSES)
223
+ tmp[int(l[1])] = 1
224
+ test_label.append(tmp)
225
+ test_image = np.asarray(test_image)
226
+ test_label = np.asarray(test_label)
227
+ f.close()
228
+
229
+ #TensorBoardのグラフに出力するスコープを指定
230
+ with tf.Graph().as_default():
231
+ # 画像を入れるためのTensor(28*28*3(IMAGE_PIXELS)次元の画像が任意の枚数(None)分はいる)
232
+ images_placeholder = tf.placeholder("float", shape=(None, IMAGE_PIXELS))
233
+
234
+ # ラベルを入れるためのTensor(3(NUM_CLASSES)次元のラベルが任意の枚数(None)分入る)
235
+ labels_placeholder = tf.placeholder("float", shape=(None, NUM_CLASSES))
236
+
237
+ # dropout率を入れる仮のTensor
238
+ keep_prob = tf.placeholder("float")
239
+
240
+ # inference()を呼び出してモデルを作る
241
+ logits = inference(images_placeholder, keep_prob)
242
+
243
+ # loss()を呼び出して損失を計算
244
+ loss_value = loss(logits, labels_placeholder)
245
+
246
+ # training()を呼び出して訓練して学習モデルのパラメーターを調整する
247
+ train_op = training(loss_value, FLAGS.learning_keep_prob)
248
+
249
+ # 精度の計算
250
+ acc = accuracy(logits, labels_placeholder)
251
+
252
+ # 保存の準備
253
+ saver = tf.train.Saver()
254
+
255
+ # Sessionの作成(TensorFlowの計算は絶対Sessionの中でやらなきゃだめ)
256
+ sess = tf.Session()
257
+
258
+ # 変数の初期化(Sessionを開始したらまず初期化)
259
+ sess.run(tf.global_variables_initializer())
260
+
261
+ # TensorBoard表示の設定(TensorBoardの宣言的な?)
262
+ summary_op = tf.summary.merge_all()
263
+
264
+ # train_dirでTensorBoardログを出力するpathを指定
265
+ summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph)
266
+
267
+ # 実際にmax_stepの回数だけ訓練の実行していく
268
+ for step in range(FLAGS.max_steps):
269
+ for i in range(len(train_image)//FLAGS.batch_size):
270
+ # batch_size分の画像に対して訓練の実行
271
+ batch = FLAGS.batch_size*i
272
+
273
+ # feed_dictでplaceholderに入れるデータを指定する
274
+ sess.run(train_op, feed_dict={
275
+ images_placeholder: train_image[batch:batch+FLAGS.batch_size],
276
+ labels_placeholder: train_label[batch:batch+FLAGS.batch_size],
277
+ keep_prob: 0.5})
278
+
279
+ # 1step終わるたびに精度を計算する
280
+ train_accuracy = sess.run(acc, feed_dict={
281
+ images_placeholder: train_image,
282
+ labels_placeholder: train_label,
283
+ keep_prob: 1.0})
284
+ print("step %d, training accuracy %g" %(step, train_accuracy))
285
+
286
+ # 1step終わるたびにTensorBoardに表示する値を追加する
287
+ summary_str = sess.run(summary_op, feed_dict={
288
+ images_placeholder: train_image,
289
+ labels_placeholder: train_label,
290
+ keep_prob: 1.0})
291
+ summary_writer.add_summary(summary_str, step)
292
+
293
+ # 訓練が終了したらテストデータに対する精度を表示する
294
+ print("test accuracy %g" %(sess.run(acc, feed_dict={
295
+ images_placeholder: test_image,
296
+ labels_placeholder: test_label,
297
+ keep_prob: 1.0})))
298
+
299
+ # データを学習して最終的に出来上がったモデルを保存
300
+ # "model.ckpt"は出力されるファイル名
301
+ save_path = saver.save(sess, "model3.ckpt")
302
+ ```
303
+
304
+
14
305
  ```result
15
306
  step 0, training accuracy 0.7
16
307
  step 1, training accuracy 0.7