简单的线性回归实例

一.导包

import torch
import matplotlib.pyplot as plt
import random

torch包处理张量,matplotlib.pyplot用于画图,ramdom用于打乱测试集的数据

二.数据生成

def create_data(w, b, data_num): #生成数据
    x = torch.normal(0, 1, (data_num, len(w)))
    y = torch.matmul(x, w) + b

    noise = torch.normal(0, 0.01, y.shape) #噪声加到y身上
    y += noise


    return x, y

num = 500
true_w = torch.tensor([8.1,2,2,4])
true_b = torch.tensor(1.1)

X, Y = create_data(true_w, true_b, num)

create_data函数用于生成指定数量,指定权值和指定偏差以及一些噪声的一组数据

true_w为权值的直值(8.1,2,2,4),true_b(1.1)是偏差的真值,实际情况中, 是不知道这些值的,需要通过深度学习训练得到

X,Y就是一组数量500的数据

三.获取数据并对数据进行处理

def data_provider(data, label, batchsize):     #每次访问这个函数,就能提供一批数据
    length = len(label)
    indices = list(range(length))
    #我不能按顺序取 把数据打乱
    random.shuffle(indices)
    for each in range(0, length, batchsize):
        get_indices = indices[each: each+batchsize]
        get_data = data[get_indices]
        get_label = label[get_indices]


        yield get_data, get_label #有存档点的return
batchsize = 16

data_provider函数用于提供数据,通过label的长度获取数据的数量,并生成相应长度的列表,通过random把列表中的序号打乱,以此模拟真实的取数据的情况。batchsize代表每次取数据的个数,而yield关键字可以将数据存档,当下一次运行这个函数时又能取到下一组数据(而不是从头开始取)。这样每次运行data_provider函数,就能获取batchsize(16)个数据

四.定义模型,损失函数和优化函数

def fun(x, w, b):
    pred_y = torch.matmul(x, w) + b
    return pred_y

def meaLoss(pre_y ,y):
    return torch.sum(abs(pre_y-y))/len(y)

def sgd(paras, lr): #随机梯度下降,更新参数
    with torch.no_grad():  #属于这句代码的部分,不计算梯度
        for para in paras:
            para -= para.grad * lr  #不能写成 para = para - pata.grad*lr
            para.grad.zero_()  #使用过的梯度归零



lr = 0.03
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True) #这个w需要计算梯度
b_0 = torch.tensor(0.01, requires_grad=True)
print(w_0, b_0)

fun函数就是定义的线性模型
meaLoss函数就是定义的损失函数

sgd就是梯度回传优化的函数,其中

with torch.no_grad():代表属于这个代码的部分不计算梯度(计算梯度会导致梯度回传出现错误),para -= pata.grad * lr pata.grad.zero_()两句就是优化权值的公式

其中,grad就是对应的梯度,lr就是学习率,而后面是一句是让使用过的梯度归零

五.参数设计与模型训练

lr = 0.03
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True) #这个w需要计算梯度
b_0 = torch.tensor(0.01, requires_grad=True)
print(w_0, b_0)

epochs = 50


for epoch in range(epochs):
    data_loss = 0
    for batch_x, batch_y in data_provider(X, Y, batchsize):
        pred_y = fun(batch_x, w_0, b_0)
        loss = meaLoss(pred_y, batch_y)
        loss.backward()
        sgd([w_0, b_0], lr)
        data_loss += loss

    print("epoch  %03d: loss: %.6f"%(epoch, data_loss))


print("真实的函数值是", true_w, true_b)
print("训练得到的参数值是", w_0, b_0)

lr是学习率,代表每次权值变化的速度

w_0是预设为随机数的权值,需要通过训练逼近真实值,b_0是预设的偏差,两者都需要计算梯度

epochs是训练的轮次,每训练完整个数据集算一轮,其中,每获取batchsize个数据,进行一次loss的计算,并进行梯度回传优化权值和偏差,并将每轮loss和打印出来检查训练效果

当lr(学习率)设置为0.001时,可以发现,经过50轮的训练,每一轮的loss值还是很大,训练得出的权值和偏差和真实值相差的很远,下面再将lr设置为0.03

可以看到,将lr设置为0.03后,在第13轮训练后,loss值就已经很小了,最后训练得到的权值和偏差和真实值比较接近。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值