这是我根据李沐学AL的视频学来的,我自己的总结
理论推导
基础理论
线性回归模型是一个线性的模型(函数是一个线性函数),模型函数比较简单,就相当于一个单层的神经网络
常用在房价预测,录取大学生预测,股票价格走势预测
W 就是权重,x1,x2,x3等经过不同的权重,汇聚成了我们要的线性模型,因为带权重的层只有一层,我们把它看成单层的神经网络
损失函数
为了找出最合适的W,b我们设定下面这个函数来求出合适的值
优化方法
我们一般采用梯度法(一阶求导)
梯度:是指函数增加最快的方向
负梯度:是指函数减少最快的方向
学习率:就是下降的幅度(超参数)
下面的每一个圆环代表的函数值都一样,就是一个环形的曲线
总结:
梯度下降通过不断的沿着反方向梯度更新参数求解
小批量随机梯度是深度学习默认的求解算法
两个重要的超参数批量大小和学习率
代码实践
从零开始
生成数据集
读取数据集
初始化模型参数
w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)#通过在均值为0,方差为0.01的正态分布采集一些随机的数据来最作为w,b
b = torch.zeros(1, requires_grad=True)
定义模型
def linreg(X, w, b): #@save
"""线性回归模型"""
return torch.matmul(X, w) + b
定义损失函数
def squared_loss(y_hat, y): #@save
"""均方损失"""
return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2#平方损失
定义优化算法
def sgd(params, lr, batch_size): #@save
"""小批量随机梯度下降"""
with torch.no_grad():
for param in params:
param -= lr * param.grad / batch_size
param.grad.zero_()
训练
lr = 0.03 #学习率为0.03
num_epochs = 3#数据扫描三遍
net = linreg#模型
loss = squared_loss#均分损失
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) # X和y的小批量损失,将想想x,y放到模型里面来求损失,放到l里面
# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,
# 并以此计算关于[w,b]的梯度
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}')
使用torch框架来实现
读取数据集
定义模型
# nn是神经网络的缩写
from torch import nn
net = nn.Sequential(nn.Linear(2, 1))#我们首先定义一个模型变量net,它是一个Sequential类的实例
初始化模型参数
#在这里,我们指定每个权重参数应该从均值为0、标准差为0.01的正态分布中随机采样, 偏置参数将初始化为零
net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)
定义损失函数
loss = nn.MSELoss()#计算均方误差使用的是MSELoss类,也称为平方 𝐿2 范数, 默认情况下,它返回所有样本损失的平均值。
定义优化算法
trainer = torch.optim.SGD(net.parameters(), lr=0.03)#我们直接调用,只需要设置后面的lr学习率就绪
训练
num_epochs = 3
for epoch in range(num_epochs):#读取三次
for X, y in data_iter:#小批量获取x,y的数据
l = loss(net(X) ,y)#计算loss
trainer.zero_grad()#梯度清零
l.backward()#通过这个求出梯度
trainer.step()#模型的更新
l = loss(net(features), labels)#将我们的feature放到net里面,然后跟labels求loss
print(f'epoch {epoch + 1}, loss {l:f}')#打印出来相关的信息