import torch
import matplotlib.pyplot as plt #画图
import random #生成随机数
def create_data(w,b,data_num): #生成数据 w是矩阵
x = torch.normal(0,1,(data_num,len(w))) # 生成自变量x,期望值0,方差为1,数量为data_num,长度和w一致
y = torch.matmul(x,w) + b #构造函数 y=wx+b
noise = torch.normal(0,0.01,y.shape) #增加噪声,与Y同型
y += noise #y = y+noise
return x,y #返回生成的x和y向量
num = 500 #创建500个数
true_w = torch.tensor([8.1,2,2,4]) #设定真实的w与b
true_b = torch.tensor(1.1) #转为张量,才可在torch中运算
X,Y = create_data(true_w,true_b,num) #根据真实的w和b生成一笔样本数据
plt.scatter(X[:,0],Y,1) #画散点图 所有行的某一列做X
plt.show()
def data_provider(data,label,batchsize): #每一次访问,就提供一笔数据 data是X,label是Y,batchsize是所有样本中一部分
length = len(label) #记录向量Y的行数
indices = list(range(length)) #记录Y的下标
random.shuffle(indices) #打乱列表的元素,即打乱下标,以达到随机取Y的目的
for each in range(0,length,batchsize): #范围+步长
get_indices = indices[each:each+batchsize] #创建一个列表,装随机取的16个下标数
get_data = data[get_indices] #取16个下标对应的X值
get_label = label[get_indices] #取16g个X对应的Y值
yield get_data,get_label #有存档点的return,每一个新的调用,就从上次的结束处开始
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 #计算y=wx+b pred_y为预测的y
return pred_y
def maeloss(pred_y,y):
loss = torch.sum(abs(pred_y-y))/len(y) #计算loss值 abs()求绝对值 torch.sum求和
return loss
def sgd(paras, lr) : #梯度下降函数 #传入参数和学习率,更新参数para
with torch.no_grad(): #接下来的计算 不算梯度(回传不用计算梯度)
for para in paras: #遍历所有参数
para -=para.grad*lr
para.grad.zero_() #回传过程,要把所有参数的梯度归零
lr = 0.025 #学习率
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True) #均值为0,方差0.01,和w同型,计算梯度
b_0 = torch.tensor(0.01,requires_grad=True) #计算梯度
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):
pred = fun(batch_x,w_0,b_0) #计算初始设定的y=(w_0)x+(b_0)
loss = maeloss(pred,batch_y) #计算loss
loss.backward() #梯度回传
sgd([w_0, b_0 ],lr)
data_loss +=loss
print("epoch %03d: loss:%.6f"%(epoch,data_loss)) #epoch取三位整数,data_loss保留6位小数
print("原来的函数值",true_w,true_b) #真实的w和b
print(w_0,b_0) #迭代更新之后的w和b
idx = 0 #某列
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, label="true") #画真实值的散点图
plt.show()
深度学习第一站——基础回归任务
于 2024-01-16 08:18:28 首次发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)