我在stackoverflow中看到过很多类似标题Error when checking target: expected dense_6 to have shape (19,) but got array with shape (1,)
的例子。我仍然无法弄清楚问题。以下是我的模型的完整摘要。
我正在研究分类问题。该数据集是从kaggle, Painters by number 主办的竞赛中收集的。任务是确定绘画的画家,风格和类型。到目前为止,我训练个人模型来预测画家,风格,类型给予绘画。现在我想结合多任务学习(即)开发一个可以预测所有三个任务的单一模型。我想出了指定的架构 Multi Task Learning Architecture
input_layer = Input(shape=(224,224,3))
shared_conv = Convolution2D(
filters = 5,# 5 feature maps
kernel_size = (5,5),
strides = 1)
shared_conv_layer_A = shared_conv(input_layer)
relu_shared = Activation('relu')(shared_conv_layer_A)
pooling = MaxPooling2D(
pool_size = (2,2),
strides = 2
)(relu_shared)
dense_layer_flatten = Flatten()(pooling)
denselayer1 = Dense(100)(dense_layer_flatten)
denselayer2 = Dense(100)(denselayer1)
out_style_1 = Dense(
100,
kernel_initializer=glorot_normal(seed=seed_val),
bias_initializer = 'zero',
kernel_regularizer = l2(l=0.0001),
activation='relu'
)(denselayer2)
out_genre_1 = Dense(
100,
kernel_initializer=glorot_normal(seed=seed_val),
bias_initializer = 'zero',
kernel_regularizer = l2(l=0.0001),
activation='relu'
)(denselayer2)
out_painter_1 = Dense(
100,
kernel_initializer=glorot_normal(seed=seed_val),
bias_initializer = 'zero',
kernel_regularizer = l2(l=0.0001),
activation='relu'
)(denselayer2)
out_style_2 = Dense(
19,
kernel_initializer=glorot_normal(seed=seed_val),
bias_initializer = 'zero',
kernel_regularizer = l2(l=0.0001),
activation = 'softmax',
)(out_style_1)
out_genre_2 = Dense(
32,
kernel_initializer=glorot_normal(seed=seed_val),
bias_initializer = 'zero',
kernel_regularizer = l2(l=0.0001),
activation = 'softmax',
)(out_genre_1)
out_painter_2 = Dense(
10,
kernel_initializer=glorot_normal(seed=seed_val),
bias_initializer = 'zero',
kernel_regularizer = l2(l=0.0001),
activation = 'softmax',
)(out_painter_1)
multi_tasking_model = Model(inputs=[input_layer],outputs=[out_style_2,out_genre_2,out_painter_2])
multi_tasking_model.summary()
multi_tasking_model.compile(
loss = 'categorical_crossentropy',
optimizer=Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=0.00000001),metrics=['accuracy'] )
history = multi_tasking_model.fit_generator(
generator = train_generator,
steps_per_epoch= 2920//10,
validation_data = valid_generator,
validation_steps = 690//10
)
使用keras数据提供程序执行此任务没有帮助。所以我创建了一个自定义数据提供程序。参考(Stanford data provider)
import numpy as np
class DataGenerator(object):
def __init__(self,dim_x = 64,dim_y=32,dim_z=32,batch_size=32,
shuffle=True,data=None,style=None,genre=None,painter=None):
self.dim_x = dim_x
self.dim_y = dim_y
self.dim_z = dim_z
self.batch_size = batch_size
self.shuffle=shuffle
self.data = data
self.y_style = style
self.y_genre = genre
self.y_painter = painter
@property
def data(self):
return self._data
@data.setter
def data(self,value):
self._data = value
@property
def y_style(self):
return self._y_style
@y_style.setter
def y_style(self,value):
self._y_style=value
@property
def y_genre(self):
return self._y_genre
@y_genre.setter
def y_genre(self,value):
self._y_genre = value
@property
def y_painter(self):
return self._y_painter
@y_painter.setter
def y_painter(self,value):
self._y_painter = value
def __get_exploration_order(self,len_list_ids):
indexes = np.arange(len_list_ids)
if self.shuffle:
np.random.shuffle(indexes)
return indexes
def __data_generation(self,list_ids_temp):
X = np.empty((self.batch_size,self.dim_x,self.dim_y,self.dim_z))
y_style = np.empty((self.batch_size), dtype=int)
y_genre = np.empty((self.batch_size), dtype=int)
y_painter = np.empty((self.batch_size), dtype=int)
for i, ID in enumerate(list_ids_temp):
X[i,:,:,:] = self.data[ID]
y_style = self.y_style[ID]
y_genre = self.y_genre[ID]
y_painter = self.y_painter[ID]
return X,[y_style,y_genre,y_painter]
def generate(self,len_list_ids):
while 1:
indexes = self.__get_exploration_order(len_list_ids)
imax = int(len(indexes)/self.batch_size)
for i in range(imax):
list_ids_temp = [ k for k in indexes[i*self.batch_size:(i+1)*self.batch_size]]
X,y = self.__data_generation(list_ids_temp)
yield X,y
from DataGenerator import DataGenerator
params = {
'dim_x': 224,
'dim_y': 224,
'dim_z': 3,
'batch_size':10,
'shuffle':True
}
data_train_gen = DataGenerator(**params)
data_train_gen.data = np.load('data.npy')
data_train_gen.y_style = np.load('y_style.npy')
data_train_gen.y_genre = np.load('y_genre.npy')
data_train_gen.y_painter = np.load('y_painter.npy')
train_generator=data_train_gen.generate(data_train_gen.data.shape[0])
data_gen_valid = DataGenerator(**params)
data_gen_valid.data = np.load('data_valid.npy')
data_gen_valid.y_style = np.load('y_style_valid.npy')
data_gen_valid.y_genre = np.load('y_genre_valid.npy')
data_gen_valid.y_painter = np.load('y_painter_valid.npy')
valid_generator= data_gen_valid.generate(data_gen_valid.data.shape[0])
Layer (type) Output Shape Param # Connected to
input_1 (InputLayer) (None, 224, 224, 3) 0
conv2d_1 (Conv2D) (None, 220, 220, 5) 380 input_1[0][0]
activation_1 (Activation) (None, 220, 220, 5) 0 conv2d_1[0][0]
max_pooling2d_1 (MaxPooling2D) (None, 110, 110, 5) 0 activation_1[0][0]
flatten_1 (Flatten) (None, 60500) 0 max_pooling2d_1[0][0]
dense_1 (Dense) (None, 100) 6050100 flatten_1[0][0]
dense_2 (Dense) (None, 100) 10100 dense_1[0][0]
dense_3 (Dense) (None, 100) 10100 dense_2[0][0]
dense_4 (Dense) (None, 100) 10100 dense_2[0][0]
dense_5 (Dense) (None, 100) 10100 dense_2[0][0]
dense_6 (Dense) (None, 19) 1919 dense_3[0][0]
dense_7 (Dense) (None, 32) 3232 dense_4[0][0]
dense_8 (Dense) (None, 10) 1010 dense_5[0][0]
Data(train) shape
-------------- --------
data_train.npy (2920,224,244,3)
y_style_train.npy (2920, 19)
y_genre_train.npy (2920, 32)
y_painter_train.npy (2920,10)
Data(valid) shape
-------------- --------
data_valid.npy (690,224,244,3)
y_style_valid.npy (690, 19) -- made change as per @JamesDong from 16 to 19
y_genre_valid.npy (690, 32) -- made change as per @JamesDong from 23 to 32
y_painter_valid.npy (690,10)
(array([[[[112., 129., 121.],
[133., 150., 144.],
[112., 130., 132.],
...,
[ 23., 22., 20.],
[ 21., 20., 18.],
[ 20., 19., 17.]],
[[109., 126., 118.],
[125., 141., 138.],
[109., 124., 127.],
...,
[ 24., 23., 21.],
[ 21., 20., 18.],
[ 18., 17., 15.]],
[[101., 116., 111.],
[109., 125., 122.],
[ 97., 112., 115.],
...,
[ 26., 25., 23.],
[ 21., 20., 18.],
[ 17., 16., 14.]],
...,
[[ 27., 30., 19.],
[ 27., 30., 19.],
[ 25., 28., 17.],
...,
[ 48., 48., 24.],
[ 47., 47., 21.],
[ 46., 46., 18.]],
[[ 27., 30., 19.],
[ 28., 31., 20.],
[ 24., 27., 16.],
...,
[ 51., 51., 27.],
[ 55., 55., 29.],
[ 54., 54., 26.]],
[[ 30., 33., 22.],
[ 31., 34., 23.],
[ 27., 30., 19.],
...,
[ 62., 62., 38.],
[ 87., 87., 61.],
[104., 104., 76.]]]]), (array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0]), array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0])))
我相信我已经发布了所有可用的信息。我完全卡住了。任何建议都会有很大的帮助。谢谢
答案 0 :(得分:0)
根据您的数据描述,验证数据集的形状不一致。
y_style_valid.npy (690, 16)
应为(690,19)
y_genre_valid.npy (690, 23)
应为(690,32)
如下所述,函数__data_generation
中也存在一些错误:
#y_style,y_genre,y_painter should be initialized with shape (batch_size,19),(batch_size,32),(batch_size,10) instead of (batchsize).
y_style = np.empty((self.batch_size,19), dtype=int)
y_genre = np.empty((self.batch_size,32), dtype=int)
y_painter = np.empty((self.batch_size,10), dtype=int)
......
for i, ID in enumerate(list_ids_temp):
....
#And accordingly, the assignment should be changed as the following:
y_style[i,:] = self.y_style[ID]
y_genre[i,:] = self.y_genre[ID]
y_painter[i,:] = self.y_painter[ID]