Stochastic Depth(確率的深度)で過学習は抑えられるか?【Keras×CIFAR-10実験】

投稿日:2026年5月25日月曜日 最終更新日:

CIFAR-10 CNN Dropout Google Colab Keras ResNet 過学習 画像分類

X f B! P L
Stochastic Depth(確率的深度)で過学習は抑えられるか?【Keras×CIFAR-10実験】 アイキャッチ画像

Dropoutは特定のニューロンをランダムに無効化することで過学習を抑えますが、Stochastic Depth(確率的深度)はそれよりひとつ大きな単位——ブロック(層のグループ)ごとをランダムにスキップします。

ResNeXt・EfficientNet・DeiTなど近年の高精度モデルで広く採用されているこの手法を、Google ColabとCIFAR-10を使って自前実装し、効果を検証します。

📘 この記事でわかること
  • Stochastic Depth(DropPath)の仕組みとDropoutとの違い
  • KerasでStochastic Depthカスタムレイヤーを実装する方法
  • あり vs なし の精度・過学習・学習曲線の比較(CIFAR-10実験)
  • drop_rate=0.1で精度が約9ポイント向上——drop_rateが大きすぎると逆効果になる理由

Stochastic Depthとは

Stochastic Depth(Huang et al., 2016)は、学習時にネットワークの一部のブロックをランダムに恒等写像(スキップ)に置き換える正則化手法です。推論時は全ブロックを使用します。

手法 スキップする単位 代替操作 代表モデル
Dropout 個別のニューロン 出力を0にする ほぼすべてのDNNで利用
DropBlock 特徴マップの矩形領域 領域全体を0にする 大規模CNNの正則化
Stochastic Depth Residualブロック全体 恒等写像(スキップ)に置き換え ResNet, EfficientNet, DeiT

Residual接続(スキップ接続)との組み合わせが前提です。ブロックをスキップしたとき、入力がそのまま出力として渡されるのはResidual接続があるからです。スキップ接続なしでStochastic Depthを使うと入力情報が完全にロストします。

学習時の出力は次のように表されます: $$\hat{x}_l = x_l + b_l \cdot f_l(x_l), \quad b_l \sim \text{Bernoulli}(1 - p_l)$$ ここで \( b_l = 0 \) のとき(確率 \( p_l \))ブロック \( f_l \) はスキップされ、入力 \( x_l \) がそのまま次の層へ渡されます。

実験コード

使用環境はGoogle Colab(GPU:T4)、データセットはCIFAR-10です。Stochastic Depthをカスタムレイヤーとして実装し、Residualブロックに組み込みます。

環境準備(最初に一度だけ実行)

# ── 環境準備(最初に一度だけ実行)──────────────────────
!apt-get -y install fonts-ipafont-gothic
!rm -rf /root/.cache/matplotlib
!pip install -q japanize_matplotlib
print("環境準備完了")
実行結果をクリックして内容を開く
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  fonts-ipafont-mincho
The following NEW packages will be installed:
  fonts-ipafont-gothic fonts-ipafont-mincho
0 upgraded, 2 newly installed, 0 to remove and 51 not upgraded.
Need to get 8,237 kB of archives.
After this operation, 28.7 MB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy/universe amd64 fonts-ipafont-gothic all 00303-21ubuntu1 [3,513 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy/universe amd64 fonts-ipafont-mincho all 00303-21ubuntu1 [4,724 kB]
Fetched 8,237 kB in 0s (34.6 MB/s)
Selecting previously unselected package fonts-ipafont-gothic.
(Reading database ... 122363 files and directories currently installed.)
Preparing to unpack .../fonts-ipafont-gothic_00303-21ubuntu1_all.deb ...
Unpacking fonts-ipafont-gothic (00303-21ubuntu1) ...
Selecting previously unselected package fonts-ipafont-mincho.
Preparing to unpack .../fonts-ipafont-mincho_00303-21ubuntu1_all.deb ...
Unpacking fonts-ipafont-mincho (00303-21ubuntu1) ...
Setting up fonts-ipafont-mincho (00303-21ubuntu1) ...
update-alternatives: using /usr/share/fonts/opentype/ipafont-mincho/ipam.ttf to provide /usr/share/fonts/truetype/fonts-japanese-mincho.ttf (fonts-japanese-mincho.ttf) in auto mode
Setting up fonts-ipafont-gothic (00303-21ubuntu1) ...
update-alternatives: using /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf to provide /usr/share/fonts/truetype/fonts-japanese-gothic.ttf (fonts-japanese-gothic.ttf) in auto mode
Processing triggers for fontconfig (2.13.1-4.2ubuntu5) ...
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.1/4.1 MB 65.0 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
  Building wheel for japanize_matplotlib (setup.py) ... done
環境準備完了

import・データ準備・カスタムレイヤー定義

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
import japanize_matplotlib
import time

(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data()
x_train = x_train.astype('float32') / 255.0
x_test  = x_test.astype('float32')  / 255.0

# ── Stochastic Depthカスタムレイヤー ──────────────────
class StochasticDepth(keras.layers.Layer):
    """DropPath / Stochastic Depth
    
    学習時: 確率 drop_rate でブロック出力を0にする(恒等写像=スキップ)
    推論時: ブロック出力に (1 - drop_rate) をスケーリング(期待値を合わせる)
    
    使い方: x = StochasticDepth(drop_rate=0.1)(block_output, shortcut)
    """
    def __init__(self, drop_rate=0.1, **kwargs):
        super().__init__(**kwargs)
        self.drop_rate = drop_rate

    def call(self, x, shortcut, training=None):
        if training:
            # バッチ単位でランダムに drop する(サンプルごとでなくバッチ全体)
            keep_prob = 1.0 - self.drop_rate
            shape = (tf.shape(x)[0],) + (1,) * (len(x.shape) - 1)
            random_tensor = tf.floor(keep_prob + tf.random.uniform(shape))
            x = x / keep_prob * random_tensor   # スケーリングして期待値を保つ
        return x + shortcut

    def get_config(self):
        config = super().get_config()
        config.update({'drop_rate': self.drop_rate})
        return config
実行結果をクリックして内容を開く
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170498071/170498071 ━━━━━━━━━━━━━━━━━━━━ 4s 0us/step

モデル構築関数

def residual_block(x, filters, use_stochastic_depth=False, drop_rate=0.1):
    """Residual Block(スキップ接続あり)
    
    use_stochastic_depth=True のときブロック出力をStochastic Depthで正則化する
    """
    shortcut = x
    # チャネル数が異なる場合は1×1 Convでショートカットを調整
    if shortcut.shape[-1] != filters:
        shortcut = layers.Conv2D(filters, 1, padding='same', use_bias=False)(shortcut)
        shortcut = layers.BatchNormalization()(shortcut)

    x = layers.Conv2D(filters, 3, padding='same', use_bias=False)(x)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)
    x = layers.Conv2D(filters, 3, padding='same', use_bias=False)(x)
    x = layers.BatchNormalization()(x)

    if use_stochastic_depth:
        x = StochasticDepth(drop_rate=drop_rate)(x, shortcut)
    else:
        x = layers.Add()([x, shortcut])

    x = layers.Activation('relu')(x)
    return x

def build_model(use_stochastic_depth, drop_rate=0.1, name='model'):
    inputs = keras.Input(shape=(32, 32, 3))

    # Stem
    x = layers.Conv2D(64, 3, padding='same', use_bias=False)(inputs)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)
    x = layers.MaxPooling2D(2)(x)    # 32×32 → 16×16

    # Block 1(filters=64)× 2
    x = residual_block(x, 64,  use_stochastic_depth, drop_rate)
    x = residual_block(x, 64,  use_stochastic_depth, drop_rate)
    x = layers.MaxPooling2D(2)(x)    # 16×16 → 8×8

    # Block 2(filters=128)× 2
    x = residual_block(x, 128, use_stochastic_depth, drop_rate)
    x = residual_block(x, 128, use_stochastic_depth, drop_rate)

    x = layers.GlobalAveragePooling2D()(x)
    x = layers.Dense(128, activation='relu')(x)
    x = layers.Dropout(0.2)(x)
    outputs = layers.Dense(10, activation='softmax')(x)

    return keras.Model(inputs, outputs, name=name)

def compile_and_fit(model):
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    start = time.time()
    history = model.fit(x_train, y_train, epochs=30, batch_size=64,
                        validation_split=0.2, verbose=1)
    return history, time.time() - start

3パターンの学習実行

# Stochastic Depthなし / drop_rate=0.1 / drop_rate=0.2 の3パターン比較
configs = [
    (False, 0.0,  'A_no_sd'),
    (True,  0.1,  'B_sd_01'),
    (True,  0.2,  'C_sd_02'),
]
histories, times, scores, params = {}, {}, {}, {}

for use_sd, dr, name in configs:
    print(f"\n=== {name} ===")
    model = build_model(use_sd, drop_rate=dr, name=name)
    model.summary()
    h, t = compile_and_fit(model)
    s = model.evaluate(x_test, y_test, verbose=0)
    histories[name] = h
    times[name]     = t
    scores[name]    = s
    params[name]    = model.count_params()
    print(f"学習時間:{t:.1f}秒 パラメータ数:{model.count_params():,} test_accuracy:{s[1]:.4f}")
実行結果をクリックして内容を開く
=== A_no_sd ===
Model: "A_no_sd"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer         │ (None, 32, 32, 3) │          0 │ -                 │
│ (InputLayer)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d (Conv2D)     │ (None, 32, 32,    │      1,728 │ input_layer[0][0] │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalization │ (None, 32, 32,    │        256 │ conv2d[0][0]      │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation          │ (None, 32, 32,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d       │ (None, 16, 16,    │          0 │ activation[0][0]  │
│ (MaxPooling2D)      │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_1 (Conv2D)   │ (None, 16, 16,    │     36,864 │ max_pooling2d[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_1[0][0]    │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_1        │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_2 (Conv2D)   │ (None, 16, 16,    │     36,864 │ activation_1[0][… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_2[0][0]    │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add (Add)           │ (None, 16, 16,    │          0 │ batch_normalizat… │
│                     │ 64)               │            │ max_pooling2d[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_2        │ (None, 16, 16,    │          0 │ add[0][0]         │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_3 (Conv2D)   │ (None, 16, 16,    │     36,864 │ activation_2[0][… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_3[0][0]    │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_3        │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_4 (Conv2D)   │ (None, 16, 16,    │     36,864 │ activation_3[0][… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_4[0][0]    │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_1 (Add)         │ (None, 16, 16,    │          0 │ batch_normalizat… │
│                     │ 64)               │            │ activation_2[0][… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_4        │ (None, 16, 16,    │          0 │ add_1[0][0]       │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d_1     │ (None, 8, 8, 64)  │          0 │ activation_4[0][… │
│ (MaxPooling2D)      │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_6 (Conv2D)   │ (None, 8, 8, 128) │     73,728 │ max_pooling2d_1[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_6[0][0]    │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_5        │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_7 (Conv2D)   │ (None, 8, 8, 128) │    147,456 │ activation_5[0][… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_5 (Conv2D)   │ (None, 8, 8, 128) │      8,192 │ max_pooling2d_1[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_7[0][0]    │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_5[0][0]    │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_2 (Add)         │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│                     │                   │            │ batch_normalizat… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_6        │ (None, 8, 8, 128) │          0 │ add_2[0][0]       │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_8 (Conv2D)   │ (None, 8, 8, 128) │    147,456 │ activation_6[0][… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_8[0][0]    │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_7        │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_9 (Conv2D)   │ (None, 8, 8, 128) │    147,456 │ activation_7[0][… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_9[0][0]    │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_3 (Add)         │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│                     │                   │            │ activation_6[0][… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_8        │ (None, 8, 8, 128) │          0 │ add_3[0][0]       │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ global_average_poo… │ (None, 128)       │          0 │ activation_8[0][… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense (Dense)       │ (None, 128)       │     16,512 │ global_average_p… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout (Dropout)   │ (None, 128)       │          0 │ dense[0][0]       │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_1 (Dense)     │ (None, 10)        │      1,290 │ dropout[0][0]     │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 695,114 (2.65 MB)
 Trainable params: 693,194 (2.64 MB)
 Non-trainable params: 1,920 (7.50 KB)
Epoch 1/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 22s 16ms/step - accuracy: 0.5107 - loss: 1.3418 - val_accuracy: 0.5485 - val_loss: 1.2489
Epoch 2/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.6644 - loss: 0.9532 - val_accuracy: 0.5258 - val_loss: 1.4386
Epoch 3/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 12ms/step - accuracy: 0.7326 - loss: 0.7724 - val_accuracy: 0.5060 - val_loss: 1.6643
Epoch 4/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.7735 - loss: 0.6554 - val_accuracy: 0.6328 - val_loss: 1.1693
Epoch 5/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8069 - loss: 0.5619 - val_accuracy: 0.7340 - val_loss: 0.7535
Epoch 6/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 12ms/step - accuracy: 0.8338 - loss: 0.4853 - val_accuracy: 0.7335 - val_loss: 0.8246
Epoch 7/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8547 - loss: 0.4242 - val_accuracy: 0.7730 - val_loss: 0.6831
Epoch 8/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8770 - loss: 0.3586 - val_accuracy: 0.7536 - val_loss: 0.7473
Epoch 9/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8924 - loss: 0.3107 - val_accuracy: 0.7530 - val_loss: 0.7654
Epoch 10/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9055 - loss: 0.2725 - val_accuracy: 0.7970 - val_loss: 0.6170
Epoch 11/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9202 - loss: 0.2313 - val_accuracy: 0.7882 - val_loss: 0.6564
Epoch 12/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9312 - loss: 0.2007 - val_accuracy: 0.7455 - val_loss: 0.9725
Epoch 13/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 14ms/step - accuracy: 0.9398 - loss: 0.1767 - val_accuracy: 0.7951 - val_loss: 0.7486
Epoch 14/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9471 - loss: 0.1488 - val_accuracy: 0.7094 - val_loss: 1.3574
Epoch 15/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9543 - loss: 0.1336 - val_accuracy: 0.7681 - val_loss: 0.9475
Epoch 16/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9595 - loss: 0.1193 - val_accuracy: 0.7112 - val_loss: 1.1541
Epoch 17/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9622 - loss: 0.1103 - val_accuracy: 0.7024 - val_loss: 1.3017
Epoch 18/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9672 - loss: 0.0928 - val_accuracy: 0.7642 - val_loss: 1.0412
Epoch 19/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9669 - loss: 0.0952 - val_accuracy: 0.7889 - val_loss: 0.8429
Epoch 20/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9708 - loss: 0.0827 - val_accuracy: 0.7952 - val_loss: 0.9167
Epoch 21/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9742 - loss: 0.0775 - val_accuracy: 0.7681 - val_loss: 1.1290
Epoch 22/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9734 - loss: 0.0754 - val_accuracy: 0.7558 - val_loss: 1.0715
Epoch 23/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9751 - loss: 0.0708 - val_accuracy: 0.7965 - val_loss: 0.8875
Epoch 24/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9778 - loss: 0.0651 - val_accuracy: 0.7229 - val_loss: 1.5549
Epoch 25/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9775 - loss: 0.0666 - val_accuracy: 0.7607 - val_loss: 1.1871
Epoch 26/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9804 - loss: 0.0583 - val_accuracy: 0.7214 - val_loss: 1.6575
Epoch 27/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9800 - loss: 0.0584 - val_accuracy: 0.7555 - val_loss: 1.2516
Epoch 28/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9813 - loss: 0.0564 - val_accuracy: 0.7726 - val_loss: 1.1516
Epoch 29/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9803 - loss: 0.0571 - val_accuracy: 0.8010 - val_loss: 1.0183
Epoch 30/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9836 - loss: 0.0473 - val_accuracy: 0.7314 - val_loss: 1.5954
学習時間:258.6秒 パラメータ数:695,114 test_accuracy:0.7280

=== B_sd_01 ===
Model: "B_sd_01"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer_1       │ (None, 32, 32, 3) │          0 │ -                 │
│ (InputLayer)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_10 (Conv2D)  │ (None, 32, 32,    │      1,728 │ input_layer_1[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 32, 32,    │        256 │ conv2d_10[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_9        │ (None, 32, 32,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d_2     │ (None, 16, 16,    │          0 │ activation_9[0][… │
│ (MaxPooling2D)      │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_11 (Conv2D)  │ (None, 16, 16,    │     36,864 │ max_pooling2d_2[… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_11[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_10       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_12 (Conv2D)  │ (None, 16, 16,    │     36,864 │ activation_10[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_12[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ stochastic_depth    │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (StochasticDepth)   │ 64)               │            │ max_pooling2d_2[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_11       │ (None, 16, 16,    │          0 │ stochastic_depth… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_13 (Conv2D)  │ (None, 16, 16,    │     36,864 │ activation_11[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_13[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_12       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_14 (Conv2D)  │ (None, 16, 16,    │     36,864 │ activation_12[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_14[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ stochastic_depth_1  │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (StochasticDepth)   │ 64)               │            │ activation_11[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_13       │ (None, 16, 16,    │          0 │ stochastic_depth… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d_3     │ (None, 8, 8, 64)  │          0 │ activation_13[0]… │
│ (MaxPooling2D)      │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_16 (Conv2D)  │ (None, 8, 8, 128) │     73,728 │ max_pooling2d_3[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_16[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_14       │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_17 (Conv2D)  │ (None, 8, 8, 128) │    147,456 │ activation_14[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_15 (Conv2D)  │ (None, 8, 8, 128) │      8,192 │ max_pooling2d_3[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_17[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_15[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ stochastic_depth_2  │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (StochasticDepth)   │                   │            │ batch_normalizat… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_15       │ (None, 8, 8, 128) │          0 │ stochastic_depth… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_18 (Conv2D)  │ (None, 8, 8, 128) │    147,456 │ activation_15[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_18[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_16       │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_19 (Conv2D)  │ (None, 8, 8, 128) │    147,456 │ activation_16[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_19[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ stochastic_depth_3  │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (StochasticDepth)   │                   │            │ activation_15[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_17       │ (None, 8, 8, 128) │          0 │ stochastic_depth… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ global_average_poo… │ (None, 128)       │          0 │ activation_17[0]… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_2 (Dense)     │ (None, 128)       │     16,512 │ global_average_p… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout_1 (Dropout) │ (None, 128)       │          0 │ dense_2[0][0]     │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_3 (Dense)     │ (None, 10)        │      1,290 │ dropout_1[0][0]   │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 695,114 (2.65 MB)
 Trainable params: 693,194 (2.64 MB)
 Non-trainable params: 1,920 (7.50 KB)
Epoch 1/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 21s 16ms/step - accuracy: 0.4622 - loss: 1.4758 - val_accuracy: 0.4895 - val_loss: 1.3888
Epoch 2/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.6112 - loss: 1.0932 - val_accuracy: 0.5002 - val_loss: 1.4521
Epoch 3/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.6697 - loss: 0.9382 - val_accuracy: 0.6587 - val_loss: 0.9645
Epoch 4/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 14ms/step - accuracy: 0.7157 - loss: 0.8188 - val_accuracy: 0.7089 - val_loss: 0.8527
Epoch 5/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.7508 - loss: 0.7264 - val_accuracy: 0.6662 - val_loss: 0.9842
Epoch 6/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.7757 - loss: 0.6564 - val_accuracy: 0.6843 - val_loss: 0.9511
Epoch 7/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.7955 - loss: 0.5953 - val_accuracy: 0.7694 - val_loss: 0.6755
Epoch 8/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8098 - loss: 0.5520 - val_accuracy: 0.7394 - val_loss: 0.7826
Epoch 9/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 10s 13ms/step - accuracy: 0.8227 - loss: 0.5093 - val_accuracy: 0.7497 - val_loss: 0.7310
Epoch 10/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8404 - loss: 0.4618 - val_accuracy: 0.7837 - val_loss: 0.6415
Epoch 11/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8536 - loss: 0.4248 - val_accuracy: 0.7770 - val_loss: 0.6625
Epoch 12/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8642 - loss: 0.3935 - val_accuracy: 0.7196 - val_loss: 0.8612
Epoch 13/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8735 - loss: 0.3656 - val_accuracy: 0.7232 - val_loss: 0.9341
Epoch 14/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8808 - loss: 0.3448 - val_accuracy: 0.7355 - val_loss: 0.9118
Epoch 15/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 14ms/step - accuracy: 0.8916 - loss: 0.3140 - val_accuracy: 0.7668 - val_loss: 0.8386
Epoch 16/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8985 - loss: 0.2898 - val_accuracy: 0.8001 - val_loss: 0.6879
Epoch 17/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9057 - loss: 0.2727 - val_accuracy: 0.7336 - val_loss: 1.1864
Epoch 18/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9101 - loss: 0.2555 - val_accuracy: 0.7771 - val_loss: 0.8551
Epoch 19/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 14ms/step - accuracy: 0.9161 - loss: 0.2395 - val_accuracy: 0.7735 - val_loss: 0.8933
Epoch 20/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9211 - loss: 0.2271 - val_accuracy: 0.8069 - val_loss: 0.7165
Epoch 21/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9275 - loss: 0.2117 - val_accuracy: 0.7084 - val_loss: 1.1470
Epoch 22/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9294 - loss: 0.2027 - val_accuracy: 0.8215 - val_loss: 0.6560
Epoch 23/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9307 - loss: 0.1986 - val_accuracy: 0.8201 - val_loss: 0.6642
Epoch 24/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 14ms/step - accuracy: 0.9346 - loss: 0.1895 - val_accuracy: 0.8006 - val_loss: 0.8400
Epoch 25/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9384 - loss: 0.1753 - val_accuracy: 0.8008 - val_loss: 0.7951
Epoch 26/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9411 - loss: 0.1698 - val_accuracy: 0.8302 - val_loss: 0.6742
Epoch 27/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9431 - loss: 0.1663 - val_accuracy: 0.7989 - val_loss: 0.7463
Epoch 28/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9461 - loss: 0.1574 - val_accuracy: 0.8111 - val_loss: 0.8352
Epoch 29/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9448 - loss: 0.1599 - val_accuracy: 0.8394 - val_loss: 0.6102
Epoch 30/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 14ms/step - accuracy: 0.9477 - loss: 0.1512 - val_accuracy: 0.8141 - val_loss: 0.8518
学習時間:266.6秒 パラメータ数:695,114 test_accuracy:0.8162

=== C_sd_02 ===
Model: "C_sd_02"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer_2       │ (None, 32, 32, 3) │          0 │ -                 │
│ (InputLayer)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_20 (Conv2D)  │ (None, 32, 32,    │      1,728 │ input_layer_2[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 32, 32,    │        256 │ conv2d_20[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_18       │ (None, 32, 32,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d_4     │ (None, 16, 16,    │          0 │ activation_18[0]… │
│ (MaxPooling2D)      │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_21 (Conv2D)  │ (None, 16, 16,    │     36,864 │ max_pooling2d_4[… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_21[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_19       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_22 (Conv2D)  │ (None, 16, 16,    │     36,864 │ activation_19[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_22[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ stochastic_depth_4  │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (StochasticDepth)   │ 64)               │            │ max_pooling2d_4[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_20       │ (None, 16, 16,    │          0 │ stochastic_depth… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_23 (Conv2D)  │ (None, 16, 16,    │     36,864 │ activation_20[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_23[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_21       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_24 (Conv2D)  │ (None, 16, 16,    │     36,864 │ activation_21[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        256 │ conv2d_24[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ stochastic_depth_5  │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (StochasticDepth)   │ 64)               │            │ activation_20[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_22       │ (None, 16, 16,    │          0 │ stochastic_depth… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d_5     │ (None, 8, 8, 64)  │          0 │ activation_22[0]… │
│ (MaxPooling2D)      │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_26 (Conv2D)  │ (None, 8, 8, 128) │     73,728 │ max_pooling2d_5[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_26[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_23       │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_27 (Conv2D)  │ (None, 8, 8, 128) │    147,456 │ activation_23[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_25 (Conv2D)  │ (None, 8, 8, 128) │      8,192 │ max_pooling2d_5[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_27[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_25[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ stochastic_depth_6  │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (StochasticDepth)   │                   │            │ batch_normalizat… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_24       │ (None, 8, 8, 128) │          0 │ stochastic_depth… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_28 (Conv2D)  │ (None, 8, 8, 128) │    147,456 │ activation_24[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_28[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_25       │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_29 (Conv2D)  │ (None, 8, 8, 128) │    147,456 │ activation_25[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 8, 8, 128) │        512 │ conv2d_29[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ stochastic_depth_7  │ (None, 8, 8, 128) │          0 │ batch_normalizat… │
│ (StochasticDepth)   │                   │            │ activation_24[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_26       │ (None, 8, 8, 128) │          0 │ stochastic_depth… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ global_average_poo… │ (None, 128)       │          0 │ activation_26[0]… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_4 (Dense)     │ (None, 128)       │     16,512 │ global_average_p… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout_2 (Dropout) │ (None, 128)       │          0 │ dense_4[0][0]     │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_5 (Dense)     │ (None, 10)        │      1,290 │ dropout_2[0][0]   │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 695,114 (2.65 MB)
 Trainable params: 693,194 (2.64 MB)
 Non-trainable params: 1,920 (7.50 KB)
Epoch 1/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 21s 17ms/step - accuracy: 0.4189 - loss: 1.5941 - val_accuracy: 0.3317 - val_loss: 2.0689
Epoch 2/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.5652 - loss: 1.2205 - val_accuracy: 0.5825 - val_loss: 1.1413
Epoch 3/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 14ms/step - accuracy: 0.6277 - loss: 1.0506 - val_accuracy: 0.6139 - val_loss: 1.0395
Epoch 4/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 14ms/step - accuracy: 0.6676 - loss: 0.9436 - val_accuracy: 0.6043 - val_loss: 1.1094
Epoch 5/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.7017 - loss: 0.8534 - val_accuracy: 0.6368 - val_loss: 1.1262
Epoch 6/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.7281 - loss: 0.7780 - val_accuracy: 0.7203 - val_loss: 0.8073
Epoch 7/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 14ms/step - accuracy: 0.7466 - loss: 0.7276 - val_accuracy: 0.7148 - val_loss: 0.8095
Epoch 8/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 10s 13ms/step - accuracy: 0.7665 - loss: 0.6728 - val_accuracy: 0.6964 - val_loss: 0.8758
Epoch 9/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.7829 - loss: 0.6297 - val_accuracy: 0.7115 - val_loss: 0.8386
Epoch 10/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.7942 - loss: 0.5903 - val_accuracy: 0.6952 - val_loss: 0.9112
Epoch 11/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8103 - loss: 0.5519 - val_accuracy: 0.7643 - val_loss: 0.6912
Epoch 12/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8202 - loss: 0.5215 - val_accuracy: 0.7655 - val_loss: 0.7166
Epoch 13/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8271 - loss: 0.4979 - val_accuracy: 0.7491 - val_loss: 0.8337
Epoch 14/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8352 - loss: 0.4756 - val_accuracy: 0.7942 - val_loss: 0.6115
Epoch 15/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8445 - loss: 0.4466 - val_accuracy: 0.7684 - val_loss: 0.7179
Epoch 16/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8553 - loss: 0.4178 - val_accuracy: 0.7886 - val_loss: 0.6438
Epoch 17/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8574 - loss: 0.4047 - val_accuracy: 0.7930 - val_loss: 0.6544
Epoch 18/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8680 - loss: 0.3820 - val_accuracy: 0.7830 - val_loss: 0.6504
Epoch 19/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8727 - loss: 0.3665 - val_accuracy: 0.8112 - val_loss: 0.5948
Epoch 20/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8790 - loss: 0.3464 - val_accuracy: 0.8330 - val_loss: 0.5253
Epoch 21/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8841 - loss: 0.3321 - val_accuracy: 0.8203 - val_loss: 0.5399
Epoch 22/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 14ms/step - accuracy: 0.8879 - loss: 0.3232 - val_accuracy: 0.7478 - val_loss: 0.8558
Epoch 23/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8931 - loss: 0.3021 - val_accuracy: 0.8115 - val_loss: 0.6403
Epoch 24/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.8967 - loss: 0.2934 - val_accuracy: 0.8078 - val_loss: 0.6563
Epoch 25/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9007 - loss: 0.2807 - val_accuracy: 0.7773 - val_loss: 0.7386
Epoch 26/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 14ms/step - accuracy: 0.9073 - loss: 0.2680 - val_accuracy: 0.8191 - val_loss: 0.6409
Epoch 27/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9094 - loss: 0.2611 - val_accuracy: 0.8019 - val_loss: 0.7013
Epoch 28/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 14ms/step - accuracy: 0.9133 - loss: 0.2485 - val_accuracy: 0.8037 - val_loss: 0.7527
Epoch 29/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9179 - loss: 0.2372 - val_accuracy: 0.7276 - val_loss: 1.0301
Epoch 30/30
625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.9181 - loss: 0.2364 - val_accuracy: 0.7966 - val_loss: 0.7781
学習時間:267.7秒 パラメータ数:695,114 test_accuracy:0.7923

グラフ+サマリー

labels_order = ['A_no_sd', 'B_sd_01', 'C_sd_02']
display_names = ['A: SD なし', 'B: SD drop=0.1', 'C: SD drop=0.2']

# ── val_accuracy / val_loss 比較グラフ ───────────────
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
for label, dname in zip(labels_order, display_names):
    axes[0].plot(histories[label].history['val_accuracy'], label=dname)
    axes[1].plot(histories[label].history['val_loss'],     label=dname)
axes[0].set_title('val_accuracy の比較(全30エポック)')
axes[1].set_title('val_loss の比較(全30エポック)')
for ax in axes:
    ax.set_xlabel('Epoch'); ax.legend(); ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('stochastic_depth_comparison.png', dpi=150)
plt.show()

# ── train vs val(過学習確認)────────────────────────
fig2, axes2 = plt.subplots(3, 1, figsize=(7, 14))
for ax, label, dname in zip(axes2, labels_order, display_names):
    ax.plot(histories[label].history['loss'],     label='train_loss')
    ax.plot(histories[label].history['val_loss'], label='val_loss')
    ax.set_title(dname); ax.set_xlabel('Epoch')
    ax.legend(); ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('stochastic_depth_overfit.png', dpi=150)
plt.show()

print("\n===== 最終結果サマリー =====")
print(f"{'Pattern':>16} | {'Val Acc':>8} | {'Test Acc':>9} | {'Time(s)':>8} | {'Params':>12}")
print("-" * 68)
for label, dname in zip(labels_order, display_names):
    val_acc  = histories[label].history['val_accuracy'][-1]
    test_acc = scores[label][1]
    t        = times[label]
    p        = params[label]
    print(f"{dname:>16} | {val_acc:>8.4f} | {test_acc:>9.4f} | {t:>8.1f} | {p:>12,}")
print("-" * 68)

最終結果サマリー

===== 最終結果サマリー =====
         Pattern |  Val Acc |  Test Acc |  Time(s) |       Params
--------------------------------------------------------------------
        A: SD なし |   0.7314 |    0.7280 |    258.6 |      695,114
  B: SD drop=0.1 |   0.8141 |    0.8162 |    266.6 |      695,114
  C: SD drop=0.2 |   0.7966 |    0.7923 |    267.7 |      695,114
--------------------------------------------------------------------

実験結果

精度グラフ

精度グラフ

損失グラフ

損失グラフ

A: SD なし

A: SD なし

B: SD drop=0.1

B: SD drop=0.1

C: SD drop=0.2

C: SD drop=0.2
パターン 最終 val_accuracy 最終 test_accuracy パラメータ数 学習時間
A: SD なし73.14%72.80%695,114258.6秒
B: SD drop=0.181.41%81.62%695,114266.6秒
C: SD drop=0.279.66%79.23%695,114267.7秒

3パターンのパラメータ数はすべて同一(695,114)です。Stochastic Depthレイヤー自体に学習パラメータはありません。

考察

① drop_rate=0.1で精度が約9ポイント向上——効果は顕著

SD なし(A)のtest_accuracy 72.80%に対し、drop_rate=0.1(B)は81.62%と約8.8ポイント上回りました。Stochastic Depthなしでは過学習が進んでいた可能性が高く、ブロック単位の確率的スキップが強力な正則化として機能していることが確認できます。

パラメータ数は3パターンとも695,114で完全に同一です。パラメータを増やさずにこれだけの精度向上が得られるのは、実務上非常に費用対効果が高い改善です。

② drop_rate=0.2は0.1より精度が低下——強すぎる正則化に注意

drop_rate=0.2(C)のtest_accuracy 79.23%はBの81.62%より約2.4ポイント低い結果になりました。drop_rateを上げすぎると、1エポック内でブロックがスキップされる回数が増えすぎてモデルの学習能力が低下します。今回の4ブロック構成ではdrop_rate=0.1が過学習抑制と学習能力のバランスが良いようです。

③ Stochastic DepthはDropoutとどう違うか

Dropoutは「ニューロン単位」でランダムにゼロにしますが、Stochastic Depthは「ブロック単位」でスキップします。ブロックごとスキップするとそのステップではブロックが存在しなかったのと同じ状態になるため、実効的な深さがステップごとに変動することになります。これが「確率的深度(Stochastic Depth)」という名前の由来です。

今回の結果を見ると、ブロック単位という大きな粒度での正則化が、今回のモデル規模(695K params・4ブロック)では特に効果的だったことがわかります。

④ drop_rateの目安

drop_rate今回の結果向いている状況
0.0(なし)test 72.80%浅いネット・データ量多め・過学習が軽微
0.1test 81.62%(最高)中程度の深さのネット。まずここから試す
0.2test 79.23%より深いネット(8層以上)・過学習が顕著な場合
0.3〜未検証非常に深いネット(ResNet50相当以上)

浅いブロックはネットワーク全体に与える影響が大きいため、一般的には深いブロックほどdrop_rateを高く設定する「Linear Decay」スケジュールが使われます。今回は簡略化して全ブロックを同一のdrop_rateにしていますが、実務では深さに応じてdrop_rateを変えるとより効果的です。

⑤ Residual接続なしでは使えない

⚠️ ハマりポイント:Stochastic DepthはResidual接続(スキップ接続)が必須です。ブロックをスキップしたとき、入力がそのままショートカットとして出力に渡されます。Residual接続がないモデルでブロックをスキップすると情報が完全にロストし、学習が崩壊します。今回のコードでは StochasticDepth(drop_rate)(x, shortcut) と呼び出すことでショートカット加算をStochastic Depthレイヤー内で行っています。

⑥ 学習時のスケーリングを忘れない

今回の実装では学習時に x / keep_prob * random_tensor でスケーリングしています。これはInverted Dropoutと同じ考え方で、学習時に期待値を保つことで推論時に特別なスケーリングが不要になります。スケーリングを省略すると、学習時と推論時でブロック出力の期待値がずれてしまい、精度が下がります。

関連記事

まとめ
  • drop_rate=0.1でtest_accuracyが72.80% → 81.62%(約+8.8ポイント)——パラメータ数を変えずにここまで改善できるのは費用対効果が高い
  • drop_rate=0.2はdrop_rate=0.1より約2.4ポイント低下——強すぎる正則化はモデルの学習能力を損なう。まずdrop_rate=0.1から試す
  • Stochastic Depth(DropPath)はResidualブロック全体をランダムにスキップする正則化——ニューロン単位のDropoutよりも大きな粒度での正則化
  • Residual接続(スキップ接続)が必須——ブロックをスキップしたときの出力はショートカット経由で渡される
  • パラメータ数への影響はなし(695,114で3パターン完全に同一)
  • 実務では深いブロックほどdrop_rateを上げる「Linear Decay」スケジュールが標準的