CNN为所有输入

时间:2018-04-29 17:50:16

标签: python python-3.x tensorflow

我试图教CNN对以下数据集中的图像进行分类:kaggle.com/nih-chest-xrays/data

我决定从GoogLeNet model开始,但是我已经使用sigmoid函数用一个14维输出替换了完全连接的层(类不是互斥的)。我在学习模型时遇到了一些问题,似乎是在尝试最小化损失的情况下,它会在一段时间内学习数据的平均值,它会输出相同的输出{ {1}}用于所有输入图像。

我已经搜索了一下,包括当前特色的问题,但似乎无法在其他地方找到解决方案,因为我的数据集相当大(112k图像)并且我已尝试过典型的我在其他问题中看到的建议。

我试过了:

  • 将优化器从Adam更改为Adagrad
  • here in 3.1
  • 所述,将未加权的交叉熵损失改为加权损失
  • 更小的2层网络(NaiveCNN.py链接)
  • 改变该地区的学习率0.1-0.00001
  • 验证我的输入管道实际上是向CNN发送不同的图像,而不仅仅是整批同一图像。
  • 使用显式权重初始值设定项而不是张量流量值默认值。 (使用tflearn默认值e.g. [0,0,0,1,0,0,1,0,0,0,0,0,0,0]
  • 使用张量流内置tf.truncated_normal_initializer(stddev=0.001)而非明确定义的交叉熵。
  • 我的预测和标签都是形状[64,14]和tf.sigmoid_cross_entropy_with_logits按预期引发错误tf.transpose所以我不认为它是

我使用tensorflow 1.4.0,typical TensorBoard output from 30 epochs of training

在GTX1080ti上使用64的批量大小

我使用的所有代码都是here: https://gist.github.com/Kaapp/abdb54b232eb7f07b87955d9a18df57d

我开始认为它可能只是我代码中某个地方的一个简单错误,但是我已经看了很长时间我无法发现它或者我已经#39我只是误解了一些事情。对于令人困惑的代码,我添加了一些_x,_y等变量,只是为了帮助调试网络输出的确切内容。

Small dataset (1000 images) example from my comment

编辑/更新:我发现在我的模型中删除丢失层使得这完全一致,模型输出从0.5开始,并且每个批次一起移动,同时预测整个批次的相同输出。

1 个答案:

答案 0 :(得分:0)

使用预训练模型解决了我的问题。由于张量流保护工作方式的微妙,我无法初始加载预训练模型。

为了解决这个问题,我需要在我的图形构建实际完成后重新初始化Saver,以便它知道整个图形,然后手动初始化额外的变量,然后最终恢复检查点,如下所示:< / p>

vars_to_init = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, "the_added_layer's_scope")
for var in vars_to_init:
    sess.run(var.initializer)
saver = tf.train.Saver()
saver.restore(sess, my_checkpoint_file_path)

一旦我这样做了,我可以通过将变量传递给最小化函数来训练最后一层来微调现有的模型检查点:

trainable_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, "my_trainable_variables_scope")
self.train_step = tf.train.AdamOptimizer(
                        learning_rate=self.lr, 
                        beta1=0.9,
                        beta2=0.999).minimize(self.loss,var_list=trainable_vars)

似乎我的数据集可能不足以从头开始正确地训练网络,但是对最终层进行微调非常有效。

希望如果你像我一样陷入困境,这可能会帮助别人。