Pytorch實戰-logistic 迴歸二元分類代碼詳細註釋

 

1、logistic 迴歸介紹
logistic 迴歸是一種廣義線性迴歸 (generalized linear model),與多重線性迴歸分析有很多相同之處。它們的模型形式基本上相同,都具有 wx+b,其中 w 和 b 是待求參數,其區別在於他們的因變量不同,多重線性迴歸直接將 wx+b 作爲因變量,即 y=wx+b,而 logistic 迴歸則通過函數L 將 wx+b 對應一個隱狀態 p, p = L(wx+b), 然後根據 p 與 1-p 的大小決定變量的值。如果 L 是logistc 函數,就是 logistic 迴歸,如果 L是多項式函數就是多項式回說的更通俗一點,就是 logistc 迴歸會在線性迴歸後再加一層 logistic 函數的調用。
logistic 迴歸主要是進行二分類預測,我們在激活函數時候講到過 Sigmod 函數, Sigmod 函數是最常見的 logistc 函數爲 Sigmod 函數的輸出的是是對於 0-1 之間的概率值,當概率大於 0.5預測爲 1,小於 0.5 預測爲 0。


2、數據集

德國信用數據集:UCI German Credit
https://archive.ics.uci.edu/ml/machine-learning-databases/statlog/german/


3、代碼實戰

# 導入相關的包

import torch # torch 是一種科學計算框架
import torch.nn as nn # torch.nn 神經網絡的接口
import numpy as np # numpy 科學計算的軟件包
torch.__version__ # 查看 torch 的版本


# 使用 numpy 的 load 方法讀取數據

data = np.loadtxt("german.data-numeric")


注:
numpy 中的 loadtxt() 函數可以用來讀取文件,主要是 txt 文件;

# 對數據做一下歸一化處理

n, l = data.shape
for j in range(l-1):
    meanVal = np.mean(data[:, j])  
    stdVal = np.std(data[:, j])  
    data[:, j] = (data[:, j]-meanVal) / stdVal


注:

  • n, l = data.shape --讀取 data 的大小;n 代表行數,l 代表列數

實例:

  • data[:, j] --讀取 data 所有行的 j 列的數

實例:

  • meanVal = np.mean(data[:, j]) # 求 data 所有行 j 列所有數的平均值
  • stdVal = np.std(data[:, j]) # 求 data 所有行 j 列所有數的方差
  • data[:, j] = (data[:, j]-meanVal)/stdVal # 歸一化


# 打亂數據

np.random.shuffle(data)

注:
shuffle() 方法將序列的所有元素隨機排序,但 shuffle() 是不能直接訪問的,需要導入 random 模塊,然後通過 random 靜態對象調用該方法。

# 區分訓練集和測試集

由於這裏沒有驗證集,所以我們直接使用測試集的準確度作爲評判好壞的標準
區分規則:900條用於訓練,100條作爲測試訓練

train_data = data[: 900, : l-1] # 訓練試集
train_lab = data[: 900, l-1] -1 # 訓練標籤
test_data = data[900: , : l-1] # 測試集
test_lab = data[900: , l-1] - 1 # 測試標籤


注意:
這裏爲什麼需要在 label 中 -1 呢?
打開原始數據看一下就明白了,主要原因是原始的數據標籤範圍是1和2,而在代碼中使用的是sigmoid函數,其對應的範圍是 0-1,因此需要把原始的 label-1.

# 定義模型

class LR(nn.Module):
    def __init__(self):  # 構造函數
        super(LR,self).__init__() # 繼承父類的構造方法,等價於 LR.__init__(self)
        self.fc = nn.Linear(24, 2) 
    
    # 定義前向傳播函數
    def forward(self,x):
        out = self.fc(x) 
        out = torch.sigmoid(out)
        return out 


注:

  • nn.Linear(24, 2) --- 對輸入的數據進行線性變換 y = x + b

原型: torch.nn.Linear(in_features, out_features, bias=True)
參數: in_features -- 輸入樣本數據的大小
out_features -- 輸出樣本數據的大小;
bias -- 如果設置爲 False,則該圖層將不會學習加法偏差。默認值:True

參考 :https://pytorch.org/docs/master/nn.html#torch.nn.Linear

# 測試集上的準確率

def test(pred,lab):
    t = pred.max(-1)[1] == lab
    return torch.mean(t.float())

注:

  • pred.max(-1) --- 表示取 pred 每一行的最大值;
  • Pred.max(-1)[1] --- 表示取 pred 每一行最大值的索引;

實例:


參考:https://blog.csdn.net/jzwong/article/details/103267516

  • t = pred.max(-1)[1] == lab --- 返回的是一個長度爲樣本個數的 0,1 向量
  • torch.mean(t.float()) --- 準確率的定義,其實就是計算 1 佔整個樣本的比率


# 設置

net = LR() # 類的實例化,創建一個實例
criterion = nn.CrossEntropyLoss() # 使用 CrossEntropyLoss 損失
optm = torch.optim.Adam(net.parameters()) # Adam 優化
epochs = 1000 # 訓練 1000 次


# 開始訓練

for i in range(epochs):
    # 指定模型爲訓練模式,計算梯度
    net.train()
    # 輸入值都需要轉換成 torch 的Tensor
    x = torch.from_numpy(train_data).float()
    y = torch.from_numpy(train_lab).long()
    y_hat = net(x)
    loss = criterion(y_hat, y) # 計算損失
    optm.zero_grad() # 前一步的損失清零
    loss.backward() # 反向傳播
    optm.step() # 優化
    if (i + 1) % 100  == 0:  # 這裏我們每 100 次輸出相關的信息
        # 指定模型爲計算模式
        net.eval()
        test_in = torch.from_numpy(test_data).float()
        test_l = torch.from_numpy(test_lab).float()
        test_out = net(test_in)
        # 使用我們的測試函數計算準確率
        accu = test(test_out, test_l)
        print("Epoch:{}, Loss:{:.4f}, Accurary:{:.2f}".format(i+1, loss.item(),accu))


準確率:

 

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