Tensorflow二元分类训练损失不下降,准确率卡在50%左右

我在这方面还是新手,需要一些建议来指导我下一步该怎么做。

我使用tensorflow 2.3.0和keras来构建一个二元分类模型。由于数据是公司所有的专有数据,我无法共享数据集,但这些特征都是数值型的金融数据,代表客户的一种直方图。

我尝试了两种模型,一种有300个特征,另一种有600个特征,后者代表更长的历史。特征首先被归一化,标签都是0或1,用来指示账户是否应该被标记。

我有50万个训练样本和6万个测试样本。0/1标签的比例大约是一半对一半。

这是我目前的代码:

import pandas as pdimport numpy as np# Make numpy values easier to read.np.set_printoptions(precision=3, suppress=True)import tensorflow as tffrom tensorflow.keras import layersfrom tensorflow.keras import utilsfeatures = 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)

这可能不是正确的拓扑结构,这只是我最近一次尝试。我尝试了几种不同的拓扑结构——从只有少量单元的小型单层网络到你在这里看到的。我尝试了不同的学习率和epochs,以及有无dropout。所有这些基本上都显示出相同的模式:

Epoch 1/10015625/15625 [==============================] - 46s 3ms/step - loss: 0.6932 - accuracy: 0.5113Epoch 2/10015625/15625 [==============================] - 46s 3ms/step - loss: 0.6929 - accuracy: 0.5127Epoch 3/10015625/15625 [==============================] - 46s 3ms/step - loss: 0.6929 - accuracy: 0.5135Epoch 4/10015625/15625 [==============================] - 47s 3ms/step - loss: 0.6928 - accuracy: 0.5142Epoch 5/10015625/15625 [==============================] - 48s 3ms/step - loss: 0.6928 - accuracy: 0.5138

损失在这里基本停止变化,准确率也在这个点附近徘徊。如果我使用非常高的学习率,损失开始时很高,但最终也在这个点附近停止变化。

为了测试模型是否有效,我尝试用数据的一个非常小的子集(只有大约5行),它很快将损失降低到接近零,准确率达到100%,当然这是大大过拟合的,但只是为了测试代码/数据。

我可以尝试哪些下一步来改进这个模型?这看起来像是特征设计得不好,神经网络无法找出如何进行相关性分析,还是说这可能不是选择的正确算法?

编辑:

根据评论和回复(谢谢!),我尝试了一些更多的调整,并且取得了一些进展。我调整了批量大小,调整了拓扑结构,并降低了学习率。我之前不太理解验证数据在其中的作用,所以我现在正在运行一个带有validation_split=0.2的训练会话——我的新问题是,现在我的训练损失在下降/准确率在上升,但验证损失/准确率却相反。这是训练过程中的一些epoch快照:

Epoch 1/10001563/1563 [==============================] - 25s 16ms/step - loss: 0.6926 - accuracy: 0.5150 - val_loss: 0.6927 - val_accuracy: 0.5134Epoch 20/10001563/1563 [==============================] - 24s 15ms/step - loss: 0.6746 - accuracy: 0.5760 - val_loss: 0.7070 - val_accuracy: 0.5103Epoch 50/10001563/1563 [==============================] - 24s 15ms/step - loss: 0.5684 - accuracy: 0.7015 - val_loss: 0.8222 - val_accuracy: 0.5043

我猜这是过拟合的表现吗?


回答:

我建议将密集层单位改为512,128,64,1。除了最后一层外,移除所有dropout层。将最后一层的dropout率设置为大约0.3。使用你的测试样本作为验证数据,这样你可以看到模型是否过拟合或欠拟合。我还建议你尝试使用keras回调ReduceLROnPlateau来调整学习率,以及使用keras回调EarlyStopping来提前停止。文档在这里。将每个回调设置为监控验证损失。我建议的代码如下所示:

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

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注