import torchimport matplotlib.pyplot as plt # 画图的import random #随机def create_data(w, b, data_num): #生成数据x torch.normal(0, 1, (data_num, len(w)))y torch.matmul(x, w) b #matmul表示矩阵相乘noise torch.normal(0, 0.01, y.shape) #噪声要加到y上y noisereturn x, ynum 500true_w torch.tensor([8.1,2,2,4])true_b torch.tensor(1.1)X, Y create_data(true_w, true_b, num)plt.scatter(X[:, 3], Y, 1)plt.show()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: eachbatchsize]get_data data[get_indices]get_label label[get_indices]yield get_data,get_label #有存档点的returnbatchsize 16# for batch_x, batch_y in data_provider(X, Y, batchsize):# print(batch_x, batch_y)# breakdef fun(x, w, b):pred_y torch.matmul(x, w) breturn pred_ydef maeLoss(pre_y, y):return torch.sum(abs(pre_y-y))/len(y)def sgd(paras, lr): #随机梯度下降更新参数with torch.no_grad(): #属于这句代码的部分不计算梯度for para in paras:para - para.grad * lr #不能写成 para para - para.grad*lrpara.grad.zero_() #使用过的梯度归0lr 0.03w_0 torch.normal(0, 0.01, true_w.shape, requires_gradTrue) #这个w需要计算梯度b_0 torch.tensor(0.01, requires_gradTrue)print(w_0, b_0)epochs 50for epoch in range(epochs):data_loss 0for batch_x, batch_y in data_provider(X, Y, batchsize):pred_y fun(batch_x,w_0, b_0)loss maeLoss(pred_y, batch_y)loss.backward()sgd([w_0, b_0], lr)data_loss lossprint(epoch %03d: loss: %.6f%(epoch, data_loss))print(真实的函数值是, true_w, true_b)print(训练得到的参数值是, w_0, b_0)idx 3plt.plot(X[:, idx].detach().numpy(), X[:, idx].detach().numpy()*w_0[idx].detach().numpy()b_0.detach().numpy())plt.scatter(X[:, idx], Y, 1)plt.show()