我的数据集由时间序列(10080)和其他描述性统计特征(85)
连接成一行
组成。 DataFrame 是
921 x 10166
数据看起来像这样,最后两列为
Y
(标签)。
id x0 x1 x2 x3 x4 x5 ... x10079 mean var ... Y0 Y1
1 40 31.05 25.5 25.5 25.5 25 ... 33 24 1 1 0
2 35 35.75 36.5 26.5 36.5 36.5 ... 29 31 2 0 1
3 35 35.70 36.5 36.5 36.5 36.5 ... 29 25 1 1 0
4 40 31.50 23.5 24.5 26.5 25 ... 33 29 3 0 1
...
921 40 31.05 25.5 25.5 25.5 25 ... 23 33 2 0 1
我检查了一些
博客
和
教程
这很有帮助,但我不确定如何处理我分成
inputs_1
和
inputs_2
的输入数据,如下面的模型所示:
inputs_1 = keras.Input(shape=(10081,1))
layer1 = Conv1D(64,14)(inputs_1)
layer2 = layers.MaxPool1D(5)(layer1)
layer3 = Conv1D(64, 14)(layer2)
layer4 = layers.GlobalMaxPooling1D()(layer3)
inputs_2 = keras.Input(shape=(85,))
layer5 = layers.concatenate([layer4, inputs_2])
layer6 = Dense(128, activation='relu')(layer5)
layer7 = Dense(2, activation='softmax')(layer6)
model_2 = keras.models.Model(inputs = [inputs_1, inputs_2], output = [layer7])
X_train, X_test, y_train, y_test = train_test_split(df.iloc[:,0:10166], merge[['Result_cat','Result_cat1']].values, test_size=0.2)
X_train = X_train.to_numpy()
X_train = X_train.reshape([X_train.shape[0], X_train.shape[1], 1])
X_train_1 = X_train[:,0:10081,:]
X_train_2 = X_train[:,10081:10166,:].reshape(736,85)
X_test = X_test.to_numpy()
X_test = X_test.reshape([X_test.shape[0], X_test.shape[1], 1])
X_test_1 = X_test[:,0:10081,:]
X_test_2 = X_test[:,10081:10166,:].reshape(185,85)
adam = keras.optimizers.Adam(lr = 0.0005)
model_2.compile(loss = 'categorical_crossentropy', optimizer = adam, metrics = ['acc'])
history = model_2.fit([X_train_1,X_train_2], y_train, epochs = 120, batch_size = 256, validation_split = 0.2, callbacks = [keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)])
将特征分为两部分的原因是| ||主要是时间序列数据,而
inputs_1
是描述性统计数据。我认为考虑到数据的不同性质,最好将它们分开。如果我错了,请纠正我。
inputs_2
我的问题是,由于我的特征数据在原始模型中被划分和单独处理,我是否应该在交叉验证中做同样的事情(处理
和
inputs_1
分开)?特别是,例如,在 Jason 的模型中:
inputs_2
使用代码
# MLP for Pima Indians Dataset with 10-fold cross validation
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import StratifiedKFold
import numpy
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load pima indians dataset
dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# define 10-fold cross validation test harness
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
cvscores = []
for train, test in kfold.split(X, Y):
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X[train], Y[train], epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.evaluate(X[test], Y[test], verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
cvscores.append(scores[1] * 100)
print("%.2f%% (+/- %.2f%%)" % (numpy.mean(cvscores), numpy.std(cvscores)))
进行评估,其中使用了
scores = model.evaluate(X[test], Y[test], verbose=0)
就我而言,由于我有
X[test], Y[test]
和
inputs_1
而不是
inputs_2
(在示例模型中),我应该使用类似
X
的东西吗?谢谢
[inputs_1,inputs_2][test]
更新:
我尝试连接
和
与
inputs_1
并将模型的第一行更改为
inputs_2
但它返回
con_x = np.concatenate((X_train_1,X_train_2), axis = 1)
但是,我仍然不确定它是否像这样连接
for train, test in kfold.split(con_x, Y):
和
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-17-d53a7058d157> in <module>()
55 cvscores = []
---> 56 for train, test in kfold.split(con_x, Y):
57
58 inputs_1 = keras.Input(shape=(10080,1))
1 frames
/usr/local/lib/python3.6/dist-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, warn_on_dtype, estimator)
537 if not allow_nd and array.ndim >= 3:
538 raise ValueError("Found array with dim %d. %s expected <= 2."
--> 539 % (array.ndim, estimator_name))
540 if force_all_finite:
541 _assert_all_finite(array,
ValueError: Found array with dim 3. Estimator expected <= 2.
是有效的。
inputs_1
and
inputs_2
like this.
下面是如何使用 Keras 对具有多个输入的 CNN 模型执行交叉验证,同时保持你的
inputs_1
和
inputs_2
分开:
import numpy as np
import pandas as pd
from sklearn.model_selection import StratifiedKFold
from tensorflow import keras
from tensorflow.keras.layers import Input, Conv1D, MaxPool1D, GlobalMaxPooling1D, concatenate, Dense
from tensorflow.keras.models import Model
# 假设你的 DataFrame 名为 df
# ...(像之前一样加载和预处理你的数据,直到 train_test_split)
# 创建一个函数来构建你的 Keras 模型
def create_model():
inputs_1 = Input(shape=(10080, 1))
layer1 = Conv1D(64, 14)(inputs_1)
layer2 = MaxPool1D(5)(layer1)
layer3 = Conv1D(64, 14)(layer2)
layer4 = GlobalMaxPooling1D()(layer3)
inputs_2 = Input(shape=(85,))
layer5 = concatenate([layer4, inputs_2])
layer6 = Dense(128, activation='relu')(layer5)
layer7 = Dense(2, activation='softmax')(layer6)
model = Model(inputs=[inputs_1, inputs_2], outputs=[layer7])
adam = keras.optimizers.Adam(lr=0.0005)
model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['acc'])
return model
# 将数据分为特征 (X) 和标签 (Y)
X = df.iloc[:, 0:10166]
Y = df[['Y0', 'Y1']].values # 假设你的标签列名为 'Y0' 和 'Y1'
# 定义 k 折交叉验证
n_splits = 10 # 你可以使用任何你想要的分割数
kfold = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=42)
cvscores = []
for fold, (train_idx, test_idx) in enumerate(kfold.split(X, np.argmax(Y, axis=1))):
print(f"在折痕 {fold + 1}/{n_splits} 上训练...")
# 将数据分割为训练集和测试集
X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
y_train, y_test = Y[train_idx], Y[test_idx]
# 为每个输入准备数据
X_train_1 = X_train.iloc[:, 0:10080].values.reshape(-1, 10080, 1)
X_train_2 = X_train.iloc[:, 10080:10166].values
X_test_1 = X_test.iloc[:, 0:10080].values.reshape(-1, 10080, 1)
X_test_2 = X_test.iloc[:, 10080:10166].values
# 创建模型
model = create_model()
# 训练模型
model.fit([X_train_1, X_train_2], y_train, epochs=120, batch_size=256,
validation_split=0.2,
callbacks=[keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)],
verbose=0) # 将 verbose 设置为 1 或 2 以查看训练进度
# 评估模型
scores = model.evaluate([X_test_1, X_test_2], y_test, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1] * 100))
cvscores.append(scores[1] * 100)
print("%.2f%% (+/- %.2f%%)" % (np.mean(cvscores), np.std(cvscores)))
说明:
-
数据分离: 不是连接
inputs_1
和inputs_2
,而是将它们分开处理,并在训练和评估期间将它们作为单独的输入传递给模型。 -
StratifiedKFold: 为了保持类别分布,使用了
StratifiedKFold
进行交叉验证。 -
模型创建函数: 定义了一个
create_model()
函数来构建和编译每个折痕的新模型实例。这确保了每个折痕都从一个干净的模型开始。 -
数据重塑: 在每个折痕的训练和评估之前,将数据重塑为每个输入的正确形状。
-
评估: 该模型使用测试集中的
inputs_1
和inputs_2
(X_test_1
和X_test_2
)进行评估。
此设置通过在交叉验证期间保持
inputs_1
和
inputs_2
的分离来正确处理多个输入,从而提供更可靠的模型性能评估。
请记住根据你的数据调整时期数、批大小和其他超参数以获得最佳结果。
标签:python,machine-learning,keras,conv-neural-network,cross-validation From: 59277549