因此,我正在使用tensorflow 1.10,并在视网膜病变数据集的子集上进行训练。问题在于它总是预测出现次数最多的类。在我的情况下,它是0类。因此,我做了一些挖掘,发现了一种称为欠采样的东西。我忽略了所有0(只是为了看看会发生什么),它仅预测0之后的2类。显然2类具有最高的频率。 这是优化代码:
def data_pipe_line(data,checkpoint_path,i_data=None,epoch=5):
place_X=tf.placeholder(tf.float32,[None,500,400,3],name='p1')
place_Y=tf.placeholder(tf.int32,[None],name='p2')
infer_data=tf.data.Dataset.from_tensor_slices((place_X,place_Y))
infer_data=infer_data.batch(100)
iterator=tf.data.Iterator.from_structure(data.output_types,data.output_shapes)
next_image,next_label=iterator.get_next()
Y=tf.one_hot(next_label,5)
Y=tf.cast(Y,tf.float32)
logits=model(next_image,0.7)
print(logits)
print(Y)
train_iterator=iterator.make_initializer(data,name='train_op')
inference_iterator_op=iterator.make_initializer(infer_data,name='inference_op')
with tf.name_scope("loss"):
loss=tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits_v2(labels=Y,logits=logits),name='cost')
#the learning rate is so low because the batch-size is very small and has a lot of noise
optimizer=tf.train.AdamOptimizer(learning_rate=0.0005).minimize(loss)
#getting the accuracy
prediction=tf.argmax(logits,1,name='pred')
equality=tf.equal(prediction,tf.argmax(Y,1))
accuracy=tf.reduce_mean(tf.cast(equality,tf.float32))
init_op=tf.global_variables_initializer()
tf.summary.scalar("loss",loss)
tf.summary.scalar("accuracy",accuracy)
merged=tf.summary.merge_all()
saver=tf.train.Saver()
j=0
with tf.Session() as sess:
writer=tf.summary.FileWriter("./nn_logs",sess.graph)
sess.run(init_op)
for _ in range(epoch):
sess.run(train_iterator)
while True:
try:
#print(sess.run(logits))
j=j+1
summary = sess.run(merged)
_,acc,l=sess.run([optimizer,accuracy,loss])
if(j%20==0 or j==1):
print("iters: {}, loss: {:.10f}, training accuracy: {:.2f}".format(j, l, acc*100))
writer.add_summary(summary,j)
except tf.errors.OutOfRangeError:
break
saver.save(sess,checkpoint_path)
模型训练得很好,损失下降了一段时间,然后在那儿波动(在5的范围内)。课程的准确性波动很大,因为它只能预测1级。
答案 0 :(得分:1)
根据您所说的,我可以得出结论,您的数据集是高度不平衡的,那么您训练的模型根本就不能概括您的数据。然后,该模型会使用最多的样本来预测类别,因为随机猜测更有可能将其作为正确的标签。为了解决这个问题,一种方法是平衡您的数据。
一种方法是使用已经发现的采样技术。在训练集中,您要验证具有较少样本的班级,然后将每个班级相同数量的样本转到训练阶段。选择是随机进行的。测试集保持不变。
在这里,您采取相反的方式:选择具有更多样本的类,并使所有其他类具有相同数量的样本。最简单的方法是随机重复样本。另一种方法是扩充您的数据。
您还可以加权损失功能。为此,安德森(G. Anderson)已经将一个不错的question链接了。
当类不平衡时,该模型可以理解,如果它为带有较少样本的类获得了错误的标签,则将因该错误而受到不利的惩罚。一旦他们拥有该类别的样本较少,该错误的发生频率就会降低,并且当错误发生时,它将产生与样本较多的一个类别的错误相同的影响。因此,加权损失的作用是使样本较少的类别中的错误更为重要,而样本较多的类别中的错误较不重要。
在评论中回答问题
请记住:损失函数用于校正学习的模型权重,并且,当您在模型中添加另一个密集层时,您所做的更改将影响学习步骤。因此,您的模型仍然会为每个班级的错误分配相同的重要性级别。