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

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

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

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

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

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

解決済

2回答

3811閲覧

TensorFlowでパッチ処理で精度計算を行い大量の画像を学習させたいです。

RSAM

総合スコア7

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

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

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

1クリップ

投稿2018/01/09 13:50

###前提・実現したいこと
TensorFlowを使って2つの画像の分類を行っています.
DeepLearningを用いるということで,10000枚程度のデータを学習したいと思っています.

###発生している問題・エラーメッセージ
メモリが足りていないため,7000枚ほど画像を使用すると

ResourceExhaustedError

というエラーが生じます.
そこで学習のみに行っていたバッチ処理を,学習,テスト精度計算にも行いたいのですがコードを変えた結果,以下のように実行されて学習がうまくできていないと思われるエラーが生じました.

step 0, training accuracy 1 test accuracy 0.5 20.000 sec step 1, training accuracy 1 test accuracy 0.5 23.360 sec step 2, training accuracy 1 test accuracy 0.5 26.485 sec step 3, training accuracy 1 test accuracy 0.5

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

Python

1import sys 2sys.path.append('/usr/local/opt/opencv3/lib/python3.5.4/site-packages') 3import cv2 4import numpy as np 5import tensorflow as tf 6import tensorflow.python.platform 7import tensorboard as tb # -> 追加 #https://qiita.com/kegamin/items/887c7dfe8bbb76197741 8import os 9import math 10import time 11start_time = time.time() 12 13# TensorBoard情報出力ディレクトリ 14log_dir = '/tmp/data1' #tensorboard --logdir=/tmp/data1 15 16#指定したディレクトリがあれば削除し、再作成 17if tf.gfile.Exists(log_dir): 18 tf.gfile.DeleteRecursively(log_dir) 19tf.gfile.MakeDirs(log_dir) 20 21NUM_CLASSES = 2 22IMAGE_SIZE_x = 48 23IMAGE_SIZE_y = 36 24IMAGE_CHANNELS = 3 25IMAGE_PIXELS = IMAGE_SIZE_x*IMAGE_SIZE_y*IMAGE_CHANNELS 26OUTPUT_SIZE_x = IMAGE_SIZE_x // 4 27OUTPUT_SIZE_y = IMAGE_SIZE_y // 4 28 29flags = tf.app.flags 30FLAGS = flags.FLAGS 31flags.DEFINE_string('train', 'train.txt', 'File name of train data') 32flags.DEFINE_string('test', 'test.txt', 'File name of train data') 33flags.DEFINE_string('image_dir', 'data', 'Directory of images') 34flags.DEFINE_string('train_dir', '/tmp/data', 'Directory to put the training data.') 35flags.DEFINE_integer('max_steps', 5000, 'Number of steps to run trainer.') 36flags.DEFINE_integer('batch_size', 10, 'Batch size' 37 'Must divide evenly into the dataset sizes.') 38flags.DEFINE_float('learning_rate', 1e-5, 'Initial learning rate.') 39 40# 予測モデルを作成する関数 41def inference(images_placeholder, keep_prob): 42 43 # 重みを標準偏差0.1の正規分布で初期化 44 def weight_variable(shape): 45 initial = tf.truncated_normal(shape, stddev=0.1) 46 return tf.Variable(initial) 47 48 # バイアスを標準偏差0.1の正規分布で初期化 49 def bias_variable(shape): 50 initial = tf.constant(0.1, shape=shape) 51 return tf.Variable(initial) 52 53 # 畳み込み層の作成 54 def conv2d(x, W): 55 return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') 56 57 # プーリング層の作成 58 def max_pool_2x2(x): 59 return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], 60 strides=[1, 2, 2, 1], padding='SAME') 61 62 # 入力を変形 63 x_image = tf.reshape(images_placeholder, [-1, IMAGE_SIZE_x, IMAGE_SIZE_y, IMAGE_CHANNELS]) 64 65 # 畳み込み層1の作成 66 # 畳み込み層のフィルタ重み、引数はパッチサイズ縦、パッチサイズ横、入力チャネル数、出力チャネル数 67 # 5x5フィルタで32チャネルを出力(入力は白黒画像なので1チャンネル) 68 with tf.name_scope('conv1') as scope: 69 W_conv1 = weight_variable([5, 5, IMAGE_CHANNELS, 32]) 70 b_conv1 = bias_variable([32]) 71 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) 72 tf.summary.histogram("wc1", W_conv1) 73 # dropoutの設定 74 h_conv1_drop = tf.nn.dropout(h_conv1, 0.8) 75 76 # プーリング層1の作成 77 with tf.name_scope('pool2') as scope: 78 h_pool1 = max_pool_2x2(h_conv1_drop) 79 80 # 畳み込み層2の作成 81 with tf.name_scope('conv2') as scope: 82 W_conv2 = weight_variable([5, 5, 32, 64]) 83 b_conv2 = bias_variable([64]) 84 h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2) + b_conv2) 85 tf.summary.histogram("wc2", W_conv2) 86 87 # プーリング層2の作成 88 with tf.name_scope('pool2') as scope: 89 h_pool2 = max_pool_2x2(h_conv2) 90 91 # 全結合層1の作成 92 with tf.name_scope('fc1') as scope: 93 W_fc1 = weight_variable([OUTPUT_SIZE_x*OUTPUT_SIZE_y*64, 1024]) 94 b_fc1 = bias_variable([1024]) 95 h_pool2_flat = tf.reshape(h_pool2, [-1, OUTPUT_SIZE_x*OUTPUT_SIZE_y*64]) 96 h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) 97 # dropoutの設定 98 h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) 99 100 # 全結合層2の作成 101 with tf.name_scope('fc3') as scope: 102 W_fc2 = weight_variable([1024, NUM_CLASSES]) 103 b_fc2 = bias_variable([NUM_CLASSES]) 104 105 # ソフトマックス関数による正規化 106 with tf.name_scope('softmax') as scope: 107 y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) 108 109 # 各ラベルの確率のようなものを返す 110 return y_conv 111 112def loss(logits, labels): 113 """ lossを計算する関数 114 115 引数: 116 logits: ロジットのtensor, float - [batch_size, NUM_CLASSES] 117 labels: ラベルのtensor, int32 - [batch_size, NUM_CLASSES] 118 119 返り値: 120 cross_entropy: 交差エントロピーのtensor, float 121 122 """ 123 # 交差エントロピーの計算 124 cross_entropy = -tf.reduce_sum(labels*tf.log(tf.clip_by_value(logits,1e-10,1.0))) 125 # TensorBoardで表示するよう指定 126 tf.summary.scalar("cross_entropy", cross_entropy) 127 return cross_entropy 128 129def training(loss, learning_rate): 130 """ 訓練のOpを定義する関数 131 132 引数: 133 loss: 損失のtensor, loss()の結果 134 learning_rate: 学習係数 135 136 返り値: 137 train_step: 訓練のOp 138 139 """ 140 141 train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss) 142 return train_step 143 144def accuracy(logits, labels): 145 """ 正解率(accuracy)を計算する関数 146 147 引数: 148 logits: inference()の結果 149 labels: ラベルのtensor, int32 - [batch_size, NUM_CLASSES] 150 151 返り値: 152 accuracy: 正解率(float) 153 154 """ 155 correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1)) 156 accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) 157 tf.summary.scalar("accuracy", accuracy) 158 return accuracy 159 160if __name__ == '__main__': 161 f = open(FLAGS.train, 'r') 162 # データを入れる配列 163 train_image = [] 164 train_label = [] 165 for line in f: 166 # 改行を除いてスペース区切りにする 167 line = line.rstrip() 168 l = line.split() 169 # データを読み込んで縮小 170 img = cv2.imread(FLAGS.image_dir + '/' + l[0]) 171 img = cv2.resize(img, (IMAGE_SIZE_x, IMAGE_SIZE_y)) 172 # 一列にした後、0-1のfloat値にする 173 train_image.append(img.flatten().astype(np.float32)/255.0) 174 # ラベルを1-of-k方式で用意する 175 tmp = np.zeros(NUM_CLASSES) 176 tmp[int(l[1])] = 1 177 train_label.append(tmp) 178 # numpy形式に変換 179 train_image = np.asarray(train_image) 180 train_label = np.asarray(train_label) 181 f.close() 182 183 f = open(FLAGS.test, 'r') 184 test_image = [] 185 test_label = [] 186 for line in f: 187 line = line.rstrip() 188 l = line.split() 189 img = cv2.imread(FLAGS.image_dir + '/' + l[0]) 190 img = cv2.resize(img, (IMAGE_SIZE_x, IMAGE_SIZE_y)) 191 test_image.append(img.flatten().astype(np.float32)/255.0) 192 tmp = np.zeros(NUM_CLASSES) 193 tmp[int(l[1])] = 1 194 test_label.append(tmp) 195 test_image = np.asarray(test_image) 196 test_label = np.asarray(test_label) 197 f.close() 198 199 with tf.Graph().as_default(): 200 # 画像を入れる仮のTensor 201 images_placeholder = tf.placeholder("float", shape=(None, IMAGE_PIXELS)) 202 # ラベルを入れる仮のTensor 203 labels_placeholder = tf.placeholder("float", shape=(None, NUM_CLASSES)) 204 # dropout率を入れる仮のTensor 205 keep_prob = tf.placeholder("float") 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 saver = tf.train.Saver() 216 # Sessionの作成 217 sess = tf.Session() 218 # 変数の初期化 219 sess.run(tf.global_variables_initializer()) 220 # TensorBoardで表示する値の設定 221 summary_op = tf.summary.merge_all() 222 summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph) 223 224 225# 訓練の実行 226for step in range(FLAGS.max_steps): 227 for i in range(int(len(train_image)/FLAGS.batch_size)): 228 # batch_size分の画像に対して訓練の実行 229 batch = FLAGS.batch_size*i 230 # feed_dictでplaceholderに入れるデータを指定する 231 sess.run(train_op, feed_dict={ 232 images_placeholder: train_image[batch:batch+FLAGS.batch_size], 233 labels_placeholder: train_label[batch:batch+FLAGS.batch_size], 234 keep_prob: 0.5}) 235 # 1 step終わるたびに精度を計算する 236 train_accuracy = sess.run(acc, feed_dict={ 237 images_placeholder: train_image, 238 labels_placeholder: train_label, 239 keep_prob: 1.0}) 240 print("step %d, training accuracy %g" %(step, train_accuracy)) 241 242 # 1 step終わるたびにTensorBoardに表示する値を追加する 243 summary_str = sess.run(summary_op, feed_dict={ 244 images_placeholder: train_image, 245 labels_placeholder: train_label, 246 keep_prob: 1.0}) 247 summary_writer.add_summary(summary_str, step) 248 249 # テストデータに対する精度を表示 250 print(" test accuracy %g"%sess.run(acc, feed_dict={ 251 images_placeholder: test_image, 252 labels_placeholder: test_label, 253 keep_prob: 1.0})) 254 255 # step毎に経過時間を表示 256 duration = time.time() - start_time 257 print('%.3f sec' %duration) 258 259 # 最終的なモデルを保存 260 save_path = saver.save(sess, os.getcwd() + "\model.ckpt") 261

###試したこと
上記のコードで7000枚程度学習できることは確認しました.
より多くの画像を学習できるように訓練精度計算の部分で[batch:batch+FLAGS.batch_size]
を追加した結果,訓練精度が1と出力され続け,テスト精度計算の部分で[batch:batch+FLAGS.batch_size]を追加した結果,テスト精度がNanと表示され,エラーを吐かれました.
また,以下のサイトで示されているやりかたも試しましたが,どうもうまくいきませんでした.
TensorFlow 大量の画像から学習するには・・・〜(ほぼ)解決編〜
TensorFlowで大量のデータを学習する方法がわかりません

###補足情報(言語/FW/ツール等のバージョンなど)
開発環境
-Windows10(64bit)
-Python3.5.4(仮想環境)(Anaconda4.4.0(64bit))
-Tensorflow-gpu1.4.0
-NVIDIA Quadro P4000(8GB)

2値分類のコードはこちらを参照しました.

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

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

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

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

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

guest

回答2

0

■訓練精度
今の実相では、
train_accuracy = sess.run(acc, feed_dict={
となっているので、最後のバッチ一回で追加されずに上書きされてしまいそうです。

なので、まずは、
train_accuracy += sess.run(acc, feed_dict={
に修正してはいかがでしょうか

あとはこれをしようとすると、train_accuracyを初期化しないといけませんね。

■テスト精度
上のやり方でうまくいくようなら、train_accuracy 関係のコードをコピペして、trainという文字列をtestに置換して動かせばうまくいきそうです。

手元にデータはないので確認できませんが、以下のようなものを想定しています。

Python

1# 訓練の実行 2for step in range(FLAGS.max_steps): 3 # 訓練 4 ############################################# 5 train_accuracy = 0 6 for i in range(int(len(train_image)/FLAGS.batch_size)): 7 # batch_size分の画像に対して訓練の実行 8 batch = FLAGS.batch_size*i 9 # feed_dictでplaceholderに入れるデータを指定する 10 sess.run(train_op, feed_dict={ 11 images_placeholder: train_image[batch:batch+FLAGS.batch_size], 12 labels_placeholder: train_label[batch:batch+FLAGS.batch_size], 13 keep_prob: 0.5}) 14 15 # 1 batch終わるたびにデータを追加する 16 train_accuracy += sess.run(acc, feed_dict={ 17 images_placeholder: train_image, 18 labels_placeholder: train_label, 19 keep_prob: 1.0}) 20 21 # 1 step毎にデータを表示する 22 print("step %d, training accuracy %g" %(step, train_accuracy)) 23 24 # TensorBoard 25 ############################################# 26 # 1 step終わるたびにTensorBoardに表示する値を追加する 27 summary_str = sess.run(summary_op, feed_dict={ 28 images_placeholder: train_image, 29 labels_placeholder: train_label, 30 keep_prob: 1.0}) 31 summary_writer.add_summary(summary_str, step) 32 33 # テスト 34 ############################################# 35 # テストデータに対する精度を表示 36 test_accuracy= 0 37 for i in range(int(len(test_image)/FLAGS.batch_size)): 38 # batch_size分の画像に対して訓練の実行 39 batch = FLAGS.batch_size*i 40 # feed_dictでplaceholderに入れるデータを指定する 41 sess.run(acc, feed_dict={ 42 images_placeholder: test_image[batch:batch+FLAGS.batch_size], 43 labels_placeholder: test_label[batch:batch+FLAGS.batch_size], 44 keep_prob: 0.5}) 45 46 # 1 batch終わるたびにデータを追加する 47 test_accuracy += sess.run(acc, feed_dict={ 48 images_placeholder: test_image, 49 labels_placeholder: test_label, 50 keep_prob: 1.0}) 51 52 # 1 step毎にデータを表示する 53 print("step %d, testing accuracy %g" %(step, test_accuracy)) 54

投稿2018/01/09 22:16

編集2018/01/09 22:25
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/01/09 22:31

このコードの「テストのplaceholder」のあたりに違和感がありますね。チョッと難ありかもです。
RSAM

2018/01/10 05:58

ご意見ありがとうございます. train_accuracy = 0を,2つのforの後ろに入れて実装してみましたが(でないと,train_accuracyが100などと表示されてしまうので・・・)かかる時間が従来の10倍近くになり,やはり大量の画像の学習は厳しいようです. 補足ですが,テストデータではバッチ処理は不要かもしれません. 学習では数万枚オーダーの画像を用いたいと考えていますが,テストでは数百枚程度を用いようと考えております.
guest

0

ベストアンサー

①学習データをシャッフルしていますか?

②どのようなエラーですか?

③どのようにメモリに乗りませんか?
0. GPU
0. メイン

いずれにしろ、手動で何とかするのは大変なので、
https://qiita.com/ornew/items/8ca914d222ce068158c4
http://tech.wonderpla.net/entry/2017/10/24/110000
バッチサイズ・データの流れを簡単に制御できるようなものに乗り換えてみてはいかがでしょう。

投稿2018/01/09 14:01

mkgrei

総合スコア8560

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

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

RSAM

2018/01/09 14:10

回答ありがとうございます. ①学習データは1000枚の場合,1000枚の中からミニバッチ学習でシャッフルするようにはしていますが,1000枚はあらかじめこちらで選択しています(シャッフルしていません) ②エラーは以下のようなものです ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[37800,32,28,28] [[Node: Conv2D = Conv2D[T=DT_FLOAT, data_format="NHWC", padding="SAME", strides=[1, 1, 1, 1], use_cudnn_on_gpu=true, _device="/job:localhost/replica:0/task:0/gpu:0"](Reshape, Variable/read)]] ③GPUの方に乗りません.メインの方は1TBあるので余裕ですが,やはり時間がかかるので使用は避けたいですね… 最悪Kerasでの実装を検討しますが,やはりTensorFlowを使い続けているのでそちらでやっていきたいです。。。
mkgrei

2018/01/09 14:58

学習データ1000枚だと全部同じラベルになっていませんか? インデックスをシャッフルして、そこから1000個ずつ与えてみてはいかがでしょう。 8GBだと確かに1000枚程度が一度に乗る限界ですね。
RSAM

2018/01/10 06:03

すみません.知識不足で同じラベルというのが理解できていないです・・・ インデックスのシャッフルとは,あらかじめ数万枚の画像を用意してその中からランダムに1000枚ずつ学習させるということでしょうか. ちなみにGPUは2GBと8GBのものをこれまで用いましたが,どちらも7000枚程度が学習させられる限界でした.(メモリを増設しても,速度が速くなっただけで枚数の上限が増えた感じはあまりしませんでした.)
mkgrei

2018/01/10 06:55

Yがラベルです。 順番に読み込むと、最初の4500個が0で次の4500個が1だったりするのかどうかが質問の意図でした。 idx = np.arange(len(Y)) np.random.shuffle(idx) Y = Y[idx] X = X[idx] とするとことによってバッチ間のシャッフルができます。 ------------ GPUのメモリは一般的にはGPUに依存しているので増設というのが少し違和感があるのですが、Quadroをよく知らないのでこれ以上はわからないです。 ただ、2GBから8GBにすると乗る量が増えるはずです。 CNN自体に一部食われていることを考えると4倍以上の枚数を学習できるようになるはずです。 メインのほうが1TBというのはHDDのことでしょうか。 スパコンなどでも768GB/CPUとかしか聞いたことがなかったので、何か非常に特殊な環境を使われているのかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問