Keras:验证准确性保持完全相同,但验证损失减少
Keras: Validation accuracy stays the exact same but validation loss decreases
我知道问题不可能出在数据集上,因为我看到其他项目使用相同的数据集。
这是我的数据预处理代码:
import pandas as pd
dataset = pd.read_csv('political_tweets.csv')
dataset.head()
dataset = pd.read_csv('political_tweets.csv')["tweet"].values
y_train = pd.read_csv('political_tweets.csv')["dem_or_rep"].values
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(dataset, y_train, test_size=0.1)
max_words = 10000
print(max_words)
max_len = 25
tokenizer = Tokenizer(num_words = max_words, filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n1234567890', lower=False,oov_token="<OOV>")
tokenizer.fit_on_texts(x_train)
x_train = tokenizer.texts_to_sequences(x_train)
x_train = pad_sequences(x_train, max_len, padding='post', truncating='post')
tokenizer.fit_on_texts(x_test)
x_test = tokenizer.texts_to_sequences(x_test)
x_test = pad_sequences(x_test, max_len, padding='post', truncating='post')
还有我的模特:
model = Sequential([
Embedding(max_words+1,64,input_length=max_len),
Bidirectional(GRU(64, return_sequences = True), merge_mode='concat'),
GlobalMaxPooling1D(),
Dense(64,kernel_regularizer=regularizers.l2(0.02)),
Dropout(0.5),
Dense(1, activation='sigmoid'),
])
model.summary()
model.compile(loss='binary_crossentropy', optimizer=RMSprop(learning_rate=0.0001), metrics=['accuracy'])
model.fit(x_train,y_train, batch_size=128, epochs=500, verbose=1, shuffle=True, validation_data=(x_test, y_test))
我的两个损失都减少了,我的训练准确率增加了,但验证准确率保持在 50%(考虑到我正在做一个二元分类模型,这太糟糕了)。
Epoch 1/500
546/546 [==============================] - 35s 64ms/step - loss: 1.7385 - accuracy: 0.5102 - val_loss: 1.2458 - val_accuracy: 0.5102
Epoch 2/500
546/546 [==============================] - 34s 62ms/step - loss: 0.9746 - accuracy: 0.5137 - val_loss: 0.7886 - val_accuracy: 0.5102
Epoch 3/500
546/546 [==============================] - 34s 62ms/step - loss: 0.7235 - accuracy: 0.5135 - val_loss: 0.6943 - val_accuracy: 0.5102
Epoch 4/500
546/546 [==============================] - 34s 62ms/step - loss: 0.6929 - accuracy: 0.5135 - val_loss: 0.6930 - val_accuracy: 0.5102
Epoch 5/500
546/546 [==============================] - 34s 62ms/step - loss: 0.6928 - accuracy: 0.5135 - val_loss: 0.6931 - val_accuracy: 0.5102
Epoch 6/500
546/546 [==============================] - 34s 62ms/step - loss: 0.6927 - accuracy: 0.5135 - val_loss: 0.6931 - val_accuracy: 0.5102
Epoch 7/500
546/546 [==============================] - 37s 68ms/step - loss: 0.6925 - accuracy: 0.5136 - val_loss: 0.6932 - val_accuracy: 0.5106
Epoch 8/500
546/546 [==============================] - 34s 63ms/step - loss: 0.6892 - accuracy: 0.5403 - val_loss: 0.6958 - val_accuracy: 0.5097
Epoch 9/500
546/546 [==============================] - 35s 63ms/step - loss: 0.6815 - accuracy: 0.5633 - val_loss: 0.7013 - val_accuracy: 0.5116
Epoch 10/500
546/546 [==============================] - 34s 63ms/step - loss: 0.6747 - accuracy: 0.5799 - val_loss: 0.7096 - val_accuracy: 0.5055
我看过关于这个主题的其他帖子,他们说要添加 dropout、交叉熵、降低学习率等。我已经完成了所有这些并且 none 有效。
任何帮助是极大的赞赏。
提前致谢!
针对您的问题的几点观察:
- 虽然对数据集不是特别熟悉,但相信在很多情况下使用都没有问题。但是,您可以尝试检查其余额。在
train_test_split()
中有一个名为 stratify
的参数,如果输入 y
,它将确保每个 class 的相同数量的样本按比例进入训练集和测试集.
- 你的验证丢失和验证准确率的现象并不是什么不寻常的事情。想象一下,在第一个时期,神经网络以 55% 的置信度考虑了一些具有
GT == 1
的真实正例 (ys)。随着训练的进行,神经网络学习得更好,现在它对具有 GT == 1
的真实正例 (ys) 有 90% 的置信度。 由于计算准确度的阈值为 50% ,因此在这两种情况下您的准确度相同。然而,损失发生了显着变化,因为 90% >> 55%
.
- 你的训练似乎在进步(缓慢但稳步)。您是否考虑过使用
Adam
作为现成的优化器?
- 如果在某些时期仍然保持低准确度,您很可能会遇到一种众所周知的现象,称为欠拟合,在这种现象中,您的模型无法捕获两者之间的依赖关系你的数据。要完全 mitigate/avoid 欠拟合,您可能需要使用更复杂的模型
(2 LSTMs / 2 GRUs) stacked
。
- 在这个阶段,删除
Dropout()
层,因为你有欠拟合,而不是过拟合。
- 减少
batch_size
。非常大 batch_size
会导致局部最小值,使您的网络无法正常 learn/generalize。
- 如果 none 这些工作,尝试从较低的学习率开始,说
0.00001
而不是 0.0001
。
- 重申数据集预处理步骤。确保句子转换正确。
我遇到过类似的问题,我想这可能是因为 dropout 就在输出层之前。尝试将其移动到之前的一层。
我知道问题不可能出在数据集上,因为我看到其他项目使用相同的数据集。 这是我的数据预处理代码:
import pandas as pd
dataset = pd.read_csv('political_tweets.csv')
dataset.head()
dataset = pd.read_csv('political_tweets.csv')["tweet"].values
y_train = pd.read_csv('political_tweets.csv')["dem_or_rep"].values
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(dataset, y_train, test_size=0.1)
max_words = 10000
print(max_words)
max_len = 25
tokenizer = Tokenizer(num_words = max_words, filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n1234567890', lower=False,oov_token="<OOV>")
tokenizer.fit_on_texts(x_train)
x_train = tokenizer.texts_to_sequences(x_train)
x_train = pad_sequences(x_train, max_len, padding='post', truncating='post')
tokenizer.fit_on_texts(x_test)
x_test = tokenizer.texts_to_sequences(x_test)
x_test = pad_sequences(x_test, max_len, padding='post', truncating='post')
还有我的模特:
model = Sequential([
Embedding(max_words+1,64,input_length=max_len),
Bidirectional(GRU(64, return_sequences = True), merge_mode='concat'),
GlobalMaxPooling1D(),
Dense(64,kernel_regularizer=regularizers.l2(0.02)),
Dropout(0.5),
Dense(1, activation='sigmoid'),
])
model.summary()
model.compile(loss='binary_crossentropy', optimizer=RMSprop(learning_rate=0.0001), metrics=['accuracy'])
model.fit(x_train,y_train, batch_size=128, epochs=500, verbose=1, shuffle=True, validation_data=(x_test, y_test))
我的两个损失都减少了,我的训练准确率增加了,但验证准确率保持在 50%(考虑到我正在做一个二元分类模型,这太糟糕了)。
Epoch 1/500
546/546 [==============================] - 35s 64ms/step - loss: 1.7385 - accuracy: 0.5102 - val_loss: 1.2458 - val_accuracy: 0.5102
Epoch 2/500
546/546 [==============================] - 34s 62ms/step - loss: 0.9746 - accuracy: 0.5137 - val_loss: 0.7886 - val_accuracy: 0.5102
Epoch 3/500
546/546 [==============================] - 34s 62ms/step - loss: 0.7235 - accuracy: 0.5135 - val_loss: 0.6943 - val_accuracy: 0.5102
Epoch 4/500
546/546 [==============================] - 34s 62ms/step - loss: 0.6929 - accuracy: 0.5135 - val_loss: 0.6930 - val_accuracy: 0.5102
Epoch 5/500
546/546 [==============================] - 34s 62ms/step - loss: 0.6928 - accuracy: 0.5135 - val_loss: 0.6931 - val_accuracy: 0.5102
Epoch 6/500
546/546 [==============================] - 34s 62ms/step - loss: 0.6927 - accuracy: 0.5135 - val_loss: 0.6931 - val_accuracy: 0.5102
Epoch 7/500
546/546 [==============================] - 37s 68ms/step - loss: 0.6925 - accuracy: 0.5136 - val_loss: 0.6932 - val_accuracy: 0.5106
Epoch 8/500
546/546 [==============================] - 34s 63ms/step - loss: 0.6892 - accuracy: 0.5403 - val_loss: 0.6958 - val_accuracy: 0.5097
Epoch 9/500
546/546 [==============================] - 35s 63ms/step - loss: 0.6815 - accuracy: 0.5633 - val_loss: 0.7013 - val_accuracy: 0.5116
Epoch 10/500
546/546 [==============================] - 34s 63ms/step - loss: 0.6747 - accuracy: 0.5799 - val_loss: 0.7096 - val_accuracy: 0.5055
我看过关于这个主题的其他帖子,他们说要添加 dropout、交叉熵、降低学习率等。我已经完成了所有这些并且 none 有效。 任何帮助是极大的赞赏。 提前致谢!
针对您的问题的几点观察:
- 虽然对数据集不是特别熟悉,但相信在很多情况下使用都没有问题。但是,您可以尝试检查其余额。在
train_test_split()
中有一个名为stratify
的参数,如果输入y
,它将确保每个 class 的相同数量的样本按比例进入训练集和测试集. - 你的验证丢失和验证准确率的现象并不是什么不寻常的事情。想象一下,在第一个时期,神经网络以 55% 的置信度考虑了一些具有
GT == 1
的真实正例 (ys)。随着训练的进行,神经网络学习得更好,现在它对具有GT == 1
的真实正例 (ys) 有 90% 的置信度。 由于计算准确度的阈值为 50% ,因此在这两种情况下您的准确度相同。然而,损失发生了显着变化,因为90% >> 55%
. - 你的训练似乎在进步(缓慢但稳步)。您是否考虑过使用
Adam
作为现成的优化器? - 如果在某些时期仍然保持低准确度,您很可能会遇到一种众所周知的现象,称为欠拟合,在这种现象中,您的模型无法捕获两者之间的依赖关系你的数据。要完全 mitigate/avoid 欠拟合,您可能需要使用更复杂的模型
(2 LSTMs / 2 GRUs) stacked
。 - 在这个阶段,删除
Dropout()
层,因为你有欠拟合,而不是过拟合。 - 减少
batch_size
。非常大batch_size
会导致局部最小值,使您的网络无法正常 learn/generalize。 - 如果 none 这些工作,尝试从较低的学习率开始,说
0.00001
而不是0.0001
。 - 重申数据集预处理步骤。确保句子转换正确。
我遇到过类似的问题,我想这可能是因为 dropout 就在输出层之前。尝试将其移动到之前的一层。