├── __init__.py ├── img ├── 2uB3.jpg ├── 7ZTm.jpg ├── 8nZe.jpg ├── CWWJ.jpg ├── MJnK.jpg ├── UCkV.jpg ├── Yt82.jpg ├── q7wy.jpg └── test.py ├── process.png ├── result.png ├── model └── readme.md ├── model_test.py ├── captcha_gen.py ├── util.py ├── model_train.py └── README.md /__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /img/2uB3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/img/2uB3.jpg -------------------------------------------------------------------------------- /img/7ZTm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/img/7ZTm.jpg -------------------------------------------------------------------------------- /img/8nZe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/img/8nZe.jpg -------------------------------------------------------------------------------- /img/CWWJ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/img/CWWJ.jpg -------------------------------------------------------------------------------- /img/MJnK.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/img/MJnK.jpg -------------------------------------------------------------------------------- /img/UCkV.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/img/UCkV.jpg -------------------------------------------------------------------------------- /img/Yt82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/img/Yt82.jpg -------------------------------------------------------------------------------- /img/q7wy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/img/q7wy.jpg -------------------------------------------------------------------------------- /process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/process.png -------------------------------------------------------------------------------- /result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyboy2017/captcha_check/HEAD/result.png -------------------------------------------------------------------------------- /model/readme.md: -------------------------------------------------------------------------------- 1 | ### 文件太大,没法上传压缩一下~ 2 | 3 | ### 还是不行 4 | 5 | 6 | ### 上传百度云盘了~ 7 | 8 | ### 下载地址:https://pan.baidu.com/s/1X7u80Gb6laWq-HjRlQI6DQ 9 | -------------------------------------------------------------------------------- /img/test.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import numpy as np 3 | from PIL import Image 4 | from util import vec2text, text2vec 5 | import tensorflow as tf 6 | 7 | 8 | img = Image.open('./q7wy.jpg') 9 | img_data = np.array(img) 10 | # if len(img_data) > 2: 11 | # img_data = np.mean(img_data, -1) 12 | # 13 | 14 | # img = Image.fromarray(img_data) 15 | # img.show() 16 | # print(img_data.shape) 17 | 18 | code = '1234' 19 | 20 | vec2 = text2vec(code) 21 | print(vec2) 22 | y = vec2text(vec2) 23 | # t = tf.reshape(code, [2, 2]) 24 | print(y) 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /model_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # description:模型测试,验证验证码识别情况 3 | 4 | import tensorflow as tf 5 | from model_train import cnn_graph 6 | from captcha_gen import gen_captcha_text_and_image 7 | from util import vec2text, convert2gray 8 | from util import CAPTCHA_LIST, CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_LEN 9 | from PIL import Image 10 | 11 | 12 | def captcha2text(image_list, height=CAPTCHA_HEIGHT, width=CAPTCHA_WIDTH): 13 | """ 14 | 验证码图片转化为文本 15 | :param image_list: 16 | :param height: 17 | :param width: 18 | :return: 19 | """ 20 | x = tf.placeholder(tf.float32, [None, height * width]) 21 | keep_prob = tf.placeholder(tf.float32) 22 | y_conv = cnn_graph(x, keep_prob, (height, width)) 23 | saver = tf.train.Saver() 24 | with tf.Session() as sess: 25 | saver.restore(sess, tf.train.latest_checkpoint('model/')) 26 | predict = tf.argmax(tf.reshape(y_conv, [-1, CAPTCHA_LEN, len(CAPTCHA_LIST)]), 2) 27 | vector_list = sess.run(predict, feed_dict={x: image_list, keep_prob: 1}) 28 | vector_list = vector_list.tolist() 29 | text_list = [vec2text(vector) for vector in vector_list] 30 | return text_list 31 | 32 | 33 | if __name__ == '__main__': 34 | text, image = gen_captcha_text_and_image() 35 | img = Image.fromarray(image) 36 | image = convert2gray(image) 37 | image = image.flatten() / 255 38 | pre_text = captcha2text([image]) 39 | print("验证码正确值:", text, ' 模型预测值:', pre_text , '正确与否:',pre_text[0] == text) 40 | img.show() 41 | 42 | 43 | -------------------------------------------------------------------------------- /captcha_gen.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # description: 用于验证码的生成,生成训练集和测试集 3 | import random 4 | import numpy as np 5 | from PIL import Image 6 | from captcha.image import ImageCaptcha 7 | 8 | 9 | NUMBER = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] 10 | LOW_CASE = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 11 | 'v', 'w', 'x', 'y', 'z'] 12 | UP_CASE = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 13 | 'V', 'W', 'X', 'Y', 'Z'] 14 | 15 | CAPTCHA_LIST = NUMBER 16 | CAPTCHA_LEN = 4 17 | CAPTCHA_HEIGHT = 60 18 | CAPTCHA_WIDTH = 160 19 | 20 | 21 | def random_captcha_text(char_set=CAPTCHA_LIST, captcha_size=CAPTCHA_LEN): 22 | """ 23 | 随机生成定长字符串 24 | :param char_set: 备选字符串列表 25 | :param captcha_size: 字符串长度 26 | :return: 字符串 27 | """ 28 | captcha_text = [random.choice(char_set) for _ in range(captcha_size)] 29 | return ''.join(captcha_text) 30 | 31 | 32 | def gen_captcha_text_and_image(width=CAPTCHA_WIDTH, height=CAPTCHA_HEIGHT, save=None): 33 | """ 34 | 生成随机验证码 35 | :param width: 验证码图片宽度 36 | :param height: 验证码图片高度 37 | :param save: 是否保存(None) 38 | :return: 验证码字符串,验证码图像np数组 39 | """ 40 | image = ImageCaptcha(width=width, height=height) 41 | # 验证码文本 42 | captcha_text = random_captcha_text() 43 | captcha = image.generate(captcha_text) 44 | # 保存 45 | if save: 46 | image.write(captcha_text, './img/' + captcha_text + '.jpg') 47 | captcha_image = Image.open(captcha) 48 | # 转化为np数组 49 | captcha_image = np.array(captcha_image) 50 | return captcha_text, captcha_image 51 | 52 | 53 | if __name__ == '__main__': 54 | t, im = gen_captcha_text_and_image(save=True) 55 | print(t, im.shape) # (60, 160, 3) 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /util.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # description:辅助功能,图片预处理,转向量,生成测试集训练集 3 | 4 | import numpy as np 5 | from captcha_gen import gen_captcha_text_and_image 6 | from captcha_gen import CAPTCHA_LIST, CAPTCHA_LEN, CAPTCHA_HEIGHT, CAPTCHA_WIDTH 7 | 8 | 9 | def convert2gray(img): 10 | """ 11 | 图片转为黑白,3维转1维 12 | :param img: np 13 | :return: 灰度图的np 14 | """ 15 | if len(img.shape) > 2: 16 | img = np.mean(img, -1) 17 | return img 18 | 19 | 20 | def text2vec(text, captcha_len=CAPTCHA_LEN, captcha_list=CAPTCHA_LIST): 21 | """ 22 | 验证码文本转为向量 23 | :param text: 24 | :param captcha_len: 25 | :param captcha_list: 26 | :return: vector 文本对应的向量形式 27 | """ 28 | text_len = len(text) # 欲生成验证码的字符长度 29 | if text_len > captcha_len: 30 | raise ValueError('验证码最长4个字符') 31 | vector = np.zeros(captcha_len * len(captcha_list)) # 生成一个一维向量 验证码长度*字符列表长度 32 | for i in range(text_len): 33 | vector[captcha_list.index(text[i])+i*len(captcha_list)] = 1 # 找到字符对应在字符列表中的下标值+字符列表长度*i 的 一维向量 赋值为 1 34 | return vector 35 | 36 | 37 | def vec2text(vec, captcha_list=CAPTCHA_LIST, captcha_len=CAPTCHA_LEN): 38 | """ 39 | 验证码向量转为文本 40 | :param vec: 41 | :param captcha_list: 42 | :param captcha_len: 43 | :return: 向量的字符串形式 44 | """ 45 | vec_idx = vec 46 | text_list = [captcha_list[int(v)] for v in vec_idx] 47 | return ''.join(text_list) 48 | 49 | 50 | def wrap_gen_captcha_text_and_image(shape=(60, 160, 3)): 51 | """ 52 | 返回特定shape图片 53 | :param shape: 54 | :return: 55 | """ 56 | while True: 57 | t, im = gen_captcha_text_and_image() 58 | if im.shape == shape: 59 | return t, im 60 | 61 | 62 | def get_next_batch(batch_count=60, width=CAPTCHA_WIDTH, height=CAPTCHA_HEIGHT): 63 | """ 64 | 获取训练图片组 65 | :param batch_count: default 60 66 | :param width: 验证码宽度 67 | :param height: 验证码高度 68 | :return: batch_x, batch_yc 69 | """ 70 | batch_x = np.zeros([batch_count, width * height]) 71 | batch_y = np.zeros([batch_count, CAPTCHA_LEN * len(CAPTCHA_LIST)]) 72 | for i in range(batch_count): # 生成对应的训练集 73 | text, image = wrap_gen_captcha_text_and_image() 74 | image = convert2gray(image) # 转灰度numpy 75 | # 将图片数组一维化 同时将文本也对应在两个二维组的同一行 76 | batch_x[i, :] = image.flatten() / 255 77 | batch_y[i, :] = text2vec(text) # 验证码文本的向量形式 78 | # 返回该训练批次 79 | return batch_x, batch_y 80 | 81 | 82 | if __name__ == '__main__': 83 | x, y = get_next_batch(batch_count=1) # 默认为1用于测试集 84 | print(x, y) 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /model_train.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # description:训练模型 3 | 4 | import tensorflow as tf 5 | from datetime import datetime 6 | from util import get_next_batch 7 | from captcha_gen import CAPTCHA_HEIGHT, CAPTCHA_WIDTH, CAPTCHA_LEN, CAPTCHA_LIST 8 | 9 | 10 | def weight_variable(shape, w_alpha=0.01): 11 | """ 12 | 初始化权值 13 | :param shape: 14 | :param w_alpha: 15 | :return: 16 | """ 17 | initial = w_alpha * tf.random_normal(shape) 18 | return tf.Variable(initial) 19 | 20 | 21 | def bias_variable(shape, b_alpha=0.1): 22 | """ 23 | 初始化偏置项 24 | :param shape: 25 | :param b_alpha: 26 | :return: 27 | """ 28 | initial = b_alpha * tf.random_normal(shape) 29 | return tf.Variable(initial) 30 | 31 | 32 | def conv2d(x, w): 33 | """ 34 | 卷基层 :局部变量线性组合,步长为1,模式‘SAME’代表卷积后图片尺寸不变,即零边距 35 | :param x: 36 | :param w: 37 | :return: 38 | """ 39 | return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') 40 | 41 | 42 | def max_pool_2x2(x): 43 | """ 44 | 池化层:max pooling,取出区域内最大值为代表特征, 2x2 的pool,图片尺寸变为1/2 45 | :param x: 46 | :return: 47 | """ 48 | return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') 49 | 50 | 51 | def cnn_graph(x, keep_prob, size, captcha_list=CAPTCHA_LIST, captcha_len=CAPTCHA_LEN): 52 | """ 53 | 三层卷积神经网络 54 | :param x: 训练集 image x 55 | :param keep_prob: 神经元利用率 56 | :param size: 大小 (高,宽) 57 | :param captcha_list: 58 | :param captcha_len: 59 | :return: y_conv 60 | """ 61 | # 需要将图片reshape为4维向量 62 | image_height, image_width = size 63 | x_image = tf.reshape(x, shape=[-1, image_height, image_width, 1]) 64 | 65 | # 第一层 66 | # filter定义为3x3x1, 输出32个特征, 即32个filter 67 | w_conv1 = weight_variable([3, 3, 1, 32]) # 3*3的采样窗口,32个(通道)卷积核从1个平面抽取特征得到32个特征平面 68 | b_conv1 = bias_variable([32]) 69 | h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1) # rulu激活函数 70 | h_pool1 = max_pool_2x2(h_conv1) # 池化 71 | h_drop1 = tf.nn.dropout(h_pool1, keep_prob) # dropout防止过拟合 72 | 73 | # 第二层 74 | w_conv2 = weight_variable([3, 3, 32, 64]) 75 | b_conv2 = bias_variable([64]) 76 | h_conv2 = tf.nn.relu(conv2d(h_drop1, w_conv2) + b_conv2) 77 | h_pool2 = max_pool_2x2(h_conv2) 78 | h_drop2 = tf.nn.dropout(h_pool2, keep_prob) 79 | 80 | # 第三层 81 | w_conv3 = weight_variable([3, 3, 64, 64]) 82 | b_conv3 = bias_variable([64]) 83 | h_conv3 = tf.nn.relu(conv2d(h_drop2, w_conv3) + b_conv3) 84 | h_pool3 = max_pool_2x2(h_conv3) 85 | h_drop3 = tf.nn.dropout(h_pool3, keep_prob) 86 | 87 | """ 88 | 原始:60*160图片 第一次卷积后 60*160 第一池化后 30*80 89 | 第二次卷积后 30*80 ,第二次池化后 15*40 90 | 第三次卷积后 15*40 ,第三次池化后 7.5*20 = > 向下取整 7*20 91 | 经过上面操作后得到7*20的平面 92 | """ 93 | 94 | # 全连接层 95 | image_height = int(h_drop3.shape[1]) 96 | image_width = int(h_drop3.shape[2]) 97 | w_fc = weight_variable([image_height*image_width*64, 1024]) # 上一层有64个神经元 全连接层有1024个神经元 98 | b_fc = bias_variable([1024]) 99 | h_drop3_re = tf.reshape(h_drop3, [-1, image_height*image_width*64]) 100 | h_fc = tf.nn.relu(tf.matmul(h_drop3_re, w_fc) + b_fc) 101 | h_drop_fc = tf.nn.dropout(h_fc, keep_prob) 102 | 103 | # 输出层 104 | w_out = weight_variable([1024, len(captcha_list)*captcha_len]) 105 | b_out = bias_variable([len(captcha_list)*captcha_len]) 106 | y_conv = tf.matmul(h_drop_fc, w_out) + b_out 107 | return y_conv 108 | 109 | 110 | def optimize_graph(y, y_conv): 111 | """ 112 | 优化计算图 113 | :param y: 正确值 114 | :param y_conv: 预测值 115 | :return: optimizer 116 | """ 117 | # 交叉熵代价函数计算loss 注意logits输入是在函数内部进行sigmod操作 118 | # sigmod_cross适用于每个类别相互独立但不互斥,如图中可以有字母和数字 119 | # softmax_cross适用于每个类别独立且排斥的情况,如数字和字母不可以同时出现 120 | loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=y_conv)) 121 | # 最小化loss优化 AdaminOptimizer优化 122 | optimizer = tf.train.AdamOptimizer(1e-3).minimize(loss) 123 | return optimizer 124 | 125 | 126 | def accuracy_graph(y, y_conv, width=len(CAPTCHA_LIST), height=CAPTCHA_LEN): 127 | """ 128 | 偏差计算图,正确值和预测值,计算准确度 129 | :param y: 正确值 标签 130 | :param y_conv: 预测值 131 | :param width: 验证码预备字符列表长度 132 | :param height: 验证码的大小,默认为4 133 | :return: 正确率 134 | """ 135 | # 这里区分了大小写 实际上验证码一般不区分大小写,有四个值,不同于手写体识别 136 | # 预测值 137 | predict = tf.reshape(y_conv, [-1, height, width]) # 138 | max_predict_idx = tf.argmax(predict, 2) 139 | # 标签 140 | label = tf.reshape(y, [-1, height, width]) 141 | max_label_idx = tf.argmax(label, 2) 142 | correct_p = tf.equal(max_predict_idx, max_label_idx) # 判断是否相等 143 | accuracy = tf.reduce_mean(tf.cast(correct_p, tf.float32)) 144 | return accuracy 145 | 146 | 147 | def train(height=CAPTCHA_HEIGHT, width=CAPTCHA_WIDTH, y_size=len(CAPTCHA_LIST)*CAPTCHA_LEN): 148 | """ 149 | cnn训练 150 | :param height: 验证码高度 151 | :param width: 验证码宽度 152 | :param y_size: 验证码预备字符列表长度*验证码长度(默认为4) 153 | :return: 154 | """ 155 | # cnn在图像大小是2的倍数时性能最高, 如果图像大小不是2的倍数,可以在图像边缘补无用像素 156 | # 在图像上补2行,下补3行,左补2行,右补2行 157 | # np.pad(image,((2,3),(2,2)), 'constant', constant_values=(255,)) 158 | 159 | acc_rate = 0.95 # 预设模型准确率标准 160 | # 按照图片大小申请占位符 161 | x = tf.placeholder(tf.float32, [None, height * width]) 162 | y = tf.placeholder(tf.float32, [None, y_size]) 163 | # 防止过拟合 训练时启用 测试时不启用 神经元使用率 164 | keep_prob = tf.placeholder(tf.float32) 165 | # cnn模型 166 | y_conv = cnn_graph(x, keep_prob, (height, width)) 167 | # 优化 168 | optimizer = optimize_graph(y, y_conv) 169 | # 计算准确率 170 | accuracy = accuracy_graph(y, y_conv) 171 | # 启动会话.开始训练 172 | saver = tf.train.Saver() 173 | sess = tf.Session() 174 | sess.run(tf.global_variables_initializer()) # 初始化 175 | step = 0 # 步数 176 | while 1: 177 | batch_x, batch_y = get_next_batch(64) 178 | sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, keep_prob: 0.75}) 179 | # 每训练一百次测试一次 180 | if step % 100 == 0: 181 | batch_x_test, batch_y_test = get_next_batch(100) 182 | acc = sess.run(accuracy, feed_dict={x: batch_x_test, y: batch_y_test, keep_prob: 1.0}) 183 | print(datetime.now().strftime('%c'), ' step:', step, ' accuracy:', acc) 184 | # 准确率满足要求,保存模型 185 | if acc > acc_rate: 186 | model_path = "./model/captcha.model" 187 | saver.save(sess, model_path, global_step=step) 188 | acc_rate += 0.01 189 | if acc_rate > 0.99: # 准确率达到99%则退出 190 | break 191 | step += 1 192 | sess.close() 193 | 194 | 195 | if __name__ == '__main__': 196 | train() 197 | 198 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # captcha_check 2 | # author: DYBOY 3 | 4 | ### 项目简介: 5 | 利用 `captcha` 库生成的图形验证码,并对其进行内容识别。首先通过对验证码图片进行一个“`灰度`”处理,使之变为灰度图,灰度图有利于去除杂色,便于提高模型精度,提升训练速度。训练过程中,使用了`三层CNN`,最终的准确率最高可达到`98.75%` 6 | 7 | 8 | ### 运行环境: 9 | - python3.6 10 | - tensorflow 1.10 (运行时,缺少什么就安装对应包 例如安装tensorflow:pip3 install tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple ) 11 | - windows 10 家庭版 12 | 13 | 14 | ### USAGE: 15 | - 训练模型:python3 model_train.py 16 | - 测试模型:python3 model_test.py 17 | 18 | ### 效果: 19 | 20 | [![预测](https://upload-images.jianshu.io/upload_images/6661013-0740ed1f4da0e286.png "预测")](https://upload-images.jianshu.io/upload_images/6661013-0740ed1f4da0e286.png "预测") 21 | 22 | ### 项目介绍文章地址: 23 | - https://blog.dyboy.cn/program/100.html 24 | 25 | 26 | ### 训练过程记录: 27 | 28 | ``` shell 29 | [root@VM_96_17_centos captcha]# /usr/local/bin/python3.6 model_train.py 30 | 2018-11-26 09:29:57.038117: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA 31 | 2018-11-26 09:29:57.408852: W tensorflow/core/framework/allocator.cc:122] Allocation of 41943040 exceeds 10% of system memory. 32 | 2018-11-26 09:29:57.451278: W tensorflow/core/framework/allocator.cc:122] Allocation of 41943040 exceeds 10% of system memory. 33 | 2018-11-26 09:29:57.498523: W tensorflow/core/framework/allocator.cc:122] Allocation of 41943040 exceeds 10% of system memory. 34 | 2018-11-26 09:29:57.525206: W tensorflow/core/framework/allocator.cc:122] Allocation of 41943040 exceeds 10% of system memory. 35 | 2018-11-26 09:29:57.566340: W tensorflow/core/framework/allocator.cc:122] Allocation of 41943040 exceeds 10% of system memory. 36 | Mon Nov 26 09:30:03 2018 step: 0 accuracy: 0.1 37 | Mon Nov 26 09:33:47 2018 step: 100 accuracy: 0.1175 38 | Mon Nov 26 09:37:29 2018 step: 200 accuracy: 0.1 39 | Mon Nov 26 09:41:11 2018 step: 300 accuracy: 0.095 40 | Mon Nov 26 09:44:53 2018 step: 400 accuracy: 0.1 41 | Mon Nov 26 09:48:32 2018 step: 500 accuracy: 0.105 42 | Mon Nov 26 09:52:11 2018 step: 600 accuracy: 0.0575 43 | Mon Nov 26 09:55:50 2018 step: 700 accuracy: 0.09 44 | Mon Nov 26 09:59:30 2018 step: 800 accuracy: 0.105 45 | Mon Nov 26 10:03:10 2018 step: 900 accuracy: 0.085 46 | Mon Nov 26 10:06:50 2018 step: 1000 accuracy: 0.0875 47 | Mon Nov 26 10:10:31 2018 step: 1100 accuracy: 0.09 48 | Mon Nov 26 10:14:11 2018 step: 1200 accuracy: 0.08 49 | Mon Nov 26 10:17:51 2018 step: 1300 accuracy: 0.0825 50 | Mon Nov 26 10:21:31 2018 step: 1400 accuracy: 0.135 51 | Mon Nov 26 10:25:11 2018 step: 1500 accuracy: 0.18 52 | Mon Nov 26 10:28:51 2018 step: 1600 accuracy: 0.31 53 | Mon Nov 26 10:32:31 2018 step: 1700 accuracy: 0.4225 54 | Mon Nov 26 10:36:09 2018 step: 1800 accuracy: 0.4625 55 | Mon Nov 26 10:39:49 2018 step: 1900 accuracy: 0.4925 56 | Mon Nov 26 10:43:28 2018 step: 2000 accuracy: 0.5475 57 | Mon Nov 26 10:47:07 2018 step: 2100 accuracy: 0.58 58 | Mon Nov 26 10:50:46 2018 step: 2200 accuracy: 0.6725 59 | Mon Nov 26 10:54:25 2018 step: 2300 accuracy: 0.69 60 | Mon Nov 26 10:58:06 2018 step: 2400 accuracy: 0.735 61 | Mon Nov 26 11:01:46 2018 step: 2500 accuracy: 0.735 62 | Mon Nov 26 11:05:27 2018 step: 2600 accuracy: 0.745 63 | Mon Nov 26 11:09:07 2018 step: 2700 accuracy: 0.825 64 | Mon Nov 26 11:12:46 2018 step: 2800 accuracy: 0.7675 65 | Mon Nov 26 11:16:26 2018 step: 2900 accuracy: 0.8425 66 | Mon Nov 26 11:20:05 2018 step: 3000 accuracy: 0.825 67 | Mon Nov 26 11:23:43 2018 step: 3100 accuracy: 0.855 68 | Mon Nov 26 11:27:23 2018 step: 3200 accuracy: 0.8425 69 | Mon Nov 26 11:31:02 2018 step: 3300 accuracy: 0.8375 70 | Mon Nov 26 11:34:41 2018 step: 3400 accuracy: 0.8575 71 | Mon Nov 26 11:38:20 2018 step: 3500 accuracy: 0.8475 72 | Mon Nov 26 11:41:59 2018 step: 3600 accuracy: 0.8775 73 | Mon Nov 26 11:45:38 2018 step: 3700 accuracy: 0.8825 74 | Mon Nov 26 11:49:17 2018 step: 3800 accuracy: 0.9025 75 | Mon Nov 26 11:52:57 2018 step: 3900 accuracy: 0.8625 76 | Mon Nov 26 11:56:37 2018 step: 4000 accuracy: 0.92 77 | Mon Nov 26 12:00:17 2018 step: 4100 accuracy: 0.8925 78 | Mon Nov 26 12:03:56 2018 step: 4200 accuracy: 0.9075 79 | Mon Nov 26 12:07:35 2018 step: 4300 accuracy: 0.91 80 | Mon Nov 26 12:11:15 2018 step: 4400 accuracy: 0.92 81 | Mon Nov 26 12:14:54 2018 step: 4500 accuracy: 0.915 82 | Mon Nov 26 12:18:36 2018 step: 4600 accuracy: 0.9275 83 | Mon Nov 26 12:22:16 2018 step: 4700 accuracy: 0.9375 84 | Mon Nov 26 12:25:56 2018 step: 4800 accuracy: 0.905 85 | Mon Nov 26 12:29:36 2018 step: 4900 accuracy: 0.915 86 | Mon Nov 26 12:33:17 2018 step: 5000 accuracy: 0.945 87 | Mon Nov 26 12:36:56 2018 step: 5100 accuracy: 0.9475 88 | Mon Nov 26 12:40:35 2018 step: 5200 accuracy: 0.9375 89 | Mon Nov 26 12:44:15 2018 step: 5300 accuracy: 0.9675 90 | Mon Nov 26 12:47:57 2018 step: 5400 accuracy: 0.945 91 | Mon Nov 26 12:51:37 2018 step: 5500 accuracy: 0.96 92 | Mon Nov 26 12:55:16 2018 step: 5600 accuracy: 0.93 93 | Mon Nov 26 12:58:56 2018 step: 5700 accuracy: 0.9 94 | Mon Nov 26 13:02:36 2018 step: 5800 accuracy: 0.9425 95 | Mon Nov 26 13:06:15 2018 step: 5900 accuracy: 0.9275 96 | Mon Nov 26 13:09:54 2018 step: 6000 accuracy: 0.9225 97 | Mon Nov 26 13:13:34 2018 step: 6100 accuracy: 0.945 98 | Mon Nov 26 13:17:13 2018 step: 6200 accuracy: 0.945 99 | Mon Nov 26 13:20:52 2018 step: 6300 accuracy: 0.9475 100 | Mon Nov 26 13:24:32 2018 step: 6400 accuracy: 0.9675 101 | Mon Nov 26 13:28:13 2018 step: 6500 accuracy: 0.95 102 | Mon Nov 26 13:31:51 2018 step: 6600 accuracy: 0.9375 103 | Mon Nov 26 13:35:30 2018 step: 6700 accuracy: 0.9475 104 | Mon Nov 26 13:39:09 2018 step: 6800 accuracy: 0.95 105 | Mon Nov 26 13:42:49 2018 step: 6900 accuracy: 0.96 106 | Mon Nov 26 13:46:29 2018 step: 7000 accuracy: 0.955 107 | Mon Nov 26 13:50:09 2018 step: 7100 accuracy: 0.9425 108 | Mon Nov 26 13:53:48 2018 step: 7200 accuracy: 0.9625 109 | Mon Nov 26 13:57:27 2018 step: 7300 accuracy: 0.94 110 | Mon Nov 26 14:01:10 2018 step: 7400 accuracy: 0.97 111 | Mon Nov 26 14:04:52 2018 step: 7500 accuracy: 0.9675 112 | Mon Nov 26 14:08:31 2018 step: 7600 accuracy: 0.9575 113 | Mon Nov 26 14:12:11 2018 step: 7700 accuracy: 0.96 114 | Mon Nov 26 14:15:51 2018 step: 7800 accuracy: 0.9425 115 | Mon Nov 26 14:19:31 2018 step: 7900 accuracy: 0.965 116 | Mon Nov 26 14:23:11 2018 step: 8000 accuracy: 0.9725 117 | Mon Nov 26 14:26:51 2018 step: 8100 accuracy: 0.9825 118 | Mon Nov 26 14:30:32 2018 step: 8200 accuracy: 0.975 119 | Mon Nov 26 14:34:11 2018 step: 8300 accuracy: 0.9625 120 | Mon Nov 26 14:37:49 2018 step: 8400 accuracy: 0.9775 121 | Mon Nov 26 14:41:29 2018 step: 8500 accuracy: 0.955 122 | Mon Nov 26 14:45:09 2018 step: 8600 accuracy: 0.9675 123 | Mon Nov 26 14:48:47 2018 step: 8700 accuracy: 0.96 124 | Mon Nov 26 14:52:27 2018 step: 8800 accuracy: 0.9625 125 | Mon Nov 26 14:56:06 2018 step: 8900 accuracy: 0.9525 126 | Mon Nov 26 14:59:45 2018 step: 9000 accuracy: 0.9575 127 | Mon Nov 26 15:03:24 2018 step: 9100 accuracy: 0.9675 128 | Mon Nov 26 15:07:02 2018 step: 9200 accuracy: 0.9725 129 | Mon Nov 26 15:10:41 2018 step: 9300 accuracy: 0.9575 130 | Mon Nov 26 15:14:19 2018 step: 9400 accuracy: 0.97 131 | Mon Nov 26 15:17:57 2018 step: 9500 accuracy: 0.9775 132 | Mon Nov 26 15:21:36 2018 step: 9600 accuracy: 0.9775 133 | Mon Nov 26 15:25:14 2018 step: 9700 accuracy: 0.97 134 | Mon Nov 26 15:28:53 2018 step: 9800 accuracy: 0.98 135 | Mon Nov 26 15:32:32 2018 step: 9900 accuracy: 0.9825 136 | Mon Nov 26 15:36:10 2018 step: 10000 accuracy: 0.9775 137 | Mon Nov 26 15:39:48 2018 step: 10100 accuracy: 0.97 138 | Mon Nov 26 15:43:26 2018 step: 10200 accuracy: 0.9575 139 | Mon Nov 26 15:47:05 2018 step: 10300 accuracy: 0.9625 140 | Mon Nov 26 15:50:42 2018 step: 10400 accuracy: 0.9675 141 | Mon Nov 26 15:54:21 2018 step: 10500 accuracy: 0.9725 142 | Mon Nov 26 15:57:59 2018 step: 10600 accuracy: 0.9825 143 | Mon Nov 26 16:01:39 2018 step: 10700 accuracy: 0.9825 144 | Mon Nov 26 16:05:18 2018 step: 10800 accuracy: 0.985 145 | Mon Nov 26 16:08:57 2018 step: 10900 accuracy: 0.9625 146 | Mon Nov 26 16:12:38 2018 step: 11000 accuracy: 0.965 147 | Mon Nov 26 16:16:18 2018 step: 11100 accuracy: 0.97 148 | Mon Nov 26 16:19:58 2018 step: 11200 accuracy: 0.9875 149 | Mon Nov 26 16:23:37 2018 step: 11300 accuracy: 0.98 150 | Mon Nov 26 16:27:17 2018 step: 11400 accuracy: 0.9625 151 | Mon Nov 26 16:30:58 2018 step: 11500 accuracy: 0.975 152 | Mon Nov 26 16:34:39 2018 step: 11600 accuracy: 0.985 153 | Mon Nov 26 16:38:18 2018 step: 11700 accuracy: 0.9775 154 | Mon Nov 26 16:41:58 2018 step: 11800 accuracy: 0.9825 155 | Mon Nov 26 16:45:38 2018 step: 11900 accuracy: 0.98 156 | Mon Nov 26 16:49:18 2018 step: 12000 accuracy: 0.9825 157 | Mon Nov 26 16:52:57 2018 step: 12100 accuracy: 0.985 158 | Mon Nov 26 16:56:36 2018 step: 12200 accuracy: 0.98 159 | Mon Nov 26 17:00:15 2018 step: 12300 accuracy: 0.9725 160 | Mon Nov 26 17:03:54 2018 step: 12400 accuracy: 0.955 161 | Mon Nov 26 17:07:35 2018 step: 12500 accuracy: 0.97 162 | Mon Nov 26 17:11:14 2018 step: 12600 accuracy: 0.9775 163 | Mon Nov 26 17:14:53 2018 step: 12700 accuracy: 0.985 164 | ... 165 | ``` 166 | --------------------------------------------------------------------------------