ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

动手学深度学习01 线性回归从零实现

2022-06-16 15:04:14  阅读:243  来源: 互联网

标签:01 features torch batch labels 动手 num 线性 size


1、导入库

# 设置图片画在网页上
%matplotlib inline
import random
import torch
from d2l import torch as d2l

2、人工模拟数据

# 定义一个方法,生成人造数据集
def synthetic_data(w, b, num_examples):
    """生成 y = Xw + b + 噪声"""
#     返回一个随机的张量
#      normal(均值,标准差,可选的输出张量)
    X = torch.normal(0, 1, (num_examples, len(w)))
#     matul 返回两个矩阵的乘积
    y = torch.matmul(X, w) + b
#     加入噪音
    y += torch.normal(0, 0.01, y.shape)
#     把X 和 y 弄成列向量返回
    return X, y.reshape((-1, 1))

true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)

3、查看数据

# 查看训练样本的样子
print('features:', features[0], '\nlabel:', labels[0])

# 输出数据集图像
# 设置图表大小
d2l.set_figsize()
# 等于matplotlib的scatter,用来绘制散点图
# detach保留数值,去除梯度
d2l.plt.scatter(features[:,1].detach().numpy(), labels.detach().numpy(), 1)

image
如图所示是人工生成的数据集,可以明显看出呈线性分布。

4、读取数据

# 定义一个方法实现每次读取一个小批量
def data_iter(batch_size, features, labels):
    num_examples = len(features)
    inices = list(range(num_examples))
#     打乱顺序,使读取样本随机,没有特定顺序
    random.shuffle(inices)
#     遍历数组,每次读取batch_size长度的数据
    for i in range(0, num_examples, batch_size):
        batch_indices = torch.tensor(inices[i:min(i + batch_size,num_examples)])
        yield features[batch_indices],labels[batch_indices]

# 步长
batch_size = 10
for X,y in data_iter(batch_size, features, labels):
#     打印 一次 小批量的样本, 样本大小与batch
    print(X, '\n' , y)
    break


5、定义参数和模型

# 定义初始化模型参数
w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
# 置零
b = torch.zeros(1, requires_grad=True)

# 定义模型
def linreg(X, w, b):
    """线性回归模型, Xw+偏差"""
    return torch.matmul(X,w) + b

6、定义损失函数和优化算法

# 定义损失函数
def squared_loss(y_hat, y):
    """均方损失"""
    return (y_hat - y.reshape(y_hat.shape))**2 / 2

# 定义优化算法
# params 是传进来的list 数据 , lr是学习率, batch_size是步长
# 因为我们计算的损失是一个批量样本的总和,所以我们用批量大小(batch_size)来归一化步长,这样步长大小就不会取决于我们对批量大小的选择
def sgd(params, lr, batch_size):
    """小批量随机梯度下降"""
    with torch.no_grad():
        for param in params:
            param-= lr * param.grad / batch_size
#             torch不会自动把梯度归零,手动归零,使下一次用到梯度就不会和上一次相关
            param.grad.zero_()

7、开始训练过程

# 开始训练
# 定义超参数
# 学习率 太大会不收敛, 太小会下降太慢需要更多轮次的训练
lr = 0.03
# 扫描轮次
num_epochs = 3
# 训练模型
net = linreg
# 损失
loss = squared_loss

for epoch in range(num_epochs):
    for X, y in data_iter(batch_size, features, labels):
        l = loss(net(X, w, b), y) # X 和 y 的小批量损失
#         因为 l 形状是(batch_size, l),而不是一个标量.l 中的所有元素被加到 y
#         并计算[w,b]的梯度
        l.sum().backward()
        sgd([w,b], lr, batch_size)# 使用参数的梯度更新
    with torch.no_grad():
        train_l = loss(net(features, w, b), labels)
        print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')

标签:01,features,torch,batch,labels,动手,num,线性,size
来源: https://www.cnblogs.com/suanai/p/16381971.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有