• python线性回归实现


    import random
    import torch
    
    # ①根据带有噪声的线性模型构造一个人造数据集。 使用线性模型参数w=[2,−3.4]  b=4.2和噪声项ϵ生成数据集及其标签
    def synthetic_data(w, b, num_examples):
        """生成 y = Xw + b + 噪声。"""
        # 生成均值为0,标准差为1,行为num_examples = 1000,列为len(w)=2的矩阵,也就是从一个标准正态分布N~(0,1),提取一个1000*2的矩阵。
        X = torch.normal(0, 1, (num_examples, len(w)))
        # 此时X为1000*2的矩阵,也就是二维张量,w为向量,也就是一维张量,符合normal运算的第四种情况,此时将w转置为列向量,也就是2*1的矩阵,做矩阵乘法结果为1000*1的列向量。
        y = torch.matmul(X, w)+b
        # 生成均值为0,标准差为0.01的噪声加上y,返回新的y
        y += torch.normal(0, 0.01, y.shape)
        # 返回X 将y转置成1列后返回
        return X, y.reshape((-1, 1))
    # 定义w
    true_w = torch.tensor([2, -3.4])
    # 定义b
    true_b = 4.2
    # 生成数据集和标签
    features, labels = synthetic_data(true_w, true_b, 1000)
    # 打印第一个特征和标签,观察数据集和特征格式
    print('features:', features[0], '\nlabel:', labels[0])
    
    # ②定义一个data_iter 函数, 该函数接收批量大小、特征矩阵和标签向量作为输入,生成大小为batch_size的小批量
    def data_iter(batch_size, features, labels):
        # features的len应该是1000
        num_examples = len(features)
        # rang(1000)的一个数据再list一下组成一个列表
        indices = list(range(num_examples))
        # 把序列进行一下乱序
        random.shuffle(indices)
        # 返回一个数据集和标签
        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], labels[batch_indices]
    # 定义尺寸
    batch_size = 10
    # 打印
    for X, y in data_iter(batch_size, features, labels):
        print(X, '\n', y)
        break
    
    # ③定义 初始化模型参数
    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
    
    # ⑤定义损失函数
    def squared_loss(y_hat, y):
        """均方损失。"""
        return (y_hat - y.reshape(y_hat.shape))**2 / 2
    
    # ⑥定义优化算法
    def sgd(params, lr, batch_size):
        """小批量随机梯度下降。"""
        with torch.no_grad():
            for param in params:
                param -= lr * param.grad / batch_size
                param.grad.zero_()
    
    # ⑦训练过程
    # 定义学习率(理解为梯度下降中的步长不知道对不对)
    lr = 0.03
    # 定义学习几轮
    num_epochs = 5
    # 定义网络
    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)
            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}')
            print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
            print(f'b的估计误差: {true_b - b}')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    学习第三轮时候基本已经稳定

    epoch 1, loss 0.035958
    w的估计误差: tensor([ 0.0963, -0.1706])
    b的估计误差: tensor([0.1828])
    epoch 2, loss 0.000128
    w的估计误差: tensor([ 0.0048, -0.0085])
    b的估计误差: tensor([0.0081])
    epoch 3, loss 0.000050
    w的估计误差: tensor([ 0.0003, -0.0001])
    b的估计误差: tensor([0.0006])
    epoch 4, loss 0.000050
    w的估计误差: tensor([4.5466e-04, 1.8120e-05])
    b的估计误差: tensor([0.0004])
    epoch 5, loss 0.000050
    w的估计误差: tensor([3.6359e-05, 3.4094e-05])
    b的估计误差: tensor([0.0004])
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    设计模式:迭代器模式(C++实现)
    Unity项目升级支持HDRP管线实践
    17 | DataSource 为何物?加载过程是怎样的
    leetcode 55. 跳跃游戏
    每日两题 131分割回文串 784字母大小写全排列(子集模版)
    三维种子点生长算法(以及Python递归深度问题)
    抖音实战~手机号验证码一键注册登录流程(限制手机终端登录)
    机器学习实战六步法之数据收集方法(四)
    CSS的弹性布局
    基于Acconeer的A121-60GHz毫米波雷达传感器SDK移植及测距示例(STM32L496为例)
  • 原文地址:https://blog.csdn.net/qq_39879126/article/details/134357610