KerasでConv2Dを書くとき、kernel_size はほぼ自動的に (3, 3) にしていませんか?
では 5×5 にしたら精度は上がるのでしょうか?1×1 は何の意味があるのでしょうか?今回はGoogle ColabとCIFAR-10を使い、kernel_sizeを3×3・5×5・1×1の3パターンで比較しました。
📘 この記事でわかること
- kernel_sizeを変えると精度・パラメータ数・学習時間がどう変わるか
- 1×1カーネルの役割と使い所
- CIFAR-10レベルで最適なkernel_sizeの選び方
kernel_sizeとは?変えると何が起きるか
kernel_size は畳み込みの「窓」のサイズです。(3, 3) なら3×3ピクセルの領域から特徴を検出します。
| kernel_size | 受容野 | パラメータ数(フィルター1つ) | 特徴 |
|---|---|---|---|
| (3, 3) | 3×3 | 3×3×入力ch | エッジ・テクスチャ検出に最も広く使われる標準サイズ |
| (5, 5) | 5×5 | 5×5×入力ch | より広い範囲の特徴を一度に捉えられる。パラメータ増 |
| (1, 1) | 1×1 | 1×1×入力ch | 空間情報を見ない。チャンネル間の情報統合に使う |
パラメータ数は kernel_size の2乗に比例して増えます。5×5 は 3×3 の約2.8倍のパラメータを持ちます。
実験コード
使用環境はGoogle Colab(GPU:T4)、データセットはCIFAR-10です。kernel_size以外の条件は全て同一にして、kernel_sizeの影響だけを取り出します。
環境準備・import・データ準備
# ── 環境準備(最初に一度だけ実行)──────────────────────
!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 42 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 1s (7,611 kB/s)
Selecting previously unselected package fonts-ipafont-gothic.
(Reading database ... 122354 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 43.4 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
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
def build_model(kernel_size, name):
return keras.Sequential([
keras.layers.Input(shape=(32, 32, 3)),
keras.layers.Conv2D(64, kernel_size, activation='relu', padding='same'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Conv2D(128, kernel_size, activation='relu', padding='same'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.2),
keras.layers.Dense(10, activation='softmax'),
], 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
実行結果をクリックして内容を開く
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 170498071/170498071 ━━━━━━━━━━━━━━━━━━━━ 6s 0us/step
3パターンの学習実行
configs = [((3, 3), 'A_kernel3x3'), ((5, 5), 'B_kernel5x5'), ((1, 1), 'C_kernel1x1')]
histories, times, scores, params = {}, {}, {}, {}
for kernel_size, name in configs:
print(f"\n=== {name} ===")
model = build_model(kernel_size, name)
print(model.summary())
h, t = compile_and_fit(model)
s = model.evaluate(x_test, y_test, verbose=0)
label = f"{name.split('_')[1]}"
histories[label] = h
times[label] = t
scores[label] = s
params[label] = model.count_params()
print(f"学習時間:{t:.1f}秒 パラメータ数:{model.count_params():,}")
実行結果をクリックして内容を開く
=== A_kernel3x3 === Model: "A_kernel3x3" ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ conv2d (Conv2D) │ (None, 32, 32, 64) │ 1,792 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ max_pooling2d (MaxPooling2D) │ (None, 16, 16, 64) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ conv2d_1 (Conv2D) │ (None, 16, 16, 128) │ 73,856 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ max_pooling2d_1 (MaxPooling2D) │ (None, 8, 8, 128) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ global_average_pooling2d │ (None, 128) │ 0 │ │ (GlobalAveragePooling2D) │ │ │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense (Dense) │ (None, 128) │ 16,512 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dropout (Dropout) │ (None, 128) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense_1 (Dense) │ (None, 10) │ 1,290 │ └─────────────────────────────────┴────────────────────────┴───────────────┘ Total params: 93,450 (365.04 KB) Trainable params: 93,450 (365.04 KB) Non-trainable params: 0 (0.00 B) None Epoch 1/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 17s 15ms/step - accuracy: 0.2726 - loss: 1.9066 - val_accuracy: 0.3609 - val_loss: 1.7075 Epoch 2/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - accuracy: 0.3783 - loss: 1.6535 - val_accuracy: 0.4159 - val_loss: 1.6028 Epoch 3/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 6ms/step - accuracy: 0.4344 - loss: 1.5416 - val_accuracy: 0.4763 - val_loss: 1.4530 Epoch 4/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.4661 - loss: 1.4570 - val_accuracy: 0.4825 - val_loss: 1.3890 Epoch 5/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.4939 - loss: 1.3816 - val_accuracy: 0.5091 - val_loss: 1.3529 Epoch 6/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.5138 - loss: 1.3373 - val_accuracy: 0.5253 - val_loss: 1.3025 Epoch 7/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.5280 - loss: 1.2957 - val_accuracy: 0.5391 - val_loss: 1.2659 Epoch 8/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.5386 - loss: 1.2642 - val_accuracy: 0.5526 - val_loss: 1.2211 Epoch 9/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.5571 - loss: 1.2310 - val_accuracy: 0.5509 - val_loss: 1.2408 Epoch 10/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - accuracy: 0.5621 - loss: 1.2067 - val_accuracy: 0.5797 - val_loss: 1.1683 Epoch 11/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.5746 - loss: 1.1745 - val_accuracy: 0.5854 - val_loss: 1.1548 Epoch 12/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.5837 - loss: 1.1527 - val_accuracy: 0.5894 - val_loss: 1.1195 Epoch 13/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.5918 - loss: 1.1280 - val_accuracy: 0.5907 - val_loss: 1.1399 Epoch 14/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.5990 - loss: 1.1072 - val_accuracy: 0.5932 - val_loss: 1.1179 Epoch 15/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6075 - loss: 1.0825 - val_accuracy: 0.6088 - val_loss: 1.0804 Epoch 16/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6146 - loss: 1.0684 - val_accuracy: 0.6072 - val_loss: 1.0897 Epoch 17/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6253 - loss: 1.0435 - val_accuracy: 0.6184 - val_loss: 1.0496 Epoch 18/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6296 - loss: 1.0301 - val_accuracy: 0.6330 - val_loss: 1.0272 Epoch 19/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6348 - loss: 1.0154 - val_accuracy: 0.6169 - val_loss: 1.0510 Epoch 20/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6398 - loss: 0.9997 - val_accuracy: 0.6448 - val_loss: 1.0047 Epoch 21/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6449 - loss: 0.9833 - val_accuracy: 0.6390 - val_loss: 0.9992 Epoch 22/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6518 - loss: 0.9690 - val_accuracy: 0.6518 - val_loss: 0.9814 Epoch 23/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6557 - loss: 0.9597 - val_accuracy: 0.6375 - val_loss: 0.9924 Epoch 24/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6649 - loss: 0.9441 - val_accuracy: 0.6563 - val_loss: 0.9539 Epoch 25/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6690 - loss: 0.9250 - val_accuracy: 0.6703 - val_loss: 0.9348 Epoch 26/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6744 - loss: 0.9163 - val_accuracy: 0.6605 - val_loss: 0.9412 Epoch 27/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.6768 - loss: 0.9031 - val_accuracy: 0.6686 - val_loss: 0.9345 Epoch 28/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6791 - loss: 0.8933 - val_accuracy: 0.6779 - val_loss: 0.9046 Epoch 29/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 6ms/step - accuracy: 0.6854 - loss: 0.8763 - val_accuracy: 0.6800 - val_loss: 0.8978 Epoch 30/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.6897 - loss: 0.8695 - val_accuracy: 0.6680 - val_loss: 0.9331 学習時間:140.6秒 パラメータ数:93,450 === B_kernel5x5 === Model: "B_kernel5x5" ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ conv2d_2 (Conv2D) │ (None, 32, 32, 64) │ 4,864 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ max_pooling2d_2 (MaxPooling2D) │ (None, 16, 16, 64) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ conv2d_3 (Conv2D) │ (None, 16, 16, 128) │ 204,928 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ max_pooling2d_3 (MaxPooling2D) │ (None, 8, 8, 128) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ global_average_pooling2d_1 │ (None, 128) │ 0 │ │ (GlobalAveragePooling2D) │ │ │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense_2 (Dense) │ (None, 128) │ 16,512 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dropout_1 (Dropout) │ (None, 128) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense_3 (Dense) │ (None, 10) │ 1,290 │ └─────────────────────────────────┴────────────────────────┴───────────────┘ Total params: 227,594 (889.04 KB) Trainable params: 227,594 (889.04 KB) Non-trainable params: 0 (0.00 B) None Epoch 1/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 11s 11ms/step - accuracy: 0.2840 - loss: 1.8832 - val_accuracy: 0.3887 - val_loss: 1.6447 Epoch 2/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - accuracy: 0.4086 - loss: 1.5957 - val_accuracy: 0.4493 - val_loss: 1.5091 Epoch 3/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.4725 - loss: 1.4430 - val_accuracy: 0.4972 - val_loss: 1.3843 Epoch 4/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 8s 13ms/step - accuracy: 0.5089 - loss: 1.3495 - val_accuracy: 0.5467 - val_loss: 1.2532 Epoch 5/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.5325 - loss: 1.2849 - val_accuracy: 0.5580 - val_loss: 1.2141 Epoch 6/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step - accuracy: 0.5594 - loss: 1.2228 - val_accuracy: 0.5779 - val_loss: 1.1650 Epoch 7/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step - accuracy: 0.5766 - loss: 1.1741 - val_accuracy: 0.6001 - val_loss: 1.1179 Epoch 8/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 9s 15ms/step - accuracy: 0.5973 - loss: 1.1242 - val_accuracy: 0.5994 - val_loss: 1.1076 Epoch 9/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step - accuracy: 0.6106 - loss: 1.0948 - val_accuracy: 0.6127 - val_loss: 1.0773 Epoch 10/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.6241 - loss: 1.0573 - val_accuracy: 0.6303 - val_loss: 1.0467 Epoch 11/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.6312 - loss: 1.0279 - val_accuracy: 0.6258 - val_loss: 1.0554 Epoch 12/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.6453 - loss: 0.9977 - val_accuracy: 0.6376 - val_loss: 1.0041 Epoch 13/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step - accuracy: 0.6488 - loss: 0.9776 - val_accuracy: 0.6539 - val_loss: 0.9786 Epoch 14/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.6591 - loss: 0.9555 - val_accuracy: 0.6657 - val_loss: 0.9387 Epoch 15/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - accuracy: 0.6667 - loss: 0.9320 - val_accuracy: 0.6699 - val_loss: 0.9401 Epoch 16/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.6779 - loss: 0.9072 - val_accuracy: 0.6657 - val_loss: 0.9440 Epoch 17/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.6805 - loss: 0.8927 - val_accuracy: 0.6671 - val_loss: 0.9275 Epoch 18/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 10s 8ms/step - accuracy: 0.6896 - loss: 0.8700 - val_accuracy: 0.6789 - val_loss: 0.9143 Epoch 19/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step - accuracy: 0.6964 - loss: 0.8531 - val_accuracy: 0.6889 - val_loss: 0.8944 Epoch 20/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7039 - loss: 0.8367 - val_accuracy: 0.6899 - val_loss: 0.8752 Epoch 21/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step - accuracy: 0.7109 - loss: 0.8184 - val_accuracy: 0.6884 - val_loss: 0.8761 Epoch 22/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 6s 9ms/step - accuracy: 0.7160 - loss: 0.7996 - val_accuracy: 0.6905 - val_loss: 0.8733 Epoch 23/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - accuracy: 0.7199 - loss: 0.7923 - val_accuracy: 0.6731 - val_loss: 0.9316 Epoch 24/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7241 - loss: 0.7752 - val_accuracy: 0.7007 - val_loss: 0.8594 Epoch 25/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7287 - loss: 0.7607 - val_accuracy: 0.7058 - val_loss: 0.8509 Epoch 26/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step - accuracy: 0.7322 - loss: 0.7497 - val_accuracy: 0.7054 - val_loss: 0.8467 Epoch 27/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7406 - loss: 0.7311 - val_accuracy: 0.7092 - val_loss: 0.8276 Epoch 28/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 9ms/step - accuracy: 0.7451 - loss: 0.7190 - val_accuracy: 0.7040 - val_loss: 0.8451 Epoch 29/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 5s 8ms/step - accuracy: 0.7499 - loss: 0.7077 - val_accuracy: 0.7113 - val_loss: 0.8339 Epoch 30/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 6s 10ms/step - accuracy: 0.7562 - loss: 0.6914 - val_accuracy: 0.7089 - val_loss: 0.8415 学習時間:179.7秒 パラメータ数:227,594 === C_kernel1x1 === Model: "C_kernel1x1" ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ conv2d_4 (Conv2D) │ (None, 32, 32, 64) │ 256 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ max_pooling2d_4 (MaxPooling2D) │ (None, 16, 16, 64) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ conv2d_5 (Conv2D) │ (None, 16, 16, 128) │ 8,320 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ max_pooling2d_5 (MaxPooling2D) │ (None, 8, 8, 128) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ global_average_pooling2d_2 │ (None, 128) │ 0 │ │ (GlobalAveragePooling2D) │ │ │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense_4 (Dense) │ (None, 128) │ 16,512 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dropout_2 (Dropout) │ (None, 128) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense_5 (Dense) │ (None, 10) │ 1,290 │ └─────────────────────────────────┴────────────────────────┴───────────────┘ Total params: 26,378 (103.04 KB) Trainable params: 26,378 (103.04 KB) Non-trainable params: 0 (0.00 B) None Epoch 1/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 7s 7ms/step - accuracy: 0.2155 - loss: 2.0757 - val_accuracy: 0.2454 - val_loss: 1.9937 Epoch 2/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.2651 - loss: 1.9540 - val_accuracy: 0.2856 - val_loss: 1.9238 Epoch 3/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.2864 - loss: 1.9144 - val_accuracy: 0.2959 - val_loss: 1.9007 Epoch 4/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.2961 - loss: 1.8837 - val_accuracy: 0.3007 - val_loss: 1.8741 Epoch 5/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3066 - loss: 1.8609 - val_accuracy: 0.3183 - val_loss: 1.8438 Epoch 6/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3160 - loss: 1.8418 - val_accuracy: 0.3307 - val_loss: 1.8216 Epoch 7/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3277 - loss: 1.8213 - val_accuracy: 0.3330 - val_loss: 1.8076 Epoch 8/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3329 - loss: 1.8055 - val_accuracy: 0.3356 - val_loss: 1.8132 Epoch 9/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 6ms/step - accuracy: 0.3410 - loss: 1.7890 - val_accuracy: 0.3464 - val_loss: 1.7840 Epoch 10/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3458 - loss: 1.7785 - val_accuracy: 0.3558 - val_loss: 1.7572 Epoch 11/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3529 - loss: 1.7668 - val_accuracy: 0.3579 - val_loss: 1.7630 Epoch 12/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3559 - loss: 1.7542 - val_accuracy: 0.3658 - val_loss: 1.7352 Epoch 13/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.3645 - loss: 1.7430 - val_accuracy: 0.3740 - val_loss: 1.7183 Epoch 14/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3672 - loss: 1.7335 - val_accuracy: 0.3746 - val_loss: 1.7126 Epoch 15/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3738 - loss: 1.7238 - val_accuracy: 0.3825 - val_loss: 1.7090 Epoch 16/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3717 - loss: 1.7204 - val_accuracy: 0.3761 - val_loss: 1.7012 Epoch 17/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.3794 - loss: 1.7109 - val_accuracy: 0.3917 - val_loss: 1.6843 Epoch 18/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3825 - loss: 1.7017 - val_accuracy: 0.3891 - val_loss: 1.6821 Epoch 19/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3815 - loss: 1.6985 - val_accuracy: 0.3950 - val_loss: 1.6666 Epoch 20/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3880 - loss: 1.6874 - val_accuracy: 0.3958 - val_loss: 1.6750 Epoch 21/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.3879 - loss: 1.6850 - val_accuracy: 0.4049 - val_loss: 1.6559 Epoch 22/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3915 - loss: 1.6812 - val_accuracy: 0.3962 - val_loss: 1.6720 Epoch 23/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3951 - loss: 1.6734 - val_accuracy: 0.4020 - val_loss: 1.6604 Epoch 24/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 4s 6ms/step - accuracy: 0.3957 - loss: 1.6724 - val_accuracy: 0.4012 - val_loss: 1.6596 Epoch 25/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3973 - loss: 1.6655 - val_accuracy: 0.4021 - val_loss: 1.6519 Epoch 26/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.3994 - loss: 1.6614 - val_accuracy: 0.4205 - val_loss: 1.6301 Epoch 27/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.4021 - loss: 1.6581 - val_accuracy: 0.4155 - val_loss: 1.6368 Epoch 28/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.4049 - loss: 1.6507 - val_accuracy: 0.4148 - val_loss: 1.6235 Epoch 29/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.4062 - loss: 1.6455 - val_accuracy: 0.4104 - val_loss: 1.6435 Epoch 30/30 625/625 ━━━━━━━━━━━━━━━━━━━━ 3s 5ms/step - accuracy: 0.4085 - loss: 1.6404 - val_accuracy: 0.4226 - val_loss: 1.6140 学習時間:103.1秒 パラメータ数:26,378
グラフ+サマリー
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
for label, h in histories.items():
axes[0].plot(h.history['val_accuracy'], label=label)
axes[1].plot(h.history['val_loss'], label=label)
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('kernelsize_comparison.png', dpi=150)
plt.show()
print("\n===== 最終結果サマリー =====")
print(f"{'Pattern':>12} | {'Val Acc':>8} | {'Test Acc':>9} | {'Time(s)':>8} | {'Params':>12}")
print("-" * 58)
for label in ['kernel3x3', 'kernel5x5', 'kernel1x1']:
val_acc = histories[label].history['val_accuracy'][-1]
test_acc = scores[label][1]
t = times[label]
p = params[label]
print(f"{label:>12} | {val_acc:>8.4f} | {test_acc:>9.4f} | {t:>8.1f} | {p:>12,}")
結果サマリ
===== 最終結果サマリー =====
Pattern | Val Acc | Test Acc | Time(s) | Params
----------------------------------------------------------
kernel3x3 | 0.6680 | 0.6614 | 140.6 | 93,450
kernel5x5 | 0.7089 | 0.6970 | 179.7 | 227,594
kernel1x1 | 0.4226 | 0.4157 | 103.1 | 26,378
実験結果
精度グラフ
損失グラフ
| パターン | 最終 val_accuracy | 最終 test_accuracy | パラメータ数 | 学習時間 |
|---|---|---|---|---|
| A:kernel_size=(3,3) | 66.80% | 66.14% | 93,450 | 140.6秒 |
| B:kernel_size=(5,5) | 70.89% | 69.70% | 227,594 | 179.7秒 |
| C:kernel_size=(1,1) | 42.26% | 41.57% | 26,378 | 103.1秒 |
考察
① 3×3 vs 5×5:5×5が精度で上回ったが、コストも増大
予想に反して 5×5が最高精度(69.70%) となり、3×3(66.14%)を約3.6%上回りました。5×5カーネルはより広い範囲の特徴を一度に捉えられるため、CIFAR-10の物体のシルエットや形状を捉えるのに有利だったと考えられます。
ただしコストの差も明確です。パラメータ数は3×3の約2.4倍(93,450→227,594)、学習時間は約1.3倍(140.6秒→179.7秒)です。精度の向上幅(3.6%)に対してコストの増加(2.4倍)が大きく、効率面では3×3に分があります。
また、CIFAR-10(32×32)程度の低解像度画像では5×5の広い受容野は相対的に有利ですが、さらに解像度が小さくなると過剰な圧縮になる可能性もあります。
② 1×1 カーネルは単独では機能しない
1×1 カーネルはtest_accuracy 41.57%と、ランダム分類(10クラスなら10%)よりは高いものの、3×3と比べて約25%低い結果になりました。
理由は明確で、1×1カーネルは空間方向(縦・横)の情報を全く参照しないためです。ピクセルごとに独立してチャンネルを混合するだけで、エッジ・テクスチャ・形状といった画像の空間的な特徴が抽出できません。
1×1カーネルの本来の使い所はチャンネル数の圧縮・拡張です。3×3カーネルの前後に1×1を組み合わせて計算量を削減する「Bottleneck構造」(ResNetなど)や、チャンネル間の情報を統合するGoogleNetのInception構造に使われています。単独で画像分類に使うものではありません。
③ kernel_sizeの選び方
今回の実験結果から以下の判断基準が得られます。
| 状況 | 推奨 | 理由 |
|---|---|---|
| 迷ったとき・プロトタイプ | (3, 3) | パラメータ数・速度・精度のバランスが最良 |
| 精度を優先・コストを許容できる | (5, 5) | より広い受容野で精度向上。ただしパラメータ約2.4倍 |
| チャンネル数を調整したい | (1, 1) | 次元変換専用。Bottleneck構造などに組み合わせて使う |
まとめ
- 5×5が最高精度(69.70%)だったが、パラメータ数は3×3の約2.4倍・学習時間は約1.3倍とコスト増が大きい
- 3×3は精度・速度・パラメータ数のバランスが最良。迷ったらまず3×3から試すのが正解
- 1×1は単独の画像分類には不向き(41.57%)。空間的な特徴を捉えられないため。Bottleneck構造などに組み合わせて使うのが正しい使い方
関連記事もあわせてどうぞ:
- Conv2Dのフィルター数の選び方 → Conv2DのFilters数(32 vs 64 vs 128)を変えると精度はどう変わる?【CIFAR-10実験】
- MaxPoolingのpool_size比較 → GAPモデルでMaxPoolingのpool_sizeを変えると精度はどう変わる?【Keras実験・予想外の結果】
- Dropout率の比較実験 → Dropoutの割合(0.0 vs 0.2 vs 0.5)を変えると過学習はどう変わる?【Keras×CIFAR-10実験】
- model.summary()の読み方 → Kerasのmodel.summary()の読み方を徹底解説|パラメータ数の計算方法【初心者向け】



0 件のコメント:
コメントを投稿