深度学习专栏
回归实战代码解析
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()