李哥AI第二节python实战

import torch
import matplotlib.pyplot as plt #  画图的

import random  #随机

该代码为所需调用的包


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

生成数据:

参考图:

  • 作用:通过默认的w和b生成x和y
  • 输入数据:参数向量w和b,data_num为需要生成多少组数据(上面矩阵的长)
  • 注解:normal表示正太:前两个数字为期望和方差,后两个数据为要生成矩阵的行和列;noise为增加噪声

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)

该代码为初始化默认参数调用函数创建数据

tensor为张量的意思

plt.scatter(X[:, 3], Y, 1)
plt.show()

该代码作用为画图

第一行作用是定义二位散点图,x轴为X第三列,y轴为Y,点的大小为1

第二行为绘制图像


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
# for batch_x, batch_y in data_provider(X, Y, batchsize):
#     print(batch_x, batch_y)
#     break

作用:每次访问这个函数提供一批数据:

输入:data为训练数据,label为标签数据,batchsize为每批数据量

代码简要解析:生成与数据长度相同的下表,随机打乱后分批输出

random.shuffle为随机打乱的函数。

yield为有存档点的return


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

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
            para.grad.zero_()      #使用过的梯度,归0

fun函数:通过训练数据计算预测的y值

maeLoss函数:计算一组数据的loss

sgd函数:对一组数据进行梯度下降

注释:

with torch.no_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)

以真实参数的排列形状定义默认初始参数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 = maeLoss(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)

作用:训练50轮,每训练一轮打印一次loss

注释:loss.backward为loss回传(虽然在这里只有一层没有什么作用)

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()

作用:画图

注释:用numpy处理不了张量,因此先要将数据转化为矩阵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值