python线性回归从零开始实现

 一、线性回归原理简述

y = w_{1}x_{1} + w_{2}x_{2} +\cdots + w_{n}x_{n}

 

 

 

二、实现思路

1:如果有真是数据集,则加载真实数据集;如果没有真是数据集则生成人造数据集

2:构建神经网络

3:定义损失函数

4:构建优化器

5:进行训练

三、代码实现

1.导入所需的包

import torch
import random

2.构建人造数据集

生成人造数据集y=XW+b+e,其中e为服从N(0, 0.001)随机误差

def synthetic_data(w, b, examples_num):
    #生成人造数据集y=XW+b+e  
    #e为服从N(0, 0.001)随机误差
    x = torch.normal(0, 1, (examples_num, len(w)))       #随机生成服从N(0,1), 形状为(examples_num, len(w)的tensor变量
    y = torch.matmul(x, w) + b                           #计算y(y=WX + b)y的x形状为(n,1)
    e = torch.normal(0, 0.001, y.shape)                  #生成随机误差e
    y = y + e                                            #生成最终的y
    return x, y.reshape(-1, 1)                           #返回x, y

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

3.构造出每次进行迷你批SGD优化的样本

def data_iter(batch_size, features, labels):
    #构建一个迭代器,用来在进行梯度优化的时候取数据
    examples_num = len(labels)                    #样本的个数就等于y的元素个数
    indices = list(range(examples_num))           #构建一个列表用于索引
    random.shuffle(indices)                       #将索引顺序打乱,保证每次取样是从样本中随机抽取
    for i in range(0, examples_num, batch_size):      #构建一个循环用来取每次优化时的样本x, y
        batch_indices = indices[i:i+batch_size]   #获取索引,索引为从列表的第i+1个元素,到第i+batch_size+1个元素
        yield features[batch_indices], labels[batch_indices]    #获得每次抽取的features和labels

4.定义神经网络(即线性回归模型)

def linreg(x, w, b):                   #定义线性回归模型
    return torch.matmul(x, w) + b          #返回经过线性模型运算之后的输出

5.定义损失函数

def squard_loss(y_hat, y):                                        #定义损失函数
    return (y_hat-y.reshape(y_hat.shape))**2/2                    #返回损失函数(不求平均是因为不知道batchsize)

6.定义优化器

def sgd(params, lr, batch_size):
    with torch.no_grad():                                       #不计算梯度(作用是节约内存,不加这个也是对的)
        for param in params:                                    #分别更新w和b
            param -= lr * param.grad / batch_size               #梯度下降算法
            param.grad.zero_()                                   #避免梯度累加

7.进行训练

lr = 0.03
epochs = 3
net = linreg
loss = squard_loss
batch_size = 10                                                  

for epoch in range(epochs):                                       #进行epochs次迭代
    for x, y in data_iter(batch_size, features, labels):               
        y_hat = net(x, w, b)                               
        all_loss = loss(y, y_hat)
        all_loss.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}') #测试神经网络

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值