目前,我有一个CNN模型,通过独热编码的y_train
向量来预测类别,类似于这样:
[ 0., 0., 0., 0., 0., 1.0, 0., 0., 0., 0., 0. ]
因此,np.argmax(y_train)
会返回5,因为这是正确的类别。
不幸的是,我的训练数据太少,网络无法正确分类测试数据。随着时间的推移,训练误差有所改善,但我认为这是过拟合。测试误差始终非常糟糕。
我认为使用正态分布会使网络的训练更容易,因此,与其说类别5是唯一正确的类别,而其他所有类别都是同样错误的,我希望如果网络预测类别0而不是5时,给予较高的惩罚,而如果预测类别4而不是5时,只给出较小的惩罚。我认为对于编码类别5的y_train
向量可以这样表示:
# 为了在一行中显示,数值已四舍五入,原始向量始终是完整的tf.float32[ 0., 0.,0.004, 0.054, 0.242, 0.399, 0.242, 0.054, 0.004, 0., 0., ]
问题是,计算成本的哪种方法是合适的?
是否这样做:
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(y_net, y_train)train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
即使y_train
向量不再是独热编码,仍然能产生合理的结果吗?
或者这是否需要更强的架构更改?目前我有两个卷积/池化层和两个全连接层。输出只是y_net = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
,因为tf.nn.softmax_cross_entropy_with_logits
会应用softmax。
我的实际架构输出的是800维的输出向量,因此由于目前训练数据非常少,网络几乎从未能在测试数据中正确预测800个类别中的任何一个,仅在训练数据中(过拟合)能做到这一点。
然而,如果网络能预测一个范围内的类别,如正负20,我完全可以接受。所以如果正确类别是400,预测380到420之间的类别对我来说就足够了。
回答:
根据文档,softmax_cross_entropy_with_logits
应该支持你的用例。
由于你对预测范围在正负20内而不是精确的标签感到满意,那么可能更适合使用其他损失函数。例如,目标值(例如400)与你的预测(例如420)之间的均方误差(MSE)?这部分听起来更像是研究问题,而非与TensorFlow直接相关的问题。