栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

李沐d2l(三)----线性回归+基础算法优化

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

李沐d2l(三)----线性回归+基础算法优化

文章目录
    • 一、线性回归
    • 二、基础优化方法
      • 1 梯度下降
      • 2 小批量随机梯度下降
    • 三、线性回归的从零开始实现
      • 1 准备数据
      • 2 定义模型
      • 3 定义损失函数
      • 4 定义优化算法
      • 5训练过程
    • 四、线性回归的简洁实现

一、线性回归

​ 线性回归是对n维输入的加权,外加偏差,有显示解,可以看做是单层神经网络。使用平方损失来衡量预测值和真实值的差异。

二、基础优化方法 1 梯度下降

​ 当一个模型没有显示解,可以随机挑选一个参数的初试值w0 ,接下来就可以不断的去更新w0 使其接近最优解。

​ 梯度:使得函数值增加最快的方向,那么负梯度就是函数值减少最快的方向。

​ 学习率:简单点就是沿梯度下降的方向走多远。步长的超参数。
选取学习率不能太大也不能太小。

2 小批量随机梯度下降

​ 如果我们在整个训练集上算梯度太贵(一个深度神经网络模型可能需要数分钟至数小时)。我们可以随机采样b个样本i1 ,i2 ,…,ib 来近似损失。

​ b叫做批量大小,不能太大也不能太小。

​ 梯度下降通过不断沿着反梯度方向更新参数求解(不需要知道显示解是多少,知道怎么求导数就行)。小批量随机梯度下降是深度学习默认的求解算法(稳定,简单)

三、线性回归的从零开始实现 1 准备数据
# 1 根据带有噪声的线性模型构造一个人造数据集
# 模型参数:w = [2, -3.4]T、b = 4.2 噪声项ε
# y = Xw + b + ε

def synthetic_data(w, b, num_examples):
  X = torch.normal(0, 1, (num_examples, len(w))) # 均值为0 方差为1
  y = torch.matmul(X, w) + b # y = Xw + b
  y += torch.normal(0, 0.01, y.shape) # 生成噪音ε
  return X, y.reshape((-1, 1)) # (-1,1)按列返回

true_w = torch.tensor([2, -3.4],dtype=torch.float32)
true_b = 4.2
features, lables = synthetic_data(true_w , true_b, 1000)
print('features:', features[0])
print('labels:', lables[0])
'''
features: tensor([-0.5429,  0.1806]) 
label: tensor([2.4989])

'''
d2l.set_figsize()
d2l.plt.scatter(features[:, 1].numpy(), lables.numpy(),1)
d2l.plt.show()

# 2定义一个data_iter函数, 该函数接收批量大小、特征矩阵和标签向量作为输入,生成大小为batch_size的小批量

def data_iter(batch_size, features, lables):
  num_examples = len(features)
  indices = list(range(num_examples)) # 生成样本的index
  random.shuffle(indices) # 打乱样本的index 随机读取样本
  for i in range(0, num_examples, batch_size):
    batch_indices = torch.tensor(
      indices[i:min(i + batch_size, num_examples)]  # 取最小值防止超出样本的个数    
    )
    yield features[batch_indices], lables[batch_indices]

batch_size = 10

for X, y in data_iter(batch_size, features, lables):
  print(X,'n',y)
  break

'''
tensor([[-0.4638, -1.0647,  1.1759],
        [ 0.5158, -2.1620,  0.7834],
        [ 1.4027, -0.0528,  0.6485],
        [-0.2318, -0.2451,  0.4256],
        [ 0.3590,  0.3890, -1.0164],
        [ 0.4841,  1.3309, -0.6631],
        [ 0.5700, -2.0868, -0.1137],
        [-0.2945,  0.2916, -0.1805],
        [ 0.7160,  3.0186, -0.2911],
        [-1.5102, -0.0275, -1.0024]]) 
 tensor([[11.1658],
        [14.8540],
        [ 9.7753],
        [ 6.1807],
        [-0.2932],
        [-1.4828],
        [11.1567],
        [ 2.0055],
        [-4.6159],
        [-2.7399]])

'''
2 定义模型
# 3 定义模型
w = torch.normal(0, 0.01, size = {2,1}, requires_grad=True)
b = torch.zeros(1,requires_grad=True)

# 线性回归模型
def linreg(X, w, b):
  return torch.matmul(X, w) + b
3 定义损失函数
# 4损失函数
def squared_loss(y_hat, y):
  '''均方损失'''
  return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
4 定义优化算法
# 5定义优化算法
def sgd(params, lr, batch_size):
  '''小批量随机梯度下降'''
  with torch.no_grad():
    for param in params:
      param -= lr * param.grad / batch_size # 这里要求均值
      param.grad.zero_() # 把梯度设为0,这样下一次计算的梯度就不会跟上一次相关
5训练过程
# 6训练过程
lr = 0.03 #学习率
num_epochs = 3 #循环3次
net = linreg # 定义的模型
loss = squared_loss # 定义的损失

for epoch in range(num_epochs):
  for X, y in data_iter(batch_size, features, lables): #每次拿出一个批量大小的X和y
    l = loss(net(X, w, b), y) # 把X w b 放进模型进行预测得到y'和真实的y做损失
    #l是一个batch_size的向量
    l.sum().backward() # 求和后做梯度
    sgd([w, b], lr, batch_size)
  with torch.no_grad():
    train_l = loss(net(features, w, b), lables)
    print(f'epoch {epoch + 1}, loss{float(train_l.mean()):f}')

比较真实参数和通过训练学到的参数来评估训练的成功程度

print(f'w的估计误差:{true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差:{true_b - b}')

'''
w的估计误差:tensor([0.0001, 0.0004], grad_fn=)
b的估计误差:tensor([0.0005], grad_fn=)
'''
四、线性回归的简洁实现
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l

# 1定义真实值,调用人工数据函数生成features和lables
true_w = torch.tensor([2,-3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)

# 2定义函数构建数据集,并打乱循序,每次batch_size读取
def load_array(data_arrays, batch_size, is_train=True):
  dataset = data.TensorDataset(*data_arrays)
  return data.DataLoader(dataset, batch_size, shuffle=is_train)

batch_size = 10
data_iter = load_array((features, labels), batch_size)

# print(next(iter(data_iter)))

# 3模型的定义
from torch import nn # 'nn'神经网络的缩写
net = nn.Sequential(nn.Linear(2, 1)) #输入维度是2,输出维度是1 Sequential相当于一个集合
net[0].weight.data.normal_(0, 0.01) 
net[0].bias.data.fill_(0)

# 4计算均方误差,使用MSELoss类(平方范数)
loss = nn.MSELoss()

# 5优化算法
trainer = torch.optim.SGD(net.parameters(), lr=0.03) #第一个参数包括net的w和b,第二个参数是学习率

# 6训练过程
num_epochs = 3
for epoch in range(num_epochs):
  for X, y in data_iter:
    l = loss(net(X), y)
    trainer.zero_grad() # 梯度清0
    l.backward()
    trainer.step() # 模型更新
  l = loss(net(features), labels)
  print(f'epoch {epoch + 1}, loss {l:f}')
    '''
epoch 1, loss 0.000170
epoch 2, loss 0.000094
epoch 3, loss 0.000097
    '''

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1018695.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号