定义
逻辑回归其实就是原来的线性回归加了激活函数,这个函数其实就是sigmoid函数,把一个回归的连续数值压缩到了0到1的空间,其实只要有函数能够满足把数值压缩到0,1之间就可以(因为0到1之间的数值就是概率值)
对于分类问题而言,不能和回归问题一样,计算与真值的距离,即MSE损失(均方误差损失),为此人们发明了交叉熵损失。
对于单个样本,其二元交叉熵损失为:
L = − [ y log ( y ^ ) + ( 1 − y ) log ( 1 − y ^ ) ] L = - [y \log(\hat{y}) + (1 - y) \log(1 - \hat{y})] L=−[ylog(y^)+(1−y)log(1−y^)]
其中, y y y 是真实标签(取值为 0 或 1), y ^ \hat{y} y^ 是模型预测的概率(取值范围在 [ 0 , 1 ] [0, 1] [0,1] 之间)。
分析:当真实值为1的时候,损失变为:
L = − y log ( y ^ ) L = - y \log(\hat{y}) L=−ylog(y^)
为了让损失最小,预测值 y ^ \hat{y} y^越大越好,即越为1越好
当真实值为0的时候,损失变为:
L = − log ( 1 − y ^ ) L = - \log(1-\hat{y}) L=−log(1−y^)
为了让损失最小,预测值 y ^ \hat{y} y^越小越好,即越为0越好
这个是符合损失函数概念的,即越接近真实值,损失越小。
对于 N N N 个样本的平均二元交叉熵损失为:
L = − 1 N ∑ i = 1 N [ y i log ( y ^ i ) + ( 1 − y i ) log ( 1 − y ^ i ) ] L = - \frac{1}{N} \sum_{i=1}^{N} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)] L=−N1i=1∑N[yilog(y^i)+(1−yi)log(1−y^i)]
对于多分类任务一样,BCE损失函数如下:
H ( y , p ) = − 1 n ∑ i = 1 n ∑ j = 1 C y i j log ( p i j ) H(y,p)=-\frac{1}{n}\sum_{i = 1}^{n}\sum_{j = 1}^{C}y_{ij}\log(p_{ij}) H(y,p)=−n1i=1∑nj=1∑Cyijlog(pij)
C是类别,n是样本数目
pytorch框架编写
不管什么模型,其实也是只有四部
- (1)准备数据
import torch
import torch.nn.functional as F
# 准备数据
x_data = torch.tensor([[1.0],[2.0],[3.0]], dtype=torch.float32)
y_data = torch.tensor([[0.0],[0.0],[1.0]], dtype=torch.float32)
- (2)构建模型
# 构建模型
class LogiscalRegression(torch.nn.Module):
def __init__(self):
super(LogiscalRegression,self).__init__()
self.linear=torch.nn.Linear(1,1)
def forward(self,x):
y_pred=F.sigmoid(self.linear(x))
return y_pred
核心在于
y_pred=F.sigmoid(self.linear(x))
线性回归的值取了一个sigmoid激活,将其压缩到【0,1】之间。
- (3)初始化模型,并定义损失
# 实例化自己构建的模型
model=LogiscalRegression()
#定义损失函数
cretirion=torch.nn.BCELoss(reduction='sum')
# 定制优化器类型
optimizer=torch.optim.SGD(model.parameters(),lr=0.01)
- (4)开始损失
#开始训练
for epoch in range(100):
#模型结果
y_pred = model(x_data)
#计算损失
loss=cretirion(y_pred,y_data)
print("loss:",loss.item())
#梯度归零
optimizer.zero_grad()
#反向转播
loss.backward()
#更新
optimizer.step()
全部代码如下
import torch
import torch.nn.functional as F
# 准备数据
x_data = torch.tensor([[1.0],[2.0],[3.0]])
y_data = torch.tensor([[0.0],[0.0],[1.0]])
# 构建模型
class LogiscalRegression(torch.nn.Module):
def __init__(self):
super(LogiscalRegression,self).__init__()
self.linear=torch.nn.Linear(1,1)
def forward(self,x):
y_pred=F.sigmoid(self.linear(x))
return y_pred
# 实例化自己构建的模型
model=LogiscalRegression()
#定义损失函数
cretirion=torch.nn.BCELoss(size_average =False)
# 定制优化器类型
optimizer=torch.optim.SGD(model.parameters(),lr=0.01)
#开始训练
for epoch in range(100):
y_pred = model(x_data)
loss=cretirion(y_pred,y_data)
print("loss:",loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()