首页 > 解决方案 > Keras多输出numpy转换

问题描述

我有一个y_train形状为(samples, 9). 我的X_train输入是(samples, 30, 1).

这些贯穿一个构建为的模型:

def create_model(input_shape, outputs):
    i = Input(shape=input_shape)

    x = Dense(256, activation="relu")(i)
    x = Dropout(0.5)(x)
    x = Dense(128, activation="relu")(x)
    x = Dropout(0.5)(x)
    x = Dense(64, activation="relu")(x)
    x = Dropout(0.5)(x)
    x = Flatten()(x)

    # Optimize each binary output independently.
    o = list(map(lambda _: Dense(1, activation='sigmoid')(x), range(outputs)))

    m = Model(i, o)
    m.compile('adam', loss='binary_crossentropy', metrics=['accuracy'])
    return m

model = create_model((30, 1), 9)

这会产生训练错误:

检查模型目标时出错:您传递给模型的 Numpy 数组列表不是模型预期的大小。预计会看到 9 个数组,但得到了以下 1 个数组的列表:

[array([[1., 1., 1., ..., 0., 0., 0.],
   [1., 0., 0., ..., 0., 0., 0.],
   [0., 0., 0., ..., 0., 0., 0.],
   ...,
   [0., 0., 0., ..., 1., 1., 1.],
   [0., 0., 0., ..., 0., 0., 0....

我尝试了y_train形状的变化,使用(9, samples, 1)(samples, 1, 9)。keras 想看到我的(samples, 9)数组形状如何变化?

标签: pythonnumpytensorflowkeras

解决方案


您的模型有 9 个输出层,每个都有二进制交叉熵。因此,您需要将输出作为 9 个输出的列表传递,其中每个输出都是一个(samples, 1)大小合适的数组,而不是具有 9 列的单个数组。

因此,您需要执行以下操作。

# Assuming your y_train is of size (samples, 9)
y_train_list = np.split(y_train, y_train.shape[1], axis=1)

model.fit(x_train, y_train_list)

这是一个带有玩具数据的工作示例

x_train = np.random.normal(size=(500,30,1))
y_train = np.random.choice([0,1], size=(500, 9))
y_train_list = np.split(y_train, y_train.shape[1], axis=1)
model.fit(X_tr, y_train_list)

使用 train_test_split 创建训练验证数据

from sklearn.model_selection import train_test_split

tr_x, ts_x, tr_y, ts_y =train_test_split(X_tr, Y_tr, test_size=0.33)
tr_list_y = np.split(tr_y, tr_y.shape[1], axis=1)
ts_list_y = np.split(ts_y, ts_y.shape[1], axis=1)
model.fit(tr_x, tr_list_y, validation_data=(ts_x, ts_list_y))

推荐阅读