UFLDL深度学习笔记 (二)Softmax 回归

本文为学习“UFLDL Softmax回归”的笔记与代码实现,文中略过了对代价函数求偏导的过程,本篇笔记主要补充求偏导步骤的详细推导。

1. 详细推导softmax代价函数的梯度

经典的logistics回归是二分类问题,输入向量$ x{(i)}\in\Re{n+1}$ 输出0,1判断\(y^{(i)}\in{\{0,1\}}\),Softmax回归模型是一种多分类算法模型,如图所示,输出包含k个类型,\(y^{(i)}\in{\{0,1,…,k\}}\)。

在经典的多分类问题MNIST数字识别任务中包含0-9十个手写数字。softmax的思路是将输入值直接判决为k个类别的概率,这里就需要一个判决函数,softmax采用指数形式。求和的倒数是为了归一化概率。

\[h_\theta(x^{(i)})=\begin{bmatrix}p(y^{(i)}=1|x^{(i)};\theta)\\ p(y^{(i)}=2|x^{(i)};\theta)\\\vdots\\ p(y^{(i)}=k|x^{(i)};\theta)\\\end{bmatrix}=\frac{1}{\sum_{j=1}^k e^{\theta_j^T \cdot x^{(i)}}}\begin{bmatrix} e^{\theta_1^T \cdot x^{(i)}} \\ e^{\theta_2^T \cdot x^{(i)}}\\\vdots\\ e^{\theta_k^T \cdot x^{(i)}}\\\end{bmatrix}
\]

为了矩阵运算方便,将权重参数记作矩阵形式 $$\theta = \begin{bmatrix} \theta_1^T \ \theta_2^T\\vdots\ \theta_k^T\\end{bmatrix}_{k\times(n+1)}$$

包含权重惩罚项的softmax的代价函数为

\[J(\theta)=-\frac 1 m \left [\sum_{i=1}^m\sum_{j=1}^k 1\{y^{(i)}=j\}\cdot log(p(y^{(i)}=j|x^{(i)};\theta)) \right] +\frac \lambda 2 \sum_{i=1}^k\sum_{j=0}^n\theta_{ij}^2
\]

原文Softmax回归略过了求偏导的过程,下文对其做分步推导。\(\theta_j\)是行向量,表示每个输入x与第j个输出分类连接的权重, 将对数内除法拆分为减法可得:

\[J(\theta)=-\frac 1 m \left [\sum_{i=1}^m\sum_{j=1}^k 1\{y^{(i)}=j\}\cdot ({\theta_j^T x^{(i)}}-log(\sum_{l=1}^ke^{\theta_l^T \cdot x^{(i)}})) \right] +\frac \lambda 2 \sum_{i=1}^k\sum_{j=0}^n\theta_{ij}^2
\]

对\(\theta_j\)求偏导,可得:

\[\begin{align} \frac {\nabla J(\theta)} {\nabla \theta_j} &= -\frac 1 m\sum_{i=1}^m \left [ \frac {\nabla\sum_{j=1}^k 1\{y^{(i)}=j\}\theta_j^T x^{(i)}} {\nabla \theta_j} - \frac {\nabla \sum_{j=1}^k 1\{y^{(i)}=j\}log(\sum_{l=1}^ke^{\theta_l^T \cdot x^{(i)}}))} {\nabla \theta_j} \right] +\lambda\theta_j \\ &= -\frac 1 m\sum_{i=1}^m \left [ 1\{y^{(i)}=j\} x^{(i)} - \frac {\nabla\sum_{j=1}^k 1\{y^{(i)}=j\}\sum_{l=1}^ke^{\theta_l^T \cdot x^{(i)}}} {\sum_{l=1}^ke^{\theta_l^T \cdot x^{(i)}}\nabla \theta_j} \right] +\lambda\theta_j \\ &= -\frac 1 m\sum_{i=1}^m \left [ 1\{y^{(i)}=j\} x^{(i)} - \frac {x^{(i)}e^{\theta_j^T \cdot x^{(i)}}} {\sum_{l=1}^ke^{\theta_l^T \cdot x^{(i)}}} \right] +\lambda\theta_j \\ &= -\frac 1 m\sum_{i=1}^m x^{(i)}\left [ 1\{y^{(i)}=j\} - p(y^{(i)}=j|x^{(i)};\theta) \right] +\lambda\theta_j \end{align}
\]

这样我们得到了代价函数对参数权重的梯度,类似前篇稀疏自编码的做法,需要做以下步骤:

  • 结合梯度下降法,使用训练数据求出参数权重\(\theta\)的最优解;
  • 用训练过的权重对测试数据做前向传播,每个测试数据得到\(k\)个软判决输出值,分别表示判决为\(1…k\)分类的概率;
  • 选取\(k\)个中的最大值即为对测试数据的分类结果;
  • 与测试数据集的真实输出对比统计获得预测准确率。

2. 偏导的矩阵化表示

当真正编写代码时会发现上述梯度公式是对行向量\(\theta\)的,UFLDL没有给出矩阵公式,矩阵表达又该是怎样呢?请看下文推导。

基本符号表达式这样的:

输入数据:\(X_{(n+1) \times m}\)

概率矩阵:\(norm(exp(\theta_{k\times (n+1)} \times X_{(n+1) \times m}) )= P_{k\times m}\)

1函数表示第i个输入的输出值是否为分类j,遍历所有输入、输出得到矩阵 $ G_{k \times m}$,称为groundTruth.

偏导第j行的向量为输入数据每一行(共n+1行)与\(G_{k \times m} P_{k \times m}\)的每一行的点积,加上\(\lambda\theta_j\) 本身:

\[\begin{align} \frac {\nabla J(\theta)} {\nabla \theta_j} &=-\frac 1 m X_{(n+1) \times m} \bullet(g_{m\times1}-p_{m\times1}) +\lambda\theta_j \end{align}
\]

再进一步写成矩阵形式:

\[\begin{align} \frac {\nabla J(\theta)} {\nabla \theta} &=-\frac 1 m (G_{k \times m}-P_{k\times m}) *X_{(n+1) \times m}^T +\lambda\theta \end{align}
\]

好了,矩阵化完成,可以痛快地写代码了!

3. matlab代码实现

这里只给出实现过程中遇到问题的代码片段,完整代码见https://github.com/codgeek/deeplearning,编写过前一节稀疏自编码 的小伙伴应该对整体结构比较熟悉了,softmaxCost.m实现给定参数权重时的代价值与梯度的矩阵计算,softmaxExercise.m结合梯度下降调用代价、梯度计算,完整实现上述四个步骤。

对1函数的计算有一些语法技巧,示例代码给出的full/sparse有些抽象,我用最基本的的==返回矩阵逻辑结果这个特性来计算,

首先把校验标签复制k份获得\(k\times m\)的矩阵:labels = repmat(labels, numClasses, 1);

然后制造出每一行等于行号的矩阵:k = repmat((1:numClasses)',1,numCases);

所以1函数对应的矩阵$ G_{k \times m}$为groundTruth = double((k == labels));

上一节已经给出了完整的矩阵化公式,也是理论转换为代码实现的难点所在,softmaxCost.m详细代码如下,

function [cost, grad] = softmaxCost(theta, numClasses, inputSize, lambda, data, labels, ~)
% numClasses - the number of classes
% inputSize - the size N of the input vector
% lambda - weight decay parameter
% data - the N x M input matrix, where each column data(:, i) corresponds to
% a single test set
% labels - an M x 1 matrix containing the labels corresponding for the input data
% % Unroll the parameters from theta
theta = reshape(theta, numClasses, inputSize); numCases = size(data, 2);
% groundTruth = full(sparse(labels, 1:numCases, 1));
%
labels = repmat(labels, numClasses, 1);
k = repmat((1:numClasses)',1,numCases);% numClasses×numCases.
groundTruth = double((k == labels));% % groundTruth algrithum is the same as (k===label)
thetagrad = zeros(numClasses, inputSize); %% ---------- YOUR CODE HERE --------------------------------------
% Instructions: Compute the cost and gradient for softmax regression.
% You need to compute thetagrad and cost.
% The groundTruth matrix might come in handy.
cost = 0;
z = theta*data;
z = z - max(max(z)); % avoid overflow while keep p unchanged.
z = exp(z); % matrix product: numClasses×numCases
p = z./repmat(sum(z,1),numClasses,1); % normalize the probbility aganist numClasses. numClasses×numCases
cost = -mean(sum(groundTruth.*log(p), 1)) + sum(sum(theta.*theta)).*(lambda/2); thetagrad = -(groundTruth - p)*(data')./numCases + theta.*lambda; % numClasses×inputSize % Unroll the gradient matrices into a vector for minFunc
grad = thetagrad(:);
end

另外一部分需要稍动脑筋的是预测判断。怎样写的简捷高效呢?请看下文.

function [pred] = softmaxPredict(softmaxModel, data)
theta = softmaxModel.optTheta; % this provides a numClasses x inputSize matrix
pred = zeros(1, size(data, 2)); inputSize = softmaxModel.inputSize;
numClasses= softmaxModel.numClasses; %% ---------- YOUR CODE HERE --------------------------------------
z=exp(theta*data);
[~, pred] = max(z);
end

关键在于使用matlab的max函数第二个返回值,它就是每列最大值的行号。

4. 图示与结果

数据集来自Yann Lecun的笔迹数据库,我们先瞜一眼原始MMIST数据集的笔迹。

设定与练习说明相同的参数,运行完整代码https://github.com/codgeek/deeplearning 可以看到预测准确率达到92.6%。达到了练习的标准结果。

小结一下,看到梯度、矩阵化推导过程不难发现,一般都是先从对矩阵单个元素的偏导开始,给出表达式,然后把每个元素列举成行成列,根据行、列计算的关系,往矩阵乘法的“乘加”模式上套用,最终给出非常精简的矩阵化公式,矩阵只是一个规范化工具,难以直接在矩阵的抽象层次上推导,也很容易把一些在矩阵上不成立的直觉公式用上去而出错,所以现阶段还是一个从抽象到具体再到抽象的过程。

UFLDL深度学习笔记 (二)SoftMax 回归(矩阵化推导)的更多相关文章

  1. UFLDL深度学习笔记 (七)拓扑稀疏编码与矩阵化

    UFLDL深度学习笔记 (七)拓扑稀疏编码与矩阵化 主要思路 前面几篇所讲的都是围绕神经网络展开的,一个标志就是激活函数非线性:在前人的研究中,也存在线性激活函数的稀疏编码,该方法试图直接学习数据的特 ...

  2. UFLDL深度学习笔记 (六)卷积神经网络

    UFLDL深度学习笔记 (六)卷积神经网络 1. 主要思路 "UFLDL 卷积神经网络"主要讲解了对大尺寸图像应用前面所讨论神经网络学习的方法,其中的变化有两条,第一,对大尺寸图像 ...

  3. UFLDL深度学习笔记 (四)用于分类的深度网络

    UFLDL深度学习笔记 (四)用于分类的深度网络 1. 主要思路 本文要讨论的"UFLDL 建立分类用深度网络"基本原理基于前2节的softmax回归和 无监督特征学习,区别在于使 ...

  4. UFLDL深度学习笔记 (三)无监督特征学习

    UFLDL深度学习笔记 (三)无监督特征学习 1. 主题思路 "UFLDL 无监督特征学习"本节全称为自我学习与无监督特征学习,和前一节softmax回归很类似,所以本篇笔记会比较 ...

  5. UFLDL深度学习笔记 (一)反向传播与稀疏自编码

    UFLDL深度学习笔记 (一)基本知识与稀疏自编码 前言 近来正在系统研究一下深度学习,作为新入门者,为了更好地理解.交流,准备把学习过程总结记录下来.最开始的规划是先学习理论推导:然后学习一两种开源 ...

  6. UFLDL深度学习笔记 (五)自编码线性解码器

    UFLDL深度学习笔记 (五)自编码线性解码器 1. 基本问题 在第一篇 UFLDL深度学习笔记 (一)基本知识与稀疏自编码中讨论了激活函数为\(sigmoid\)函数的系数自编码网络,本文要讨论&q ...

  7. 深度学习笔记 (二) 在TensorFlow上训练一个多层卷积神经网络

    上一篇笔记主要介绍了卷积神经网络相关的基础知识.在本篇笔记中,将参考TensorFlow官方文档使用mnist数据集,在TensorFlow上训练一个多层卷积神经网络. 下载并导入mnist数据集 首 ...

  8. 深度学习笔记:优化方法总结(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam)

    深度学习笔记:优化方法总结(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam) 深度学习笔记(一):logistic分类 深度学习笔记(二):简单神经网络,后向传播算法及实现 ...

  9. 深度学习(二十六)Network In Network学习笔记

    深度学习(二十六)Network In Network学习笔记 Network In Network学习笔记 原文地址:http://blog.csdn.net/hjimce/article/deta ...

随机推荐

  1. [TypeScript] Type Definitions and Modules

    For example you are building your own module, the same as Lodash: my-lodash.d.ts declare module &quo ...

  2. 搭建dubbo-admin-2.5.3

    dubbo管理界面 一,安装zookeeper 1,下载包zookeeper-3.3.3.tar.gz 2,解压 tar zxvf zookeeper-3.3.3.tar.gz cd zookeepe ...

  3. WORD中无损复制图片

    问题 默认 Ctrl+C复制出来图片图片的严重模糊,复制出来的不是原图片!因为图片尺寸被修改后复制出来的则是模糊的 解决办法 解决办法把WORD中的图片恢复成默认的,如果对图片进行了缩放请把缩放比恢复 ...

  4. Activity生命周期以及启动模式对生命周期的影响(二)

    前面一篇文章概述了Android四大组件之一的Activity生命周期方法的调用先后顺序,但对于非标准启动模式下Activity被多次调用时的一些生命周期方法并未详细阐述,现在针对该情况着重记录. 现 ...

  5. EditText输入为空button不可点击搜索

    一丶任务详情 二丶改动后演示效果 三丶改动过程 分析:非常明显这里是须要监听EditText,推断输入字符串长度是否不为0来改变Button样式 首先的屡清楚代码逻辑在适当的位子加监听推断是最好的处理 ...

  6. Spring容器的属性配置详解的六个专题

    在spring IOC容器的配置文件applicationContext.xml里,有一些配置细节值得一提.我们将一些问题归结为以下几个专题.   专题一:字面值问题 配置的bean节点中的值,我们提 ...

  7. 使用Python爬虫爬取网络美女图片

    代码地址如下:http://www.demodashi.com/demo/13500.html 准备工作 安装python3.6 略 安装requests库(用于请求静态页面) pip install ...

  8. 【Linux设备驱动程序】Chapter 2 - 构造和运行模块

    Hello World 模块 #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Du ...

  9. mysql中的时间类型datetime,date,time,year,timestamp小知识点

    1.datetime,date,time,year四个类型的值,可以手动输入,也可以调用函数获得值 ① 手动输入,格式如下: datetime "2016-6-22 14:09:30&quo ...

  10. python相关性分析与p值检验

    ## 最近两天的成果 ''' ########################################## # # # 不忘初心 砥砺前行. # # 418__yj # ########### ...