%matplotlib inline
import random
import torch
from d2l import torch as d2l
def syn_data(w,b,num_examples):
x = torch.normal(0,1,(num_examples,len(w)))
y = torch.matmul(x,w)+b
y=y +torch.normal(0,0.01,y.shape)
return x,y.reshape((-1,1))
t_w = torch.tensor([2,-3.4])
t_b = 4.2
features,labels = syn_data(t_w,t_b,1000)
features.size(),labels.size()
(torch.Size([1000, 2]), torch.Size([1000, 1]))
def data_iter(batch_size,features,labels):
num_examples = len(features)
indices =list(range(num_examples))
random.shuffle(indices)
for i in range(0,num_examples,batch_size):
batch_indiecs = torch.tensor(indices[i:min(i+batch_size,num_examples)])
yield features[batch_indiecs],labels[batch_indiecs]
batch_size = 10
w = torch.normal(0,0.01,size=(2,1),requires_grad = True)
b = torch.zeros(1,requires_grad = True)
w,b
(tensor([[-0.0050],
[ 0.0162]], requires_grad=True),
tensor([0.], requires_grad=True))
def linreg(x,w,b):
return torch.matmul(x,w) + b
def squared_loss(y_hat,y):
return (y_hat -y.reshape(y_hat.shape))**2/2
def sgd(params,lr,batch_size):
with torch.no_grad():
for param in params:
param.sub_(lr*param.grad/batch_size)
param.grad.zero_()
lr = 0.003
num_epochs = 10
net = linreg
loss = squared_loss
for epoch in range(num_epochs):
for x,y in data_iter(batch_size,features,labels):
y_hat = net(x,w,b)
l = loss(y_hat,y)
l.size()
l.sum().backward()
sgd([w,b],lr ,batch_size)
with torch.no_grad():
train_l = loss(net(features,w,b),labels)
print(f'epoch {epoch + 1},loss {float(train_l.mean()):f}')
epoch 1,loss 9.036007
epoch 2,loss 5.028663
epoch 3,loss 2.799776
epoch 4,loss 1.559638
epoch 5,loss 0.869278
epoch 6,loss 0.484746
epoch 7,loss 0.270458
epoch 8,loss 0.150984
epoch 9,loss 0.084333
epoch 10,loss 0.047141
print(f'w的误差:{t_w -w.reshape(t_w.shape)}')
print(f'w的误差:{t_b -b}')
w的误差:tensor([ 0.1238, -0.2036], grad_fn=<SubBackward0>)
w的误差:tensor([0.2017], grad_fn=<RsubBackward1>)
|