国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用TensorFlow訓練Weibo.cn驗證碼

Dr_Noooo / 2725人閱讀

摘要:最近在抽時間學習這個庫的使用,學的斷斷續續的,看官網上第一個案例就是訓練手寫字符識別。此外,還需要有個,用來把訓練的標簽和實際的標簽對應,比如說對應字母,對應字母。然后使用的函數,把訓練集和測試集分開。

最近在抽時間學習TensorFlow這個DL庫的使用,學的斷斷續續的,看官網上第一個案例就是訓練手寫字符識別。我之前在做Weibo.cn驗證碼識別的時候,自己搞了一個數據集,當時用的c++庫tiny-dnn進行訓練的(見:驗證碼破解技術四部曲之使用卷積神經網絡(四)),現在我把它移植到TensorFlow上試試。

完整代碼見:weibo.cn/tensorflow-impl

使用的庫

TensorFlow-1.0

scikit-learn-0.18

pillow

加載數據集

數據集下載地址:training_set.zip

解壓過后如下圖:

我把同一類的圖片放到了一個文件夾里,文件夾的名字也就是圖片的label,打開文件夾后可以看到字符的圖片信息。

下面,我們把數據加載到一個pickle文件里面,它需要有train_dataset、train_labels、test_dataset、test_labels四個變量代表訓練集和測試集的數據和標簽。

此外,還需要有個label_map,用來把訓練的標簽和實際的標簽對應,比如說3對應字母M,4對應字母N。

此部分的代碼見:load_models.py。注:很多的代碼參考自udacity的deeplearning課程。

首先根據文件夾的來加載所有的數據,index代表訓練里的標簽,label代表實際的標簽,使用PIL讀取圖片,并轉換成numpy數組。

import numpy as np
import os
from PIL import Image

def load_dataset():
    dataset = []
    labelset = []
    label_map = {}

    base_dir = "../trainer/training_set/"  # 數據集的位置
    labels = os.listdir(base_dir)

    for index, label in enumerate(labels):
        if label == "ERROR" or label == ".DS_Store":
            continue
        print "loading:", label, "index:", index
        try:
            image_files = os.listdir(base_dir + label)
            for image_file in image_files:
                image_path = base_dir + label + "/" + image_file
                im = Image.open(image_path).convert("L")
                dataset.append(np.asarray(im, dtype=np.float32))
                labelset.append(index)
            label_map[index] = label
        except: pass

    return np.array(dataset), np.array(labelset), label_map


dataset, labelset, label_map = load_dataset()

接下來,把數據打亂。

def randomize(dataset, labels):
    permutation = np.random.permutation(labels.shape[0])
    shuffled_dataset = dataset[permutation, :, :]
    shuffled_labels = labels[permutation]
    return shuffled_dataset, shuffled_labels


dataset, labelset = randomize(dataset, labelset)

然后使用scikit-learn的函數,把訓練集和測試集分開。

from sklearn.model_selection import train_test_split
train_dataset, test_dataset, train_labels, test_labels = train_test_split(dataset, labelset)

在TensorFlow官網給的例子中,會把label進行One-Hot Encoding,并把28*28的圖片轉換成了一維向量(784)。如下圖,查看官網例子的模型。

我也把數據轉換了一下,把32*32的圖片轉換成一維向量(1024),并對標簽進行One-Hot Encoding。

def reformat(dataset, labels, image_size, num_labels):
    dataset = dataset.reshape((-1, image_size * image_size)).astype(np.float32)
    # Map 1 to [0.0, 1.0, 0.0 ...], 2 to [0.0, 0.0, 1.0 ...]
    labels = (np.arange(num_labels) == labels[:, None]).astype(np.float32)
    return dataset, labels

train_dataset, train_labels = reformat(train_dataset, train_labels, 32, len(label_map))
test_dataset, test_labels = reformat(test_dataset, test_labels, 32, len(label_map))
print "train_dataset:", train_dataset.shape
print "train_labels:", train_labels.shape
print "test_dataset:", test_dataset.shape
print "test_labels:", test_labels.shape

轉換后,格式就和minist一樣了。

最后,把數據保存到save.pickle里面。

save = {
    "train_dataset": train_dataset,
    "train_labels": train_labels,
    "test_dataset": test_dataset,
    "test_labels": test_labels,
    "label_map": label_map
}
with open("save.pickle", "wb") as f:
    pickle.dump(save, f)
驗證數據集加載是否正確

加載完數據后,需要驗證一下數據是否正確。我選擇的方法很簡單,就是把trainset的第1個(或者第2個、第n個)圖片打開,看看它的標簽和看到的能不能對上。

import cPickle as pickle
from PIL import Image
import numpy as np

def check_dataset(dataset, labels, label_map, index):
    data = np.uint8(dataset[index]).reshape((32, 32))
    i = np.argwhere(labels[index] == 1)[0][0]
    im = Image.fromarray(data)
    im.show()
    print "label:", label_map[i]

if __name__ == "__main__":
    with open("save.pickle", "rb") as f:
        save = pickle.load(f)
        train_dataset = save["train_dataset"]
        train_labels = save["train_labels"]
        test_dataset = save["test_dataset"]
        test_labels = save["test_labels"]
        label_map = save["label_map"]

    # check if the image is corresponding to it"s label
    check_dataset(train_dataset, train_labels, label_map, 0)

運行后,可以看到第一張圖片是Y,標簽也是正確的。

訓練

數據加載好了之后,就可以開始訓練了,訓練的網絡就使用TensorFlow官網在Deep MNIST for Experts里提供的就好了。

此部分的代碼見:train.py。

先加載一下模型:

import cPickle as pickle
import numpy as np
import tensorflow as tf

with open("save.pickle", "rb") as f:
    save = pickle.load(f)
    train_dataset = save["train_dataset"]
    train_labels = save["train_labels"]
    test_dataset = save["test_dataset"]
    test_labels = save["test_labels"]
    label_map = save["label_map"]

image_size = 32
num_labels = len(label_map)

print "train_dataset:", train_dataset.shape
print "train_labels:", train_labels.shape
print "test_dataset:", test_dataset.shape
print "test_labels:", test_labels.shape
print "num_labels:", num_labels

minist的數據都是28*28的,把里面的網絡改完了之后,如下:

def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)


def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)


def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding="SAME")


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


graph = tf.Graph()
with graph.as_default():
    x = tf.placeholder(tf.float32, shape=[None, image_size * image_size])
    y_ = tf.placeholder(tf.float32, shape=[None, num_labels])

    x_image = tf.reshape(x, [-1, 32, 32, 1])

    # First Convolutional Layer
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])

    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
    h_pool1 = max_pool_2x2(h_conv1)

    # Second Convolutional Layer
    W_conv2 = weight_variable([5, 5, 32, 64])
    b_conv2 = bias_variable([64])

    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
    h_pool2 = max_pool_2x2(h_conv2)

    # Densely Connected Layer
    W_fc1 = weight_variable([image_size / 4 * image_size / 4 * 64, 1024])
    b_fc1 = bias_variable([1024])

    h_pool2_flat = tf.reshape(h_pool2, [-1, image_size / 4 * image_size / 4 * 64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

    # Dropout
    keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

    # Readout Layer
    W_fc2 = weight_variable([1024, num_labels])
    b_fc2 = bias_variable([num_labels])

    y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2

    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))

    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
    correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

主要改動就是輸入層把28*28改成了image_size*image_size(32*32),然后第三層的全連接網絡把7*7改成了image_size/4*image_size/4(8*8),以及把10(手寫字符一共10類)改成了num_labels。

然后訓練,我這里把batch_size改成了128,訓練批次改少了。

batch_size = 128
with tf.Session(graph=graph) as session:
    tf.global_variables_initializer().run()
    print("Initialized")

    for step in range(2001):
        offset = (step * batch_size) % (train_labels.shape[0] - batch_size)
        # Generate a minibatch.
        batch_data = train_dataset[offset:(offset + batch_size), :]
        batch_labels = train_labels[offset:(offset + batch_size), :]

        if step % 50 == 0:
            train_accuracy = accuracy.eval(feed_dict={
                x: batch_data, y_: batch_labels, keep_prob: 1.0})
            test_accuracy = accuracy.eval(feed_dict={
                x: test_dataset, y_: test_labels, keep_prob: 1.0})
            print("Step %d, Training accuracy: %g, Test accuracy: %g" % (step, train_accuracy, test_accuracy))

        train_step.run(feed_dict={x: batch_data, y_: batch_labels, keep_prob: 0.5})

    print("Test accuracy: %g" % accuracy.eval(feed_dict={
        x: test_dataset, y_: test_labels, keep_prob: 1.0}))

運行,可以看到識別率在不斷的上升。

最后,有了接近98%的識別率,只有4000個訓練數據,感覺不錯了。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/38574.html

相關文章

發表評論

0條評論

Dr_Noooo

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<