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


    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}')
    
  • 相关阅读:
    Java并发基础10:原子性操作类的使用
    Java并发基础09. 多个线程间共享数据问题
    Java并发基础08. 造成HashMap非线程安全的原因
    Java并发基础07. ThreadLocal类以及应用技巧
    Java并发基础06. 线程范围内共享数据
    Java并发基础05. 传统线程同步通信技术
    Java并发基础04. 线程技术之死锁问题
    我是如何从通信转到Java软件开发工程师的?
    IOS 判断耳机插入/拔出
    海量数据处理
  • 原文地址:https://www.cnblogs.com/suanai/p/16381971.html
Copyright © 2020-2023  润新知