糖尿病數(shù)據(jù)集來源:UCI
1.特征包括:懷孕次數(shù)璧函,血糖,血壓哈恰,胰島素等特征
2.target:預(yù)測是否患糖尿病---0/1
這是一個典型的二分類問題圾另,可以用Sigmoid函數(shù)來解決
1. 數(shù)據(jù)集構(gòu)建
構(gòu)建自己的DiabetesDataSet類,繼承自torch中的Dataset
from torch.utils.data import Dataset # 構(gòu)建數(shù)據(jù)集
# dataset是一個抽象類,不能實例化,必須先用子類繼承該抽象類
class DiabetesDataSet(Dataset):
def __init__(self, filepath):
xy = np.loadtxt(filepath, delimiter=" ", dtype=np.float32)
self.len = xy.shape[0] # 讀取矩陣第一維的長度
# self.shape = xy.shape() # 讀取矩陣的形狀
# 若不寫 self. 開頭的話, 那么x_data就是函數(shù)內(nèi)部的成員變量
# 若寫了 self. 的話,那么這個成員變量就是類中的成員變量
self.x_data = torch.from_numpy(xy[:, :-1])
self.y_data = torch.from_numpy(xy[:, [-1]])
# 通過 index 獲得數(shù)據(jù)索引
def __getitem__(self, index):
return self.x_data[index], self.y_data[index]
# 獲取數(shù)據(jù)的長度 length
def __len__(self):
return self.len
# 初始化數(shù)據(jù)集
dataset = DiabetesDataSet("../DataSet/diabetes/diabetes_data.csv.gz")
2. 用Pytorch提供的DataLoader來加載數(shù)據(jù)集
# dataset:數(shù)據(jù)集 batch_size:mini-batch的大小 shuffle:是否打亂數(shù)據(jù)集順序 num_workers:讀取 batch 時采用的多線程的線程數(shù)
train_loader = DataLoader(dataset=dataset, batch_size=64, shuffle=True, num_workers=0)
3.采用全連接的神經(jīng)網(wǎng)絡(luò)诸衔,最后用sigmoid來處理output
# 構(gòu)建神經(jīng)網(wǎng)絡(luò)模型
class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()
# 線性模型: y = w*x + b
# 在線性模型 Linear 類中,第一次訓(xùn)練時的參數(shù) w 和 b 都是給的隨機數(shù)盯漂,所以多次運行代碼,結(jié)果不大相同
self.linear1 = torch.nn.Linear(9, 6)
self.linear2 = torch.nn.Linear(6, 4)
self.linear3 = torch.nn.Linear(4, 1)
self.sigmoid = torch.nn.Sigmoid()
# 類里面定義的每個函數(shù)都需要有個參數(shù)self,來代表自己笨农,用來調(diào)用類中的成員變量和方法
def forward(self, x):
x = self.linear1(x)
x = self.linear2(x)
x = self.linear3(x)
x = self.sigmoid(x)
return x
4. 構(gòu)建損失函數(shù)和優(yōu)化器
損失函數(shù)采用BCELoss計算兩個分布之間的差異
優(yōu)化器采用 SGD 隨機梯度優(yōu)化算法
# 構(gòu)建損失函數(shù)和優(yōu)化器:BCELoss---運用交叉熵計算兩個分布之間的差異
criterion = torch.nn.BCELoss(reduction="mean")
opt = torch.optim.SGD(params=model.parameters(), lr=0.001)
5.完整代碼
# -*- codeing = utf-8 -*-
import numpy as np
import torch
from matplotlib import pyplot as plt
from torch.utils.data import Dataset # 構(gòu)建數(shù)據(jù)集
from torch.utils.data import DataLoader # 加載數(shù)據(jù) mini-batch 以供訓(xùn)練
# dataset是一個抽象類,不能實例化,必須先用子類繼承該抽象類
class DiabetesDataSet(Dataset):
def __init__(self, filepath):
xy = np.loadtxt(filepath, delimiter=" ", dtype=np.float32)
self.len = xy.shape[0] # 讀取矩陣第一維的長度
# self.shape = xy.shape() # 讀取矩陣的形狀
# 若不寫 self. 開頭的話, 那么x_data就是函數(shù)內(nèi)部的成員變量
# 若寫了 self. 的話,那么這個成員變量就是類中的成員變量
self.x_data = torch.from_numpy(xy[:, :-1])
self.y_data = torch.from_numpy(xy[:, [-1]])
# 通過 index 獲得數(shù)據(jù)索引
def __getitem__(self, index):
return self.x_data[index], self.y_data[index]
# 獲取數(shù)據(jù)的長度 length
def __len__(self):
return self.len
# 初始化數(shù)據(jù)集
dataset = DiabetesDataSet("../DataSet/diabetes/diabetes_data.csv.gz")
# dataset:數(shù)據(jù)集 batch_size:mini-batch的大小 shuffle:是否打亂數(shù)據(jù)集順序 num_workers:讀取 batch 時采用的多線程的線程數(shù)
train_loader = DataLoader(dataset=dataset, batch_size=64, shuffle=True, num_workers=0)
# 2.構(gòu)建神經(jīng)網(wǎng)絡(luò)模型
class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()
# 線性模型: y = w*x + b
# 在線性模型 Linear 類中,第一次訓(xùn)練時的參數(shù) w 和 b 都是給的隨機數(shù)就缆,所以多次運行代碼,結(jié)果不大相同
self.linear1 = torch.nn.Linear(9, 6)
self.linear2 = torch.nn.Linear(6, 4)
self.linear3 = torch.nn.Linear(4, 1)
self.sigmoid = torch.nn.Sigmoid()
# 類里面定義的每個函數(shù)都需要有個參數(shù)self,來代表自己谒亦,用來調(diào)用類中的成員變量和方法
def forward(self, x):
x = self.linear1(x)
x = self.linear2(x)
x = self.linear3(x)
x = self.sigmoid(x)
return x
model = Model()
# 3.構(gòu)建損失函數(shù)和優(yōu)化器:BCELoss---運用交叉熵計算兩個分布之間的差異
criterion = torch.nn.BCELoss(reduction="mean")
opt = torch.optim.SGD(params=model.parameters(), lr=0.001)
epochs = []
costs = []
# 4.開始訓(xùn)練
for epoch in range(300):
epochs.append(epoch)
# enumerate: 在循環(huán)列表或元組的同時引入下標 i
# zip: 將兩個 list 或 tuple , 取出一一對應(yīng)
for i, data in enumerate(train_loader, 0):
inputs, labels = data
# 前向計算模型訓(xùn)練輸出的值
y_pred_data = model(inputs)
# 計算訓(xùn)練輸出的值和真實的值之前的分布差異
loss = criterion(y_pred_data, labels)
print(print("epoch=", epoch, "batch=", i, "loss=", loss.item()))
# 重置梯度
opt.zero_grad()
# 計算梯度反向傳播
loss.backward()
# 優(yōu)化器根據(jù)梯度值進行優(yōu)化
opt.step()
costs.append(loss.item())
# 5.進行模型測試
# 6.訓(xùn)練過程可視化
plt.plot(epochs, costs)
plt.ylabel('Cost')
plt.xlabel('Epoch')
plt.show()
6.結(jié)果展示
result.png