深度学习项目:线性表示代码

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

import random  #随机


def create_data(w, b, data_num):  #生成数据
#服从N(0,1)的数据,生成data_num个长度为len(w)的张量,因为w,b也是张量
    x = torch.normal(0, 1, (data_num, len(w))) 
#y=x*w+b;
    y = torch.matmul(x, w) + b    #matmul表示矩阵相乘
# 添加噪声,服从N(0,0.01) y,shape表示y的维度
    noise = torch.normal(0, 0.01, y.shape)  #噪声要加到y上
    y += noise
    return x, y
----------------------以上是生成数据x,y的函数-------------------------------------------
num = 500
#创造的“真实”数据w和b
true_w = torch.tensor([8.1,2,2,4]) #w是4维向量,b为标量1.1
true_b = torch.tensor(1.1)
#这些都是随便取的
#创建X,Y数据
X, Y = create_data(true_w, true_b, num)


plt.scatter(X[:, 3], Y, 1)
plt.show()#画出真实数据,也就是图上的散点


def data_provider(data, label, batchsize):       #每次访问这个函数, 就能提供一批数据
    length = len(label)#获取label的数量,也就是有多少个样本,机器学习中label一般为样本总数
    indices = list(range(length))#创建0-length-1的列表
     #目的是把样本数量转换为列表,此时列表内容为0,1,2,...499

    #我不能按顺序取  把数据打乱
    random.shuffle(indices) #shuffle有洗牌的意思

    for each in range(0, length, batchsize):
#从0到length,步长为batchsize,batchsize表示一次处理多少数据,和维度并无关系
        get_indices = indices[each: each+batchsize]#切片,从each到each+batchize
#取data和label
        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
------------上面代码是取数据,其中注释掉的代码可以打印数据--------------------------------

def fun(x, w, b):#实现y=x*w+b,并返回y
    pred_y = torch.matmul(x, w) + b
    return pred_y

def maeLoss(pre_y, y):#计算loss,|pre_y-y|的平均值
    return torch.sum(abs(pre_y-y))/len(y)

def sgd(paras, lr):          #随机梯度下降,更新参数
    with torch.no_grad():  
#属于这句代码的部分,不计算梯度只要在 requires_grad=True的张量上做任何操作,PyTorch 默认会
#尝试构建计算图(即使你不需要)
        for para in paras:
            para -= para.grad * lr  #para减去其梯度*学习率,完成梯度下降
    #不能写成   para = para - para.grad*lr,否则会创建新的para
            para.grad.zero_()      #使用过的梯度,归0,否则后面再用会累加

-----------------------------以上为了计算loss--------------------------------
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#表示要训练50轮,每次都是一样的数据,但是每次都在进行梯度下降慢慢找到最接近的位置

for epoch in range(epochs):  #50轮数据
    data_loss = 0 #每轮开始前初始化loss为0
    for batch_x, batch_y in data_provider(X, Y, batchsize):
#生成数据并用batch_x,batch_y承接,batch_y是真实的y
        pred_y = fun(batch_x,w_0, b_0)  #用函数预测的y
        loss = maeLoss(pred_y, batch_y)  #计算loss
        loss.backward() #可以反向链式求导,求出梯度
        sgd([w_0, b_0], lr)
#完成梯度下降,对w和b进行更新,这里是每个batch进行更新而不是每个epochs
        data_loss += loss #data_loss保存总的loss值

    print("epoch %03d: loss: %.6f"%(epoch, data_loss))
---------------------以上是50轮训练-----------------------------------------------

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

idx = 3 #假设为身高
plt.plot(
X[:, idx].detach().numpy(), #X的所有行,第idx列
X[:, idx].detach().numpy()*w_0[idx].detach().numpy()+b_0.detach().numpy()
)
#detach是把w和b从张量网上拿下来,不然无法进行画图
plt.scatter(X[:, idx], Y, 1) 
#横轴x为所有样本数据的身高,纵轴y为要预测的相应因变量,1为散点大小
plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值