🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

4547閲覧

kerasのCNNで「入力次元が間違っている」というエラーが出る

yolloy

総合スコア5

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/12/06 15:30

前提・実現したいこと

Kerasを用いてCNNを実装しようとしています。
RGBAのような4チャンネルの画像データを読み込ませて学習させることを検討しています。最終的にResNetのネットワーク構造で利用したいので、kerasのfunctional APIで実装しています。

手始めにダミーデータを作成し、作成したネットワークで読み込めるか試している最中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

x_train.shape = (7, 8, 8, 4) <class 'tensorflow.python.framework.ops.Tensor'> input.shape = (None, 8, 8, 4) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-15-a964a900b16c> in <module>() 47 model = ResNet(img_rows,img_cols,img_channels, x_train) 48 #model = ResNet(32, 32, 3, x_train) ---> 49 history = model.fit(x_train, y_train, batch_size=2, epochs=20, validation_data = (x_test, y_test), verbose = 0) 50 51 # モデルをプロット ~\AppData\Roaming\Python\Python37\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs) 1152 sample_weight=sample_weight, 1153 class_weight=class_weight, -> 1154 batch_size=batch_size) 1155 1156 # Prepare validation data. ~\AppData\Roaming\Python\Python37\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size) 619 feed_output_shapes, 620 check_batch_axis=False, # Don't enforce the batch size. --> 621 exception_prefix='target') 622 623 # Generate sample-wise weight values given the `sample_weight` and ~\AppData\Roaming\Python\Python37\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix) 133 ': expected ' + names[i] + ' to have ' + 134 str(len(shape)) + ' dimensions, but got array ' --> 135 'with shape ' + str(data_shape)) 136 if not check_batch_axis: 137 data_shape = data_shape[1:] ValueError: Error when checking target: expected dense_10 to have 4 dimensions, but got array with shape (7, 8, 8)

エラーの内容は「dense層に与えられる入力の形状は4次元のはずなのに、君は(7,8,8)の3次元で渡してるからダメだよ!」とのことです。この(7,8,8)は(バッチサイズ,画像の行数,画像の列数)です。正常に動作させるには、(バッチサイズ,画像の行数,画像の列数,チャンネル数)の4次元が必要だと思われます。

該当のソースコード

ネットワーク構成部とダミーデータ作成部で構成しています。

ネットワーク構成部(エラー箇所確認のため、中間層をコメントアウトしています)

#~ResNetモデル構築~ from keras.layers import Dense, Dropout, Activation, Flatten, Input, add from keras.layers import Conv2D from keras.layers.normalization import BatchNormalization from keras import Model from keras import optimizers import numpy as np def rescell(data, filters, kernel_size): strides=(1,1) x=Conv2D(filters=filters,kernel_size=kernel_size,strides=strides,padding="same")(data) x=BatchNormalization()(x) x=Activation('relu')(x) data=Conv2D(filters=int(x.shape[3]), kernel_size=(1,1), strides=strides, padding="same")(data) x=Conv2D(filters=filters,kernel_size=kernel_size,strides=(1,1),padding="same")(x) x=BatchNormalization()(x) x=add([x,data]) x=Activation('relu')(x) return x def ResNet(img_rows, img_cols, img_channels, x_train): #inputs=Input(batch_shape=(None,img_rows,img_cols,img_channels)) inputs = Input(shape=x_train.shape[1:]) ''' x=Conv2D(filters=256, kernel_size(3,3), padding="same", input_shape=x_train.shape[1:],activation="relu")(input) x=MaxPooling2D(pool_size=(2,2))(x) ''' #print(type(inputs)) #aaaaaaaaaaaaaaaaaaaaaaaaaa #第1層 #''' print("input.shape = " + str(inputs.shape)) #''' #メモ:input_shapeはbatch_sizeを含まない #input= np.expand_dims(input, axis=0) #Conv2D は (BatchSize, Height, Width, Channels)の4次元入力を期待している???????????? #メモ:層の引数input_shapeは1データの形状を記述するので、画像を入れるなら3次元(行、列、チャンネル)の表記にする。 #  ただし、実際に渡すデータは4次元の(バッチサイズ、行、列、チャンネル)である必要がある。 x=Conv2D(filters=256, kernel_size=(3,3), padding="same", input_shape=(img_rows,img_cols,img_channels))(inputs) ''' x=BatchNormalization()(x) x=Activation('relu')(x) #第2~39層 for i in range(19): x=rescell(x,256,(3,3)) #次の1手予測部第1層 x=Conv2D(filters=2, kernel_size=(1,1), padding="same")(x) x=BatchNormalization()(x) x=Activation('relu')(x) #次の1手予測部第2層 x=Flatten()(x) #1次元に整形 ''' x=Dense(units=8*8, kernel_initializer="he_normal", activation="softmax")(x) #全結合層 model=Model(inputs=inputs,outputs=[x]) #model.compile(loss="softmax_cross_entropy_with_logits", optimizer=SGD(lr=self.learning_rate, momentum = config.MOMENTUM)) adam = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False) model.compile(loss='categorical_crossentropy', optimizer=adam) return model

ダミーデータ作成部

import numpy as np from sklearn.model_selection import train_test_split #ダミーデータ作成 data_n = 10 #学習データの数 img_rows = 8 #画像の行数 img_cols = 8 #画像の列数 img_channels = 4 #画像のチャンネル数 data_x = [] data_y = [] for i in range(data_n): row_x = [] row_y = [] for j in range(img_rows): col_x = [] col_y = [] for k in range(img_cols): channel_x = [] for l in range(img_channels): channel_x.append(1) col_x.append(channel_x) col_y.append(1) row_x.append(col_x) row_y.append(col_y) data_x.append(row_x) data_y.append(row_y) #data_x = np.expand_dims(np.array(data_x), axis=-1) #data_y = np.expand_dims(np.array(data_y), axis=-1) x_train = np.array(data_x) y_train = np.array(data_y) x_train, x_test, y_train, y_test = train_test_split(x_train, y_train, test_size=0.30) print("x_train.shape = "+str(x_train.shape)) model = ResNet(img_rows,img_cols,img_channels, x_train) history = model.fit(x_train, y_train, batch_size=2, epochs=20, validation_data = (x_test, y_test), verbose = 0)

試したこと

・エラーの発生しているDense層をコメントアウトして実行しました。
結果:Conv2d層で同様のエラーが出た。
→エラーの原因はConv2dに入力されるinputsにある?

・kerasでCNNを実装するときの入力形状について調べました。Conv2D()の引数として指定するinput_shapeにはバッチサイズは含めないこと。例えば50000枚の32*32サイズのRGB画像を読み込ませたいなら、input_shape=(32,32,3)と記述する。ネットワーク構成部のConv2Dではinput_shape=(img_rows,img_cols,img_channels)を指定しているので、ここの形状指定ミスではないと思われます。

・inputs形状を出力してみました。比較用に訓練データの形状も出力しました。エラーメッセージの冒頭部分に出力されているように、inputsの形状は(None, 8, 8, 4)となりバッチサイズがNoneになっています。ここが原因でしょうか?

・訓練データを拡張しようとしました。ダミーデータ作成部のdata_x = np.expand_dims(np.array(data_x), axis=-1)のコメントアウトを外した状態にしました。これで実行した結果、以下のようなエラーが出ました。

x_train.shape = (7, 8, 8, 4, 1) <class 'tensorflow.python.framework.ops.Tensor'> input.shape = (None, 8, 8, 4, 1) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-16-ad9f21bd03c9> in <module>() 45 print("x_train.shape = "+str(x_train.shape)) 46 #print(x_train[1]) ---> 47 model = ResNet(img_rows,img_cols,img_channels, x_train) 48 #model = ResNet(32, 32, 3, x_train) 49 history = model.fit(x_train, y_train, batch_size=2, epochs=20, validation_data = (x_test, y_test), verbose = 0) <ipython-input-14-05129b474cf2> in ResNet(img_rows, img_cols, img_channels, x_train) 38 #メモ:層の引数input_shapeは1データの形状を記述するので、画像を入れるなら3次元(行、列、チャンネル)の表記にする。 39 #  ただし、実際に渡すデータは4次元の(バッチサイズ、行、列、チャンネル)である必要がある。 ---> 40 x=Conv2D(filters=256, kernel_size=(3,3), padding="same", input_shape=(img_rows,img_cols,img_channels))(inputs) 41 ''' 42 x=BatchNormalization()(x) ~\AppData\Roaming\Python\Python37\site-packages\keras\backend\tensorflow_backend.py in symbolic_fn_wrapper(*args, **kwargs) 73 if _SYMBOLIC_SCOPE.value: 74 with get_graph().as_default(): ---> 75 return func(*args, **kwargs) 76 else: 77 return func(*args, **kwargs) ~\AppData\Roaming\Python\Python37\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs) 444 # Raise exceptions in case the input is not compatible 445 # with the input_spec specified in the layer constructor. --> 446 self.assert_input_compatibility(inputs) 447 448 # Collect input shapes to build layer. ~\AppData\Roaming\Python\Python37\site-packages\keras\engine\base_layer.py in assert_input_compatibility(self, inputs) 340 self.name + ': expected ndim=' + 341 str(spec.ndim) + ', found ndim=' + --> 342 str(K.ndim(x))) 343 if spec.max_ndim is not None: 344 ndim = K.ndim(x) ValueError: Input 0 is incompatible with layer conv2d_11: expected ndim=4, found ndim=5

今度は「Input層は4次元データが欲しいのに5次元データが入力されているよ」と言われました。

以上をまとめますと、データを5次元にするとInput層から大きすぎと文句を言われ、4次元にするとConv2d層から小さすぎると文句を言われて困っている状況です。

よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

開発環境:jupyter notebook
使用言語:python 3.7
使用ライブラリ:keras 2.3.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

y_trainの次元が3になってました。ダミーデータを作るのでしたらnumpy.randomが便利です。

python

1data_n = 10 2img_rows = 8 3img_cols = 8 4img_channels = 4 5img_channels_out = 64 # 今、ネットワークを途中で切っているので出力のチャネルが4でないのに注意 6 7# 形状を指定してランダムなデータを生成 8x_train = np.random.rand(data_n, img_rows, img_cols, img_channels) 9y_train = np.random.rand(data_n, img_rows, img_cols, img_channels_out) 10 11# ここから下は同じ 12x_train, x_test, y_train, y_test = train_test_split(x_train, y_train, test_size=0.30) 13model = ResNet(img_rows, img_cols, img_channels, x_train) 14model.summary() 15history = model.fit( 16 x_train, 17 y_train, 18 batch_size=2, 19 epochs=20, 20 validation_data=(x_test, y_test), 21 verbose=0, 22) 23

投稿2019/12/07 00:45

Yhaya

総合スコア439

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yolloy

2019/12/09 12:49

回答ありがとうございます。そして返信が遅くなって申し訳ありません。 Yhayaさんのコードを参考に修正した結果、「ValueError: Error when checking target: expected dense_10 to have 4 dimensions, but got array with shape (7, 8, 8)」のようなエラーはなくなりました。ありがとうございます。 しかし、新たに「ValueError: None values not supported.」というエラーが出てしまい、こちらもいろいろ調べたのですが解決できず、また文章も長くなってしまったので、新たに質問させていただきました。以下にURLを置いておきます。 https://teratail.com/questions/228395?modal=q-comp 今回の質問についてはYhayaさんをベストアンサーとし、示させていただこうと思います。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問