-《度人经》
这是台大李宏毅程深度学习课程第一课的内容,这节课主要阐述了如何使用神经网络来拟合函数,即可以通过若干个线性整流函数(ReLU)组合形成分段函数,去逼近目标函数的各个部分。通过证明,可以得到浅层的神经网络可以拟合一切函数的结论。通过直观上比较和理论证明(没有看懂),可以得到在相同参数(神经元)情况下,深层结构网络优于浅层网络结构的结论。
浅层神经网络是否可以拟合一切函数
给定一个L-Lipschitz function,即
现在考虑在区间[0,1]上,使用一个只有一个隐藏层的网络,如果通过这个网络能找到一个拟合$f(x)$的函数$f^*(x)$,使
$\epsilon$是一个很小的正数,那么拟合的目标就达到了。
如何才能做到呢?在几何直观上可以有以下关系
是
的充分条件,所以只要做到第一个不等式,第二个不等式就满足了。设该函数被神经网络用$1/l$段分段函数来表示,根据第一条性质,那么有$l*L \le \epsilon$,所以$l \le
\epsilon/L$,即需要$L/\epsilon$段分段函数才能满足要求。假设每一段函数需要用两个ReLU神经元来表示,那么就需要$2L/\epsilon$个神经元。
深度神经网络比浅层神经网络好多少
通过上述推导,可以发现浅层的神经网络的确可以拟合任何函数,但是使用Deep Structure会更有效率,输入相同参数的情况下,深层网络可以表示更多分段函数的片段。可以证明,如果使用取绝对值的神经元(线性整流函数),每增加一个神经元,可以使原来的分段函数的段数翻倍。给一个宽度为K,深度为H的网络,可以表示至少$K^H$段分段函数。
$f(x)=x^2$
考虑如上函数,如果在区间[0,1]要使用$2^m$个片段来拟合,可以算出浅层网络至少需要$O(1/\sqrt(\epsilon))$个神经元才能做到。如果是深度神经网络的话,可以发现使用m个取绝对值的神经元(两个ReLU)就可以表示,可以发现深度网络的优势很大。
而有了这个表示之后,可以通过$x^2$表示$x_1,x_2$,即$\frac{1}{2}((x_1+x_2)^2-x_1^2-x_2^2)$,以此类推,可以表示$x^n$以及任意多项式函数。所以从这个角度来看,深层网络对于浅层网络具有很大优势。
TensorFlow
学习使用tensorflow,参考了香港科技大学在Google Drive上分享的PPT,8012年了,我才初次接触深度学习框架,看着这么多花花绿绿的API还真是摸不到头脑。不过通过学习最简单的模型,我觉得tensorflow的使用流程大致可以分为以下几步:
- 设定数据源格式,一般使用tf.placeholder()方法定义,就是要把什么格式的数据倒进这堆矩阵进行训练。
- 设定训练过程中需要的参数,一般使用tf.Variable()方法定义
- 设定数据源如何与参数在矩阵中相互作用流动变化,最后得到我们对数据源的假设,比如预测数据源的标签
- 通过比较假设与真实数据的差别,设定损失函数
- 选定一种优化方法,设定学习速率去优化损失函数
通过以上定义,得到了一个计算图模型,现在初始化所有参数,开启tensorflow环境,通过run()方法传入数据源,并运行假设、损失函数、优化方法这些计算图,使参数得到更新,如果不出意外,通过多次迭代,当损失函数下降到一定程度后并经过交叉验证的考验后,我们需要的金丹(参数)就出炉了,然后就可以愉快的使用这些参数来对新数据进行预测了,不过如果丹炉的火焰久久不能化为天青色损失函数不能收敛,那么就要考虑是不是缺了什么玄学调参的步骤。
课堂作业
课堂作业只做了一个。即使用具有相同参数的深层结构神经网络和浅层神经网络来拟合一个非线性函数,然后比较它们的收敛速度。代码放到了Github上。
下面贴一下结果(这两个网络好像都不是很好,运行了好多遍才得到勉强能看的结果),可以发现相同参数的情况下,浅层网络(1x9x1)刚开始很好,但是后劲不比深层的网络(1x4x3x1):