我是深度学习的初学者,并参加了一些关于 Udacity 的课程。最近我正在尝试构建一个深度网络来检测输入深度图像中的手部关节,但似乎效果不佳。(我的数据集是ICVL Hand Posture Dataset)网络结构如图所示。
① 一批输入图片,240x320;
② 一个8通道的卷积层,内核为5x5;
③ 一个最大池化层,ksize = stride = 2;
④ 一个全连接层,weight.shape = [38400, 1024];
⑤ 一个全连接层,weight.shape = [1024, 48]。
经过几次训练后,最后一层的输出收敛为 (0, 0, ..., 0) 向量。我选择均方误差作为损失函数,它的值保持在 40000 以上并且似乎没有减少。
网络结构已经太简单了,无法再次简化,但问题仍然存在。任何人都可以提供任何建议吗?
我的主要代码发布如下:
image = tf.placeholder(tf.float32, [None, 240, 320, 1])
annotations = tf.placeholder(tf.float32, [None, 48])
W_convolution_layer1 = tf.Variable(tf.truncated_normal([5, 5, 1, 8], stddev=0.1))
b_convolution_layer1 = tf.Variable(tf.constant(0.1, shape=[8]))
h_convolution_layer1 = tf.nn.relu(
tf.nn.conv2d(image, W_convolution_layer1, [1, 1, 1, 1], 'SAME') + b_convolution_layer1)
h_pooling_layer1 = tf.nn.max_pool(h_convolution_layer1, [1, 2, 2, 1], [1, 2, 2, 1], 'SAME')
W_fully_connected_layer1 = tf.Variable(tf.truncated_normal([120 * 160 * 8, 1024], stddev=0.1))
b_fully_connected_layer1 = tf.Variable(tf.constant(0.1, shape=[1024]))
h_pooling_flat = tf.reshape(h_pooling_layer1, [-1, 120 * 160 * 8])
h_fully_connected_layer1 = tf.nn.relu(
tf.matmul(h_pooling_flat, W_fully_connected_layer1) + b_fully_connected_layer1)
W_fully_connected_layer2 = tf.Variable(tf.truncated_normal([1024, 48], stddev=0.1))
b_fully_connected_layer2 = tf.Variable(tf.constant(0.1, shape=[48]))
detection = tf.nn.relu(
tf.matmul(h_fully_connected_layer1, W_fully_connected_layer2) + b_fully_connected_layer2)
mean_squared_error = tf.reduce_sum(tf.losses.mean_squared_error(annotations, detection))
training = tf.train.AdamOptimizer(1e-4).minimize(mean_squared_error)
# This data loader reads images and annotations and convert them into batches of numbers.
loader = ICVLDataLoader('../data/')
with tf.Session() as session:
session.run(tf.global_variables_initializer())
for i in range(1000):
# batch_images: a list with shape = [BATCH_SIZE, 240, 320, 1]
# batch_annotations: a list with shape = [BATCH_SIZE, 48]
[batch_images, batch_annotations] = loader.get_batch(100).to_1d_list()
[x_, t_, l_, p_] = session.run([x_image, training, mean_squared_error, detection],
feed_dict={images: batch_images, annotations: batch_annotations})
它运行像这样。
主要问题可能relu
是输出层中的激活。您应该删除它,即让detection
简单地成为矩阵乘法的结果。如果您想强制输出为正数,请考虑使用指数函数之类的东西。
虽然relu
是一种流行的隐藏激活,但我发现将其用作输出激活的一个主要问题:众所周知,relu
将负输入映射为 0——然而,至关重要的是,梯度也将为 0。这发生在输出层基本上意味着当您的网络产生小于 0 的输出时(这很可能在随机初始化时发生),您的网络无法从错误中学习。这可能会严重影响整个学习过程。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句