检查目标时出错:预期density_9的形状为(1,),但数组的形状为(20,)

时间:2019-11-18 11:15:31

标签: python tensorflow keras classification conv-neural-network

我正在为20个课程编写CNN分类器。如标题中所述,这是我尝试fit模型时遇到的错误。

我已经检查了以下答案:Error,但我已经(我认为)设置了categorical转换。

这是我的代码:

1)图像生成器:

apply_data_augmentation = True

if apply_data_augmentation:
   train_datagen = ImageDataGenerator(rotation_range=10,    #Training data generator + validation split (20%)
                                      width_shift_range=10,
                                      height_shift_range=10,
                                      zoom_range=0.3,
                                      horizontal_flip=True,
                                      vertical_flip=True,
                                      fill_mode='constant',
                                      cval=0,
                                      rescale=1./255,
                                      validation_split=0.2)
else:
    train_datagen = ImageDataGenerator(rescale=1./255)

2)获取数据:

dataset_dir = os.path.join(cwd, 'Classification_Dataset')

bs = 8

# img shape
img_h = 28
img_w = 28

 num_classes=20

 decide_class_indices = False
 if decide_class_indices:
    classes = ['airplane',       # 0
               'bear',           # 1
               'calculator',    # 2
               'computer-monitor',              # 3
               'fireworks',          # 4
               'galaxy',          # 5
               'grand-piano',   # 6
               'kangaroo',             # 7
               'laptop',            # 8
               'lightbulb',         # 9
               'lightning',             # 10
               'mountain-bike',       # 11
               'owl',  # 12
               'school-bus',     # 13
               'sheet-music',           # 14
               'skyscraper',         # 15
               'sword',              # 16
               't-shirt',             # 17
               'waterfall',  # 18
               'wine-bottle']        # 19
else:
    classes=None
print(classes)
# Training
training_dir = os.path.join(dataset_dir, 'training')

train_generator = train_datagen.flow_from_directory(
    training_dir,
    target_size=(img_h, img_w),
    batch_size=bs,
    class_mode='categorical',
    classes=classes,
    subset='training',
    shuffle=True,
    seed=SEED) # set as training data

validation_generator = train_datagen.flow_from_directory(
    training_dir, # same directory as training data
    target_size=(img_h, img_w),
    batch_size=bs,
    class_mode='categorical',
    classes=classes,
    subset='validation',
    shuffle=False,
    seed=SEED) # set as validation data

print(train_generator)

3)型号+适合:

from keras.datasets import mnist

import matplotlib.pyplot as plt
import numpy as np
from keras import Sequential
from keras.layers import Conv2D, AveragePooling2D, Flatten, Dense, Dropout
from keras.callbacks import EarlyStopping


model = Sequential()
model.add(Conv2D(filters=6, kernel_size=(3, 3), activation='relu', input_shape=(28,28,3)))
model.add(AveragePooling2D())
model.add(Conv2D(filters=16, kernel_size=(3, 3), activation='relu'))
model.add(AveragePooling2D())
model.add(Flatten())

model.add(Dense(units=120, activation='relu'))
model.add(Dropout(0.3))

model.add(Dense(units=100, activation='relu'))
model.add(Dropout(0.3))

model.add(Dense(units=20, activation='softmax'))
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])



nb_epochs = 5
model.fit_generator(
    train_generator,
    steps_per_epoch = train_generator.samples // bs,
    validation_data = validation_generator, 
    validation_steps = validation_generator.samples // bs,
    epochs = nb_epochs)

我检查了许多问题中提到的所有可能的问题(例如缺少拼合层,分类转换,不匹配的输入等),但是(至少对我而言)一切都很好。 我不明白问题出在哪里。

1 个答案:

答案 0 :(得分:1)

带有flow_from_directory的{​​{1}}函数会生成一个热编码的2D标签(Ref),而class_mode='categorical'则需要整数值。
您有两种方法可以解决此问题:
1.编译模型时,将损失函数更改为sparse_categorical_crossentropy
2.通过使用categorical_crossentropy函数中的sparse将标签更改为class_mode='sparse'模式

简而言之,当标签是整数值(代表类)时,请使用flow_from_directory,而标签是单次编码时,请使用sparse_categorical_crossentropy作为损失函数。