我正在用tf.keras编程一个神经网络,有3层。我的数据集是MNIST数据集。我减少了数据集中的示例数,因此运行时更低。这是我的密码:
import tensorflow as tf
from tensorflow.keras import layers
import numpy as np
import pandas as pd
!git clone https://github.com/DanorRon/data
%cd data
!ls
batch_size = 32
epochs = 10
alpha = 0.0001
lambda_ = 0
h1 = 50
train = pd.read_csv('/content/first-repository/mnist_train.csv.zip')
test = pd.read_csv('/content/first-repository/mnist_test.csv.zip')
train = train.loc['1':'5000', :]
test = test.loc['1':'2000', :]
train = train.sample(frac=1).reset_index(drop=True)
test = test.sample(frac=1).reset_index(drop=True)
x_train = train.loc[:, '1x1':'28x28']
y_train = train.loc[:, 'label']
x_test = test.loc[:, '1x1':'28x28']
y_test = test.loc[:, 'label']
x_train = x_train.values
y_train = y_train.values
x_test = x_test.values
y_test = y_test.values
nb_classes = 10
targets = y_train.reshape(-1)
y_train_onehot = np.eye(nb_classes)[targets]
nb_classes = 10
targets = y_test.reshape(-1)
y_test_onehot = np.eye(nb_classes)[targets]
model = tf.keras.Sequential()
model.add(layers.Dense(784, input_shape=(784,)))
model.add(layers.Dense(h1, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(lambda_)))
model.add(layers.Dense(10, activation='sigmoid', kernel_regularizer=tf.keras.regularizers.l2(lambda_)))
model.compile(optimizer=tf.train.GradientDescentOptimizer(alpha),
loss = 'categorical_crossentropy',
metrics = ['accuracy'])
model.fit(x_train, y_train_onehot, epochs=epochs, batch_size=batch_size)每当我运行它时,就会发生以下三件事中的一件:
大多数情况下,模型会做这些事情之一,但有时它会做一些随机的事情。似乎这种不稳定的行为是完全随机的。我不知道问题出在哪里。我该如何解决这个问题?
编辑:有时,损失减少,但准确性保持不变。此外,有时损失减少,精度提高,但经过一段时间,精度下降,而损失仍在下降。或者,损失减少,精度提高,然后开关和损失迅速上升,而精度直线下降,最终以损失结束: 2.3025 acc: 0.0986。
编辑2:这是有时会发生的事情的一个例子:
Epoch 1/100
49999/49999 [==============================] - 5s 92us/sample - loss: 1.8548 - acc: 0.2390
Epoch 2/100
49999/49999 [==============================] - 5s 104us/sample - loss: 0.6894 - acc: 0.8050
Epoch 3/100
49999/49999 [==============================] - 4s 90us/sample - loss: 0.4317 - acc: 0.8821
Epoch 4/100
49999/49999 [==============================] - 5s 104us/sample - loss: 2.2178 - acc: 0.1345
Epoch 5/100
49999/49999 [==============================] - 5s 90us/sample - loss: 2.3025 - acc: 0.0986
Epoch 6/100
49999/49999 [==============================] - 4s 90us/sample - loss: 2.3025 - acc: 0.0986
Epoch 7/100
49999/49999 [==============================] - 4s 89us/sample - loss: 2.3025 - acc: 0.0986编辑3:我把损失改为均方误差,现在网络运行良好。有没有办法使它保持在交叉熵中,而不使它收敛到局部最小值呢?
发布于 2019-03-31 23:02:51
我把损失改为均方误差,现在网络运行良好。
MSE是,而不是,对于这类分类问题,适当的损失函数;您当然应该坚持使用loss = 'categorical_crossentropy'。
最可能的原因是您的MNIST数据没有标准化;您应该将最终变量标准化为
x_train = x_train.values/255
x_test = x_test.values/255不规范输入数据是爆炸梯度问题的一个已知原因,这可能就是这里正在发生的情况。
其他建议:为您的第一个密集层设置activation='relu',并消除来自所有层的正则化和初始化参数(默认的glorot_uniform实际上是一个更好的初始化器,而这里的正则化实际上可能对性能有害)。
作为一个普遍的建议,尽量不要重新发明车轮-从一个Keras示例开始使用内置的MNIST数据.
发布于 2019-03-24 22:45:12
你对代码的随机输出的挫折感是可以理解和正确识别的。每次模型开始训练时,它都会随机初始化权重。根据这个初始化,您可以看到三个输出场景中的一个。
这个问题很可能是由于渐变消失造成的。这是一种现象,当反向传播导致非常小的权重被乘以一个小的数,从而产生一个几乎无限小的值。解决方案是将小抖动(1e-10)添加到每个梯度(从成本函数中),这样它们就永远不会达到零。
有大量关于在线渐变消失的更详细的博客,例如这个TensorFlow网络的第217行签出。
https://stackoverflow.com/questions/55328966
复制相似问题