Keras 的 model.predict() 一次调用多个批次与逐个调用单个批次时产生非常不同的准确性
Keras' model.predict() produces very different accuracy when calling on multiple batches at once VS calling on individual batches one by one
这是我用过的模型:
model = Sequential()
model.add(LSTM(units=200, input_shape=(15, 17), return_sequences=True)
model.add(Dropout(drop_out))
model.add(BatchNormalization())
model.add(LSTM(units=unit_per_layer))
model.add(Dropout(drop_out))
model.add(BatchNormalization())
model.add(Dense(units=unit_per_layer, activation='tanh'))
model.add(Dropout(drop_out))
model.add(BatchNormalization())
model.add(Dense(units=1, activation='sigmoid'))
model.compile(optimizer=opti_func, loss='binary_crossentropy', metrics=['binary_accuracy'])
现在,在 model.fit()
之后,当我调用 model.predict(X_dataset_multiple_batch)
时,我得到了一些很好的预测。但是,如果我将 X_dataset_multiple_batch
分成一系列单独的批次(让我们称它们为 X_dataset_single_batch
)并逐个调用 model.predict(X_dataset_single_batch)
(即多次调用 model.predict(X_dataset_single_batch)
), 预测变得比前者差很多。
补充说明
老实说,我只需要最后一个预测,但由于 Keras 的内部设计,我不能只有一个预测。必须分批次。所以我必须对批次进行预测,然后提取最后的预测。这很好,但现在的问题是我必须给出的最佳批次数是多少 model.predict()
?
胡乱猜测
这不是与 LSTM 在每批次后重置其状态的方式有关吗?
更新 1
这就是我从 test.csv 中挑选个别批次的方式:
df = pd.read_csv("/content/drive/MyDrive/Colab Notebooks/Data/Test_file.csv")
X_ = df.loc[:, 'b':'dm'].to_numpy()
Y_ = df.loc[:, 'dn'].to_numpy()
predictions = []
for i in range (0, 2 + X_.shape[0] - (n_batch + time_step)):
X = X_[i:i+n_batch+time_step]
Y = Y_[i:i+n_batch+time_step]
scaler = MinMaxScaler()
X = scaler.fit_transform(X)
X_one_batch_of_data = np.zeros((n_batch, time_step, X.shape[1]))
for j in range(0, X_one_batch_of_data.shape[0]):
X_one_batch_of_data[j] = X[j:j+time_step, :]
predictions.append(model.predict(X_one_batch_of_data, batch_size=n_batch)[-1, 0])
您基本上是在训练和测试时以不同方式预处理(缩放)数据。
这里的教训是,如果你的预处理管道适合数据(就像你的 MinMaxScaler
是*),它应该适合训练数据并保存以便在测试时重新使用。通过这种方式,您可以确保测试数据接受与训练数据相同的处理(这就是您的模型知道如何处理的内容)。
(*) MinMaxScaler
查找数据集中每个特征的最小值和最大值。当然,训练和测试数据集的某些或所有特征可能具有不同的最小值和最大值。
这是我用过的模型:
model = Sequential()
model.add(LSTM(units=200, input_shape=(15, 17), return_sequences=True)
model.add(Dropout(drop_out))
model.add(BatchNormalization())
model.add(LSTM(units=unit_per_layer))
model.add(Dropout(drop_out))
model.add(BatchNormalization())
model.add(Dense(units=unit_per_layer, activation='tanh'))
model.add(Dropout(drop_out))
model.add(BatchNormalization())
model.add(Dense(units=1, activation='sigmoid'))
model.compile(optimizer=opti_func, loss='binary_crossentropy', metrics=['binary_accuracy'])
现在,在 model.fit()
之后,当我调用 model.predict(X_dataset_multiple_batch)
时,我得到了一些很好的预测。但是,如果我将 X_dataset_multiple_batch
分成一系列单独的批次(让我们称它们为 X_dataset_single_batch
)并逐个调用 model.predict(X_dataset_single_batch)
(即多次调用 model.predict(X_dataset_single_batch)
), 预测变得比前者差很多。
补充说明
老实说,我只需要最后一个预测,但由于 Keras 的内部设计,我不能只有一个预测。必须分批次。所以我必须对批次进行预测,然后提取最后的预测。这很好,但现在的问题是我必须给出的最佳批次数是多少 model.predict()
?
胡乱猜测
这不是与 LSTM 在每批次后重置其状态的方式有关吗?更新 1
这就是我从 test.csv 中挑选个别批次的方式:df = pd.read_csv("/content/drive/MyDrive/Colab Notebooks/Data/Test_file.csv")
X_ = df.loc[:, 'b':'dm'].to_numpy()
Y_ = df.loc[:, 'dn'].to_numpy()
predictions = []
for i in range (0, 2 + X_.shape[0] - (n_batch + time_step)):
X = X_[i:i+n_batch+time_step]
Y = Y_[i:i+n_batch+time_step]
scaler = MinMaxScaler()
X = scaler.fit_transform(X)
X_one_batch_of_data = np.zeros((n_batch, time_step, X.shape[1]))
for j in range(0, X_one_batch_of_data.shape[0]):
X_one_batch_of_data[j] = X[j:j+time_step, :]
predictions.append(model.predict(X_one_batch_of_data, batch_size=n_batch)[-1, 0])
您基本上是在训练和测试时以不同方式预处理(缩放)数据。
这里的教训是,如果你的预处理管道适合数据(就像你的 MinMaxScaler
是*),它应该适合训练数据并保存以便在测试时重新使用。通过这种方式,您可以确保测试数据接受与训练数据相同的处理(这就是您的模型知道如何处理的内容)。
(*) MinMaxScaler
查找数据集中每个特征的最小值和最大值。当然,训练和测试数据集的某些或所有特征可能具有不同的最小值和最大值。