4.2tensorflow多層感知器MLP識別手寫數字最易懂實例代碼


自己開發了一個股票智能分析軟件,功能很強大,需要的點擊下面的鏈接獲取:

https://www.cnblogs.com/bclshuai/p/11380657.html

1.1  多層感知器MLP(multilayer perception)

1.1.1          多層感知器的結構

除了輸入輸出層,它中間可以有多個隱層,最簡單的MLP只含一個隱層,即三層的結構。,假設輸入層用向量X表示,則隱藏層的輸出就是 f (W1X+b1),W1是權重(也叫連接系數),b1是偏置,函數f 可以是常用的sigmoid函數或者tanh函數。

 

 

 

 

1.1.2          激活函數

能夠給神經元引入非線性因素,使得神經網絡可以任意逼近任何非線性函數,這樣神經網絡就可以利用到更多的非線性模型中。

(1) 連續並可導(允許少數點上不可導)的非線性函數。可導的激活函數可以直接利用數值優化的方法來學習網絡參數。

(2)激活函數及其導函數要盡可能的簡單,有利於提高網絡計算效率。

(3)激活函數的導函數的值域要在一個合適的區間內,不能太大也不能太小,否則會影響訓練的效率和穩定性。

sigmod激活函數取值范圍是(0,1),

 

 

 

 

導數為

 

 

 

 

tanh激活函數取值范圍是(-1,1)

 

 

 

 

導數為

 

 

 

 

MLP所有的參數就是各個層之間的連接權重以及偏置,最簡單的就是梯度下降法了(SGD):首先隨機初始化所有參數,然后迭代地訓練,不斷地計算梯度和更新參數,直到滿足某個條件為止(比如誤差足夠小、迭代次數足夠多時)。這個過程涉及到代價函數、規則化(Regularization)、學習速率(learning rate)、梯度計算等,最后得出參數,就是模型訓練的過程。

1.1.3          tensorflow建立多層感知器的步驟

(1)定義手寫數字數據獲取類,用於下載數據和隨機獲取小批量訓練數據。

(2)定義多層感知器,繼承繼承keras.Model,init函數定義層,call函數中組織數據處理流程。

(3)定義訓練參數和模型對象,數據集對象。

(4)通過梯度下降法對模型參數進行訓練,優化模型。

(5)用測試數據集評估模型的准確性

 

 

 

 

1.1.4          手寫數字識別模型實例

下載60000個手寫數字圖片進行圖像識別,識別出數字,用多層感知器去識別,用梯度下降法去訓練模型參數。代碼實例。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plot
#(1)定義手寫數字數據獲取類,用於下載數據和隨機獲取小批量訓練數據
class MNISTLoader():
    def __init__(self):
        minist = tf.keras.datasets.mnist
        #訓練數據x_train, 正確值y_train,測試數據x_test,測試數據正確值self.y_test
        (self.x_train, self.y_train), (self.x_test, self.y_test) = minist.load_data()
        #[60000,28,28,1],60000個28*28像素的圖片數據,每個像素點時0-255的整數,除以255.0是將每個像素值歸一化為0-1間
        #的浮點數,並通過np.expand_dims增加一維,作為顏色通道.默認值為1。
        self.x_train = np.expand_dims(self.x_train.astype(np.float) / 255.0, axis=-1)
        print(self.x_train.shape)
        #[10000,28,28]->[10000,28,28,1]
        self.x_test = np.expand_dims(self.x_test.astype(np.float) / 255.0, axis=-1)
        #訓練用的標簽值
        self.y_train = self.y_train.astype(np.int)
        #測試用的標簽值
        self.y_test = self.y_test.astype(np.int)
        self.num_train_data = self.x_train.shape[0]
        self.num_test_data = self.x_test.shape[0]
    #隨機從數據集中獲取大小為batch_size手寫圖片數據
    def get_batch(self, batch_size):
        #shape[0]獲取數據總數量,在0-總數量之間隨機獲取數據的索引值,相當於抽樣。
        index = np.random.randint(0, self.x_train.shape[0], batch_size)
        #通過索引值去數據集中獲取訓練數據集。
        return self.x_train[index, :], self.y_train[index]
#(2)定義多層感知器,繼承繼承keras.Model,init函數定義層,call函數中組織數據處理流程
class MLP(tf.keras.Model):
    def __init__(self):
        super(MLP, self).__init__()
        #扁平化,將28*28的二維數組,變成1維數組,0-783.
        self.flatten = tf.keras.layers.Flatten()
        #全連接層,將784個像素點轉化為100個
        self.dence1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)
        #全連接層,將100個單元轉化為10個點
        self.dence2 = tf.keras.layers.Dense(units=10)

    def call(self, inputs, training=None, mask=None):
        #編寫數據流的處理過程,
        x = self.flatten(inputs)#28*28的二維矩陣扁平化為784個1維數組
        x = self.dence1(x)#784個映射到100個
        x = self.dence2(x)#100個映射到10個,分別表示對應0,1..9數字的概率
        output = tf.nn.softmax(x)#輸出0,1..9概率最大的值。
        return output

#(3)定義訓練參數和模型對象,數據集對象
num_epochs = 5
batch_size = 500#一批數據的數量
learning_rate = 0.001#學習率
model = MLP()#創建模型
data_loader = MNISTLoader()#創建數據源對象
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)#創建優化器,用於參數學習優化
#開始訓練參數
num_batches=int(data_loader.num_train_data//batch_size*num_epochs)#計算訓練數據的總組數
arryindex=np.arange(num_batches)
arryloss=np.zeros(num_batches)
#(4)通過梯度下降法對模型參數進行訓練,優化模型
for batch_index in range(num_batches):
    X,ylabel=data_loader.get_batch(batch_size)#隨機獲取訓練數據
    with tf.GradientTape() as tape:
        ypred=model(X)#模型計算預測值
        #計算損失函數
        loss=tf.keras.losses.sparse_categorical_crossentropy(y_true=ylabel,y_pred=ypred)
        #計算損失函數的均方根值,表示誤差大小
        loss=tf.reduce_mean(loss)
        print("第%d次訓練后:誤差%f" % (batch_index,loss.numpy()))
        #保存誤差值,用於畫圖
        arryloss[batch_index]=loss
        #根據誤差計算梯度值
    grads=tape.gradient(loss,model.variables)
    #將梯度值調整模型參數
    optimizer.apply_gradients(grads_and_vars=zip(grads,model.variables))

#畫出訓練誤差隨訓練次數的圖片圖
plot.plot(arryindex,arryloss,c='r')
plot.show()
#(5)評估模型的准確性
#建立評估器對象
sparse_categorical_accuracy=tf.keras.metrics.SparseCategoricalAccuracy()
#用測試數據集計算預測值
ytestpred=model.predict(data_loader.x_test)
#向評估器輸入預測值和真實值,計算准確率
sparse_categorical_accuracy.update_state(y_true=data_loader.y_test,y_pred=ytestpred)
print("test accuracy is %f" % sparse_categorical_accuracy.result())

 

 

訓練誤差收斂情況

 

 

 

 

輸出評估分析結果,訓練時誤差是0.089,用測試數據進行測試准確性是0.955。

 

 

 

 

1.1.5          mlp使用知識點

(1)    expand_dims(a, axis) 給張量a,在位置axis處增加一個維度。

# 't' is a tensor of shape [2]

shape(expand_dims(t, 0)) ==> [1, 2]#在位置0處加

shape(expand_dims(t, 1)) ==> [2, 1]#在位置1處加

shape(expand_dims(t, -1)) ==> [2, 1]#默認在后面加

 

# 't2' is a tensor of shape [2, 3, 5]

shape(expand_dims(t2, 0)) ==> [1, 2, 3, 5]

shape(expand_dims(t2, 2)) ==> [2, 3, 1, 5]

shape(expand_dims(t2, 3)) ==> [2, 3, 5, 1]

(2)    tf.keras.layers.Flatten()將多維的張量轉化為1維數組

將輸入層的數據壓成一維的數據,一般用再卷積層和全連接層之間(因為全連接層只能接收一維數據,而卷積層可以處理二維數據,就是全連接層處理的是向量,而卷積層處理的是矩陣。

(3)     x_train.shape[0],獲取張量的維度,0表示第一個維度,也可以通過給shape賦值,改變張量的維度。

建立一個2*3*4的張量
>>> y = np.zeros((2, 3, 4))
>>> y.shape
(2, 3, 4)獲取維度
>>> y.shape = (3, 8)#賦值維度
>>> y#輸出y的值,變成3行8列的二維矩陣
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

(4)    tf.keras.layers.Dense全連接層

def __init__(self,

               units,

               activation=None,

               use_bias=True,

               kernel_initializer='glorot_uniform',

               bias_initializer='zeros',

               kernel_regularizer=None,

               bias_regularizer=None,

               activity_regularizer=None,

               kernel_constraint=None,

               bias_constraint=None,

               **kwargs)

units: 正整數,輸出空間維度。

activation: 激活函數 (詳見 activations)。 若不指定,則不使用激活函數 (即,線性激活: a(x) = x)。

use_bias: 布爾值,該層是否使用偏置向量。

kernel_initializer: kernel 權值矩陣的初始化器 (詳見 initializers)。

bias_initializer: 偏置向量的初始化器 (詳見 initializers)。

kernel_regularizer: 運用到 kernel 權值矩陣的正則化函數 (詳見 regularizer)。

bias_regularizer: 運用到偏置向量的的正則化函數 (詳見 regularizer)。

activity_regularizer: 運用到層的輸出的正則化函數 (它的 "activation")。 (詳見 regularizer)。

kernel_constraint: 運用到 kernel 權值矩陣的約束函數 (詳見 constraints)。

bias_constraint: 運用到偏置向量的約束函數 (詳見 constraints)。

 

(5)    tf.keras.optimizers.Adam參數優化器

keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)

Adam 優化器。

learning_rate: float >= 0. 學習率。

beta_1: float, 0 < beta < 1. 通常接近於 1。

beta_2: float, 0 < beta < 1. 通常接近於 1。

amsgrad: boolean. 是否應用此算法的 AMSGrad 變種,來自論文 "On the Convergence of Adam and Beyond"。

(6)    tf.keras.losses.sparse_categorical_crossentropy交叉熵函數

將模型的預測值和標簽值傳入計算損失函數的值,當預測概率分布和真實的概率分布越接近,交叉熵值越小,誤差越小。

(7)    tf.keras.metrics.SparseCategoricalAccuracy()模型評估器

將測試數據輸入模型得出預測值,通過調用update_state()方法向評估器輸入y_pred和y_true兩個參數,可以傳入多次,最后調用result()函數輸出總的預測的准確率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM