回归实战代码解析
import torch import matplotlib.pyplot as plt # 画图用的 import random # 生成随机数 import os os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # y = wx + b # 一般一维的称为向量,二维的,多维的称为矩阵 # 创建数据 def create_data(w, b, data_num): # w是一个向量,b也是一个向量,data_num表示生成多少组数据 x = torch.normal(0, 1, (data_num, len(w))) y = torch.matmul(x, w) + b noise = torch.normal(0, 0.01, y.shape) # 与y同型,加噪音, y += noise return x, y num = 500 true_w = torch.tensor([8, 1, 2, 2, 4], dtype=torch.float32) # 真实值 true_b = torch.tensor(1.1) # 真实值 X, Y = create_data(true_w, true_b, num) # X是500 * 5,Y是500*1 # X[:,0]是一个张量,表示取X的所有行的第0列,则X[:,4]所有行第5列 # plt.scatter(X[:, 2], Y, 1) # 用于画散点图,x为500*4,y为500*1 # plt.show() # data是x,label是y, 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 # 存档点,下一次访问的时候从这儿开始访问。 batchsize = 16 for batch_x, batch_y in data_provider(X, Y, batchsize): # print(batch_x, batch_y) break def func(x, w, b): pred_y = torch.matmul(x, w) + b return pred_y # 预测值y def maeloss(pred_y, y):#mae均绝对误差的loss函数 loss = torch.sum(abs(pred_y - y)) / len(y) return loss def sgd(params, lr):#梯度下降的函数,梯度下降就类似求导数 with torch.no_grad(): # 接下来的计算不计算梯度 for para in params: para -= para.grad * lr para.grad.zero_() # 把梯度归零 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) epochs = 50 # 训练轮次 # 训练 for epoch in range(epochs): data_loss = 0 for batch_x, batch_y in data_provider(X, Y, batchsize): pred = func(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)) print("原来的函数值:", true_w, true_b) print("预测值:", w_0, b_0) # 下面是画图,X[:, idx].derach().numpy(),是将张量取下来。 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, label="true") plt.show()