from torch.utils import data
import torch
from d2l import torch as d2l
from torch import nn
#生成数据
def synthetic_data(w, b, num_examples):
"""生成 y = Xw + b + 噪声。"""
X = torch.normal(0, 1, (num_examples, len(w)))
y = torch.matmul(X, w) + b
y += torch.normal(0, 0.01, y.shape)
return X, y.reshape((-1, 1))
true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)
#对数据进行封
#dataloader 是为了对数据进行封装成模块
def load_array(data_arrays, batch_size, is_train=True):
"""构造一个PyTorch数据迭代器。"""
dataset = data.TensorDataset(*data_arrays)
return data.DataLoader(dataset, batch_size, shuffle=is_train)
batch_size = 10 #分成100个 每组10个
data_iter = load_array((features, labels), batch_size)
#不要也行 自己能迭代
# next(iter(data_iter))
# print("1,",next(iter(data_iter)))
#练习中的huber loss1
def Huber_loss(y_hat,y_true,a):
loss_temp = nn.L1Loss()
loss = loss_temp(y_hat, y)
flag = loss - a
if flag > 0:
return loss - a / 2
else:
return 1 / (2 * a) * loss ** 2
#练习中的huber loss2
def huber_loss(y_hat, y, beta = 0.005):
error = torch.abs(y_hat - y)
return torch.where(error < beta , 0.5 * error ** 2 / beta, error - 0.5 * beta)
net = nn.Sequential(nn.Linear(2, 1))#网络模型
#初始化网路参数
net[0].weight.data.normal_(0, 0.01)#net的第一层 本来也就只有一层 .data.normal来修改参数
net[0].bias.data.fill_(0)#一样的修改偏置项 这里是把偏置项弄成0了
# 如果采用sum的话 学习率也需要改成/batch——size 但是效果肯定还是没平均值的好
# loss = nn.MSELoss(reduction="sum")#定义损失函数
# trainer = torch.optim.SGD(net.parameters(), lr=0.025/batch_size)#优化器
loss = nn.MSELoss(reduction="mean")#定义损失函数
trainer = torch.optim.SGD(net.parameters(), lr=0.025)#优化器
# 通过调用net(X)生成预测并计算损失l(前向传播)。
# 通过进行反向传播来计算梯度。
# 通过调用优化器来更新模型参数。
i = 0;
num_epochs = 3
for epoch in range(num_epochs):
for X, y in data_iter:#每次取10个 因为batchsize=10 取100次 i+100
l = loss(net(X), y)#计算loss 因为有10个 所以计算的loss的平均值 平方/2n 就是一个值 loss 一维 还是这个loss算出来误差最好 以后其实一般不会自己定义loss的 只是这里用作练习
#l = Huber_loss(net(X),y,0.005)
#l = huber_loss(net(X), y).sum()/batch_size
trainer.zero_grad()#清0
l.backward()#loss求导
#访问梯度
#print("w的梯度是:{}".format(net[0].weight.grad))
trainer.step()#优化参数
i= i+1
print(i)
l = loss(net(features), labels)#这里是优化后再算一遍loss 来监视loss的变化
print(f'epoch {epoch + 1}, loss {l:f}')
w = net[0].weight.data
print('w的估计误差:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b的估计误差:', true_b - b)
print(w.shape)
print(true_w.shape)#所以上面需要变形
运行结果:
F:\python3\python.exe C:\study\project_1\3_27_linear.py
100
epoch 1, loss 0.001376
200
epoch 2, loss 0.000096
300
epoch 3, loss 0.000096
w的估计误差: tensor([-0.0006, 0.0005])
b的估计误差: tensor([-0.0001])
torch.Size([1, 2])
torch.Size([2])
进程已结束,退出代码0