简体   繁体   English

在 keras 中构造多输出 model 时出错

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM