如何在 python 中的 keras functional api 中执行交叉验证
How to perform cross-validation in keras functional api in python
我想对具有多个输入的 Keras 模型执行交叉验证。所以,我尝试了 KerasClassifier
。这适用于只有一个输入的普通顺序模型。但是,当使用功能 api 并扩展到两个输入时,sklearn 的 cross_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])
有趣的一点是 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 的单个输入。然后为了模拟两个密集层,你展平并有一个单一的密集层,其大小是两倍大小 :) 这会将您带到模型相同的连接层。
我想对具有多个输入的 Keras 模型执行交叉验证。所以,我尝试了 KerasClassifier
。这适用于只有一个输入的普通顺序模型。但是,当使用功能 api 并扩展到两个输入时,sklearn 的 cross_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])
有趣的一点是 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 的单个输入。然后为了模拟两个密集层,你展平并有一个单一的密集层,其大小是两倍大小 :) 这会将您带到模型相同的连接层。