实现线性回归我们需要一下几个步骤
1. 手动创建一个人造的数据集
2.需要生成一个迭代器
3.构建一个线性回归的函数 Y = WX+B
4.定义一个损失函数,此文章采用均方误差
5.进行梯度下降,本文采用的随机梯度下降的方法
1.构建一个人造的数据集合
num_example 为需要构建的数据集的大小
生成数据集后在数据集中添加一些均值为0 , 方差为0.01 的噪声
# 构造一人人造的数据集
def make_dataset( w , b , num_example):
x = torch.normal(0,1 ,(num_example ,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
x , y = make_dataset(true_w , true_b , 1000)
x.shape, y.shape
true_w = torch.tensor([2,-3.4])
true_b = 4.2
x , y = make_dataset(true_w , true_b , 1000)
构建完成的x.shape 和 y.shape 为 (torch.Size([1000, 2]), torch.Size([1000, 1]))
2.迭代器的生成
构建一个迭代器,shuffle函数文random中的函数,目的是打乱数据集。因为我们采用的随机梯度下降的方法,需要从数据集中随机选取数据。
yield相当于return,但是在下一次调用此函数的时候会从上一次末尾进行操作
def data_iter(x , y ,batch_size):
lens = len(y)
indices = list(range(lens))
random.shuffle(indices)
for i in range (0,lens,batch_size):
index = torch.tensor(
indices[i:min(i+batch_size ,lens)]
)
yield x[index] , y[index]
3.定义一个线性回归的函数
def linger(w , x , b):
return torch.matmul(x , w)+b
4.定义损失函数
def loss(y_hat , y):
return ((y_hat-y.reshape(y_hat.shape))**2)/2
5.进行梯度下降的操作
param 里面存储的就是我们的需要求解的w和b。每一次从他下降最快的方向进行下降
def sgd(params , lr , batch_size):
with torch.no_grad():
for param in params:
param -= lr*param.grad / batch_size
param.grad.zero_()
6.进行最后的循环操作
num_epoch = 10
batch_size = 10
for epoch in range(num_epoch):
for x_ , y_ in data_iter(x , y ,batch_size):
los = loss(linger(w , x_ , b),y_)
los.sum().backward()
sgd([w,b],0.03 , batch_size)
display(los.sum())
display(true_w - w.reshape(true_w.shape) )
display(true_b - b )
tensor(0.0003, grad_fn=)
tensor(0.0006, grad_fn=)
tensor(0.0004, grad_fn=)
tensor(0.0008, grad_fn=)
tensor(0.0007, grad_fn=)
tensor(0.0007, grad_fn=)
tensor(0.0005, grad_fn=)
tensor(0.0005, grad_fn=)
tensor(0.0004, grad_fn=)
tensor(0.0009, grad_fn=)
tensor([-0.0002, 0.0001], grad_fn=)
tensor([0.0004], grad_fn=)