我是深度学习的初学者,最近尝试实现 34 层残差神经网络。我用 CIFAR-10 图像训练了神经网络,但测试准确率没有预期的那么高,大约 65%,如下图所示。
基本上,我实现残差块的方式如下:
对于没有维数增加的残差块,如以下示例:
"""
Convolution Layers 1, Sub Unit 1
"""
conv_weights_1_2 = tf.Variable(tf.random_normal([3,3,64,64]),dtype=tf.float32)
conv_1_2 = tf.nn.conv2d(conv_1_1, conv_weights_1_2, strides=[1,1,1,1], padding="SAME")
axis = list(range(len(conv_1_2.get_shape()) - 1))
mean, variance = tf.nn.moments(conv_1_2, axis)
beta = tf.Variable(tf.zeros(conv_1_2.get_shape()[-1:]),dtype=tf.float32)
gamma = tf.Variable(tf.ones(conv_1_2.get_shape()[-1:]),dtype=tf.float32)
conv_1_2 = tf.nn.batch_normalization(conv_1_2, mean, variance, beta, gamma, 0.001)
conv_1_2 = tf.nn.relu(conv_1_2)
conv_weights_1_3 = tf.Variable(tf.random_normal([3,3,64,64]),dtype=tf.float32)
conv_1_3 = tf.nn.conv2d(conv_1_2, conv_weights_1_3, strides=[1,1,1,1], padding="SAME")
axis = list(range(len(conv_1_3.get_shape()) - 1))
mean, variance = tf.nn.moments(conv_1_3, axis)
beta = tf.Variable(tf.zeros(conv_1_3.get_shape()[-1:]),dtype=tf.float32)
gamma = tf.Variable(tf.ones(conv_1_3.get_shape()[-1:]),dtype=tf.float32)
conv_1_3 = tf.nn.batch_normalization(conv_1_3, mean, variance, beta, gamma, 0.001)
conv_1_3 = conv_1_3 + conv_1_1
conv_1_3 = tf.nn.relu(conv_1_3)
对于尺寸增加的块,如下所示:
"""
Convolution Layers 3 starts here.
Convolution Layers 3, Sub Unit 0
"""
conv_weights_3_0 = tf.Variable(tf.random_normal([3,3,128,256]),dtype=tf.float32)
conv_3_0 = tf.nn.conv2d(conv_2_out, conv_weights_3_0, strides=[1,2,2,1], padding="SAME")
axis = list(range(len(conv_3_0.get_shape()) - 1))
mean, variance = tf.nn.moments(conv_3_0, axis)
beta = tf.Variable(tf.zeros(conv_3_0.get_shape()[-1:]),dtype=tf.float32)
gamma = tf.Variable(tf.ones(conv_3_0.get_shape()[-1:]),dtype=tf.float32)
conv_3_0 = tf.nn.batch_normalization(conv_3_0, mean, variance, beta, gamma, 0.001)
conv_3_0 = tf.nn.relu(conv_3_0)
conv_weights_3_1 = tf.Variable(tf.random_normal([3,3,256,256]),dtype=tf.float32)
conv_3_1 = tf.nn.conv2d(conv_3_0, conv_weights_3_1, strides=[1,1,1,1], padding="SAME")
axis = list(range(len(conv_3_1.get_shape()) - 1))
mean, variance = tf.nn.moments(conv_3_1, axis)
beta = tf.Variable(tf.zeros(conv_3_1.get_shape()[-1:]),dtype=tf.float32)
gamma = tf.Variable(tf.ones(conv_3_1.get_shape()[-1:]),dtype=tf.float32)
conv_3_1 = tf.nn.batch_normalization(conv_3_1, mean, variance, beta, gamma, 0.001)
conv_weights_3_pre = tf.Variable(tf.ones([1,1,128,256]),dtype=tf.float32,trainable=False)
conv_3_pre = tf.nn.conv2d(conv_2_out, conv_weights_3_pre, strides=[1,2,2,1], padding="SAME")
axis = list(range(len(conv_3_pre.get_shape()) - 1))
mean, variance = tf.nn.moments(conv_3_pre, axis)
conv_3_pre = tf.nn.batch_normalization(conv_3_pre, mean, variance, None, None, 0.001)
conv_3_1 = conv_3_1 + conv_3_pre
conv_3_1 = tf.nn.relu(conv_3_1)
我使用学习率为 0.001 的 AdamOptimizer 对来自 CIFAR-10 的所有 50000 张训练图像进行了训练,并使用这 10000 张测试图像进行了测试。在图中,训练将近 1000 个 epoch,每个 epoch 有 500 个批次(每批次 100 张图像)。在每个 epoch 之前,我将所有 50000 张训练图像打乱。同样,在很长一段时间内,测试准确率几乎保持在 65% 左右。
完整的代码可以在https://github.com/freegyp/my-implementation-of-ResNet-in-Tensorflow找到。我的实施有什么问题吗?我期待着任何改进我的实施的建议。