首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

python线性回归实现

  • 23-11-17 19:21
  • 4454
  • 8265
blog.csdn.net
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
id="article_content" class="article_content clearfix"> id="content_views" class="markdown_views prism-atom-one-light">

2024年我的技术成长之路

大家好,我是小寒。又到年底了,一年过得真快啊!趁着这次活动的机会,和大家聊聊我这一年在技术上的收获和踩过的坑。

说实话,今年工作特别忙,写博客的时间比去年少了不少。不过还是坚持记录一些开发中遇到的问题和解决方案,毕竟这也是我最初写博客的初衷 - 给自己留个笔记,方便以后查阅。

没想到这些随手记录的文章,居然帮助到了不少遇到同样问题的小伙伴。经常看到有博友在评论区说"太感谢了,困扰了好久的问题终于解决了",每次看到这样的评论都特别有成就感!
在这里插入图片描述

一、Spring Cloud踩坑实录

说实话,年初接手一个大型电商的微服务项目时还挺懵的。连连支付的对接就让我头疼了好久,特别是处理异步通知和订单状态同步时翻了不少文档。最后总算搞定了,也写了几篇博客记录解决方案,没想到还挺受欢迎的。
在这里插入图片描述

最让我印象深刻的是解决了一个困扰团队很久的问题:连连支付异步通知总是出现重复通知的情况。当时私下和几个博友讨论了很多实现细节,比如如何处理网络超时、如何避免重复入账等问题,大家互相学习,收获很多。排查下来发现是幂等性处理的问题,小寒准备把这个经历也整理出一篇文章《支付系统异步通知幂等性解决方案》,希望后面能对大家有所帮助。

二、Vue3项目实战经验

今年主要在用Vue3重构我们的管理后台。说真的,从Vue2迁移到Vue3的过程并不轻松。特别是组合式API的使用,一开始真的不适应,老是想用选项式API的思维去写代码。

不过用着用着就发现Vue3真香,特别是