天天看點

動手學深度學習 | 多層感覺機+代碼實作 | 08

目錄

  • ​​感覺機​​
  • ​​多層感覺機​​
  • ​​多層感覺機從零開始實作​​
  • ​​多層感覺機簡潔實作​​
  • ​​QA​​

感覺機

動手學深度學習 | 多層感覺機+代碼實作 | 08

1960年的“實體感覺機”。

動手學深度學習 | 多層感覺機+代碼實作 | 08

感覺機是人工智能最早最早的一個模型。

動手學深度學習 | 多層感覺機+代碼實作 | 08

感覺機就是線性回歸套了一層激活函數。

因為感覺機的輸出隻有一個元素,是以隻能做為一個二分類的問題。

動手學深度學習 | 多層感覺機+代碼實作 | 08

可以了解為感覺機使用了\(l(y,x,w)=max(0,-y<w,x>)\)這個損失函數。(隻預測正确的)

動手學深度學習 | 多層感覺機+代碼實作 | 08
動手學深度學習 | 多層感覺機+代碼實作 | 08
動手學深度學習 | 多層感覺機+代碼實作 | 08

多層感覺機

動手學深度學習 | 多層感覺機+代碼實作 | 08
動手學深度學習 | 多層感覺機+代碼實作 | 08

多層感覺機如何解決XOR問題呢?

假設一次做不了,那麼先學一個簡單的函數,再學一個簡單的函數,再用一個函數将兩部分進行組合,那麼就從一層變成了多層,這就是多層感覺機幹的事情。

動手學深度學習 | 多層感覺機+代碼實作 | 08

為什麼隐藏層大小是超參數?因為inputs是不能改的,outputs基本也是固定的,那麼可以進行修改的就是隐藏層。

動手學深度學習 | 多層感覺機+代碼實作 | 08
動手學深度學習 | 多層感覺機+代碼實作 | 08

如果不是非線性的激活函數,其實也沒有意義,因為如果是線性的激活函數,基本加了和沒加是一樣的。

動手學深度學習 | 多層感覺機+代碼實作 | 08
動手學深度學習 | 多層感覺機+代碼實作 | 08
動手學深度學習 | 多層感覺機+代碼實作 | 08

ReLU的唯一好處就是算的特别快,前面的sigmoid和tanh都要進行指數運算,指數運算是一件很貴的事情,一次指數運算可以抵得上100次乘法運算的計算開銷。

動手學深度學習 | 多層感覺機+代碼實作 | 08

其實如果沒有中間這個隐層的話,實際上和softmax回歸是沒有差别的。

動手學深度學習 | 多層感覺機+代碼實作 | 08

這裡隻是把單個輸出變成了k個輸出。

動手學深度學習 | 多層感覺機+代碼實作 | 08

多層感覺機是可以把層數做深的。

在隐層中,每一層的激活函數都不能少,如果少了,就相當于層數減一。輸出是不用激活函數的。

超參數:

  • 隐藏層數
  • 每層隐藏層的大小

怎麼設定隐藏層的數量和每層的大小呢?其實是有工程經驗的。

從有種角度來說,深度學習就是在做壓縮,把輸入很多的資料,最後輸出成幾個簡單的類别,這個本質上就是對資料進行壓縮。是以其實第一隐層是可以适當大一些的,比如輸入是128,那麼可以先擴充到256,然後後面再進行加深,進行資料的壓縮。是以隐層一般都是“先肥後窄”,一般都不會反過來,如果反過來的話,過度壓縮的話就會損失很多資訊。當然後面CNN有些模型是先壓縮,後面再擴充的,這個後面會講到。(沒有太多科學可以講,純粹靠手感.. 深度學習目前是工程走在理論研究的前面了)

動手學深度學習 | 多層感覺機+代碼實作 | 08

常用的激活函數,如果沒有想法,使用ReLU就可以了,因為ReLU簡單,算的快。

多層感覺機從零開始實作

動手學深度學習 | 多層感覺機+代碼實作 | 08

操作總結

# 導入資料
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

# 設定層數的數目
num_inputs, num_outputs, num_hiddens = 784, 10, 256

# nn.Parameter() 套不套這個都是可以的
W1 = nn.Parameter(
    torch.randn(num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(
    torch.randn(num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))

params = [W1, b1, W2, b2]

# 實作ReLU的激活函數
def relu(X):
    a = torch.zeros_like(X)
    return torch.max(X, a)

def net(X):
    # 先将X拉成一個矩陣
    X = X.reshape((-1, num_inputs))
    # @表示矩陣乘法
    H = relu(X @ W1 + b1)
    return (H @ W2 + b2)

loss = nn.CrossEntropyLoss()

# 訓練過程
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)


      

多層感覺機簡潔實作

動手學深度學習 | 多層感覺機+代碼實作 | 08
# 這樣就建構了一個具有單層 256個隐藏單元的,并使用ReLU激活函數的多層感覺機模型了
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 256), nn.ReLU(),nn.Linear(256, 10))

# 初始化權重
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights);


# 訓練過程
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)
      

QA

  1. 多層感覺機和純softmax模型相比,loss是下降了,但是精度并沒有提升。

可以解釋為因為模型更大了,是以資料拟合性更好,是以loss在下降。

  1. MLP和SVM

現在基本都是使用的MLP,因為MLP要改動的代碼其實不多,輸入和輸出基本都不用變,隻要把中間部分進行更換即可。

但是SVM就不是了,需要調整的東西會比較多。

  1. 神經網絡中一層是怎麼看的?

一層主要隻可以學習的參數,比如下圖,就是有兩層(輸入層不算做一層)

動手學深度學習 | 多層感覺機+代碼實作 | 08

有幾層參數需要學習,就可以認為是幾層,當然在隐層之間可以認為激活函數是一個分界。

  1. 為什麼神經網絡要增加隐藏層的層數,而不是神經元的個數?

其實增加深度效果會更好,如果隻是增加寬度的話,因為神經元是并行的,并不能很好的進行特征的提取。如果是深層的話,可以第一層先提取一點,第二層再提取其他的....

其實增加網絡的寬度和深度都是有用的,但是增加網絡的深度效果會更好。

(可以認為2014年之前,深度學習基本都是沒有什麼突破的東西,和20,30年前做的東西是一樣的,隻是把網絡做的更深)

  1. 不同任務下的激活函數是不是都不一樣?也是通過實驗來确認的嗎?

激活函數遠遠沒有選擇隐藏層那些大小和數量來的重要,是以就用ReLU吧...就是你可以選,但是本質上沒有太多的差別。

繼續閱讀