背景
今天的主题是 线性回归(回归问题)和SoftMax回归(分类问题)
开始着手准备秋招了
一些基础的代码实现是在面试中经常出现的
麻雀虽小 五脏俱全
基础回归包含了在深度学习训练过程中的
数据准备、网络模型、损失函数、优化器、训练及验证的完整流程
需要着重掌握
线性回归
引入基础包
1
2
3import torch
from torch import nn
from torch.utils import data设置基础的参数
1
2
3
4
5
6true_w = torch.Tensor([1.5, -2.2, 0.8])
true_b = 2.7
batch_size = 10
epochs = 5
lr = 1e-2
train_size = 1000生成训练数据
1
2
3
4
5
6
7
8def synthetic_data(w, b, num_examples):
X = torch.rand((num_examples, len(w)))
y = torch.matmul(X, w) + b
y += torch.rand(1)
return X, y.reshape(-1, 1)
features, labels = synthetic_data(true_w, true_b, train_size)
print(features.shape, labels.shape)
# (torch.Size([1000, 3]), torch.Size([1000, 1]))准备数据,选择模型、损失以及优化器
1
2
3
4
5net = nn.Sequential(nn.Linear(3, 1))
loss = nn.MSELoss()
optim = torch.optim.SGD(net.parameters(), lr=lr)
dataset = data.TensorDataset(feature, labels)
dataIter = data.DataLoader(dataset, batch_size, shuffle=True)开始训练
1
2
3
4
5
6
7
8for epoch in range(epochs):
for X, y in dataIter:
l = loss(net(X), y)
optim.zero_grad() # 将上一次的梯度清零
l.backward() # 计算梯度
optim.step() # 梯度下降
l = loss(net(features), labels)
print(f'epoch{epoch}: loss{l: f}')查看训练结果(模型参数)
1
2
3for param in net.parameters():
print(param)
print(true_w, true_b)
softmax回归
用softmax回归来解决分类问题
使用单层的全连接层来解决图片分类问题
和线性回归大同小异 只是需要最后处理一下类别
用softmax + cross_entropy 来作为损失函数进行模型的训练
引入基础包
1
2
3
4import torch
import torchvision
from torchvision import transform
from torch import nn设置基础参数
1
2
3batch_size = 256
lr = 0.1
num_epochs = 10生成训练数据
1
2
3
4
5
6
7def load_data_fashion_mnist(batch_size, resize=None):
trans = transforms.ToTensor()
mnist_train = torchvision.datasets.FashionMNIST(root='../data', train=True, transform=trans, download=True) # dataset
mnist_test = torchvision.datasets.FashionMNIST(root='../data', train=False, transform=trans, download=True)
return (data.DataLoader(mnist_train, batch_size, shuffle=True),
data.DataLoader(mnist_test, batch_size, shuffle=True)) #dataIter
train_iter, test_iter = load_data_fashion_mnist(batch_size)设置模型、损失以及优化器
1
2
3
4
5
6
7def init_weights(w):
if type(w) == nn.Linear:
nn.init.normal_(w.weight, std=0.01)
net = nn.Sequential(nn.Linear(nn.Flatten(), nn.Linear(784, 10)))
net.apply(init_weights)
loss = nn.CrossEntropyLoss(reduction='none')
trainer = torch.optim.SGD(net.parameters(), lr=lr)开始训练
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def accuracy(y_hat, y): # 计算准确率
if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:
y_hat = y_hat.argmax(axis=1)
cmp = y.hat.type(y.d_type) == y
return float(cmp.type(y.dtype).sum())
def train_epoch(net, loss, trainer, train_iter):
net.train()
loss_sum = 0
acc_sum = 0
y_sum = 0
for X, y in train_iter:
y_hat = net(X)
l = loss(y_hat, y)
trainer.zero_grad()
l.mean().backward()
trainer.step()
loss_sum += l
acc_sum += accuracy(y_hat, y)
y_sum += y.numel()
return loss_sum / y_sum, accuracy_sum / y_sum
for epoch in num_epochs:
_loss, _acc = train_epoch(net, loss, trainer, train_iter)
print('epoch {}: loss: {:.6f} acc: {:.4f}'.format(epoch, _loss, _acc))
"""
epoch 0: loss: 0.784160 acc: 0.7510
epoch 1: loss: 0.569403 acc: 0.8135
epoch 2: loss: 0.524297 acc: 0.8260
epoch 3: loss: 0.501037 acc: 0.8328
epoch 4: loss: 0.484912 acc: 0.8363
epoch 5: loss: 0.473458 acc: 0.8403
epoch 6: loss: 0.463434 acc: 0.8437
epoch 7: loss: 0.457866 acc: 0.8452
epoch 8: loss: 0.452482 acc: 0.8459
epoch 9: loss: 0.446812 acc: 0.8478
"""进行预测
1
2
3
4
5
6
7
8
9for X, y in test_iter:
break
trues = y
preds = net(X).argmax(axis=1)
cmp = (trues==preds).sum()
print('acc', len(cmp) / len(trues))
"""
acc 0.859375
"""