天天看點

動手學深度學習之多層感覺機

感覺機

  • 感覺機其實就是一個二分類問題
  • 給定輸入x,權重w,和偏移b,感覺機的輸出: o = σ ( ⟨ w , x ⟩ + b ) σ = { 1 i f x > 0 − 1 o t h e r w i s e o=\sigma (\left \langle w, x \right \rangle + b) \quad \sigma = \left\{\begin{matrix} 1 & if x > 0 \\ -1 & otherwise \end{matrix}\right. o=σ(⟨w,x⟩+b)σ={1−1​ifx>0otherwise​
    動手學深度學習之多層感覺機
  • 二分類:1或-1

    vs.回歸模型輸出實數

    vs.Softmax回歸輸出機率

訓練感覺機

動手學深度學習之多層感覺機
  • 等價于使用批量大小為1的梯度下降并使用損失函數: l ( y , x , w ) = m a x ( 0 , − y ⟨ w , x ⟩ ) l(y,x,w)=max(0,-y\left \langle w,x \right \rangle) l(y,x,w)=max(0,−y⟨w,x⟩)

收斂定理

  • 所謂的收斂定理就是算法什麼時候能夠停
  • 這裡做幾個假設:資料在半徑r内,餘量 ρ \rho ρ分類兩類: y ( x T w = b ) ≥ ρ y(x^Tw=b) \geq \rho y(xTw=b)≥ρ,對于 ∥ w ∥ 2 + b 2 ≤ 1 \left \|w \right \|^2 + b^2 \leq 1 ∥w∥2+b2≤1。餘量的意思就是兩個類分的很開,也就是兩類之間還有一些空間。

    感覺機保證在 r 2 + 1 ρ \frac{r^2+1}{\rho} ρr2+1​步後收斂。這裡的意思就是r是資料的大小, ρ \rho ρ就是看我們的資料是不是分的很開

XOR問題(Minsky & Papert, 1969)

  • 感覺機不能拟合XOR函數,它隻能産生線性分割面
    動手學深度學習之多層感覺機

總結

  • 感覺機是一個二分類模型,是最早的AI模型之一
  • 它的求解算法等價于使用批量大小為1的梯度下降
  • 它不能拟合XOR函數,導緻的第一次AI寒冬

多層感覺機

  • 學習XOR:這裡的意思就是如果我們使用一層感覺機做不了我們就使用多層,先去學習一個簡單的。下圖的意思就是把坐标先把坐标分開,然後相乘
    動手學深度學習之多層感覺機
  • 單隐藏層

    隐藏層的大小是一個超參數

    動手學深度學習之多層感覺機
  • 單隐藏層——單分類

    輸入 x ∈ R n x\in \mathbb{R}^n x∈Rn

    隐藏層 W 1 ∈ R m × n , b 1 ∈ R m W_1 \in \mathbb{R}^{m\times n}, b_1 \in \mathbb{R}^m W1​∈Rm×n,b1​∈Rm

    輸出層 w 2 ∈ R m , b 2 ∈ R w_2 \in \mathbb{R}^m, b_2\in \mathbb{R} w2​∈Rm,b2​∈R

    h = σ ( W 1 x + b 1 ) h=\sigma(W_1x+b_1) h=σ(W1​x+b1​)

    o = w 2 T h + b 2 o=w_2^Th+b_2 o=w2T​h+b2​

    σ 是 按 元 素 的 激 活 函 數 \sigma是按元素的激活函數 σ是按元素的激活函數

    為什麼我們需要一個非線性的激活函數?

    如果是一個線性函數,放進去其實沒什麼變化

    Sigmoid激活函數

    将輸入投影到(0,1), s i g m o i d ( x ) = 1 1 + e x p ( − x ) sigmoid(x)=\frac{1}{1+exp(-x)} sigmoid(x)=1+exp(−x)1​

    Tanh激活函數

    将輸入投影到(-1,1), t a n h ( x ) = 1 − e x p ( − 2 x ) 1 + e x p ( − 2 x ) tanh(x)=\frac{1-exp(-2x)}{1+exp(-2x)} tanh(x)=1+exp(−2x)1−exp(−2x)​

    ReLU函數

    ReLU:rectified linear unit, R e L U ( x ) = m a x ( x , 0 ) ReLU(x)=max(x,0) ReLU(x)=max(x,0)

  • 多類分類

    和softmax類似,softmax沒有隐藏層

    輸入 x ∈ R n x\in \mathbb{R}^n x∈Rn

    隐藏層 W 1 ∈ R m × n , b 1 ∈ R m W_1 \in \mathbb{R}^{m\times n}, b_1 \in \mathbb{R}^m W1​∈Rm×n,b1​∈Rm

    輸出層 w 2 ∈ R m × k , b 2 ∈ R k w_2 \in \mathbb{R}^{m\times k}, b_2\in \mathbb{R}^k w2​∈Rm×k,b2​∈Rk

    h = σ ( W 1 x + b 1 ) h=\sigma(W_1x+b_1) h=σ(W1​x+b1​)

    o = w 2 T h + b 2 o=w_2^Th+b_2 o=w2T​h+b2​

    y = s o f t m a x ( o ) y=softmax(o) y=softmax(o)

    σ 是 按 元 素 的 激 活 函 數 \sigma是按元素的激活函數 σ是按元素的激活函數

    [外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-7ancBqwv-1627187888558)(attachment:image-3.png)]

  • 多隐藏層
    動手學深度學習之多層感覺機

總結

  • 多層感覺機使用隐藏層和激活函數來來得到非線形模型
  • 常用激活函數是Sigmoid、Tanh、ReLU
  • 使用Softmax來處理多類分類
  • 超參數為隐藏層數,和各個隐藏層大小

多層感覺機從零開始實作

import torch
from torch import nn
from d2l import torch as d2l

# 加載資料
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
           

實作一個具有單隐藏層的多層感覺機,它包含256個隐藏單元

num_inputs, num_outputs, num_hiddens = 784, 10, 256

# 這裡的作用初始化一個隐藏層随機的參數,行數為784,列數為256,256的意思就是有256個隐藏單元
W1 = nn.Parameter(torch.randn(num_inputs, num_hiddens, requires_grad=True))  #Parameter函數的作用就是使得某些參數可以在學習過程中不斷的優化以達到最好的值
# 這裡是隐藏層的bias
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))

# 這裡是初始化輸出層
W2 = nn.Parameter(torch.randn(num_hiddens, num_outputs, requires_grad=True))
# 這裡是輸出層的bias
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))

# 這裡是我們的所有的參數
params = [W1, b1, W2, b2]
           

實作ReLU激活函數

def relu(X):
    a = torch.zeros_like(X)  # 這裡zeros_like函數的作用就是建立一個形狀和X相同但是元素值都為0的矩陣
    return torch.max(X, a)
           

實作我們的模型

def net(X):
    X = X.reshape((-1, num_inputs))
    H = relu(X @ W1 + b1)  # @就相當于X.dot(W1)做矩陣乘法
    return (H @ W2 + b2)
loss = nn.CrossEntropyLoss()
           

多層感覺機的訓練過程與softmax回歸的訓練過程完全相同

num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
           
---------------------------------------------------------------------------

AssertionError                            Traceback (most recent call last)

<ipython-input-12-c05076c9830f> in <module>
      1 num_epochs, lr = 10, 0.1
      2 updater = torch.optim.SGD(params, lr=lr)
----> 3 d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)


~/miniconda3/envs/d2l-zh/lib/python3.8/site-packages/d2l/torch.py in train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
    333         animator.add(epoch + 1, train_metrics + (test_acc,))
    334     train_loss, train_acc = train_metrics
--> 335     assert train_loss < 0.5, train_loss
    336     assert train_acc <= 1 and train_acc > 0.7, train_acc
    337     assert test_acc <= 1 and test_acc > 0.7, test_acc


AssertionError: 0.5474652306556702
           
動手學深度學習之多層感覺機

多層感覺機的簡潔實作

通過進階API更簡潔的實作多層感覺機

import torch
from torch import nn
from d2l import torch as d2l
           
# 這裡的nn.Flatten()展平層,就是将輸入轉成一個二維的東西。nn.Linear()線形層輸入是784,輸出是256。
# nn.ReLU()表示激活函數是ReLU,nn.Linear()表示輸入是256輸出是10
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 256), nn.ReLU(), nn.Linear(256, 10))  # Sequential的作用就是拿到一個network
           
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights)
           
Sequential(
  (0): Flatten(start_dim=1, end_dim=-1)
  (1): Linear(in_features=784, out_features=256, bias=True)
  (2): ReLU()
  (3): Linear(in_features=256, out_features=10, bias=True)
)
           
batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(), lr=lr)

train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
           
動手學深度學習之多層感覺機

繼續閱讀