import torch
import matplotlib.pyplot as plt # 画图的
import random #随机
def create_data(w, b, data_num): #生成数据
#服从N(0,1)的数据,生成data_num个长度为len(w)的张量,因为w,b也是张量
x = torch.normal(0, 1, (data_num, len(w)))
#y=x*w+b;
y = torch.matmul(x, w) + b #matmul表示矩阵相乘
# 添加噪声,服从N(0,0.01) y,shape表示y的维度
noise = torch.normal(0, 0.01, y.shape) #噪声要加到y上
y += noise
return x, y
----------------------以上是生成数据x,y的函数-------------------------------------------
num = 500
#创造的“真实”数据w和b
true_w = torch.tensor([8.1,2,2,4]) #w是4维向量,b为标量1.1
true_b = torch.tensor(1.1)
#这些都是随便取的
#创建X,Y数据
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)#获取label的数量,也就是有多少个样本,机器学习中label一般为样本总数
indices = list(range(length))#创建0-length-1的列表
#目的是把样本数量转换为列表,此时列表内容为0,1,2,...499
#我不能按顺序取 把数据打乱
random.shuffle(indices) #shuffle有洗牌的意思
for each in range(0, length, batchsize):
#从0到length,步长为batchsize,batchsize表示一次处理多少数据,和维度并无关系
get_indices = indices[each: each+batchsize]#切片,从each到each+batchize
#取data和label
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)
# break
------------上面代码是取数据,其中注释掉的代码可以打印数据--------------------------------
def fun(x, w, b):#实现y=x*w+b,并返回y
pred_y = torch.matmul(x, w) + b
return pred_y
def maeLoss(pre_y, y):#计算loss,|pre_y-y|的平均值
return torch.sum(abs(pre_y-y))/len(y)
def sgd(paras, lr): #随机梯度下降,更新参数
with torch.no_grad():
#属于这句代码的部分,不计算梯度只要在 requires_grad=True的张量上做任何操作,PyTorch 默认会
#尝试构建计算图(即使你不需要)
for para in paras:
para -= para.grad * lr #para减去其梯度*学习率,完成梯度下降
#不能写成 para = para - para.grad*lr,否则会创建新的para
para.grad.zero_() #使用过的梯度,归0,否则后面再用会累加
-----------------------------以上为了计算loss--------------------------------
lr = 0.03#学习率
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True) #这个w需要计算梯度
b_0 = torch.tensor(0.01, requires_grad=True)
print(w_0, b_0)#w_0和#b_0是初始的参数
epochs = 50#表示要训练50轮,每次都是一样的数据,但是每次都在进行梯度下降慢慢找到最接近的位置
for epoch in range(epochs): #50轮数据
data_loss = 0 #每轮开始前初始化loss为0
for batch_x, batch_y in data_provider(X, Y, batchsize):
#生成数据并用batch_x,batch_y承接,batch_y是真实的y
pred_y = fun(batch_x,w_0, b_0) #用函数预测的y
loss = maeLoss(pred_y, batch_y) #计算loss
loss.backward() #可以反向链式求导,求出梯度
sgd([w_0, b_0], lr)
#完成梯度下降,对w和b进行更新,这里是每个batch进行更新而不是每个epochs
data_loss += loss #data_loss保存总的loss值
print("epoch %03d: loss: %.6f"%(epoch, data_loss))
---------------------以上是50轮训练-----------------------------------------------
print("真实的函数值是", true_w, true_b)
print("训练得到的参数值是", w_0, b_0)
idx = 3 #假设为身高
plt.plot(
X[:, idx].detach().numpy(), #X的所有行,第idx列
X[:, idx].detach().numpy()*w_0[idx].detach().numpy()+b_0.detach().numpy()
)
#detach是把w和b从张量网上拿下来,不然无法进行画图
plt.scatter(X[:, idx], Y, 1)
#横轴x为所有样本数据的身高,纵轴y为要预测的相应因变量,1为散点大小
plt.show()
深度学习项目:线性表示代码
最新推荐文章于 2026-04-15 10:39:39 发布

479

被折叠的 条评论
为什么被折叠?



