動手學深度學習(tensorflow)---學習筆記整理(四、多層感知機篇)

(有關公式、基本理論等大量內容摘自《動手學深度學習》(TF2.0版)

多層感知機是什麼?

個人的理解就是:多層的神經網絡+非線形的。具體說說就是至少包含一層隱含層和輸出層構成多層,非線性這個概念可以通過下面的內容來學習,由激活函數實現的線性到非線形的映射。

隱藏層、多層神經網絡的相關知識

通過最後一段話可以發現,對於線性的神經網絡,不論是多少層都等價於單層神經網絡,所以對於線性的模型,多少層都沒有意義,當每層轉化爲非線形後,上述等價式即無法成立,可以得出,多層感知機所表示的模型(多層+非線形),不同的層次所代表的含義不同。下面將解釋如何實現線性到非線形的轉換,即激活函數。

激活函數

常用的激活函數包括ReLU函數、sigmoid函數和tanh函數。

ReLU函數:只保留正數元素,並將負數元素清零

其圖像:

其導數圖像:

sigmoid函數:可以將元素的值變換到0和1之間

其圖像:

其導數圖像:

tanh函數:可以將元素的值變換到-1和1之間

其圖像:

其導數圖像:

多層感知機

通過上述公式可以發現引入激活函數後多層感知機並不等價與單層的感知機。

多層感知機從零開始實現

import tensorflow as tf
import numpy as np
import sys
print(tf.__version__)
#加載數據集
from tensorflow.keras.datasets import fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
#設置神經元個數
batch_size = 256
#歸一化
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)
x_train = x_train/255.0
x_test = x_test/255.0
#將訓練集合和測試集合轉換成Dataset類型
train_iter = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(batch_size)
test_iter = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(batch_size)
#定義模型參數
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = tf.Variable(tf.random.normal(shape=(num_inputs, num_hiddens),mean=0, stddev=0.01, dtype=tf.float32))
b1 = tf.Variable(tf.zeros(num_hiddens, dtype=tf.float32))
W2 = tf.Variable(tf.random.normal(shape=(num_hiddens, num_outputs),mean=0, stddev=0.01, dtype=tf.float32))
b2 = tf.Variable(tf.random.normal([num_outputs], stddev=0.1))
#定義激活函數,實現relu函數
def relu(x):
    return tf.math.maximum(x,0)
#定義網絡
def net(X):
    X = tf.reshape(X, shape=[-1, num_inputs])
    h = relu(tf.matmul(X, W1) + b1)
    return tf.math.softmax(tf.matmul(h, W2) + b2)
#定義損失函數
def loss(y_hat,y_true):
    return tf.losses.sparse_categorical_crossentropy(y_true,y_hat)
#定義參數
num_epochs, lr = 5, 0.5
params = [W1, b1, W2, b2]
num_epochs, lr = 5, 0.1
# 描述,對於tensorflow2中,比較的雙方必須類型都是int型,所以要將輸出和標籤都轉爲int型
#定義求準確率的函數
def evaluate_accuracy(data_iter, net):
    acc_sum, n = 0.0, 0
    for _, (X, y) in enumerate(data_iter):
        y = tf.cast(y,dtype=tf.int64)
        acc_sum += np.sum(tf.cast(tf.argmax(net(X), axis=1), dtype=tf.int64) == y)
        n += y.shape[0]
    return acc_sum / n
#訓練模型
def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params=None, lr=None, trainer=None):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
        for X, y in train_iter:
            with tf.GradientTape() as tape:
                y_hat = net(X)
                l = tf.reduce_sum(loss(y_hat, y))
            grads = tape.gradient(l, params)
            if trainer is None:
                # 如果沒有傳入優化器,則使用原先編寫的小批量隨機梯度下降
                for i, param in enumerate(params):
                    param.assign_sub(lr * grads[i] / batch_size)
            else:
                # tf.keras.optimizers.SGD 直接使用是隨機梯度下降 theta(t+1) = theta(t) - learning_rate * gradient
                # 這裏使用批量梯度下降,需要對梯度除以 batch_size, 對應原書代碼的 trainer.step(batch_size)
                trainer.apply_gradients(zip([grad / batch_size for grad in grads], params))

            y = tf.cast(y, dtype=tf.float32)
            train_l_sum += l.numpy()
            train_acc_sum += tf.reduce_sum(tf.cast(tf.argmax(y_hat, axis=1) == tf.cast(y, dtype=tf.int64), dtype=tf.int64)).numpy()
            n += y.shape[0]
        test_acc = evaluate_accuracy(test_iter, net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'% (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))
trainer = tf.keras.optimizers.SGD(lr)
train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)

多層感知機的簡單實現

import tensorflow as tf
from tensorflow import keras
import sys
from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
#定義模型
model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(256, activation='relu',),
    tf.keras.layers.Dense(10, activation='softmax')
])
#加載數據集
fashion_mnist = keras.datasets.fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train = x_train / 255.0
x_test = x_test / 255.0
#加載參數
model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.5),
             loss = 'sparse_categorical_crossentropy',
             metrics=['accuracy'])
#模型的訓練
model.fit(x_train, y_train, epochs=50,
              batch_size=256,
              validation_data=(x_test, y_test),
              validation_freq=1)

 

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