本程序作为一个基础版的CNN使用教程,以识别简单的英文验证码作为目标完成一个简单的实例。在这个实例中,我们会涉及到以下三步,并通过这三部曲来带大家体验深度学习的魅力。

仅2分,可直接运行的程序:https://download.csdn.net/download/qq_32791307/10651274

1. 对数据的基本读取、处理并生成batch

2. 搭建简单的CNN模型

3. 训练并得出结果

一 .  数据处理

 1. 首先我们需要先生成一批验证码,代码如下,十分简单。生成效果如图。名字为0B73.jpg

我们可以用程序生成大量的验证码作为样本。可以更改代码中for i in range(数字) 的数字来生成不同数量的样本。大小170*80

#coding=utf-8
from captcha.image import ImageCaptcha
import matplotlib.pyplot as plt
import numpy as np
import random
from scipy.misc import imread,imresize,imsave
import string#用于生成不同长度的训练集(3..6)/验证集
characters=string.digits+string.ascii_uppercase+string.ascii_lowercase
width,height,n_len,n_class=170,80,6,len(characters)generater=ImageCaptcha(width=width,height=height)
dir=".\\train"
for i in range(8000):#生成3,6位random_str="".join([random.choice(characters) for j in range(0,random.choice(range(3,6)))])#生成4位
#   random_str="".join([random.choice(characters) for j in range(0,4)])image=generater.generate_image(random_str)   imsave(dir+"/"+random_str+".jpg",image)

      2.  其次有了样本之后,我们需要对样本进行以下的操作。

第一步:获取图片和图片名称的代码,非常简单,注释如下。

def get_image_name():#获得目录下所有图片all_image = os.listdir('D:/tensorflow3_captcha/train/')#打散训练集random_file = random.randint(0,8000) #拓展名获取, eg: 123.txt 分为[0] 123 ,[1] txtbase = os.path.basename('D:/tensorflow_captcha/train/' + all_image[random_file])name = os.path.splitext(base)[0]#读取图片并转为灰度图image = cv2.imread('D:/tensorflow_captcha/train/' + all_image[random_file],cv2.IMREAD_GRAYSCALE)
#     cv2.imshow("tu",image)
#     cv2.waitKey(0)
#     print(name)return name,image

第二步:确定字母次序为0-9a-zA-Z得到字母对应位置标签. 如 a 对应标签为 11

#ord(c)随机给定一个无符号数,ord('0')=48
#字符固定位置
def char2pos(c):   if c =='_':k=62return kk= ord(c)-48# ord(c)为0-9时的位置
#ord(c)为大写字母时的位置,因为0-9占了10位,所以是ord(c)-ord('A')+10=ord(c)-55if k > 9: #如ord('C')=67-55=12k = ord(c) - 55
#ord(c)为小写字母时的位置,0-z占了35位          if k > 35: #ord('c')=99-61=38k = ord(c) - 61if k > 61:raise ValueError('No Map')return k

第三步:名字标签与one-hot编码的形式互相转换。(注:1,2,3对应one-hot示例 [ [0 ,1 ,0 ,0], [0 ,0 ,1 ,0], [0 ,0 ,0 ,1]])

#名字转向量标签
def name2vec(name):vector = np.zeros(max_captcha*char_set)     for i, c in enumerate(name):    idx = i * char_set + char2pos(c)vector[idx] = 1return vector  #return 不能忘!!导致loss = nan
#          print (vector);print(idx)#向量标签转名字,为了结果可以对应,也可以名字向量互转用字典代替。
def vec2name(vec):char_pos = vec.nonzero()[0]name=[]for i, c in enumerate(char_pos):char_idx = c % char_setif char_idx < 10:char_code = char_idx + ord('0')elif char_idx < 36:char_code = char_idx - 10 + ord('A')elif char_idx < 62:char_code = char_idx-  36 + ord('a')elif char_idx == 62:char_code = ord('_')else:raise ValueError('error')name.append(chr(char_code))return "".join(name)

第四步:制作batch。(注:batch_size 一般大小为2的n次方,常用大小为32,64)

def get_next_batch(batch_size):batch_x = np.zeros([batch_size,image_height*image_width])batch_y = np.zeros([batch_size,max_captcha*char_set])for i in range(batch_size): #格式注意range,np.zeros([])name,image = get_image_name()batch_x[i,:] = image.flatten()/255batch_y[i,:] = name2vec(name)return batch_x,batch_y

二. 搭建简单的CNN模型

通常,我会将搭建过程分为前后两期,前期定义输入变量,定义weight、bias 、conv2d、max_pool等所需要的‘积木块’。后期开始堆积积木块。各大著名网络结构可以看为积木搭建的图纸,只要我们有安装图纸,前期只要定义好各类所需的‘积木块’,后期就可以按图索骥就好。本次只是简单的堆积了一个模型,大家也可以去体验更多的网络结构。下面,我们开始吧!

第一步:定义各类变量

X = tf.placeholder(tf.float32,[None,image_height*image_width])
Y = tf.placeholder(tf.float32,[None,max_captcha*char_set])
y_in = tf.sparse_placeholder(tf.int32)
seq_length=tf.placeholder(tf.int32,[None])
keep_prob = tf.placeholder(tf.float32) # dropout#这里的learn_rate比较详细,不麻烦的话也可以直接用learn_rate=0.0001作为学习速率
global_step = tf.Variable(0, trainable=False)
learn_rate = tf.train.exponential_decay(INITIAL_LEARNING_RATE,global_step,DECAY_STEPS,LEARNING_RATE_DECAY_FACTOR,staircase=True)#define weight biaes
def weight(shape):#tf.truncated_normal(shape, mean, stddev)initial = 0.01*tf.random_normal(shape)return tf.Variable(initial)def biases(shape):initial = 0.1*tf.random_normal(shape) #tf.constant(0.1,shape=shape)return tf.Variable(initial)#define conv and pool ,padding有'SAME'和'VALID'两种
def conv2d(x,w):return tf.nn.conv2d(x,w,strides=[1,1,1,1],padding='SAME')
def max_pool(x):#ksize是pool的窗口大小=[1,height,width,1]也就是卷积核大小;return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')#因为是2x2的池化,所以输出是池化一次就/2 ,和权重的卷积取多少无关

第二步:积木堆积,本次所用图片大小为80*170, 所以第一次的卷积输出为40*85

模仿的VGG16

def cnn(weight,biases):     img_x = tf.reshape(X,[-1,image_height,image_width,1])#### conv layer 1 ####w_conv1 = weight([3,3,1,32]) #3X3的卷积核,第一层输出32b_conv1 = biases([32])h_conv1 = tf.nn.relu(conv2d(img_x,w_conv1)+b_conv1)h_pool1 = max_pool(h_conv1) #outsize = 40*85     conv1 = tf.nn.dropout(h_pool1, keep_prob)#### conv layer 2 ####     w_conv2 = weight([3,3,32,64]) #3X3的卷积核,第2层输出64b_conv2 = biases([64])h_conv2 = tf.nn.relu(conv2d(conv1,w_conv2)+b_conv2)h_pool2 = max_pool(h_conv2)  #20,42.5      conv2 = tf.nn.dropout(h_pool2, keep_prob)     #### conv layer 3 ####w_conv3 = weight([3,3,64,64]) #3X3的卷积核,第2层输出64b_conv3 = biases([64])h_conv3 = tf.nn.relu(conv2d(conv2,w_conv3)+b_conv3)h_pool3 = max_pool(h_conv3)     #10, 21.25--->10,22   conv3 = tf.nn.dropout(h_pool3, keep_prob)        ## ## Fully connected layer 1 ####w_fc1 = weight([10*22*64,1024])b_fc1 = biases([1024])
#     h_pool3_flat = tf.reshape(h_pool3,[-1,10*22*64])h_pool3_flat = tf.reshape(conv3, [-1, w_fc1.get_shape().as_list()[0]])h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat,w_fc1)+b_fc1)#[64,1024]h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)## ## out 输出特征 ####w_out = weight([1024,max_captcha*char_set])b_out = biases([max_captcha*char_set])#out用的sigmoid,loss对应sigmoid#out = [64,1024]*[1024,378]+378 =[64,378]out = tf.matmul(h_fc1_drop,w_out)+b_out  #sigmoid ,注意行列顺序,HXWreturn out , h_fc1

三. 训练并验证

1. 开始训练前容易犯的错误是没有初始化变量。

2.sess.close不加也可以,但是加上是个好习惯。

3.其实也可以单独定义 loss,accuracy。

4.及时使用tf.train.Saver()来储存模型。这样可以多次训练模型。用saver.restore即可快速恢复训练。


def train_cnn():output, conv_3 = cnn(weight,biases) #output 64*378
#     loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=output,labels=Y))loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output, labels=Y))train_step = tf.train.AdamOptimizer(0.001).minimize(loss)predict = tf.reshape(output,[-1,max_captcha,char_set])label = tf.reshape(Y,[-1,max_captcha,char_set])
#     print(label,'\n',predict)max_idx_pre = tf.argmax(predict,2) #沿char_set找最大值索引即63个里最大的。max_idx_lab = tf.argmax(label,2)accuracy = tf.metrics.accuracy(labels=max_idx_lab,predictions=max_idx_pre) #tuplesaver = tf.train.Saver()sess = tf.Session()init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer()) # the local var is for accuracy_opsess.run(init_op)step = 0while True:
######需要恢复模型,继续训练时可使用以下注释部分
#          model_file=tf.train.latest_checkpoint('model/')
#          saver.restore(sess,model_file )      batch_x,batch_y = get_next_batch(64)_,loss_ ,out= sess.run([train_step,loss,output] ,feed_dict={X:batch_x,Y:batch_y,keep_prob: 0.6})
#          print('step:',step)
#          print(out.shape)if step%100 == 0:batch_x_test,batch_y_test = get_next_batch(64)acc = sess.run(accuracy,feed_dict={X:batch_x_test,Y:batch_y_test, keep_prob: 1.})[1]print('train loss: ' , loss_,'train acc: ', acc)if acc > 0.8 :saver.save(sess,"model/my_captcha.ckpt", global_step=step)break  step += 1sess.close()
train_cnn()

四. 训练过程中可能出现的问题

1. 训练的 Loss和Acc 可能值会上下波动,这是正常现象,只要整体Loss趋势变小,Acc变大即可

2. 训练时间需要长一些,因为样本比较复杂,且没预处理,请耐心等待。

3. 如果训练很长时间测试的Acc却达不到很高的水平,可以尝试增加样本数量。

cnn识别不定长英文验证码相关推荐

  1. chinese-ocr自然场景下不定长文字识别(ctpn + densenet)

    chinese-ocr自然场景下不定长文字识别(ctpn + densenet) 注:本文中多处使用各位前辈的经验,项目代码不方便提供,可参考: https://github.com/YCG09/ch ...

  2. tensorflow LSTM+CTC实现端到端的不定长数字串识别

    转载地址: https://www.jianshu.com/p/45828b18f133 上一篇文章tensorflow 实现端到端的OCR:二代身份证号识别实现了定长18位数字串的识别,并最终达到了 ...

  3. 使用Python基于VGG/CTPN/CRNN的自然场景文字方向检测/区域检测/不定长OCR识别

    GitHub:https://github.com/pengcao/chinese_ocr https://github.com/xiaofengShi/CHINESE-OCR |-angle 基于V ...

  4. DL之CNN:基于CNN-RNN(GRU,2)算法(keras+tensorflow)实现不定长文本识别

    DL之CNN:基于CNN-RNN(GRU,2)算法(keras+tensorflow)实现不定长文本识别 目录 输出结果 实现代码 输出结果 后期更新-- 实现代码 后期更新-- image_ocr代 ...

  5. [验证码识别技术] 字符型验证码终结者-CNN+BLSTM+CTC

    验证码识别(少样本,高精度)项目地址:https://github.com/kerlomz/captcha_trainer 1. 前言 本项目适用于Python3.6,GPU>=NVIDIA G ...

  6. 【OCR技术系列之八】端到端不定长文本识别CRNN代码实现

    CRNN是OCR领域非常经典且被广泛使用的识别算法,其理论基础可以参考我上一篇文章,本文将着重讲解CRNN代码实现过程以及识别效果. 数据处理 利用图像处理技术我们手工大批量生成文字图像,一共360万 ...

  7. CRNN:端到端不定长文字识别算法

    点击上方"AI搞事情"关注我们 ❝ 论文:<An End-to-End Trainable Neural Network for Image-based Sequence R ...

  8. 文字识别(六)--不定长文字识别CRNN算法详解

    转自:https://www.cnblogs.com/skyfsm/p/10335717.html 在以前的OCR任务中,识别过程分为两步:单字切割和分类任务.我们一般都会讲一连串文字的文本文件先利用 ...

  9. 1tensorflow 实现端到端的OCR:二代身份证号识别 + 2tensorflow LSTM+CTC实现端到端的不定长数字串识别

    1tensorflow 实现端到端的OCR:二代身份证号识别 链接地址:https://www.jianshu.com/p/803642d0d8f8 2tensorflow LSTM+CTC实现端到端 ...

最新文章

  1. 基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)
  2. 奥鹏计算机基础18秋在线作业答案,18秋华师《计算机基础》在线作业1(标准答案).doc...
  3. 光驱怎么挂载第二个光驱_电脑光驱怎么安装?台式机安装光驱的方法
  4. linux如何打开url,用于打开URL的命令?
  5. 初学jQuery之选择器
  6. 配置Https 和 HSTS
  7. Windows 64 位 mysql 5.7以上版本包解压中没有data目录和my-default.ini和my.ini文件以及服务无法启动的解决办法以及修改初始密码的方法
  8. 秒懂Https之CA证书与自签名证书漫谈
  9. OpenBmc开发5:bitbake介绍与使用
  10. PHP使用Composer配置微信支付SDK
  11. 农村土地确权之调查公示 —— ArcGIS中地块分布图标注设置说明[地块分布图制作]
  12. Redis系列总结--这几点你会了吗?
  13. Exeinfo PE查壳工具
  14. Win10邮件应用怎么添加网易邮箱
  15. 用Python制作可视化GUI界面,一键实现证件照背景颜色的替换
  16. fing网络扫描仪android,Fing网络扫描仪
  17. ASP.NET Core中的环境Development、Staging、Production
  18. 连续型随机变量的分布(均匀分布、指数分布、正态分布)
  19. 图解iPhone开发入门教程
  20. 马云退休,7300天里为阿里巴巴留下1个奇迹、2大争议、4大挑战

热门文章

  1. -- 34、查询课程名称为“数学“,且分数低于60的学生姓名和分数
  2. 海盗分金c语言算法,[经典算法]海盗分金问题sql求解(贪心算法)
  3. DTAS-电机机壳与端盖止口垂直度对电机气隙影响
  4. 高清电脑壁纸桌面图片|到高图随心换高清图
  5. 32位嵌入式微处理器(processor)一览
  6. 光盘驱动计算机无法识别,win7系统读不出光盘怎么办 win7电脑光盘不能被识别的解决方法...
  7. 深入理解volatile(Java)
  8. 10大网络美女排行榜(组图)(*^__^*) ……
  9. 什么是8K视频技术!8K视频测试解决方案
  10. 论文|翻译——行为数据挖掘(持续更新!)