linear_regression_model

本文介绍了如何从零开始实现线性回归模型,包括数据生成、批量处理、定义模型结构、损失函数和优化算法。后续章节通过框架简化了线性回归的实现过程。
摘要由CSDN通过智能技术生成

在前面,我们已经学习了线性回归的基本原理,以及模型训练的基本要素和流程。本节我们就来完成线性回归模型的代码实现

1 从零实现线性回归

首先,我们来导入需要的包

import  matplotlib_inline
import random
import torch
from d2l import torch as d2l

生成训练样本
对于模型 y = w 1 x 1 + w 2 x 2 + b y=w_1 x_1+w_2 x_2+b y=w1x1+w2x2+b,我们自己来创建一些数据来作为模型的样本,通过

def synthetic_data(w, b, num_examples):
    """
    人工生成训练数据
    :param w: 真实的权重
    :param b: 真实的偏置
    :param num_examples:数据个数 
    :return: 生成的X、y训练数据
    """
    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
    
w_true=torch.tensor([2,-3.4])
b_true=4.2
features,labels=synthetic_data(w_true,b_true,100)

批量打包数据
前面我们提到过,深度学习不会直接使用所有数据来训练计算损失函数,那会带来极大的成本,所以会采用批处理的方式
此时我们就按指定的batch_size大小产生数据

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):
        bathIndides=torch.tensor(Indices[i:min(i+batch_size,num_examples)])
        yield features[bathIndides],labels[bathIndides]

batch_size=10
for X,y in data_iter(batch_size,features,labels):
    print(X,"\n",y)
    break
tensor([[ 0.3174,  0.8440],
        [-0.1825,  0.6330],
        [ 0.6303, -0.6279],
        [-0.1898, -0.3718],
        [ 1.4762, -2.3725],
        [-1.0628, -0.2374],
        [-1.4689, -1.6751],
        [-0.5215,  0.8446],
        [ 1.0405,  0.3750],
        [ 0.1340,  0.7184]]) 
 tensor([ 1.9422,  1.6872,  7.5901,  5.0734, 15.2126,  2.9003,  6.9655,  0.2776,
         5.0088,  2.0295])

定义模型
下面我们来实现线性回归模型的定义:包括网络架构和参数权重

#参数权重随机初始化
w=torch.normal(0,0.01,(2,1),requires_grad=True)
b=torch.zero(1,requires_grad=True)
#定义模型架构
def linreg(X,w,b):
    return torch.matmul(X,w)+b

下面我们进行模型的训练
本模块包含损失函数和优化算法的定义,以及训练过程的实现

#定义损失函数
def squred_loss(y_hat,y):
    return (y_hat-y.reshape(y_hat.shape))**2

#定义优化算法
def SGD(params,lr,batch_size):
    with torch.nograd():
        for param in params:
            param-=params.grad*lr/batch_size
        params.grad.zero_()
##定义训练过程
lr=0.05
net=linreg
epoches=5
loss_function=squred_loss
for epoch in epoches:
    for X,y in data_iter(batch_size,features,labels):
        y_hat=net(X,w,b)
        loss=loss_function(y_hat,y)
        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}')

2 快捷线性回归

前面我们从零实现了线性回归,现在我们通过框架来简洁实现线性回归

import numpy as np
import torch
from d2l import torch as d2l
from torch.utils import data
from torch import nn

def synthetic_data(w, b, num_examples):
    """
    人工生成训练数据
    :param w: 真实的权重
    :param b: 真实的偏置
    :param num_examples:数据个数 
    :return: 生成的X、y训练数据
    """
    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)
    
w_true=torch.tensor([2,-3.4])
b_true=4.2
features,labels=synthetic_data(w_true,b_true,100)


def load_array(data_arrays,batch_size,is_train=True):
    """
    分批次读取数据
    
    :param data_arrays: 源数据
    :param batch_size:  批大小
    :param is_train:    是否为训练数据,若是,则打乱后再分批
    :return:            一个迭代器,可以迭代获取数据
    """
    dataset=data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset,batch_size,shuffle=is_train)

batch_size=10
data_iter=load_array((features,labels),batch_size)
next(iter(data_iter))

net=nn.Sequential(nn.Linear(2,1))
net[0].weight.data.normal_(0,00.1)
net[0].bias.data.fill_(0)

loss = nn.MSELoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
num_epochs = 3
for epoch in range(num_epochs):
    for X, y in data_iter:
        l = loss(net(X), y)
        trainer.zero_grad()
        l.backward()
        trainer.step()
    l = loss(net(features), labels)
    print(f'epoch{num_epochs + 1}:loss={l:f}')
epoch4:loss=9.925650
epoch4:loss=3.212693
epoch4:loss=1.054000
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值