Python 如何在Keras中为多重输出回归设置目标(y)数组的形状/格式?

Python 如何在Keras中为多重输出回归设置目标(y)数组的形状/格式?,python,numpy,tensorflow,keras,neural-network,Python,Numpy,Tensorflow,Keras,Neural Network,这就是我在运行以下代码时遇到的错误: ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 4 array(s), but instead got the following list of 1 arrays: [array([[115.

这就是我在运行以下代码时遇到的错误:

ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 4 array(s), but instead got the following list of 1 arrays: [array([[115.,  23.,  37.,  27.,  60.,  35.,  77.,  50., 104., 134.,  99.,
         59.,  52., 179.,  77.,  85.],
       [495., 457., 601., 602., 586., 549., 558., 627., 552., 500., 524.,
        587....
imageLoader功能如下:

inp = Input((480,640,3))
x = Dense(13, activation = 'relu')(inp)
out1 = Dense(1 , activation = 'linear')(x)
out2 = Dense(1 , activation = 'linear')(x)
out3 = Dense(1 , activation = 'linear')(x)
out4 = Dense(1 , activation = 'linear')(x)
model = Model(inp , [out1,out2,out3,out4])
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit_generator(generator = imageLoader(train_can , 16) , steps_per_epoch = 14000/16 , epochs = 1)
def imageLoader(files, batch_size = 16):

   L = len(files)

#this line is just to make the generator infinite, keras needs that    
   while True:

     batch_start = 0
     batch_end = batch_size

     while batch_start < L:
        limit = min(batch_end, L)
        X = someMethodToLoadImages(files[batch_start:limit])
        Y = rearrange(train_y[batch_start:limit])

        yield (X,Y) #a tuple with two numpy arrays with batch_size samples     

        batch_start += batch_size   
        batch_end += batch_size
def someMethodToLoadImages(files ):
    images =  np.empty((0,480,640,3) , float)
    for file in files:
         img =  image.load_img(os.path.join("G:/flipkart/images" , file ) ) #no target size required as all images are of same size
         images = np.append(images ,  image.img_to_array(img).reshape(1,480,640,3), axis = 0)
    return images/255.0
重新排列的功能如下所示:

inp = Input((480,640,3))
x = Dense(13, activation = 'relu')(inp)
out1 = Dense(1 , activation = 'linear')(x)
out2 = Dense(1 , activation = 'linear')(x)
out3 = Dense(1 , activation = 'linear')(x)
out4 = Dense(1 , activation = 'linear')(x)
model = Model(inp , [out1,out2,out3,out4])
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit_generator(generator = imageLoader(train_can , 16) , steps_per_epoch = 14000/16 , epochs = 1)
def imageLoader(files, batch_size = 16):

   L = len(files)

#this line is just to make the generator infinite, keras needs that    
   while True:

     batch_start = 0
     batch_end = batch_size

     while batch_start < L:
        limit = min(batch_end, L)
        X = someMethodToLoadImages(files[batch_start:limit])
        Y = rearrange(train_y[batch_start:limit])

        yield (X,Y) #a tuple with two numpy arrays with batch_size samples     

        batch_start += batch_size   
        batch_end += batch_size
def someMethodToLoadImages(files ):
    images =  np.empty((0,480,640,3) , float)
    for file in files:
         img =  image.load_img(os.path.join("G:/flipkart/images" , file ) ) #no target size required as all images are of same size
         images = np.append(images ,  image.img_to_array(img).reshape(1,480,640,3), axis = 0)
    return images/255.0
如何解决这个问题?我已经在stack上查看了类似的问题,但我仍然无法找到解决方案

----------------------------------------更新-------------------------------

def rearrange(arr):
   length = arr.shape[0]
   arr_ = np.ones((4,length))
   for i,sample in enumerate(arr):
       for index,number in enumerate(sample):
            arr_[index,i] = number
   return arr_
这是模型摘要:

运行此命令时:

inp = Input((480,640,3))
#x = Dense(13, activation = 'relu')(inp)
x = Conv2D(filters = 10, kernel_size = (3,3), strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)(inp)
x1 = Flatten()(x)
out1 = Dense(1 , activation = 'linear')(x1)
out2 = Dense(1 , activation = 'linear')(x1)
out3 = Dense(1 , activation = 'linear')(x1)
out4 = Dense(1 , activation = 'linear')(x1)

model = Model(inp , [out1,out2,out3,out4])
model.compile(loss='mean_squared_error', optimizer='adam')

print(model.summary())
我得到:

model.fit_generator(generator = imageLoader(train_can , 16) , steps_per_epoch = 14000/16 , epochs = 1)

您的模型有四个输出,因此您必须将groundtruth标签作为包含四个元素的python列表。而是返回一个numpy数组。
有关多个输入/输出模型的示例,请参见。

您是否调用了
model.summary()
以查看4个输出层的输出形状?在最新的Keras版本中,4个输出层中的每一层都将是
(无、480、640、1)
None
是批量大小)。这可能不是你想要的。通过查看如何生成
Y
-值,我假设您只需要使用
(无,1)

但是,不管您想要的实际输出形状是什么,要回答您的问题:
Y
必须是一个大小为4的普通列表(因为您有4个输出层),其中该列表的每个元素必须是一个numpy数组,其形状与相应输出层的输出形状完全匹配。在您的情况下,所有输出层都具有相同的形状。因此,对于给定的
模型
,正如您在问题中介绍的那样

ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 4 array(s), but instead got the following list of 1 arrays: [array([[115.,  23.,  37.,  27.,  60.,  35.,  77.,  50., 104., 134.,  99.,
     59.,  52., 179.,  77.,  85.],
   [495., 457., 601., 602., 586., 549., 558., 627., 552., 500., 524.,
    587....
将是
重排
函数的有效返回值。此列表的第一个条目将应用于
out1
的输出,第二个条目应用于
out2
,等等

如果我的猜测是正确的,并且您实际上希望有4个输出形状的
(无,1)
,那么首先(当然)您必须重新设计您的模型以实际拥有这些输出形状。然后

Y = [np.ones((batch_size, 480, 640, 1)), np.ones((batch_size, 480, 640, 1)), np.ones((batch_size, 480, 640, 1)), np.ones((batch_size, 480, 640, 1))]
这就是你需要的


注意,只有当输出层具有不同的输出形状时,才需要普通列表。但是,在这个特定的示例中,所有输出形状都是相同的,因此您也可以返回
Y=np.ones((4,batch\u size,1))
。由于这几乎正是您当前正在做的事情(您只需调用
重塑((4,批次大小,1))
来添加缺少的最后一个维度),我很有信心您只是误解了
密集层的工作原理。它们只改变输入张量的最后一个维度。图层是获得一维张量的最简单方法(如果在批量大小中计算,实际上是二维的)。同样,
model.summary()
是您的朋友。

感谢您的回复,我删除了稠密层,并将其替换为Conv2D层,但仍然得到了相同的错误。请查看我帖子中的更新。@FarazGerrardJamal哦,我的错。最后一个维度将始终保持不变。我已经更正了我的答案。