线性回归pytorch实现笔记
本周首先学的是《动手学深度学习(pytorch版)》里面的线性回归的实现,但是有些东西看不懂,所以先在b站上找了个简单的视频跟着学了一遍
实例一 【用 Pytorch 实现一个简单的线性回归】
课程来自:
PyTorch 从入门到精通(5)—用 Pytorch 实现一个简单的线性回归
先导入包和模块
import torch
import numpy as np
from tqdm import tqdm
我们给定样本集inputs和实际值targets
inputs = np.array( [[73,67,43],
[91,88,64],
[87,134,58],
[102,43,37],
[69,96,70]],dtype='float32')
targets = np.array([[56,70],
[81,101],
[119,133],
[22,37],
[103,119]],dtype='float32')
inputs_tensor = torch.from_numpy(inputs)
targets_tensor = torch.from_numpy(targets)
随机生成参数:权重和偏差
w = torch.randn(2, 3, requires_grad=True)
b = torch.randn(2, requires_grad=True)
# print(w)
# print(b)
看一下生成的随机参数
tensor([[-2.2122, 0.4708, -0.9458],
[ 1.6726, 1.2096, -0.2875]], requires_grad=True)
tensor([-0.1555, -0.4671], requires_grad=True)
建立线性回归的函数
def model(x):
return x @ w.t() + b
pred = model(inputs_tensor) # 预测结果
# print(pred)
预测结果pred的值为
tensor([[ 116.6629, -163.4659],
[ 148.9410, -221.4479],
[ 375.6723, -230.6700],
[ -30.1504, -168.7918],
[ 211.2514, -214.7471]], grad_fn=< AddBackward0 >)
显然pred和targets差的很远。
建立损失函数
# metric ()
def mse(pred, ground_truth):
diff = pred - ground_truth
return torch.sum(diff*diff) / diff.numel()
loss = mse(pred, targets_tensor) # 损失函数
# print(loss)
求梯度,迭代一次
loss.backward() # 反向传播
# print(w)
# print(w.grad)
w.grad.zero_()
b.grad.zero_()
# print(w.grad)
# print(b.grad)
with torch.no_grad(): # 这里不用求梯度
w -= w.grad * 1e-5
b -= b.grad * 1e-5
w.grad.zero_()
b.grad.zero_()
# print(w)
# print(b)
迭代一次以后的结果为
tensor([[ 0.6583, 1.5759, 0.2232],
[ 1.3011, -0.0160, -0.3618]], requires_grad=True)
tensor([-0.6590, -1.1407], requires_grad=True)
(第一次参数没保存,重新随机了参数)
迭代5000次
for epoch in tqdm(range(5000)): # 不断迭代
preds = model(inputs_tensor)
loss = mse(preds, targets_tensor)
loss.backward()
with torch.no_grad():
w -= w.grad * 1e-5
b -= b.grad * 1e-5
w.grad.zero_()
b.grad.zero_()
# print(w)
# print(b)
迭代结果是:
100%|██████████| 5000/5000 [00:00<00:00, 5326.52it/s]tensor([[-0.3965, 0.8490, 0.6874],
[-0.2831, 0.8030, 0.8995]], requires_grad=True)
tensor([-0.3978, -1.7858], requires_grad=True)
使用迭代过后的参数求预测值
preds = model(inputs_tensor)
loss = mse(preds, targets_tensor)
print(loss) # 损失值
print(preds) # 预测值
print(targets) # 真实值
输出结果:
100%|██████████| 5000/5000 [00:00<00:00, 5600.33it/s]tensor(0.6086, grad_fn=)
tensor([[ 57.4097, 70.6969],
[ 82.0064, 100.3976],
[118.7603, 132.9620],
[ 21.0812, 36.9854],
[101.8528, 119.1335]], grad_fn=< AddBackward0 >)
[[ 56. 70.]
[ 81. 101.]
[119. 133.]
[ 22. 37.]
[103. 119.]]
对比pred和targets,已经非常接近了,这是一次成功的简单线性回归。
全部代码:
import torch
import numpy as np
from tqdm import tqdm
#temp
#linear
inputs = np.array( [[73,67,43],
[91,88,64],
[87,134,58],
[102,43,37],
[69,96,70]],dtype='float32')
targets = np.array([[56,70],
[81,101],
[119,133],
[22,37],
[103,119]],dtype='float32')
inputs_tensor = torch.from_numpy(inputs)
targets_tensor = torch.from_numpy(targets)
# y = x @ w^T + b
# y (batch, 2)
# x = (batch, 3)
# w^T (3, 2) = batch 2 w(2, 3)
# b(2)
w = torch.randn(2, 3, requires_grad=True)
b = torch.randn(2, requires_grad=True)
# print(w)
# print(b)
def model(x):
return x @ w.t() + b
pred = model(inputs_tensor) # 预测结果
# print(pred)
# metric ()
def mse(pred, ground_truth):
diff = pred - ground_truth
return torch.sum(diff*diff) / diff.numel()
loss = mse(pred, targets_tensor) # 损失函数
# print(loss)
loss.backward()
# print(w)
# print(w.grad)
w.grad.zero_()
b.grad.zero_()
# print(w.grad)
# print(b.grad)
with torch.no_grad():
w -= w.grad * 1e-5
b -= b.grad * 1e-5
w.grad.zero_()
b.grad.zero_()
# print(w)
# print(b)
for epoch in tqdm(range(5000)): # 不断迭代
preds = model(inputs_tensor)
loss = mse(preds, targets_tensor)
loss.backward()
with torch.no_grad():
w -= w.grad * 1e-5
b -= b.grad * 1e-5
w.grad.zero_()
b.grad.zero_()
# print(w)
# print(b)
preds = model(inputs_tensor)
loss = mse(preds, targets_tensor)
print(loss) # 损失值
print(preds) # 预测值
print(targets) # 真实值