http://blog.csdn.net/u011239443/article/details/78148087
6.1 实例:学习 XOR
通过学习一个表示来解决 XOR 问题。图上的粗体数字标明了学得的函数必须在每个点输出的值。(左) 直接应用于原始输入的线性模型不能实现 XOR 函数。当 x 1 = 0 时,模型的输出必须随着 x 2 的增大而增大。当 x 1 = 1 时,模型的输出必须随着 x 2 的增大而减小。线性模型必须对x 2 使用固定的系数 w 2 。因此,线性模型不能使用 x 1 的值来改变 x 2 的系数,从而不能解决这个问题。(右) 在由神经网络提取的特征表示的变换空间中,线性模型现在可以解决这个问题了。在我们的示例解决方案中,输出必须为 1 的两个点折叠到了特征空间中的单个点。换句话说,非线性特征将 x = [1,0] ⊤ 和 x = [0,1] ⊤ 都映射到了特征空间中的单个点 h = [1,0] ⊤ 。线性模型现在可以将函数描述为 h 1 增大和 h 2 减小。在该示例中,学习特征空间的动机仅仅是使得模型的能力更大,使得它可以拟合训练集。在更现实的应用中,学习的表示也可以帮助模型泛化。
代码实现:
import tensorflow as tf
import numpy as np
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
Y = np.array([[0], [1], [1], [0]])
x = tf.placeholder(tf.float32, [None, 2])
y = tf.placeholder(tf.float32, [None, 1])
w1_1 = tf.Variable(tf.random_normal([2, 1]))
w1_2 = tf.Variable(tf.random_normal([2, 1]))
w2 = tf.Variable(tf.random_normal([2, 1]))
b1_1 = tf.constant(0.1, shape=[1])
b1_2 = tf.constant(0.1, shape=[1])
b2 = tf.constant(0.1, shape=[1])
h1 = tf.nn.relu(tf.matmul(x, w1_1) + b1_1)
h2 = tf.nn.relu(tf.matmul(x, w1_2) + b1_2)
# 将两数组按列合并
hidden = tf.concat([h1, h2], 1)
out = tf.matmul(hidden, w2) + b2
loss = tf.reduce_mean(tf.square(out - y))
train = tf.train.AdamOptimizer(0.01).minimize(loss)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(1000):
for j in range(4):
sess.run(train, feed_dict={x: np.expand_dims(X[j], 0), y: np.expand_dims(Y[j], 0)})
loss_ = sess.run(loss, feed_dict={x: X, y: Y})
print("step: %d, loss: %.3f"%(i, loss_))
print("X: %r"%X)
print("pred: %r"%sess.run(out, feed_dict={x: X}))
6.2 基于梯度的学习
神经网络中的非线性导致它的大部分代价函数变得非凸,对于非凸的损失函数,梯度下降算法不能保证收敛到全局最优,因此神经网络模型中的参数初始化是非常重要的,通常会将所有的权重初始化为一个较小的随机数,并且将偏置初始化为0或者较小的正值。同其他机器学习算法一样,基于梯度的学习方法,需要设计代价函数,选择模型输出的表示方法。这里介绍神经网络中关于它们的一些设计方法。
6.2.1 代价函数
同其他机器学习模型一样,大多数情况下,神经网络的参数模型定义一个分布由于神经网络的特殊结构,导致神经网络必须注意的是损失函数的梯度必须有足够大的预测性,这样才能很好的指导算法的学习。很多输出单元都会包含一个指数函数,当变量取绝对值非常大的负值时函数会变得饱和(函数变得很“平”),函数梯度变得很小,而负的对数似然能够抵消输出单元中的指数效果。
6.2.1.2 学习条件统计量
我们有时只需要学习给定 x 的某个条件统计量,不需要学习一个完整的概率分布
,线性输出层常被用来产生条件高斯分布均值:
这满足概率要求,但是使用梯度下降算法无法高效训练这个模型,因为当
处于单位区间外,模型梯度都将为0,梯度为0则使得算法不能再继续学习参数。我们需要使用一种方法使得无论模型合适给出错误答案,都能有一个比较大的梯度。这就是使用sigmoid单元的原因,sigmoid单元定义如下:
我们分析使用sigmoid单元的极大似然交叉熵损失函数,首先忽略对于 x 的依赖性,只讨论如何用z 的概率分布。sigmoid可以构造一个非归一化(和不为1)的概率分布 其中初始化的仿射变换参数的建议是将 b 的所有元素设置成一个较小的正值,这样整流线性单元在初始时就对训练集中的大多数输入处于激活状态,并且允许导数通过。
整流线性单元的一个缺陷是未激活状态不能带来基于梯度学习的效果。因此许多整流线性单元的扩展设计了不同的方法避免这种情况。当 z_i=0时使用一个非零的斜率 alpha_i ,表示为
下面是三种基于这种设计方法的激活函数:
绝对值整流(absolute value rectification):通过固定
,maxout可以学习 k 段的分段线性凸函数。当 k 足够大时,maxout可以以任意精度来近似任何凸函数。由于maxout相比普通整流线性单元增加了 k 组,因此参数增加了 k 倍,所以训练maxout需要更多的正则化或者更多训练样本来提高模型的泛化能力。
6.3.2 logistic sigmoid与双曲正切函数
对于隐藏单元,logistic sigmoid函数只有在输入接近0的时候它们的梯度才比较大,因此不鼓励将它们作为前馈网络中的隐藏层,对于上文提到的输出层,对数似然损失函数抵消了sigmoid的饱和性,因此可以用在基于梯度学习的输出单元中。
那么第二层为:
在这个链式结构中,主要考虑的是网络的深度和每一层的宽度。通常来说更深的网络对每一层能够使用更少的单元数以及参数,并且泛化效果更好,但是它也更能难以训练
6.4.1 万能近似性质和深度
万能近似定理(universal approximation theorem)表明一个前馈神经网络如果具有线性输出层和至少一层具有任何一种“挤压”性质的激活函数(如logistic sigmoid激活函数)的隐藏层,只要给与网络足够数量的隐藏单元,它可以以任意精度来近似任何从一个有限维空间到另一有限维空间的Borel可测函数,前馈网络的导数也可以任意精度来近似函数的导数。简单的说,定义在 R^n 的有界闭集上的任意连续函数是Borel可测的,因此可以用神经网络来近似。神经网络也可以近似从任何有限维离散空间映射到另一个的函数。万能近似性质被证明对于比较广泛类别的激活函数都是适用的,其中包括整流线性单元。
万能近似定理说明了存在达到任意精度的这么一个神经网络,但是没有指出这个网络有多大。Barron提供了单层网络近似一大类函数所需大小的一些界,在最坏的情况下,隐藏单元的数量是指数数量。具有单层的前馈网络足以表达任何函数,但是单元数会多到无法实现,因此无法正确学习和泛化,在很多情况下,使用更深的模型能够减少表示期望函数所需的单元数量,并且可以减少泛化误差。增加网络的深度往往能够得到比增加宽度更加好的泛化能力。增加深度能够更好的泛化的原因可以理解为神经网络将学习分解成了多个步骤(例如先认识点,再认识线,再认识形状等),每一层在上一层的基础上进行了学习。
6.5 反向传播和其他的微分算法
可参阅:http://blog.csdn.net/u011239443/article/details/76680704#t2
编码例子:http://blog.csdn.net/u011239443/article/details/75008380
网友评论