我建立了一个模型,当我训练它时,我的验证损失比训练模型小,验证精度比训练模型高。模型是否安装过度?我做错什么了吗?有人能看看我的模型,看看是否有什么问题吗?多谢各位
input_text = Input(shape=(200,), dtype='int32', name='input_text')
meta_input = Input(shape=(2,), name='meta_input')
embedding = Embedding(input_dim=len(tokenizer.word_index) + 1,
output_dim=300,
input_length=200)(input_text)
lstm = Bidirectional(LSTM(units=128,
dropout=0.5,
recurrent_dropout=0.5,
return_sequences=True),
merge_mode='concat')(embedding)
pool = GlobalMaxPooling1D()(lstm)
dropout = Dropout(0.5)(pool)
text_output = Dense(n_codes, activation='sigmoid', name='aux_output')(dropout)
output = concatenate([text_output, meta_input])
output = Dense(n_codes, activation='relu')(output)
main_output = Dense(n_codes, activation='softmax', name='main_output')(output)
model = Model(inputs=[input_text,meta_input], outputs=[output])
optimer = Adam(lr=.001)
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
model.summary()
model.fit([X1_train, X2_train], [y_train],
validation_data=([X1_valid,X2_valid], [y_valid]),
batch_size=64, epochs=20, verbose=1)
以下是输出:
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_text (InputLayer) [(None, 200)] 0
__________________________________________________________________________________________________
embedding (Embedding) (None, 200, 300) 889500 input_text[0][0]
__________________________________________________________________________________________________
bidirectional (Bidirectional) (None, 200, 256) 439296 embedding[0][0]
__________________________________________________________________________________________________
global_max_pooling1d (GlobalMax (None, 256) 0 bidirectional[0][0]
__________________________________________________________________________________________________
dropout (Dropout) (None, 256) 0 global_max_pooling1d[0][0]
__________________________________________________________________________________________________
aux_output (Dense) (None, 545) 140065 dropout[0][0]
__________________________________________________________________________________________________
meta_input (InputLayer) [(None, 2)] 0
__________________________________________________________________________________________________
concatenate (Concatenate) (None, 547) 0 aux_output[0][0]
meta_input[0][0]
__________________________________________________________________________________________________
dense (Dense) (None, 545) 298660 concatenate[0][0]
==================================================================================================
Total params: 1,767,521
Trainable params: 1,767,521
Non-trainable params: 0
__________________________________________________________________________________________________
Train on 11416 samples, validate on 2035 samples
Epoch 1/20
11416/11416 [==============================] - 158s 14ms/sample - loss: 0.0955 - accuracy: 0.9929 -
val_loss: 0.0559 - val_accuracy: 0.9964
Epoch 2/20
11416/11416 [==============================] - 152s 13ms/sample - loss: 0.0562 - accuracy: 0.9963 -
val_loss: 0.0559 - val_accuracy: 0.9964
Epoch 3/20
11416/11416 [==============================] - 209s 18ms/sample - loss: 0.0562 - accuracy: 0.9963 -
val_loss: 0.0559 - val_accuracy: 0.9964
Epoch 4/20
11416/11416 [==============================] - 178s 16ms/sample - loss: 0.0562 - accuracy: 0.9963 -
val_loss: 0.0559 - val_accuracy: 0.9964
Epoch 5/20
11416/11416 [==============================] - 211s 18ms/sample - loss: 0.0562 - accuracy: 0.9963 -
val_loss: 0.0559 - val_accuracy: 0.9964
Epoch 6/20
差别很小,所以我不会担心。 一般来说,可能发生的情况是,在随机拆分训练集和验证集的过程中,验证集中选择的示例比训练集中的示例“更容易”猜测
您可以通过制定如下交叉验证策略来克服这一问题:
- 取数据集的10%(保存),并将其视为测试集。<李>
- 对于剩余的数据集,对训练集和验证集进行80%-20%的分割李>
- 重复80-20培训验证拆分5次李>
- 在5个不同的Train有效数据集上训练5个模型,并查看结果李>
- 您甚至可以在测试集上比较所有5个模型,以查看“真实”或“更接近真实”的精度。这可能有助于了解哪种模型更具普遍性李>
最后,你甚至可以考虑把它们堆在一起: https://machinelearningmastery.com/stacking-ensemble-for-deep-learning-neural-networks/事实上,训练和验证精度看起来相似,并且在训练期间没有变化,这表明模型可能陷入局部极小值。 值得进行更多的历次(至少20次)训练,看看模型是否能以当前的学习速度“跳出”局部极小值
如果这不能解决问题,我会将学习率从.001改为.0001或.00001。这将有助于模型有希望收敛到全局极小值
如果这不能解决问题,通常还有许多其他参数/超参数可用于进一步检查:层中的节点数、层数、优化器策略、训练集的大小和分布(通用性和差异性)
不,没有错,这种效果(验证指标优于培训指标)在使用辍学时很常见,就像您的网络使用的那样
辍学会在训练过程中增加噪声,而这种噪声在验证/测试过程中不存在,因此训练指标自然会变得更差,但验证指标没有这种噪声,并且由于辍学所产生的改进的泛化效果而更好
当
acc
高于val_acc
且loss
低于val_loss
时,会出现过度拟合但是,在我看来,您的验证数据集不能代表数据集中的总体分布。无论出于何种原因,验证数据集的结果都是恒定的,甚至更高
您正在进行二进制分类。注意班级不平衡
例如,如果99%的样本是类}并有一定的损失。而且
0
,1%是类1
, 然后,即使你的模型没有学到任何东西,如果它总是预测0
,而从来没有预测过1
,那么它的准确率将达到99%。 想象一下,您(大部分是随机的)数据分割创建了一个数据集,其中99.5%的验证数据是class0
和0.5%的class1
。 想象一下,在最坏的情况下,你的模型什么也学不到。并且吐出(“预测”)总是一个0
。然后列车acc将持续{val_acc
将不断地0.995
对我来说,令人费解的是,你的绩效指标是恒定不变的。这总是很糟糕。因为通常情况下,如果模型学习到某个东西,即使它过度拟合,也会出现随机噪声
没有一本书会告诉你以下内容——没有初学者的书。我从经验中学到了这一点:你必须把
shuffle=True
放在你的model.fit()
里。 因为对我来说,你似乎在以一种方式进行训练,你首先只展示一个类的样本,然后展示另一个类的样本。混合一类和另一类的样本可以很好地扰动模型,避免陷入局部极小或者有时候,即使在洗牌时,我也会得到如此稳定的结果
在这种情况下,我只是尝试选择另一个随机分割,这样效果更好。(因此:尝试其他拆分!)
相关问题 更多 >
编程相关推荐