如何解决有关CNN培训的价值错误

时间:2019-10-23 16:41:18

标签: python keras deep-learning conv-neural-network

问题:

因此,当我尝试训练cnn时,会发生此错误。

ValueError: Error when checking target: expected dense_4 to have shape (32,) but got array with shape (1,)

我不知道这意味着什么。这个代码不是100%我的,我只是拿了一个CNN代码并对其进行了修改以使其适用于我的需求。 尽管我对CNN编码的知识非常有限,而且我也没有对Python编程的适当培训。

有人可以向我解释该错误是怎么回事,而我想知道是什么原因引起的。你们能告诉我到目前为止我对代码所做的是否正确吗?

我计划创建一个CNN,它将能够对图像进行分类,以包含性,暴力,恐怖和毒品内容。因此,这是具有图像输入的多类CNN,输出将对图像所属的类别进行分类。

以下是CNN代码的其余部分:

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Flatten
from keras.callbacks import ModelCheckpoint

IMAGE_LENGHT = 300
EPOCH_COUNT = 10
MODEL_PATH = 'model.hdf5'
WEIGHTS_PATH = 'weights.hdf5'

model = Sequential()

model.add(Conv2D(32, (9, 9),  input_shape = (IMAGE_LENGHT,IMAGE_LENGHT, 3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))

model.add(Conv2D(32, (9, 9), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))

model.add(Conv2D(64, (9, 9), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))

model.add(Flatten())

model.add(Dense(64, activation = 'relu'))
model.add(Dropout(rate = 0.5))
model.add(Dense(32, activation = 'softmax'))

model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['binary_accuracy'])

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator()

test_datagen = ImageDataGenerator()

training_set = train_datagen.flow_from_directory(
        'TRAIN_SET',
        target_size = (IMAGE_LENGHT,IMAGE_LENGHT),
        batch_size = 100,
        class_mode = 'binary')

test_set = test_datagen.flow_from_directory(
        'TEST_SET',
        target_size = (IMAGE_LENGHT,IMAGE_LENGHT),
        batch_size = 100,
        class_mode = 'binary')

checkpoint = ModelCheckpoint(WEIGHTS_PATH, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
model.fit_generator(
        training_set,
        steps_per_epoch=60,
        epochs = EPOCH_COUNT,
        validation_data = test_set,
        validation_steps =20,
        callbacks = [checkpoint])
model.save(MODEL_PATH, True, True)

任何帮助将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:0)

原因在这里

model.add(Dense(32, activation = 'softmax'))

在这里

class_mode = 'binary'

导致错误的原因是您的模型需要将输出形状设为(batch_size, 32),但是到class_mode = 'binary'时,您只能得到(batch_size, 1)

首先,您需要知道图像是多少类,在这种情况下,TRAIN_SET中有多少个文件夹,然后将其放入Dense()中。就像您有7个班级一样

model.add(Dense(7, activation = 'softmax'))

,然后将class_mode = 'binary'更改为class_mode = 'categorical'。对于多类分类,您不能像0是狗1是猫2是鸭子而3是马一样标记,不能将鸭子切成两半得到一只猫或减去一匹马到一只狗。您需要使用one-hot编码。

第二,关于binary类,如果您的数据仅是2类,例如猫和狗,那么您可以让模型答案像“这张图片是狗吗”,那么如果是,那是狗还是是错的,是猫。

在这种情况下,您可以使用

model.add(Dense(1, activation = 'sigmoid'))  # beware, it's 'sigmoid' here, not 'softmax'
model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])  # binary_crossentropy here, not categorical

class_mode = 'binary'

编辑

One hot就像,让我们定义毒品= 0,恐怖= 1,暴力= 2和性行为= 3,如果答案为violence,则目标数据将为[0, 0, 1, 0] 。该模型将像[0.1, 0.05, 0.8, 0.05]那样预测每个类别的概率,而不是实际的数字2。就像我说的那样,您不能将horrorviolence相加并得到sexual作为结果您需要分别定义它们,让模型预测这里最可能的类。

编辑2

当您的每个图像都可以超过1个等级时,将使用二进制精度,例如Emma Watson既可以是女演员,也可以是男人或女人,而这两个等级都不对。输出可能像[1, 0, 1, 1, 0],总和不需要为1。但是在您的情况下,它是categorical classification,而不是binary,每个图像都是从flow_from_directory生成的如果您希望它是多类的,则将其标记为categorical,您仍然可以使用binary_accuracy并获得相同的结果,但并非出于此目的,以后有人在阅读代码时可能会might头所以我认为在这里使用accuracy是一个更好的主意。

答案 1 :(得分:0)

您的最后一层有32个单位,您正在使用softmax。因此,您应该拥有超过2个班级。神经网络期望目标为32维,因此您必须通过以下操作对目标形状(1,)进行一次热编码:

import pandas as pd
y_train=pd.get_dummies(target)

然后,通过运行以下命令检查数据维(类数):

y_train.shape[1]

此输出维是目标变量中具有的类数。这样您将拥有:

model.add(Dense(y_train.shape[1], activation = 'softmax'))

我也会更改:

metrics = ['accuracy']

如果您确实有二进制目标,则最后一层应该是:

model.add(Dense(2, activation = 'sigmoid'))

在这种情况下,您还应该将目标变量热编码为(batch_size,number_classes)