我正在尝试训练 LSTM 模型,但问题是损失和val_loss从 12 和 5 减少到小于 0.01,但训练集acc = 0.024和验证集acc = 0.0000e+00在训练期间保持不变。为什么会发生这种情况,我该如何解决?
loss/val_loss 正在减少,但 LSTM 中的准确度是相同的!
我认为这是因为您的目标y是连续的而不是二元的。因此,要么忽略accuracy报告,要么在适用时对目标进行二值化。
我假设你正在使用Keras. 当您使用 时metrics=['accuracy'],这就是幕后发生的事情:
if metric in ('accuracy', 'acc'):
metric_fn = metrics_module.binary_accuracy
在哪里
def binary_accuracy(y_true, y_pred):
return K.mean(K.equal(y_true, K.round(y_pred)), axis=-1)
在连续目标的情况下,只有那些y_true完全0或完全1等于模型预测的目标K.round(y_pred))。因此,accuracy不能用于连续目标。
这是演示此问题的代码:
from keras import Sequential
from keras.layers import LSTM, Dense
import numpy as np
# Parameters
N = 1000
halfN = int(N/2)
seq_len = 10
dimension = 2
lstm_units = 3
# Data
np.random.seed(123) # to generate the same numbers
X_zero = np.random.normal(0, 1, size=(halfN, seq_len, dimension))
y_binary_zero = np.zeros((halfN, 1)) # output is only 0
y_continuous_zero = np.random.randint(0, 50, (halfN, 1)) / 100 # output is in [0, 0.5]
X_one = np.random.normal(1, 1, size=(halfN, seq_len, dimension))
y_binary_one = np.ones((halfN, 1)) # output is only 1
y_continuous_one = 0.5 + np.random.randint(0, 50, (halfN, 1)) / 100 # output is in [0.5, 1.0]
p = np.random.permutation(N) # to shuffle zero and one classes
X = np.concatenate((X_zero, X_one))[p]
y_binary = np.concatenate((y_binary_zero, y_binary_one))[p]
y_continuous = np.concatenate((y_continuous_zero, y_continuous_one))[p]
# Build model
model = Sequential()
model.add(LSTM(lstm_units, input_shape=(None, dimension)))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
print(model.summary())
# Fit model
# fit using binary outputs
print('-----------------------Binary---------------------')
model.fit(X, y_binary, batch_size=32, epochs=10)
# fit using continuous outputs
print('-----------------------Continuous---------------------')
model.fit(X, y_continuous, batch_size=32, epochs=10)
哪个输出
...
-----------------------Binary---------------------
...
1000/1000 [==============================] - 0s 122us/step - loss: 0.3989 - acc: 0.9500
-----------------------Continuous---------------------
...
1000/1000 [==============================] - 0s 135us/step - loss: 0.5759 - acc: 0.0050
为了回答这个问题,我应该澄清什么是成本(损失)函数以及什么是评估指标的函数。
成本(损失)函数
成本函数是衡量目标样本(标签)与网络输出(由特征向量提供时)之间的平均差异的函数。您的机器学习算法试图在训练过程中最小化成本函数的值(当您的网络仅由训练特征向量提供时)。因此,在 LSTM 网络的情况下,它会尝试在每个 epoch 中调整 LSTM 权重,以降低在训练样本上计算的成本函数值。在您的问题中,根据标签的数量,成本函数可以是交叉熵或二元交叉熵,分别用于两个以上的类别或两个类别的情况。
评价指标的作用
评估指标的函数是衡量目标训练样本或验证样本与网络输出之间的平均相似度的函数(当它由训练或验证特征向量提供时)。与成本函数不同,您的机器学习算法不使用评估指标的函数来调整 LSTM 网络权重。相反,它使用评估指标的功能来评估模型在给定特征向量作为输入时预测类标签的能力。在您的问题中,准确性是评估指标。
因此,如果 training_loss 和 val_loss 正在减少,但 training_acc 和 validation_acc 在训练期间保持不变,您不应该感到惊讶,因为您的训练算法不能保证每个时期的准确性都会增加。那是因为它不检查准确性来调整模型的权重,而是检查 training_loss 来做到这一点。