1. Logistic 分布和对率回归

监督学习的模型可以是概率模型或非概率模型,由条件概率分布\(P(Y|\bm{X})\)或决 策函数(decision function)\(Y=f(\bm{X})\)表示,随具体学习方法而定。对具体的输入\(\bm{x}\)进行相应的输出预测并得到某个结果时,写作\(P(y|\bm{x})\)或\(y=f(\bm{x})\)。

我们这里的 Logistic 分类模型是概率模型,模型\(P(Y|\bm{X})\)表示给定随机向量\(\bm{X}\)下,分类标签\(Y\)的条件概率分布。这里我们只讨论二分类问题。后面我们介绍多层感知机的时候会介绍多分类问题。道理是一样的。

先介绍 Logistic 分布。

Logistic 的分布函数为:

\[F(x) = P(X<=x) = \frac{1}{1+e^{-(x-u)/\gamma}}
\]

该分布函数的图像为:

该函数以点\((u,1/2)\)中心对称,在中心附近增长速度较快,在两端增长速度较慢。

我们后面对于未归一化的数\(z\),采用\(\text{sigmoid}\)函数

\[σ(z) = \frac{1}{1 + \text{exp}(−z)}
\]

将其“压”在(0, 1)之间。这样就可以使\(z\)归一化,一般我们使归一化后的值表示置信度(belief),可以理解成概率,但是与概率有着细微的差别,更体现 “属于××类的把握”的意思。

对于二分类,标签\(Y=0\)或\(Y=1\),我们将\(P(Y=0|\bm{X}=\bm{x})\)和\(P(Y=1|\bm{X}=\bm{x})\)表示如下,也就定义了二项逻辑回归模型:

\[\begin{aligned}
P(Y=1|\bm{X}=\bm{x}) &= \sigma(\bm{w}^T\bm{x}+b) \\
&= \frac{1}{1+\text{exp}(-(\bm{w}^T\bm{x}+b))}
\end{aligned}\space (1)
\\
\begin{aligned}
P(Y=0|\bm{X}=\bm{x}) &= 1-\sigma(\bm{w}^T\bm{x}+b) \\
&= \frac{1}{1+\text{exp}(\bm{w}^T\bm{x}+b)}
\end{aligned} \qquad (2)
\]

现在考察 Logistic 回归模型的特点,一个事件的几率(odds)是指该事件发生的概率与不发生的概率的比值。如果事件发生的概率是\(p\),那么该事件的几率是\(p/(1-p)\),该事件的对数几率(log odds,简称对率)或 logit 函数是

\[\text{logit}(p) = \text{log}\space p/(1-p)
\]

对 Logistic 回归而言,由式子\((1)\)和式子\((2)\)得到:

\[\text{log}\frac{P(Y = 1|\bm{X}=\bm{x})}{1 − P(Y = 1|\bm{X}=\bm{x})} = \bm{w}^T\bm{x} + b
\]

这玩意在统计学里面称之为“对率回归”,其实就是“Logistic regression 名称”的由来。这里的 Logistic 和“逻辑”没有任何关系,和对率才是有关系的。 可以看出,输出\(Y=1\)的对数几率是由输入\(\bm{x}\)的线性函数表示的模型,即 Logistic 回归模型。

2. Logistic 回归模型的参数估计

我们在《统计推断:极大似然估计、贝叶斯估计与方差偏差分解》)中说过,从概率模型的视角来看,机器模型学习的过程就是概率分布参数估计的过程,这里就是估计条件概率分布\(P(Y|\bm{X})\)的参数\(\bm{θ}\)。对于给定的训练数据集\(T=\{\{\bm{x}_1, y_1\},\{\bm{x}_2, y_2\}, \dots, \{\bm{x}_N, y_N\}\}\),其中,\(\bm{x}_i∈\mathbb{R}^n\),\(y_i∈\{0, 1\}\),可以应用极大似然估计法估计模型参数,从而得到Logistic回归模型。

我们设\(P(Y=1|x)=π(\bm{x})\),\(P(Y=0|\bm{x})=1-π(\bm{x})\),很显然\(P(Y|\bm{x})\)服从一个伯努利分 布,不过这个伯努利分布很复杂,它的参数\(p\)是一个函数\(π(\bm{x})\)。我们这里采用一个抽象的观念,将函数\(π(\bm{x})\)看做一个整体,这样\(P(Y|\bm{x})\)服从二项分布,可以方便我们理解。我们的参数\(\bm{θ}=(w, b)\),不过我们还是采用之前的技巧,将权值向量和输入向量加以扩充,直接记做\(\bm{θ}=\bm{w}\)。

这样,对于\(N\)个样本,定义似然函数:

\[L(\bm{w}|\bm{x}_1,\bm{x}_2,...,\bm{x}_N) = \Pi_{i=1}^N[\pi(\bm{x}_i)]^{y_i}[1-\pi(\bm{x}_i)]^{1-y_i}
\]

因为函数比较复杂,我们采用数值优化进行求解。然而这个函数是非凸的, 如果直接用数值迭代算法作用于次函数,可能陷入局部最优解不能保证到收敛到全局最优解。我们为了将其变为负对数似然函数(想一想为什么要取负号),也就是一个凸函数,方便用梯度下降法、牛顿法进行求解:

\[-L(\bm{w}|\bm{x}_1,\bm{x}_2,...,\bm{x}_N) =
- \sum_{i=1}^N[y_i\text{log}\space \pi(\bm{x}_i)+(1-y_i)\text{log}(1-\pi(\bm{x}_i))]
\]

配凑 \(1/N\)转换为关于数据经验分布期望的无偏估计 ,即\(\mathbb{E}_{\bm{x}\sim \hat{p}_{data}}\text{log}\space p_{model}(\bm{x}_i| \bm{\theta})\)而不改变目标函数的优化方向。

\[- \frac{1}{N}\sum_{i=1}^N[y_i\text{log}\space \pi(\bm{x}_i)+(1-y_i)\text{log}(1-\pi(\bm{x}_i))]
\]

上面这个式子,就是我们在深度学习里面常用的交叉熵损失函数(cross entropy loss function)的特殊情况。(交叉熵损失函数一般是多分类,这里是二分类)。后面我们会学习,在深度学习领域中,我们用\(f(\cdot)\)表示神经网络对输入\(\bm{x}\)加以的 映射(这里没有激活函数,是线性的映射),\(f(\bm{x})\)就是输出的条件概率分布\(P(Y|\bm{X}=\bm{x})\)。 设类别总数为\(K\),\(\bm{x}_i\)为第\(i\)个样本的特征向量(特征维度为\(D\)),\(f(\bm{x}_i)\)输出维度也为\(K\)。\(f(\bm{x}_i)_k\)表示\(P(y_k | \bm{x}_i)\)。因为是多分类,\(P(y_k | \bm{x}_i)\)的计算方法就不能通过\(\text{sigmoid}\)函数来得到了,取而代之是更通用的\(\text{softmax}\)函数。我们给定输入样本\(\bm{x}\),设\(z_k=\sum_{j=1}^Dw_{zj}x_{j}\),其中\(\textbf{W} ∈\mathbb{R}^{K\times D}\)神经网络的权重矩阵\(D\)为特征向量维度,\(K\)为类别总数。则我们有:

\[f(\bm{x})_k = \text{softmax}(\bm{z})_k=\frac{\text{exp}(z_k)}{\sum_k\text{exp}(z_k)}
\]

我们规定第\(i\)个样本的标签\(\bm{y}_i\)为\(K\)维one-hot向量。则交叉熵函数表述如下:

\[- \frac{1}{N}\sum_{i=1}^N\sum_{k=1}^K y_{ik}\text{log}f(\bm{x}_i)_k
\]

因为\(\bm{y}_i\)为 one-hot 向量,只有一个维度为 1,设这个维度为\(c\)(即表示类别\(c\)),则交叉熵函数可以化简为:

\[- \frac{1}{N}\sum_{i=1}^N \text{log}f(\bm{x}_i)_c
\]

很明显,如果\(f(\bm{x}_i)_c\)越大,表示神经网络预测\(\bm{x}_i\)样本类别为第\(c\)类的概率越大,这也是目标函数优化的方向——即对于类别为\(c\)的样本\(\bm{x}_i\),优化器尽量使样本\(\bm{x}_i\)被预测为第\(c\)类的概率更大。

如下为使用梯度下降法求解二分类逻辑回归问题:

import numpy as np
import random
import torch
# batch_size表示单批次用于参数估计的样本个数
# y_pred大小为(batch_size, 1)
# y大小为(batch_size, ),为类别型变量
def cross_entropy(y_pred, y):
# 这里y是创建新的对象,这里将y变为(batch_size. 1)形式
y = y.reshape(-1, 1)
return -(y*torch.log(y_pred) + (1-y)*torch.log(1-y_pred)).sum()/y_pred.shape[0] # 前向函数
def logistic_f(X, w):
z = torch.matmul(X, w).reshape(-1, 1)
return 1/(1+torch.exp(-z)) # 之前实现的梯度下降法,做了一些小修改
def gradient_descent(X, w, y, n_iter, eta, loss_func, f):
# 初始化计算图参数,注意:这里是创建新对象,非参数引用
w = torch.tensor(w, requires_grad=True)
X = torch.tensor(X)
y = torch.tensor(y)
for i in range(1, n_iter+1):
y_pred = f(X, w)
loss_v = loss_func(y_pred, y)
loss_v.backward()
with torch.no_grad():
w -= eta*w.grad
w.grad.zero_()
w_star = w.detach().numpy()
return w_star # 本模型按照二分类架构设计
def LR(X, y, n_iter=200, eta=0.001, loss_func=cross_entropy, optimizer=gradient_descent):
# 初始化模型参数
# 我们使W和b融合,X后面添加一维
X = np.concatenate([X, np.ones([X.shape[0], 1])], axis=1)
w = np.zeros(X.shape[1], dtype=np.float64)
# 调用梯度下降法对函数进行优化
# 这里采用单次迭代对所有样本进行估计,后面我们会介绍小批量法减少时间复杂度
w_star = optimizer(X, w, y, n_iter, eta, loss_func, logistic_f)
return w_star if __name__ == '__main__':
# 数据矩阵,一共4个样本,每个样本特征维度为3
X = np.array([
[1, 5, 3],
[4, 5, 6],
[7, 1, 9],
[10, 1, 12]
], dtype=np.float64)
# 标签向量,注意要从0开始编码
y = np.array([1, 1, 0, 0], dtype=np.int64)
# 迭代次数
n_iter = 200
# 学习率
eta = 0.001
w = LR(X, y, n_iter, eta, cross_entropy, gradient_descent)
# 学得的权重,最后一维是偏置b
print(w)

最终学得的权重向量为(最后一维为偏置\(b\)):

[-0.10717712  0.20524747 -0.06932763  0.01892475]

如下是多分类逻辑回归问题,我们需要将\(\text{sigmoid}\)函数修改为\(\text{softmax}\)函数,损失函数修改为更为通用的交叉熵函数,根据输出维度变化将权重向量修改为权重矩阵等。

import numpy as np
import random
import torch
# batch_size表示单批次用于参数估计的样本个数
# n_feature为特征向量维度
# n_class为类别个数
# y_pred大小为(batch_size, n_class)
# y大小为(batch_size, ),为类别型变量
def cross_entropy(y_pred, y):
# 这里y是创建新的对象,这里将y变为(batch_size. 1)形式
y = y.reshape(-1, 1)
return -torch.log(torch.gather(y_pred, 1, y)).sum()/ y_pred.shape[0] # 前向函数,注意,这里的sigmoid改为多分类的softmax函数
def logistic_f(X, W):
z = torch.matmul(X, W)
return torch.exp(z)/torch.exp(z).sum() # 之前实现的梯度下降法,做了一些小修改
def gradient_descent(X, W, y, n_iter, eta, loss_func, f):
# 初始化计算图参数,注意:这里是创建新对象,非参数引用
W = torch.tensor(W, requires_grad=True)
X = torch.tensor(X)
y = torch.tensor(y)
for i in range(1, n_iter+1):
y_pred = f(X, W)
loss_v = loss_func(y_pred, y)
loss_v.backward()
with torch.no_grad():
W -= eta*W.grad
W.grad.zero_()
W_star = W.detach().numpy()
return W_star # 本模型按照多分类架构设计
def LR(X, y, n_iter=200, eta=0.001, loss_func=cross_entropy, optimizer=gradient_descent, n_class=2):
# 初始化模型参数
# 我们使W和b融合,X后面添加一维
X = np.concatenate([X, np.ones([X.shape[0], 1])], axis=1)
W = np.zeros((X.shape[1], n_class), dtype=np.float64)
# 调用梯度下降法对函数进行优化
# 这里采用单次迭代对所有样本进行估计,后面我们在深度学习专栏中会介绍小批量法
W_star = optimizer(X, W, y, n_iter, eta, loss_func, logistic_f)
return W_star if __name__ == '__main__':
X = np.array([
[1, 5, 3],
[4, 5, 6],
[7, 1, 9],
[10, 1, 12]
], dtype=np.float64)
# 标签向量,注意要从0开始编码
y = np.array([1, 2, 0, 0], dtype=np.int64)
# 迭代次数
n_iter = 200
# 学习率
eta = 0.001
# 分类类别数
n_class = 3
W = LR(X, y, n_iter, eta, cross_entropy, gradient_descent, n_class)
# 学得的权重矩阵,最后一行是偏置向量
print(W)

最终学得的权重为(同样,最后一行为偏置向量\(\bm{b}\)。因为是多分类,每一个类别维度\(k\)都会对应一个偏置\(b_k\)):

[[ 0.07124357 -0.10592994 -0.03893547]
[-0.13648944 0.10387124 0.07448013]
[ 0.04985565 -0.08291154 -0.04056595]
[-0.01069396 0.0115092 -0.00081524]]

统计学习:逻辑回归与交叉熵损失(Pytorch实现)的更多相关文章

  1. 【深度学习】softmax回归——原理、one-hot编码、结构和运算、交叉熵损失

    1. softmax回归是分类问题 回归(Regression)是用于预测某个值为"多少"的问题,如房屋的价格.患者住院的天数等. 分类(Classification)不是问&qu ...

  2. DL基础补全计划(二)---Softmax回归及示例(Pytorch,交叉熵损失)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  3. Hinge Loss、交叉熵损失、平方损失、指数损失、对数损失、0-1损失、绝对值损失

    损失函数(Loss function)是用来估量你模型的预测值 f(x) 与真实值 Y 的不一致程度,它是一个非负实值函数,通常用 L(Y,f(x)) 来表示.损失函数越小,模型的鲁棒性就越好. 损失 ...

  4. 从交叉熵损失到Facal Loss

    1交叉熵损失函数的由来1.1关于熵,交叉熵,相对熵(KL散度) 熵:香农信息量的期望.变量的不确定性越大,熵也就越大,把它搞清楚所需要的信息量也就越大.其计算公式如下: 其是一个期望的计算,也是记录随 ...

  5. 深度学习原理与框架-Tensorflow卷积神经网络-卷积神经网络mnist分类 1.tf.nn.conv2d(卷积操作) 2.tf.nn.max_pool(最大池化操作) 3.tf.nn.dropout(执行dropout操作) 4.tf.nn.softmax_cross_entropy_with_logits(交叉熵损失) 5.tf.truncated_normal(两个标准差内的正态分布)

    1. tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')  # 对数据进行卷积操作 参数说明:x表示输入数据,w表示卷积核, stride ...

  6. 【python实现卷积神经网络】损失函数的定义(均方误差损失、交叉熵损失)

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  7. pytorch 中交叉熵损失实现方法

  8. 分布式机器学习:逻辑回归的并行化实现(PySpark)

    1. 梯度计算式导出 我们在博客<统计学习:逻辑回归与交叉熵损失(Pytorch实现)>中提到,设\(w\)为权值(最后一维为偏置),样本总数为\(N\),\(\{(x_i, y_i)\} ...

  9. 线性模型之逻辑回归(LR)(原理、公式推导、模型对比、常见面试点)

    参考资料(要是对于本文的理解不够透彻,必须将以下博客认知阅读,方可全面了解LR): (1).https://zhuanlan.zhihu.com/p/74874291 (2).逻辑回归与交叉熵 (3) ...

随机推荐

  1. vue - public 引入 <script>报错 Uncaught SyntaxError: Unexpected token '<'

    1.现象 原本我是直接在母版引入 <script type="application/javascript" src="static/config.js" ...

  2. Windows 重装系统,配置 WSL,美化终端,部署 WebDAV 服务器,并备份系统分区

    最新博客文章链接 最近发现我 Windows11 上的 WSL 打不开了,一直提示我虚拟化功能没有打开,但我看了下配置,发现虚拟化功能其实是开着的.然后试了各种方法,重装了好几次系统,我一个软件一个软 ...

  3. Java 在PDF中添加工具提示|ToolTip

    本文,将介绍如何通过Java后端程序代码在PDF中创建工具提示.添加工具提示后,当鼠标悬停在页面上的元素时,将显示工具提示内容. 导入jar包 本次程序中使用的是 Free Spire.PDF for ...

  4. system (color XX )函数详解:调整控制台颜色的命令

    1.指定控制台输出的颜色属性 2.颜色属性由两个十六进制数字指定 -- 第一个为背景,第二个则为前景.每个数字可以为以下任何值之一: 例如: "COLOR fc" 在亮白色上产生亮 ...

  5. mysql数据库优化1

    目录 数据库结构的设计优化 1.数据库结构的设计 2.针对大型的数据量提前进行分库和分表 3.分库分表带来的问题 4.表结构设计注意的问题 查询优化 1.查询语句的注意事项 2.应尽量避免在 wher ...

  6. RabbitMQ 中的分布式,普通 cluster 模式的构建

    RabbitMQ 如何做分布式 前言 集群配置方案 cluster 普通模式 镜像模式 federation shovel 节点类型 RAM node Disk node 集群的搭建 1.局域网配置 ...

  7. jsp标签问题

    在jsp页面使用标签过程中有时候不注意规则的话,eclipse会提示一些错误,下面针对这些错误提出相应的解决办法:<form></form>标签1. Invalid locat ...

  8. Android学习笔记4

    activity配置文件 //AndroidMainifest.xml <?xml version="1.0" encoding="utf-8"?> ...

  9. QPS、TPS、并发用户数、吞吐量

    1.QPS QPS Queries Per Second 是每秒查询率 ,是一台服务器 每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内 所处理流量多少的衡量标准, 即每秒的响应请求数,也 ...

  10. Lesson3——Pandas Series结构

    1 什么是Series结构? Series 结构,也称 Series 序列,是 Pandas 常用的数据结构之一,它是一种类似于一维数组的结构,由一组数据值(value)和一组标签组成,其中标签与数据 ...