浅析深度学习(一)线性回归

任务:通过自己建立数据,分析loss,做出基本拟合图像的直线

一.引入包 矩阵,画图,随机数

import torch
import matplotlib.pyplot as plt #画图
import random #生成随机数

二.创建函数--拟设数据 y = b + [w1 w2 w3 w4][x1 x2 x3 x4]

  • w--权值

  • b--附加值

  • data_num --有多少个参考项

拟设数据:x为方差为0[数都一样],均值为1,行列为data_num *len(w)的矩阵

浅析深度学习(一)线性回归_第1张图片

def create_data(w,b,data_num):      #y = b + [w1 w2 w3 w4][x1 x2 x3 x4]
    x = torch.normal(0,1,(data_num,len(w)))  #0为方差,1为均值,后面为矩阵行列500*4
    y = torch.matmul(x,w) + b       
    #noise为方差为0,均值为1,与y同型的矩阵,用来表误差
    noise = torch.normal(0,0.01,y.shape)  #与y同型
    y += noise
    return x,y

三.创建数据

用真实值得到X,Y

num = 500
#必须是张量tensor才能运算
true_w = torch.tensor([8.1,2,2,4])  #真实值
true_b = torch.tensor(1.1)           #真实值
X,Y = create_data(true_w,true_b,num)   #x是500*4,y是500*1
#用来划散点图的,scatter为
plt.scatter(X[:,0],Y,1)  #x拟设全部维中的第1列
plt.show()

三.创建函数--提供数据

data就是x,label就是y,batchisize就是loss的平均量,

输出结果为随机的关于x,关于y的一笔数据

#每次访问就提供一笔数据    
def data_provider(data,label,batchisize):     
    length = len(label)            #长度
    indices = list(range(length))  #转成列表   range表示生成0-500的数
    random.shuffle(indices)        #打乱列表
    for each in range(0,length,batchisize):  #从0到length,步长为batchisize,each为变量
        get_indices = indices[each:each+batchisize]   #取each到each+batchisize列表的下标
        get_data = data[get_indices]  #取下标中的数据
        get_label = label[get_indices]
        yield get_data,get_label #有存档点的return

四.提供数据

用batch_x和batch_y来遍历由X,Y组成的数据,,得到关于X,Y的随机数据

batchsize = 16    #每步走16
for batch_x,batch_y in data_provider(X,Y,batchsize):
    print(batch_x,batch_y)
    break

五.创建函数--拟定线性回归函数

def fun(x,w,b):     #做函数
    pred_y = torch.matmul(x,w) + b    #预测值pred_y
    return pred_y

六.创建函数--拟定loss

def maeLoss(pred_y,y):   #做loss
    loss = torch.sum(abs(pred_y - y)) / len(y)
    return loss

七.创建函数--梯度回传0.

(梯度相当于导数)

  • paras--

浅析深度学习(一)线性回归_第2张图片

  • lr--学习率

浅析深度学习(一)线性回归_第3张图片
def sgd(paras,lr):#梯度下降
    with torch.no_grad():    #接下来的计算不算梯度
        for para in paras:
            para -= para.grad*lr
            para.grad.zero_()     #把梯度归0

七.训练

#拟设一个学习率
lr = 0.03
#声明两个随机的w,b来训练
w_0 = torch.normal(0,0.01,true_w.shape,requires_grad=True)  #计算梯度
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):
        #用fun函数得到的预测值
        pred = fun(batch_x,w_0,b_0)
        #计算loss
        loss = maeLoss(pred,batch_y)
        #梯度回传,能将所有梯度传回去
        loss.backward() 
        #w_0,b_0 相当于全部参数进行训练
        sgd([w_0,b_0],lr)
        
        data_loss += loss
        #03d表三位整数,
        print("epoch %03d:loss:%.6f"%(epoch,data_loss))

print("原来的函数值:",true_w,true_b)
print(w_0,b_0)

打印直线

idx = 2
#全部从张量上放下
plt.plot(X[:,idx].detach().numpy(),X[:,idx].detach().numpy()*w_0[idx].detach().numpy()+b_0.detach().numpy(),label="pred")
plt.scatter(X[:,idx],Y,1)
plt.show()

你可能感兴趣的:(python,深度学习)