我在使用Keras时遇到了一个似乎是初学者常见的问题。我试图将彩色图像分类为“某物”或“非某物”,并运行一个基本模型,以便我可以调整超参数,以更好地理解它们各自的作用。
我希望有人能解释为什么我在model.fit中遇到了这个错误,并解释在一般意义上,在训练和测试集之前,我应该关注和查找的维度问题。我不确定在二分类的情况下,Dense(units)应该是1还是2,你能解释一下吗?
错误:
“`
ValueError: Error when checking target: expected dense_18 to have 4 dimensions, but got array with shape (584, 1)
“`
代码:
“`
from identify_mounds import *from PIL import Imageimport numpy as npnp.random.seed(6)import osimport subprocessfrom collections import defaultdictimport picklefrom scipy.misc import imreadfrom sklearn.model_selection import train_test_splitfrom keras.models import Sequentialfrom keras.layers import Dense, Dropout, Activation, Flattenfrom keras.layers import Convolution2D, MaxPooling2Dfrom keras.utils import np_utilsdef train_nomound_mound(dic): X = [] y = [] X_ = [] for im in dic: X.extend(dic[im]['img_lst']) y.extend(dic[im]['label']) for im in X: arr = imread(im) X_.append(arr) X_ = (np.array(X_).reshape(779, 4, 16, 16)/255).astype('float32') y = np.array(y).astype('float32') X_train, X_test, y_train, y_test = train_test_split(X_, y, stratify = y) #Demensions: X_train: (584, 4, 16, 16), y_train: (584,), X_test: (195, 4, 16, 16), y_test: (195,) model = Sequential() batch_size = 128 nb_epoch = 12 nb_filters = 32 kernel_size = (3, 3) input_shape = (4, 16, 16) pool_size = (2, 2) model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1], activation='relu', input_shape=input_shape)) model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1], activation='relu')) # model.add(MaxPooling2D(pool_size=pool_size)) model.add(Dropout(0.25)) model.add(Dense(32, activation='relu')) model.add(Dropout(.50)) model.add(Dense(1, activation='relu')) model.compile(loss = 'categorical_crossentropy', optimizer='Adadelta', metrics=['accuracy']) model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=1, validation_data=(X_test, y_test)) score = model.evaluate(X_test, y_test, verbose=0) print('Test score:', score[0]) print('Test accuracy:', score[1])
“`
回答:
当使用binary_crossentropy
损失函数时,单个神经元的Dense层是合适的。使用categorical_crossentropy
损失函数时,需要进行one-hot编码,并且输出层的neurons数量应与类别数相同。根据Keras损失函数文档中的说明:
注意:使用categorical_crossentropy损失函数时,您的目标应为分类格式(例如,如果您有10个类别,每个样本的目标应为一个10维向量,除了对应样本类别的索引位置为1外,其余均为0)。
通过to_categorical
函数进行one-hot编码的示例在Keras的MNIST MLP示例中得到了简洁的展示。