特徴を抽出するために使用するレイヤーを見てきたので、それらをまとめて自分自身のネットワークを構築する時が来ました!
ということでチュートリアルを見てみます。
https://www.kaggle.com/code/ryanholbrook/custom-convnets
シンプルから洗練されたものへ
最後の3つのレッスンで、私たちは畳み込みネットワークが3つの操作、すなわちフィルタリング、検出、および圧縮を通じて特徴抽出をどのように実行するかを見てきました。一回の特徴抽出だけでは、シンプルな線やコントラストのような比較的単純な特徴しか画像から抽出できません。これらはほとんどの分類問題を解決するには単純すぎます。代わりに、コンボネットはこの抽出を何度も繰り返し、特徴がネットワークの深い部分に進むにつれてより複雑で洗練されたものになるようにします。
これらの畳み込みブロックは、Conv2DとMaxPool2Dの層のスタックであり、私たちは最後の数レッスンでその特徴抽出における役割について学びました。
ある種の抽出ブロック: 畳み込み、ReLU、プーリング。
各ブロックは1回の抽出を表し、これらのブロックを組み合わせることで、コンボネットは生成された特徴を組み合わせて再組み合わせることができ、それらを成長させて、手元の問題により適合する形に成形します。現代のコンボネットの深い構造は、この洗練された特徴エンジニアリングを可能にし、その優れた性能の大部分を担っています。
# Imports
import os, warnings
import matplotlib.pyplot as plt
from matplotlib import gridspec
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing import image_dataset_from_directory
Reproducability
def set_seed(seed=31415):
np.random.seed(seed)
tf.random.set_seed(seed)
os.environ['PYTHONHASHSEED'] = str(seed)
os.environ['TF_DETERMINISTIC_OPS'] = '1'
set_seed()
Set Matplotlib defaults
plt.rc('figure', autolayout=True)
plt.rc('axes', labelweight='bold', labelsize='large',
titleweight='bold', titlesize=18, titlepad=10)
plt.rc('image', cmap='magma')
warnings.filterwarnings("ignore") # to clean up output cells
Load training and validation sets
ds_train_ = image_dataset_from_directory(
'../input/car-or-truck/train',
labels='inferred',
label_mode='binary',
image_size=[128, 128],
interpolation='nearest',
batch_size=64,
shuffle=True,
)
ds_valid_ = image_dataset_from_directory(
'../input/car-or-truck/valid',
labels='inferred',
label_mode='binary',
image_size=[128, 128],
interpolation='nearest',
batch_size=64,
shuffle=False,
)
Data Pipeline
def convert_to_float(image, label):
image = tf.image.convert_image_dtype(image, dtype=tf.float32)
return image, label
AUTOTUNE = tf.data.experimental.AUTOTUNE
ds_train = (
ds_train_
.map(convert_to_float)
.cache()
.prefetch(buffer_size=AUTOTUNE)
)
ds_valid = (
ds_valid_
.map(convert_to_float)
.cache()
.prefetch(buffer_size=AUTOTUNE)
)
Found 5117 files belonging to 2 classes.
Found 5051 files belonging to 2 classes.
こんなレイヤーを作ります。
さて、モデルを定義しましょう。私たちのモデルが、Conv2DとMaxPool2Dの層の3つのブロック(ベース)に続いて、Denseの層のヘッドで構成されていることに注目してください。この図を、適切なパラメータを埋め込むだけで、KerasのSequentialモデルにほぼ直接変換することができます。
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
# First Convolutional Block
layers.Conv2D(filters=32, kernel\_size=5, activation="relu", padding='same',
# give the input dimensions in the first layer
# \[height, width, color channels(RGB)\]
input\_shape=\[128, 128, 3\]),
layers.MaxPool2D(),
# Second Convolutional Block
layers.Conv2D(filters=64, kernel\_size=3, activation="relu", padding='same'),
layers.MaxPool2D(),
# Third Convolutional Block
layers.Conv2D(filters=128, kernel\_size=3, activation="relu", padding='same'),
layers.MaxPool2D(),
# Classifier Head
layers.Flatten(),
layers.Dense(units=6, activation="relu"),
layers.Dense(units=1, activation="sigmoid"),
])
model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
Model: "sequential"conv2d (Conv2D) (None, 128, 128, 32) 2432
max_pooling2d (MaxPooling2D (None, 64, 64, 32) 0
)
conv2d_1 (Conv2D) (None, 64, 64, 64) 18496
max_pooling2d_1 (MaxPooling (None, 32, 32, 64) 0
2D)
conv2d_2 (Conv2D) (None, 32, 32, 128) 73856
max_pooling2d_2 (MaxPooling (None, 16, 16, 128) 0
2D)
flatten (Flatten) (None, 32768) 0
dense (Dense) (None, 6) 196614
dense_1 (Dense) (None, 1) 7
=================================================================
Total params: 291,405
Trainable params: 291,405
Non-trainable params: 0
_________________________________________________________________
この定義で注目すべきは、フィルターの数がブロックごとに倍増していることです:32、64、128。これは一般的なパターンです。MaxPool2D層が特徴マップのサイズを縮小しているので、作成する量を増やすことができます。
ステップ3 - トレーニング
このモデルは、レッスン1のモデルと同じようにトレーニングすることができます:バイナリ分類に適した損失とメトリクスとともに最適化アルゴリズムを使ってコンパイルします。
model.compile(
optimizer=tf.keras.optimizers.Adam(epsilon=0.01),
loss='binary_crossentropy',
metrics=['binary_accuracy']
)
history = model.fit(
ds_train,
validation_data=ds_valid,
epochs=40,
verbose=0,
)
import pandas as pd
history_frame = pd.DataFrame(history.history)
history_frame.loc[:, ['loss', 'val_loss']].plot()
history_frame.loc[:, ['binary_accuracy', 'val_binary_accuracy']].plot();
このモデルは、レッスン1のVGG16モデルよりもはるかに小さいです -- VGG16の16に対して畳み込み層が3つしかありません。それにもかかわらず、このデータセットにかなりうまくフィットさせることができました。もっと畳み込み層を追加することで、このシンプルなモデルをさらに改善できるかもしれません。データセットにより適応した特徴を作成することを目指しています。これについては練習問題で試みます。
結論
このチュートリアルでは、多くの畳み込みブロックから成るカスタムなconvnetを構築し、複雑な特徴エンジニアリングが可能な方法を見てきました。