1.导入必要的库
import torch
import matplotlib.pyplot as plt
import random
torch
: PyTorch库,用于深度学习计算。matplotlib.pyplot
: 绘图库,用于显示数据。random
: Python标准库,用于生成随机数。
2.定义数据生成函数
def create_data(w,b,data_num):
x=torch.normal(0,1,(data_num,len(w))) #生成随机的x,0为方差,1位均值,data_num代表多少组数据,len(w)代表输入的w类型数【宽度】
y=torch.matmul(x,w)+b
noise=torch.normal(0,0.01,y.shape) #0.01位噪声,与y同型
y+=noise
return x,y
这个函数生成线性回归问题的训练数据。
x
: 使用正态分布生成,均值为0,标准差为1,形状为(data_num, len(w))。y
: 是x
和w
的线性组合加上偏置b
,然后加上噪声。
3.生成训练数据
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) #x:500*4 y:500*1
- 设置数据量为500。
- 定义真实的权重
true_w
和偏置true_b
。 - 使用
create_data
函数生成训练数据X
和Y
。
4.显示数据
plt.scatter(X[:,0],Y,1)
plt.show()
使用matplotlib显示生成的数据点。
5.定义数据提供器
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 #yield相当于有存档点的return
这个函数用于按批次提供数据,常用于训练过程中的小批量梯度下降。
6.获取一批数据
batchsize=16
for batch_x,batch_y in data_provider(X,Y,batchsize):
print(batch_x,batch_y)
break
使用数据提供器从数据中获取一个批次的数据,并打印出来。
7.定义预测函数
def fun(x,w,b):
pred_y=torch.matmul(x,w)+b
return pred_y
这个函数计算给定x、w和b的预测值。
8.定义平均绝对误差损失函数
def maeloss(pred_y,y):
loss=torch.sum(abs(pred_y-y)/len(y))
return loss
这个函数计算预测值pred_y和真实值y之间的平均绝对误差。
9.定义随机梯度下降函数
def sgd(paras,lr):
with torch.no_grad(): #接下来不需要计算梯度(前向要计算,回传不需要)
for para in paras:
para-=para.grad*lr
para.grad.zero_() #把梯度归0
这个函数实现随机梯度下降算法,用于更新权重和偏置。
10.初始化权重和偏置
lr=0.03
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)
- 设置学习率。
- 初始化权重
w_0
和偏置b_0
,并设置requires_grad=True
以便计算梯度。
11.训练模型
epochs=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)
loss=maeloss(pred,batch_y)
loss.backward()
sgd([w_0,b_0],lr)
data_loss+=loss
print("epoch %03d:loss:%.6f"%(epoch,data_loss))
这个循环进行多次迭代(即epochs),每次迭代都会遍历整个数据集。
- 在每次迭代中,使用数据提供器按批次获取数据。
- 使用预测函数计算预测值。
- 计算损失。
- 使用损失进行反向传播,计算梯度。
- 使用SGD更新权重和偏置。
- 打印当前迭代的损失。
12.显示结果
print("原来的函数值:",true_w,true_b)
print(w_0,b_0)
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)
plt.show()
使用matplotlib显示训练后的预测结果和实际数据点。