web-dev-qa-db-ja.com

ターゲットをチェックする際のエラー:dense_3には形状(3、)が必要ですが、形状(1)の配列を取得しました

私は、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 は、ラベルデータをワンホットエンコード形式に変換します。

14
Kamil Kaczmarek

他の人が述べたように、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'を意味します。

8
Peter

同じ問題がありました。この問題を解決するには、validation_generatorとtrain_generatorでクラスモードを 'binary'から 'categorical'に変更します。これは、バイナリではない3つのクラスがあるためです。

8
Doctor Strange

問題: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を入れると正しく機能しました。

1
Vinay Verma