损失保持不变
我只是在机器学习的职业生涯的开始,并想创建简单的CNN来分类2种不同类型的树叶(属于2种不同树种)。 在收集大量的树叶图片之前,我决定在Tensorflow中创建非常小巧,简单的CNN,并仅在一幅图像上进行训练,以检查代码是否正常。 我将尺寸为256x256(x3通道)的照片标准化为<0,1>,并创建了4层(2个conv和2个稠密)网络。 不幸的是,从一开始,损失几乎总是趋向于一些常数值(通常是一些整数)。 我认为图片有些问题,所以我用相同尺寸的随机数组替换它。 不幸的是,损失仍然不变。 有时网络似乎在学习,因为损失在减少,但大多数时候从一开始就是不变的。 任何人都可以帮助解释,为什么这样呢? 我读过一个例子的培训是检查你的代码是否缺乏错误的最好方法,但是我与它斗争的时间越长,我越是看不到。
这里是我的代码(基于这个TensorFlow教程1)。 我使用了指数线性单位,因为我认为我的问题是由初始化不良的ReLU中0梯度引起的。
import matplotlib.pyplot as plt
import numpy as np
from numpy import random
from sklearn import utils
import tensorflow as tf
#original dataset of 6 leaves
# input = [ndimage.imread("E:leavesdab1.jpg"),
# ndimage.imread("E:leavesdab2.jpg"),
# ndimage.imread("E:leavesdab3.jpg"),
# ndimage.imread("E:leavesklon1.jpg"),
# ndimage.imread("E:leavesklon2.jpg"),
# ndimage.imread("E:leavesklon3.jpg")]
#normalize each image (originally uint8)
#input=[input/255 for i in range(len(input))
#temporary testing dataset, mimicking 6 images, each 3-channel, of dimension 256x256
input=[random.randn(256,256,3)]
# random.randn(256, 256, 3),
# random.randn(256, 256, 3),
# random.randn(256, 256, 3),
# random.randn(256, 256, 3),
# random.randn(256, 256, 3)]
#each image belong to one of two classes
labels=[[1]]#,[1,0],[1,0],[0,1],[0,1],[0,1]]
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.truncated_normal(shape, stddev=.1)
return tf.Variable(initial)
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
x = tf.placeholder(tf.float32, shape=[None, 256,256,3])
y_ = tf.placeholder(tf.float32, shape=[None, 1])
x_image = tf.reshape(x, [-1,256,256,3])
#first conv layer
W_conv1 = weight_variable([5,5, 3,8])
b_conv1 = bias_variable([8])
h_conv1 = tf.nn.elu(conv2d(x_image, W_conv1) + b_conv1)
#second conv layer
W_conv2 = weight_variable([5,5, 8,16])
b_conv2 = bias_variable([16])
h_conv2 = tf.nn.elu(conv2d(h_conv1, W_conv2) + b_conv2)
#first dense layer
W_fc1 = weight_variable([256*256*16, 10])
b_fc1 = bias_variable([10])
out_flat = tf.reshape(h_conv2, [-1, 256*256*16])
h_fc1 = tf.nn.elu(tf.matmul(out_flat, W_fc1) + b_fc1)
#second dense layer
W_fc2 = weight_variable([10, 1])
b_fc2 = bias_variable([1])
h_fc2 = tf.nn.elu(tf.matmul(h_fc1, W_fc2) + b_fc2)
#tried also with softmax with logits
cross_entropy=tf.losses.mean_squared_error(predictions=h_fc2, labels=y_)
train_step = tf.train.AdamOptimizer(1e-3).minimize(cross_entropy)
print("h2", h_fc2.shape)
print("y", y_.shape)
sess=tf.Session()
sess.run(tf.global_variables_initializer())
loss = []
for i in range(10):
sess.run(train_step, feed_dict={x:input, y_:labels})
input, labels = utils.shuffle(input, labels)
loss.append(sess.run(cross_entropy, feed_dict={x:input, y_:labels}))
print(i, " LOSS: ", loss[-1])
np.set_printoptions(precision=3, suppress=True)
for i in range(len(input)):
print(labels[i], sess.run(h_fc2, feed_dict={x:[input[i]], y_:[labels[i]]}))
plt.plot(loss)
plt.show()
这里列出了我所尝试的:
有没有人有任何想法,为什么会发生这种情况? 据我所知,如果网络不能一概而论,损失不会减少,反而会增加/波动,但不会保持不变?
我找到了答案。 问题是由该行引起的:
h_fc2 = tf.nn.elu(tf.matmul(h_fc1, W_fc2) + b_fc2)
我不知道为什么,但它使输出等于-1。 当我改变它
h_fc2 = f.matmul(h_fc1, W_fc2) + b_fc2
它像一个魅力一样工作,损失开始减少。 任何人都可以解释,为什么我们应该避免在最后一层使用激活函数(我在上述TensorFlow教程中看到了同样的问题)? 我不明白,我认为每一层都应该有自己的激活功能?
我看到的一些问题:
您使用平方损失,而不是交叉熵,用于分类使用tf.nn.sigmoid_cross_entropy_with_logits(...)
,而不是tf.losses.mean_squared_error
在这个代码中:
#normalize each image (originally uint8)
#input=[input/255 for i in range(len(input))
如果您的输入是uint8,那么您的数据可能会被舍入为0,而您只是发送空白图像,这会在您遇到时收敛到一个损失。
您的第一个调试步骤应该是将图像保存在 sess.run
之前的行中 。 保存您发送到网络的确切图像以进行验证。 不要让它变得复杂,只需使用scipy将图像保存到文件并进行完整性检查。
另外,你在这里有对TF的多余呼叫:
sess.run(train_step, feed_dict={x:input, y_:labels})
input, labels = utils.shuffle(input, labels)
loss.append(sess.run(cross_entropy, feed_dict={x:input, y_:labels}))
将其替换为:
result_train_step, result_cross_entropy = sess.run([train_step, cross_entropy], feed_dict={x:input, y_:labels})
关于学习率的注意事项,从1e-4开始是一个好的起点。
此外,请仔细检查您的标签是否与您的图像正确匹配,并在转储图像和完整性检查时将标签保存到文件中。 排列标签很容易。
我也很难用自己的工作来解决这个问题。 减少学习率帮助我摆脱不断的损失。
对于你的问题,我会建议接近5e-5的东西。 希望问题能够解决
链接地址: http://www.djcxy.com/p/32053.html