李哥深度学习第一课

import torch
import matplotlib.pyplot as plt  # 画图的
import random  # 随机操作
import numpy


# 创建数据
def create_data(w, b, data_num):  # 创建生成数据
    x = torch.normal(0, 1, (data_num, len(w)))
    y = torch.matmul(x, w) + b  # matmul表示矩阵相乘
    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)#创建一组数据
plt.scatter(X[:, 3], Y, 1)  # plt.scatter 画一个散点图;1表示点的大小为1
plt.show()  # plt.show()为画图函数


def data_provider(data, label, batchsize):  # 每次访问这个函数,就能提供一批数据,一批一批的取数据,求loss
    length = len(label)  # 求出数据的长度
    indices = list(range(length))  # 把0到500变为范围并变成列表
    # 不能按顺序取数据 需要把数据打乱
    random.shuffle(indices)
    for each in range(0, length, batchsize):
        get_indices = indices[each:each + batchsize]  # 每次循环依次把列表indices中的从each到each+batchsize中的数据提取到get_indices中
        get_data = data[get_indices]  # 取X中0到15个张量
        get_label = label[get_indices]  # 取Y中0到15个张量
        yield get_data, get_label  # yield为有存档点的return


batchsize = 16
for batch_x, batch_y in data_provider(X, Y, batchsize):  # X为数据,Y为标签
    print(batch_x, batch_y)
    break


# 定义模型
def fun(x, w, b):
    pred_y = torch.matmul(x, w) + b
    return pred_y


# 计算loss
def maeLoss(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-para.grad()*lr,这一步就是用来更新w_0和b_0的值的
            para.grad.zero_()  # 使用过的梯度,需要归零,方便下一个参数更新


# 开始训练,随机选择一个w_0和b_0
lr = 0.01
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True)  # 这个w需要计算梯度
b_0 = torch.tensor(0.01, requires_grad=True)  # 这个b需要计算梯度
print(w_0, b_0)
epochs = 50#每次训练50次
for epoch in range(epochs):
    data_loss = 0
    for batch_x, batch_y in data_provider(X, Y, batchsize):  # X为数据,Y为标签
        pred_y = fun(batch_x, w_0, b_0)  # 计算预测值y
        loss = maeLoss(pred_y, batch_y)  # 计算loss=|y-pred_y|
        loss.backward()  # 梯度回传
        sgd([w_0, b_0], lr)  # 更新每个参数,也就是w_0和b_0
        data_loss += loss  # 更新模型
    print("epoch %03d:loss:%.6f" % (epoch, data_loss))
print("真实的函数值是", true_w, true_b)
print("训练得到的参数值是", w_0, b_0)
# 可视化,只能取x和w_0的某一列,方便做线形图;数据在张量网上无法画图,必须使用.detach().numpy()
idx = 3
plt.plot(X[:, idx].detach().numpy(), X[:, idx].detach().numpy() * w_0[idx].detach().numpy() + b_0.detach().numpy())
plt.scatter(X[:, idx], Y, 1)
plt.show()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值