私は、KerasでVGG16に似たモデルをPlaces205の3つのクラスサブセットでトレーニングしようとしていますが、次のエラーが発生しました。
ValueError: Error when checking target: expected dense_3 to have shape (3,) but got array with shape (1,)
同様の問題を複数読みましたが、これまでのところ何も助けませんでした。エラーは最後のレイヤーにあります。これは、今試しているクラスの数だからです。
コードは次のとおりです。
import keras from keras.datasets
import cifar10 from keras.preprocessing.image
import ImageDataGenerator from keras.models
import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K import os
# Constants used
img_width, img_height = 224, 224
train_data_dir='places\\train'
validation_data_dir='places\\validation'
save_filename = 'vgg_trained_model.h5'
training_samples = 15
validation_samples = 5
batch_size = 5
epochs = 5
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height) else:
input_shape = (img_width, img_height, 3)
model = Sequential([
# Block 1
Conv2D(64, (3, 3), activation='relu', input_shape=input_shape, padding='same'),
Conv2D(64, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
# Block 2
Conv2D(128, (3, 3), activation='relu', padding='same'),
Conv2D(128, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
# Block 3
Conv2D(256, (3, 3), activation='relu', padding='same'),
Conv2D(256, (3, 3), activation='relu', padding='same'),
Conv2D(256, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
# Block 4
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
# Block 5
Conv2D(512, (3, 3), activation='relu', padding='same',),
Conv2D(512, (3, 3), activation='relu', padding='same',),
Conv2D(512, (3, 3), activation='relu', padding='same',),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
# Top
Flatten(),
Dense(4096, activation='relu'),
Dense(4096, activation='relu'),
Dense(3, activation='softmax') ])
model.summary()
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# no augmentation config train_datagen = ImageDataGenerator() validation_datagen = ImageDataGenerator()
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
validation_generator = validation_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
model.fit_generator(
train_generator,
steps_per_Epoch=training_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=validation_samples // batch_size)
model.save_weights(save_filename)
問題は、ラベルデータの形状にあります。マルチクラス問題では、考えられるすべてのクラスの確率を予測するため、ラベルデータを(N、m)の形で提供する必要があります。ここで、Nはトレーニングの例の数、mは可能なクラスの数です(あなたの場合は3) 。
Kerasは、y-dataを(N、3)の形で期待しますが、これは(N、)であると思われますが、これがエラーを発生させる理由です。
使用する OneHotEncoder は、ラベルデータをワンホットエンコード形式に変換します。
他の人が述べたように、Kerasはマルチクラスの問題で「ワンホット」エンコーディングを期待しています。
ケラスにはラベルを再コーディングする便利な機能が付属しています
print(train_labels)
[1. 2. 2. ... 1. 0. 2.]
print(train_labels.shape)
(2000,)
to_categorical
を使用してラベルを再コーディングし、入力の正しい形状を取得します。
from keras.utils import to_categorical
train_labels = to_categorical(train_labels)
print(train_labels)
[[0. 1. 0.]
[0. 0. 1.]
[0. 0. 1.]
...
[0. 1. 0.]
[1. 0. 0.]
[0. 0. 1.]]
print(train_labels.shape)
(2000, 3) # viz. 2000 observations, 3 labels as 'one hot'
マルチクラスで変更/チェックする他の重要な事項(バイナリ分類と比較して):
generator()
関数でclass_mode='categorical'
を設定します。
last密層はラベル(またはクラス)の数を指定する必要があることを忘れないでください。
model.add(layers.Dense(3, activation='softmax'))
マルチクラスの問題に合わせてactivation=
とloss=
が選択されていることを確認してください。通常、これはactivation='softmax'
とloss='categorical_crossentropy'
を意味します。
同じ問題がありました。この問題を解決するには、validation_generatorとtrain_generatorでクラスモードを 'binary'から 'categorical'に変更します。これは、バイナリではない3つのクラスがあるためです。
問題:dense_3には形状(3、)が必要ですが、形状(1)の配列を取得しました
分類に使用する場合、密なレイヤーを追加するためのパラメーターの変数の数が正しいはずです。
variables_for_classification=5 #change it as per your number of categories
model.add(Dense(variables_for_classification, activation='softmax'))
model.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size,validation_split=0.1,callbacks=[EarlyStopping(monitor='val_loss', patience=3, min_delta=0.0001)])
より明確にするため。 LSTMを使用してニュースのカテゴリを予測していたため、カテゴリは5つのビジネス、テクノロジー、政治、スポーツ、エンターテイメントでした
その密な関数では、5を入れると正しく機能しました。