分类模型
- 输入:
- 输出:
- 由总共有多少个类别决定
- 2分类
- 有多少个输出,就有多少个偏置
信息熵
import numpy as np
probs = np.array([0.999, 0.001, 0.001])
entropy = probs @ np.log2(1 / probs)
entropy
交叉熵
- cross entropy
- 分类问题最重要的损失函数
- 衡量预测结果和真实分类之间的误差
- 本质:从概率分布的角度来衡量损失
"""
总共有3类:
- 0, 1, 2
- 真实标签:2
"""
# 真实标签
y_true = 2
# 预测结果(原始输出)
# y_pred = np.array([-0.32, 0.04, 1.98])
y_pred = np.array([-0.32, 1.90, 1.98])
# 1,把真实标签变为概率分布(one-hot)
y_true = np.array([0.0, 0.0, 1.0])
# 2,把模型原始预测输出变为概率分布(softmax)
y_pred = np.exp(y_pred) / np.exp(y_pred).sum()
# 3. 交叉熵 cross entropy
ce = y_true @ np.log(1 / y_pred)
逻辑回归
1. 加载数据
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)
2. 数据预处理
"""
标准化
- 对特征进行标准化处理
"""
# 提取需要的参数
mu = X_train.mean(axis=0)
sigma = X_train.std(axis=0)
# 预处理特征
X_train = (X_train - mu) / sigma
X_test = (X_test - mu) / sigma
3. 构建模型
import torch
from torch import nn
model = nn.Linear(in_features=30, out_features=2)
4. 准备训练
# 训练步数
steps = 200
# 优化器
optimizer = torch.optim.SGD(params=model.parameters(), lr=1e-3)
# 损失函数
loss_fn = nn.CrossEntropyLoss()
"""
数据转张量
- 全量训练
"""
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)
5. 过程监控
def get_acc(X, y):
"""
计算准确率
"""
with torch.no_grad():
# 1,正向传播
y_pred = model(X)
# 2,解析结果
y_pred = y_pred.argmax(dim=1)
# 3, 计算准确率
acc = (y == y_pred).to(dtype=torch.float32).mean().item()
return acc
6. 训练过程
def train():
# 训练前,测试一下准确率
train_acc = get_acc(X=X_train, y=y_train)
test_acc = get_acc(X=X_test, y=y_test)
print(f"开始训练之前,train_acc: {train_acc}, test_acc: {test_acc}")
for step in range(steps):
# 1, 正向传播
y_pred = model(X_train)
# 2,计算损失
loss = loss_fn(y_pred, y_train)
# 3, 反向传播
loss.backward()
# 4, 优化一步
optimizer.step()
# 5,清空梯度
optimizer.zero_grad()
# 6, 模型评估
train_acc = get_acc(X=X_train, y=y_train)
test_acc = get_acc(X=X_test, y=y_test)
print(f"训练了{step + 1}轮,train_acc: {train_acc}, test_acc: {test_acc}")
train()
7. 模型保存
"""
1,模型整体保存和加载
- 不推荐
"""
torch.save(obj=model, f="model.lxh")
m = torch.load(f="model.lxh")
"""
2, 参数和网络分离式保存
- 骨肉分离
"""
# 1, 保存权重
torch.save(obj=model.state_dict(), f="model.pt")
# 加载模型:1,构建模型(随机初始化)
m = nn.Linear(in_features=30, out_features=2)
m.load_state_dict(state_dict=torch.load(f="model.pt", weights_only=True))
8. 推理流程
# 初始化模型
m = nn.Linear(in_features=30, out_features=2)
# 加载训练好的权重
m.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)
# 数据结构判断 [batch_size, num_features]
if X.ndim !=2 or X.size(1) != 30:
raise ValueError("输入数据有误!!!")
# 模型推理
y_pred = m(X)
y_pred = y_pred.argmax(dim=1)
return y_pred
predict(X=X_test)
y_test