├── .gitignore ├── README.md ├── crack_captcha ├── README.MD ├── requirements.txt ├── src │ ├── __init__.py │ ├── config.py │ ├── gen_image.py │ ├── gen_model.py │ └── validate.py └── train.py ├── crack_captcha_3d ├── README.MD └── src │ ├── __init__.py │ ├── config.py │ ├── data │ ├── test │ │ └── 7430_KGEM.jpeg │ ├── train │ │ └── 3570_HCHF.jpeg │ └── validate │ │ └── 4851_DPBO.jpeg │ ├── gen_data.py │ ├── train_model.py │ └── validate.py ├── crack_captcha_rgb ├── README.MD ├── requirements.txt ├── src │ ├── __init__.py │ ├── config.py │ ├── gen_image.py │ ├── gen_model.py │ └── validate.py └── train.py └── mnist └── src └── __init__.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Python template 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *,cover 49 | .hypothesis/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # dotenv 85 | .env 86 | 87 | # virtualenv 88 | .venv 89 | venv/ 90 | ENV/ 91 | 92 | # Spyder project settings 93 | .spyderproject 94 | 95 | # Rope project settings 96 | .ropeproject 97 | ### JetBrains template 98 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 99 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 100 | 101 | # User-specific stuff: 102 | .idea 103 | 104 | # Sensitive or high-churn files: 105 | .idea/**/dataSources/ 106 | .idea/**/dataSources.ids 107 | .idea/**/dataSources.xml 108 | .idea/**/dataSources.local.xml 109 | .idea/**/sqlDataSources.xml 110 | .idea/**/dynamic.xml 111 | .idea/**/uiDesigner.xml 112 | 113 | # Gradle: 114 | .idea/**/gradle.xml 115 | .idea/**/libraries 116 | 117 | # Mongo Explorer plugin: 118 | .idea/**/mongoSettings.xml 119 | 120 | ## File-based project format: 121 | *.iws 122 | 123 | ## Plugin-specific files: 124 | 125 | # IntelliJ 126 | /out/ 127 | 128 | # mpeltonen/sbt-idea plugin 129 | .idea_modules/ 130 | 131 | # JIRA plugin 132 | atlassian-ide-plugin.xml 133 | 134 | # Crashlytics plugin (for Android Studio and IntelliJ) 135 | com_crashlytics_export_strings.xml 136 | crashlytics.properties 137 | crashlytics-build.properties 138 | fabric.properties 139 | 140 | 141 | creak_captcha_3d/src/data/ 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tensorflow-demos 2 | all kinds of demos of tensorflow code 3 | 4 | # environment 5 | * python: 2.7.12 6 | * system: ubuntu 14.04 7 | * tensorflow: tensorflow-gpu==1.0.1 (if you do not has the gpu ,just use the cpu version) 8 | 9 | # demo list 10 | * [x] crack_captcha -- gen image to crack the captcha. 11 | * [x] crack_captcha_rgb -- since the captcha will in rgb mode ,so just train a model to crack it. 12 | * [x] crack_captcha_3d -- the data source comes from the sogou wexin capthca. 13 | * [ ] mnist 14 | * [ ] cat_vs_dog 15 | 16 | 17 | 18 | ## crack_captcha 19 | * install the requirements 20 | * `python gen_model.py` it will start to train the model 21 | * after finish train model ,`python validate.py` will do validate the image result 22 | 23 | ## crack_captcha_rgb 24 | * install the requirements 25 | * `python gen_model.py` it will start to train the model 26 | * after finish train model ,`python validate.py` will do validate the image result 27 | 28 | ## crack_captcha_3d 29 | 30 | * install the requirements 31 | * `python train_model.py` it will start to train the model 32 | * after finish train model ,`python validate.py` will do validate the image result 33 | 34 | -------------------------------------------------------------------------------- /crack_captcha/README.MD: -------------------------------------------------------------------------------- 1 | # demo to show how to crack the captcha images 2 | 3 | * first please make sure you already install lib as the requirements list. 4 | * just run the `train.py` script ,i will train and save the model 5 | -------------------------------------------------------------------------------- /crack_captcha/requirements.txt: -------------------------------------------------------------------------------- 1 | Pillow==3.4.2 2 | tensorflow==1.0.1 3 | captcha==0.2.2 -------------------------------------------------------------------------------- /crack_captcha/src/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- -------------------------------------------------------------------------------- /crack_captcha/src/config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | NUMBER = '0123456789' 3 | CHAR_SMALL = 'abcdefghijklmnopqrstuvwxyz' 4 | CHAR_BIG = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 5 | 6 | MAX_CAPTCHA = 6 # 测试1位的训练准确率 7 | VALIDATE_STRING = NUMBER + CHAR_SMALL # + CHAR_BIG 8 | CHAR_SET_LEN = len(VALIDATE_STRING) 9 | 10 | IMAGE_HEIGHT = 60 11 | IMAGE_WIDTH = 160 12 | FONT_SIZE = 35 13 | 14 | MAX_ACCURACY = 0.9 15 | -------------------------------------------------------------------------------- /crack_captcha/src/gen_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from captcha.image import ImageCaptcha 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | # from config import NUMBER, CHAR_SMALL, CHAR_BIG, MAX_CAPTCHA, CHAR_SET_LEN, FONT_SIZE 7 | import config 8 | from PIL import Image 9 | import random 10 | 11 | char_dict = {} 12 | number_dict = {} 13 | 14 | 15 | # 生成随机的指定的字符串 16 | def __gen_random_captcha_text(char_set=config.VALIDATE_STRING, size=None): 17 | # char_set must be a str 18 | if not char_set or not isinstance(char_set, str): 19 | raise ValueError('get the empty char_set') 20 | 21 | # 随机 22 | result = list(char_set) 23 | random.shuffle(result) 24 | 25 | # 返回字符串 26 | return ''.join(result[0:size]) 27 | 28 | 29 | def gen_random_captcha_image(): 30 | image = ImageCaptcha(width=config.IMAGE_WIDTH, height=config.IMAGE_HEIGHT,font_sizes=[config.FONT_SIZE]) 31 | 32 | text = __gen_random_captcha_text(size=config.MAX_CAPTCHA) 33 | captcha = image.generate(text) 34 | captcha_image = Image.open(captcha) 35 | captcha_source = np.array(captcha_image) 36 | return text, captcha_source 37 | 38 | 39 | # always gen the require image height ,and width image 40 | def gen_require_captcha_image(): 41 | while 1: 42 | text, image = gen_random_captcha_image() 43 | if image.shape == (config.IMAGE_HEIGHT, config.IMAGE_WIDTH, 3): 44 | return text, image 45 | 46 | 47 | # 把彩色图像转为灰度图像(色彩对识别验证码没有什么用,对于抽取特征也没啥用) 48 | def convert2gray(img): 49 | if len(img.shape) > 2: 50 | gray = np.mean(img, -1) 51 | # 上面的转法较快,正规转法如下 52 | # r, g, b = img[:,:,0], img[:,:,1], img[:,:,2] 53 | # gray = 0.2989 * r + 0.5870 * g + 0.1140 * b 54 | return gray 55 | else: 56 | return img 57 | 58 | 59 | # prepare the char to index 60 | def prepare_char_dict(): 61 | if char_dict: 62 | return char_dict 63 | 64 | for index, val in enumerate(config.VALIDATE_STRING): 65 | char_dict[val] = index 66 | 67 | return char_dict 68 | 69 | 70 | def prepare_number_dict(): 71 | if number_dict: 72 | return number_dict 73 | 74 | for index, val in enumerate(config.VALIDATE_STRING): 75 | number_dict[index] = val 76 | 77 | return number_dict 78 | 79 | 80 | def text_to_array(text): 81 | char_dict_tmp = prepare_char_dict() 82 | 83 | arr = np.zeros(config.MAX_CAPTCHA * config.CHAR_SET_LEN, dtype=np.int8) 84 | for i, p in enumerate(text): 85 | key_index = char_dict_tmp[p] 86 | index = i * config.CHAR_SET_LEN + key_index 87 | arr[index] = 1 88 | 89 | return arr 90 | 91 | 92 | def array_to_text(arr): 93 | num_dict_tmp = prepare_number_dict() 94 | text = [] 95 | char_pos = arr.nonzero()[0] 96 | for index, val in enumerate(char_pos): 97 | if index == 0: 98 | index = 1 99 | key_index = val % (index * config.CHAR_SET_LEN) 100 | text.append(num_dict_tmp[key_index]) 101 | return ''.join(text) 102 | 103 | def show_image_text(): 104 | text, image = gen_random_captcha_image() 105 | 106 | f = plt.figure() 107 | ax = f.add_subplot(111) 108 | ax.text(0.1, 0.9, text, ha='center', va='center', transform=ax.transAxes) 109 | plt.imshow(image) 110 | 111 | plt.show() 112 | 113 | # 114 | if __name__ == '__main__': 115 | # __do_image_text() 116 | # arr = text_to_array('0142') 117 | # print '===========' 118 | # print array_to_text(arr) 119 | show_image_text() 120 | -------------------------------------------------------------------------------- /crack_captcha/src/gen_model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import tensorflow as tf 3 | import numpy as np 4 | from gen_image import text_to_array 5 | from config import MAX_CAPTCHA, CHAR_SET_LEN, IMAGE_HEIGHT, IMAGE_WIDTH, MAX_ACCURACY 6 | from gen_image import gen_require_captcha_image 7 | 8 | x_input = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT * IMAGE_WIDTH]) 9 | y_input = tf.placeholder(tf.float32, [None, CHAR_SET_LEN * MAX_CAPTCHA]) 10 | keep_prob = tf.placeholder(tf.float32) 11 | 12 | 13 | # 把彩色图像转为灰度图像(色彩对识别验证码没有什么用,对于抽取特征也没啥用) 14 | def convert2gray(img): 15 | if len(img.shape) > 2: 16 | gray = np.mean(img, -1) 17 | return gray 18 | else: 19 | return img 20 | 21 | 22 | def __weight_variable(shape, stddev=0.01): 23 | initial = tf.random_normal(shape, stddev=stddev) 24 | return tf.Variable(initial) 25 | 26 | 27 | def __bias_variable(shape, stddev=0.1): 28 | initial = tf.random_normal(shape=shape, stddev=stddev) 29 | return tf.Variable(initial) 30 | 31 | 32 | def __conv2d(x, w): 33 | # strides 代表移动的平长 34 | return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') 35 | 36 | 37 | def __max_pool_2x2(x): 38 | return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') 39 | 40 | 41 | # 100个一个批次 42 | def gen_next_batch(batch_size=100): 43 | batch_x = np.zeros([batch_size, IMAGE_HEIGHT * IMAGE_WIDTH]) 44 | batch_y = np.zeros([batch_size, MAX_CAPTCHA * CHAR_SET_LEN]) 45 | 46 | for i in xrange(batch_size): 47 | text, image = gen_require_captcha_image() 48 | 49 | # 转成灰度图片,因为颜色对于提取字符形状是没有意义的 50 | image = convert2gray(image) 51 | 52 | batch_x[i, :] = image.flatten() / 255 53 | batch_y[i, :] = text_to_array(text) 54 | 55 | return batch_x, batch_y 56 | 57 | 58 | def create_layer(x_input, keep_prob): 59 | x_image = tf.reshape(x_input, shape=[-1, IMAGE_WIDTH, IMAGE_HEIGHT, 1]) 60 | 61 | # 定义第1个卷积层 62 | w_c1 = __weight_variable([5, 5, 1, 32], stddev=0.1) # 3x3 第一层32个卷积核 采用黑白色 63 | b_c1 = __bias_variable([32], stddev=0.1) 64 | h_c1 = tf.nn.relu(tf.nn.bias_add(__conv2d(x_image, w_c1), b_c1)) # 定义第一个卷积层 65 | h_pool1 = __max_pool_2x2(h_c1) # 定义第一个池化层 66 | # h_pool1 = tf.nn.dropout(h_pool1, keep_prob) 67 | 68 | # 定义第2个卷积层 69 | w_c2 = __weight_variable([5, 5, 32, 64], stddev=0.1) 70 | b_c2 = __bias_variable([64], stddev=0.1) 71 | h_c2 = tf.nn.relu(tf.nn.bias_add(__conv2d(h_pool1, w_c2), b_c2)) 72 | h_pool2 = __max_pool_2x2(h_c2) 73 | # h_pool2 = tf.nn.dropout(h_pool2, keep_prob) 74 | 75 | # 定义第3个卷积层 76 | w_c3 = __weight_variable([5, 5, 64, 64], stddev=0.1) 77 | b_c3 = __bias_variable([64], stddev=0.1) 78 | h_c3 = tf.nn.relu(tf.nn.bias_add(__conv2d(h_pool2, w_c3), b_c3)) 79 | h_pool3 = __max_pool_2x2(h_c3) 80 | # h_pool3 = tf.nn.dropout(h_pool3, keep_prob) 81 | 82 | # 3层池化之后 width 144 / 8 = 18 83 | # height 64 / 8 = 8 84 | 85 | # 全链接层1 86 | w_fc1 = __weight_variable([20 * 8 * 64, 1024], stddev=0.1) 87 | b_fc1 = __bias_variable([1024]) 88 | h_pool3_flat = tf.reshape(h_pool3, [-1, w_fc1.get_shape().as_list()[0]]) 89 | h_fc1 = tf.nn.relu(tf.add(tf.matmul(h_pool3_flat, w_fc1), b_fc1)) 90 | # drop out 内容0 91 | h_fc1_dropout = tf.nn.dropout(h_fc1, keep_prob) 92 | 93 | # 全链接层2 94 | w_output = __weight_variable([1024, MAX_CAPTCHA * CHAR_SET_LEN], stddev=0.1) 95 | b_output = __bias_variable([MAX_CAPTCHA * CHAR_SET_LEN]) 96 | y_output = tf.add(tf.matmul(h_fc1_dropout, w_output), b_output) 97 | 98 | return y_output 99 | 100 | 101 | def create_loss(layer, y_input): 102 | loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_input, logits=layer)) 103 | return loss 104 | 105 | 106 | def create_accuracy(output, y_input): 107 | predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]) 108 | max_idx_p = tf.argmax(predict, 2) 109 | max_idx_l = tf.argmax(tf.reshape(y_input, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2) 110 | correct_pred = tf.equal(max_idx_p, max_idx_l) 111 | accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) 112 | return accuracy 113 | 114 | 115 | def train(): 116 | # create the layer and loss 117 | layer_output = create_layer(x_input, keep_prob) 118 | loss = create_loss(layer_output, y_input) 119 | accuracy = create_accuracy(layer_output, y_input) 120 | 121 | train_step = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) 122 | # save model 123 | saver = tf.train.Saver() 124 | 125 | with tf.Session() as sess: 126 | 127 | tf.global_variables_initializer().run() 128 | acc = 0.0 129 | i = 0 130 | 131 | while acc < MAX_ACCURACY: 132 | i = i + 1 133 | batch_x, batch_y = gen_next_batch(64) 134 | _, _loss = sess.run([train_step, loss], 135 | feed_dict={x_input: batch_x, y_input: batch_y, keep_prob: 0.75}) 136 | 137 | print(i, _loss) 138 | 139 | # 每100 step计算一次准确率 140 | if i % 50 == 0: 141 | batch_x_test, batch_y_test = gen_next_batch(100) 142 | acc = sess.run(accuracy, feed_dict={x_input: batch_x_test, y_input: batch_y_test, keep_prob: 1.}) 143 | print('step is %s' % i, 'and accy is %s' % acc) 144 | # 如果准确率大于50%,保存模型,完成训练 145 | if acc > MAX_ACCURACY: 146 | print('current acc > %s ,stop now' % MAX_ACCURACY) 147 | saver.save(sess, "break.model", global_step=i) 148 | break 149 | 150 | 151 | if __name__ == '__main__': 152 | train() 153 | -------------------------------------------------------------------------------- /crack_captcha/src/validate.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from gen_model import create_layer 3 | import tensorflow as tf 4 | import config 5 | import numpy as np 6 | from gen_image import convert2gray, gen_random_captcha_image, array_to_text 7 | 8 | 9 | def crack_captcha(captcha_image): 10 | x_input = tf.placeholder(tf.float32, [None, config.IMAGE_HEIGHT * config.IMAGE_WIDTH]) 11 | keep_prob = tf.placeholder(tf.float32) # dropout 12 | output = create_layer(x_input, keep_prob) 13 | 14 | saver = tf.train.Saver() 15 | with tf.Session() as sess: 16 | saver.restore(sess, tf.train.latest_checkpoint('.')) 17 | predict = tf.argmax(tf.reshape(output, [-1, config.MAX_CAPTCHA, config.CHAR_SET_LEN]), 2) 18 | text_list = sess.run(predict, feed_dict={x_input: [captcha_image], keep_prob: 1}) 19 | 20 | text = text_list[0].tolist() 21 | vector = np.zeros(config.MAX_CAPTCHA * config.CHAR_SET_LEN) 22 | i = 0 23 | for n in text: 24 | vector[i * config.CHAR_SET_LEN + n] = 1 25 | i += 1 26 | 27 | return array_to_text(vector) 28 | 29 | 30 | def validate_image(): 31 | text, image = gen_random_captcha_image() 32 | image = convert2gray(image) 33 | 34 | # map the value to 0 -> 1 ,this will really affect the loss function update ,always remember the value should 35 | # suit to the loss learning rate 36 | # refer https://www.youtube.com/watch?v=pU5TG_X7b6E&index=6&list=PLwY2GJhAPWRcZxxVFpNhhfivuW0kX15yG 21:00 37 | image = image.flatten() / 255 38 | predict_text = crack_captcha(image) 39 | print("label is : {} <----> predict is : {}".format(text, predict_text)) 40 | 41 | 42 | if __name__ == '__main__': 43 | validate_image() 44 | -------------------------------------------------------------------------------- /crack_captcha/train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from src.gen_model import train 3 | 4 | if __name__ == '__main__': 5 | train() 6 | -------------------------------------------------------------------------------- /crack_captcha_3d/README.MD: -------------------------------------------------------------------------------- 1 | # Folder 2 | * test 3 | * train 4 | * validate 5 | 6 | test folder for test data ,train for train data for model , when you finish train data ,you can use the validate folder to validate your image 7 | 8 | ## How to use 9 | * download the captcha image from the url of :http://mp.weixin.qq.com/mp/verifycode?cert=1492745324932.2913 -- it has changed rule now ,please pay attention 10 | * label the image as demo of data folder image 11 | * if you want the high accuracy ,please label as much as you can ,it will really increase the accuracy 12 | * update the `config.py` relay on your situation 13 | * just run the `train_model.py` script ,it will start to train -------------------------------------------------------------------------------- /crack_captcha_3d/src/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- -------------------------------------------------------------------------------- /crack_captcha_3d/src/config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | NUMBER = '0123456789' 4 | CHAR_SMALL = 'abcdefghijklmnopqrstuvwxyz' 5 | CHAR_BIG = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 6 | 7 | MAX_CAPTCHA = 4 # 测试1位的训练准确率 8 | VALIDATE_STRING = CHAR_BIG 9 | CHAR_SET_LEN = len(VALIDATE_STRING) 10 | 11 | IMAGE_HEIGHT = 53 12 | IMAGE_WIDTH = 130 13 | 14 | MAX_ACCURACY = 0.5 15 | 16 | TRAIN_DATA_JSON = '/Users/brucedone/Data/weixin/228_run.json' 17 | TRAIN_IMG_PATH = '/Users/brucedone/Data/yanzenma_20w/train_captcha' 18 | 19 | VALIDATE_DATA_JSON = '/Users/brucedone/Data/weixin/226_run.json' 20 | VALIDATE_IMG_PATH = '/Users/brucedone/Data/yanzenma_20w/test_captcha' 21 | 22 | TRAIN_IMG_DST_PATH = '/data/weixin_captcha/train' 23 | VALIDATE_IMG_DST_PATH = '/data/weixin_captcha/test' 24 | 25 | REAL_TRAIN_PATH = '/data/weixin_captcha/train' 26 | REAL_TEST_PATH = '/data/weixin_captcha/test' 27 | -------------------------------------------------------------------------------- /crack_captcha_3d/src/data/test/7430_KGEM.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BruceDone/tensorflow-demos/03c7968746734f08091b4c953f0cd67eeb660a4a/crack_captcha_3d/src/data/test/7430_KGEM.jpeg -------------------------------------------------------------------------------- /crack_captcha_3d/src/data/train/3570_HCHF.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BruceDone/tensorflow-demos/03c7968746734f08091b4c953f0cd67eeb660a4a/crack_captcha_3d/src/data/train/3570_HCHF.jpeg -------------------------------------------------------------------------------- /crack_captcha_3d/src/data/validate/4851_DPBO.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BruceDone/tensorflow-demos/03c7968746734f08091b4c953f0cd67eeb660a4a/crack_captcha_3d/src/data/validate/4851_DPBO.jpeg -------------------------------------------------------------------------------- /crack_captcha_3d/src/gen_data.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import re 3 | import tensorflow as tf 4 | import config 5 | from PIL import Image 6 | import numpy as np 7 | import json 8 | from sys import path 9 | from shutil import copyfile 10 | from glob import glob 11 | from random import shuffle 12 | 13 | char_dict = {} 14 | number_dict = {} 15 | 16 | current_index = 0 17 | current_test_index = 0 18 | 19 | total_img = [] 20 | total_test_img = [] 21 | 22 | 23 | # if the folder has the img 24 | def move_img(): 25 | i = 0 26 | with open(config.VALIDATE_DATA_JSON, 'r') as train: 27 | for p in train.readlines(): 28 | i = i + 1 29 | hit = json.loads(p) 30 | read_img_and_move(hit, i) 31 | 32 | print 'done' 33 | 34 | 35 | def read_img_and_move(hit, index): 36 | image_name = hit['hit_input'].split('/')[-1] 37 | image_val = hit['hit_result']['num'].upper() 38 | full_file_name = '/'.join([config.VALIDATE_IMG_PATH, image_name]) 39 | # print full_file_name, image_val 40 | 41 | dst_file = '/'.join([config.VALIDATE_IMG_DST_PATH, str(index) + '_' + image_val + '.jpeg']) 42 | 43 | print 'handle the file of %s' % dst_file 44 | copyfile(full_file_name, dst_file) 45 | 46 | 47 | def read_one_img(file_path): 48 | img = Image.open(file_path) 49 | img = img.convert("L") 50 | 51 | source = np.array(img) 52 | 53 | if source.shape != (53, 130): 54 | print 'find one shape is not right %s' % file_path 55 | return None, None 56 | 57 | img_data = source.flatten() / 255.0 58 | file_name = file_path.split('/')[-1] 59 | file_name = re.search('_(.{4})[.]', file_name) 60 | 61 | if not file_name: 62 | print 'since the result is None :%s' % file_path 63 | return None, None 64 | 65 | text = file_name.group(1) 66 | if '0' in text: 67 | text = text.replace('0', 'O') 68 | 69 | return text_to_array(text), img_data 70 | 71 | 72 | # prepare the char to index 73 | def prepare_char_dict(): 74 | if char_dict: 75 | return char_dict 76 | 77 | for index, val in enumerate(config.VALIDATE_STRING): 78 | char_dict[val] = index 79 | 80 | return char_dict 81 | 82 | 83 | def prepare_number_dict(): 84 | if number_dict: 85 | return number_dict 86 | 87 | for index, val in enumerate(config.VALIDATE_STRING): 88 | number_dict[index] = val 89 | 90 | return number_dict 91 | 92 | 93 | def text_to_array(text): 94 | char_dict_tmp = prepare_char_dict() 95 | 96 | arr = np.zeros(config.MAX_CAPTCHA * config.CHAR_SET_LEN, dtype=np.int8) 97 | for i, p in enumerate(text): 98 | key_index = char_dict_tmp[p] 99 | index = i * config.CHAR_SET_LEN + key_index 100 | arr[index] = 1 101 | 102 | return arr 103 | 104 | 105 | def array_to_text(arr): 106 | num_dict_tmp = prepare_number_dict() 107 | text = [] 108 | char_pos = arr.nonzero()[0] 109 | for index, val in enumerate(char_pos): 110 | if index == 0: 111 | index = 1 112 | key_index = val % (index * config.CHAR_SET_LEN) 113 | text.append(num_dict_tmp[key_index]) 114 | return ''.join(text) 115 | 116 | 117 | def read_train_folder(): 118 | res = [] 119 | 120 | train_path = config.REAL_TRAIN_PATH + '/*.jpeg' 121 | for img in glob(train_path): 122 | res.append(img) 123 | 124 | print 'read once ' 125 | shuffle(res) 126 | 127 | global total_img 128 | total_img = res 129 | 130 | 131 | def read_test_folder(): 132 | global total_test_img 133 | 134 | test_path = config.REAL_TEST_PATH + '/*.jpeg' 135 | if total_test_img: 136 | print 'already read one,please check it ' 137 | return 138 | 139 | for img in glob(test_path): 140 | total_test_img.append(img) 141 | 142 | print 'read once with test folder' 143 | 144 | 145 | def gen_train_batch(batch_size): 146 | global current_index 147 | 148 | # prepare the total img 149 | if not total_img: 150 | read_train_folder() 151 | 152 | start = current_index * batch_size 153 | end = (current_index + 1) * batch_size 154 | 155 | batch_x = np.zeros([batch_size, config.IMAGE_WIDTH * config.IMAGE_HEIGHT]) 156 | batch_y = np.zeros([batch_size, config.MAX_CAPTCHA * config.CHAR_SET_LEN]) 157 | 158 | i = 0 159 | for img in total_img[start:end]: 160 | label, image = read_one_img(img) 161 | 162 | if image is None: 163 | continue 164 | 165 | batch_y[i, :] = label 166 | batch_x[i, :] = image 167 | i = i + 1 168 | 169 | current_index = current_index + 1 170 | return batch_x, batch_y 171 | 172 | 173 | def gen_test_batch(batch_size): 174 | global current_test_index 175 | 176 | if not total_test_img: 177 | read_test_folder() 178 | 179 | start = current_test_index * batch_size 180 | end = (current_test_index + 1) * batch_size 181 | 182 | batch_x = np.zeros([batch_size, config.IMAGE_WIDTH * config.IMAGE_HEIGHT]) 183 | batch_y = np.zeros([batch_size, config.MAX_CAPTCHA * config.CHAR_SET_LEN]) 184 | 185 | i = 0 186 | for img in total_test_img[start:end]: 187 | label, image = read_one_img(img) 188 | 189 | if image is None: 190 | continue 191 | 192 | batch_x[i, :] = image 193 | batch_y[i, :] = label 194 | i = i + 1 195 | 196 | current_test_index = current_test_index + 1 197 | return batch_x, batch_y 198 | 199 | 200 | if __name__ == '__main__': 201 | # print gen_train_batch(64) 202 | # print gen_train_batch(64) 203 | print gen_test_batch(32) 204 | # print gen_test_batch(32) 205 | # print gen_test_batch(32) 206 | # print current_index 207 | print current_test_index 208 | -------------------------------------------------------------------------------- /crack_captcha_3d/src/train_model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import tensorflow as tf 3 | from gen_data import text_to_array 4 | from config import MAX_CAPTCHA, CHAR_SET_LEN, IMAGE_HEIGHT, IMAGE_WIDTH, MAX_ACCURACY 5 | from gen_data import gen_train_batch, gen_test_batch 6 | 7 | x_input = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT * IMAGE_WIDTH]) # use the gray 8 | y_input = tf.placeholder(tf.float32, [None, CHAR_SET_LEN * MAX_CAPTCHA]) 9 | keep_prob = tf.placeholder(tf.float32) 10 | 11 | 12 | def __weight_variable(shape, stddev=0.01): 13 | initial = tf.random_normal(shape, stddev=stddev) 14 | return tf.Variable(initial) 15 | 16 | 17 | def __bias_variable(shape, stddev=0.1): 18 | initial = tf.random_normal(shape=shape, stddev=stddev) 19 | return tf.Variable(initial) 20 | 21 | 22 | def __conv2d(x, w): 23 | # strides 代表移动的平长 24 | return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') 25 | 26 | 27 | def __max_pool_2x2(x): 28 | return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') 29 | 30 | 31 | def create_layer(x_input, keep_prob): 32 | x_image = tf.reshape(x_input, shape=[-1, IMAGE_WIDTH, IMAGE_HEIGHT, 1]) 33 | 34 | w_stddev = 0.1 35 | 36 | # 定义第1个卷积层 37 | w_c1 = __weight_variable([7, 7, 1, 32], stddev=w_stddev) # 3x3 第一层32个卷积核 采用黑白色 38 | b_c1 = __bias_variable([32], stddev=0.1) 39 | h_c1 = tf.nn.relu(tf.nn.bias_add(__conv2d(x_image, w_c1), b_c1)) # 定义第一个卷积层 40 | h_pool1 = __max_pool_2x2(h_c1) # 定义第一个池化层 41 | 42 | # 定义第2个卷积层 43 | w_c2 = __weight_variable([7, 7, 32, 64], stddev=w_stddev) 44 | b_c2 = __bias_variable([64], stddev=0.1) 45 | h_c2 = tf.nn.relu(tf.nn.bias_add(__conv2d(h_pool1, w_c2), b_c2)) 46 | h_pool2 = __max_pool_2x2(h_c2) 47 | 48 | # 定义第3个卷积层 49 | w_c3 = __weight_variable([7, 7, 64, 128], stddev=w_stddev) 50 | b_c3 = __bias_variable([128], stddev=0.1) 51 | h_c3 = tf.nn.relu(tf.nn.bias_add(__conv2d(h_pool2, w_c3), b_c3)) 52 | h_pool3 = __max_pool_2x2(h_c3) 53 | 54 | # print h_pool4 55 | w_c4 = __weight_variable([7, 7, 128, 128], stddev=w_stddev) 56 | b_c4 = __bias_variable([128], stddev=0.1) 57 | h_c4 = tf.nn.relu(tf.nn.bias_add(__conv2d(h_pool3, w_c4), b_c4)) 58 | 59 | # 全链接层1 60 | w_fc1 = __weight_variable([7 * 17 * 128, 2048], stddev=w_stddev) 61 | b_fc1 = __bias_variable([2048]) 62 | 63 | h_pool3_flat = tf.reshape(h_c4, [-1, w_fc1.get_shape().as_list()[0]]) 64 | h_fc1 = tf.nn.relu(tf.add(tf.matmul(h_pool3_flat, w_fc1), b_fc1)) 65 | # drop out 内容0 66 | h_fc1_dropout = tf.nn.dropout(h_fc1, keep_prob) 67 | 68 | # 全链接层2 69 | w_output = __weight_variable([2048, MAX_CAPTCHA * CHAR_SET_LEN], stddev=w_stddev) 70 | b_output = __bias_variable([MAX_CAPTCHA * CHAR_SET_LEN]) 71 | y_output = tf.add(tf.matmul(h_fc1_dropout, w_output), b_output) 72 | 73 | return y_output 74 | 75 | 76 | def create_loss(layer, y_input): 77 | loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_input, logits=layer)) 78 | return loss 79 | 80 | 81 | def create_accuracy(output, y_input): 82 | predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]) 83 | 84 | print 'predict', predict 85 | max_idx_p = tf.argmax(predict, 2) 86 | 87 | print 'max_idx_p', max_idx_p 88 | max_idx_l = tf.argmax(tf.reshape(y_input, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2) 89 | 90 | print 'max_idx_p', max_idx_l 91 | correct_pred = tf.equal(max_idx_p, max_idx_l) 92 | accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) 93 | return accuracy 94 | 95 | 96 | def train(): 97 | # create the layer and loss 98 | layer_output = create_layer(x_input, keep_prob) 99 | loss = create_loss(layer_output, y_input) 100 | accuracy = create_accuracy(layer_output, y_input) 101 | 102 | train_step = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) 103 | # save model 104 | saver = tf.train.Saver() 105 | 106 | with tf.Session() as sess: 107 | 108 | tf.global_variables_initializer().run() 109 | acc = 0.0 110 | i = 0 111 | 112 | while True: 113 | i = i + 1 114 | batch_x, batch_y = gen_train_batch(64) 115 | _, _loss = sess.run([train_step, loss], 116 | feed_dict={x_input: batch_x, y_input: batch_y, keep_prob: 0.75}) 117 | 118 | print(i, _loss) 119 | 120 | # 每100 step计算一次准确率 121 | if i % 50 == 0: 122 | batch_x_test, batch_y_test = gen_test_batch(100) 123 | acc = sess.run(accuracy, feed_dict={x_input: batch_x_test, y_input: batch_y_test, keep_prob: 1.}) 124 | print('step is %s' % i, 'and accy is %s' % acc) 125 | # 如果准确率大于50%,保存模型,完成训练 126 | if acc > MAX_ACCURACY or i == 650: 127 | print('current acc > %s ,stop now' % MAX_ACCURACY) 128 | saver.save(sess, "weixin.model", global_step=i) 129 | break 130 | 131 | 132 | if __name__ == '__main__': 133 | train() 134 | -------------------------------------------------------------------------------- /crack_captcha_3d/src/validate.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from train_model import create_layer 3 | import tensorflow as tf 4 | import config 5 | import numpy as np 6 | from gen_data import array_to_text, read_one_img 7 | 8 | 9 | def crack_captcha(captcha_image): 10 | x_input = tf.placeholder(tf.float32, [None, config.IMAGE_HEIGHT * config.IMAGE_WIDTH]) 11 | keep_prob = tf.placeholder(tf.float32) # dropout 12 | output = create_layer(x_input, keep_prob) 13 | 14 | saver = tf.train.Saver() 15 | with tf.Session() as sess: 16 | saver.restore(sess, tf.train.latest_checkpoint('.')) 17 | predict = tf.argmax(tf.reshape(output, [-1, config.MAX_CAPTCHA, config.CHAR_SET_LEN]), 2) 18 | 19 | print 'hello:',predict 20 | text_list = sess.run(predict, feed_dict={x_input: [captcha_image], keep_prob: 1}) 21 | print text_list 22 | 23 | text = text_list[0].tolist() 24 | vector = np.zeros(config.MAX_CAPTCHA * config.CHAR_SET_LEN) 25 | i = 0 26 | for n in text: 27 | vector[i * config.CHAR_SET_LEN + n] = 1 28 | i += 1 29 | 30 | return array_to_text(vector) 31 | 32 | 33 | def validate_image(): 34 | text, image = read_one_img('/Users/brucedone/Data/weixin_captcha/test/3571_RCBE.jpeg') 35 | 36 | image = image.flatten() / 255.0 37 | predict_text = crack_captcha(image) 38 | print("label is : {} <----> predict is : {}".format(array_to_text(text), predict_text)) 39 | 40 | 41 | if __name__ == '__main__': 42 | validate_image() 43 | -------------------------------------------------------------------------------- /crack_captcha_rgb/README.MD: -------------------------------------------------------------------------------- 1 | # demo to show how to crack the captcha images -- rgb images 2 | 3 | * first please make sure you already install lib as the requirements list. 4 | * just run the `train.py` script ,i will train and save the model 5 | -------------------------------------------------------------------------------- /crack_captcha_rgb/requirements.txt: -------------------------------------------------------------------------------- 1 | Pillow==3.4.2 2 | tensorflow==1.0.1 3 | captcha==0.2.2 -------------------------------------------------------------------------------- /crack_captcha_rgb/src/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- -------------------------------------------------------------------------------- /crack_captcha_rgb/src/config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | NUMBER = '0123456789' 3 | CHAR_SMALL = 'abcdefghijklmnopqrstuvwxyz' 4 | CHAR_BIG = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 5 | 6 | MAX_CAPTCHA = 4 # 测试1位的训练准确率 7 | VALIDATE_STRING = NUMBER # + CHAR_SMALL #+ CHAR_BIG 8 | CHAR_SET_LEN = len(VALIDATE_STRING) 9 | 10 | IMAGE_HEIGHT = 60 11 | IMAGE_WIDTH = 160 12 | FONT_SIZE = 35 13 | 14 | MAX_ACCURACY = 0.5 15 | -------------------------------------------------------------------------------- /crack_captcha_rgb/src/gen_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from captcha.image import ImageCaptcha 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | # from config import NUMBER, CHAR_SMALL, CHAR_BIG, MAX_CAPTCHA, CHAR_SET_LEN, FONT_SIZE 7 | import config 8 | from PIL import Image 9 | import random 10 | 11 | char_dict = {} 12 | number_dict = {} 13 | 14 | 15 | # 生成随机的指定的字符串 16 | def __gen_random_captcha_text(char_set=config.VALIDATE_STRING, size=None): 17 | # char_set must be a str 18 | if not char_set or not isinstance(char_set, str): 19 | raise ValueError('get the empty char_set') 20 | 21 | # 随机 22 | result = list(char_set) 23 | random.shuffle(result) 24 | 25 | # 返回字符串 26 | return ''.join(result[0:size]) 27 | 28 | 29 | def gen_random_captcha_image(): 30 | image = ImageCaptcha(width=config.IMAGE_WIDTH, height=config.IMAGE_HEIGHT, font_sizes=[config.FONT_SIZE]) 31 | 32 | text = __gen_random_captcha_text(size=config.MAX_CAPTCHA) 33 | captcha = image.generate(text) 34 | captcha_image = Image.open(captcha) 35 | captcha_source = np.array(captcha_image) 36 | return text, captcha_source 37 | 38 | 39 | # always gen the require image height ,and width image 40 | def gen_require_captcha_image(): 41 | while 1: 42 | text, image = gen_random_captcha_image() 43 | if image.shape == (config.IMAGE_HEIGHT, config.IMAGE_WIDTH, 3): 44 | return text, image 45 | 46 | 47 | # prepare the char to index 48 | def prepare_char_dict(): 49 | if char_dict: 50 | return char_dict 51 | 52 | for index, val in enumerate(config.VALIDATE_STRING): 53 | char_dict[val] = index 54 | 55 | return char_dict 56 | 57 | 58 | def prepare_number_dict(): 59 | if number_dict: 60 | return number_dict 61 | 62 | for index, val in enumerate(config.VALIDATE_STRING): 63 | number_dict[index] = val 64 | 65 | return number_dict 66 | 67 | 68 | def text_to_array(text): 69 | char_dict_tmp = prepare_char_dict() 70 | 71 | arr = np.zeros(config.MAX_CAPTCHA * config.CHAR_SET_LEN, dtype=np.int8) 72 | for i, p in enumerate(text): 73 | key_index = char_dict_tmp[p] 74 | index = i * config.CHAR_SET_LEN + key_index 75 | arr[index] = 1 76 | 77 | return arr 78 | 79 | 80 | def array_to_text(arr): 81 | num_dict_tmp = prepare_number_dict() 82 | text = [] 83 | char_pos = arr.nonzero()[0] 84 | for index, val in enumerate(char_pos): 85 | if index == 0: 86 | index = 1 87 | key_index = val % (index * config.CHAR_SET_LEN) 88 | text.append(num_dict_tmp[key_index]) 89 | return ''.join(text) 90 | 91 | 92 | def show_image_text(): 93 | text, image = gen_random_captcha_image() 94 | 95 | f = plt.figure() 96 | ax = f.add_subplot(111) 97 | ax.text(0.1, 0.9, text, ha='center', va='center', transform=ax.transAxes) 98 | plt.imshow(image) 99 | 100 | plt.show() 101 | 102 | 103 | # 104 | if __name__ == '__main__': 105 | # __do_image_text() 106 | # arr = text_to_array('0142') 107 | # print '===========' 108 | # print array_to_text(arr) 109 | show_image_text() 110 | -------------------------------------------------------------------------------- /crack_captcha_rgb/src/gen_model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import tensorflow as tf 3 | import numpy as np 4 | from gen_image import text_to_array 5 | from config import MAX_CAPTCHA, CHAR_SET_LEN, IMAGE_HEIGHT, IMAGE_WIDTH, MAX_ACCURACY 6 | from gen_image import gen_require_captcha_image 7 | 8 | x_input = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT * IMAGE_WIDTH * 3]) # using the rgb image 9 | y_input = tf.placeholder(tf.float32, [None, CHAR_SET_LEN * MAX_CAPTCHA]) 10 | keep_prob = tf.placeholder(tf.float32) 11 | 12 | 13 | def __weight_variable(shape, stddev=0.01): 14 | initial = tf.random_normal(shape, stddev=stddev) 15 | return tf.Variable(initial) 16 | 17 | 18 | def __bias_variable(shape, stddev=0.1): 19 | initial = tf.random_normal(shape=shape, stddev=stddev) 20 | return tf.Variable(initial) 21 | 22 | 23 | def __conv2d(x, w): 24 | # strides 代表移动的平长 25 | return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') 26 | 27 | 28 | def __max_pool_2x2(x): 29 | return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') 30 | 31 | 32 | # 100个一个批次 33 | def gen_next_batch(batch_size=100): 34 | batch_x = np.zeros([batch_size, IMAGE_HEIGHT * IMAGE_WIDTH * 3]) 35 | batch_y = np.zeros([batch_size, MAX_CAPTCHA * CHAR_SET_LEN]) 36 | 37 | for i in xrange(batch_size): 38 | text, image = gen_require_captcha_image() 39 | batch_x[i, :] = image.flatten() / 255.0 40 | batch_y[i, :] = text_to_array(text) 41 | 42 | return batch_x, batch_y 43 | 44 | 45 | def create_layer(x_input, keep_prob): 46 | x_image = tf.reshape(x_input, shape=[-1, IMAGE_WIDTH, IMAGE_HEIGHT, 3]) 47 | 48 | # 定义第1个卷积层 49 | w_c1 = __weight_variable([5, 5, 3, 32], stddev=0.1) # 3x3 第一层32个卷积核 采用黑白色 50 | b_c1 = __bias_variable([32], stddev=0.1) 51 | h_c1 = tf.nn.relu(tf.nn.bias_add(__conv2d(x_image, w_c1), b_c1)) # 定义第一个卷积层 52 | h_pool1 = __max_pool_2x2(h_c1) # 定义第一个池化层 53 | # h_pool1 = tf.nn.dropout(h_pool1, keep_prob) 54 | 55 | # 定义第2个卷积层 56 | w_c2 = __weight_variable([5, 5, 32, 64], stddev=0.1) 57 | b_c2 = __bias_variable([64], stddev=0.1) 58 | h_c2 = tf.nn.relu(tf.nn.bias_add(__conv2d(h_pool1, w_c2), b_c2)) 59 | h_pool2 = __max_pool_2x2(h_c2) 60 | # h_pool2 = tf.nn.dropout(h_pool2, keep_prob) 61 | 62 | # 定义第3个卷积层 63 | w_c3 = __weight_variable([5, 5, 64, 64], stddev=0.1) 64 | b_c3 = __bias_variable([64], stddev=0.1) 65 | h_c3 = tf.nn.relu(tf.nn.bias_add(__conv2d(h_pool2, w_c3), b_c3)) 66 | h_pool3 = __max_pool_2x2(h_c3) 67 | # h_pool3 = tf.nn.dropout(h_pool3, keep_prob) 68 | 69 | # 3层池化之后 width 144 / 8 = 18 70 | # height 64 / 8 = 8 71 | 72 | # 全链接层1 73 | w_fc1 = __weight_variable([20 * 8 * 64, 1024], stddev=0.1) 74 | b_fc1 = __bias_variable([1024]) 75 | h_pool3_flat = tf.reshape(h_pool3, [-1, w_fc1.get_shape().as_list()[0]]) 76 | h_fc1 = tf.nn.relu(tf.add(tf.matmul(h_pool3_flat, w_fc1), b_fc1)) 77 | # drop out 内容0 78 | h_fc1_dropout = tf.nn.dropout(h_fc1, keep_prob) 79 | 80 | # 全链接层2 81 | w_output = __weight_variable([1024, MAX_CAPTCHA * CHAR_SET_LEN], stddev=0.1) 82 | b_output = __bias_variable([MAX_CAPTCHA * CHAR_SET_LEN]) 83 | y_output = tf.add(tf.matmul(h_fc1_dropout, w_output), b_output) 84 | 85 | return y_output 86 | 87 | 88 | def create_loss(layer, y_input): 89 | loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_input, logits=layer)) 90 | return loss 91 | 92 | 93 | def create_accuracy(output, y_input): 94 | predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]) 95 | max_idx_p = tf.argmax(predict, 2) 96 | max_idx_l = tf.argmax(tf.reshape(y_input, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2) 97 | correct_pred = tf.equal(max_idx_p, max_idx_l) 98 | accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) 99 | return accuracy 100 | 101 | 102 | def train(): 103 | # create the layer and loss 104 | layer_output = create_layer(x_input, keep_prob) 105 | loss = create_loss(layer_output, y_input) 106 | accuracy = create_accuracy(layer_output, y_input) 107 | 108 | train_step = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) 109 | # save model 110 | saver = tf.train.Saver() 111 | 112 | with tf.Session() as sess: 113 | 114 | tf.global_variables_initializer().run() 115 | acc = 0.0 116 | i = 0 117 | 118 | while True: 119 | i = i + 1 120 | batch_x, batch_y = gen_next_batch(64) 121 | _, _loss = sess.run([train_step, loss], 122 | feed_dict={x_input: batch_x, y_input: batch_y, keep_prob: 0.75}) 123 | 124 | print(i, _loss) 125 | 126 | # 每100 step计算一次准确率 127 | if i % 50 == 0: 128 | batch_x_test, batch_y_test = gen_next_batch(100) 129 | acc = sess.run(accuracy, feed_dict={x_input: batch_x_test, y_input: batch_y_test, keep_prob: 1.}) 130 | print('step is %s' % i, 'and accy is %s' % acc) 131 | # 如果准确率大于50%,保存模型,完成训练 132 | if acc > MAX_ACCURACY: 133 | print('current acc > %s ,stop now' % MAX_ACCURACY) 134 | saver.save(sess, "break.model", global_step=i) 135 | break 136 | 137 | 138 | if __name__ == '__main__': 139 | train() 140 | -------------------------------------------------------------------------------- /crack_captcha_rgb/src/validate.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from gen_model import create_layer 3 | import tensorflow as tf 4 | import config 5 | import numpy as np 6 | from gen_image import gen_random_captcha_image, array_to_text 7 | 8 | 9 | def crack_captcha(captcha_image): 10 | x_input = tf.placeholder(tf.float32, [None, config.IMAGE_HEIGHT * config.IMAGE_WIDTH * 3]) 11 | keep_prob = tf.placeholder(tf.float32) # dropout 12 | output = create_layer(x_input, keep_prob) 13 | 14 | saver = tf.train.Saver() 15 | with tf.Session() as sess: 16 | saver.restore(sess, tf.train.latest_checkpoint('.')) 17 | predict = tf.argmax(tf.reshape(output, [-1, config.MAX_CAPTCHA, config.CHAR_SET_LEN]), 2) 18 | text_list = sess.run(predict, feed_dict={x_input: [captcha_image], keep_prob: 1}) 19 | 20 | text = text_list[0].tolist() 21 | vector = np.zeros(config.MAX_CAPTCHA * config.CHAR_SET_LEN) 22 | i = 0 23 | for n in text: 24 | vector[i * config.CHAR_SET_LEN + n] = 1 25 | i += 1 26 | 27 | return array_to_text(vector) 28 | 29 | 30 | def validate_image(): 31 | text, image = gen_random_captcha_image() 32 | # image = convert2gray(image) 33 | 34 | # map the value to 0 -> 1 ,this will really affect the loss function update ,always remember the value should 35 | # suit to the loss learning rate 36 | # refer https://www.youtube.com/watch?v=pU5TG_X7b6E&index=6&list=PLwY2GJhAPWRcZxxVFpNhhfivuW0kX15yG 21:00 37 | image = image.flatten() / 255.0 38 | predict_text = crack_captcha(image) 39 | print("label is : {} <----> predict is : {}".format(text, predict_text)) 40 | 41 | 42 | if __name__ == '__main__': 43 | validate_image() 44 | -------------------------------------------------------------------------------- /crack_captcha_rgb/train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from src.gen_model import train 3 | 4 | if __name__ == '__main__': 5 | train() 6 | -------------------------------------------------------------------------------- /mnist/src/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- --------------------------------------------------------------------------------