1 线性回归
3.1 线性模型
3.1.1 机器学习模型
机器学习关键要素:训练数据,模型,损失函数,优化方法
3.1.2 线性回归损失函数
线性函数的损失函数为平方误差函数。
使用平方误差函数的推导是:
1、线性回归函数目标函数y = W *x +b
2、假设训练样本包含噪声,假设噪声为高斯分布
3、包含噪声的目标函数为 y = W * x + b + \((x), 其中\)(x)为服从步骤2高斯分布
4、则步骤3的概率目的函数为
5、根据极大似然估计法,则求步骤4在所有样本 概率最大,由于历史原因,优化通常是说最小化而不是最大化,所以极大似然估计最大化变成−logP(y∣X) 最小化, 最小化。
优化标准差可以假设为常数,第一项为常数省去和第二项常数忽略,即平方误差最小化
3.1.3 矢量化运算速度快
import torch
import time
a = torch.randn(50,6)
b = torch.randn(50,6)
row = 5
col = 6
c = torch.zeros(50,6)
start = time.time()
for i in range(row):
for j in range(col):
c[i][j] = a[i][j] + b[i][j]
print(time.time() - start)
start = time.time()
c = a +b
print(time.time()-start)
3.1.6 练习
1、假设我们有一些数据 x1,…,xn∈R 。我们的目标是找到一个常数 b ,使得最小化 ∑i(xi−b)2 。
找到最优值 b 的解析解。 为x1...xn均值
这个问题及其解与正态分布有什么关系? 这个解为假设x误差为正太分布的情况下的回归
2、推导出使用平方误差的线性回归优化问题的解析解。为了简化问题,可以忽略偏置 b (我们可以通过向 X 添加所有值为1的一列来做到这一点)。
用矩阵和向量表示法写出优化问题(将所有数据视为单个矩阵,将所有目标值视为单个向量)。
计算损失对 w 的梯度。
通过将梯度设为0、求解矩阵方程来找到解析解。
什么时候可能比使用随机梯度下降更好?这种方法何时会失效?
假定控制附加噪声 ϵ 的噪声模型是指数分布。也就是说, p(ϵ)=12exp(−|ϵ|)
写出模型 −logP(y∣X) 下数据的负对数似然。
你能写出解析解吗?
提出一种随机梯度下降算法来解决这个问题。哪里可能出错?(提示:当我们不断更新参数时,在驻点附近会发生什么情况)你能解决这个问题吗?
3.8 线性回归实现
构造数据
import torch
import numpy as np
from torch.utils import data
W = torch.tensor([2, -3.4])
b = 4.2
data_size = 1000
X = torch.normal(0,1, (data_size, len(W)))
y = torch.matmul(X, W) + b
y += torch.normal(0, 0.01, y.shape)
print(y.shape, y)
y = y.reshape((-1,1))
print(y.shape,y)
data_set = data.TensorDataset(X, y)
data_iter = data.DataLoader(data_set, batch_size=50, shuffle=True)
net = torch.nn.Sequential(torch.nn.Linear(len(W), 1))
参数初始化
net[0].weight.data.normal_(0,0.01)
net[0].bias.data.fill_(0.0)
loss = torch.nn.MSELoss()
loss = torch.nn.MSELoss(reduction='sum')
optimzer = torch.optim.SGD(net.parameters(), lr=0.003)
训练过程
epochs = 3
for i in range(epochs):
for XX, yy in data_iter:
print(XX.shape, yy.shape)
y_pred = net(XX)
print(y_pred.shape, yy.shape)
l = loss(y_pred, yy)
optimzer.zero_grad()
l.backward()
optimzer.step()
print("%d, loss is %f" % (i, loss(net(X), y)))
比较参数差异
net[0].weight - W, net[0].bias - b, net[0].weight.grad
3.3.9 练习
1、如果我们用 nn.MSELoss() 替换 nn.MSELoss(reduction='sum'),为了使代码的行为相同,需要怎么更改学习速率?为什么?
reduction默认为mead均值,修改为sum之后,loss变大了,所以要减小lr
2、查看 PyTorch 文档,了解提供了哪些损失函数和初始化方法。用Huber损失来代替。
3、你如何访问 net[0].weight 的梯度?
net[0].weight.grad

浙公网安备 33010602011771号