深度学习,李沐老师课程笔记_从0开始实现线性回归

对于深度学习,非常推荐李沐老师的课程,受益匪浅

课程视频08 线性回归 + 基础优化算法【动手学深度学习v2】_哔哩哔哩_bilibili

这里对源码做一些注释,希望大家可以更好理解这里面的意思

有基础的也可以直接看代码,来加深理解

若有差错,请与我联系探讨pwp

%matplotlib inline
import random
import torch


# 生成随机特征值和标签,即features和labels当作训练和验证集;这里的features的shape为(num_examples, len(w));labels为torch.matmul(X, w)
def synthetic_data(w, b, num_examples):  
    """生成 y = Xw + b + 噪声。"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    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)
# 这里的features是(1000,2),这里w是(2,),是一维张量,所以可以当成(2,1)去进行matmul。


# 这里是分类器,把数据分为一组一组的形式
def data_iter(batch_size, features, labels):
    num_examples = len(features)
    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
    
    
    # torch.normal 是正态分布中提取的随机数张量,平均数为0,方差为0.01,shape为(2,1);b是全零,一个1维张量
w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)


# return y,y=wx+b
def linreg(X, w, b):  
    """线性回归模型。"""
    return torch.matmul(X, w) + b



# MSE   (features - y)的平方/2,这里是按组算的,所以这里没除大小有点问题,但不大
def squared_loss(y_hat, y):  
    """均方损失。"""
    return (y_hat - y.reshape(y_hat.shape))**2 / 2


# 梯度下降,params是参数,lr是学习率,核心是梯度下降靠:参数减去导数与学习率的积,这里是按组来的,因为
# 后面梯度算的时候是sum()后再backward所以这里还要除一个batch_size,别忘了用完梯度后梯度清零
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 = 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)
# 这里的l是一个含10个值的向量,或者说是一个(10,1)的矩阵,所以这里要sum()
# 这里先sum在backward要清楚什么是反向传播,他记住了你的计算模式,所以反向传播最后一步是把梯度全部加一起
        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}')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值