Python Keras定制数据生成器,提供多输入多输出的尺寸误差(函数api模型)

Python Keras定制数据生成器,提供多输入多输出的尺寸误差(函数api模型),python,tensorflow,keras,deep-learning,lstm,Python,Tensorflow,Keras,Deep Learning,Lstm,我已经用Keras编写了一个生成器函数,在从\uuuu getitem\uuuuu返回X,y之前,我已经仔细检查了X和y的形状,它们都正常,但是生成器给出了尺寸不匹配数组和警告 (要复制的Colab代码:) 我的培训和验证生成器与 class ValidGenerator(Sequence): def __init__(self, df, batch_size=64): self.batch_size = batch_size self.df = df

我已经用Keras编写了一个生成器函数,在从
\uuuu getitem\uuuuu
返回X,y之前,我已经仔细检查了X和y的形状,它们都正常,但是生成器给出了尺寸不匹配数组和警告

(要复制的Colab代码:)

我的培训和验证生成器与

class ValidGenerator(Sequence):
    def __init__(self, df, batch_size=64):
        self.batch_size = batch_size
        self.df = df
        self.indices = self.df.index.tolist()
        self.num_classes = num_classes
        self.shuffle = shuffle
        self.on_epoch_end()

    def __len__(self):
        return int(len(self.indices) // self.batch_size)

    def __getitem__(self, index):
        index = self.index[index * self.batch_size:(index + 1) * self.batch_size]
        batch = [self.indices[k] for k in index]
        
        X, y = self.__get_data(batch)
        return X, y

    def on_epoch_end(self):
        self.index = np.arange(len(self.indices))
        if self.shuffle == True:
            np.random.shuffle(self.index)

    def __get_data(self, batch):
        #some logic is written here
        #hat prepares 3 X features and 3 Y outputs 
        X = [input_array_1,input_array_2,input_array_3]
        y = [out_1,out_2,out_3]
        #print(len(X))
        
        return X, y
我是X的返回元组,y的每个元组有3个输入特征和3个输出特征,所以X的形状是
(3,32,10,1)

我正在使用函数式api构建具有以下结构的模型(我有连接、多输入/输出之类的东西,这在序列中是不可能的)

当我尝试用下面的代码将generator与模型相匹配时

train_datagen = TrainGenerator(df=train_df,  batch_size=32, num_classes=None, shuffle=True)
valid_datagen = ValidGenerator(df=train_df,  batch_size=32, num_classes=None, shuffle=True)
model.fit(train_datagen, epochs=2,verbose=1,callbacks=[checkpoint,es])
我得到了这些警告和错误,它们不会消失

纪元1/2 警告:tensorflow:为输入>张量(“输入_1:0”,形状=(无,10),数据类型=float32)使用形状(无,10)构造模型,但在形状不兼容的输入上调用了>模型(无,无,无)

警告:tensorflow:模型是以形状(无,10)作为输入构建的 张量(“input_2:0”,shape=(None,10),dtype=float32),但它是 对具有不兼容形状(无、无、无)的输入调用。 警告:tensorflow:模型的形状(无,10)为 输入张量(“input_3:0”,shape=(None,10),dtype=float32),但它是 对具有不兼容形状(无、无、无)的输入调用。 ... ... 呼叫 返回超级(RNN,自我)。调用(输入,**kwargs) /home/eduardo/.virtualenvs/kgpu3/lib/python3.8/site packages/tensorflow/python/keras/engine/base_layer.py:975 呼叫 输入规格。断言输入规格兼容性(self.input规格,输入, /home/eduardo/.virtualenvs/kgpu3/lib/python3.8/site packages/tensorflow/python/keras/engine/input\u spec.py:176 断言输入兼容性 raise VALUERROR('Input'+str(Input_index)+'of layer'+

ValueError: Input 0 of layer lstm is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: [None, None, None, 88]
我重新检查了整个代码,不可能有输入(无,无,无),如警告或错误,我的输入维度是
(3,32,10,1)

更新

我还试图用python编写一个生成器函数,但得到了完全相同的错误

我的发电机功能

def generate_arrays_from_file(batchsize,df):
    #print(bat)
    inputs = []
    targets = []
    batchcount = 0
    while True:
            
            df3 = df.loc[np.arange(batchcount*batchsize,(batchcount*batchsize)+batchsize)]
            #Some pre processing
            X = [input_array_1,input_array_2,input_array_3]
            y = [out_1,out_2,out_3]
            yield X,y 
            batchcount = batchcount +1
keras内部似乎有问题(可能是因为我使用的是函数式API)

更新2

我还尝试输出tuple

       X = (input1_X,input2_X,input3_X)
       y = (output1_y,output2_y,output3_y)
也被命名为输入/输出,但它不起作用

        X =  {"input_1": input1_X, "input_2": input2_X,"input_3": input3_X}
        y = {"output_1": output1_y, "output_2": output2_y,"output_3": output3_y}
关于问题表述的注意事项:


将单个X特征更改为形状(32,10)而不是(32,10,1)可能有助于消除此错误,但这不是我想要的,它改变了我的问题(我不再有10个时间步,每个特征一个)

Keras对动态尺寸使用“无”

正如您在model.summary()图表上所看到的,该模型希望您的所有输入都是二维的形状(无,10)。对于batch dimension,您应该向模型提供三维数据

但您正在输入四维数据

我猜您的模型没有将输入列表拆分为三个输入。请尝试将输入更改为元组:

    X = (input_array_1,input_array_2,input_array_3)

KERA对动态尺寸使用“无”

正如您在model.summary()图表上所看到的,该模型希望您的所有输入都是二维的形状(无,10)。对于batch dimension,您应该向模型提供三维数据

但您正在输入四维数据

我猜您的模型没有将输入列表拆分为三个输入。请尝试将输入更改为元组:

    X = (input_array_1,input_array_2,input_array_3)

要解决此错误,请执行以下操作:

ValueError: Input 0 of layer lstm is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: [None, None, None, 88]
列车发电机应按以下方式更换。 当前代码:

input1_X = np.array(df3['input1_X'].to_list()).reshape(dlen,pad_len,1)
input2_X = np.array(df3['input2_X'].to_list()).reshape(dlen,pad_len,1)
input3_X = np.array(df3['input3_X'].to_list()).reshape(dlen,pad_len,1)
应改为:

input1_X = np.array(df3['input1_X'].to_list()).reshape(dlen,pad_len)
input2_X = np.array(df3['input2_X'].to_list()).reshape(dlen,pad_len)
input3_X = np.array(df3['input3_X'].to_list()).reshape(dlen,pad_len)

原因是3个输入中的每一个都需要一个二维数组,但生成器提供了一个三维数组。需要的形状是(批次大小,10)。

为了解决此错误:

ValueError: Input 0 of layer lstm is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: [None, None, None, 88]
列车发电机应按以下方式更换。 当前代码:

input1_X = np.array(df3['input1_X'].to_list()).reshape(dlen,pad_len,1)
input2_X = np.array(df3['input2_X'].to_list()).reshape(dlen,pad_len,1)
input3_X = np.array(df3['input3_X'].to_list()).reshape(dlen,pad_len,1)
应改为:

input1_X = np.array(df3['input1_X'].to_list()).reshape(dlen,pad_len)
input2_X = np.array(df3['input2_X'].to_list()).reshape(dlen,pad_len)
input3_X = np.array(df3['input3_X'].to_list()).reshape(dlen,pad_len)

原因是3个输入中的每一个都需要一个二维数组,但生成器提供了一个三维数组。预期的形状是(批次大小,10).

为什么数据的最后一个维度是1?模型期望10谢谢你的回答,我刚刚尝试过,但没有帮助。我有完全相同的错误32是我的批次,10是时间步长,1不是任何特征。你必须更改模型-在最后一个dim它期望10而不是1,或者只是压缩数据的最后一个dim为什么最后一个d你的数据的维度是1?模型期望10谢谢你的回答,我刚刚尝试过,但没有帮助。我有完全相同的错误32是我的批次,10是时间步长,1不是特征。你必须更改你的模型,然后-它期望10而不是最后一个dim的1或者只是压缩数据的最后一个dim你尝试过run\u急切地=T吗rue in model.compile。这可能会解决您的问题。您是否尝试过在model.compile中使用run_急切地=True。这可能会解决您的问题。我有多对一体系结构,其中我有10个时间步,我预测下一个时间步。您建议的更改将带走顺序预测的所有好处,因为它将使数据具有10个特性(dlen,10),应该是(dlen,10,1)我有多对一架构,其中我有10个时间步,我预测下一个。您建议的更改将带走顺序预测的所有好处,因为它将使数据具有10个特征(dlen,10),应该是(dlen,10,1)