加载数据
import torch
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X ,y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.2, random_state=0)
标准化
mu = X_train.mean(axis=0)
sigma = X_train.std(axis=0)
X_train = (X_train-mu)/sigma
X_test = (X_test-mu)/sigma
转张量
X_train = torch.tensor(data=X_train, dtype=torch.float32)
X_test = torch.tensor(data=X_test, dtype=torch.float32)
y_train = torch.tensor(data=y_train, dtype=torch.long)
y_test = torch.tensor(data=y_test, dtype=torch.long)
定义权重
w = torch.randn(30, 2, requiers_grad=True)
b = torch.zeros(1, 1, requiers_grad=True)
定义模型
def model(X):
return X @ w + b
交叉熵
def get_cross_entropy(y_pred, y_true):
y_true = torch.eye(2)[y_true]
y_pred = torch.exp(y_pred)/torch.exp(y_pred).sum(dim=1, keepdim=True)
cross_entropy = (y_true * torch.log(1/y_pred)).sum(dim=1)
cross_entropy = cross_entropy.mean()
return cross_entropy
开始训练
steps = 200
learning_rate = 1e-2
for step in range(steps):
y_pred = model(X_train)
loss = get_cross_entropy(y_pred, y_train)
loss.backward()
w.data -= learning_rate*w.grad
b.data -= learning_rate*b.grad
w.grad.zero_()
b.grad.zero_()
print(loss.item())
神经网络实现
improt torch
from torch import nn
model = nn.Linear(in_features=30, out_features=2)
steps = 1000
optimizer = torch.optim.SGD(params=model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()
for step in range(steps):
y_pred = model(X_train)
loss = loss_fn(y_pred, y_train)
loss.backward()
optimizer.step()
optimizer.zero_grad()
保存模型
torch.save(model,f="model.lxh")
model = torch.load(f="model.lxh")
torch.save(obj=model.state.dict(), f="model.pt")
model = nn.Linear(in_features=30, out_features=2)
model.load_state_dict(state_dict=torch.load(f="model.pt", weights_only=True))
推理流程
model = nn.Linear(in_features=30, out_features=2)
model.load_state_dict(state_dict=torch.load(f="model.pt", weights_only=True))
def predict(X):
if not isinstance(X, torch.Tensor):
X = torch.tensor(data=X, dtype=torch.float32)
if X.ndim !=2 or X.size(1) != 30:
raise ValueError("输入数据有误!!!")
y_pred = model(X)
y_pred = y_pred.argmax(dim=1)
return y_pred
y_pred= predict(X_test)
(y_pred==y_test).to(dtype=torch.float32).mean()