Logistic regression和Linear Regression的区别
- 预测目标不同:Logistic regression预测一个概率,例如二分类,是或者否;Linear Regression预测连续值,例如房价
- 输出前处理不同:Logistic regression要过一下sigmoid;Linear Regression模型输出就是预测值
- loss函数不同:Logistic regression用的是CE;Linear Regression用的是MSE
上个Pytorch代码
LinearRegressionModel的代码
import torch.nn as nn
import torch
class LinearRegressionModel(nn.Module):
def __init__(self, in_features, out_features):
super(LinearRegressionModel, self).__init__()
self.fc = nn.Linear(in_features, out_features)
def forward(self, input):
output = self.fc(input)
return output
if __name__ == '__main__':
in_features,out_features = 1,1
bs = 100
model = LinearRegressionModel(in_features,out_features)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
input = torch.unsqueeze(torch.linspace(-1, 1, bs), dim=1)
target = 2*input + 1 + 0.2*torch.rand(input.size())
epoch = 1000
for i in range(epoch):
optimizer.zero_grad()
output = model(input)
loss = nn.MSELoss()(output, target)
loss.backward()
print('loss = {}'.format(loss))
optimizer.step()
Logistics Regression的代码(使用CE Loss)
再来一份Logistic Regression的code,注意由于是CrossEntropy的要求,out_features必须得是2才行:
import torch.nn as nn
import torch
class LogisticsRegressionModel(nn.Module):
def __init__(self, in_features, out_features):
super(LogisticsRegressionModel, self).__init__()
self.fc = nn.Linear(in_features, out_features)
def forward(self, input):
output = nn.Sigmoid()(self.fc(input))
return output
if __name__ == '__main__':
in_features,out_features = 1,1
bs = 100
model = LogisticsRegressionModel(in_features,out_features)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
x0 = torch.randn((bs,1))+1
y0 = torch.zeros(bs)
x1 = torch.randn((bs,1))-1
y1 = torch.ones(bs)
input = torch.cat((x0, x1), dim=0)
target = torch.cat((y0, y1), dim=0).long()
epoch = 1000
for i in range(epoch):
optimizer.zero_grad()
output0 = model(input)
output1 = 1-output0
output = torch.concat([output0, output1], dim=1)
loss = nn.CrossEntropyLoss()(output, target)
loss.backward()
print('loss = {}'.format(loss))
optimizer.step()
Logistics Regression的代码(使用BCE Loss)
注意target在这里是float:
import torch.nn as nn
import torch
class LogisticsRegressionModel(nn.Module):
def __init__(self, in_features, out_features):
super(LogisticsRegressionModel, self).__init__()
self.fc = nn.Linear(in_features, out_features)
def forward(self, input):
output = nn.Sigmoid()(self.fc(input))
return output
if __name__ == '__main__':
in_features,out_features = 1,1
bs = 100
model = LogisticsRegressionModel(in_features,out_features)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
x0 = torch.randn((bs,1))+1
y0 = torch.zeros(bs)
x1 = torch.randn((bs,1))-1
y1 = torch.ones(bs)
input = torch.cat((x0, x1), dim=0)
target = torch.cat((y0, y1), dim=0).float()
epoch = 1000
for i in range(epoch):
optimizer.zero_grad()
output = model(input)
loss = nn.BCELoss()(output, target.view(-1,1))
loss.backward()
print('loss = {}'.format(loss))
optimizer.step()
logistic regression的推导
逻辑斯蒂回归的先验分布是伯努利分布,softmax的先验分布是多项式分布
LR太简单了,简单到经常被用,但是很多推导仍然迷糊的程度,这篇主要用来总结一下。
线性回归的表达式:
f(x)=wTx+bf(x)=w^Tx+bf(x)=wTx+b
由于带一个b,我们可以令x′=[1,x]Tx'=[1, x]^Tx′=[1,x]T,同时w′=[b,w]Tw'=[b, w]^Tw′=[b,w]T,这样直线方程就可以简化成
f′(x)=w′Txf'(x)=w^{'T}xf′(x)=w′Tx
所以,当有m组训练数据,n维features时,一会儿得到的梯度是n+1维,接下来推梯度,先得推导一下loss function。由于线性回归结果是个实数,为了让他属于(0,1)之间,给它过一个sigmoid。如果是多分类,最后接Softmax。假设有一组样本(x1,y1),(x2,y2)...(xn,yn)(x_1,y_1),(x_2,y_2)...(x_n,y_n)(x1,y1),(x2,y2)...(xn,yn),针对2分类的情况,yn=0或1y_n=0或1yn=0或1,给定xix_ixi的情况下,yiy_iyi是1的概率是pi=11+exp(−wxi)p_i=\frac{1}{1+exp(-wx_i)}pi=1+exp(−wxi)1,loss function利用了最大似然的想法:
L=ln[∏i=1npiyi(1−pi)(1−yi)]L=∑i[yilnpi+(1−yi)ln(1−pi)]obj=arg maxwL(w)当然可以改成obj=arg minw−L(w)所以L=−∑i[yilnpi+(1−yi)ln(1−pi)]L=ln[\prod_{i=1}^np_i^{y_i}(1-p_i)^{(1-y_i)}] \\
L=\sum_i[{y_ilnp_i+(1-y_i)ln(1-p_i)]} \\
obj = \argmax_w{L(w)} \\
当然可以改成
obj = \argmin_w{-L(w)} \\
所以 \\
L=-\sum_i[{y_ilnp_i+(1-y_i)ln(1-p_i)]}
L=ln[i=1∏npiyi(1−pi)(1−yi)]L=i∑[yilnpi+(1−yi)ln(1−pi)]obj=wargmaxL(w)当然可以改成obj=wargmin−L(w)所以L=−i∑[yilnpi+(1−yi)ln(1−pi)]
接下来开始求梯度,注意∂pi∂wi=pi(1−pi)xi\frac{\partial p_i}{\partial w_i} = p_i(1-p_i)x_i∂wi∂pi=pi(1−pi)xi
∂L∂w=−∑i=1nxi(yi−pi)\frac{\partial L}{\partial w}=-\sum_{i=1}^nx_i(y_i-p_i)∂w∂L=−i=1∑nxi(yi−pi)
最后用Adam求解就可以
另外一个问题是LR是不是凸函数,当然是,因为二阶Hessian矩阵>=0,下面我们求一下二阶导数:
∂2L∂2w=−∑i=1npi(1−pi)xixiT>=0\frac{\partial^2 L}{\partial^2 w}=-\sum_{i=1}^np_i(1-p_i)x_ix_i^T >= 0∂2w∂2L=−i=1∑npi(1−pi)xixiT>=0