Kerasのmodel.summary()の読み方を徹底解説|パラメータ数の計算方法【初心者向け】

投稿日:2026年4月11日土曜日 最終更新日:

CNN Google Colab Keras model.summary() Python

X f B! P L
アイキャッチ画像 Kerasのmodel.summary()の読み方を徹底解説|パラメータ数の計算方法【初心者向け】

Kerasでモデルを作ると、こんな出力を必ず目にします。

model.summary()

でも最初のうちは、「Output ShapeのNoneって何?」「Param # はどうやって計算されてるの?」と疑問に思いながら読み飛ばしてしまいがちです。

この記事では、model.summary()の各列の意味パラメータ数の計算方法を、CNNモデルを例に使ってひとつずつ丁寧に解説します。一度理解してしまえば、モデルの設計ミスやパラメータ数の膨らみにもすぐ気づけるようになります。

📘 この記事でわかること

  • model.summary()の3つの列(Layer / Output Shape / Param #)の読み方
  • Conv2D・Dense・Pooling・Flatten層それぞれのパラメータ数の計算方法
  • パラメータ数を確認するべき理由(過学習との関係)

model.summary()を表示するコード

まず確認用のシンプルなCNNモデルをKerasで作り、summary()を表示してみます。データセットはMNIST(28×28のグレースケール画像)を想定しています。

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    keras.Input(shape=(28, 28, 1)),
    layers.Conv2D(32, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(10, activation='softmax'),
])

model.summary()

ここでDense層を2層(64次元 → 10次元)にしているのには理由があります。5,408次元をいきなり10次元に落とすより、一度中間層で特徴を整理してからクラス分類する方が、モデルが複雑なパターンを学習しやすいためです。ただしMNISTのようなシンプルなデータでは、Dense層を1層にしても精度はほとんど変わりません。今回はパラメータ計算のパターンを2種類紹介するという教育的な目的もあって2層にしています。

実行すると、以下のような出力が得られます。

Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ conv2d (Conv2D)                 │ (None, 26, 26, 32)     │           320 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling2d (MaxPooling2D)    │ (None, 13, 13, 32)     │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ flatten (Flatten)               │ (None, 5408)           │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense)                   │ (None, 64)             │       346,176 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense)                 │ (None, 10)             │           650 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 347,146 (1.32 MB)
 Trainable params: 347,146 (1.32 MB)
 Non-trainable params: 0 (0.00 B)

では、この表をひとつずつ読み解いていきましょう。


3つの列の意味

① Layer (type):層の名前と種類

そのままの意味で、モデルに追加した層の名前と種類が表示されます。Sequential APIで作ると自動で conv2d dense などと命名されます。Functional APIや name= 引数で任意の名前をつけることもできます。

② Output Shape:その層が出力するテンソルの形

各層を通過したあとのデータの「形(shape)」が表示されます。たとえば (None, 26, 26, 32) は「バッチサイズ × 縦26 × 横26 × チャンネル32」を意味します。

先頭の None はバッチサイズです。バッチサイズはコンパイル時には未確定なので、Kerasは None として表示します。実際の学習時には 3264 などの値が入ります。

③ Param #:その層が持つ学習パラメータの数

その層が持つ「重み(weight)」と「バイアス(bias)」の合計数です。学習の際に調整される値の数です。多いほどモデルが複雑になり、過学習のリスクも上がります。

Pooling層とFlatten層は常に 0 です。これらはデータを変換するだけで、学習可能なパラメータを持ちません。


Output Shape の変化を追う

入力から出力まで、データの形がどう変わるかを順番に見てみましょう。

入力:(None, 28, 28, 1)

MNISTの入力画像。28×28ピクセル、チャンネル数1(グレースケール)。

Conv2D(32, (3,3)) → (None, 26, 26, 32)

3×3のカーネルを padding='valid'(デフォルト)で適用すると、縦横それぞれ (28 - 3 + 1) = 26 になります。フィルター数32なので、チャンネルが32になります。

MaxPooling2D((2,2)) → (None, 13, 13, 32)

2×2の領域で最大値をとり、サイズが半分になります。26 ÷ 2 = 13。チャンネル数は変わりません。

Flatten() → (None, 5408)

多次元テンソルを1次元ベクトルに展開します。13 × 13 × 32 = 5,408

Dense(64) → (None, 64)

全結合層。5,408次元の入力を64次元に変換します。

Dense(10) → (None, 10)

出力層。MNIST(0〜9)の10クラス分類なので10次元。Softmaxで確率に変換します。


Param # の計算方法

Param # がどのように計算されているかを、各層ごとに確認します。一度理解すると、モデル設計のときにパラメータ数を頭の中で見積もれるようになります。

Conv2D:320パラメータ

計算式はこうなります:

(カーネルH × カーネルW × 入力チャンネル数 + 1) × フィルター数

今回の場合:

(3 × 3 × 1 + 1) × 32 = 10 × 32 = 320

+1 はバイアス(bias)の分です。バイアスはフィルターごとに1つ存在します。use_bias=False を指定するとバイアスなしにもできます。

MaxPooling2D:0パラメータ

Pooling層は「領域内の最大値を取る」という固定の演算を行うだけで、学習可能なパラメータを持ちません。

Flatten:0パラメータ

データの形を変えるだけで、演算や学習はありません。

Dense(64):346,176パラメータ

計算式:

(入力ユニット数 + 1) × 出力ユニット数
(5408 + 1) × 64 = 5409 × 64 = 346,176

Flattenで5,408次元になった入力を、64次元に変換します。各入力ユニットから各出力ユニットへの重みが全部で 5,408 × 64 本、それにバイアスが64個で 346,176 になります。

Denseのパラメータ数が膨らむ原因はここです。 Flattenの出力次元(5,408)が大きければ大きいほど、その後のDense層のパラメータ数が爆発的に増えます。

Dense(10):650パラメータ

(64 + 1) × 10 = 65 × 10 = 650

64次元を10次元(クラス数)に変換します。


Total params の内訳

Total params:     347,146
Trainable params: 347,146
Non-trainable params: 0

Trainable params:学習中に更新されるパラメータの数。
Non-trainable params:固定されて更新されないパラメータ。BatchNormalizationを使うときや、転移学習でベースモデルをフリーズしたときにここに数が出ます。

今回はシンプルなモデルなのでNon-trainable paramsは0ですが、たとえばMobileNetV2を使って特定の層を layer.trainable = False で固定すると、その分がNon-trainableに移ります。


パラメータ数と過学習の関係

パラメータ数はモデルの「表現力の大きさ」を表します。パラメータが多いほど複雑なパターンを学習できますが、一方で訓練データへの過学習が起きやすくなります

今回のモデルでは Dense(64) の1層だけで346,176パラメータを占めています。これはConv2DやMaxPoolingなど残りの全層を合わせたパラメータの約1,000倍です。

このように、Flatten → Dense の組み合わせがパラメータ数を一気に増やす原因になりがちです。これを防ぐ手法のひとつが GlobalAveragePooling2D(GAP)です。FlattenをGAPに置き換えると、Denseへの入力次元を大幅に小さくできます。

※FlattenとGAPの比較実験はこちらの記事で詳しく解説しています:
Global Average Pooling vs Flatten|CNNの最終層、どっちが精度・速度で有利か?【Keras実験】


補足:count_params() でパラメータ数を数値で取得する

summary()の表示だけでなく、パラメータ数をコードの中で数値として取得したいときは count_params() が使えます。

print(model.count_params())
# → 347146

複数モデルを比較するスクリプトや、実験ログに記録したいときに便利です。


まとめ

model.summary()の各列をまとめると次のようになります。

列名 意味 注意点
Layer (type) 層の名前と種類 nameで任意の名前をつけられる
Output Shape その層の出力テンソルの形 先頭のNoneはバッチサイズ(未確定)
Param # 学習パラメータ(重み+バイアス)の数 Pooling・Flattenは常に0

パラメータ数の計算式まとめ:

  • Conv2D:(カーネルH × カーネルW × 入力ch + 1) × フィルター数
  • Dense:(入力ユニット数 + 1) × 出力ユニット数
  • MaxPooling / AveragePooling / Flatten:常に 0

model.summary()を読む習慣をつけると、「パラメータが多すぎないか」「特徴マップのサイズが想定通りか」を毎回確認できます。モデルの設計ミスを早期に発見するためにも、summary()をこまめに確認するようにしましょう。

関連記事もあわせてどうぞ: