※この記事は、個人技術ブログ CodeArchPedia.com の技術メモ(要約)です。
機械学習モデルを構築していて、TensorFlowやKerasで「Invalid input shape」というエラーに遭遇した話。モデル定義でinput_shape=(N,)としたのに、学習時に(None, N)を期待され、データが通らないという現象です。このNoneが何を意味するのか、どこでつまずいているのか、検証を重ねた結果を共有します。
何が起きたか(課題)
学習時に発生した具体的なエラーとその症状は以下の通りです。
- モデル定義時の形状と、学習時の期待形状が一致しない。
-
input_shape=(28,)を指定したが、モデルは(None, 28)を要求している。 - 原因は、多くの場合、
tf.data.Datasetを使用している際のバッチ処理の欠如にある。 - エラーが解消した後も、次にターゲット(ラベル)の形状不一致でエラーになる場合がある。
どう解決したか(概要)
この問題の核心は、Kerasモデルが単一サンプルではなく、バッチ単位での入力を期待している点にあります。Kerasモデルのinput_shapeは単一サンプルの形状を指定しますが、model.fit()実行時は並列処理のためにデータがバッチ化されて渡されます。
tf.data.Dataset APIでこのバッチ処理を明示的に行うため、訓練データセットと検証データセットの両方に.batch(BATCH_SIZE)を適用しました。これにより、単一データ(28,)の取り出しから、モデルが期待する(バッチサイズ, 28)の形状を持つデータパイプラインへと修正できました。
(None, 28)のNoneは、バッチサイズが実行時に可変であることを示す重要なインジケータです。TensorFlowは最後のバッチが不完全な場合にも対応できるように、この表記を使います。
また、入力形状エラーが解消した後、ラベル(ターゲット)とモデル出力の次元数(ランク)が一致しないエラー(例:ターゲットが(None,)、出力が(None, 1))に遭遇するケースもあります。これは、ラベルデータにも明示的に次元を追加し、形状を(バッチサイズ, 1)に揃えることで解決しました。具体的には、.map()関数内でtf.expand_dims(y, axis=-1)を使用して形状を拡張するアプローチを取りました。
効果(Before/After)
バッチ処理をデータパイプラインに組み込んだ結果、以前は発生していた形状不一致による学習の中断が完全に解消しました。また、ラベル形状の調整により、モデル出力とターゲットの次元不一致エラーもなくなり、安定して学習が進行するようになりました。
- Before: 形状不一致により
model.fit()が即座に失敗。 - After: データパイプラインが最適化され、GPUの並列処理能力を活かしたスムーズな学習が実現。
🚀 詳細な設定とコードはこちら
具体的なWAFのルール設定や、より詳細なログ解析データは元のブログで公開しています。