动手学深度学习----linear regression
看了B站上《跟着李沐学AI》线性回归章节,来记录一下吧!
1.colab使用方法:
可以自行看网上教程,我暂时还没怎么搞懂,哈哈哈哈!
2.环境搭建:
基本环境电脑上有,但是我选择用colab,在使用过程中遇到了很多问题,就比如说“d2l"库的安装,d2l库是李沐大神自己写的库函数,包括了一些我们常用的库和自定义函数。
看了其他blog写的方法是直接使用:
pip install -U d2l
但是我用了之后还是不行,还是说找不到,然后我就从github上下载下来,然后上传文件到***/usr/local/lib/python3.9/dist-packages***下面,然后又运行还是报错,错误是:No module named ‘matplotlib_inline’,解决方法是:从https://github.com/ipython/matplotlib-inline下载,然后导入到同上的文件夹,
基本所需的库就好了,如果还需要什么模块不存在就可以直接pip安装即可。
3.linear regression从0开始实现:
首先大致了解一下线性回归的基本流程:模型函数:y=wx+b;
损失函数:y=1/2(y’-y)^2
参数更新:使用梯度下降法
- 导入所需库函数
%matplotlib inline
import random
import torch
import numpy
from d2l import torch as d2l
- 构造所需数据集
根据带有噪声的线性模型构造一个人造数据集,使用w=[2,-3.4],b=4.2和噪音项进行构造,基本公式是:y=wx+b+noise,其中的w,x是2维列向量进行内积,再加上bias和noise。
torch.normal()函数原型如下:
normal(mean, std, *, generator=None, out=None)
该函数返回从单独的正态分布中提取的随机数的张量,该正态分布的均值是mean,标准差是std。
用法如下:我们从一个标准正态分布N~(0,0.01),提取一个2x1的向量。
torch.matmul():返回两个张量的矩阵成绩;
pytorch中两个张量的乘法可以分为两种:
- 两个张量对应元素相乘,在PyTorch中可以通过torch.mul函数(或*运算符)实现;
- 两个张量矩阵相乘,在PyTorch中可以通过torch.matmul函数实现;
def synthetic_data(w,b,num_examples):
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=synthetic_data(true_w,true_b,1000)
print('featrue:',features[0],'\nlabel:',labels[0])
- 生成小批量
定义一个data_iter函数,该函数主要是接受批量大小,特征矩阵和标签向量作为input,生成大小为batch_size的小批量
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_indices=torch.tensor(indices[i:min(i+batch_size,num_examples)])
yield features[batch_indices],labels[batch_indices]
batch_size=10
for x,y in data_iter(batch_size,features,labels):
print(x,'\n',y)
break
- 初始化模型参数
w=torch.normal(0,0.01,size=(2,1),requires_grad=True)
b=torch.zeros(1,requires_grad=True)
- 定义模型
def linear(x,w,b):
return torch.matmul(x,w)+b
#定义损失函数,均方误差
def lossfunc(y_,y):
return (y_-y.reshape(y_.shape))**2/2
#定义优化算法,小批量随机梯度下降
def sgd(params,lr,batch_size):
with torch.no_grad():
for param in params:
param-=lr*param.grad/batch_size
#梯度归零
param.grad.zero_()
- 训练过程
lr=0.03
num_epochs=5
net=linear
loss=lossfunc
for epoch in range(num_epochs):
for x,y in data_iter(batch_size,features,labels):
#x,y的小批量损失
l=loss(net(x,w,b),y)
l.sum().backward()
sgd([w,b],lr,batch_size)
with torch.no_grad():
tran_l=loss(net(features,w,b),labels)
print(f'epoch:{epoch +1}, loss:{float(tran_l.mean()):f}')