CNN to LSTM识别验证码并显示

import tensorflow as tf
import numpy as np
from matplotlib import image
import matplotlib.pyplot as plt
import os

batch_size = 100
H = 60
W = 120
C = 3

class Sample:
    def __init__(self):
        self.x = []
        self.y = []
    def to_one_hot(self,y):
        y = y.split('.')[0]
        z = np.zeros([4,10])
        for i in range(4):
            z[i][int(y[i])] = 1
        return z
    def get_batch(self,n):
        self.x = []
        self.y = []
        f = []
        file = []
        for path in os.listdir('yzm'):
            f.append('yzm/' + path)  # 将路径全部加载过来
            file.append(path)#将文件名加载过来
        for i in range(n):
            rand = np.random.randint(0,len(f))
            img = image.imread(f[rand])
            self.x.append(img)
            self.y.append(self.to_one_hot(file[rand]))
        return self.x,self.y

class Net:
    def __init__(self):
        self.x = tf.placeholder(shape=[batch_size,H,W,C],dtype=tf.float32)
        self.y = tf.placeholder(shape=[batch_size,4,10],dtype=tf.float32)
        self.encoder = Encode()
        self.decoder = Decode()
    def forward(self):
        x = self.encoder.forward(self.x)
        self.output = self.decoder.forward(x)
    def backward(self):
        self.loss = tf.reduce_mean((self.output-self.y)**2)
        self.opt = tf.train.AdamOptimizer().minimize(self.loss)

class Encode:
    def __init__(self):
        self.conv1_w = tf.Variable(tf.random_normal(shape=[5,5,3,6],dtype=tf.float32,stddev=0.1))
        self.conv1_b = tf.Variable(tf.zeros([6]))
        self.conv2_w = tf.Variable(tf.random_normal(shape=[5, 5, 6, 16], dtype=tf.float32, stddev=0.1))
        self.conv2_b = tf.Variable(tf.zeros([16]))
        self.w = tf.Variable(tf.random_normal(shape=[12*27*16,batch_size+H],dtype=tf.float32,stddev=0.1))
        self.b = tf.Variable(tf.zeros([batch_size+H]))
    def forward(self,x):
        self.conv1 = tf.nn.relu(tf.nn.conv2d(x,self.conv1_w,strides=[1,1,1,1],padding='VALID')+self.conv1_b)#56*116*6
        self.pool1 = tf.nn.relu(tf.nn.max_pool(self.conv1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='VALID'))#28*58*6
        self.conv2 = tf.nn.relu(tf.nn.conv2d(self.pool1,self.conv2_w,strides=[1,1,1,1],padding='VALID')+self.conv2_b)#24*54*16
        self.pool2 = tf.nn.relu(tf.nn.max_pool(self.conv2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='VALID'))#12*27*16
        self.flat = tf.reshape(self.pool2,[-1,12*27*16])
        return tf.nn.relu(tf.matmul(self.flat,self.w)+self.b)


class Decode:
    def __init__(self):
        self.w = tf.Variable(tf.random_normal(shape=[batch_size+H,10],dtype=tf.float32,stddev=tf.sqrt(1/10)))
        self.b = tf.Variable(tf.zeros([10]))
    def forward(self,x):
        y = tf.expand_dims(x,axis=1)
        y1 = tf.tile(y,[1,4,1])
        cell = tf.contrib.rnn.BasicLSTMCell(batch_size+H)
        init_state = cell.zero_state(batch_size,dtype=tf.float32)
        output,final_state = tf.nn.dynamic_rnn(cell,y1,initial_state=init_state,time_major=False)
        output = tf.reshape(output,[batch_size*4,batch_size+H])
        y2 = tf.nn.softmax(tf.matmul(output,self.w)+self.b)
        self.output = tf.reshape(y2,[batch_size,4,10])
        return self.output


if __name__ == '__main__':
    sample = Sample()
    net = Net()
    net.forward()
    net.backward()
    init = tf.global_variables_initializer()
    with tf.Session() as sess:
        sess.run(init)
        for i in range(100):
            x,y = sample.get_batch(batch_size)
            loss,opt = sess.run([net.loss,net.opt],feed_dict={net.x:x,net.y:y})
            print(loss)
        x,y = sample.get_batch(batch_size)
        output = sess.run(net.output,feed_dict={net.x:x})
        lable = []
        for l in output:
            Y = ''
            for number in l:
                Y += str(np.argmax(number))
            lable.append(Y)
        for i in range(batch_size):
            plt.imshow(x[i])
            plt.text(30,-10,lable[i],fontsize=24)
            plt.pause(1)
            plt.clf()

猜你喜欢

转载自blog.csdn.net/weixin_38241876/article/details/88758922