如标题,任务就是对于 这样的线性方程组拟合的代码实现
1. 导入任务需要的库
import torch #深度学习框架
import matplotlib.pyplot as plt #画图,可视化
import random #随机
2. 生成数据(用函数实现)
def create_data(w,b,data_num): #w表示权重weight, b表示bias偏差, data_num控制生成的矩阵大小
x = torch.normal(0,1,(data_num,len(w))) #x为正态分布状的一个矩阵,参数分别为mean平均值,std标准差,generator生成形状
y = torch.matmul(x,w)+ b #矩阵乘法后得到y向量
noise = torch.normal(0,0.01,y.shape) #加入噪声,更加具有普适性
y += noise
return x, y
3. 给定待预测值,并初步检查函数功能
num = 500 #行数
true_w = torch.tensor([8.1,2,2,4]) #待预测的真实值w与b
true_b = torch.tensor(1.1)
X, Y = create_data(true_w,true_b,num)
plt.scatter(X[:,0],Y,1) #由参数绘图,设定点大小为1
plt.show()
附上生成的散点图
4. 定义一个data_provider函数来提供一批数据
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) #输出每小块的x与y以供检查
# break
5. 定义相关函数
def fun(x,w,b): # 获取预测的y向量
pred_y = torch.matmul(x,w)+b
return pred_y
def maeLoss(pred_y,y): #以mae均绝对误差作为损失函数
return torch.sum(abs(pred_y-y))/len(y)
def sgd(paras, lr): #随机梯度下降,更新参数
with torch.no_grad():# 属于这句代码的这块,不计算梯度
for para in paras:
para -= para.grad* lr #迭代更新参数
para.grad.zero_() #清理用过的梯度
6.设定相关参数
lr = 0.01 #学习率
w_0 = torch.normal(0,0.01,true_w.shape,requires_grad=True) #w_0, b_0需要计算梯度
b_0 = torch.tensor(0.01,requires_grad=True)
print(w_0,b_0)
7. 训练模型
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) #预测出的y
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)) #观察损失程度
附上损失度图片
此处损失度越小的话,对应的模型训练效果就比较好
8. 检验预测结果
print(true_w,true_b)
print(w_0,b_0)
由上图可知,模型训练效果较好
9. 可视化结果
idx = 0 #选定特征列
plt.plot(X[:,idx].detach().numpy(),X[:,idx].detach().numpy()*w_0[idx].detach().numpy()+b_0.detach().numpy())
# tensor张量不可以直接绘制,需要将其detach操作一下
plt.scatter(X[:,idx], Y, 1)
plt.show()# 可视化
由此图可知,拟合效果良好 ,结束实验