1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
import tensorflow.compat.v1 as tf from datetime import datetime from util import get_next_batch from captcha_gen import CAPTCHA_HEIGHT, CAPTCHA_WIDTH, CAPTCHA_LEN, CAPTCHA_LIST
tf.compat.v1.disable_eager_execution()
def weight_variable(shape, w_alpha=0.01): """ 初始化权值 :param shape: :param w_alpha: :return: """ initial = w_alpha * tf.random_normal(shape) return tf.Variable(initial)
def bias_variable(shape, b_alpha=0.1): """ 初始化偏置项 :param shape: :param b_alpha: :return: """ initial = b_alpha * tf.random_normal(shape) return tf.Variable(initial)
def conv2d(x, w): """ 卷基层 :局部变量线性组合,步长为1,模式‘SAME’代表卷积后图片尺寸不变,即零边距 :param x: :param w: :return: """ return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x): """ 池化层:max pooling,取出区域内最大值为代表特征, 2x2 的pool,图片尺寸变为1/2 :param x: :return: """ return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
def cnn_graph(x, keep_prob, size, captcha_list=CAPTCHA_LIST, captcha_len=CAPTCHA_LEN): """ 三层卷积神经网络 :param x: 训练集 image x :param keep_prob: 神经元利用率 :param size: 大小 (高,宽) :param captcha_list: :param captcha_len: :return: y_conv """ image_height, image_width = size x_image = tf.reshape(x, shape=[-1, image_height, image_width, 1])
w_conv1 = weight_variable([3, 3, 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) h_drop1 = tf.nn.dropout(h_pool1, keep_prob)
w_conv2 = weight_variable([3, 3, 32, 64]) b_conv2 = bias_variable([64]) h_conv2 = tf.nn.relu(conv2d(h_drop1, w_conv2) + b_conv2) h_pool2 = max_pool_2x2(h_conv2) h_drop2 = tf.nn.dropout(h_pool2, keep_prob)
w_conv3 = weight_variable([3, 3, 64, 64]) b_conv3 = bias_variable([64]) h_conv3 = tf.nn.relu(conv2d(h_drop2, w_conv3) + b_conv3) h_pool3 = max_pool_2x2(h_conv3) h_drop3 = tf.nn.dropout(h_pool3, keep_prob)
""" 原始:60*160图片 第一次卷积后 60*160 第一池化后 30*80 第二次卷积后 30*80 ,第二次池化后 15*40 第三次卷积后 15*40 ,第三次池化后 7.5*20 = > 向下取整 7*20 经过上面操作后得到7*20的平面 """
image_height = int(h_drop3.shape[1]) image_width = int(h_drop3.shape[2]) w_fc = weight_variable([image_height*image_width*64, 1024]) b_fc = bias_variable([1024]) h_drop3_re = tf.reshape(h_drop3, [-1, image_height*image_width*64]) h_fc = tf.nn.relu(tf.matmul(h_drop3_re, w_fc) + b_fc) h_drop_fc = tf.nn.dropout(h_fc, keep_prob)
w_out = weight_variable([1024, len(captcha_list)*captcha_len]) b_out = bias_variable([len(captcha_list)*captcha_len]) y_conv = tf.matmul(h_drop_fc, w_out) + b_out return y_conv
def optimize_graph(y, y_conv): """ 优化计算图 :param y: 正确值 :param y_conv: 预测值 :return: optimizer """ loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=y_conv)) optimizer = tf.train.AdamOptimizer(1e-3).minimize(loss) return optimizer
def accuracy_graph(y, y_conv, width=len(CAPTCHA_LIST), height=CAPTCHA_LEN): """ 偏差计算图,正确值和预测值,计算准确度 :param y: 正确值 标签 :param y_conv: 预测值 :param width: 验证码预备字符列表长度 :param height: 验证码的大小,默认为4 :return: 正确率 """ predict = tf.reshape(y_conv, [-1, height, width]) max_predict_idx = tf.argmax(predict, 2) label = tf.reshape(y, [-1, height, width]) max_label_idx = tf.argmax(label, 2) correct_p = tf.equal(max_predict_idx, max_label_idx) accuracy = tf.reduce_mean(tf.cast(correct_p, tf.float32)) return accuracy
def train(height=CAPTCHA_HEIGHT, width=CAPTCHA_WIDTH, y_size=len(CAPTCHA_LIST)*CAPTCHA_LEN): """ cnn训练 :param height: 验证码高度 :param width: 验证码宽度 :param y_size: 验证码预备字符列表长度*验证码长度(默认为4) :return: """
acc_rate = 0.95 x = tf.placeholder(tf.float32, [None, height * width]) y = tf.placeholder(tf.float32, [None, y_size]) keep_prob = tf.placeholder(tf.float32) y_conv = cnn_graph(x, keep_prob, (height, width)) optimizer = optimize_graph(y, y_conv) accuracy = accuracy_graph(y, y_conv) saver = tf.train.Saver() sess = tf.Session() sess.run(tf.global_variables_initializer()) step = 0 while 1: batch_x, batch_y = get_next_batch(64) sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, keep_prob: 0.75}) 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.0}) print(datetime.now().strftime('%c'), ' step:', step, ' accuracy:', acc) if acc > acc_rate: model_path = "./model/captcha.model" saver.save(sess, model_path, global_step=step) acc_rate += 0.01 if acc_rate > 0.99: break step += 1 sess.close()
if __name__ == '__main__': train()
|