我有一个深度CNN,可以为3d图像中的每个像素预测“0”和“2”之间的标签。我已经在一个图像上训练了模型,其中每个像素都标记为“1”。因此,在测试模型时,我相信每个预测应该是“1”。相反,该模型仅预测“0”。
以下是整个模型的存储库:https://github.com/dhasl002/Research-DeepLearning。
由于代码差不多是300行,我将只包含下面的相关代码。
x = tf.placeholder(tf.float32, shape=[None, 7168])
y_ = tf.placeholder(tf.float32, shape=[None, 7168, 3])
W_final = weight_variable([7168,7168,3])
b_final = bias_variable([7168,3])
#"final" is the result of the many convolutions
final_conv = tf.tensordot(final, W_final, axes=[[1], [1]]) + b_final
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=final_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(final_conv, 2), tf.argmax(y_, 2))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
#a is a threshold associate with each pixel, b is the label of each pixel
a = np.zeros((1,7168),dtype = float)
b = np.zeros((1,7168, 3), dtype = float)
#this is a little simplified for clarity of reader
#TRAINING
for line in inputFile:
thresh, label = line.strip().split(",")
a[0][it] = thresh
b[0][it][label] = 1
train_step.run(feed_dict={x: a, y_: b, keep_prob: .5})
#TESTING
for line in inputFile:
thresh, label = line.strip().split(",")
a[0][it] = thresh
b[0][it][label] = 1
temp = sess.run(tf.argmax(final_conv,2), feed_dict={x: a})
我相信最后一行的“temp”应该保持正确的预测(7168个标签 - 每个像素一个)。 为什么“temp”在仅使用“1”标签对图像进行实际训练时始终会生成所有“0”标签?
答案 0 :(得分:2)
您提供的数据不仅包含1
个标签,还包含偶然的2
(您可以浏览文本文件或只打印label
值看到这个)。它不仅违背了你训练常数函数的想法,它还打破了单热编码,从而打破了整个算法。
以下是您脚本的摘录:
a = np.zeros((1,N*M*P),dtype = float)
b = np.zeros((1,N*M*P, 3), dtype = float)
[...]
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
parent = "..."
with open(parent) as inf1:
next(inf1)
for line5 in inf1:
line1, maxNum = line5.strip().split(",")
path = "..."
num = 0
while num < maxNum:
it = 0
with open(path + str(num) + ".txt") as inf:
next(inf)
num = num + 1
for line in inf:
[...]
a[0][it] = thresh
b[0][it][label] = 1
it = it + 1
查看您的代码,b
应该是一个单热的向量。但请注意,只有在定义变量时,它才会归零。之后,它被分配到不同索引的1
。 while
循环的后续迭代更新了相同的b
数组,因此最终在批处理的后续行中包含多个1
。 cross-entropy loss期望有效的概率分布,因此对于您的数据,其输出变得毫无意义:
每行
labels[i]
必须是有效的概率分布。
摘要:您进行数据处理的方式过于复杂,因此容易出错。尝试更简单地组织输入文件,以便可以将其读入numpy数组(或pandas数据帧)并提供给会话。
答案 1 :(得分:1)
由于你正在使用ReLUs,一种可能性是你正在遭受垂死的ReLU问题;你可以通过切换到漏水的ReLUs来解决这个问题。
除此之外,你的模型非常深刻和复杂;为了确保它正常工作,您可能希望将其大幅缩放,测试它是否能给出合理的结果,然后分阶段添加。
无论如何,看起来你的模型对于这个问题来说太复杂了。为每个像素生成标签的模型应该非常简单,因为给定像素的标签可能仅取决于附近的像素,并且可能不是非常复杂的方式。