【小白學(xué)習(xí)PyTorch教程】七、基于乳腺癌數(shù)據(jù)集??構(gòu)建Logistic 二分類模型
「@Author:Runsen」
在邏輯回歸中預(yù)測的目標(biāo)變量不是連續(xù)的,而是離散的。可以應(yīng)用邏輯回歸的一個示例是電子郵件分類:標(biāo)識為垃圾郵件或非垃圾郵件。圖片分類、文字分類都屬于這一類。
在這篇博客中,將學(xué)習(xí)如何在 PyTorch 中實現(xiàn)邏輯回歸。
1. 數(shù)據(jù)集加載
在這里,我將使用來自 sklearn 庫的乳腺癌數(shù)據(jù)集。這是一個簡單的二元類分類數(shù)據(jù)集。從 sklearn.datasets 模塊加載。接下來,可以使用內(nèi)置函數(shù)從數(shù)據(jù)集中提取 X 和 Y,代碼如下所示。
from sklearn import datasets
breast_cancer=datasets.load_breast_cancer()
x,y=breast_cancer.data,breast_cancer.target
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test= train_test_split(x,y,test_size=0.2)
在上面的代碼中,測試大小表示要用作測試數(shù)據(jù)集的數(shù)據(jù)的比例。因此,80% 用于訓(xùn)練,20% 用于測試。
2. 預(yù)處理
由于這是一個分類問題,一個好的預(yù)處理步驟是應(yīng)用標(biāo)準(zhǔn)的縮放器變換。
scaler=sklearn.preprocessing.StandardScaler()
x_train=scaler.fit_transform(x_train)
x_test=scaler.fit_transform(x_test)
現(xiàn)在,在使用Logistic 模型之前,還有最后一個關(guān)鍵的數(shù)據(jù)處理步驟。在Pytorch 需要使用張量。因此,我們使用“torch.from_numpy()”方法將所有四個數(shù)據(jù)轉(zhuǎn)換為張量。
在此之前將數(shù)據(jù)類型轉(zhuǎn)換為 float32很重要。可以使用“astype()”函數(shù)來做到這一點(diǎn)。
import numpy as np
import torch
x_train=torch.from_numpy(x_train.astype(np.float32))
x_test=torch.from_numpy(x_test.astype(np.float32))
y_train=torch.from_numpy(y_train.astype(np.float32))
y_test=torch.from_numpy(y_test.astype(np.float32))
我們知道 y 必須采用列張量而不是行張量的形式。因此,使用代碼中所示的view操作執(zhí)行此更改。對 y_test 也做同樣的操作。
y_train=y_train.view(y_train.shape[0],1)
y_test=y_test.view(y_test.shape[0],1)
預(yù)處理步驟完成,您可以繼續(xù)進(jìn)行模型構(gòu)建。
3. 模型搭建
現(xiàn)在,我們已準(zhǔn)備好輸入數(shù)據(jù)。讓我們看看如何在 PyTorch 中編寫用于邏輯回歸的自定義模型。第一步是用模型名稱定義一個類。這個類應(yīng)該派生torch.nn.Module。
在類內(nèi)部,我們有__init__ 函數(shù)和 forward函數(shù)。
class Logistic_Reg_model(torch.nn.Module):
def __init__(self,no_input_features):
super(Logistic_Reg_model,self).__init__()
self.layer1=torch.nn.Linear(no_input_features,20)
self.layer2=torch.nn.Linear(20,1)
def forward(self,x):
y_predicted=self.layer1(x)
y_predicted=torch.sigmoid(self.layer2(y_predicted))
return y_predicted
在__init__方法中,必須在模型中定義所需的層。在這里,使用線性層,可以從 torch.nn 模塊聲明。需要為圖層指定任何名稱,例如本例中的“l(fā)ayer1”。所以,我已經(jīng)聲明了 2 個線性層。
語法為:torch.nn.Linear(in_features, out_features, bias=True)接下來,也要有“forward()”函數(shù),負(fù)責(zé)執(zhí)行前向傳遞/傳播。輸入通過之前定義的 2 個層。此外,第二層的輸出通過一個稱為 sigmoid的激活函數(shù)。
激活函數(shù)用于捕捉線性數(shù)據(jù)中的復(fù)雜關(guān)系。在這種情況下,我們使用 sigmoid 激活函數(shù)。
在這種情況下,我們選擇 sigmoid 函數(shù)的原因是它會將值限制為(0 到 1)。下面是 sigmoid 函數(shù)的圖形及其公式

4. 訓(xùn)練和優(yōu)化
定義類后,初始化模型。
model=Logistic_Reg_model(n_features)
現(xiàn)在,需要定義損失函數(shù)和優(yōu)化算法。在 Pytorch 中,可以通過簡單的步驟選擇并導(dǎo)入所需的損失函數(shù)和優(yōu)化算法。在這里,選擇 BCE 作為我們的損失標(biāo)準(zhǔn)。
BCE代表二元交叉熵?fù)p失。它通常用于二元分類示例。值得注意的一點(diǎn)是,當(dāng)使用 BCE 損失函數(shù)時,節(jié)點(diǎn)的輸出應(yīng)該在(0-1)之間。我們需要為此使用適當(dāng)?shù)募せ詈瘮?shù)。
對于優(yōu)化器,選擇 SGD 或隨機(jī)梯度下降。SGD 算法,通常用作優(yōu)化器。還有其他優(yōu)化器,如 Adam、lars 等。
優(yōu)化算法有一個稱為學(xué)習(xí)率的參數(shù)。這基本上決定了算法接近局部最小值的速率,此時損失最小。這個值很關(guān)鍵。

因為如果學(xué)習(xí)率值太高,算法可能會突然出現(xiàn)并錯過局部最小值。如果它太小,則會花費(fèi)大量時間并且可能無法收斂。因此,學(xué)習(xí)率“l(fā)r”是一個超參數(shù),應(yīng)該微調(diào)到最佳值。
criterion=torch.nn.BCELoss()
optimizer=torch.optim.SGD(model.parameters(),lr=0.01)
接下來,決定 epoch 的數(shù)量,然后編寫訓(xùn)練循環(huán)。
number_of_epochs=100
for epoch in range(number_of_epochs):
y_prediction=model(x_train)
loss=criterion(y_prediction,y_train)
loss.backward()
optimizer.step()
optimizer.zero_grad()
if (epoch+1)%10 == 0:
print('epoch:', epoch+1,',loss=',loss.item())
如果發(fā)生了第一次前向傳播。接下來,計算損失。當(dāng)loss.backward()被調(diào)用時,它計算損失相對于(層的)權(quán)重的梯度。然后通過調(diào)用optimizer.step()更新權(quán)重。之后,必須為下一次迭代清空權(quán)重。因此調(diào)用 zero_grad()方法。
計算準(zhǔn)確度
with torch.no_grad():
y_pred=model(x_test)
y_pred_class=y_pred.round()
accuracy=(y_pred_class.eq(y_test).sum())/float(y_test.shape[0])
print(accuracy.item())
# 0.92105
使用torch.no_grad(),目的是基跳過權(quán)重的梯度計算。所以,我在這個循環(huán)中寫的任何內(nèi)容都不會導(dǎo)致權(quán)重發(fā)生變化,因此不會干擾反向傳播過程。
