我有一个形状为 (1280, 100, 20, 4096) 的训练集,我将其提供给基于变压器的模型进行二元分类(标签为 0 或 1)。这导致我难以处理大量的特征(我尝试将其批量提供给模型,但我不确定最好的方法。现在我只是将其减少到(450, 100, 20, 4096),但任何建议都值得赞赏),但我目前的问题是,无论我训练模型多少个时期,准确率始终为 67.5%(即 0 的百分比) -测试集中的标记特征),测试集上的精度和召回率将始终为 0%。在将数据输入模型之前,我尝试对其进行标准化:
scaler = StandardScaler()
train_data = scaler.fit_transform(train_data.reshape(-1, train_data.shape[-1])).reshape(train_data.shape)
test_data = scaler.transform(test_data.reshape(-1, test_data.shape[-1])).reshape(test_data.shape)
但这并没有带来任何改善。我使用的模型基于仅编码器变压器:
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 100, 20, 4096)] 0
_________________________________________________________________
frame_position_embedding (Po (None, 100, 20, 4096) 8192000
_________________________________________________________________
transformer_layer (Encoder) (None, 100, 20, 4096) 134299652
_________________________________________________________________
global_max_pooling (GlobalMa (None, 4096) 0
_________________________________________________________________
dropout (Dropout) (None, 4096) 0
_________________________________________________________________
output (Dense) (None, 1) 4097
=================================================================
Total params: 142,495,749
Trainable params: 142,495,749
Non-trainable params: 0
_________________________________________________________________
在训练过程中,我可以看到损失、准确度、精确度和召回率达到了不错的水平,但是当我在测试集上评估模型时,所有这些值都如我之前所描述的那样:
Epoch 100/100
29/29 [==============================] - 90s 3s/step - loss: 0.0839 - accuracy: 0.9610 - recall: 0.9316 - precision: 0.9589
2024-02-06 12:38:38.815759: W tensorflow/core/framework/cpu_allocator_impl.cc:80] Allocation of 9175040000 exceeds 10% of free system memory.
9/9 [==============================] - 21s 2s/step - loss: 9.4117 - accuracy: 0.6750 - recall: 0.0000e+00 - precision: 0.0000e+00
Test accuracy: 67.5%
Test recall: 0.0%
Test precision: 0.0%
模型优化器是adam,损失是二元交叉熵。激活是S形的。 我正在努力寻找模型的适当调整,甚至理解其当前的行为。此外,我不清楚将批量数据输入缩放器和拟合函数是否会改变模型的实际训练。
听起来模型正在适应训练集,但没有推广到测试集。这是过度拟合行为,这似乎很可能发生,因为与模型大小相比,您的样本相对较少(1300 个样本 vs 1.4 亿个参数)。
为了帮助网络更好地泛化,而不需要过多修改现有模型,这里有一些想法:
使用
AdamW
而不是Adam
,并将其正则化weight_decay
参数设置为较大的值。这将有效地减少模型可以轻松利用的参数数量。
在每个阶段添加 dropout 层。从仅一个开始,并在添加更多 dropout 层时监视变化。
减小变压器层的尺寸。还可以尝试减小嵌入层的嵌入大小或模型大小。
将提前停止与上述方法结合使用可能也会有所帮助。我会从上述几点开始,否则模型可能会立即过度拟合。
它还可能有助于使用
sklearn
或神经网络将数据预处理为更少/更小的特征。
一次尝试一件事并观察其对验证集指标的影响。随着模型能够准确识别阳性案例(召回),召回率和精确度应该会提高。训练分数会同时下降,这些趋势意味着模型的泛化能力更好。