[英]error in constructing multioutput model in keras
I am trying to create a multi-output model in Keras.我正在尝试在 Keras 中创建多输出 model。 The model starts with a convolution and aims to stack the results of two separate dense layers. model 从卷积开始,旨在堆叠两个独立密集层的结果。 I created some random data for a regression task where x1
is the inputs and df
is labels.我为回归任务创建了一些随机数据,其中x1
是输入, df
是标签。 The df
contains three columns. df
包含三列。 After defining the train and test split and forming the model, I receive an error in fitting the model.在定义训练和测试拆分并形成 model 后,我在拟合 model 时收到错误消息。 Can anyone help me to correct my code?谁能帮我更正我的代码?
x1 = np.random.rand(500, 244, 244, 20)
df = pd.DataFrame(np.random.uniform(0,1,size=(500, 3)), columns=list('XYZ'))
x_train, x_test, y_train, y_test = train_test_split(x1,df ,test_size=0.2)
n1_y_train=y_train['X'].values
n1_y_test=y_test['X'].values
n2_y_train=y_train['Y'].values
n2_y_test=y_test['Y'].values
n3_y_train=y_train['Z'].values
n3_y_test=y_test['Z'].values
train_shape = x_train.shape
inputs = layers.Input(shape = train_shape[1:])
x = layers.Conv2D(16, (3,3), activation='relu', padding="same")(inputs)
x = layers.Flatten()(x)
# section1:
l1 = layers.Dense(16, activation='relu')(x)
l1 = layers.Dense(1)(l1)
# section2:
l2 = layers.Dense(32, activation='relu')(x)
l2 = layers.Dense(1)(l2)
output1 = tf.reduce_mean(tf.stack([l1, l2], axis=0), axis=0, name = "output1")
output2 = tf.reduce_mean(tf.stack([l1, l2], axis=0), axis=0, name = "output2")
output3 = tf.reduce_mean(tf.stack([l1, l2], axis=0), axis=0, name = "output3")
model = tf.keras.models.Model(inputs, [output1,output2,output3])
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss= tf.keras.losses.mse,
metrics=tf.keras.metrics.RootMeanSquaredError(name="rmse"))
history = model.fit(x_train,{"output1": n1_y_train, "output2": n2_y_train, "output3": n3_y_train},
validation_data = (x_test,{"output1": n1_y_test, "output2": n2_y_test, "output3": n3_y_test}),
verbose=2,
epochs=100,
batch_size=32)
error:错误:
ValueError: Found unexpected losses or metrics that do not correspond to any Model output: dict_keys(['output1', 'output2', 'output3']). Valid mode output names: ['tf.math.reduce_mean', 'tf.math.reduce_mean_1', 'tf.math.reduce_mean_2']. Received struct is: {'output1': <tf.Tensor 'IteratorGetNext:1' shape=(None,) dtype=float32>, 'output2': <tf.Tensor 'IteratorGetNext:2' shape=(None,) dtype=float32>, 'output3': <tf.Tensor 'IteratorGetNext:3' shape=(None,) dtype=float32>}.
You should wrap the output layers with Lambda
layers and use tf.concat
instead of tf.stack
.您应该用Lambda
层包裹 output 层,并使用tf.concat
而不是tf.stack
。 By using Lambda
layers, you can explicitly set the names of the outputs, which will be captured by your model.通过使用Lambda
层,您可以明确设置输出的名称,这些名称将由您的 model 捕获。 Here is a working example:这是一个工作示例:
import pandas as pd
import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split
x1 = np.random.rand(10, 244, 244, 20)
df = pd.DataFrame(np.random.uniform(0,1,size=(10, 3)), columns=list('XYZ'))
x_train, x_test, y_train, y_test = train_test_split(x1,df ,test_size=0.2)
n1_y_train=y_train['X'].values
n1_y_test=y_test['X'].values
n2_y_train=y_train['Y'].values
n2_y_test=y_test['Y'].values
n3_y_train=y_train['Z'].values
n3_y_test=y_test['Z'].values
train_shape = x_train.shape
inputs = tf.keras.layers.Input(shape = train_shape[1:])
x = tf.keras.layers.Conv2D(16, (3,3), activation='relu', padding="same")(inputs)
x = tf.keras.layers.Flatten()(x)
l1 = tf.keras.layers.Dense(16, activation='relu')(x)
l1 = tf.keras.layers.Dense(1)(l1)
l2 = tf.keras.layers.Dense(32, activation='relu')(x)
l2 = tf.keras.layers.Dense(1)(l2)
output1 = tf.keras.layers.Lambda(lambda x: tf.reduce_mean(x, axis=1, keepdims=True), name='output1')(tf.concat([l1, l2], axis=1))
output2 = tf.keras.layers.Lambda(lambda x: tf.reduce_mean(x, axis=1, keepdims=True), name='output2')(tf.concat([l1, l2], axis=1))
output3 = tf.keras.layers.Lambda(lambda x: tf.reduce_mean(x, axis=1, keepdims=True), name='output3')(tf.concat([l1, l2], axis=1))
model = tf.keras.Model(inputs, [output1,output2,output3])
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss= tf.keras.losses.mse,
metrics=tf.keras.metrics.RootMeanSquaredError(name="rmse"))
history = model.fit(x_train,{"output1": n1_y_train, "output2": n2_y_train, "output3": n3_y_train},
validation_data = (x_test,{"output1": n1_y_test, "output2": n2_y_test, "output3": n3_y_test}),
verbose=2,
epochs=100,
batch_size=2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.