CIFAR 10 データセット(
教師データとして用いる画像データのデータ拡張を行う.増量では,TensorFlow の機能を使い,画像を縦横にずらす,コントラストを変化させることを行う.
前提として,このページの手順では,増量後の画像データがメモリに入り切る分量であるとしている.
TensorFlow データセットのCIFAR 10 データセットを使用する.
CNN としては,次のものを使用する.
この資料の URL: https://www.kkaneko.jp/db/imclassify/preprocess.html
【サイト内の関連ページ】
参考Webページ:
このページの内容は,Google Colaboratory でも実行できる.
そのために,次の URL で,Google Colaboratory のノートブックを準備している.
次のリンクをクリックすると,Google Colaboratory のノートブックが開く. そして,Google アカウントでログインすると,Google Colaboratory のノートブック内のコードを実行することができる.Google Colaboratory のノートブックは書き換えて使うこともできる.このとき,書き換え後のものを,各自の Google ドライブ内に保存することもできる.
https://colab.research.google.com/drive/1osVlD5wpv-pFMrIt2WgXWbTB8t5fKu9f?usp=sharing
自分で,Google Colaboratory のノートブックを新規作成する場合(上のリンクを使わない)のため,手順を説明する.
パソコンを使う場合は,下に「前準備(パソコンを使う場合)」で説明している.
https://colab.research.google.com
Google Colab はオンラインの Python 開発環境. 使用するには Google アカウントが必要
システム 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 開発環境のインストール】
JupyterLab, spyder, nteract (Python 開発環境) のインストールは, Windows でコマンドプロンプトを管理者として実行し, 次のコマンドを実行.
python -m pip install -U pip setuptools jupyterlab jupyter jupyter-console jupytext nteract_on_jupyter spyder
詳しくは,: 別ページで説明している.
JupyterLab, spyder, nteract (Python 開発環境) のインストール: : 別ページで説明している.
Windows での pip の実行では,コマンドプロンプトを管理者として実行することにする。
python -m pip uninstall -y tensorflow tensorflow-cpu tensorflow-gpu tensorflow_datasets tensorflow-hub keras python -m pip install -U tensorflow tensorflow_datasets numpy matplotlib seaborn scikit-learn scikit-learn-intelex
Windows でのインストール詳細(NVIDIA グラフィックスドライバ,NVIDIA CUDA ツールキット,NVIDIA cuDNN, TensorFlow 関連ソフトウエアを含む): 別ページで説明している.
端末で,次のコマンドを実行.
sudo pip3 uninstall -y tensorflow tensorflow-cpu tensorflow-gpu tensorflow_datasets tensorflow-hub keras 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 関連ソフトウエアを含む): 別ページで説明している.
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow.compat.v2 as tf
tf.enable_v2_behavior()
from tensorflow.keras import backend as K
K.clear_session()
print(tf.__version__)
import numpy as np
import tensorflow_datasets as tfds
from tensorflow.keras.preprocessing import image
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore') # Suppress Matplotlib warnings
cifar10, cifar10_info = tfds.load('cifar10', with_info = True, shuffle_files=True, as_supervised=True, batch_size = -1)
MatplotLib を用いて,0 番目の画像を表示する
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore') # Suppress Matplotlib warnings
NUM = 0
# NUM 番目の画像を表示
plt.imshow(cifar10['train'][0][NUM])
MatplotLib を用いて,複数の画像を並べて表示する.
def plot25(ds, start):
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
image, label = ds[0][i + start], ds[1][i + start]
plt.imshow(image)
plt.xlabel(label.numpy())
plt.show()
plot25(cifar10['train'], 0)
print(cifar10_info) print(cifar10_info.features["label"].num_classes) print(cifar10_info.features["label"].names)
cifar10['train']: サイズ 32 かける 32 の 50000枚のカラー画像,50000枚のカラー画像それぞれのラベル(0 から 9 のどれか)
cifar10['test']: サイズ 32 かける 32 の 10000枚のカラー画像,10000枚のカラー画像それぞれのラベル(0 から 9 のどれか)
print(cifar10['train'][0].shape) print(cifar10['train'][1].shape) print(cifar10['test'][0].shape) print(cifar10['test'][1].shape)
ds_train, ds_test = cifar10['train'], cifar10['test']
値は,もともと int で 0 から 255 の範囲であるのを, float32 で 0 から 1 の範囲になるように前処理を行う.
ds_train = (ds_train[0].numpy().astype("float32") / 255., ds_train[1])
ds_test = (ds_test[0].numpy().astype("float32") / 255., ds_test[1])
画像データのデータ拡張を行う. 画像データは,ds_train[0] にある. TensorFlow の機能を使い,画像を縦横にずらす,コントラストを変化させることを行う. ds_train[1] にはラベルのデータが入っているとする.
結果の入る augmented_ds_train はタップル.うち1つ目は,numpy の配列.2つ目は,要素が tf.Tensor の配列.
INPUT_SHAPE = [32, 32, 3]
CROP_SIZE = 3
# 関数オブジェクトを生成
def gen_data_augmentation(seed):
data_augmentation = tf.keras.Sequential(
[
tf.keras.layers.experimental.preprocessing.RandomFlip("horizontal", input_shape=INPUT_SHAPE, seed=seed),
# tf.keras.layers.experimental.preprocessing.RandomContrast(factor=(0.1, 0.1), seed=seed),
# tf.keras.layers.experimental.preprocessing.RandomRotation(factor=(-0.2, 0.2), seed=seed),
tf.keras.layers.experimental.preprocessing.RandomZoom(height_factor=(-0.1, 0.1), width_factor=(-0.1, 0.1), seed=seed),
tf.keras.layers.experimental.preprocessing.RandomTranslation(height_factor=(-0.1, 0.1), width_factor=(-0.1, 0.1), fill_mode='wrap', seed=seed)
]
)
return data_augmentation
# 複数画像を一括して増強
def augment_images(images, seed):
data_augmentation = gen_data_augmentation(seed)
a = [*map(lambda x: np.squeeze(data_augmentation(x[np.newaxis, ...], training=True), 0), images)]
result = np.array(a)
return result
augmented_ds_train = (augment_images(ds_train[0], seed = 0), ds_train[1])
plot25(augmented_ds_train, 0)
print(augmented_ds_train[0].shape)
ここで増やした画像データは,あとで使用する
def increase_image_data(ds_train, t):
# t 倍に増やす
x1 = augment_images(ds_train[0], 1)
y1 = ds_train[1]
if t > 1:
for i in range(t - 1):
x2 = augment_images(ds_train[0], i + 1)
# 画像は nparray, ラベルは tf.Tensorを要素とする配列にする
x1 = np.concatenate([x1, x2])
y1 = tf.concat([y1, ds_train[1]], axis = 0)
result = (x1, y1)
return result
augmented_ds_train = increase_image_data(ds_train, 5)
plot25(augmented_ds_train, 0)
print(augmented_ds_train[0].shape) print(augmented_ds_train[1].shape) print(ds_test[0].shape) print(ds_test[1].shape)
NUM_CLASSES = 10
INPUT_SHAPE = [32, 32, 3]
m1 = tf.keras.applications.mobilenet.MobileNet(input_shape=INPUT_SHAPE, weights=None, classes=NUM_CLASSES)
m1.summary()
m1.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='sparse_categorical_crossentropy',
metrics=['sparse_categorical_crossentropy', 'accuracy']
)
Keras のモデルのビジュアライズについては: https://keras.io/ja/visualization/
ここでの表示で,エラーメッセージが出る場合でも,モデル自体は問題なくできていると考えられる.続行する.
from tensorflow.keras.utils import plot_model import pydot plot_model(m1)
ニューラルネットワークの学習は fit メソッドにより行う. 教師データを使用する. 教師データを投入する.
EPOCHS = 20
history = m1.fit(augmented_ds_train[0], augmented_ds_train[1],
epochs=EPOCHS,
validation_data=(ds_test[0], ds_test[1]),
verbose=1)
ds_test を分類してみる.
print(m1.predict(ds_test[0]))
それぞれの数値の中で、一番大きいものはどれか?
m1.predict(ds_test[0]).argmax(axis=1)
y_test 内にある正解のラベル(クラス名)を表示する(上の結果と比べるため)
print(y_test[1])
過学習や学習不足について確認.
import pandas as pd hist = pd.DataFrame(history.history) hist['epoch'] = history.epoch print(hist)
過学習や学習不足について確認.
https://www.tensorflow.org/tutorials/keras/overfit_and_underfit?hl=ja で公開されているプログラムを使用
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore') # Suppress Matplotlib warnings
def plot_history(histories, key='binary_crossentropy'):
plt.figure(figsize=(16,10))
for name, history in histories:
val = plt.plot(history.epoch, history.history['val_'+key],
'--', label=name.title()+' Val')
plt.plot(history.epoch, history.history[key], color=val[0].get_color(),
label=name.title()+' Train')
plt.xlabel('Epochs')
plt.ylabel(key.replace('_',' ').title())
plt.legend()
plt.xlim([0,max(history.epoch)])
plot_history([('history', history)], key='sparse_categorical_crossentropy')
plot_history([('history', history)], key='accuracy')
データのデータ拡張を行わない場合の結果(学習曲線など)は, 別ページで説明している.