Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
書籍転載:TensorFlowはじめました ― 実践!最新Googleマシンラーニング(7)

書籍転載:TensorFlowはじめました ― 実践!最新Googleマシンラーニング(7)

TensorFlowによる評価 ― 画像を分類するCIFAR-10の基礎

2016年8月23日

転載7回目(最終回)。CIFAR-10データセットを使った学習と評価を行う。「学習」(=訓練)が終わったので、今回は「評価」について説明する。「第2章 CIFAR-10の学習と評価」は今回で完結。

有山 圭二
  • このエントリーをはてなブックマークに追加

書籍転載について

 本コーナーは、インプレスR&D[Next Publishing]発行の書籍『TensorFlowはじめました ― 実践!最新Googleマシンラーニング』の中から、特にBuild Insiderの読者に有用だと考えられる項目を編集部が選び、同社の許可を得て転載したものです。

 『TensorFlowはじめました ― 実践!最新Googleマシンラーニング』(Kindle電子書籍もしくはオンデマンドペーパーバック)の詳細や購入はAmazon.co.jpのページをご覧ください。書籍全体の目次は連載INDEXページに掲載しています。プログラムのダウンロードは、「TensorFlowはじめました」のサポート用フォームから行えます。

ご注意

本記事は、書籍の内容を改変することなく、そのまま転載したものです。このため用字用語の統一ルールなどはBuild Insiderのそれとは一致しません。あらかじめご了承ください。

2.4 評価(evaluate)

 学習によるlogitsの値の変化は期待通りのものでした。しかし、ここまでの良好な結果は「過学習」である可能性を否定できません。

 「過学習」とは、学習したことのあるデータ(画像)については正しい答えが出せても、未知のデータに対して正しい答えを返すことができない状態を言います。未知のデータに対しても正しい答えが出せる「汎化性能」を得ていることを確認するために、「評価用のデータセット」は「学習用のデータセット」と分離されている必要があります。

 CIFAR-10には、評価用のデータセットtest_batch.binが用意されています。

図2.7: logitsとlabelから結果を判定するin_top_k

 リスト2.16は、推論の結果logitsと、label_placeholderで与えられる正解データを元に、推論が正解かそうでないかを判定するオペレーション(tf.nn.in_top_k)をグラフに追加します。

 また、コマンドラインの引数(FLAGS)にテストデータを指定する「--test_data」を追加しています。

Python
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_integer('epoch', 30, "訓練するEpoch数")
tf.app.flags.DEFINE_string('data_dir', './data/', "訓練データのディレクトリ")
tf.app.flags.DEFINE_string('checkpoint_dir', './checkpoints/',
                          "チェックポイントを保存するディレクトリ")
tf.app.flags.DEFINE_string('test_data', None, "テストデータのパス")

def main(argv=None):
  global_step = tf.Variable(0, trainable=False)
  
  train_placeholder = tf.placeholder(tf.float32,
                                     shape=[32, 32, 3],
                                     name='input_image')
  label_placeholder = tf.placeholder(tf.int32, shape=[1], name='label')
  
  # (width, height, depth) -> (batch, width, height, depth)
  image_node = tf.expand_dims(train_placeholder, 0)
  
  logits = model.inference(image_node)
  total_loss = _loss(logits, label_placeholder)
  train_op = _train(total_loss, global_step)
  
  top_k_op = tf.nn.in_top_k(logits, label_placeholder, 1)
  
  with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    
    total_duration = 0
    
    for epoch in range(1, FLAGS.epoch + 1):
      start_time = time.time()
      
      for file_index in range(5):
        print('Epoch %d: %s' % (epoch, filenames[file_index]))
        reader = Cifar10Reader(filenames[file_index])
        
        for index in range(10000):
          image = reader.read(index)
          
          _, loss_value = sess.run([train_op, total_loss],
                                   feed_dict={
                                     train_placeholder: image.byte_array,
                                     label_placeholder: image.label
                                   })
          
          assert not np.isnan(loss_value), \
            'Model diverged with loss = NaN'
        
        reader.close()
      
      duration = time.time() - start_time
      total_duration += duration
      
      prediction = _eval(sess, top_k_op,
                         train_placeholder, label_placeholder)
      print('epoch %d duration = %d sec, prediction = %.3f'
            % (epoch, duration, prediction))
      
      tf.train.SummaryWriter(FLAGS.checkpoint_dir, sess.graph)
    
    print('Total duration = %d sec' % total_duration)
リスト2.16: train_with_eval.py

 リスト2.17は、オペレーションtop_k_opを実行する関数です。引数のセッション(sess)内で評価を実行します。

Python
def _eval(sess, top_k_op, input_image, label_placeholder):
  if not FLAGS.test_data:
    return np.nan
  
  image_reader = Cifar10Reader(FLAGS.test_data)
  true_count = 0
  for index in range(10000):
    image = image_reader.read(index)
    
    predictions = sess.run([top_k_op],
                           feed_dict={
                             input_image: image.image,
                             label_placeholder: image.label
                           })
    true_count += np.sum(predictions)
  image_reader.close()
  
  return (true_count / 10000.0)
リスト2.17: train_with_eval.py

 プログラムを実行すると、エポック終了ごとに評価を実行して正答率(predictions)を表示します。

$ python3 train.py --test_data ./data/test_batch.bin
epoch 1 duration = 1028 sec, prediction = 0.354
epoch 2 duration = 1012 sec, prediction = 0.364
epoch 3 duration = 1045 sec, prediction = 0.404

 表2.1は、30エポック実行した際の各エポックの正答率です。

エポック 1 2 3 4 5 10 15 20 30
正答率(%) 39.4 39.8 39.2 38.8 42.6 39.8 38.9 41.1 35.8
表2.1: テストデータでの正答率

 以上、「CIFAR-10データセットを使った学習と評価」について説明しました。転載は今回をもって完結です。

※以下では、本稿の前後を合わせて5回分(第3回~第7回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

書籍転載:TensorFlowはじめました ― 実践!最新Googleマシンラーニング(7)
3. TensorFlowの“テンソル(Tensor)”とは? TensorBoardの使い方

転載3回目。テンソル(Tensor)とTensorBoardによるグラフの可視化を解説する。「第1章 TensorFlowの基礎」は今回で完結。

書籍転載:TensorFlowはじめました ― 実践!最新Googleマシンラーニング(7)
4. TensorFlowでデータの読み込み ― 画像を分類するCIFAR-10の基礎

転載4回目。今回から「畳み込みニューラルネットワーク」のモデルを構築して、CIFAR-10のデータセットを使った学習と評価を行う。今回はデータの読み込みを説明。

書籍転載:TensorFlowはじめました ― 実践!最新Googleマシンラーニング(7)
5. TensorFlowによる推論 ― 画像を分類するCIFAR-10の基礎

転載5回目。CIFAR-10データセットを使った学習と評価を行う。画像データの読み込みが終わったので、今回は画像の種類(クラス)を判別、つまり「推論」について説明する。

書籍転載:TensorFlowはじめました ― 実践!最新Googleマシンラーニング(7)
6. TensorFlowによる学習 ― 画像を分類するCIFAR-10の基礎

転載6回目。CIFAR-10データセットを使った学習と評価を行う。「推論」(=画像の種類・クラスを判別)が終わったので、今回は「学習」(=訓練)について説明する。

書籍転載:TensorFlowはじめました ― 実践!最新Googleマシンラーニング(7)
7. 【現在、表示中】≫ TensorFlowによる評価 ― 画像を分類するCIFAR-10の基礎

転載7回目(最終回)。CIFAR-10データセットを使った学習と評価を行う。「学習」(=訓練)が終わったので、今回は「評価」について説明する。「第2章 CIFAR-10の学習と評価」は今回で完結。

サイトからのお知らせ

Twitterでつぶやこう!