tensorflow实现验证码识别(三)

搭积木

数据都准备好了之后,就剩下定义网络结构了,定义网络结构说白了就是搭积木。我这边的积木是酱紫:
在这里插入图片描述
可以看出来我搭了4层卷积+1层FC+1层softmax的辣鸡积木,搭积木的代码是酱紫:

#推理
    def __inference(self, images, keep_prob):
        images = tf.reshape(images, (-1, utility.IMG_HEIGHT, utility.IMG_WIDTH, 1))
        # 用于tensorboard中可视化原图
        tf.summary.image('src_img', images, 5)

        with tf.variable_scope('conv1') as scope:
            kernel = self.__weight_variable('weights_1', shape=[5, 5, 1, 64])
            biases = self.__bias_variable('biases_1', [64])
            pre_activation = tf.nn.bias_add(self.__conv2d(images, kernel), biases)
            conv1 = tf.nn.relu(pre_activation, name=scope.name)
            tf.summary.histogram('conv1/weights_1', kernel)
            tf.summary.histogram('conv1/biases_1', biases)

            kernel_2 = self.__weight_variable('weights_2', shape=[5, 5, 64, 64])
            biases_2 = self.__bias_variable('biases_2', [64])
            pre_activation = tf.nn.bias_add(self.__conv2d(conv1, kernel_2), biases_2)
            conv2 = tf.nn.relu(pre_activation, name=scope.name)
            tf.summary.histogram('conv1/weights_2', kernel_2)
            tf.summary.histogram('conv1/biases_2', biases_2)


            # 用于可视化第一层卷积后的图像
            conv1_for_show1 = tf.reshape(conv1[:, :, :, 1], (-1, 60, 160, 1))
            conv1_for_show2 = tf.reshape(conv1[:, :, :, 2], (-1, 60, 160, 1))
            conv1_for_show3 = tf.reshape(conv1[:, :, :, 3], (-1, 60, 160, 1))
            tf.summary.image('conv1_for_show1', conv1_for_show1, 5)
            tf.summary.image('conv1_for_show2', conv1_for_show2, 5)
            tf.summary.image('conv1_for_show3', conv1_for_show3, 5)

            # max pooling
            pool1 = self.__max_pool_2x2(conv1, name='pool1')



        with tf.variable_scope('conv2') as scope:
            kernel = self.__weight_variable('weights_1', shape=[5, 5, 64, 64])
            biases = self.__bias_variable('biases_1', [64])
            pre_activation = tf.nn.bias_add(self.__conv2d(pool1, kernel), biases)
            conv2 = tf.nn.relu(pre_activation, name=scope.name)
            tf.summary.histogram('conv2/weights_1', kernel)
            tf.summary.histogram('conv2/biases_1', biases)

            kernel_2 = self.__weight_variable('weights_2', shape=[5, 5, 64, 64])
            biases_2 = self.__bias_variable('biases_2', [64])
            pre_activation = tf.nn.bias_add(self.__conv2d(conv2, kernel_2), biases_2)
            conv2 = tf.nn.relu(pre_activation, name=scope.name)
            tf.summary.histogram('conv2/weights_2', kernel_2)
            tf.summary.histogram('conv2/biases_2', biases_2)


            # 用于可视化第二层卷积后的图像
            conv2_for_show1 = tf.reshape(conv2[:, :, :, 1], (-1, 30, 80, 1))
            conv2_for_show2 = tf.reshape(conv2[:, :, :, 2], (-1, 30, 80, 1))
            conv2_for_show3 = tf.reshape(conv2[:, :, :, 3], (-1, 30, 80, 1))
            tf.summary.image('conv2_for_show1', conv2_for_show1, 5)
            tf.summary.image('conv2_for_show2', conv2_for_show2, 5)
            tf.summary.image('conv2_for_show3', conv2_for_show3, 5)

            # max pooling
            pool2 = self.__max_pool_2x2(conv2, name='pool2')



        with tf.variable_scope('conv3') as scope:
            kernel = self.__weight_variable('weights', shape=[3, 3, 64, 64])
            biases = self.__bias_variable('biases', [64])
            pre_activation = tf.nn.bias_add(self.__conv2d(pool2, kernel), biases)
            conv3 = tf.nn.relu(pre_activation, name=scope.name)
            tf.summary.histogram('conv3/weights', kernel)
            tf.summary.histogram('conv3/biases', biases)

            kernel_2 = self.__weight_variable('weights_2', shape=[3, 3, 64, 64])
            biases_2 = self.__bias_variable('biases_2', [64])
            pre_activation = tf.nn.bias_add(self.__conv2d(conv3, kernel_2), biases_2)
            conv3 = tf.nn.relu(pre_activation, name=scope.name)
            tf.summary.histogram('conv3/weights_2', kernel_2)
            tf.summary.histogram('conv3/biases_2', biases_2)

            conv3_for_show1 = tf.reshape(conv3[:, :, :, 1], (-1, 15, 40, 1))
            conv3_for_show2 = tf.reshape(conv3[:, :, :, 2], (-1, 15, 40, 1))
            conv3_for_show3 = tf.reshape(conv3[:, :, :, 3], (-1, 15, 40, 1))
            tf.summary.image('conv3_for_show1', conv3_for_show1, 5)
            tf.summary.image('conv3_for_show2', conv3_for_show2, 5)
            tf.summary.image('conv3_for_show3', conv3_for_show3, 5)

            pool3 = self.__max_pool_2x2(conv3, name='pool3')


        with tf.variable_scope('conv4') as scope:
            kernel = self.__weight_variable('weights', shape=[3, 3, 64, 64])
            biases = self.__bias_variable('biases', [64])
            pre_activation = tf.nn.bias_add(self.__conv2d(pool3, kernel), biases)
            conv4 = tf.nn.relu(pre_activation, name=scope.name)
            tf.summary.histogram('conv4/weights', kernel)
            tf.summary.histogram('conv4/biases', biases)

            conv4_for_show1 = tf.reshape(conv4[:, :, :, 1], (-1, 8, 20, 1))
            conv4_for_show2 = tf.reshape(conv4[:, :, :, 2], (-1, 8, 20, 1))
            conv4_for_show3 = tf.reshape(conv4[:, :, :, 3], (-1, 8, 20, 1))
            tf.summary.image('conv4_for_show1', conv4_for_show1, 5)
            tf.summary.image('conv4_for_show2', conv4_for_show2, 5)
            tf.summary.image('conv4_for_show3', conv4_for_show3, 5)

            pool4 = self.__max_pool_2x2(conv4, name='pool4')



        #全连接层
        with tf.variable_scope('local1') as scope:
            reshape = tf.reshape(pool4, [images.get_shape()[0].value, -1])
            weights = self.__weight_variable('weights', shape=[4*10*64, 1024])
            biases = self.__bias_variable('biases', [1024])
            local1 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name=scope.name)
            tf.summary.histogram('local1/weights', kernel)
            tf.summary.histogram('local1/biases', biases)

            local1_drop = tf.nn.dropout(local1, keep_prob)
            tf.summary.tensor_summary('local1/dropout', local1_drop)

        #输出层
        with tf.variable_scope('softmax_linear') as scope:
            weights = self.__weight_variable('weights', shape=[1024, self.__CHARS_NUM * self.__CLASSES_NUM])
            biases = self.__bias_variable('biases', [self.__CHARS_NUM * self.__CLASSES_NUM])
            result = tf.add(tf.matmul(local1_drop, weights), biases, name=scope.name)

        reshaped_result = tf.reshape(result, [-1, self.__CHARS_NUM, self.__CLASSES_NUM])
        return reshaped_result

训练

第二篇已经说过数据是dump成tfrecords,然后用队列来读取tfrecords,所以训练的时候肯定是要运行队列,让队列从tfrecords里不断的拿数据。但是如果单线程来拿数据的话肯定不是个好主意,所以应该是主线程创建一个专门往队列里塞数据的子线程。主线程在需要的时候只要从队列里拿数据训练就行了。这些线程间同步的操作tf已经封装好了,tf.train.Coordinator()能实例化一个线程协调器,tf.train.start_queue_runners()会把graph里的所有队列run起来,并返回管理队列的对应的子线程。所以代码时酱紫:

        with tf.Session() as sess:
            tf.global_variables_initializer().run()
            tf.local_variables_initializer().run()
            writer = tf.summary.FileWriter(utility.LOG_DIR, sess.graph)
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess=sess, coord=coord)
            try:
                step = 0
                while not coord.should_stop():
                    start_time = time.time()
                    _, loss_value, performance, summaries = sess.run([train_op, loss, accuracy, summary_op])
                    duration = time.time() - start_time
                    if step % 10 == 0:
                        print('>> 已训练%d个批次: loss = %.2f (%.3f sec), 该批正确数量 = %d' % (step, loss_value, duration, performance))
                    if step % 100 == 0:
                        writer.add_summary(summaries, step)
                        saver.save(sess, utility.MODEL_DIR, global_step=step)
                    step += 1
            except tf.errors.OutOfRangeError:
                print('训练结束')
                saver.save(sess, utility.MODEL_DIR, global_step=step)
                coord.request_stop()
            finally:
                coord.request_stop()
            coord.join(threads)


demo的完整代码在:https://github.com/aolingwen/fuck_verifycode
代码写的比较搓,欢迎各位大佬指正。如果对你有帮助,还望fork或star一把,谢谢!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
验证码识别是一个常见的图像识别任务,使用 TensorFlow 2 进行验证码识别可以分为以下几个步骤: 1. 数据预处理:将验证码图片转换为灰度图像,并将像素值归一化到 [0,1] 范围内。 2. 数据增强:对于每个验证码,进行随机旋转、平移、缩放和噪声添加等数据增强操作,以扩充数据集。 3. 搭建模型:使用 TensorFlow 2 中的 Keras API 搭建卷积神经网络模型,可以使用卷积层、池化层、全连接层等。 4. 模型训练:使用训练数据集对模型进行训练,可以使用交叉熵损失函数和优化器进行训练。 5. 模型评估:使用测试数据集对模型进行评估,可以计算准确率、召回率、F1 值等指标。 6. 模型预测:使用训练好的模型对新的验证码进行预测,可以输出验证码的字符序列。 以下是一个简单的验证码识别模型的代码示例: ```python import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers # 数据预处理 def preprocess(image): image = tf.image.rgb_to_grayscale(image) # 转换为灰度图像 image = tf.image.convert_image_dtype(image, tf.float32) # 归一化到 [0,1] return image # 数据增强 def augment(image, label): image = tf.image.random_brightness(image, max_delta=0.1) # 随机调整亮度 image = tf.image.random_contrast(image, lower=0.5, upper=1.5) # 随机调整对比度 image = tf.image.random_flip_left_right(image) # 随机左右翻转 image = tf.image.random_flip_up_down(image) # 随机上下翻转 image = tf.image.rot90(image, tf.random_uniform(shape=[], minval=0, maxval=4, dtype=tf.int32)) # 随机旋转 image = tf.image.random_crop(image, size=[28, 28, 1]) # 随机裁剪 return image, label # 加载数据集 (train_images, train_labels), (test_images, test_labels) = keras.datasets.mnist.load_data() train_images = preprocess(train_images) test_images = preprocess(test_images) # 构建模型 model = keras.Sequential([ layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)), layers.MaxPooling2D((2, 2)), layers.Conv2D(64, (3, 3), activation='relu'), layers.MaxPooling2D((2, 2)), layers.Flatten(), layers.Dense(128, activation='relu'), layers.Dense(10, activation='softmax') ]) # 编译模型 model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # 训练模型 train_dataset = tf.data.Dataset.from_tensor_slices((train_images, train_labels)) train_dataset = train_dataset.map(augment).shuffle(10000).batch(32) test_dataset = tf.data.Dataset.from_tensor_slices((test_images, test_labels)) test_dataset = test_dataset.batch(32) model.fit(train_dataset, epochs=10, validation_data=test_dataset) # 评估模型 model.evaluate(test_dataset) # 预测新的验证码 image = tf.io.read_file('captcha.png') image = tf.image.decode_png(image, channels=3) image = preprocess(image) image = tf.expand_dims(image, axis=0) predictions = model.predict(image) print(predictions) ``` 这里使用的是 MNIST 数据集进行训练,但是可以将验证码数据集替换掉。同时,需要根据验证码的具体情况,调整模型的参数和数据增强方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

alw_123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值