我试图用Keras复制Neural Networks and Deep Learning中的一些示例,但是在基于第1章的体系结构训练网络时遇到了一些问题。目的是从MNIST数据集中对书写数字进行分类。 体系结构:
超参数:
我的代码:
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
from keras.initializers import RandomNormal
# import data
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# input image dimensions
img_rows, img_cols = 28, 28
x_train = x_train.reshape(x_train.shape[0], img_rows * img_cols)
x_test = x_test.reshape(x_test.shape[0], img_rows * img_cols)
input_shape = (img_rows * img_cols,)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
num_classes = 10
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('y_train shape:', y_train.shape)
# Construct model
# 784 * 30 * 10
# Normal distribution for weights/biases
# Stochastic Gradient Descent optimizer
# Mean squared error loss (cost function)
model = Sequential()
layer1 = Dense(30,
input_shape=input_shape,
kernel_initializer=RandomNormal(stddev=1),
bias_initializer=RandomNormal(stddev=1))
model.add(layer1)
layer2 = Dense(10,
kernel_initializer=RandomNormal(stddev=1),
bias_initializer=RandomNormal(stddev=1))
model.add(layer2)
print('Layer 1 input shape: ', layer1.input_shape)
print('Layer 1 output shape: ', layer1.output_shape)
print('Layer 2 input shape: ', layer2.input_shape)
print('Layer 2 output shape: ', layer2.output_shape)
model.summary()
model.compile(optimizer=SGD(lr=3.0),
loss='mean_squared_error',
metrics=['accuracy'])
# Train
model.fit(x_train,
y_train,
batch_size=10,
epochs=30,
verbose=2)
# Run on test data and output results
result = model.evaluate(x_test,
y_test,
verbose=1)
print('Test loss: ', result[0])
print('Test accuracy: ', result[1])
输出(使用Python3.6和TensorFlow后端):
^{pr2}$(30个时代重复)
Epoch 30/30
- 6s - loss: nan - acc: 0.0987
10000/10000 [==============================] - 0s 22us/step
Test loss: nan
Test accuracy: 0.098
正如你所看到的,网络根本没有学习,我不知道为什么。据我所知,这些形状看起来还不错。我在做什么阻止网络学习?在
(顺便说一句,我知道交叉熵损失和softmax输出层会更好;但是,从链接的书来看,它们似乎没有必要。这本书在第一章中手动实现的网络学习成功;在继续学习之前,我试图复制这一点。)
在分类问题中选择MSE作为损失函数确实很奇怪,而且我不确定这项练习的介绍性质是否是一个好的理由,正如在连载书一章中所声称的那样。然而:
lr
,3.0,是巨大的;尝试一些至少0.1,甚至更低的东西。在activation='sigmoid'
(因为您明确希望避免{stddev=1
值也是巨大的;请尝试0.05(default value)范围内的值。另外,standard practice是将偏差初始化为零。在最好从Keras MNIST MLP example开始,并根据您的学习需求调整它(关于层的数量、激活函数等)。在
您需要指定每个层的激活。所以对于每一层。应该是这样的:
注意我在这里指定了激活参数。同样对于最后一层,您应该使用
activation="softmax"
,因为您有多个类别。在另一件要考虑的事情是分类(与回归相反)在熵损失的情况下效果最好。所以您可能需要将
model.compile
中的损失值更改为loss='categorical_crossentropy'
。但是,这是不必要的,而且您仍然可以使用mean_square_error
丢失来获得结果。在如果您仍然得到
nan
值,您可以尝试更改SGD
的学习率。在我使用您展示的脚本测试了
0.9425
,只将第一层的激活更改为sigmoid
,并将第二层的激活更改为softmax
。在相关问题 更多 >
编程相关推荐