質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
Keras

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

Python 3.x

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

Q&A

解決済

3回答

1915閲覧

kerasのコードでConv2Dの実行でエラーが発生します

TOMO6181

総合スコア39

Keras

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

Python 3.x

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

0グッド

0クリップ

投稿2020/01/28 11:44

kerasを使用して、CNNによる数値分類のコードを作成しています。
以下実行環境です。

OS:Windows 10
Anaconda Navigator: Ver 1.9.7
keras:Ver.2.1.3
Python:Ver.3.6
tensorflow-gpu:Ver.1.4.0
CUDA:Ver.8.0
cudnn:Ver.6.0

Anaconda上で、以下のコードを実行しました。

Python

1import keras 2from keras.datasets import mnist 3from keras.models import Sequential 4from keras.layers import Conv2D, MaxPooling2D 5from keras.layers.core import Dropout, Dense 6from keras.optimizers import Adam 7from keras.utils import np_utils 8 9# mnistのデータをロードする 10(x_train, y_train), (x_test, y_test) = mnist.load_data() 11 12TRAIN_NUM = 60000 13TEST_NUM = 10000 14GASO_NUM = 28 * 28 15LABEL_NUM = 10 16 17x_train = x_train.reshape(TRAIN_NUM, GASO_NUM).astype("float32") 18x_test = x_test.reshape(TEST_NUM, GASO_NUM).astype("float32") 19x_train = x_train / 255.0 20x_test = x_test / 255.0 21 22# ラベルは0~9の数字なので0,1の列数10個のデータに変換 23y_train = np_utils.to_categorical(y_train, LABEL_NUM) 24y_test = np_utils.to_categorical(y_test, LABEL_NUM) 25 26# 各レイヤーを作成する 27model = Sequential() 28 29# 出力ニューロンの数 30OUT_NUM = 512 31# ドロップアウト率 32DROP_RATE = 0.2 33 34# 畳み込み層 35model.add(Conv2D(filters=512, kernel_size=(5, 5), strides=(1, 1), padding="same", activation="relu", input_shape=(28, 28, 1))) 36# MaxPooling層 37model.add(MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding="same")) 38# 畳み込み層 39model.add(Conv2D(filters=512, kernel_size=(5, 5), strides=(1, 1), padding="same", activation="relu")) 40# MaxPooling層 41model.add(MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding="same")) 42 43# 全結合層 44model.add(Dense(OUT_NUM, activation="relu")) 45model.add(Dropout(DROP_RATE)) 46 47# ラベルの読み出し層 48model.add(Dense(LABEL_NUM, activation="softmax")) 49 50model.compile(optimizer=Adam(), loss="categorical_crossentropy", metrics=["accuracy"]) 51 52# 学習の処理を行う 53model.fit(x_train, y_train, batch_size=100, epochs=10) 54 55# 誤差と精度の表示を行う 56accuracy = model.evaluate(x_test, y_test, batch_size=100, verbose=1) 57print("誤差率:", accuracy[0]) 58print("正解率:", accuracy[1]) 59

上記コードを実行すると、「model.fit(x_train, y_train, batch_size=100, epochs=10)」のところで、下記のエラーが発生します。

ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (60000, 784)

エラーメッセージを読む限り、Conv2Dは4つの引数を要求しているが、60000、784の2つしか入っていない、と表示されているようです。

しかし、実際Conv2Dには(28, 28, 1)の3つの引数しか渡していないので、何故4つとみなされるのか分かりません。
(28, 28, 1)にした理由としては、読み込む画像の縦と横の大きさが28×28で、チャンネル数が1チャンネルのためです。

エラーメッセージの内容、及び正しい引数の指定方法が分かる方がおられましたら、宜しくお願い致します。

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

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

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

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

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

guest

回答3

0

ベストアンサー

Conv2Dには(batch, height, width, channels)の形でデータが入力されますが、input_shapeにはbatchを明記する必要はなくinput_shape=(28, 28, 1)でこの場合(60000, 28, 28, 1)の形で入力されるはずです。
しかし

x_train = x_train.reshape(TRAIN_NUM, GASO_NUM).astype("float32")

x_test = x_test.reshape(TEST_NUM, GASO_NUM).astype("float32")

で入力データを(60000, 28, 28)から(60000, 784)の形に変換しているためbut got array with shape (60000, 784)のエラーが出ています。
つまりこの部分をx_train = x_train[..., None], xtest = x_test[..., None]に書き換えて入力データを(60000, 28, 28)から(60000, 28, 28, 1)に変えればこのエラーは解決します。

また、全結合層の入力がConv2Dの出力をそのまま受け取っているので次元数が合わずエラーが出るはずです。keras.layer.coreからFlattenをimportし全結合層の前にmodel.add(Flatten())を入れてください。

投稿2020/01/29 08:36

編集2020/01/29 08:50
passerby

総合スコア19

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

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

TOMO6181

2020/01/29 14:58

御回答ありがとうございます。 仰られる通り、x_trainとx_testのshapeを(60000, 28, 28, 1)、(10000, 28, 28, 1)に修正し、全結合層の前にmodel.add(Flatten())を入れたら無事学習、評価ができました。
guest

0

shapeを確認してみればすぐにわかります。
プーリング層の入出力は、4次元のテンソルです

# 畳み込み層 model.add(Conv2D(filters=512, kernel_size=(5, 5), strides=(1, 1), padding="same", activation="relu", input_shape=(28, 28, 1))) # MaxPooling層 model.add(MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding="same")) # 畳み込み層 model.add(Conv2D(filters=512, kernel_size=(5, 5), strides=(1, 1), padding="same", activation="relu")) # MaxPooling層 model.add(MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding="same")) print(model.input_shape) print(model.output_shape)

(None, 28, 28, 1)
(None, 28, 28, 512)

投稿2020/01/28 13:35

編集2020/01/28 13:41
technocore

総合スコア7200

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

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

TOMO6181

2020/01/29 14:53

モデルの入力のshapeと出力のshapeを表示できるのを初めて知りました。 ありがとうございました。
guest

0

しかし、実際Conv2Dには(28, 28, 1)の3つの引数しか渡していないので、何故4つとみなされるのか分かりません。
(28, 28, 1)にした理由としては、読み込む画像の縦と横の大きさが28×28で、チャンネル数が1チャンネルのためです。

Kerasの場合は、最初の次元はバッチ数で固定になります。
すなわち、(バッチ数, 28, 28, 1)とする必要があります。

投稿2020/01/28 13:24

fiveHundred

総合スコア9774

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

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

TOMO6181

2020/01/29 14:52

御回答ありがとうございます。 Conv2Dの最初の次元には、固定でバッチ数が入るようになっていたから次元数が4つと見なされていたのですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問