|
Kerasはニューラルネットワークの学習を容易にすために開発されたライブラリです。2015年に開発が開始されたKerasはTheanoをベースとして構築され、広く利用されているPythonで書かれたライブラリになっている。現在、Theano、Tensorflow及びCNTKなどをバックエンドとして利用できます。Kerasの標準インストールで、デフォルトでは、Tensorflowがバックエンドになっています。
KerasはPythonで書かれていますので、Pythonの基礎的な知識を持っている人を想定します。なお、anaconda等でPythonのモジュール一式がインストールされていることも前提とします。deep-learningの理論的な説明は、例えば、3層パーセプトロン(MLP)や畳み込みニューラルネットワーク(CNN)の説明は、Deep Learningと人工知能のページにありますので、併せて読むと理解が深まると思います。
GoogleのTensorFlow開発チームは2019年10月1日、オープンソースの機械学習ライブラリ TensorFlow 2 を公開しました。これにより、TensorFlow が大幅に改訂されて、version 1.x からversion 2.xに変更されました。Keras がTensorFLowのモジュールに統合されました。そして、それに対応しての関係でしょうが、TensorFlow 1.xで使用されていたいくつかの重要なモジュールが廃止されました。とりわけ、TensorFlow 2で、tf.contribが廃止された影響は大きいです。また、Keras がTensorFLowのモジュールに統合されましたので、従来のKeras単体でのコードが正常に動作しません。
このページでは、TensorFlow 2のもとで正常に作動するKerasを用いて、Deep Learning(CNN)のPython実装の例を説明します。特に、画像識別のアルゴリズムをPythonでコード化したライブラリの代表的な事例を取り上げて、機械学習プログラムの実装と実行について説明します。
python関連のパッケージなどの環境はセットアップされているとします。ここでは、macOS で実行していますが、TensorFlow 2 がインストールされていれば、Ubuntu および Windowsでも正常に作動すると思います。TensorFlow の公式ページにおけるPython開発環境の設定では、'virtualenv' を用いた 'Python virtual environments' を構築することが推奨されています。
プログラミング経験がまったくなく、とりあえず Tensorflow を体験してみたいという場合には、自身のPCにPythonをインストールする必要はありません。 Google Colaboratoryを使うと、WebブラウザからPythonを使えます。Google のアカウントが必要です。ただし、Jupyter Notebook 形式になっていますので、Jupyter Notebookの操作で戸惑うかもしれません。その場合には、Jupyter Notebook のページを読むことをお勧めします。
ここでは、GPUを搭載していないPCを前提にしているので、リアルタイムでの物体検出では、処理速度が遅く、画像の切り替わりがスムーズでないことはやむを得ません。また、動作確認は以下に明記されたTensorflowやKerasなどのバージョンで行っています。ソフトウエ環境は以下の通りです。
numpyのバージョンは1.20.3です scipyのバージョンは1.6.3です matplotlibのバージョンは3.4.2です PIL(Pillow)のバージョンは8.2.0です kerasのバージョンは2.8.0です tensorflowのバージョンは2.8.0です pandasのバージョンは1.2.4です sklearnのバージョンは0.24.2です
このページに説明されるコードはすべて、私のGitHubのrepoにあります。そこにあるプログラムはすべて Google Colab にて実行可能です。
Last updated: 2022.9.20( First uploaded 2018.4.22)
Tensorflow 2.0のインストール |
Tensorflow のインストールでは、Python の仮想環境を構築することが推奨されていますが、ここでは仮想環境の構築は済んでいるとします。Python の仮想環境の構築についての説明は、このページを参照ください。
システムPython を使用するケース、または、仮想環境を利用すケースを含めて、Python 3.9.4 がインストールされているとします。python を起動します。
$ python Python 3.9.4 (default, May 15 2021, 14:49:04) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
以下のようなコマンドを入力してtensorflow 2 をインストールします。
$ pip install --upgrade tensorflow
この入力で、TensorFlowのパッケージは ~/site-packages/tensorflow/にインストールされます。
TensorFlow のバージョン確認をします。
$ python -c "import tensorflow as tf; print( tf.__version__ )"
次に、Keras のバージョン確認もします。
$ python -c "import keras; print( keras.__version__ )"
kerasでモデルの保存を行うためにはHDF5が必要となるので、そのためのパッケージもインストールします。
$ pip install h5py
さらに、構成したモデルを可視化して、そのグラフを描画するためには、graphvizとpydotを利用する必要があります。それらのパッケージは
$ pip install graphviz $ pip install pydot
とインストールします。
keras.Sequentialモデルを用いた手書き数値の識別 |
Tensorflowの公式サイトにあるtutorialsに沿って説明します。TensorFlowのモデルを構築し訓練するためのハイレベルのAPIである tf.kerasを使用します。tf.keras.Sequential モデルを用いた最も単純な例は以下のように書けます。第1行目の、
from __future__ import absolute_import, division, print_function, unicode_literals
はこうするのが慣例だと思って下さい。
from __future__ import absolute_import, division, print_function, unicode_literals from tensorflow.keras import datasets, layers, models mnist = datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 model = models.Sequential() model.add(layers.Flatten(input_shape=(28, 28))) model.add(layers.Dense(128, activation='relu')) model.add(layers.Dropout(0.2)) model.add(layers.Dense(10, activation='softmax')) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.fit(x_train, y_train, epochs=5) model.evaluate(x_test, y_test, verbose=2)
ネットワークは4層のlayersから構成されます。model = Sequential()で、Sequentialモデルを用いた具体的なモデル名をmodelとします。簡単にネットワークのレイヤーを積み重ねて、モデルを構築します。Flatten(input_shape=(28, 28))は入力サイズが28✖️28の2次元データを1次元にフラットにします。Dense(128, activation='relu')は、128個のニューロンが隣接する層と全結合されたレイヤで、活性化関数がRelu関数であることを意味します。Dense(units=10, activation='softmax')は、追加される第4層が10個のニューロンからなる全結合層で、活性化関数がsoftmax関数であることを示します。Dropoutはディープラーニングの過学習を防ぐために行います。Dropoutは、隣接層のニューロンとのつながりをランダムに切断してあげることで、過学習を防ぎます。0.2という数字は、その切断するニューロンの割合を示しています。訓練時には、データが読み込まれるごとにニューロンはランダムに切断されます。
compile()で、以上で指定された4層のレイヤをもつニューラルネットワークに損失関数と学習方法を指定して、モデルを完成させ、このモデルを用いた訓練(学習)プロセスを設定します。損失関数は交差エントロピー、最適化手法はadamを指定しています。loss='mean_squared_error'と指定すると二乗和誤差関数を使用されます。この例で指定されている'categorical_crossentropy'を使用するためには、データ(x_train,y_train)を'to_categorical'でone-hot形式にする前処理が必要です。損失関数の最小点を検索するための最適化手法にはいくつかの種類があります。SGD(stochastic Gradient Descent)は最も単純なアルゴリズムで、RMSprop、Adagrad, Adadelta、Adamなどのアルゴリズムが利用可能です。これらの詳細については、ディープラーニングの参考書などを参照ください。
この後、fit()メソッドを用いて、epochs数とbatch_sizeの大きさを与えて、モデルのパラメータ値の訓練(学習)をします。訓練データは教師ラベル付きの(x_train,y_train)です。y_trainが教師ラベルです。mnistデータはmnist.load_data() で読み込んでいます。
上記のコードを実行すると、以下のように、エポックごとに学習の計算結果が表示されます。
Train on 60000 samples Epoch 1/5 60000/60000 [==============================] - 4s 73us/sample - loss: 0.2952 - accuracy: 0.9145 Epoch 2/5 60000/60000 [==============================] - 5s 82us/sample - loss: 0.1409 - accuracy: 0.9575 Epoch 3/5 60000/60000 [==============================] - 4s 66us/sample - loss: 0.1086 - accuracy: 0.9672 Epoch 4/5 60000/60000 [==============================] - 4s 72us/sample - loss: 0.0861 - accuracy: 0.9730 Epoch 5/5 60000/60000 [==============================] - 4s 72us/sample - loss: 0.0743 - accuracy: 0.9766 10000/1 - 0s - loss: 0.0415 - accuracy: 0.9761 [0.07995059116524644, 0.9761]
次に、MNIST データを用いて、手書き数値の分類をするための、上記のネットワークよりは少し高度な畳み込みニューラルネットワーク (CNN: Convolutional Neural Network) を用いた学習について説明します。このネットワークは MNIST テストセットにおいて、99%以上の精度を達成します。tf.Keras.Sequential APIを使用するため、ほんの数行のコードでモデルの作成と学習を行うことができます。以下にコードを紹介します。モデルは8層のネットワーク層から構成されています。
from __future__ import absolute_import, division, print_function, unicode_literals from tensorflow.keras import datasets, layers, models (train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data() train_images = train_images.reshape((60000, 28, 28, 1)) test_images = test_images.reshape((10000, 28, 28, 1)) # ピクセルの値を 0~1 の間に正規化 train_images, test_images = train_images / 255.0, test_images / 255.0 model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.Flatten()) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(10, activation='softmax'))
ネットワーク層のモデルを完成するために、Conv2D(64, (3, 3), activation='relu'))層の後に、ネットワーク層が3層追加されています。(shape (3, 3, 64) の) 畳み込みの基礎部分からの最後の出力テンソルを、1つ以上の Dense レイヤーに入れて分類を実行します。現在の出力は 3D テンソルですが、Dense レイヤーは入力としてベクトル (1D) を取ります。まず、3D 出力を 1D に平滑化 (または展開) してから、最上部に1つ以上の Dense レイヤーを追加します。MNIST は 10 個の出力クラスを持ちます。そのため、我々は最後の Dense レイヤーの出力を 10 にし、softmax関数を使用します。
model.summary()
# opuput Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 26, 26, 32) 320 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 11, 11, 64) 18496 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 3, 3, 64) 36928 _________________________________________________________________ flatten (Flatten) (None, 576) 0 _________________________________________________________________ dense (Dense) (None, 64) 36928 _________________________________________________________________ dense_1 (Dense) (None, 10) 650 ================================================================= Total params: 93,322 Trainable params: 93,322 Non-trainable params: 0 _________________________________________________________________
モデルの構造がよく理解できます。以下の通りに、モデルをコンパイルして、学習する。
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.fit(train_images, train_labels, epochs=5)
結果は次の通りです。
Train on 60000 samples Epoch 1/5 60000/60000 [==============================] - 39s 643us/sample - loss: 0.1437 - accuracy: 0.9553 Epoch 2/5 60000/60000 [==============================] - 43s 718us/sample - loss: 0.0470 - accuracy: 0.9851 Epoch 3/5 60000/60000 [==============================] - 48s 800us/sample - loss: 0.0334 - accuracy: 0.9897 Epoch 4/5 60000/60000 [==============================] - 47s 776us/sample - loss: 0.0257 - accuracy: 0.9920 Epoch 5/5 60000/60000 [==============================] - 44s 734us/sample - loss: 0.0209 - accuracy: 0.9932
シンプルなモデルですが、相当に正確な識別ができます。
keras.Sequentialモデルを用いた画像の識別 |
ここでは、tf.keras.Sequential modelを用いてイメージ画像から動物を識別する方法について説明します。 Convolutional Neural Network (CNN) を使用して、CIFAR images の分類問題を取り上げます。 CIFAR-10は、airplane(飛行機)、automobile(自動車)、bird(鳥)、cat(猫)、deer(鹿)、dog(犬)、frog(カエル)、horse(馬)、ship(船)、truck(トラック)の10種類のいずれかが写っている写真を集めて、ラベルをつけたデータセットです。各種類(クラス)当たり60,000 color images 画像があります。詳しくは、https://www.cs.toronto.edu/~kriz/cifar.htmlを参照ください。
データセットには、 訓練用として 50,000 training images 、検証用とし 10,000 testing imagesが用意されています。Kerasにはこのデータセットを読み込むコードが付録しています
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf from tensorflow.keras import datasets, layers, models import matplotlib.pyplot as plt (train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data() # Normalize pixel values to be between 0 and 1 train_images, test_images = train_images / 255.0, test_images / 255.0
と入力すると、cifar10のデータセットが読み込まれます。内容を見てみるために、以下のように入力します。
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] plt.figure(figsize=(10,10)) for i in range(25): plt.subplot(5,5,i+1) plt.xticks([]) plt.yticks([]) plt.grid(False) plt.imshow(train_images[i], cmap=plt.cm.binary) # The CIFAR labels happen to be arrays, # which is why you need the extra index plt.xlabel(class_names[train_labels[i][0]]) plt.show()
25枚の画像が表示されます。画像はかなり不鮮明です。CNNモデルを作成し、学習するために、以下のコード作成します。cifarの画像のshapeは(32, 32, 3)です。
model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.Flatten()) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(10, activation='softmax')) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) history = model.fit(train_images, train_labels, epochs=10, validation_data=(test_images, test_labels))
Train on 50000 samples, validate on 10000 samples Epoch 1/10 50000/50000 [==============================] - 11s 222us/sample - loss: 1.5684 - accuracy: 0.4266 - val_loss: 1.2367 - val_accuracy: 0.5543 Epoch 2/10 50000/50000 [==============================] - 7s 130us/sample - loss: 1.1648 - accuracy: 0.5879 - val_loss: 1.1616 - val_accuracy: 0.5853 Epoch 3/10 50000/50000 [==============================] - 6s 130us/sample - loss: 1.0314 - accuracy: 0.6379 - val_loss: 1.0190 - val_accuracy: 0.6374 Epoch 4/10 50000/50000 [==============================] - 6s 129us/sample - loss: 0.9382 - accuracy: 0.6711 - val_loss: 0.9656 - val_accuracy: 0.6617 Epoch 5/10 50000/50000 [==============================] - 6s 129us/sample - loss: 0.8650 - accuracy: 0.6970 - val_loss: 0.9005 - val_accuracy: 0.6870 Epoch 6/10 50000/50000 [==============================] - 6s 129us/sample - loss: 0.8054 - accuracy: 0.7183 - val_loss: 0.9217 - val_accuracy: 0.6748 Epoch 7/10 50000/50000 [==============================] - 7s 131us/sample - loss: 0.7557 - accuracy: 0.7356 - val_loss: 0.9336 - val_accuracy: 0.6858 Epoch 8/10 50000/50000 [==============================] - 7s 132us/sample - loss: 0.7145 - accuracy: 0.7514 - val_loss: 0.9107 - val_accuracy: 0.6906 Epoch 9/10 50000/50000 [==============================] - 7s 134us/sample - loss: 0.6758 - accuracy: 0.7647 - val_loss: 0.8696 - val_accuracy: 0.7077 Epoch 10/10 50000/50000 [==============================] - 6s 130us/sample - loss: 0.6410 - accuracy: 0.7757 - val_loss: 0.8684 - val_accuracy: 0.7076
MNIST分類で採用した前項のモデルと同一ですが、学習の結果はそれほど高精度のモデルにはなっていません。MNISTのデータは白黒でしたので、このような結果となりました。
学習済みモデルを用いた画像からの物体の識別 |
通常のCPUを搭載したPCでは、正答率が90%を超えるまでニューラルネットワークの学習を行うためには、数時間から数日も必要とされます。Kerasには、学習済みモデルが用意されています。ImageNetで学習した重みをもつ画像分類のモデルとして、以下のものが用意されています。
Xception VGG16 VGG19 ResNet50 InceptionV3 InceptionResNetV2 MobileNet DenseNet NASNet
ここでは、ディープラーニングでよく使用されるニューラルネットワークであるVGG、ResNet及びInceptionV3を使用します。VGGは、畳み込み層とプーリング層から構成される基本的なCNNです。畳み込み層と全結合層を全部で16もしくは19層にしてディープにしています。前者をVGG16、後者をVGG19と呼びます。VGGは、2014年に開催された大規模画像認識のコンペILSVRC(ImageNet Large Scale Visual Recognition Challenge)で2位の成績に終わりましたが、シンプルな構成なので応用面ではよく使用されます。(ちなみに、優勝者はGoogLeNetでした)VGGは3x3のフィルターによる畳み込み層を2回から4回連続して、プーリング層でサイズを半分にするという処理を繰り返します。
ResNetは2015年Microsoftのチームによって開発されたニューラルネットワークです。その特徴は、層を深くしすぎると過学習などの問題が起きるのを回避するために、スキップ構造(ショートカット)と呼ばる概念を導入した点です。ResNetは、VGGのネットワークをベースにして、スキップ構造を取り入れて、層を深くしています。具体的には、畳み込み層を2層おきにスキップしてつなぎ、層を150層以上まで深くしています。ILSVRCのコンペでは、誤認識率が3.5%という驚異的な成果を出しています。
最初に、この中で最も単純なVGG16モデルを取り上げます。上で触れたとおり、VGG16は2014年のILSVRCで提案された畳み込み13層とフル結合3層の計16層から成る畳み込みニューラルネットワークです。層の数が多いだけで一般的な畳み込みニューラルネットと大きな違いはなく、同時期に提案されたGoogLeNetに比べるとシンプルでわかりやすい。ImageNetと呼ばれる大規模な画像データセットを使って訓練したモデルが公開されています。VGG16の出力層は1000ユニットあり、ImageNetの1000クラスを分類するニューラルネットです。
KerasではVGG16モデルがkeras.applications.vgg16モジュールに実装されているため簡単に使えます。ImageNetの大規模画像セットで学習済みのモデルなので自分で画像を集めて学習する必要がなくて、簡単に利用できて便利です。能です。
学習済みモデルVGG16を用いた画像識別のコードは以下のようになります。
from tensorflow.keras.applications.vgg16 import VGG16 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.vgg16 import preprocess_input, decode_predictions import numpy as np model = VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None) img_path = 'images/elephant.jpg' img = image.load_img(img_path, target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) model.summary() preds = model.predict(x) # decode the results into a list of tuples (class, description, probability) # (one such list for each sample in the batch) print('Predicted:', decode_predictions(preds, top=3)[0])
一般的に、VGG16クラス、VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None)は4つの引数を取ります。include_topはVGG16のトップにある1000クラス分類するフル結合層(FC)を含むか含まないかを指定します。ここでは画像分類を行いたいためFCを含んだ状態で使いますので、Trueがデフォルトです。weightsはVGG16の重みの種類を指定します。VGG16は単にモデル構造であるため必ずしもImageNetを使って学習しなければいけないわけではありません。しかし、現状ではImageNetで学習した重みしか提供されていないので、これを採用します。input_tensorは自分でモデルに画像を入力したいときに使うので、ここでは必要ありませんので、デフォルトでいいです。input_shapeは入力画像の形状を指定します。include_top=Trueにして画像分類器として使う場合は 、デフォルトにしておきます。このとき、入力のshapeは(224, 224, 3) ('channels_last'データフォーマットのとき) または (3, 224, 224) ('channels_first'データフォーマットのとき)となっています。
この例では以下にある像の画像'elephant.jpg'を用いています。
Model: "vgg16" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) [(None, 224, 224, 3)] 0 _________________________________________________________________ block1_conv1 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ block1_conv2 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ block1_pool (MaxPooling2D) (None, 112, 112, 64) 0 _________________________________________________________________ block2_conv1 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________ block2_conv2 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________ block2_pool (MaxPooling2D) (None, 56, 56, 128) 0 _________________________________________________________________ block3_conv1 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ block3_conv2 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ block3_conv3 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ block3_pool (MaxPooling2D) (None, 28, 28, 256) 0 _________________________________________________________________ block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ block4_pool (MaxPooling2D) (None, 14, 14, 512) 0 _________________________________________________________________ block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_pool (MaxPooling2D) (None, 7, 7, 512) 0 _________________________________________________________________ flatten (Flatten) (None, 25088) 0 _________________________________________________________________ fc1 (Dense) (None, 4096) 102764544 _________________________________________________________________ fc2 (Dense) (None, 4096) 16781312 _________________________________________________________________ predictions (Dense) (None, 1000) 4097000 ================================================================= Total params: 138,357,544 Trainable params: 138,357,544 Non-trainable params: 0 _________________________________________________________________ Predicted: [('n02504458', 'African_elephant', 0.7639979), ('n01871265', 'tusker', 0.17359596), ('n02504013', 'Indian_elephant', 0.062363148)]
from tensorflow.keras.applications.resnet50 import ResNet50 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions import numpy as np model = ResNet50(include_top=True, weights='imagenet', input_tensor=None, input_shape=None) img_path = 'images/elephant.jpg' img = image.load_img(img_path, target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) preds = model.predict(x) # decode the results into a list of tuples (class, description, probability) # (one such list for each sample in the batch) print('Predicted:', decode_predictions(preds, top=3)[0])
Predicted: [('n02504458', 'African_elephant', 0.8259493), ('n01871265', 'tusker', 0.09973397), ('n02504013', 'Indian_elephant', 0.07116784)]
という結果が表示されます。 確率82.59%で対象物が'African_elephant'であると識別しました。このケースは正答率が比較的高く出る画像です。VGG16モデルに比較して識別能力が高いと思われます。画像を色々と変えて試して見てください。上で表示した'flower.jpg'を用いて識別を行って見てください。この画像はヒマワリですが、'daisy'であるという確率が一番高く出ます。ImageNetの1000クラス分類にはヒマワリの分類がありません。
GoogleのチームがTensorFlow向けに開発しているInceptionV3(GoogLeNet)を取り上げます。畳み込み層の深さは159と、ResNet50の深さと同じ程度です。このモデルは,TheanoとTensorFlowの両方のbackendで利用でき, 'channels_first'データフォーマット (channels, height, width) か'channels_last'データフォーマット (height, width, channels)の両方で構築可能です。デフォルトの入力サイズは299x299です。この入力サイズはVGG16及びResNet50と異なります。
InceptionV3による画像識別のスクリプトを以下のように作成します。
from tensorflow.keras.applications.inception_v3 import InceptionV3 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.inception_v3 import preprocess_input, decode_predictions import numpy as np #model = InceptionV3(weights='imagenet') model = InceptionV3(include_top=True, weights='imagenet', input_tensor=None, input_shape=None) img_path = 'images/elephant.jpg' img = image.load_img(img_path, target_size=(299, 299)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) #model.summary() preds = model.predict(x) # decode the results into a list of tuples (class, description, probability) # (one such list for each sample in the batch) print('Predicted:', decode_predictions(preds, top=3)[0])
Predicted: [('n02504458', 'African_elephant', 0.61769515), ('n01871265', 'tusker', 0.31645632), ('n02504013', 'Indian_elephant', 0.032580543)]