小能豆

如何在 Python 中的 keras 函数式 API 中执行交叉验证

py

我想对具有多个输入的 Keras 模型执行交叉验证。因此,我尝试了KerasClassifier。这对于只有一个输入的普通顺序模型来说效果很好。但是,当使用函数式 API 并扩展到两个输入时,sklearncross_val_predict似乎无法按预期工作。

def create_model():
    input_text = Input(shape=(1,), dtype=tf.string)
    embedding = Lambda(UniversalEmbedding, output_shape=(512, ))(input_text)
    dense = Dense(256, activation='relu')(embedding)    
    input_title = Input(shape=(1,), dtype=tf.string)
    embedding_title = Lambda(UniversalEmbedding, output_shape=(512, ))(input_title)
    dense_title = Dense(256, activation='relu')(embedding_title)    
    out = Concatenate()([dense, dense_title])

    pred = Dense(2, activation='softmax')(out)
    model = Model(inputs=[input_text, input_title], outputs=pred)
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

    return model

交叉验证代码失败

keras_classifier = KerasClassifier(build_fn=create_model, epochs=10, batch_size=10, verbose=1)
cv = StratifiedKFold(n_splits=10, random_state=0)
results = cross_val_predict(keras_classifier, [X1, X2], y, cv=cv, method = "predict_proba")

后来我发现KerasClassifier它只支持顺序模型:https ://keras.io/scikit-learn-api/ 。换句话说,它不支持具有多个输入的函数式 api。

因此,我想知道是否有其他方法可以对使用 keras 中的功能 api 的模型进行交叉验证。更具体地说,我想获得每个数据实例的预测概率(当它在交叉验证中的测试切片中时) - 这就是所发生的情况cross_val_predict

如果需要,我很乐意提供更多详细信息。

编辑:我现在的问题是如何将多个输入输入到StratifiedKFold.split()。我已经输入了????????????代码。只是在想是否可以将其作为[input1, input2, input3, input4, input5]

假设我有 5 个输入input1,如input2,,,,,input3我该如何使用这些input4输入input5``StratifiedKFold.split()

k_fold = StratifiedKFold(n_splits=10, shuffle=True, random_state=0)

for train_index, test_index in k_fold.split(????????????, labels):

    print("iteration", i, ":")
    print("train indices:", train_index)

    #input1
    print("train data:", input1[train_index])

    #input2
    print("train data:", input2[train_index])

    #input3
    print("train data:", input3[train_index])

    #input4
    print("train data:", input1[train_index])

    #input5
    print("train data:", input1[train_index])

    print("test indices:", test_index)
    print("test data:", X[test_index])

阅读 6

收藏
2024-12-23

共1个答案

小能豆

有趣的是,sklearn 仅支持Sequential但查看您的模型,我认为您可以有一个输入,因为它们共享嵌入等:

def create_model():
    model = Sequential()
    model.add(Lambda(UniversalEmbedding, output_shape=(2, 512), input_shape=(2,)))
    # (2, 512)
    model.add(Flatten()) # (2*512)
    model.add(Dense(2*256, activation='relu')) # (2*256)
    model.add(Dense(2, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

    return model

换句话说,您有 2 个以相同方式嵌入的同一域的输入,因此您可以使用大小为 2 的单个输入。然后,为了模拟两个密集层,您可以将其展平并拥有一个大小为两倍的单个密集层:)这会将您带到与模型相同的连接层。

2024-12-23