我已经用Keras编写了一个LSTM网络(以下代码):
df = pd.read_csv("../data/training_data.csv")
# Group by and pivot the data
group_index = df.groupby('group').cumcount()
data = (df.set_index(['group', group_index])
.unstack(fill_value=0).stack())
# getting np array of the data and labeling
# on the label group we take the first label because it is the same for all
target = np.array(data['label'].groupby(level=0).apply(lambda x: [x.values[0]]).tolist())
data = data.loc[:, data.columns != 'label']
data = np.array(data.groupby(level=0).apply(lambda x: x.values.tolist()).tolist())
# shuffel the training set
data, target = shuffle(data, target)
# spilt data to train and test
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=4)
# ADAM Optimizer with learning rate decay
opt = optimizers.Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0001)
# build the model
model = Sequential()
num_features = data.shape[2]
num_samples = data.shape[1]
model.add(LSTM(8, batch_input_shape=(None, num_samples, num_features), return_sequences=True, activation='sigmoid'))
model.add(LeakyReLU(alpha=.001))
model.add(Dropout(0.2))
model.add(LSTM(4, return_sequences=True, activation='sigmoid'))
model.add(LeakyReLU(alpha=.001))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer=opt,
metrics=['accuracy', keras_metrics.precision(), keras_metrics.recall(),f1])
model.summary()
# Training, getting the results history for plotting
history = model.fit(x_train, y_train, epochs=3000, validation_data=(x_test, y_test))
受监控的指标包括损失,准确性,准确性,召回率和f1得分。
我注意到验证损失指标开始攀升约300个纪元,因此我认为过度拟合!,但是召回率仍在攀升,而精度则略有提高。
那是为什么?我的模特过拟合吗?
答案 0 :(得分:4)
验证损失指标开始攀升约300个纪元(...),召回率仍在攀升,并且精度有所提高。 (...)为什么?
精确度和召回率是衡量分类器根据预测的类标签执行情况的方式。另一方面,模型损失是cross entropy(分类概率误差)的度量:
其中
y = predicted label
p = probability of predicted label
例如,对于一个不同的时期,模型的(softmax)输出可能看起来像这样
# epoch 300
y = [0.1, 0.9] => argmax(y) => 1 (class label 1)
loss = -(1 * log(0.9)) = 0.10
# epoch 500
y = [0.4, 0.6] => argmax(y) => 1 (class label 1)
loss = -(1 * log(0.6)) = 0.51
在两种情况下,精度和召回率指标均保持不变(类别标签仍可正确预测),但是模型损失有所增加。一般而言,该模型对其预测已经“不确定”,但仍然正确。
请注意,模型中的损失是针对所有观察结果而计算的,而不仅仅是单个观察结果。为了简化我限制讨论。通过将所有观测值的损失取平均值,将损失公式简单地扩展为n> 1个观测值。
我的模型过拟合吗?
为了确定这一点,您必须比较训练损失和验证损失。您不能仅凭验证损失来判断。如果训练损失减少而验证损失增加,则表明模型过度拟合。
答案 1 :(得分:2)
实际上,如果验证损失再次开始增加,那么您可能希望尽早停止。这是一种“标准”方法,称为“提前停止”(https://en.wikipedia.org/wiki/Early_stopping)。显然,如果验证和数据的损失在增加,则该模型的工作可能不尽如人意,那就是过度拟合。
精确度和召回率还不够,如果您的模型给出的是更多阳性结果,而阴性结果较少(例如9个阳性结果表示1个阴性结果),则准确度和召回率会增加。这样,这些比率似乎可以得到改善,但这仅仅是因为您的真实负面因素更少。
将这两个部分放在一起可以帮助您了解此处发生的情况。好的答案可能仍然是好的答案,但是质量较低(单个样本的损失平均增加,但仍然使好的答案保持良好),并且可能会从错误的答案变为带有偏差的正确答案(真否定)被转化为误报)。
答案 2 :(得分:1)
正如@Matthieu提到的,仅看一类的精度和召回率可能会产生偏差。也许我们也必须考虑其他班级的表现。
在二元分类的情况下,更好的度量可能是一致性(roc的auc)。一致性衡量模型对基于类的可能性对数据点进行排序的良好性。
另一种选择是宏/微精度/调用,以获取模型性能的完整图片。