Tensorflow二元分类培训损失赢得';t降低,精度保持在50%左右

Tensorflow二元分类培训损失赢得';t降低,精度保持在50%左右,tensorflow,machine-learning,keras,Tensorflow,Machine Learning,Keras,我对这一点还不太熟悉,我可以从这里得到一些建议 我正在使用tensorflow 2.3.0和keras构建一个二元分类模型。我无法共享数据集,因为它是我的公司拥有的专有数据,但所有功能都是数字财务数据,代表客户的直方图 我试过两个模型,一个有300个功能,一个有600个,一个有600个,只是代表了一个较长的历史。首先规范化这些功能,标签都是0或1,以指示是否应标记该帐户 我有500000个培训样本和60000个测试样本。0/1标签拆分大约为一半 这是我目前拥有的代码: import pandas

我对这一点还不太熟悉,我可以从这里得到一些建议

我正在使用tensorflow 2.3.0和keras构建一个二元分类模型。我无法共享数据集,因为它是我的公司拥有的专有数据,但所有功能都是数字财务数据,代表客户的直方图

我试过两个模型,一个有300个功能,一个有600个,一个有600个,只是代表了一个较长的历史。首先规范化这些功能,标签都是0或1,以指示是否应标记该帐户

我有500000个培训样本和60000个测试样本。0/1标签拆分大约为一半

这是我目前拥有的代码:

import pandas as pd
import numpy as np

# Make numpy values easier to read.
np.set_printoptions(precision=3, suppress=True)

import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras import utils

features = pd.read_csv('train.csv')
labels = np.array(features.pop('target'))
features = np.array(features)
num_features = features.shape[1]
features = utils.normalize(features)


model = tf.keras.Sequential([
    layers.Dense(512, activation='relu', input_shape=(num_features,)),
    layers.Dropout(0.5),
    layers.Dense(512, activation='relu'),
    layers.Dropout(0.5),
    layers.Dense(512, activation='relu'),
    layers.Dropout(0.5),
    layers.Dense(1, activation='sigmoid')
])

model.compile(loss = tf.losses.BinaryCrossentropy(), optimizer = tf.optimizers.Adam(learning_rate=0.001), metrics=['accuracy'])

model.fit(features, labels, epochs=100)
这可能是错误的拓扑,这只是我最近的一次尝试。我尝试过几种不同的拓扑结构——从带有少量单元的小型单层网络到您在这里看到的。我尝试过不同的学习速度和学习时期,有没有辍学。它们都给出了基本相同的模式:

Epoch 1/100
15625/15625 [==============================] - 46s 3ms/step - loss: 0.6932 - accuracy: 0.5113
Epoch 2/100
15625/15625 [==============================] - 46s 3ms/step - loss: 0.6929 - accuracy: 0.5127
Epoch 3/100
15625/15625 [==============================] - 46s 3ms/step - loss: 0.6929 - accuracy: 0.5135
Epoch 4/100
15625/15625 [==============================] - 47s 3ms/step - loss: 0.6928 - accuracy: 0.5142
Epoch 5/100
15625/15625 [==============================] - 48s 3ms/step - loss: 0.6928 - accuracy: 0.5138
这里的损耗基本上是平的,精度徘徊在这一点上。如果我使用一个非常高的学习率,损失开始很高,但最终在同一点附近趋于平缓

为了测试模型是否正常工作,我尝试了一个非常小的数据子集(只有5行左右),它可以快速地将损失降低到接近零的水平,并具有100%的准确度,这当然是非常过分的,但只是为了测试代码/数据

我可以采取哪些后续步骤来改进这一点?这看起来可能只是设计糟糕的功能,神经网络无法找出如何关联,或者这可能不是正确的算法选择

编辑:

根据评论和回复(谢谢!),我尝试了更多的调整,并且取得了一些进展。我已经调整了批量大小,调整了拓扑结构,降低了学习率。我也不太明白验证数据是如何融入到图中的,所以我现在正在运行一个培训课程,使用
validation\u split=0.2
——我的新问题是,现在我的培训损失在减少/准确度在增加,但验证损失/准确度的情况正好相反。以下是一些epoch快照:

Epoch 1/1000
1563/1563 [==============================] - 25s 16ms/step - loss: 0.6926 - accuracy: 0.5150 - val_loss: 0.6927 - val_accuracy: 0.5134

Epoch 20/1000
1563/1563 [==============================] - 24s 15ms/step - loss: 0.6746 - accuracy: 0.5760 - val_loss: 0.7070 - val_accuracy: 0.5103

Epoch 50/1000
1563/1563 [==============================] - 24s 15ms/step - loss: 0.5684 - accuracy: 0.7015 - val_loss: 0.8222 - val_accuracy: 0.5043

我假设这是过度拟合?

我会将密集层单位更改为512128,64,1。删除除最后一层之外的所有退出层。将最后一个的退学率设置为。3。使用测试样本作为验证数据,以便查看模型是否过拟合/欠拟合。还建议您尝试使用keras回调ReducelRonplation进行可调学习,并尽早停止使用keras回调Earlystoping。文档位于[此处][1]设置每个回调以监视验证丢失。我建议的代码如下所示:

reduce_lr=tf.keras.callbacks.ReduceLROnPlateau(
          monitor="val_loss",factor=0.5, patience=2, verbose=1)
e_stop=tf.keras.callbacks.EarlyStopping( monitor="val_loss", patience=5, 
          verbose=0,  restore_best_weights=True)
callbacks=[reduce_lr, e_stop]
在model.fit中包括

callbacks=callbacks

试试标准的亚当学习率1e-5,这是一个很大的辍学率!我的建议是完全删除它,看看它的性能如何,然后逐渐添加您需要的内容。请记住,辍学主要是为了正规化,所以如果你陷入了随机猜测的状态,我会从放松监管开始。我已经将你的建议和一些评论结合起来,我正在取得进展,但我确实认为我现在有一个过度适应的问题。查看我的编辑。是的,这是经典的过度拟合。您是否在模型中留下了一个退出层?如果是的话,提高利率。如果这不能解决问题,请添加一个附加的退出层。如果这不起作用,减少密集单元的数量。看到我修改过的答案了吗?我确实留下了辍学者,我会尝试更多的尝试,调整单位和回调。将报告结果,谢谢你的建议。我想你已经把我引向了正确的方向,所以我会把这个作为答案。干杯