#coding:utf-8 from gen_captcha import gen_captcha_text_and_image from gen_captcha import number from gen_captcha import alphabet from gen_captcha import ALPHABET import tensorflow.contrib.slim as slim import numpy as np import tensorflow as tf from scipy.misc import imread text, image = gen_captcha_text_and_image() #先生成验证码和文字测试模块是否完全 print("验证码图像channel:", image.shape) # (60, 160, 3) # 图像大小 IMAGE_HEIGHT = 60 IMAGE_WIDTH = 160 MAX_CAPTCHA = len(text) print("验证码文本最长字符数", MAX_CAPTCHA) # 验证码最长4字符; 我全部固定为4,可以不固定. 如果验证码长度小于4,用'_'补齐 # 把彩色图像转为灰度图像(色彩对识别验证码没有什么用) def convert2gray(img): if len(img.shape) > 2: gray = np.mean(img, -1) # 上面的转法较快,正规转法如下 # r, g, b = img[:,:,0], img[:,:,1], img[:,:,2] # gray = 0.2989 * r + 0.5870 * g + 0.1140 * b return gray else: return img # 文本转向量 char_set = number + alphabet + ALPHABET + ['_'] # 如果验证码长度小于4, '_'用来补齐 CHAR_SET_LEN = len(char_set) def text2vec(text): text_len = len(text) if text_len > MAX_CAPTCHA: raise ValueError('验证码最长4个字符') vector = np.zeros(MAX_CAPTCHA*CHAR_SET_LEN) def char2pos(c): if c =='_': k = 62 return k k = ord(c)-48 if k > 9: k = ord(c) - 55 if k > 35: k = ord(c) - 61 if k > 61: raise ValueError('No Map') return k for i, c in enumerate(text): idx = i * CHAR_SET_LEN + char2pos(c) vector[idx] = 1 return vector # 向量转回文本 def vec2text(vec): char_pos = vec.nonzero()[0] text=[] for i, c in enumerate(char_pos): char_at_pos = i #c/63 char_idx = c % CHAR_SET_LEN if 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') text.append(chr(char_code)) return "".join(text) """ #向量(大小MAX_CAPTCHA*CHAR_SET_LEN)用0,1编码 每63个编码一个字符,这样顺利有,字符也有 vec = text2vec("F5Sd") text = vec2text(vec) print(text) # F5Sd vec = text2vec("SFd5") text = vec2text(vec) print(text) # SFd5 """ # 生成一个训练batch def get_next_batch(batch_size=128): batch_x = np.zeros([batch_size, IMAGE_HEIGHT*IMAGE_WIDTH]) batch_y = np.zeros([batch_size, MAX_CAPTCHA*CHAR_SET_LEN]) # 有时生成图像大小不是(60, 160, 3) def wrap_gen_captcha_text_and_image(): ''' 获取一张图,判断其是否符合(60,160,3)的规格''' while True: text, image = gen_captcha_text_and_image() if image.shape == (60, 160, 3):#此部分应该与开头部分图片宽高吻合 return text, image for i in range(batch_size): text, image = wrap_gen_captcha_text_and_image() image = convert2gray(image) # 将图片数组一维化 同时将文本也对应在两个二维组的同一行 batch_x[i,:] = image.flatten() / 255 # (image.flatten()-128)/128 mean为0 batch_y[i,:] = text2vec(text) # 返回该训练批次 return batch_x, batch_y #################################################################### # 申请占位符 按照图片 X = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT*IMAGE_WIDTH]) Y = tf.placeholder(tf.float32, [None, MAX_CAPTCHA*CHAR_SET_LEN]) keep_prob = tf.placeholder(tf.float32) # dropout # 定义CNN def crack_captcha_cnn(): # 将占位符 转换为 按照图片给的新样式 #slim.conv2d的stride默认为1,slim.max_pool2d的stride默认与f保持一致, padding默认都为SAME x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1]) with slim.arg_scope([slim.conv2d, slim.fully_connected], activation_fn=tf.nn.relu, weights_initializer=tf.truncated_normal_initializer(stddev=0.1), weights_regularizer=slim.l2_regularizer(0.0005)): net = slim.conv2d(x, 32, 3, scope="conv1")#32为通道,3为f即[3, 3],stride默认为1,padding默认为SAME net= slim.max_pool2d(net, 2, scope="pool1")#2即f为[2,2],stride默认与f保持一致 net = slim.conv2d(net, 64, 1, scope="conv2") net = slim.max_pool2d(net, 2, scope="pool2") net = slim.conv2d(net, 64, 1, scope="conv3") net = slim.max_pool2d(net, 2, scope="pool3") net = slim.flatten(net, scope='flat_1') net = slim.dropout(net, keep_prob=keep_prob, scope='drop1') net = slim.fully_connected(net, 1024, scope="f1") net = slim.fully_connected(net, 512, scope="f2") z = slim.fully_connected(net, MAX_CAPTCHA*CHAR_SET_LEN, activation_fn=None, scope="f3") p = tf.nn.sigmoid(z, name="prediction") return z, p # 训练 def train_crack_captcha_cnn(): z, p = crack_captcha_cnn() #sigmoid多任务模式,一个标签中有多个目标 loss = tf.reduce_mean(slim.losses.sigmoid_cross_entropy(z, Y)) #loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=z, labels=Y)) optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) predict = tf.reshape(p, [-1, MAX_CAPTCHA, CHAR_SET_LEN]) max_idx_p = tf.argmax(predict, 2) max_idx_l = tf.argmax(tf.reshape(Y, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2) correct_pred = tf.equal(max_idx_p, max_idx_l) accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) saver = tf.train.Saver() saver_r = tf.train.import_meta_graph('E:/data/tensorflow-master/1.Cnn_Captcha/model-8800.meta') # 指定监测结果输出目录 with tf.Session() as sess: #sess.run(tf.global_variables_initializer()) summary_writer = tf.summary.FileWriter('E:/data/tensorflow-master/1.Cnn_Captcha/result/', sess.graph) saver_r.restore(sess, tf.train.latest_checkpoint('E:/data/tensorflow-master/1.Cnn_Captcha/')) step = 0 while True: batch_x, batch_y = get_next_batch(64) _, loss_ = sess.run([optimizer, loss], feed_dict={X: batch_x, Y: batch_y, keep_prob: 0.75}) # 把Tensor添加到观测中 tf.summary.scalar('loss', loss) print(step, loss_) # 每100 step计算一次准确率 if step % 100 == 0: batch_x_test, batch_y_test = get_next_batch(100) #acc = sess.run(accuracy, feed_dict={X: batch_x_test, Y: batch_y_test, keep_prob: 1.}) tf.summary.scalar('accuracy', accuracy) #sum_ops = tf.merge_all_summaries() sum_ops = tf.summary.merge_all() metall = sess.run(sum_ops, feed_dict={X: batch_x_test, Y: batch_y_test, keep_prob: 1.}) summary_writer.add_summary(metall, global_step=step) # 写入文件 #print(step, acc) # 如果准确率大于50%,保存模型,完成训练 if step % 1000 == 0 and step != 0: saver.save(sess, "E:/data/tensorflow-master/1.Cnn_Captcha/model/", global_step=step) break step += 1 def train(): train_log_dir = "E:/data/tensorflow-master/1.Cnn_Captcha/result/" if not tf.gfile.Exists(train_log_dir): tf.gfile.MakeDirs(train_log_dir) with tf.Graph().as_default(): batch_x, batch_y = get_next_batch(64) x = tf.reshape(batch_x, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1]) y = tf.cast(batch_y, tf.float32) z, p = crack_captcha_cnn(tf.cast(x, tf.float32), 0.75) loss = tf.reduce_mean(slim.losses.sigmoid_cross_entropy(z, y)) optimizer = tf.train.AdamOptimizer(learning_rate=0.001) tf.summary.scalar('losses/total_loss', loss) predict = tf.reshape(p, [-1, MAX_CAPTCHA, CHAR_SET_LEN]) max_idx_p = tf.argmax(predict, 2) max_idx_l = tf.argmax(tf.reshape(y, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2) correct_pred = tf.equal(max_idx_p, max_idx_l) accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) tf.summary.scalar('losses/accuracy', accuracy) train_tensor = slim.learning.create_train_op(loss, optimizer,global_step=10) slim.learning.train(train_tensor, train_log_dir) #train() train_crack_captcha_cnn() saver = tf.train.import_meta_graph('E:/data/tensorflow-master/1.Cnn_Captcha/model-8800.meta') with tf.Session() as sess: saver.restore(sess, tf.train.latest_checkpoint('E:/data/tensorflow-master/1.Cnn_Captcha/')) graph = tf.get_default_graph() image = imread("E:/data/tensorflow-master/1.Cnn_Captcha/create_image/image/0h6Y.jpg") batch_x = np.zeros([1, IMAGE_HEIGHT * IMAGE_WIDTH]) batch_y = np.zeros([1, MAX_CAPTCHA * CHAR_SET_LEN]) batch_x[0, :] = image.flatten() / 255 # (image.flatten()-128)/128 mean为0 batch_y[0, :] = text2vec("0h6Y") p = graph.get_tensor_by_name("prediction:0") predict = tf.reshape(p, [-1, MAX_CAPTCHA, CHAR_SET_LEN]) X = graph.get_tensor_by_name("Placeholder_3:0") Y = graph.get_tensor_by_name("Placeholder_1:0") keep_prob = graph.get_tensor_by_name("Placeholder_2_1:0") max_idx_p = tf.argmax(predict, 2) p = sess.run(max_idx_p, feed_dict={X: batch_x, Y: batch_y, keep_prob: 1}) print(p) print(np.argmax(np.array(batch_y).reshape([MAX_CAPTCHA, CHAR_SET_LEN]), axis=1)) # Do some work with the model ...
test
最新推荐文章于 2019-11-01 11:04:15 发布