質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

8751閲覧

TensorFlowのaccuracyの値が少しも変動しません。

poker

総合スコア14

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2017/12/29 08:43

こちらのブログを参考にしてTensorFlowを用いた顔認識のプログラムを作成しています。
ディープラーニングでザッカーバーグの顔を識別するAIを作る③(データ学習編)

学習データを生成するmain.pyを実行したのですが、accuracyの値が少しも変動しません。

step 0, training accuracy 0.102362 step 1, training accuracy 0.102362 step 2, training accuracy 0.102362 step 3, training accuracy 0.102362 step 4, training accuracy 0.102362 step 5, training accuracy 0.102362 … step 46, training accuracy 0.102362 step 47, training accuracy 0.102362 step 48, training accuracy 0.102362 step 49, training accuracy 0.102362 test accuracy 0.101773

各クラスの学習画像の枚数は
クラス1 623枚
クラス2 3376枚
クラス3 2096枚
になります。

解決方法を教えていただきたいです。
よろしくお願いします。

python3系、tensorflow (1.4.1)になります。

以下コード全文です。。

python

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

*説明
カンですが、問題はこれだと思います。

# 1回の学習で何枚の画像を使うか flags.DEFINE_integer('batch_size', 20, 'Batch size Must divide evenly into the dataset sizes.')

注目するところは、
Batch size Must divide evenly into the dataset sizes.
データセットは、バッチサイズで必ず余りなく割り切れなければならない。

これに対し現状の設定は、

クラス1 623

クラス2 3376
クラス3 2096

つまり、batch size(20)で割り切れない枚数ですので、問題ありですね。

*対策
batch_sizeは20ですので、20の倍数に合うように各クラスの枚数を切り捨てればよいです。

  • クラス1 620
  • クラス2 3360
  • クラス3 2080

追記
Accuracyが変化しない旨@teratailの投稿がありました。
他の対応として、学習率を1桁上げたり下げたりするとうまくいく可能性がありますので試してください。

flags.DEFINE_float('learning_rate', 1e-4, 'Initial learning rate.')

これの'1e-4'を'1e-3'や'1e-5'にして数STEP回すだけでも多分違いが出ると思います。

投稿2017/12/29 08:58

編集2017/12/29 09:18
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

poker

2017/12/29 09:13 編集

回答ありがとうございます! 早速クラス枚数を620,3360,2080としてmain.pyを実行したのですが現状 step 0, training accuracy 0.10231 step 1, training accuracy 0.10231 step 2, training accuracy 0.10231 step 3, training accuracy 0.10231 step 4, training accuracy 0.10231 step 5, training accuracy 0.10231 step 6, training accuracy 0.10231 step 7, training accuracy 0.10231 step 8, training accuracy 0.10231 step 9, training accuracy 0.10231 となっていて変動しません^^;
退会済みユーザー

退会済みユーザー

2017/12/29 09:14

追記しますね
poker

2017/12/29 09:30

ありがとうございます! 5stepまで試したところ、1e-3はaccuracy 0.10231のまま5stepが終了したのですが、1e-5にしたところ step 0, training accuracy 0.343234 step 1, training accuracy 0.343234 step 2, training accuracy 0.439604 step 3, training accuracy 0.680088 step 4, training accuracy 0.777998 と学習が始まりました!本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問