Pytorch实现逻辑回归

  我们还是先回顾一下线性回归。之前学习的线性回归,我们使用了下图所示的模型。

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归


  

  在线性回归中,我们要估计的 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 是属于连续的空间,像这种任务我们就称做是回归任务。但是在很多机器学习任务里面,我们要做的是分类,比如 MNIST 数据集(手写数字),那么它一共有 10 类分别是数字 0-9,那么最后我们要估计的 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 是属于一个集合,就是拥有 10 个离散值的集合。那么预测 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 是属于其中的哪一类,这种问题我们称做分类问题。

  

  可以用以下命令来下载 MNIST 数据集。

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_05

  
  下面来看看回归任务和分类任务的比较。举一个小例子,图(1) 是一个回归任务,图(2)是一个分类任务。两张图中 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_06 表示学习时间,图(1) 的 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 表示他将来能拿到的点数,图(2) 的 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 表示他能否通过考试,0 表示不能通过,1 表示能够通过。这里面只有两个类别,我们将这种问题叫做二分类。二分类我们最终需要解决的问题就是求出 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_09 的概率是多少?pytorch实现 lstm进行回归的代码分析 pytorch回归分类_损失函数_10

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_11


  

  之前我们学习的线性模型 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_损失函数_12 的输出是属于实数范围的,但是我们现在需要求概率,概率的取值是在 0-1 之间,那么我们怎样能把一系列的实数的值域约束在 0-1 之间呢?换句话说,我们要找到一个函数将线性模型的输出值从实数空间映射到 [0, 1]。

  

  逻辑回归用了这样一个函数:

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_损失函数_13


  

  当 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_06 趋近于正无穷, pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 的值趋近于 1;当 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_06 趋近于负无穷, pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 的值趋近于 0;当 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_06 等于 1, pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 的值等于 0.5,那么可以画出 Logistic Function 图像如下:

  

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_20


  

  我们会注意到该函数有一个特点,当 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_06 大于了某一个值或者小于了某一个值之后,函数的增长是非常缓慢的,它们的导数会变得越来越小,越来越接近于 0,这种函数在数学中被称为饱和函数,在机器学习领域称为 Sigmoid 函数。饱和函数的导数类似于正态分布函数。

  

  我们再来看看其它的 Sigmoid 函数。

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_损失函数_22


  

  只要满足函数值域都在 0-1 之间,而且都是单增函数,还有就是它们都是饱和函数这些条件的函数都是 Sigmoid 函数。

  

  接下来我们看看逻辑回归模型和线性模型的区别。逻辑回归相当于把线性回归的输出值作为 Sigmoid 函数的输入值来计算相应的概率。一般的 Sigmoid 函数都用 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_23

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_损失函数_24


  

  总的来说,逻辑回归和线性模型唯一的区别就是加了一个 Sigmoid 函数。那么模型改变了之后,相应的损失函数也会跟着改变。对于 Linear Regression,它计算的是两个实数值之间的差值,是在计算一个距离。但是 Logistic Regression 不再是数值了,输出是一个分布,表示类别为 0 的概率,类别为 1 的概率等等。所以我们这里比较的是两个分布之间的差异,分布的差异之前在概率论与数理统计里面学习过一些分布差异的计算,比如:KL散度,cross-entropy(交叉熵)。

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_损失函数_25


  

  这里的逻辑回归就是使用的交叉熵的方式。如果 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_09,那么 loss = -ylog(y_hat),我们的目标是要使得 loss 尽可能小,所以 y_hat 要尽可能的大;如果 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_损失函数_10,那么 loss = -log(1 - y_hat),我们的目标是要使得 loss 尽可能小,所以 y_hat 要尽可能的小。我们把这样的损失函数叫做 BCE。

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_28


  

  如果我们之后要求小批量的损失函数,就需要对所有的损失进行一个求和。

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_29


  

  下面举一个小栗子具体求解一下 BCE。

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_30


  

  从上面结果可以看出,当 y_hat 越接近与 pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_02 ,相应的 BCE 也就越小,反之。

  

  下面我们从代码观察两者之间的区别:

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性回归_32


  

  还有另外一个不同的地方就是求 Loss,之前使用的是 MSE,现在使用的是 BCE(交叉熵)。

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_33


  

  所以整个的代码就只有上面两处的变化。

  

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_损失函数_34


  

  总的来说,整个深度学习用 Pytorch 框架来写代码基本上我们就把它分成四大块。

    在上面的逻辑回归模型训练完成之后,我们就可以用 Model 进行测试。

  

pytorch实现 lstm进行回归的代码分析 pytorch回归分类_线性模型_35


  具体代码见 09 Pytorch实现逻辑回归.ipynb