[DL] 基于theano.tensor.dot的逻辑回归代码中的SGD部分的疑问探幽
在Hinton的教程中, 使用Python的theano库搭建的CNN是其中重要一环, 而其中的所谓的SGD - stochastic gradient descend算法又是如何实现的呢? 看下面源码
(篇幅考虑只取测试模型函数, 训练函数只是多了一个updates参数, 并且部分参数有改动):
classifier = LogisticRegression(input=x, n_in=24 * 48, n_out=32)
cost = classifier.negative_log_likelihood(y)
test_model = theano.function(inputs=[index],
outputs=classifier.errors(y),
givens={
x: test_set_x[index * batch_size: (index + 1) * batch_size],
y: test_set_y[index * batch_size: (index + 1) * batch_size]})
行3声明了一个对象classifer, 它的输入是符号x, 大小为24*48, 输出长度为32.
行11定义了一个theano的函数对象, 接收的是下标index, 使用输入数据的第index*batch_size~第(index+1)*batch_size个数据作为函数的输入, 输出为误差.
我们再来看看行12中的errors函数的定义:
def errors(self, y):
# check if y has same dimension of y_pred
if y.ndim != self.y_pred.ndim:
raise TypeError('y should have the same shape as self.y_pred',
('y', target.type, 'y_pred', self.y_pred.type))
# check if y is of the correct datatype
if y.dtype.startswith('int'):
# the T.neq operator returns a vector of 0s and 1s, where 1
# represents a mistake in prediction
return T.mean(T.neq(self.y_pred, y))
else:
raise NotImplementedError()
self.y_pred 是一个大小为batch_size的向量, 每个元素代表batch_size中对应输入的网络判断结果, errors函数接受1个同等大小的期望输出y, 将两者进行比较求差后作均值返回, 这正是误差的定义.
那么问题来了, 这个 self.y_pred 是如何计算的? 这里我们看LogisticRegression的构造函数:
def __init__(self, input, n_in, n_out):
# initialize with 0 the weights W as a matrix of shape (n_in, n_out)
self.W = theano.shared(value=numpy.zeros((n_in, n_out),
dtype=theano.config.floatX),
name='W', borrow=True)
# initialize the baises b as a vector of n_out 0s
self.b = theano.shared(value=numpy.zeros((n_out,),
dtype=theano.config.floatX),
name='b', borrow=True)
# compute vector of class-membership probabilities in symbolic form
self.p_y_given_x = T.nnet.softmax(T.dot(input, self.W) + self.b)
# compute prediction as class whose probability is maximal in
# symbolic form
self.y_pred = T.argmax(self.p_y_given_x, axis=1)
# parameters of the model
self.params = [self.W, self.b]
在行13可以看到, 使用input和self.W, self.b进行了一个softmax的映射. softmax本身是一个一一映射所以此处不再细说, 详情可以搜索引擎. 这里我们来说一说T.dot(input, self.W).
这里的dot是theano的tensor变量的点乘操作, T.dot接受两个矩阵(向量)输入, 计算它们的点积并返回一个保存了点乘信息的节点对象, 使用返回的对象调用eval()方法即可获得实际数值结果, 如下:
>>> a = numpy.asarray([1,2,3])
>>> b = numpy.asarray([[3],[2],[1]])
>>> T.dot(a,b).eval()
array([10])
上述代码是在ab大小匹配的情况, 即a的第2维等于b的第1维. 所以本例中正常情况(非SGD)下, input是1行1152列的, W是1152行32列的, b的长度为1行32列.
这里的T.dot计算的结果是(input*W), 见如下代码:
>>> a = numpy.ones((1, 1152))
>>> W.shape
(1152, 32)
>>> dotaW = T.dot(a, W)
>>> dotaW = dotaW.eval()
>>> dotaW.shape
(1, 32)
注意, 如果颠倒了a和W的位置, 会报尺寸不匹配的错误.
那么在SGD算法中, 行13代码中的input的大小实际上是batch_size行1152(24*48)列的, 所以我不禁疑惑, 如果a和b大小不匹配呢? 一个合理的推断就是, T.dot会自动截断input. 看如下代码:
>>> a = numpy.ones((10, 1152))
>>> dotaW = T.dot(a, W)
>>> dotaW = dotaW.eval()
>>> dotaW.shape
(10, 32)
果然, T.dot会自动截断input, 将其按照匹配W的尺寸(1行1152列)依次和W进行点乘后返回, 所以大小为(10, 32), 又偏置b的大小为(1, 32), 所以b会按列进行相加.
解决了T.dot的问题, 一开篇的疑问就比较容易解答了, SGD基于T.dot的这种特性, 一次性输入batch_size行1152列样本, T.dot配合softmax生成batch_size行32列输出, 再基于 T.argmax(self.p_y_given_x, axis=1) , 计算每行(样本)的最大值作为期望输出y_pred(尺寸为batch_size行1列).
本人预测, 卷积神经网络中的conv2d也是同样的机理, 对于一定数量的输入, 如20个48行24列大小的图像, 它会针对每一个输入样本产生对应的N张特征图->降采样->第二层卷积层->MLP, 到了MLP中, 配合上述的T.dot的特性, 就完成了SGD中的批训练的目的.
[DL] 基于theano.tensor.dot的逻辑回归代码中的SGD部分的疑问探幽的更多相关文章
- 逻辑回归代码demo
程序所用文件:https://files.cnblogs.com/files/henuliulei/%E5%9B%9E%E5%BD%92%E5%88%86%E7%B1%BB%E6%95%B0%E6%8 ...
- 线性回归,感知机,逻辑回归(GD,SGD)
线性回归 线性回归是一个回归问题,即用一条线去拟合训练数据 线性回归的模型: 通过训练数据学习一个特征的线性组合,以此作为预测函数. 训练目标:根据训练数据学习参数(w1,w2, ... , wn,b ...
- 分布式机器学习:逻辑回归的并行化实现(PySpark)
1. 梯度计算式导出 我们在博客<统计学习:逻辑回归与交叉熵损失(Pytorch实现)>中提到,设\(w\)为权值(最后一维为偏置),样本总数为\(N\),\(\{(x_i, y_i)\} ...
- 线性模型之逻辑回归(LR)(原理、公式推导、模型对比、常见面试点)
参考资料(要是对于本文的理解不够透彻,必须将以下博客认知阅读,方可全面了解LR): (1).https://zhuanlan.zhihu.com/p/74874291 (2).逻辑回归与交叉熵 (3) ...
- Spark Mllib逻辑回归算法分析
原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3816289.html 本文以spark 1.0.0版本MLlib算法为准进行分析 一.代码结构 逻辑回归 ...
- 逻辑回归应用之Kaggle泰坦尼克之灾(转)
正文:14pt 代码:15px 1 初探数据 先看看我们的数据,长什么样吧.在Data下我们train.csv和test.csv两个文件,分别存着官方给的训练和测试数据. import pandas ...
- Coursera《machine learning》--(6)逻辑回归
六 逻辑回归(Logistic Regression:LR) 逻辑回归(Logistic Regression, LR)模型其实仅在线性回归的基础上,套用了一个逻辑函数,但也就是由于这个逻辑函数,使得 ...
- AI之旅(4):初识逻辑回归
前置知识 求导 知识地图 逻辑回归是用于分类的算法,最小的分类问题是二元分类.猫与狗,好与坏,正常与异常.掌握逻辑回归的重点,是理解S型函数在算法中所发挥的作用,以及相关推导过程. 从一个例子 ...
- 机器学习入门11 - 逻辑回归 (Logistic Regression)
原文链接:https://developers.google.com/machine-learning/crash-course/logistic-regression/ 逻辑回归会生成一个介于 0 ...
随机推荐
- ajax post data 获取不到数据,注意contentType
$.ajax({ url:'/web/register/', type:"POST", data:{'user':'66'}, dataType:'json', 这个东西困惑我一天 ...
- python-day41--数据库---数据类型
一.存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 二.mysql 数据类型 1.数字:(宽度指的是显示宽度,与存储无关) 不用指定宽度, ...
- iterator not dereferencable问题
STL中的迭代器总是出现各种问题,这个是我在打表达式求值时碰到的... 综合网上的答案,一般来说有两种情况: 第一:访问了非法位置. 一般来说可能在queue为空时取front(),rear(),或者 ...
- nyoj-310-河南省第四届省赛题目-二分+dinic
SECRET 时间限制:3000 ms | 内存限制:65535 KB 难度:6 描述 Dr.Kong is constructing a new machine and wishes to ...
- Oracle性能诊断艺术-读书笔记
create table test0605 as select * from dba_objects; select t1.owner,t1.object_name,t1.object_id from ...
- Oracle sqlloader
一.SQL*LOADER简介 SQL*Loader是oracle提供的可以从多种平面文件中向数据库中加载数据的工具,使用sqlldr工具可以在很短的时间内向数据库中加载大量的数据,像把制作好的exce ...
- EXCEL FAQ
1.win7双击打开EXCEL07时显示停止工作,但是在打开方式中可以打开,怎么破? 加载项的问题,在选项-信任中心-信任中心设置-加载项-禁用所有应用程序加载项即可,但是这样会丧失一些功能,也可以把 ...
- C++ bitset
itset存储二进制数位. bitset就像一个bool类型的数组一样,但是有空间优化——bitset中的一个元素一般只占1 bit,相当于一个char元素所占空间的八分之一. bitset中的每个元 ...
- 在ant中将依赖jar包一并打包的方法
一般jar包里面是不包含jar文件的,如果自己的类有依赖其他jar包,可以通过ant命令将这些jar包解析,然后和自己的class文件打在一起,命令如下: build.xml 1 2 3 4 5 6 ...
- 2019.1.5 China’s population
China’s population is expected to hit a peak of 1.44 billion in 2029, and start to experience negati ...