【小白學PyTorch】1 搭建一個超簡單的網絡

文章目錄:

1 任務

首先說下我們要搭建的網絡要完成的學習任務:
讓我們的神經網絡學會邏輯異或運算,異或運算也就是俗稱的“相同取0,不同取1” 。再把我們的需求說的簡單一點,也就是我們需要搭建這樣一個神經網絡,讓我們在輸入(1,1)時輸出0,輸入(1,0)時輸出1(相同取0,不同取1),以此類推。

2 實現思路

因爲我們的需求需要有兩個輸入,一個輸出,所以我們需要在輸入層設置兩個輸入節點,輸出層設置一個輸出節點。因爲問題比較簡單,所以隱含層我們只需要設置10個節點就可以達到不錯的效果了,隱含層的激活函數我們採用ReLU函數,輸出層我們用Sigmoid函數,讓輸出保持在0到1的一個範圍,如果輸出大於0.5,即可讓輸出結果爲1,小於0.5,讓輸出結果爲0.

3 實現過程

我們使用的簡單的快速搭建法。

3.1 引入必要庫

import torch
import torch.nn as nn
import numpy as np

用pytorch當然要引入torch包,然後爲了寫代碼方便將torch包裏的nn用nn來代替,nn這個包就是neural network的縮寫,專門用來搭神經網絡的一個包。引入numpy是爲了創建矩陣作爲輸入。

3.2 創建訓練集

# 構建輸入集
x = np.mat('0 0;'
           '0 1;'
           '1 0;'
           '1 1')
x = torch.tensor(x).float()
y = np.mat('1;'
           '0;'
           '0;'
           '1')
y = torch.tensor(y).float()

我個人比較喜歡用np.mat這種方式構建矩陣,感覺寫法比較簡單,當然你也可以用其他的方法。但是構建完矩陣一定要有這一步torch.tensor(x).float(),必須要把你所創建的輸入轉換成tensor變量。

什麼是tensor呢?你可以簡單地理解他就是pytorch中用的一種變量,你想用pytorch這個框架就必須先把你的變量轉換成tensor變量。而我們這個神經網絡會要求你的輸入和輸出必須是float浮點型的,指的是tensor變量中的浮點型,而你用np.mat創建的輸入是int型的,轉換成tensor也會自動地轉換成tensor的int型,所以要在後面加個.float()轉換成浮點型。

這樣我們就構建完成了輸入和輸出(分別是x矩陣和y矩陣),x是四行二列的一個矩陣,他的每一行是一個輸入,一次輸入兩個值,這裏我們把所有的輸入情況都列了出來。輸出y是一個四行一列的矩陣,每一行都是一個輸出,對應x矩陣每一行的輸入。

3.3 搭建網絡

myNet = nn.Sequential( 
    nn.Linear(2,10),
    nn.ReLU(),
    nn.Linear(10,1),
    nn.Sigmoid()
    )
print(myNet)

輸出結果:
在這裏插入圖片描述

我們使用nn包中的Sequential搭建網絡,這個函數就是那個可以讓我們像搭積木一樣搭神經網絡的一個東西。

nn.Linear(2,10)的意思搭建輸入層,裏面的2代表輸入節點個數,10代表輸出節點個數。Linear也就是英文的線性,意思也就是這層不包括任何其它的激活函數,你輸入了啥他就給你輸出了啥。nn.ReLU()這個就代表把一個激活函數層,把你剛纔的輸入扔到了ReLU函數中去。 接着又來了一個Linear,最後再扔到Sigmoid函數中去。 2,10,1就分別代表了三個層的個數,簡單明瞭。

3.4 設置優化器

optimzer = torch.optim.SGD(myNet.parameters(),lr=0.05)
loss_func = nn.MSELoss()

對這一步的理解就是,你需要有一個優化的方法來訓練你的網絡,所以這步設置了我們所要採用的優化方法。

torch.optim.SGD的意思就是採用SGD(隨機梯度下降)方法訓練,你只需要把你網絡的參數和學習率傳進去就可以了,分別是myNet.parametslrloss_func這句設置了代價函數,因爲我們的這個問題比較簡單,所以採用了MSE,也就是均方誤差代價函數。

3.5 訓練網絡

for epoch in range(5000):
    out = myNet(x)
    loss = loss_func(out,y)
    optimzer.zero_grad()
    loss.backward()
    optimzer.step()

我這裏設置了一個5000次的循環(可能不需要這麼多次),讓這個訓練的動作迭代5000次。每一次的輸出直接用myNet(x),把輸入扔進你的網絡就得到了輸出out(就是這麼簡單粗暴!),然後用代價函數和你的標準輸出y求誤差。 清除梯度的那一步是爲了每一次重新迭代時清除上一次所求出的梯度,你就把這一步記住就行,初學不用理解太深。 loss.backward()當然就是讓誤差反向傳播,接着optimzer.step()也就是讓我們剛剛設置的優化器開始工作。

3.6 測試

print(myNet(x).data)

運行結果:

在這裏插入圖片描述

可以看到這個結果已經非常接近我們期待的結果了,當然你也可以換個數據測試,結果也會是相似的。這裏簡單解釋下爲什麼我們的代碼末尾加上了一個.data,因爲我們的tensor變量其實是包含兩個部分的,一部分是tensor數據,另一部分是tensor的自動求導參數,我們加上.data意思是輸出取tensor中的數據,如果不加的話會輸出下面這樣:

在這裏插入圖片描述

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