転移学習での特徴抽出器(ImageNet で学習済みの ResNet50 による転移学習)(Windows あるいは Ubuntu 上)
転移学習 (transfer learning): CNN の学習では,ImageNet などのデータを用いた前学習 (pretrain) ののち,別のデータを用いた学習に移るということがよく行われる.別のデータでの学習は,次のいずれかで行う.
- CNN を画像からの特徴抽出器として使う: CNN の最終層である全結合層を取り除く.残りは,画像からの特徴抽出器(最終層のユニットの数だけの数値を出力する.ImageNet で学習したときは 1000 個の数値である)と見ることができる.そして,CNN の最終層の代わりに,線形分類器 (linear classifier) を付け加える.線形分類器には,線形 SVM や,softmax 分類器がある.その後,データを用いて,学習を行う.画像からの特徴抽出器と言っている部分(最終層である全結合層を取り除いた残り)の結合の重みは変化させない.
- CNN での Fine Tuning も行う: CNN を画像からの特徴抽出器として使うことに加えて, 画像からの特徴抽出器と言っている部分(最終層である全結合層を取り除いた残り)の結合の重みを,バックプロパゲーションにより,変化させる(このことを Fine Tuning という).Fine Tuning においては,すべての層の結合の重みを変化させることもあるし,後段の層の結合の重みのみを変化させる場合もある(過学習の防止のため). Fine Tuning でのエポック数(学習率)は,過学習の防止のため,小さな値にすることを意識する.
上の 1, 2 のどちらで行うかの目安
前学習でのデータと類似している別データで転移学習を行うとき:過学習が起きないだけの十分な量の別データがあるときは,Fine Tuning も行い,Fine Tuning においては,すべての層の結合の重みを変化させる.十分な量の別データがないときは,CNN を画像からの特徴抽出器として使うだけにとどめて,Fine Tuning を行わないことを検討する.
前学習でのデータと類似していない別データで転移学習を行うとき: 過学習が起きないだけの十分な量の別データがあるときは,Fine Tuning も行い,Fine Tuning においては,すべての層の結合の重みを変化させるのか,あるいは,転移学習を行わないのかを検討する(転移学習を行う方がよい場合があると期待できる).十分な量の別データがないときは,CNN を画像からの特徴抽出器として使うだけにとどめる(Fine Tuning を行わない),あるいは,線形分離器として線形 SVM を用いた上で,層を最終層から少しさかのぼってのFine Tuning を行うのがよい可能性がある.
Keras の機能として, ImageNet で学習済みのモデル(ResNet50,Inception-ResNet, DenseNet, MobileNetV2 など)がある. (Keras で利用可能なモデルは,https://keras.io/api/applications/ で説明されている.)
モデルからの最終層の除去,線形分類器 (linear classifier) の追加と別データでの学習,学習曲線の確認,Fine Tuning の実行を行う.
目次:
- Google Colaboratory での実行
- Windows での実行
- 特徴抽出を行う画像データの準備
- ImageNet で学習済みの ResNet50 をベースモデルとして,特徴抽出器を作成
参考 Web ページ:
- https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html
- https://www.tensorflow.org/guide/keras/transfer_learning?hl=ja
- TensorFlow チュートリアルのページ: https://www.tensorflow.org/tutorials/images/transfer_learning?hl=ja
- Keras アプリケーションのページ: https://keras.io/api/applications/
1. Google Colaboratory での実行
自分で,Google Colaboratory のノートブックを新規作成する場合(上のリンクを使わない)のため,手順を説明する.
パソコンを使う場合は,下に「前準備(パソコンを使う場合)」で説明している.
- Google Colaboratory のWebページを開く
https://colab.research.google.com
Google Colab はオンラインの Python 開発環境. 使用するには Google アカウントが必要
- 「ファイル」で、「ノートブックを新規作成」を選ぶ
- Google アカウントでのログインが求められたときはログインする
2. Windows での実行
Python のインストール,pip と setuptools の更新,Python 開発環境のインストール
- Windows での Python のインストール: 別ページ »で説明,pip と setuptools の更新: 別ページ »で説明(あとのトラブルが起きにくいような手順を定めている)
- Ubuntu の場合:
システム Python を使うことができる(システム Python を使う場合,Python のインストールは行わない)
システム Python を用いるときは,pip, setuptools の更新は次のコマンドで行う.
sudo apt -y update sudo apt -y install python3-pip python3-setuptools
Ubuntu で,システム Python 以外の Python をインストールしたい場合は pyenv が便利である: 別ページ »で説明
Python の URL: http://www.python.org/
【Python, pip の使い方】
Python, pip は,次のコマンドで起動できる.
【Python 開発環境のインストール】
- Windows:
JupyterLab, spyder, nteract (Python 開発環境) のインストールは, Windows でコマンドプロンプトを管理者として実行し, 次のコマンドを実行.
python -m pip install -U pip setuptools jupyterlab jupyter jupyter-console jupytext nteract_on_jupyter spyder
詳しくは,: 別ページ »で説明
- Ubuntu
JupyterLab, spyder, nteract (Python 開発環境) のインストール: : 別ページ »で説明
TensorFlow,tensorflow_datasets,numpy,matplotlib, seaborn, scikit-learn のインストール
- Windows の場合:
Windows での pip の実行では,コマンドプロンプトを管理者として実行することにする。
python -m pip uninstall -y tensorflow tensorflow-cpu tensorflow-gpu tensorflow-text tf-models-official tf_slim tensorflow_datasets tensorflow-hub keras keras-tuner keras-visualizer python -m pip install -U tensorflow tensorflow_datasets numpy matplotlib seaborn scikit-learn scikit-learn-intelex
Windows でのインストール詳細(NVIDIA グラフィックスドライバ,NVIDIA CUDA ツールキット,NVIDIA cuDNN, TensorFlow 関連ソフトウエアを含む): 別ページ »で説明
- Ubuntu の場合:
端末で,次のコマンドを実行.
sudo pip3 uninstall -y tensorflow tensorflow-cpu tensorflow-gpu tensorflow-text tf-models-official tf_slim tensorflow_datasets tensorflow-hub keras keras-tuner keras-visualizer sudo pip3 uninstall -y six wheel astunparse tensorflow-estimator numpy keras-preprocessing absl-py wrapt gast flatbuffers grpcio opt-einsum protobuf termcolor typing-extensions google-pasta h5py tensorboard-plugin-wit markdown werkzeug requests-oauthlib rsa cachetools google-auth google-auth-oauthlib tensorboard tensorflow sudo apt -y install python3-six python3-wheel python3-numpy python3-grpcio python3-protobuf python3-termcolor python3-typing-extensions python3-h5py python3-markdown python3-werkzeug python3-requests-oauthlib python3-rsa python3-cachetools python3-google-auth sudo apt -y install python3-numpy python3-sklearn python3-matplotlib python3-seaborn sudo pip3 install -U tensorflow tensorflow_datasets
Ubuntu でのインストール詳細(NVIDIA グラフィックスドライバ,NVIDIA CUDA ツールキット,NVIDIA cuDNN, TensorFlow 関連ソフトウエアを含む): 別ページ »で説明
GraphViz のインストール
- Windows での GraphViz のインストール: 別ページ »で説明
- Ubuntu での GraphViz のインストール
sudo apt -y insatll graphviz python3-graphviz libgraphviz-dev
特徴抽出を行う画像データの準備
TensorFlow チュートリアルのページ: https://www.tensorflow.org/tutorials/images/transfer_learning?hl=jaに掲載の犬,猫のデータを使用.
train_dataset, validation_dataset, test_dataset を準備する.
import os from tensorflow.keras.preprocessing import image_dataset_from_directory # 追加データである画像の画像サイズを IMG_SIZE に設定すること IMG_SIZE = (160, 160) IMG_SHAPE = IMG_SIZE + (3,) # TensorFlow の API で処理するときのバッチサイズの設定 BATCH_SIZE = 32 # URL によりダウンロード _URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip' path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True) PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered') train_dir = os.path.join(PATH, 'train') validation_dir = os.path.join(PATH, 'validation') train_dataset = image_dataset_from_directory(train_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_SIZE) validation_dataset = image_dataset_from_directory(validation_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_SIZE) val_batches = tf.data.experimental.cardinality(validation_dataset) # validation_dataset を test_dataset とvalidation_dataset に振り分け test_dataset = validation_dataset.take(val_batches // 5) validation_dataset = validation_dataset.skip(val_batches // 5) # プリフェッチの設定(読み込み高速化のため) AUTOTUNE = tf.data.AUTOTUNE train_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE) validation_dataset = validation_dataset.prefetch(buffer_size=AUTOTUNE) test_dataset = test_dataset.prefetch(buffer_size=AUTOTUNE)
ImageNet で学習済みの ResNet50 をベースモデルとして,特徴抽出器を作成
ImageNet で学習済みの ResNet50 をベースモデルとして使用.
参考 Web ページ: https://keras.io/ja/applications/
謝辞:ここでは、https://keras.io/ja/applications に記載のプログラムを変更して使用している
- ベースモデルの作成
次の Python プログラムを実行
Python プログラムの実行
- Windows では python (Python ランチャーは py)
- Ubuntu では python3
Python 開発環境(Jupyter Qt Console, Jupyter ノートブック (Jupyter Notebook), Jupyter Lab, Nteract, Spyder, PyCharm, PyScripterなど)も便利である.
Python のまとめ: 別ページ »にまとめ
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow.compat.v2 as tf import tensorflow_datasets as tfds from tensorflow.keras.preprocessing import image import numpy as np %matplotlib inline import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # Suppress Matplotlib warnings tf.enable_v2_behavior() from tensorflow.keras import backend as K K.clear_session() from tensorflow.keras.applications.resnet50 import ResNet50 from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions from tensorflow.keras.models import Model from tensorflow.keras.layers import Dense, Dropout, GlobalAveragePooling2D # include_top=False により分類層を含まないようにする base_model = ResNet50(weights='imagenet', input_shape=IMG_SHAPE, include_top=False) # 学習中に結合の重みが更新されないようにする base_model.trainable = False base_model.summary()
- ベースモデルと画像データの事前確認のため,ベースモデルを用いて画像データを処理してみる
エラーメッセージが出ないことを確認.ここの結果をあとで使うことはない.
image_batch, label_batch = iter(train_dataset).get_next() feature_batch = base_model(image_batch) print(feature_batch.shape)
- ベースモデルを用いて,特徴抽出器のモデルの作成
inputs = tf.keras.Input(IMG_SHAPE) x = base_model(inputs, training=False) x = GlobalAveragePooling2D()(x) m = Model(inputs=inputs, outputs=x) m.summary()
- 別データを,特徴抽出器により処理し結果を得る
特徴抽出器による処理結果は,feature_batch_all に格納する. それは,長さ 2048 の数値ベクトル,2000個になる.
feature_batch_all = None label_batch_all = None it = iter(train_dataset) while True: try: image_batch, label_batch = it.get_next() except tf.errors.OutOfRangeError: break if feature_batch_all is None: feature_batch_all = m(image_batch).numpy() label_batch_all = label_batch.numpy() else: feature_batch_all = np.vstack((feature_batch_all, m(image_batch).numpy())) label_batch_all = np.append(label_batch_all, label_batch.numpy()) print(feature_batch_all.shape) print(label_batch_all.shape)
- データのプロット
主成分分析(PCA)による
import pandas as pd features = [str(i) for i in range(feature_batch_all.shape[1])] df = pd.DataFrame(feature_batch_all, columns=features) df['label'] = label_batch_all df.shape # 主成分分析 import sklearn pca = sklearn.decomposition.PCA(n_components=2) pca_result = pca.fit_transform(df[features].to_numpy()) df['pca1'] = pca_result[:,0] df['pca2'] = pca_result[:,1] # プロット %matplotlib inline import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # Suppress Matplotlib warnings import seaborn as sns plt.style.use('default') plt.figure(figsize=(10,10)) # 2クラスなので,パレット数は2 sns.scatterplot( x="pca1", y="pca2", hue="label", palette=sns.color_palette("hls", 2), data=df, legend="full", alpha=0.4 )
- データのプロット
6次元に次元削減ののち,SOM を作り,SOM をプロット.前準備として「pip install minisom」を実行しておくこと.
import pandas as pd features = [str(i) for i in range(feature_batch_all.shape[1])] df = pd.DataFrame(feature_batch_all, columns=features) df['label'] = label_batch_all df.shape # まず,主成分分析により,次元削減する.結果は X へ. import sklearn DIM = 6 pca = sklearn.decomposition.PCA(n_components=DIM) pca_result = pca.fit_transform(df[features].values) df['pca1'] = pca_result[:,0] df['pca2'] = pca_result[:,1] df['pca3'] = pca_result[:,2] df['pca4'] = pca_result[:,3] df['pca5'] = pca_result[:,4] df['pca6'] = pca_result[:,5] X = df[['pca1', 'pca2', 'pca3', 'pca4', 'pca5', 'pca6']].to_numpy() # see https://github.com/JustGlowing/minisom/blob/master/examples/BasicUsage.ipynb # マーカーと色は2種類を設定(2クラスなので),label_batch_all に入っっている 0, 1 の値に応じて選択. markers = ['o', 's'] colors = ['C0', 'C1'] from minisom import MiniSom som = MiniSom(20, 20, DIM, sigma=0.3, learning_rate=0.5) # initialization of 20x20 SOM som.train(X, 100000) # trains the SOM with 50000 iterations plt.figure(figsize=(10, 10)) plt.pcolor(som.distance_map().T, cmap='bone_r') plt.colorbar() for cnt, xx in enumerate(X): w = som.winner(xx) print(w, cnt, xx) plt.plot(w[0]+.5, w[1]+.5, markers[label_batch_all[cnt]], markersize=12, markeredgewidth=2, markerfacecolor='None', markeredgecolor=colors[label_batch_all[cnt]]) plt.show()