TensorFlow筆記六:基於cifar10數據庫的AlexNet識別

準確率只有70%,cpu版本的TF竟然跑了兩天才跑完,其餘方法將繼續嘗試。git

生成數據目錄:網絡

import numpy as np
import os


train_label = {}

for i in range(10):
    search_path = './data/train/{}'.format(i)
    file_list = os.listdir(search_path)
    for file in file_list:
        train_label[os.path.join(search_path, file)] = i

np.save('label.npy', train_label)

test_label = {}

for i in range(10):
    search_path = './data/test/{}'.format(i)
    file_list = os.listdir(search_path)
    for file in file_list:
        test_label[os.path.join(search_path, file)] = i

np.save('test-label.npy', test_label)
View Code

訓練:app

import tensorflow as tf
import numpy as np
import random
import cv2

# 將傳入的label轉換成one hot的形式。
def getOneHotLabel(label, depth):
    m = np.zeros([len(label), depth])
    for i in range(len(label)):
        m[i][label[i]] = 1
    return m

# 創建神經網絡。
def alexnet(image, keepprob=0.5):

    # 定義卷積層1,卷積核大小,偏置量等各項參數參考下面的程序代碼,下同。
    with tf.name_scope("conv1") as scope:
        kernel = tf.Variable(tf.truncated_normal([11, 11, 3, 64], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(image, kernel, [1, 4, 4, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[64]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv1 = tf.nn.relu(bias, name=scope)

        pass

    # LRN層
    lrn1 = tf.nn.lrn(conv1, 4, bias=1.0, alpha=0.001/9, beta=0.75, name="lrn1")

    # 最大池化層
    pool1 = tf.nn.max_pool(lrn1, ksize=[1,3,3,1], strides=[1,2,2,1],padding="VALID", name="pool1")

    # 定義卷積層2
    with tf.name_scope("conv2") as scope:
        kernel = tf.Variable(tf.truncated_normal([5,5,64,192], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(pool1, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[192]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv2 = tf.nn.relu(bias, name=scope)
        pass

    # LRN層
    lrn2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001 / 9, beta=0.75, name="lrn2")

    # 最大池化層
    pool2 = tf.nn.max_pool(lrn2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding="VALID", name="pool2")

    # 定義卷積層3
    with tf.name_scope("conv3") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,192,384], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(pool2, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[384]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv3 = tf.nn.relu(bias, name=scope)
        pass

    # 定義卷積層4
    with tf.name_scope("conv4") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,384,256], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(conv3, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[256]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv4 = tf.nn.relu(bias, name=scope)
        pass

    # 定義卷積層5
    with tf.name_scope("conv5") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,256,256], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(conv4, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[256]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv5 = tf.nn.relu(bias, name=scope)
        pass

    # 最大池化層
    pool5 = tf.nn.max_pool(conv5, ksize=[1,3,3,1], strides=[1,2,2,1], padding="VALID", name="pool5")

    # 全鏈接層
    flatten = tf.reshape(pool5, [-1, 6*6*256])

    weight1 = tf.Variable(tf.truncated_normal([6*6*256, 4096], mean=0, stddev=0.01))

    fc1 = tf.nn.sigmoid(tf.matmul(flatten, weight1))

    dropout1 = tf.nn.dropout(fc1, keepprob)

    weight2 = tf.Variable(tf.truncated_normal([4096, 4096], mean=0, stddev=0.01))

    fc2 = tf.nn.sigmoid(tf.matmul(dropout1, weight2))

    dropout2 = tf.nn.dropout(fc2, keepprob)

    weight3 = tf.Variable(tf.truncated_normal([4096, 10], mean=0, stddev=0.01))

    fc3 = tf.nn.sigmoid(tf.matmul(dropout2, weight3))

    return fc3


def alexnet_main():
    # 加載使用的訓練集文件名和標籤。
    files = np.load("label.npy",  allow_pickle=True , encoding='bytes')[()]

    # 提取文件名。
    keys = [i for i in files]

    print(len(keys))

    myinput = tf.placeholder(dtype=tf.float32, shape=[None, 224, 224, 3], name='input')
    mylabel = tf.placeholder(dtype=tf.float32, shape=[None, 10], name='label')

    # 創建網絡,keepprob爲0.6。
    myoutput = alexnet(myinput, 0.6)

    # 定義訓練的loss函數。
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=myoutput, labels=mylabel))

    # 定義優化器,學習率設置爲0.09,學習率能夠設置爲其餘的數值。
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.09).minimize(loss)

    # 定義準確率
    valaccuracy = tf.reduce_mean(
        tf.cast(
            tf.equal(
                tf.argmax(myoutput, 1),
                tf.argmax(mylabel, 1)),
            tf.float32))

    # tensorflow的saver,能夠用於保存模型。
    saver = tf.train.Saver()
    init = tf.global_variables_initializer()
    with tf.Session() as sess:
        sess.run(init)
        # 40個epoch
        for loop in range(40):

            # 生成並打亂訓練集的順序。
            indices = np.arange(50000)
            random.shuffle(indices)

            # batch size此處定義爲200。
            # 訓練集一共50000張圖片,前40000張用於訓練,後10000張用於驗證集。
            for i in range(0, 0+40000, 200):
                photo = []
                label = []
                for j in range(0, 200):
                    # print(keys[indices[i + j]])
                    photo.append(cv2.resize(cv2.imread(keys[indices[i + j]]), (224, 224))/225)
                    label.append(files[keys[indices[i + j]]])
                m = getOneHotLabel(label, depth=10)
                a, b = sess.run([optimizer, loss], feed_dict={myinput: photo, mylabel: m})
                print("\r%lf"%b, end='')

            acc = 0
            # 每次取驗證集的200張圖片進行驗證,返回這200張圖片的正確率。
            for i in range(40000, 40000+10000, 200):
                photo = []
                label = []
                for j in range(i, i + 200):
                    photo.append(cv2.resize(cv2.imread(keys[indices[j]]), (224, 224))/225)
                    label.append(files[keys[indices[j]]])
                m = getOneHotLabel(label, depth=10)
                acc += sess.run(valaccuracy, feed_dict={myinput: photo, mylabel: m})
            # 輸出,一共有50次驗證集數據相加,因此須要除以50。
            print("Epoch ", loop, ': validation rate: ', acc/50)
        # 保存模型。
        saver.save(sess, "model/model.ckpt")

if __name__ == '__main__':
    alexnet_main()
View Code

測試:dom

import tensorflow as tf
import numpy as np
import random
import cv2

def getOneHotLabel(label, depth):
    m = np.zeros([len(label), depth])
    for i in range(len(label)):
        m[i][label[i]] = 1
    return m

# 創建神經網絡
def alexnet(image, keepprob=0.5):

    # 定義卷積層1,卷積核大小,偏置量等各項參數參考下面的程序代碼,下同
    with tf.name_scope("conv1") as scope:
        kernel = tf.Variable(tf.truncated_normal([11, 11, 3, 64], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(image, kernel, [1, 4, 4, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[64]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv1 = tf.nn.relu(bias, name=scope)

        pass

    # LRN層
    lrn1 = tf.nn.lrn(conv1, 4, bias=1.0, alpha=0.001/9, beta=0.75, name="lrn1")

    # 最大池化層
    pool1 = tf.nn.max_pool(lrn1, ksize=[1,3,3,1], strides=[1,2,2,1],padding="VALID", name="pool1")

    # 定義卷積層2
    with tf.name_scope("conv2") as scope:
        kernel = tf.Variable(tf.truncated_normal([5,5,64,192], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(pool1, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[192]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv2 = tf.nn.relu(bias, name=scope)
        pass

    # LRN層
    lrn2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001 / 9, beta=0.75, name="lrn2")

    # 最大池化層
    pool2 = tf.nn.max_pool(lrn2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding="VALID", name="pool2")

    # 定義卷積層3
    with tf.name_scope("conv3") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,192,384], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(pool2, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[384]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv3 = tf.nn.relu(bias, name=scope)
        pass

    # 定義卷積層4
    with tf.name_scope("conv4") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,384,256], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(conv3, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[256]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv4 = tf.nn.relu(bias, name=scope)
        pass

    # 定義卷積層5
    with tf.name_scope("conv5") as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,256,256], dtype=tf.float32, stddev=1e-1, name="weights"))
        conv = tf.nn.conv2d(conv4, kernel, [1, 1, 1, 1], padding="SAME")
        biases = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[256]), trainable=True, name="biases")
        bias = tf.nn.bias_add(conv, biases)
        conv5 = tf.nn.relu(bias, name=scope)
        pass

    # 最大池化層
    pool5 = tf.nn.max_pool(conv5, ksize=[1,3,3,1], strides=[1,2,2,1], padding="VALID", name="pool5")

    # 全鏈接層
    flatten = tf.reshape(pool5, [-1, 6*6*256])

    weight1 = tf.Variable(tf.truncated_normal([6*6*256, 4096], mean=0, stddev=0.01))

    fc1 = tf.nn.sigmoid(tf.matmul(flatten, weight1))

    dropout1 = tf.nn.dropout(fc1, keepprob)

    weight2 = tf.Variable(tf.truncated_normal([4096, 4096], mean=0, stddev=0.01))

    fc2 = tf.nn.sigmoid(tf.matmul(dropout1, weight2))

    dropout2 = tf.nn.dropout(fc2, keepprob)

    weight3 = tf.Variable(tf.truncated_normal([4096, 10], mean=0, stddev=0.01))

    fc3 = tf.nn.sigmoid(tf.matmul(dropout2, weight3))

    return fc3


def alexnet_main():
    # 加載測試集的文件名和標籤。
    files = np.load("test-label.npy", encoding='bytes')[()]
    keys = [i for i in files]
    print(len(keys))

    myinput = tf.placeholder(dtype=tf.float32, shape=[None, 224, 224, 3], name='input')
    mylabel = tf.placeholder(dtype=tf.float32, shape=[None, 10], name='label')
    myoutput = alexnet(myinput, 0.6)

    prediction = tf.argmax(myoutput, 1)
    truth = tf.argmax(mylabel, 1)
    valaccuracy = tf.reduce_mean(
        tf.cast(
            tf.equal(
                prediction,
                truth),
            tf.float32))

    saver = tf.train.Saver()

    with tf.Session() as sess:
        # 加載訓練好的模型,路徑根據本身的實際狀況調整
        saver.restore(sess, r"model/model.ckpt")

        cnt = 0
        for i in range(10000):
            photo = []
            label = []

            photo.append(cv2.resize(cv2.imread(keys[i]), (224, 224))/225)
            label.append(files[keys[i]])
            m = getOneHotLabel(label, depth=10)
            a, b= sess.run([prediction, truth], feed_dict={myinput: photo, mylabel: m})
            print(a, ' ', b)
            if a[0] == b[0]:
                cnt += 1

        print("Epoch ", 1, ': prediction rate: ', cnt / 10000)

if __name__ == '__main__':
    alexnet_main()
View Code
相關文章
相關標籤/搜索