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

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

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

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

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Q&A

解決済

4回答

7396閲覧

Tensorflow画像識別実行結果がおかしい

pfirsich

総合スコア15

Python 3.x

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

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

0グッド

4クリップ

投稿2017/06/30 07:32

###前提・実現したいこと
プログラミング初心者です以下当然のことを記載していたらすいません。

TensorFlowでアニメゆるゆりの制作会社を識別する(http://kivantium.hateblo.jp/entry/2015/11/18/233834)のブログを参考に画像認識識別をしようと実行したところ下記のように同じ結果しかでません。

1番最初に動かした時はstep145くらいまで精度があがり最高0.992843までいきましたが、step146になった途端精度が0.0889571に下がりそれ以降全200step行いましたがずっとその精度が表示され、その後何度試しても下記のような結果がでてしまうようになりました。

正常に動かない原因は何でしょうか。

###発生している問題・エラーメッセージ

step 0 training accuracy 0.0889571 test accuracy 0.2 step 1 training accuracy 0.0889571 test accuracy 0.2 step 2 training accuracy 0.0889571 test accuracy 0.2 step 3 training accuracy 0.0889571 test accuracy 0.2 step 4 training accuracy 0.0889571 test accuracy 0.2 step 5 training accuracy 0.0889571 test accuracy 0.2 step 6 training accuracy 0.0889571 test accuracy 0.2 step 7 training accuracy 0.0889571 test accuracy 0.2 step 8 training accuracy 0.0889571 test accuracy 0.2 step 9 training accuracy 0.0889571 test accuracy 0.2 step 10 training accuracy 0.0889571 test accuracy 0.2 step 11 training accuracy 0.0889571 test accuracy 0.2 step 12 training accuracy 0.0889571 test accuracy 0.2 step 13 training accuracy 0.0889571 test accuracy 0.2 step 14 training accuracy 0.0889571 test accuracy 0.2 step 15 training accuracy 0.0889571 test accuracy 0.2 step 16 training accuracy 0.0889571 test accuracy 0.2 step 17 training accuracy 0.0889571 test accuracy 0.2 step 18 training accuracy 0.0889571 test accuracy 0.2 step 19 training accuracy 0.0889571 test accuracy 0.2

###該当のソースコード

import sys import cv2 import numpy as np import tensorflow as tf import tensorflow.python.platform NUM_CLASSES =10 IMAGE_SIZE = 28 IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3 flags = tf.app.flags FLAGS = flags.FLAGS flags.DEFINE_string('train', '/home/k123/anaconda2/envs/tensorflow/data/train2.txt', 'File name of train data') flags.DEFINE_string('test', '/home/k123/anaconda2/envs/tensorflow/data/test.txt', 'File name of train data') flags.DEFINE_string('train_dir', '/home/k123/anaconda2/envs/tensorflow/data/gazo', 'Directory to put the training data.') flags.DEFINE_integer('max_steps', 20, 'Number of steps to run trainer.') flags.DEFINE_integer('batch_size', 10, 'Batch size' 'Must divide evenly into the dataset sizes.') flags.DEFINE_float('learning_rate', 1e-4, 'Initial learning rate.') def inference(images_placeholder, keep_prob): # 重みを標準偏差0.1の正規分布で初期化 def weight_variable(shape): initial = tf.truncated_normal(shape, stddev=0.1) return tf.Variable(initial) # バイアスを標準偏差0.1の正規分布で初期化 def bias_variable(shape): initial = tf.constant(0.1, shape=shape) return tf.Variable(initial) # 畳み込み層の作成 def conv2d(x, W): return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') # プーリング層の作成 def max_pool_2x2(x): return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # 入力を28x28x3に変形 x_image = tf.reshape(images_placeholder, [-1, 28, 28, 3]) # 畳み込み層1の作成 with tf.name_scope('conv1') as scope: W_conv1 = weight_variable([5, 5, 3, 32]) b_conv1 = bias_variable([32]) h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) # プーリング層1の作成 with tf.name_scope('pool1') as scope: h_pool1 = max_pool_2x2(h_conv1) # 畳み込み層2の作成 with tf.name_scope('conv2') as scope: W_conv2 = weight_variable([5, 5, 32, 64]) b_conv2 = bias_variable([64]) h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # プーリング層2の作成 with tf.name_scope('pool2') as scope: h_pool2 = max_pool_2x2(h_conv2) # 全結合層1の作成 with tf.name_scope('fc1') as scope: W_fc1 = weight_variable([7*7*64, 1024]) b_fc1 = bias_variable([1024]) h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) # dropoutの設定 h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 全結合層2の作成 with tf.name_scope('fc2') as scope: W_fc2 = weight_variable([1024, NUM_CLASSES]) b_fc2 = bias_variable([NUM_CLASSES]) # ソフトマックス関数による正規化 with tf.name_scope('softmax') as scope: y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) # 各ラベルの確率のようなものを返す return y_conv def loss(logits, labels): # 交差エントロピーの計算 cross_entropy = -tf.reduce_sum(labels*tf.log(logits)) # TensorBoardで表示するよう指定 tf.scalar_summary("cross_entropy", cross_entropy) return cross_entropy def training(loss, learning_rate): train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss) return train_step def accuracy(logits, labels): correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) tf.scalar_summary("accuracy", accuracy) return accuracy if __name__ == '__main__': # ファイルを開く f = open(FLAGS.train, 'r') # データを入れる配列 train_image = [] train_label = [] for line in f: # 改行を除いてスペース区切りにする line = line.rstrip() l = line.split() # データを読み込んで28x28に縮小 img = cv2.imread(l[0]) img = cv2.resize(img, (28, 28)) # 一列にした後、0-1のfloat値にする train_image.append(img.flatten().astype(np.float32)/255.0) # ラベルを1-of-k方式で用意する tmp = np.zeros(NUM_CLASSES) tmp[int(l[1])] = 1 train_label.append(tmp) # numpy形式に変換 train_image = np.asarray(train_image) train_label = np.asarray(train_label) f.close() f = open(FLAGS.test, 'r') test_image = [] test_label = [] for line in f: line = line.rstrip() l = line.split() img = cv2.imread(l[0]) img = cv2.resize(img, (28, 28)) test_image.append(img.flatten().astype(np.float32)/255.0) tmp = np.zeros(NUM_CLASSES) tmp[int(l[1])] = 1 test_label.append(tmp) test_image = np.asarray(test_image) test_label = np.asarray(test_label) f.close() with tf.Graph().as_default(): # 画像を入れる仮のTensor images_placeholder = tf.placeholder("float", shape=(None, IMAGE_PIXELS)) # ラベルを入れる仮のTensor labels_placeholder = tf.placeholder("float", shape=(None, NUM_CLASSES)) # dropout率を入れる仮のTensor keep_prob = tf.placeholder("float") # inference()を呼び出してモデルを作る logits = inference(images_placeholder, keep_prob) # loss()を呼び出して損失を計算 loss_value = loss(logits, labels_placeholder) # training()を呼び出して訓練 train_op = training(loss_value, FLAGS.learning_rate) # 精度の計算 acc = accuracy(logits, labels_placeholder) # 保存の準備 saver = tf.train.Saver() # Sessionの作成 sess = tf.Session() # 変数の初期化 sess.run(tf.initialize_all_variables()) # TensorBoardで表示する値の設定 summary_op = tf.merge_all_summaries() summary_writer = tf.train.SummaryWriter(FLAGS.train_dir, sess.graph_def) # 訓練の実行 for step in range(FLAGS.max_steps): for i in range(len(train_image)//FLAGS.batch_size): # batch_size分の画像に対して訓練の実行 batch = FLAGS.batch_size*i # feed_dictでplaceholderに入れるデータを指定する sess.run(train_op, feed_dict={ images_placeholder: train_image[batch:batch+FLAGS.batch_size], labels_placeholder: train_label[batch:batch+FLAGS.batch_size], keep_prob: 0.5}) # 1 step終わるたびに精度を計算する train_accuracy = sess.run(acc, feed_dict={ images_placeholder: train_image, labels_placeholder: train_label, keep_prob: 1.0}) print('step %d training accuracy %g'%(step, train_accuracy)) # 1 step終わるたびにTensorBoardに表示する値を追加する summary_str = sess.run(summary_op, feed_dict={ images_placeholder: train_image, labels_placeholder: train_label, keep_prob: 1.0}) summary_writer.add_summary(summary_str, step) # 訓練が終了したらテストデータに対する精度を表示 print('test accuracy %g'%(sess.run(acc, feed_dict={ images_placeholder: test_image, labels_placeholder: test_label, keep_prob: 1.0}))) # 最終的なモデルを保存 save_path = saver.save(sess, "model0.ckpt")

###試したこと
◎画像の分類するクラス数を減らして実行したところ、トレーニング精度の数値が現在の0.889571から変わったもののやはり学習回数をいくらつんでも同じ精度しか表示されませんでした。
◎モデルファイル”model0.ckpt”を一回消して実行してみましたが変わりませんでした。

###補足情報(言語/FW/ツール等のバージョンなど)
ubuntu16.04/python3.5
画像形式はjpgまたはpngです。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/07/01 01:30

訓練用の画像と検証用の画像、それぞれの数(枚数)はいくつでしょうか?
pfirsich

2017/07/02 12:10

練習用1000枚、検証用3枚で実行しました。
guest

回答4

0

自己解決

学習率の値を1e-5にしたところ正常に学習値があがるようになりました。この学習率が今回は適正だった為でしょうか。

また、1e-4や1e-8の学習値では上記の実行結果のように正常な学習ができませんでした。

1e-5より高い値のみできないとなると発散したことで正常な学習ができないとわかりますが、低い値も正常に動かなかったことから結局原因はなんだったんでしょうか。今後も学習率、勾配について勉強して、画像、分類項目を減らしたり増やしたりすると学習率に関係してくるのかどうなるか今後も勉強していきたいと思います。

丁寧に回答してくれた方々、知らない言葉もでてきて調べたりしました、とても勉強になり助かりました。ありがとうございました。

投稿2017/07/14 08:33

pfirsich

総合スコア15

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

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

0

よくわからないところもありますが、以下を確認してみてはいかがでしょうか?

  1. 単純に勾配の数値を見るかグラフにする
  2. gradient clipping する
  3. initializerを設定する

そもそも、勾配が原因なのかを確認してみましょう。
次に、勾配が発散していたら clippingしてある大きさ以上学習しないようにしましょう。
また、initializerを設定するとそもそも発散しにくくなります。

投稿2017/07/08 04:12

MasashiKimura

総合スコア1150

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

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

pfirsich

2017/07/14 08:42

勾配の数値ですが、損失関数?と同じ意味でしょうか。知識不足ですいません。 表示させたところloss値は固まっていました。今回は発散はしていなかったのでしょうか・・。 2。3とても参考になります。まだpython自体わからないことだらけなので、プログラムを理解した上で初期値の設定も今後していきたいと思います。ありがとうございます。
guest

0

pythonユーザーです。

もしヒントになればと試しに書き込んでみました。あんまりうまく行かなければごめんなさい。

「step145くらいまで精度があがり最高0.992843までいきましたが、step146になった途端精度が0.0889571に下がりそれ以降全200step行いましたがずっとその精度が表示され、その後何度試しても下記のような結果がでてしまう」

ここから勾配が146stepで消えてしまった可能性がある(いわゆる勾配消失)ので検証してみてはいかがでしょうか?活性化関数でReLU関数が使われているので、ReLU関数に入力する値が負の数であれば導関数の値は0になるので、学習が不安定になることが知られています。(ちょっとお使いのデータ見てないのでわかりませんが、正規化すると平均が0になるため負の数も元データに混ざるため 影響することもありそうかなと・・・)

解決策は、アクティベーションに勾配消失しにくい他の関数をつかう、ですが、ハイパボリックタンジェント関数(as tf でインポート後 tf.nn.tanh() )がtensor flow では使えるようです。他にReLUの親戚のLeakyReLU、ParametricReLUというものがあるようですが、tensor flowではサポートがなく自分で書く必要があるようなので検索してコード例を調べると検証できると思います。

あとは学習率をわざといじって、学習がきちんと学習率に応じて進んで行くかどうか調べてバグがないか調べていくのも良いかもしれません。(学習率は大きすぎるとコスト関数の値がどんどん大きくなり発散しますので、そのあたりを留意しながらという点はあります・・・)

投稿2017/07/03 11:07

k_mawa82

総合スコア234

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

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

pfirsich

2017/07/07 05:33

学習率を1e-8にしたりしていじったところやはり同じ様な結果になりました。勾配消失の可能性も視野に入れて少しプログラムを見直してみます。 何度もモデルファイルを消し実行したところまた1回だけ学習が上がってうまくいくことがありました。 サイズとファイル形式が統一されていない画像データにも問題がありそうなので、データに問題があるか、MNISTに差し替えて調査していきたいと思います。 回答ありがとうございました。
guest

0

練習用1000枚、検証用3枚で実行しました。

理由はよくわかりませんが、ロジックが完璧だったとしても、練習用の画像や検証用の画像もバッチサイズの倍数でないとうまくいかなかったと思います。

とりあえず、検証用画像をあと7枚用意するか、検証用を5枚にしてバッチサイズを5にするかのような手当てをしてみてください。


この場合、
練習用は10(バッチサイズ)x100(ステップ)--->バッチサイズの倍数なのでOK
検証用は10(バッチサイズ)x0.333(ステップ)->バッチサイズの倍数でないのでNG

投稿2017/07/02 12:19

編集2017/07/02 12:20
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

pfirsich

2017/07/03 06:35

バッチサイズとの関連性があるとは知りませんでした、勉強になります、ありがとうございます。 訓練用1000枚、検証用10枚、バッチサイズ10で実行したところ、 step 0 training accuracy 0.0889571 test accuracy 0.1 とtest accuaryの値は変化したもののこのままステップ数をかさねてもやはり結果はずっと同じ表示でした。モデルや保存の部分で問題があるのでしょうか・・。 関連するかはわかりませんがpythonを閉じずに2回目に同じコードを実行しようとすると、最初のほうのコードの flags.DEFINE_string('train', '/home/k123/anaconda2/envs/tensorflow/data/train2.txt', 'File name of train data') flags.DEFINE_string('test', '/home/k123/anaconda2/envs/tensorflow/data/test.txt', 'File name of train data') flags.DEFINE_string('train_dir', '/home/k123/anaconda2/envs/tensorflow/data/gazo', 'Directory to put the training data.') flags.DEFINE_integer('max_steps', 20, 'Number of steps to run trainer.') flags.DEFINE_integer('batch_size', 10, 'Batch size' 'Must divide evenly into the dataset sizes.') flags.DEFINE_float('learning_rate', 1e-4, 'Initial learning rate.') の部分を実行すると、 ArgumentError: argument --train: conflicting option string: --train というエラーがでます。このエラーは例えばflags.DEFINE_string('train', '/home/k・...の部分をflags.DEFINE_string('train002', '/home/k...など別の名前にするとエラーはなくなりました。 引き続き原因を探して行きたいと思います。回答ありがとうございました。
退会済みユーザー

退会済みユーザー

2017/07/03 12:15

>flags.DEFINE_string(... の部分は、tensorflowで使う変数を簡単に扱えるように定義している部分だと思います。 trainは学習用、testは検証用のリストですね。 >ArgumentError: argument --train: conflicting option string: --train 引数エラー:引数 --train: オプション文字列 --trainが衝突(カブって)います。 という意味ですので、確かにtrain002とすれば被らなくはなりますが、tensorflowが参照しない文字列になってしまう(無意味な定義)になってしまうと思います。 どういう状態かモヤーっとしていますが、一度pythonを落として再起動させたほうが良さそうですね。 k_mawa82さんが別の切り口から回答してくれていますので、そちらもご参照ください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問