线性回归pytorch实现笔记

线性回归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) # 真实值

上一篇:【PyTorch】自定义损失函数


下一篇:《动手学深度学习》第二章 预备知识