学習にあまり時間がかからない、データセットが豊富にある場合はモデルを一から学習させることは問題ではないのですが、そうではない場合はこれらの方法では望む結果が得られないことがあります。今回はそのような事態に陥った際に使える手法として、「学習済みモデル」と呼ばれるものを利用し、身の回りにある物の写真を適切に分類するタスクに取り組みたいと思います。
Contents
学習済みモデルを使った文房具の分類
本演習ではニューラルネットワークを用いた画像分類を実際に体験してもらいます。
ImageNetは学術用の大規模なカラー写真の画像データベースであり、オープンソースとして公開されています。2010年から2017年あたりまで、ILSVRCと呼ばれる画像認識の競技で、ImageNetの画像から一部の画像をどれだけ正確に分類できるか競われてきました。現在は高速計算を可能にするGPUと呼ばれるツールをある程度無料で利用をできるサービスがあります。しかし、高精細な画像を精度良く分類するにあたっては計算コストと時間が莫大にかかるため、今回はImageNetで事前に学習された学習済みモデルを使って画像分類を体験してもらおうと思います。
深層学習の実装の手助けをしてくれるライブラリーは世の中にいくつかあります。今回はその中でもGoogle社が開発したTensorFlowと呼ばれるライブラリーを使います。使い方を全部知らなくても課題に取り組むことができるので安心してください。
では、TensorFlowを使うためにPythonのスクリプト上でTensorFlowをインポートします。
モデルの読み込み
ImageNetでトレーニングされたモデルはいくつもあり、そのモデルの中からいくつかを選んで使ってみましょう。今回はモデルを3つ用意したので、この中から好きなものを選んで利用してください。使わないモデルは#を冒頭につけてコメントアウトしてください。
今回はdensenet121,densenet169, densenet201と呼ばれるCNNモデルを利用します。densenetモデルの構造を下に示します。何層ものの畳み込み層から構成され、通常の畳み込みに加えて、それぞれのレイヤーが繋がっている構造になっていることが分かれば十分です。
DenseNet以外に使ってみたいモデルがあったら、このリンクから調べてみてください。
ではTensorFlowでモデルを読み込みましょう。以下の記述を参考にしてください。モデルの読み込みを行い、モデルの構造を確認します。
画像の選択ならびに前処理
まずは推論したい画像を選択します。今回は象の画像を用いて、機械が「elephant(象)」と正しく予測できるかを確認したいと思います。まず始めに、使うネットワークの構造上、使う画像の形状を変換したりなどの前処理が必要となります。以下行っている処理は全て理解する必要はなく、参考程度に留めておくことをおすすめします。
上で行っている処理は、
1. 画像の読み込み
#画像を読み込む
img = tf.keras.preprocessing.image.load_img('/mnt/lib/ztodataset/trained_model/image/elephant.jpg',target_size=(224,224))
2. Numpy Arrayと呼ばれる配列に変換
#読み込んだ画像をnumpy arrayに変換する
img = tf.keras.preprocessing.image.img_to_array(img)
3. データの形状の変形
#画像の形状を(batch,h,w,channel)に拡張する(これがないとエラーが起こる)
img = img[tf.newaxis]
4. 画像の正規化(平均を0, 分散を1にする処理)
#画像の正規化(平均が0,分散が1になるようにデータを変形すること)
mean = np.mean(img)
std = np.std(img)
img_scale = (img-mean)/std
の4つです。ニューラルネットワークに学習をさせる前に行う必要のある大切な前処理です。
学習済みモデルで推論してみる
ここまでモデルの読み込みやデータの準備を行いました。では次に、持ってきた画像が正しく分類されるか確認してみましょう。
持ってきた画像の分類は上手くいったようです。では、他のモデルを用いた場合は、結果はどのくらい異なるのでしょうか?上のコメントアウトされているモデルでも試してみてください。
学習済みモデルを用いたタスクについて
以下、参考までに学習済みモデルを用いたタスクの応用について紹介します。
転移学習
定義に従って説明すると、ある領域で学習したモデルを別の領域に適合させる手法を転移学習と呼びます。説明がやや抽象的であるため、具体例を挙げて説明したいと思います。
図3の真ん中の図は、通常の一から作成したネットワークを表します。学習済みモデルを用いた転移学習モデルは、学習済みモデル由来の層を重ね、そのまま出力を返すのではなく、分類タスクによって層を追加します。これにより、例えば100クラス分類用のモデルから10クラス分類用のモデルを作成することができます。注意としては、分類させたい画像を再学習させるとき、ベースとなる学習済みモデルの重みは固定して、最終層だけを学習させることです。メリットとしては、学習データが少ない時などに1からモデルを学習させるよりも高精度な結果を得られることです。今回の演習では、学習済みのモデルに追加で層を結合して追加層のみ再学習を行う転位学習の実装を行います。
ファインチューニング
転移学習とセットで登場する手法としてファインチューニングがあります。ファインチューニングは追加した最後層のみを学習させる転移学習と異なり、学習済みモデルの重みを初期値として、モデルを一部作り変えた上で全ての重みor重みの一部を再学習させます。これにより、特徴量抽出器の再学習が可能になります。図3において、2番目のConv&Pool層までの重みは固定したまま、その後に新たな畳み込み層を追加し、それ以降の層を再度学習させます。ファインチューニングのメリットとしては、ベースとなるモデル層をタスクに応じて変更することで、モデルを本来の性能を失わずに自分仕様にカスタマイズできる点です。これにより、作りたいモデルを1から学習させるコストを削減できます。
転位学習の実装
上で説明したタスクのうち、ベースとなる学習済みの層の後に別の層を加えて、異なる画像の分類問題に取り組んでみたいと思います。いわゆる転位学習の実装です。
今回分類させたい画像は、犬と猫のカラー画像です。(cifar10 と呼ばれる32×32の10クラスのカラー画像) ベースネットワークとしては、cifar10を学習させた畳み込みニューラルネットワークを用います。そして、犬と猫の2クラス分類を行うため、出力2層の全結合層を追加します。ベースとなるネットワークは再学習させないため、重みを固定し、最終層のみを再学習させます。そして、全く適合を行わない状態と転位学習を用いて適合を行った時を比較してみましょう。まずは、用いる画像がどのようなものなのか可視化してみましょう。
32×32ピクセルなので画質は荒いですが、犬と猫の画像を表示されたことがわかります。では、転位学習の実装を行います。
何も学習させず、学習済みモデルをそのまま使うと正答率は40~50%程度ですが、分類させる画像のラベル数に合わせて層を追加し、最終層のみを学習させると正答率は80%程度まで上がることがわかりました。転位学習では、このように学習済みのモデルを組み合わせて1から学習させることなく、そこそこの分類精度を手に入れることができます。
まとめ
今回は、ImageNetと呼ばれる巨大分類ネットワークを用いて、任意の画像の推論やそれを用いた転位学習に取り組みました。最後の演習では、転位学習のみ取り組みましたが、途中の特徴抽出の畳み込み層を一部再学習させるファインチューニングにも興味があれば取り組んでみて下さい。