TensorFlow新手实战破验证码(2)

来源:互联网 发布:excel筛选数据求和 编辑:程序博客网 时间:2024/05/17 23:17

上接TensorFlow新手实战破验证码(1)

第三步 搭建神经网络

我用了三层卷积,两层池化。
别问我为啥这么搭,没错,我就是瞎搭的,完全照搬官网教程,只是改了一下输入输出的接口。
1.首先改写一下之前的gene_code()函数
tensorflow接受ndarray类型数据,我们需要把PIL的Image类型转为numpy的ndarray,似乎没有直接转换的函数,需要自己写。
改写后的函数如下:

def gene_code():    width,height = size #宽和高    image = Image.new('1',(width,height),1) #创建图片    font = ImageFont.truetype(font_path+typet[random.randint(0, typen-1)],70) #验证码的字体    draw = ImageDraw.Draw(image)  #创建画笔    source = ['0','1','2','3','4','5','6','7','8','9']    text = random.randint(0, 9) #生成字符串    font_width, font_height = font.getsize(source[text])    draw.text(((width - font_width) /2, (height - font_height)/2-5),source[text],            font= font,fill=0) #填充字符串    rx=random.uniform(-0.2, 0.2)    ry=random.uniform(-0.2, 0.2)    image = image.transform((width+100,height+100), Image.AFFINE, (1,rx,0,ry,1,0),Image.BILINEAR)  #创建扭曲    px=random.randint(-20, 20)    py=random.randint(-6, 6)    image = image.crop((65-70*rx+py,40-70*ry+px,115-70*rx+py,140-70*ry+px))    draw = ImageDraw.Draw(image)    gene_line(draw)    gene_line(draw)    m=0    mtr=np.zeros(5000,np.int)    while m<50:           n=0        while n<100:                  mtr[m+n*50]=image.getpixel((m,n))            n=n+1        m=m+1    return text,mtr

2.然后还有写一个给网络提供训练集的函数
提供训练集时不可能一次只给一个,所以还要写一个函数提供给网络指定大小的训练集。

def get_next_batch(batch_size=128):    batch_x = np.zeros([batch_size,5000])    batch_y = np.zeros([batch_size,10])    for i in range(batch_size):        text, image = gene_code()        batch_x[i,:] = image        batch_y[i,text] = 1    return batch_x, batch_y

3.构建模型和训练
这部分基本完全按官网来的,我只改了输入输出的数据大小,有兴趣的可以去官网查看。

x = tf.placeholder(tf.float32, [None, 5000])y_ = tf.placeholder(tf.float32, [None, 10])#=======================================def weight_variable(shape):    initial = tf.truncated_normal(shape,stddev=0.1)    return tf.Variable(initial)def bias_variable(shape):    initial =tf.constant(0.01,shape=shape)    return tf.Variable(initial)def conv2d(x,W):    return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')def max_pool_2x2(x):    return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')#===============网络=====================x_image = tf.reshape(x, [-1,100,50,1])W_conv1=weight_variable([5,5,1,32])b_conv1=bias_variable([32])h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)h_pool1=max_pool_2x2(h_conv1)W_conv2 = weight_variable([5, 5, 32, 64])b_conv2 = bias_variable([64])h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)h_pool2 = max_pool_2x2(h_conv2)W_fc1 = weight_variable([20800, 1024])b_fc1 = bias_variable([1024])h_pool2_flat = tf.reshape(h_pool2, [-1, 20800])h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)keep_prob = tf.placeholder(tf.float32)h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)W_fc2 = weight_variable([1024, 10])b_fc2 = bias_variable([10])y_conv=tf.matmul(h_fc1_drop,W_fc2)+b_fc2#===============================================cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y_conv))train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))saver = tf.train.Saver()with tf.Session() as sess:    sess.run(tf.global_variables_initializer())    i=0    ggg=0.5    while True:        batch = get_next_batch(250)        train_accuracy=accuracy.eval(feed_dict={            x:batch[0], y_: batch[1], keep_prob: 1.0})        print ("step %d, training accuracy %g"%(i, train_accuracy))        if i%600==599:            saver.save(sess, filename+"model", global_step=i)        if train_accuracy>ggg:            ggg=(ggg+1.02)/2            saver.save(sess, filename+"model", global_step=i)        train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})        i=i+1

第四步 使用训练完的神经网络

训练完神经网络后就到了使用环境,我们只要把训练好的参数给模型,再把网站上的验证码交给模型,就可以查看结果了。

import urllib.requestfrom PIL import Imageimport tensorflow as tfimport numpy as npname=["1","2","3","4"]x = tf.placeholder(tf.float32, [None, 5000])y_ = tf.placeholder(tf.float32, [None, 10])#=======================================def weight_variable(shape):    initial = tf.truncated_normal(shape,stddev=0.1)    return tf.Variable(initial)def bias_variable(shape):    initial =tf.constant(0.01,shape=shape)    return tf.Variable(initial)def conv2d(x,W):    return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')def max_pool_2x2(x):    return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')#===============网络=====================x_image = tf.reshape(x, [-1,100,50,1])W_conv1=weight_variable([5,5,1,32])b_conv1=bias_variable([32])h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)h_pool1=max_pool_2x2(h_conv1)W_conv2 = weight_variable([5, 5, 32, 64])b_conv2 = bias_variable([64])h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)h_pool2 = max_pool_2x2(h_conv2)W_fc1 = weight_variable([20800, 1024])b_fc1 = bias_variable([1024])h_pool2_flat = tf.reshape(h_pool2, [-1, 20800])h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)keep_prob = tf.placeholder(tf.float32)h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)W_fc2 = weight_variable([1024, 10])b_fc2 = bias_variable([10])y_conv=tf.matmul(h_fc1_drop,W_fc2)+b_fc2#===============================================cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y_conv))train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))saver = tf.train.Saver()sess=tf.Session()saver.restore(sess, "D:/tensorflow/model6/crack_capcha.model-36599")for j in range(50):    response = urllib.request.urlopen('http://xxxxxx/jw_css/getCheckCode')    cat_img = response.read()    with open('D:/tensorflow/test.jpg','wb') as f:        f.write(cat_img)    img=Image.open('D:/tensorflow/test.jpg')    img.save("D:/tensorflow/img/"+str(j)+".jpg")    for i in range(4):        img1=img.crop((0+50*i,0,50+50*i,100)).convert('L')        m=0        mtr=np.zeros(5000,np.int)        while m<50:               n=0            while n<100:                      if img1.getpixel((m,n))>128:                    mtr[m+n*50]=1                else:                    mtr[m+n*50]=0                n=n+1            m=m+1        batch_x = np.zeros([1,5000])        batch_x[0,:] = mtr        result = sess.run(tf.argmax(y_conv,1), feed_dict={x: batch_x,keep_prob: 0.5})        print(result,end='')    print('|'+str(j))

下载的图片默认在D盘,识别出的结果会显示在命令行,自行查看吧。