図 2.11 : 誤差の変化 グリッドベースの物体検出 0.0040 0.0035 0.0030 0.0025 0.0020 0.0015 0.0010 0.0005 0 modelO be 凵 055 20000 0.00008 0.00007 0.00006 0.00005 0.00004 0.00003 0.00002 0.00001 0 20000 modelO IOC b55 60000 2 つの誤差は、概ね順調に下がっているように見えます。特に座標の誤差 (model@-toc ユ oss) は、確信度誤差 (modet@_label-loss) と比較して誤差が小さく、ステップ数を重ねるにつ れて下がっています。 次に、この学習済みモデルを使って、実際にイラスト画像から顔領域を検出します。 2.5 検証 リスト 2.14 は、画像を学習済みモデルに入力して結果を出力するプログラムです。 リスト 2.14 : eval_ssd. py import json nmport OS import numpy as np import tensorftow as tf from PIL import lmage, ImageDraw import box—util from tfbook_model import model@ as base—model # 使用するモデル from tfbook—model import model@ as model tf. app . ftags . FLAGS FLAGS tf. app. flags . DEF 工 NE—string('image_dir' , None, " 処理対象のディレクトリ " ) tf. app. flags. DEFINE—string('output—dir' , None, " 出力するディレクトリ " ) tf. app . flags . DEFINE—string('train_path' None, " 訓練結果のファイルバス " ) 48 第 2 章
リスト 2.12 : train_ssd. py def _init_optimizer(learning—rate) : return tf. train. AdamOptimizer(Iearning—rate=Iearning—rate) tf ・ app ・ flags tf ・ app ・ flags tf ・ app. flags tf ・ app ・ ftags tf ・ app . flags tf ・ app . flags リスト 2.13 は、これまで作成したプログラムを使ってモデルの学習を行います。 学習の実行 dataset_loader.load_ssd_dataset でデータセットを読み込み、 tf. train. shuffle ー batch を通してバッチサイズの数だけまとめます。 model-base. prepare-layers に与えて得た中間結果 ([batch-size, を、さらに model. output ユ ayers に与えて出力を得ます。 リスト 2.13 : train_ssd. py import OS import tensorftow as tf import numpy as np from tfbook_model import modet@ as model—base # 使用するモデル from tfbook_model import modet@ as modet 21 , 21 , 256 ] ) nmport FLAGS tf ・ app ・ dataset_loader tf. app . flags . FLAGS flags . DEF 工 NE . DEF 工 NE . DEFINE . DEFINE . DEFINE . DEFINE . DEF 工 NE string( 'tfrecords_di None, " 学習データを出力したディレクトリ " ) string('train_dir' . /train' " 学習結果のディレクトリ " ) 32 , 、ニバッチのサイズ " ) float( 'learning—rate' integer( 'batch_size integer('capacity' , integer( 'min—after—dequeue' 600 , ー 1 , " 学習するステップ数 " ) integer( 'max—step' , 44 第 2 章グリッドベースの物体検出
Tensor("add 1:@" 3 3 3 , 4 ] ) 2 , 算できませんが、プロードキャスティングにより計算が可能になります。 リスト 1.18 のように、本来、一次元配列の arrayl とスカラーの valuel は、そのままでは計 スティングを使うと、形の異なる配列同士を自動的に変換して計算できます。 プロードキャスティング (Broadcasting) は、 NumPy5 で一般的な機能です。プロードキャ 1 .6 プロードキャスティング 置き換えられています。そのため、オペレーションを実行するまで値は得られません。 dtype=i nt32 ) であることに注意してください。演算子 + はオーバーロードで tf. add に shape=() , 度目の print(result2) で表示されるのが Tensor("add-1:@" resultl と resutt2 の結果は同じになりました。 nmport numpy as np リスト 1 . 1 8 : NumPy のプロードキャスティング shape=() , dtype=int32) arrayl valuel result np . a r ray ( [ 1 , 2 , 3 5 arrayl + valuel print(result) [ 6 7 8 9 ] TensorFlow にもプロードキャスティングの仕組みがあり、形の違う配列同士で演算するこ リスト 1 . 1 9 : TensorFlow のプロードキャスティング とができます ( リスト 1.19 ) 。 import tensorftow as tf 20 arrayl valuel result 第 1 章 tf. constant([l, tf. constant(5) TensorFlow の基礎 arrayl + valuel
writer. write(example. SeriaIizeToString()) 領域についてはすべて labet を 1 としています。これは筆者が作成したデータセットが、顔 をさらに分類してラベル付けしている ( 1 より上の値のラベルが存在する ) ためです。 変換の実行 リスト 2.9 は、画像とアノテーションを読み込んで TFRecord へ変換するプログラムです。 リスト 2.9 : create_dataset. py import OS import sys import gflags import numpy as np import tensorflow as tf from P 工 L import lmage import box_util from entity. region_list import RegionList # 使用するモデル from tfbook_model import model@ as model FLAGS = gflags . FLAGS gflags . DEFINE—string('base—dir' . /base—dir' " 処理する対象データのディレクトリ " ) gflags . DEF 工 NE—string('output—dir' . /output' "TFReco rd を出力するティレクトリ " ) , 256 , " 画像をリサイズする大きさ " ) gflags . DEFINE_integer( 'image_size' def _load_image(image—path, image_size) : return lmage. open(image—path) . convert( 'RGB' ) \ . resize((image_size, image_size) ) def _process—file(annotation—fite, output—di r) : dir OS . path. dirname(annotation_file) annotation = Annotation() annotation . load(annotation_file) 第 2 章グリッドベースの物体検出 37
リスト 1 . 1 : 足し算 # coding: UTF—8 from from from import constl const2 add—op future futu re_ future_ import absotute_import import division import print—function tf. add(constl, const2) tf. constant(3) tf. constant(2) tensorflow as tf with tf. Session() as sess: sess . run(add—op) result print(result) では、リスト 1.2 はどうでしようか リスト 1.2 : add_op を print 文で表示 定数 constl と c 。 nst2 を加算しています。実行すると「 2 + 3 」の結果「 5 」が表示されます。 constl const2 add—op tf. constant(2) tf. constant(3) tf. add(constl, const2) print(add—op) shape=(), dtype=int32) Tensor("Add:@" ドを「オペレーション (Operation: op ) 」と呼びます。 グラフは Tensor オプジェクトの「ノード」で構成されます。 TensorFIow では、これらのノー 繰り返しになりますが、 TensorFlow の処理は「データフローグラフ」として構築します。 グラフとノード、オペレーション 同様です。そのまま print しても、計算結果の値は表示されません。 文字列が表示され、加算した結果は得られませんでした。定数 c 。 nstl や c 。 nst2 についても 8 第 1 章 TensorFlow の基礎
name リスト 2.10 は、 TFRecord 形式のデータセットを読み込むプログラムです。 うようにするには、モデルに画像を入力すると、顔の確信度と座標を出力するように「学習 ( 訓 モデルを定義しただけでは、期待するとおりの機能 ( 物体検出 ) は果たしません。目的に適 2.4 学習 ( 訓練 ) -image-size [ 画像をリサイズする大きさ ] -output—dir [TFRecord を出力するディレクトリ ] \ -base-dir [ 処理する対象データのディレクトリ ] \ $ python create—dataset ・ py \ リスト 2.9 のプログラムは、次のように実行します。 のとして含んでいるためです。 ともとのデータセットが画像分類のために作成したもので、顔と誤認識した領域を負例 (labet Annota ⅱ on を読み込んだあと labet が@ より大きい Region のみフィルターしているのは、も main(sys. argv) 学習は、次の手順で行います。 練 ) 」する必要があります。 4 . 学習の実行 3 . 最適化アルゴリズムの設定 2 . 誤差関数の定義 データセットの読み込み m a 1 n 1 . def —get—filelist(path) : import tensorflow as tf import OS リスト 2.10 : dataset 」 oader. py データセットの読み込み return [ ] if not os. path. isdir(path): 40 第 2 章 グリッドベースの物体検出
図 27 : 画像とアノテーション 0 left top right bottom 5- 1 -0 5- ( 0 1 8 「′ 1 っ ~ 8 ・て C V 0 ・ 1 宀 0 ↓し C 0 ・ 1 0 っっ 5 ) 【 0 っ 4 ② -. 0 っ っ 4 4 つ」 4 . C V 0 ・ 1 0 7 ・つ」 1 7 ・ 5 7 4- (D 51 -2 4 へ 0 4 . C V 0 ・ 1 一 0 7 1 ② 24X1 ② 24 リスト 2.3 は、アノテーションを読み込むクラス Annotation です。ファイル名 (file_name) の他に、座標とラベルの組み合わせである Region クラスのリストがあります。 リスト 2.3 : entity/annotation. py import json class Annotation(object) : file_name None None regnons def load(setf, file_path) : self. regions with open(fite_path, mode=' r' json—object json ユ oad(fp) self. file_name json—object['file—name'] encoding='utf8') as fp: region_tist json—object. get( ' regions' None) if not region—list: return 第 2 章グリッドベースの物体検出 29
3.3 モテルの定義 [ 6 , 6 ] , [ 3 , 3 ] , [ 2 , 2 ] , 図 3.10 : モデル構造 21 x21 X256 conv 3X3X2 stride 2 conv 3X3X256 stride 2 conv 3X3X2 stride 2 conv 3X3X256 stride 2 SigmoidfTanh 21X21X5 11X11X5 6X6X5 。 1XIX5 conv stride 2 ロ 2X2X5 ロ 3X3X5 conv lxlx ( 4 + 1 ) リスト 3.2 の output_tayers は、モデルを構築します。 output ユ ayers は、 prepare ユ ayers で得た中間結果を繰り返し畳み込んで、各段階の特 徴マップから確信度と座標の組み合わせを出力します ( 図 3.10 ) 。出力するグリッドのサイズは 1 NUM_CLASSES NAME 'modell' import tensorflow as tf リスト 3.2 : tfbook_model/modell . py OUTPUT_SHAPES で定義しています。 工 NPUT 工 MAGE OUTPUT_SHAPES 1 ] , 11 ] , [ 21 , 21 ] , [ 1 , [ 11 , 192 第 3 章 物体認識奮闘記
現在は YOLO (You On ツ Look Once)l や SSD (SingIe Shot MuItiBox Detector) と いった手法が発表されていて、検出と分類を 1 つのネットワークで行うことができます。 本書では、 TensorFlow を使ってイラスト画像から顔を検出する機械学習のモデルを作成し モデルは、次の手順で作成します。 0 4 . 検証 3 . 学習 データセットの作成 モデルの定義 2 . 1 . リングを経て [ 21 , 21 , 256 ] の中間結果を返します。 output_tayers は、 prepare_layers prepare-layers は、縦横 192PX (INPUT-IMAGE で定義 ) の画像を入力すると、畳み込みとプー を構築します。 リスト 2.1 の prepare_layers と output_layers は、本書で使う物体検出のモデル ( 図 2.2 ) 2.2 モデルの定義 で得た中間結果を元に [ 21 , 21 , 5 ] を出力します。 図 2.2 : モテル構造 ReLU ReLU ReLU ReLU 2X2 stnde 2 ReLlJ 3X3X256 conv conv 2X2 3X3X64 3X3X64 stride 2 リスト 2.1 : tfbook_modeI/modelO. py nmport tensorftow as 'modet@' NAME NUM_CLASSES 1 conv 3X3X128 3X3X128 conv tf INPUT_IMAGE OUTPUT_SHAPES [ 21 , 21 ] , 192 ReLU 3X3X256 第 2 章 Sigmoid conv 21X21X5 conv 1XIX4 Tanh グリッドベースの物体検出 23