我有一个小型研究项目,我尝试解码一些验证码图像。我使用Tensorflow 0.9中实现的convnet,基于MNIST示例(https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/convolutional_network.py)
我的代码可在github https://github.com/ksopyla/decapcha/blob/master/decaptcha_convnet.py
找到我尝试重现所描述的想法:
其中特定的字符序列被编码为一个二进制矢量。在我的例子中,验证码包含最多20个拉丁字符,每个字符编码为63个暗淡的二进制矢量,其中1位设置在位置,根据:
所以最后当我连接所有20个字符时,我得到20 * 63暗淡的向量,我的网络应该学习。我的主要问题是如何为优化器定义适当的损失函数。
我的网络架构:
所以我的主要问题是如何为优化器定义损失以及如何评估模型。我试过这样的事情
# Construct model
pred = conv_net(x, weights, biases, keep_prob)
# Define loss and optimizer
#split prediction for each char it takes 63 continous postions, we have 20 chars
split_pred = tf.split(1,20,pred)
split_y = tf.split(1,20,y)
#compute partial softmax cost, for each char
costs = list()
for i in range(20):
costs.append(tf.nn.softmax_cross_entropy_with_logits(split_pred[i],split_y[i]))
#reduce cost for each char
rcosts = list()
for i in range(20):
rcosts.append(tf.reduce_mean(costs[i]))
# global reduce
loss = tf.reduce_sum(rcosts)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
# Evaluate model
# pred are in format batch_size,20*63, reshape it in order to have each character prediction
# in row, then take argmax of each row (across columns) then check if it is equal
# original label max indexes
# then sum all good results and compute mean (accuracy)
#batch, rows, cols
p = tf.reshape(pred,[batch_size,20,63])
#max idx acros the rows
#max_idx_p=tf.argmax(p,2).eval()
max_idx_p=tf.argmax(p,2)
l = tf.reshape(y,[batch_size,20,63])
#max idx acros the rows
#max_idx_l=tf.argmax(l,2).eval()
max_idx_l=tf.argmax(l,2)
correct_pred = tf.equal(max_idx_p,max_idx_l)
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))enter code here
我尝试从输出中拆分每个char,并为每个char单独执行softmax和cross_entropy,然后合并所有成本。但我已将tensorflow函数与普通的python列表混合在一起,我可以这样做吗?请问tensorflow引擎能理解这个吗?我可以使用哪些tensorflow函数而不是python列表?
精度以类似的方式计算,输出重新整形为20x63,我从每一行获取argmax,而不是与真正的编码char进行比较。
当我运行此损失功能正在减少,但精度上升然后下降。 这张照片显示了它的外观https://plon.io/files/57a0a7fb4bb1210001ca0476
如果有任何进一步的评论,我所犯的错误或想法,我将不胜感激。
答案 0 :(得分:1)
真正的问题是我的网络卡住了,网络输出对于任何输入都是不变的。
当我将损失函数更改为#include "header1.h"
entry start_entry;
void func(void)
{
//here i use start_entry
}
void init(void)
{
start_entry.text = str_ptr;
start_entry.var = a;
}
并对输入进行标准化时,网络开始学习模式。
标准化(减去均值并除以标准)有很大帮助,
Xdata是矩阵[N,D]
loss = tf.nn.sigmoid_cross_entropy_with_logits(pred,y)
数据预处理是关键,值得阅读http://cs231n.github.io/neural-networks-2/#data-preprocessing