深層神經網絡-圖片識別-TF實現-數據可視化【人工智能學習】

經過上一篇文章的學習,我們對於淺層神經網絡的學習已經有了初步印象,我們來複習以下:
對於神經網絡,我們已經有了神經元的概念:每一個都是一個單獨的迴歸函數罷了

對於從迴歸學習到淺層神經網絡,我們知道添加隱藏層可以提高預測的準確率,並且成功定義了add_layer方法爲我們添加節點,快速生成隱藏層

但是我們在淺層神經網絡的學習裏面的構建隱藏層還是採用了寫死的方式,如果說要是想從淺層神經網絡改成深層神經網絡,則需要對上篇代碼繼續修改/

深層神經網絡

淺層神經網絡不同的是,深層神經網絡的隱藏層是可變的,我們可以根據不同的數據源、訓練集和數據特徵來改變學習策略,以此達到一個比較好的學習效果。

一個兩層的深層神經網絡結構如下:
兩層神經網絡
上圖所示的是一個具有兩層隱藏層的深層神經網絡

  1. 第一個隱藏層有 4 個節點,對應的激活函數爲 ReLu 函數
  2. 第一個隱藏層有 2 個節點,對應的激活函數也是 Relu 函數
  3. 最後,輸出層使用 softmax 函數作爲激活函數

那麼對於這樣的,或者更多的神經網絡,我們不可以再用下面的方法:

#淺層

    # 添加隱藏層
    l1 = add_layer(X, 784, 2000, activation_function=tf.nn.relu)
    pre = add_layer(l1, 2000, 10, activation_function=None)  # 輸出

而是要先對深層網絡的節點做好配置,之後構建可以服用的for循環函數,從而快速搭建

 #深層
 #【重點】規定節點結構
    layer_dims = [784,500,500,10] #結構,結構配置的地方
    layer_count = len(layer_dims)-1 #深度計算不算輸入層

    layer_iter = X #初始化輸入值,因節點輸入層構建需要所以第一層用X,for循環構建神經網絡,遍歷layer_dims替換X
    for l in range(1,layer_count):
        layer_iter = add_layer(layer_iter,layer_dims[l-1],layer_dims[l],activation_function = tf.nn.relu)
    pre = add_layer(layer_iter,layer_dims[layer_count-1],layer_dims[layer_count],activation_function = None) #輸出層節點要用最後一層隱藏層節點數量做輸入

我們只需要改變這個構建方法即可,其它方式均可不變,最後得到代碼:

#-*- coding:utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

def add_layer(inputs ,in_size,out_size,activation_function= True):
    #初始化變量
    W = tf.Variable(tf.random_normal([in_size,out_size]))#初始化正態分佈,in列,out行,第一層in傳入784,第二層傳入1000
    b = tf.Variable(tf.zeros([1,out_size])) #偏置量初始化,1列。out行

    Z = tf.matmul(inputs,W)+b #初始化公式,每一層都要有

     #爲了防止報錯,如果沒有傳入激活共識,則不作處理
    if activation_function is None:
        outputs = Z
    else:
        outputs = activation_function(Z)

    return outputs
 #構建主函數邏輯
if __name__ == "__main__":
    MNIST = input_data.read_data_sets("./", one_hot=True)
    cost_accum = []

    learning_rate = 0.01
    batch_size = 128
    n_epochs = 22

    X = tf.placeholder(tf.float32, [batch_size, 784])
    Y = tf.placeholder(tf.float32, [batch_size, 10])
    #【重點】規定節點結構
    layer_dims = [784,500,500,10] #結構,結構配置的地方
    layer_count = len(layer_dims)-1 #深度計算不算輸入層

    layer_iter = X #初始化輸入值,因節點輸入層構建需要所以第一層用X,for循環構建神經網絡,遍歷layer_dims替換X
    for l in range(1,layer_count):
        layer_iter = add_layer(layer_iter,layer_dims[l-1],layer_dims[l],activation_function = tf.nn.relu)
    pre = add_layer(layer_iter,layer_dims[layer_count-1],layer_dims[layer_count],activation_function = None) #輸出層節點要用最後一層隱藏層節點數量做輸入

    # 添加隱藏層
    # l1 = add_layer(X, 784, 2000, activation_function=tf.nn.relu)
    # pre = add_layer(l1, 2000, 10, activation_function=None)  # 輸出
    # w = tf.Variable(tf.random_normal(shape=[784,10], stddev=0.01), name="weights")
    # b = tf.Variable(tf.zeros([1, 10]), name="bias")

    # logits = tf.matmul(X, w) + b

    entropy = tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=pre)
    loss = tf.reduce_mean(entropy)
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
    # optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss)

    init = tf.global_variables_initializer()

    with tf.Session() as sess:
        sess.run(init)

        n_batches = int(MNIST.train.num_examples/batch_size)
        for i in range(n_epochs):
            for j in range(n_batches):
                X_batch, Y_batch = MNIST.train.next_batch(batch_size)
                loss_ = sess.run([optimizer, loss], feed_dict={ X: X_batch, Y: Y_batch})
                if j==0 :
                    print("Loss of epochs[{0}]: {1}".format(i, loss_))
                cost_accum.append(loss_)


        n_batches = int(MNIST.test.num_examples/batch_size)
        total_correct_preds = 0
        for i in range(n_batches):
            X_batch, Y_batch = MNIST.test.next_batch(batch_size)
            # preds = tf.nn.softmax(tf.matmul(X_batch, w) + b)  # 算預測結果
            preds = sess.run(pre, feed_dict={X: X_batch, Y: Y_batch}) #算預測結果
            correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(Y_batch, 1)) #判斷預測結果和標準結果
            accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32))#先轉化判斷的字符類型,再降維求和,這樣就得到了一大堆壓縮後的判斷結果
            total_correct_preds += sess.run(accuracy) #之前都是公式,必須要run纔有用,然後記錄數量


        print("Accuracy {0}".format(total_correct_preds/MNIST.test.num_examples))#判斷正確率並輸出

    plt.plot(range(len(cost_accum)), cost_accum, 'r')
    plt.title('Logic Regression Cost Curve')
    plt.xlabel('epoch*batch')
    plt.ylabel('loss')
    print('show')
    plt.show()

爲了提高代碼的複用性質,我將構建+學習部分、繪圖部分單獨變成了兩個方法,得到代碼如下:

#-*- coding:utf-8 -*-
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

def add_layer(inputs ,in_size,out_size,activation_function= True):
    #初始化變量
    W = tf.Variable(tf.random_normal([in_size,out_size]))#初始化正態分佈,in列,out行,第一層in傳入784,第二層傳入1000
    b = tf.Variable(tf.zeros([1,out_size])) #偏置量初始化,1列。out行

    Z = tf.matmul(inputs,W)+b #初始化公式,每一層都要有

     #爲了防止報錯,如果沒有傳入激活共識,則不作處理
    if activation_function is None:
        outputs = Z
    else:
        outputs = activation_function(Z)

    return outputs

def draw(cost_accum):
    plt.plot(range(len(cost_accum)), cost_accum, 'r')
    plt.title('Logic Regression Cost Curve')
    plt.xlabel('epoch*batch')
    plt.ylabel('loss')
    print('show')
    plt.show()

def learning(layer_dims,layer_count,layer_iter,input_data):
    for l in range(1,layer_count):
        layer_iter = add_layer(layer_iter,layer_dims[l-1],layer_dims[l],activation_function = tf.nn.relu)
    pre = add_layer(layer_iter,layer_dims[layer_count-1],layer_dims[layer_count],activation_function = None) #輸出層節點要用最後一層隱藏層節點數量做輸入

    entropy = tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=pre)
    loss = tf.reduce_mean(entropy)
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
    # optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss)

    init = tf.global_variables_initializer()

    with tf.Session() as sess:
        sess.run(init)

        cost_accum = [] #繪製信息收集
        n_batches = int(input_data.train.num_examples / batch_size)
        for i in range(n_epochs):
            for j in range(n_batches):
                X_batch, Y_batch = input_data.train.next_batch(batch_size)
                loss_ = sess.run([optimizer, loss], feed_dict={X: X_batch, Y: Y_batch})
                if j == 0:
                    print("Loss of epochs[{0}]: {1}".format(i, loss_))
                cost_accum.append(loss_)

        n_batches = int(input_data.test.num_examples / batch_size)
        total_correct_preds = 0
        for i in range(n_batches):
            X_batch, Y_batch = input_data.test.next_batch(batch_size)
            # preds = tf.nn.softmax(tf.matmul(X_batch, w) + b)  # 算預測結果
            preds = sess.run(pre, feed_dict={X: X_batch, Y: Y_batch})  # 算預測結果
            correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(Y_batch, 1))  # 判斷預測結果和標準結果
            accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32))  # 先轉化判斷的字符類型,再降維求和,這樣就得到了一大堆壓縮後的判斷結果
            total_correct_preds += sess.run(accuracy)  # 之前都是公式,必須要run纔有用,然後記錄數量

        print("Accuracy {0}".format(total_correct_preds / MNIST.test.num_examples))  # 判斷正確率並輸出

        draw(cost_accum = cost_accum)

#構建主函數邏輯
if __name__ == "__main__":
    MNIST = input_data.read_data_sets("./", one_hot=True)

    learning_rate = 0.01
    batch_size = 128
    n_epochs = 22

    X = tf.placeholder(tf.float32, [batch_size, 784])
    Y = tf.placeholder(tf.float32, [batch_size, 10])
    #【重點】規定節點結構
    layer_dims = [784,500,500,10] #結構,結構配置的地方
    layer_count = len(layer_dims)-1 #深度計算不算輸入層
    layer_iter = X #初始化輸入值,因節點輸入層構建需要所以第一層用X,for循環構建神經網絡,遍歷layer_dims替換X

    learning(layer_dims =layer_dims,layer_count = layer_count,layer_iter = layer_iter,input_data = MNIST)

經過訓練22次之後,結果爲:
在這裏插入圖片描述
此外,我們可以在主函數當中調整配置,來做一下對比實驗:調整layer_dims = [784,800,200,10]
來觀察實驗結果
在這裏插入圖片描述
調整layer_dims = [784,200,800,10]
來觀察實驗結果
在這裏插入圖片描述
可見神經元結構對於學習效果是有顯著影響的!

你也可以多去嘗試新得到算法、結構,這就是算法和結構的優化啦~
下一篇文章,我們將走進被神化的算法:卷積神經網絡,看看他和我們有什麼不同,又怎樣的獨特效果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章