Keras训练和验证指标值在使用相同数据时不同(逻辑回归)

我一直在尝试更好地理解keras模型fit()循环中的训练/验证序列。因此,我尝试了一个简单的训练循环,试图拟合一个简单的逻辑回归模型,输入数据仅包含一个特征。

我为训练验证都提供了相同的数据。在这些条件下,并且通过指定批次大小与总数据大小相同,人们期望得到完全相同的损失和准确率。但事实并非如此。

这是我的代码:

生成一些两类随机数据:

N = 100x = np.concatenate([np.random.randn(N//2, 1), np.random.randn(N//2, 1)+2])y = np.concatenate([np.zeros(N//2), np.ones(N//2)])

并绘制两个类的数据分布(一个特征x):

data = pd.DataFrame({'x': x.ravel(), 'y': y})sns.violinplot(x='x', y='y', inner='point', data=data, orient='h')pyplot.tight_layout(0)pyplot.show()

enter image description here

构建并拟合keras模型:

model = tf.keras.Sequential([tf.keras.layers.Dense(1, activation='sigmoid', input_dim=1)])model.compile(optimizer=tf.keras.optimizers.SGD(2), loss='binary_crossentropy', metrics=['accuracy'])model.fit(x, y, epochs=10, validation_data=(x, y), batch_size=N)

请注意,我为训练和validation_data都指定了数据x和目标y。此外,批次大小与总大小相同batch_size=N

训练结果如下:

100/100 [==============================] - 1s 5ms/step - loss: 1.4500 - acc: 0.2300 - val_loss: 0.5439 - val_acc: 0.7200Epoch 2/10100/100 [==============================] - 0s 18us/step - loss: 0.5439 - acc: 0.7200 - val_loss: 0.4408 - val_acc: 0.8000Epoch 3/10100/100 [==============================] - 0s 16us/step - loss: 0.4408 - acc: 0.8000 - val_loss: 0.3922 - val_acc: 0.8300Epoch 4/10100/100 [==============================] - 0s 16us/step - loss: 0.3922 - acc: 0.8300 - val_loss: 0.3659 - val_acc: 0.8400Epoch 5/10100/100 [==============================] - 0s 17us/step - loss: 0.3659 - acc: 0.8400 - val_loss: 0.3483 - val_acc: 0.8500Epoch 6/10100/100 [==============================] - 0s 16us/step - loss: 0.3483 - acc: 0.8500 - val_loss: 0.3356 - val_acc: 0.8600Epoch 7/10100/100 [==============================] - 0s 17us/step - loss: 0.3356 - acc: 0.8600 - val_loss: 0.3260 - val_acc: 0.8600Epoch 8/10100/100 [==============================] - 0s 18us/step - loss: 0.3260 - acc: 0.8600 - val_loss: 0.3186 - val_acc: 0.8600Epoch 9/10100/100 [==============================] - 0s 18us/step - loss: 0.3186 - acc: 0.8600 - val_loss: 0.3127 - val_acc: 0.8700Epoch 10/10100/100 [==============================] - 0s 23us/step - loss: 0.3127 - acc: 0.8700 - val_loss: 0.3079 - val_acc: 0.8800

结果显示,每个epoch结束时的val_lossloss不同,accval_acc也不完全相同。然而,基于这种设置,人们期望它们是相同的。

我一直在查看keras的代码,特别是这部分:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/keras/engine/training.py#L1364

到目前为止,我只能说差异是由于计算图中的某些不同计算引起的。

有没有人知道为什么会有这样的差异?


回答:

因此,在更仔细地查看结果后,训练步骤中的lossacc值是在当前批次用于更新模型之前计算的。

因此,在每个epoch只有一个批次的情况下,训练的accloss是在批次输入时评估的,然后根据提供的优化器更新模型参数。在训练步骤完成后,我们通过输入验证数据来计算损失和准确率,这些数据现在使用的是更新后的新模型来评估。

从训练结果输出中可以明显看出,第1个epoch的验证准确率和损失等于第2个epoch的训练准确率和损失,等等…

使用tensorflow进行的快速检查确认了在变量更新之前获取了值:

输出:

MSE: 14.721437454223633, W: 0.0, b: 0.0MSE: 13.372591018676758, W: 0.08826743811368942, b: 0.1636980175971985

由于参数Wb被初始化为0,因此很明显,即使会话已经运行了梯度更新请求,获取的值仍然是0…

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中创建了一个多类分类项目。该项目可以对…

发表回复

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