Tensorflow 直接对于图片进行3通道卷积

June 4, 2018, 10:22 a.m.

read: 1061

每张图的信息如下大小 218 * 82

0x00

需要预测的图片如下:

实际上是3个通道(RGB,有些图片会存在4个通道 RGBA, 包含透明度A),那就是 218 x 82 x 3

0x01

很多教程都建议把图片转化成灰度图片,把三个通道合并成一个通道进行卷积,在我的训练中发现,图片不进行转化,直接对三通道卷积并且不需要进行转置这样训练的效果更好,集中表现在收敛速度特别快。在训练以上集合的时候,在BATCH_SIZE等于64的时候,往往一千步以内就能收敛完成。(我猜可能这个留下的信息会更多,适合卷积)
给出训练代码如下:

import tensorflow as tf
import numpy as np
from PIL import Image
import os
import random

train_data_dir = r'C:\Users\HUPENG\Desktop\check_code_crack\check_code\train'
test_data_dir = r''

train_file_name_list = os.listdir(train_data_dir)

def gen_train_data(batch_size=32):
    selected_train_file_name_list = random.sample(train_file_name_list, batch_size)
    x_data = []
    y_data = []
    for selected_train_file_name in selected_train_file_name_list:
        captcha_image = Image.open(train_data_dir + "/" + selected_train_file_name)
        captcha_image_np = np.array(captcha_image)
        x_data.append(captcha_image_np)
        y_data.append(np.array(list(selected_train_file_name.split('.')[0])).astype(np.int32))
    x_data = np.array(x_data)
    y_data = np.array(y_data)
    return x_data, y_data

X = tf.placeholder(tf.float32, name="input")
Y = tf.placeholder(tf.int32)
keep_prob = tf.placeholder(tf.float32)
y_one_hot = tf.one_hot(Y, 10, 1, 0)
y_one_hot = tf.cast(y_one_hot, tf.float32)
# keep_prob = 1.0
def net(w_alpha=0.01, b_alpha=0.1):
    x_reshape = tf.reshape(X, (-1, 218, 82, 3))
    w_c1 = tf.Variable(w_alpha * tf.random_normal([3, 3, 3, 16]))
    b_c1 = tf.Variable(b_alpha * tf.random_normal([16]))
    conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x_reshape, w_c1, strides=[1, 1, 1, 1], padding='SAME'), b_c1))
    conv1 = tf.nn.max_pool(conv1, ksize=[1, 4, 4, 1], strides=[1, 2, 2, 1], padding='SAME')
    conv1 = tf.nn.dropout(conv1, keep_prob)

    w_c2 = tf.Variable(w_alpha * tf.random_normal([3, 3, 16, 16]))
    b_c2 = tf.Variable(b_alpha * tf.random_normal([16]))
    conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding='SAME'), b_c2))
    conv2 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    conv2 = tf.nn.dropout(conv2, keep_prob)

    w_c3 = tf.Variable(w_alpha * tf.random_normal([3, 3, 16, 16]))
    b_c3 = tf.Variable(b_alpha * tf.random_normal([16]))
    conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding='SAME'), b_c3))
    conv3 = tf.nn.max_pool(conv3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    conv3 = tf.nn.dropout(conv3, keep_prob)

    # Fully connected layer
    # 随机生成权重
    w_d = tf.Variable(w_alpha * tf.random_normal([28 * 11 * 16, 1024]))
    # 随机生成偏置
    b_d = tf.Variable(b_alpha * tf.random_normal([1024]))
    dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]])
    dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d))

    w_out = tf.Variable(w_alpha * tf.random_normal([1024, 5 * 10]))
    b_out = tf.Variable(b_alpha * tf.random_normal([5 * 10]))
    out = tf.add(tf.matmul(dense, w_out), b_out)
    out = tf.reshape(out, (-1, 5, 10))

    # out = tf.nn.softmax(out)
    return out
cnn = net()
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=cnn, labels=y_one_hot))
optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)

def train():
    saver = tf.train.Saver()
    with tf.Session() as sess:
        step = 0
        tf.global_variables_initializer().run()
        while True:
            x_data, y_data = gen_train_data(64)
            x_data = np.reshape(x_data, (-1))
            loss_, cnn_, y_one_hot_, optimizer_ = sess.run([loss, cnn, y_one_hot, optimizer],
                                                           feed_dict={Y: y_data, X: x_data, keep_prob: 0.75})
            print(loss_)
            if loss_ < 0.001:
                saver.save(sess, "./crack_capcha.model", global_step=step)
                print("save model successful!")
                break
            step += 1

if __name__=='__main__':
    train()
    print("ok")

0x02

一些细节:
验证码是5位数字,此处并不是直接预测5个数字,(我没试过直接预测5个数字的,有兴趣的读者可以尝试下,在评论区留下训练情况,一起交流下)。
在把所有的数字进行了one-hot encoding再扔进去训练的。

实际上one-hot之后网络的输出 需要softmax之后效果会更好,但是在这里进过softmax之后收敛速度不行。
还有最后一点,预测出来的值需要arg_max之后才能用 。arg max之前的值跟label one hot 之后的值相差很大,应该是和loss表达式关系比较大,此处用的交叉熵,应该和上一点softmax的问题存在一定的联系。

把上述的代码的

tf.nn.sigmoid_cross_entropy_with_logits

改成

tf.nn.softmax_cross_entropy_with_logits

问题就没有了~




Tensorflow 与 PyTorch 的 LSTM的权值排布差异

Tensorflow: # i = input_gate, j = new_input, f = forget_gate, o = output_gate i, j, f, o = array_o…

班级主页管理系统

文章标题:班级主页管理系统文章内容:班级主页管理系统项目地址在文章中 技术参数:前台:html + js + css后台:python3 + django 2.0.3数据库:sqlite3(免安装,…

此站点由 ASP.NETIIS 驱动 | © 2018-2023 hupeng.me. All Rights Reserved.