Neural network identification codes Discuz

Nanjing eastern corner of the old door

Recently I tried their own projects online identification code verification code, which is a small project, see the following links:

https://cuijiahua.com/blog/2018/01/dl_5.html

Data also spent 60,000 Discuz code of upload. The author is to create a class that encapsulates all of the variables and functions, I looked after his own code to try to achieve this without class network.

The authors say they can train to more than 90% accuracy. But after I read his code findings, the authors is trained to test data, namely the training set and test set is the same .

I think the test set should not be involved in the training process, for example, we do mnist handwritten numeral recognition when the training set and test set is certainly not the same.

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=False)

Extracting /tmp/data/train-images-idx3-ubyte.gz
Extracting /tmp/data/train-labels-idx1-ubyte.gz
Extracting /tmp/data/t10k-images-idx3-ubyte.gz
Extracting /tmp/data/t10k-labels-idx1-ubyte.gz

So I own in the process of implementation, the data set taken after disrupting 10000 as the test set, is not involved in the training, the rest of the 50000 code as the training set.

Training process and found that only the learning rate is set to 0.001 when, loss will go down, too, loss will be stuck at 0.07; secondly, my training accuracy only to a maximum of about 50%, but I use the training data to save test the model, certainly achieved 90% accuracy, precision, ie authors see. But this model does not have a generalization , it is only 50% accuracy on the test set not seen.

At the same time this code is also the problem: when the calculation accuracy, a in FIG. 4 codes has two error, the correct rate is 50% instead of 0. When the one in FIG. 4 codes identify an error, that code identification it should fail. So the accuracy is really considerable moisture.

So to consider solutions. First, I tried to cut the learning rate, found 50% never or would not increase.

Then I was in the original three-layer convolution layer, another layer of convolution layer. However, this did not have much to enhance accuracy.

Then I added a layer of fully connected layers, expect to fit a little better, but this makes me into trouble.

My loss in the value of the cards 0.07, regardless of my learning rate is 0.1 or 0.00001. Even iteration a million times as well. This time of testing accuracy ?????? only 3%.

I do not know what the problem is but do not know how to improve.

It made me feel that no one take me, just how uncomfortable; but also a deeper experience of theoretical knowledge how important it is (of course I always knew).

Attach my own code, they can communicate with each other. Data can be downloaded at the link at the top of the article, the author compression good.

The following is a theoretical training :( python3 and python2 script should be able to run. I used to write 2)
training I used the learning rate decay, had wanted to discover the basic training does not give me the chance to use over-fitting dropout results so training plus does not make sense.

from __future__ import print_function, division, absolute_import
import tensorflow as tf
import os
import cv2
import matplotlib.pyplot as plt 
import random
import numpy as np
from optparse import OptionParser

path = 'Discuz/' #存放数据的路径
imgs = os.listdir(path) #以列表形式读取所有图片名称
random.shuffle(imgs) #打乱
max_steps = 1000000 #最大迭代步数
save_path = 'model4cnn-1fcn' #保存模型的路径,会自动生成
dropout = 1 #没用到

trainnum = 50000 #定义训练集和测试集的大小
testnum = 10000

traindatas = imgs[:trainnum] #取出训练集和测试集及其标签
trainlabels = list(map(lambda x: x.split('.')[0],traindatas))

testdatas = imgs[trainnum:]
testlabels = list(map(lambda x: x.split('.')[0],testdatas))

#定义取数据集的指针
train_ptr = 0
test_ptr = 0

def next_batch(batch=100, train_flag=True):
    global train_ptr
    global test_ptr
    batch_x = np.zeros([batch,30*100])
    batch_y = np.zeros([batch, 4*63])

    if train_flag == True:
        if batch + train_ptr < trainnum:
            trains = traindatas[train_ptr:(train_ptr+batch)]
            labels = trainlabels[train_ptr:(train_ptr+batch)]
            train_ptr += batch
        else:
            new_ptr = (train_ptr + batch) % trainnum 
            trains = traindatas[train_ptr:] + traindatas[:new_ptr]
            labels = trainlabels[train_ptr:] + traindatas[:new_ptr]
            train_ptr = new_ptr

        for index, train in enumerate(trains):
            img = np.mean(cv2.imread(path + train), -1)
            batch_x[index,:] = img.flatten() /255
        for index, label in enumerate(labels):
            batch_y[index,:] = text2vec(label)

    else:
        if batch + test_ptr < testnum:
            tests = testdatas[test_ptr:(test_ptr+batch)]
            labels = testlabels[test_ptr:(test_ptr+batch)]
            test_ptr += batch
        else:
            new_ptr = (test_ptr + batch) % testnum 
            tests = testdatas[test_ptr:] + testdatas[:new_ptr]
            labels = testlabels[test_ptr:] + testlabels[:new_ptr]
            test_ptr = new_ptr

        for index, test in enumerate(tests):
            img = np.mean(cv2.imread(path + test), -1)
            batch_x[index, :] = img.flatten() /255
        for index, label in enumerate(labels):
            batch_y[index,:] = text2vec(label)

    return batch_x, batch_y

def text2vec(text):
    if len(text) > 4:
        raise ValueError('too long captcha')

    vector = np.zeros(4*63)
    def char2pos(c):
        if c == '_':
            k = 62
            return k
        k = ord(c)-48
        if k > 9:
            k = ord(c)-55
            if k > 35:
                k = ord(c) - 61
                if k > 61:
                    raise ValueError('No Map')

        return k

    for i, c in enumerate(text):
        idx = i*63 + char2pos(c)
        vector[idx] = 1

    return vector

X = tf.placeholder(tf.float32, [None, 30*100])
Y = tf.placeholder(tf.float32, [None,4*63])
_lr = tf.placeholder(tf.float32)
keep_prob = tf.placeholder(tf.float32)

def conv2d(x, W, b, strides=1):
    x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
    x = tf.nn.bias_add(x, b)
    return tf.nn.relu(x)

def max_pool2d(x, k=2):
    x = tf.nn.max_pool(
        x, ksize=[
            1, k, k, 1], strides=[
            1, k, k, 1], padding='SAME')
    return x

weights = {
        'wc1': tf.Variable(0.01*tf.random_normal([3, 3, 1, 32])),
        'wc2': tf.Variable(0.01*tf.random_normal([3, 3, 32, 64])),
        'wc3': tf.Variable(0.01*tf.random_normal([3, 3, 64, 64])),
        'wc4': tf.Variable(0.01*tf.random_normal([3, 3, 64, 64])),
        'wf1': tf.Variable(0.01*tf.random_normal([2 * 7 * 64, 1024])),
        'wf2': tf.Variable(0.01*tf.random_normal([1024, 1024])),
        'wout': tf.Variable(0.01*tf.random_normal([1024, 4*63]))
        }

biases = {
        'bc1': tf.Variable(0.1*tf.random_normal([32])),
        'bc2': tf.Variable(0.1*tf.random_normal([64])),
        'bc3': tf.Variable(0.1*tf.random_normal([64])),
        'bc4': tf.Variable(0.1*tf.random_normal([64])),
        'bf1': tf.Variable(0.1*tf.random_normal([1024])),
        'bf2': tf.Variable(0.1*tf.random_normal([1024])),
        'bout': tf.Variable(0.1*tf.random_normal([4*63]))
    }

def conv_net(x, weights, biases, dropout):
    x = tf.reshape(x, [-1,100,30,1])

    conv1 = conv2d(x, weights['wc1'], biases['bc1'], 1)
    conv1 = max_pool2d(conv1, 2)

    conv2 = conv2d(conv1, weights['wc2'], biases['bc2'], 1)
    conv2 = max_pool2d(conv2, 2)

    conv3 = conv2d(conv2, weights['wc3'], biases['bc3'], 1)
    conv3 = max_pool2d(conv3, 2)
    
    conv4 = conv2d(conv3, weights['wc4'], biases['bc4'], 1)
    conv4 = max_pool2d(conv4, 2)

    fc1 = tf.reshape(
        conv4, shape=[-1, weights['wf1'].get_shape().as_list()[0]])
    fc1 = tf.matmul(fc1, weights['wf1'])
    fc1 = tf.add(fc1, biases['bf1'])
    fc1 = tf.nn.relu(fc1)


    out = tf.add(tf.matmul(fc1, weights['wout']), biases['bout'])

    return out


output = conv_net(X, weights, biases, keep_prob)

loss_op = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
            logits=output, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=_lr).minimize(loss_op)

y = tf.reshape(output, [-1,4,63])
y_ = tf.reshape(Y, [-1,4,63])

correct_pred = tf.equal(tf.argmax(y, 2), tf.argmax(y_,2))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
init = tf.global_variables_initializer()
lr = 0.001
saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(init)
    for step in range(1,1+max_steps):
        batch_x, batch_y = next_batch(100,True)
        loss_value,_ = sess.run([loss_op, optimizer],
            feed_dict = {X:batch_x, Y:batch_y, keep_prob:dropout,_lr:lr})
        if step % 10 == 0:
            batch_x_test, batch_y_test = next_batch(100, False)
            acc = sess.run(accuracy, 
                feed_dict={X:batch_x_test, Y:batch_y_test,keep_prob:1})
            print('step{}, loss={}, accuracy={}'.format(step,loss_value, acc))

        if step % 500 == 0:
            random.shuffle(traindatas)
            trainlabels = list(map(lambda x: x.split('.')[0],traindatas))

        if step % 3000 == 0:
            lr *= 0.9

        if step % 10000 == 0:
            saver.save(sess, save_path + "/model.ckpt-%d" % step)
            print('model saved!')

Then I wrote a visual observation training effect, create a new script, add the following code, and then run the script, will show four random verification code and your predictions, the terminal will display the accuracy of this forecast .

from __future__ import print_function, division, absolute_import
import tensorflow as tf
import os
import cv2
import matplotlib.pyplot as plt 
import random
import numpy as np
from datasplit import use
#from optparse import OptionParser


testnumber = 4 #要更改的话需要改画图部分的代码否则会出错
path = 'Discuz/'
imgs = os.listdir(path)
model_path = 'model4cnn-1fcn/model.ckpt-500000' #读取你训练好的模型
testdatas = random.sample(imgs,testnumber)
testlabels = list(map(lambda x: x.split('.')[0],testdatas))
#testnum = len(testdatas)
#test_ptr = 0

X = tf.placeholder(tf.float32, [None, 30*100])
Y = tf.placeholder(tf.float32, [None,4*63])
keep_prob = tf.placeholder(tf.float32)

def text2vec(text):
    if len(text) > 4:
        raise ValueError('too long captcha')

    vector = np.zeros(4*63)
    def char2pos(c):
        if c == '_':
            k = 62
            return k
        k = ord(c)-48
        if k > 9:
            k = ord(c)-55
            if k > 35:
                k = ord(c) - 61
                if k > 61:
                    raise ValueError('No Map')

        return k

    for i, c in enumerate(text):
        idx = i*63 + char2pos(c)
        vector[idx] = 1

    return vector

def vec2text(vec):

    char_pos = vec.nonzero()[0]
    text = []
    for i, c in enumerate(char_pos):
        char_at_pos = i #c/63
        char_idx = c % 63
        if char_idx < 10:
            char_code = char_idx + ord('0')
        elif char_idx < 36:
            char_code = char_idx - 10 + ord('A')
        elif char_idx < 62:
            char_code = char_idx - 36 + ord('a')
        elif char_idx == 62:
            char_code = ord('_')
        else:
            raise ValueError('error')
        text.append(chr(char_code))
    return "".join(text)

batch_x = np.zeros([testnumber,30*100])
batch_y = np.zeros([testnumber, 4*63])

for index, test in enumerate(testdatas):
    img = np.mean(cv2.imread(path + test), -1)
    batch_x[index, :] = img.flatten() /255
for index, label in enumerate(testlabels):
    batch_y[index, :] = text2vec(label)

def conv2d(x, W, b, strides=1):
    x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
    x = tf.nn.bias_add(x, b)
    return tf.nn.relu(x)

def max_pool2d(x, k=2):
    x = tf.nn.max_pool(
        x, ksize=[
            1, k, k, 1], strides=[
            1, k, k, 1], padding='SAME')
    return x

weights = {
        'wc1': tf.Variable(0.01*tf.random_normal([3, 3, 1, 32])),
        'wc2': tf.Variable(0.01*tf.random_normal([3, 3, 32, 64])),
        'wc3': tf.Variable(0.01*tf.random_normal([3, 3, 64, 64])),
        'wc4': tf.Variable(0.01*tf.random_normal([3, 3, 64, 64])),
        'wf1': tf.Variable(0.01*tf.random_normal([2 * 7 * 64, 1024])),
        'wf2': tf.Variable(0.01*tf.random_normal([1024, 1024])),
        'wout': tf.Variable(0.01*tf.random_normal([1024, 4*63]))
        }

biases = {
        'bc1': tf.Variable(0.1*tf.random_normal([32])),
        'bc2': tf.Variable(0.1*tf.random_normal([64])),
        'bc3': tf.Variable(0.1*tf.random_normal([64])),
        'bc4': tf.Variable(0.1*tf.random_normal([64])),
        'bf1': tf.Variable(0.1*tf.random_normal([1024])),
        'bf2': tf.Variable(0.1*tf.random_normal([1024])),
        'bout': tf.Variable(0.1*tf.random_normal([4*63]))
    }

def conv_net(x, weights, biases, dropout):
    x = tf.reshape(x, [-1,100,30,1])

    conv1 = conv2d(x, weights['wc1'], biases['bc1'], 1)
    conv1 = max_pool2d(conv1, 2)

    conv2 = conv2d(conv1, weights['wc2'], biases['bc2'], 1)
    conv2 = max_pool2d(conv2, 2)

    conv3 = conv2d(conv2, weights['wc3'], biases['bc3'], 1)
    conv3 = max_pool2d(conv3, 2)
    
    conv4 = conv2d(conv3, weights['wc4'], biases['bc4'], 1)
    conv4 = max_pool2d(conv4, 2)
    
    fc1 = tf.reshape(
        conv4, shape=[-1, weights['wf1'].get_shape().as_list()[0]])
    fc1 = tf.matmul(fc1, weights['wf1'])
    fc1 = tf.add(fc1, biases['bf1'])
    fc1 = tf.nn.relu(fc1)

    out = tf.add(tf.matmul(fc1, weights['wout']), biases['bout'])

    return out

output = conv_net(X, weights, biases, keep_prob)

y = tf.reshape(output, [-1,4,63])
y_ = tf.reshape(Y, [-1,4,63])

predict = tf.argmax(y,2)
correct_pred = tf.equal(predict, tf.argmax(y_,2))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
saver = tf.train.Saver()

with tf.Session() as sess:
    saver.restore(sess, model_path)

    pred, acc = sess.run([predict,accuracy], feed_dict ={ X:batch_x, Y:batch_y,keep_prob:1})
    print('accuracy={}'.format(acc))
    for i in range(1,testnumber+1):

        plt.subplot(2,2,i)
        img = cv2.imread(path+testdatas[i-1])
        plt.imshow(img)
        plt.title('number%d' %i)
        plt.xticks([])
        plt.yticks([])
        vect = np.zeros([4*63])

        #print(pred[i-1])
        for ind,j in enumerate(pred[i-1]):
            vect[ind*63+j] = 1

        xlabel = 'True label:{};Pred label:{}'.format(testlabels[i-1], vec2text(vect))
        plt.xlabel(xlabel)

    plt.show()

Have any questions please discuss.

Guess you like

Origin www.cnblogs.com/guiguiguoguo/p/11086932.html