前言
本文主要講神經網路的上半部分。
這篇文章開始有很多公式了,這些公式都很簡單,但是如果是不經常在腦海裡思考公式的人,那可能需要多花點時間做一下自我訓練,個人感覺,也就幾天時間,就能把自己感覺給調整出來。
習慣了公式看下面內容就會輕鬆很多,另外如果要深入學習人工智慧,熟練的認知公式也是個必須的事情。
另外,我發現我前面文章寫的有歧義的地方還是挺多,雖然,已經改了一部分,但,可能還有沒發現的,大家看的時候儘量多理解著看吧。
本著目的是學會使用神經網路的開發,至於數學的部分,就能過就過吧。
神經網路
先學個例子
先結合以前的知識理解一個例子,理解了這個例子,後面理解神經網路就容易多了。
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的模式
啟用函式使用參考下面程式碼
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差的平方的均值,如下圖:
後面我們的例子裡,就把MSELoss換成了BCELoss,當時我們就是把他當做一個求損失值的函式,沒研究他的邏輯。
BCELoss的全稱是 Binary Cross Entropy Loss(二元交叉熵損失)他的公式是這樣的。
經過這個轉換y_pred的值範圍已經是(0, 1)了。
後來在寫例子的時候,在前向傳播的時候,又增加了torch.sigmoid做資料轉換。
sigmoid的公式是這樣的。
softmax和cross_entropy
cross_entropy是 交叉熵損失函式,他的公式是這樣的。
結合程式碼理解。
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],表示各個類別的機率分佈。
公式如下:
結合程式碼理解:
# 之前把預測的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函式的執行,在呼叫自己的計算邏輯(就是對數計算那一套)。
Dataset
這段程式碼是Dataset和DataLoader的邏輯,簡單理解一下即可。
# https://gist.github.com/tijptjik/9408623 下獲取wine.csv
import torch
import torchvision
from torch.utils.data import Dataset, DataLoader
import numpy as np
import math
import os
class WineDataset(Dataset):
def __init__(self, transform=None):
# data loading
# 獲取指令碼所在的目錄
script_dir = os.path.dirname(__file__)
# 構建檔案的完整路徑
file_path = os.path.join(script_dir, 'wine.csv')
xy = np.loadtxt(file_path, delimiter=",", dtype=np.float32, skiprows=1)
self.x = xy[:, 1:]
self.y = xy[:, [0]] # nsamples, 1
self.n_samples = xy.shape[0]
self.transform = transform
def __getitem__(self, index):
sample = self.x[index], self.y[index]
if (self.transform):
sample = self.transform(sample)
return sample
def __len__(self):
return self.n_samples
class ToTensor:
def __call__(self, sample):
inputs, targets = sample
return torch.from_numpy(inputs), torch.from_numpy(targets)
dataset = WineDataset(transform=ToTensor())
first_data = dataset[0]
feautres, labels = first_data
print(feautres)
print(type(feautres), type(labels))
傳送門:
零基礎學習人工智慧—Python—Pytorch學習(一)
零基礎學習人工智慧—Python—Pytorch學習(二)
零基礎學習人工智慧—Python—Pytorch學習(三)
零基礎學習人工智慧—Python—Pytorch學習(四)
零基礎學習人工智慧—Python—Pytorch學習(五)
零基礎學習人工智慧—Python—Pytorch學習(六)
注:此文章為原創,任何形式的轉載都請聯絡作者獲得授權並註明出處!
若您覺得這篇文章還不錯,請點選下方的【推薦】,非常感謝!
https://www.cnblogs.com/kiba/p/18369584