Keras多输入模型无法匹配生成器的输入

我对Keras和人工智能完全是新手。我使用的是Ubuntu 20.04下的Keras 2.9和Python 3.8.10。我有一个使用C++函数生成的合成数据的2输入模型。我使用Pybind11调用C++函数。这个函数返回一个512×512的灰度图像和一个数字。我将这些连同一个生成的参数数字一起输入模型,两个数字在一个带有重复的向量中。训练模型时出现了以下错误消息:

[INFO] training model...Epoch 1/102022-08-22 18:36:27.276873: W tensorflow/core/framework/op_kernel.cc:1733] INVALID_ARGUMENT: TypeError: `generator` yielded an element that did not match the expected structure. The expected structure was ((tf.float32, tf.float32), tf.float32), but the yielded element was [[array([0.47688578, 0.47688578, 0.53283023, 0.53283023]), array([[0.56156078, 0.56156078, 0.56291341, ..., 0.64667391, 0.64674161,        0.64741869],          ...,       [0.42745098, 0.43529412, 0.41568627, ..., 0.48235294, 0.45882353,        0.45098039]])], array([0.64286654])].

而打印模型分支输入和输出(见下面的代码)显示如下:

KerasTensor(type_spec=TensorSpec(shape=(None, 4), dtype=tf.float32, name='input_1'), name='input_1', description="created by layer 'input_1'")KerasTensor(type_spec=TensorSpec(shape=(None, 512, 512, 1), dtype=tf.float32, name='input_2'), name='input_2', description="created by layer 'input_2'")KerasTensor(type_spec=TensorSpec(shape=(None, 4), dtype=tf.float32, name=None), name='dense/Relu:0', description="created by layer 'dense'")KerasTensor(type_spec=TensorSpec(shape=(None, 4), dtype=tf.float32, name=None), name='activation_5/Relu:0', description="created by layer 'activation_5'")

代码如下:

def generate(aBatchSize:int=32, aRepeatParameter:int=2):  dim = (512, 512)  paraShape = (aRepeatParameter * 2,)  def generator():    xParameter = numpy.empty(paraShape, dtype=float)    xImage     = numpy.empty(dim, dtype=float)    y          = numpy.empty((1), dtype=float)# populate variables    xImage = randomLandscape(dist, height, tempAmb, tempBase) # Pybind11 call    for i in range(1, aRepeatParameter):      xParameter[i] = xParameter[0]      xParameter[aRepeatParameter + i] = xParameter[aRepeatParameter]    y[0]          = (tempBase - tempAmb) / 5    yield [[xParameter, xImage], y]    # This was already yield {"parameters": xParameter, "image": xImage}, y -- no luck    dataset = tensorflow.data.Dataset.from_generator(generator,    output_signature=(      (tensorflow.TensorSpec(shape=paraShape, dtype=tensorflow.float32, name="parameters"),      tensorflow.TensorSpec(shape=dim, dtype=tensorflow.float32, name="image")),      tensorflow.TensorSpec(shape=(1), dtype=tensorflow.float32, name="y")            ))  dataset = dataset.batch(aBatchSize)  return datasetdef createMlp(aRepeatParameter:int):  vectorSize = aRepeatParameter * 2  inputs = Input(shape=(vectorSize,))  x = inputs  x = Dense(vectorSize, activation="relu")(x)  return Model(inputs, x)def createCnn():   filters=(8, 4, 2, 1)  inputShape = (512, 512, 1)  chanDim = -1  inputs = Input(shape=inputShape)  x = inputs   for (i, f) in enumerate(filters):    x = Conv2D(f, (3, 3), padding="same")(x)    x = Activation("relu")(x)    x = BatchNormalization(axis=chanDim)(x)    x = MaxPooling2D(pool_size=(2, 2))(x)  x = Flatten()(x)  x = Dense(16)(x)  x = Activation("relu")(x)  x = BatchNormalization(axis=chanDim)(x)  x = Dropout(0.5)(x)  x = Dense(4)(x)  x = Activation("relu")(x)  return Model(inputs, x)repeatParameter:int = 2mlp = createMlp(repeatParameter)cnn = createCnn()print(mlp.input)print(cnn.input)print(mlp.output)print(cnn.output)combinedInput = Concatenate(axis=1)([mlp.output, cnn.output])x = Dense(4, activation="relu")(combinedInput)x = Dense(1, activation="linear")(x)model = Model(inputs=[mlp.input, cnn.input], outputs=x)opt = Adam(learning_rate=1e-3, decay=1e-3 / 200)model.compile(loss="mean_absolute_percentage_error", optimizer=opt)batchSize = 32model.fit(landscapeGenerator.generate(batchSize, repeatParameter), validation_data=landscapeGenerator.generate(batchSize, repeatParameter),  epochs=10, steps_per_epoch=10, validation_split=0.3,  use_multiprocessing=True, workers=2)

回答:

原来我的生成器函数并不是真正的Python生成器。以下是正确的形式:

def generate(aBatchSize:int=32, aRepeatParameter:int=2):  dim = (512, 512)  paraShape = (aRepeatParameter * 2,)  def generator():    while True:      xParameter = numpy.empty(paraShape, dtype=float)      xImage     = numpy.empty(dim, dtype=float)      y          = numpy.empty((1), dtype=float)# populate variables      xImage = randomLandscape(dist, height, tempAmb, tempBase)      for i in range(1, aRepeatParameter):        xParameter[i] = xParameter[0]        xParameter[aRepeatParameter + i] = xParameter[aRepeatParameter]      y[0]          = (tempBase - tempAmb) / 5      yield ((xParameter, xImage), y)  dataset = tensorflow.data.Dataset.from_generator(generator,    output_signature=(      (tensorflow.TensorSpec(shape=paraShape, dtype=tensorflow.float32),      tensorflow.TensorSpec(shape=dim, dtype=tensorflow.float32)),      tensorflow.TensorSpec(shape=(1), dtype=tensorflow.float32)            ))  dataset = dataset.batch(aBatchSize)  return dataset

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注