我正在尝试使用 TensorFlow 中的简单全连接神经网络开发验证码求解器。所有验证码都有 5 个数字/字母,每个字符可以是数字 0-9 或字母 AZ。它们看起来都是这样的:
每个验证码都有一个这样的标签,例如:“AB4D1”。我取这些标签,将它们拆分 ['A', 'B', '4', 'D', '1'],将每个字符转换为 0 到 35 之间的数字(26 个字母和 10 个数字)并转换每一个都指向一个热表示 [0, 0, 0, 1, 0,..]。然后,我将验证码中所有字母的 one-hot 数组连接起来,因此我最终为每个图像提供了一个 5*36 长度的数组。(该数组有 5 个 1,其余为 0)
现在我想知道使用什么损失函数。我尝试了均方误差,但由于某种原因根本不起作用。现在我正在尝试使用交叉熵(首先使用softmax),但据我了解,我需要将它分别应用于每个字母,然后将每个字母的损失相加,因为softmax需要专有类别。
我尝试拆分模型输出和标签:
split_logits = tf.split(logits, num_or_size_splits=5, axis=1)
split_train_labels = tf.split(tf_train_labels, num_or_size_splits=5, axis=1)
这很有效。现在我只是将每个字母的交叉熵损失加在一起。
loss =
tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits_v2(labels=split_train_labels[0], logits=split_logits[0])) +
tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits_v2(labels=split_train_labels[1], logits=split_logits[1])) +
tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits_v2(labels=split_train_labels[2], logits=split_logits[2])) +
tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits_v2(labels=split_train_labels[3], logits=split_logits[3])) +
tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits_v2(labels=split_train_labels[4], logits=split_logits[4]))
但这是我有问题的地方。只要我在那里只有第一个(0th)数字/字母的行,它就可以很好地工作(但显然只学会识别第一个字母)。一旦我为另一个字母添加术语,或者只添加一个其他字母而不是第一个字母,网络在训练开始后立即停滞不前,并且永远不会提高到高于随机的性能。
我不知道如何解决这个问题。我认为问题出在我的损失函数或网络结构中。
问题是除了第一个之外的所有字母由于不同的字体大小/宽度而在它们的位置上变化很大吗?我知道卷积网络会更好,但我真的很想先用全连接网络试试。




