零基礎學習人工智慧—Python—Pytorch學習(六)

kiba518發表於2024-08-21

前言

本文主要講神經網路的上半部分。
另外,我發現我前面文章寫的有歧義的地方還是挺多,雖然,已經改了一部分,但,可能還有沒發現的,大家看的時候儘量多理解著看吧。
本著目的是學會使用神經網路的開發,至於數學的部分,就能過就過吧。

神經網路

先學個例子

先結合以前的知識理解一個例子,理解了這個例子,後面理解神經網路就容易多了。

class NeuralNet1(nn.Module):
    def __init__(self, input_size, hidden_size):
        super(NeuralNet1,self).__init__()
        self,linear1 = nn.Linear(input_size, hidden_size) # x的列 轉成 隱藏層的列
        self.relu = nn.ReLU() #使用了ReLU(Rectified Linear Unit) 作為啟用函式
        self.linear2 = nn.Linear(hidden_size,1) #隱藏層的列轉成1列
    def forward(self, x):
        out = self.linear1(x)
        out = self.relu(out)
        out = self.linear2(out)# sigmoid at the end
        y_pred = torch.sigmoid(out)
        return y_pred 
model=NeuralNet1(input_size=28*28,hidden_size=5)
criterion =nn.BCELoss()

結合我們之前的知識,上面程式碼就是定義了一個類,該類繼承了Module。
然後初始化函式接受了兩引數,倆引數分別是x列,和隱藏層列,然後定義三個物件linear1,linear2,relu。
然後forward就是執行,中間的轉換邏輯是x列轉成hidden列,hidden列轉1列,這中間再加一個啟用函式,我們先不管啟用函式是什麼,反正,程式碼結構,大概就是這樣的邏輯。
criterion =nn.BCELosS()是定義損失函式,BCELoss 的全稱是 Binary Cross Entropy Loss(二元交叉熵損失)。
ps:大家有沒有注意到,自從我們開始使用model後,就再也沒使用 requires_grad來開啟張量計算了,這是因為model在計算的時候自己就開了【torch.tensor(0.0, requires_grad=True)】

啟用函式

啟用函式其實也是函式,就是把x進行一下資料轉換。
我們上篇文章已經使用過了Sigmoid把資料轉換成百分比了。
下面看一下最受歡迎的啟用函式都有什麼,如下:

# Most popular activationfunctions
# 1. Step function
# 2. Sigmoid
# 3. TanH
# 4. ReLU (不知道用什麼,就用這個)
# 5. Leaky ReLU6. Softmax

各個啟用函式x轉換成y的模式
image
image
image
image
image
啟用函式使用參考下面程式碼

import torch
import torch.nn as nn
import numpy as np
import torch.nn.functional as F #nn不好使時,在這裡找啟用函式
# 方法1 (create nn modules)
class NeuralNet(nn.Module):
    def __init__(self, input_size, hidden_size):
        super(NeuralNet, self)._init ()
        self.linear1 =nn.Linear(input_size,hidden_size)
        self.relu = nn.ReLU()
        self.linear2 =nn.inear(hidden_size,1)
        self.sigmoid = nn.Sigmoid()
    def forward(self, x):
        out = self.linear1(x)
        out = self.relu(out)
        out = self.linear2(out)
        out = self.sigmoid(out)
        return out
    
# 方法2 (use activation functions directly in forward pass)
class NeuralNet(nn.Module):
    def __init__(self, input_size, hidden_size):
        super(NeuralNet,self).__init__()
        self.linear1 =nn.Linear(input_size,hidden_size)
        self.linear2 =nn.Linear(hidden_size,1)
    def forward(self,x):
        # F.leaky_relu() #leaky_relu使用方法
     
        out = torch.relu(self.linear1(x))
        out = torch.sigmoid(self.linear2(out))
        return out

函式

我們先對下面函式進行一下邏輯理解。

sigmoid,MSELoss,BCELoss

前面我們使用了MSELoss做損失函式,他的邏輯是求y預測和y差的平方的均值,如下圖:
image
後面我們的例子裡,就把MSELoss換成了BCELoss,當時我們就是把他當做一個求損失值的函式,沒研究他的邏輯。
BCELoss的全稱是 Binary Cross Entropy Loss(二元交叉熵損失)他的公式是這樣的。
image
經過這個轉換y_pred的值範圍已經是(0, 1)了。
後來在寫例子的時候,在前向傳播的時候,又增加了torch.sigmoid做資料轉換。
sigmoid的公式是這樣的。
image

softmax和cross_entropy

cross_entropy是 交叉熵損失函式,他的公式是這樣的。
image
結合程式碼理解。

loss = nn.CrossEntropyLoss()
Y= torch.tensor([0]) #這y是一行一列矩陣,但值0表示類別,如0=貓,1=狗,2=兔子
#nsamples x nclasses=1x3  1行3列
Y_pred_good = torch.tensor([[2.0,1.0, 0.1]]) # 這個預測的y裡,2最大,2的索引是0.所以,這個預測的y最可能是貓
Y_pred_bad = torch.tensor([[0.5,2.0,0.3]])  # 這個預測的y裡,2最大,2的索引是1.所以,這個預測的y最可能是狗
11 = loss(Y_pred_good, Y)
12 = loss(Y_pred_bad, Y)
print(l1.item())
print(l2.item())

_,predictions1 = torch.max(Y_pred_good, 1)
_,predictions2 = torch.max(Y_pred_bad, 1)
print(predictions1)
print(predictions2)

多個類別的預測如下:

loss = nn.CrossEntropyLoss()
Y= torch.tensor([2,0,1]) #這y是一行三列矩陣,但值表示的含義是類別,如2,0,1=貓,0,1,2=狗,2,1,0=兔子
#nsamples x nclasses=3x3  3行3列
Y_pred_good = torch.tensor([[2.0,1.0, 2.1],[2.0,1.0, 0.1],[2.0,3.0, 0.1]]) # 這個預測的y裡,三個張量的最大值的索引分別是 2,0,1 ,他跟上面的貓的類別一致,所以是貓這個類別,因為Y的值就代表貓,所以這個是一個好的預測
Y_pred_bad = torch.tensor([[0.5,2.0,0.3],[0.5,2.0,0.3],[0.5,2.0,0.3]])  # 這個預測跟Y不匹配,所以是個不好的預測
11 = loss(Y_pred_good, Y)
12 = loss(Y_pred_bad, Y)
print(l1.item())
print(l2.item())

_,predictions1 = torch.max(Y_pred_good, 1) #values, indices = torch.max(input, dim)
_,predictions2 = torch.max(Y_pred_bad, 1)
print(predictions1)
print(predictions2)

Softmax 啟用函式
假設你有一個模型輸出的向量 [2.0, 1.0, 0.1],應用 Softmax 函式可以將其轉換為 [0.7, 0.2, 0.1],表示各個類別的機率分佈。
公式如下:
image
結合程式碼理解:

# 之前把預測的y都轉成了0~1之間的機率值,現在可以用softmax處理
# softmax
def softmax(x):
    return np.exp(x)/np.sum(np.exp(x), axis=0)


x = np.array([2.0, 1.0, 0.1])
outputs = softmax(x)
print('softmax numpy:', outputs)

torch的softmax使用。

x= torch.tensor([2.0,1.0,0.1])
outputs = torch.softmax(x, dim=0)
print(outputs)

CrossEntropyLoss內部會先申請Softmax函式的執行,在呼叫自己的計算邏輯(就是對數計算那一套)。

傳送門:
零基礎學習人工智慧—Python—Pytorch學習(一)
零基礎學習人工智慧—Python—Pytorch學習(二)
零基礎學習人工智慧—Python—Pytorch學習(三)
零基礎學習人工智慧—Python—Pytorch學習(四)
零基礎學習人工智慧—Python—Pytorch學習(五)
零基礎學習人工智慧—Python—Pytorch學習(六)


注:此文章為原創,任何形式的轉載都請聯絡作者獲得授權並註明出處!



若您覺得這篇文章還不錯,請點選下方的【推薦】,非常感謝!

https://www.cnblogs.com/kiba/p/18369584

相關文章