Tuesday, July 11, 2017

反向传播算法

反向传播算法backpropagation

反向传播算法是用来求代价函数C对权重w和偏置b的偏导数的,有了这个偏导数,随机梯度下降算法才可以应用在深度神经网络的学习中。偏导数其实就代表改变本身对代价函数的影响的大小。
𝜹是代价函数C对节点的偏导数,计算出𝜹后,就可以根据3,4式来计算代价函数C对权重和偏置的偏导数。而𝜹是通过从后向前反向一步一步迭代计算的(公式2),所以,要首先计算输出层没一个节点的𝜹(公式1)。

a是激活值,𝝈是激励函数,w是l层的权重矩阵,b是偏置向量。其中,中间量z是l层的带权输入

在算式BP1中,∇C是代价函数对激活值a的偏导数,可以看到代价函数对激活值a的改变速度。当代价函数C为二次代价函数时,
∇C就是:a-y, 此时BP1就成为:
𝝈'(z)是𝝈对z的导数,表示z处激活函数的变化速率。







实现方法:
def sigmoid(z):
     return 1.0/(1.0+np.exp(-z))

def sigmoid_prime(z):
    return sigmoid(z)*(1-sigmoid(z))

def delta(z, a, y):
    return (a-y) * sigmoid_prime(z)


def backprop(self, x, y):
使用反向传播算法计算𝛁b 和𝛁w
     """Return a tuple ``(nabla_b, nabla_w)`` representing the
gradient for the cost function C_x. ``nabla_b`` and
``nabla_w`` are layer-by-layer lists of numpy arrays, similar
to ``self.biases`` and ``self.weights``."""
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
# feedforward
activation = x
#用来保存激活值
activations = [x] # list to store all the activations, layer by layer
#用来保存带权输入
zs = [] # list to store all the z vectors, layer by layer
for b, w in zip(self.biases, self.weights):
   
    z = np.dot(w, activation)+b #计算带权输入z
      zs.append(z)
    activation = sigmoid(z)  #计算激活值
    activations.append(activation)
# backward pass
def delta(z, a, y):
# return (a-y) * sigmoid_prime(z)
# 计算BP1
delta = (self.cost).delta(zs[-1], activations[-1], y)
# 计算BP3
nabla_b[-1] = delta
#计算BP4
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
# Note that the variable l in the loop below is used a little
# differently to the notation in Chapter 2 of the book. Here,
# l = 1 means the last layer of neurons, l = 2 is the
# second-last layer, and so on. It's a renumbering of the
# scheme in the book, used here to take advantage of the fact
# that Python can use negative indices in lists.
for l in xrange(2, self.num_layers):
    z = zs[-l]
    sp = sigmoid_prime(z)
    # 计算BP2
    delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
    # 计算BP3
    nabla_b[-l] = delta
    # 计算BP4
    nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
return (nabla_b, nabla_w)



Monday, July 3, 2017

基于神经网络实现的图像压缩

https://research.googleblog.com/2016/09/image-compression-with-neural-networks.html

在网络中,数据压缩无处不在。在线观看的视频,分享的图片,听到的音乐,甚至现在阅读的博客,压缩技术让你可以快速和高效的分享内容,如果没有压缩技术,将要话费大量的时间和带宽。
在"Full Resolution Image Compression with Recurrent Neural Networks",中,我们使用神经网络扩展了以前在“Variable Rate Image Compression with Recurrent Neural Networks”使用的数据压缩方法,探索了机器学习是否可以提供一个更好的方法,就像他在图像识别和文字概括方面的表现。进一步,我们分享了我们的压缩模型,通过tenforflow, 你可以使用它来压缩自己的图像。
我们引入了一个新的Gated Recurrent Unit的变种,叫做Residual Gated Recurrent Unit (Residual GRU). 我们的Residual GRU是GRU和residual connect的结合,residual connect是在"Deep Residual Learning for Image Recognition"中介绍的,对于给定的压缩率,他可以获得很好的图像质量。与现在的基于DCT的压缩算法不同,我们训练2套神经网络,一套编码,一套解码。
 我们的系统以迭代的方式工作,逐步精细化重建图像,编码器和解码器都是用Residual GRU,附加信息可以从一个迭代向下一次迭代传递。每一次迭代生成一些新的Bit,可以用来提高重建图像质量。概念上,这个网络的工作方式是:
1. 初始残差,R[0]对应于原始图像I,R[0]=I
2. 设置i=1,为第一次迭代
3. 迭代[i]把R[i-1]作为输入,编码和比特化,生成压缩后的码流B[i]
4. 迭代[i]把压缩后的码流B[i]解码,生成重建图像P[i]
5. 计算迭代[i]的残差R[i]=I-P[i]
6. 设置i=i+1,跳转到第三步
残差R[i]代表当前的迭代后,生成图像与原图像有多少差异,R[i]作为输入,交给下一次迭代,目标是消除压缩误差。此时,码率B[1]到B[N]的级联就可以代表压缩图像。N越大,压缩的图像质量就越好。
为了理解他是如何工作,考虑下面的例子。

左边是原始图像,中间是第一次迭代生成的重建图像,右边是残差。

左图是第二次迭代的输入,中间是第二次迭代生成的重建图像,右边是第二次残差。
一个明显的问题是,第二次迭代,为什么可以从残差输入R[1]中,重建出高质量的重建图像P[2]呢?答案是,模型中使用的RNN模型有记忆功能,他在每一次迭代中都保存了信息用于下一次的迭代。在第一次迭代中,他从原始的图像中学习到了一些东西,用来与R[1]一起,从B[2]中生成更好的重建图像P[2]。
在每一次迭代中,网络都得到更多的关于残差的信息,
At each further iteration, the network gains more information about the errors introduced by compression (which is captured by the residual image). If it can use that information to predict the residuals even a little bit, the result is a better reconstruction. Our models are able to make use of the extra bits up to a point. We see diminishing returns, and at some point the representational power of the network is exhausted.


Sunday, July 2, 2017

BinaryConnect:二进制加权训练深层神经网络

BinaryConnect:二进制加权训练深层神经网络
BinaryConnect: TrainingDeepNeuralNetworkswith binaryweightsduringpropagations
MatthieuCourbariaux
´ Ecole Polytechnique de Montr´eal matthieu.courbariaux@polymtl.ca
YoshuaBengio Universit´e de Montr´eal, CIFAR Senior Fellow yoshua.bengio@gmail.com
Jean-PierreDavid
´ Ecole Polytechnique de Montr´eal jean-pierre.david@polymtl.ca


摘要
深层神经网络(DNN)已经在广泛的任务中取得了先进的成果,在大训练集和大量模型的帮助下,得到了最好的结果。在过去,GPU使这些突破成为可能,因为其拥有更高的计算速度的。今后,在训练和测试时,尤其是低功耗设备的消费类应用中,更快的计算很可能是能否取得进一步的进展的关键因素。因此,人们在研究开发深度学习(DL)专用硬件方面有很大兴趣。BinaryConnect,二进制的权重,即,权值被限制到只有两个可能值(例如-1或1),可以给DL带来巨大的好处,因为许多乘法累加操作被简化为加法操作,同时也能节省功耗。我们所说的BinaryConnect,其在于在向前和向后的传播训练DNN中使用二进制权重,同时保持在该梯度中累积的存储权重的精度。类似于dropout操作,BinaryConnect是一种规则化方法,使用这种方法,我们可以获得同等结果,在训练集对置换不变MNIST,CIFAR-10和SVHN中。
引言
深神经网络(DNN)已经在各方面推进了前沿技术的发展,尤其是在语音识别[1,2]和计算机视觉,特别是目标识别 [3,4 ]。最近,深度学习在自然语言处理作出了重要的进展,尤其是统计机器翻译[5,6,7]。有趣的是,取得该重大进展的关键因素之一是图形处理单元(GPU)的出现,速度提高10到30量级,从[8],以及类似的具有分布式训练的改进[9,10]。事实上,近几年的重大突破得益于能够使用大数据训练大模型的能力。如今,研究人员和开发人员在设计新的深度学习算法和应用时,经常发现自己被计算能力所限制。再加上,把深度学习系统应用于低功耗设备的需求,都大大增加了研究和开发深度网络[11,12,13]专用硬件的兴趣。
训练和应用深度网络所需要的大量计算是:由实值激活和实值权重的乘法(在反向传播算法的识别或正向传播相)或梯度(在向后传播相位反向传播算法的)。本文提出了称为BinaryConnect一种方法来降低这种乘法的运算量:强制在前向和反向运算中使用binary权值(只有2个数,1和0)。我们在训练集对置换不变MNIST,CIFAR-10和SVHN中取得了很好的结果

我们的工作之所以可行,源于两个原因
1,在累加和平均大量随机梯度时,足够的精度是必要的,但是噪音权重(以及我们可以查看到离散少数值作为噪音的一种形式,尤其是如果我们做这种离散随机)适用于随机梯度下降算法(SGD),他是深度学习的主要优化算法。 SGD在探索参数空间的时候,通过使用小的和噪音的方法,每个权重都是累积的随机梯度的平均值。因此,要保持足够的精度。乍一看,对高精度的追求绝对是非常重要的。 [14]和[15]表明,随机或随机的舍入可用于提供无偏离散化。 [14]已经表明,SGD要求权重值至少有6至8个比特的精度,[16]表示成功训练DNNs需要12位动态定点计算。此外,脑突触的估计精度为6到12比特[17]。
2.噪声权重实际提供功能是正则化,如前所述,通过使用变量噪声[18],dropout[19,20]和DropConnect [21]向激励或权重增加噪声。例如,DropConnect [21],比较类似于BinaryConnect,是一种非常有效的正则化方法,它随机的把一半的权值用0来代替。所有这些以前的工作都表明,只有权值的期望值需要具有高精度,并且,噪音实际上是有益的。
这篇文章的主要贡献有以下几种。
•我们介绍BinaryConnect,在DNN中使用,在向前和向后的传播中使用。
•我们证明了BinaryConnect是一个正则化方法,我们在MNIST,CIFAR-10和SVHN(第3节)取得了很好的效果。

•我们为BinaryConnect编写了.的代码

2 BinaryConnect

在本节中,我们给出BinaryConnect的更详细的描述,包括如何选择这两个值,如何离散化,如何训练和推论。
2.1 +1和-1
一个DNN的应用只要包含卷积和矩阵乘法。于是,关键的运算就是乘加运算。神经元把权值乘以输入,再加在一起。
BinaryConnect在传播的过程中,把权值限制为+1或-1两个值。于是,乘加运算简化为加法。

2.2 确定的和随机的二值化
二值化操作把实值权值变成2个可能值。一个最直接的二值化方法就是取符号
Wb = +1 w>=0; -1 w<0
Wb是实值权值w的二值化。虽然这是一个确定的操作,但是因为隐藏层节点很多,这么多的值上的平均化可以弥补信息的损失。
另一种方法可能更好,平均值更加的正确,就是随机二值化方法
Wb = +1 概率p=Q(w); =-1 概率1-q
其中Q是hard sigmoid函数:
Q(x) = clip((x+1)/2,0,1) = max(0,min(1,(x+1)/2))
我们使用hard sigmoid而不是sigmoid,因为hard sigmoid更容易计算,而且从实验结果看也不错。
2.3 传播和更新
让我们考虑随机梯度下降更新算法中的不同阶段
1. 给定DNN输入,逐层计算单元的活动直到顶层,顶层为DNN的输出层,这一步为前向传播
2. 给定DNN输出,计算训练目标的梯度,也就是每一层的行为,从顶层向下直到第一个隐藏层,这一步叫后向传播
3. 计算梯度,使用新的梯度和旧的值,更新权值,这一步叫权值更新

算法:
BinaryConnect的SGD训练方法:C为cost函数,binary()为二值化方法,clip()为clip权值的函数,L是层数
需求:输入,目标,上一次的权值Wt-1和偏移Bt-1,学习速度l
保证:更新权值Wt和偏移Bt
1. 前向传播
Wb=binary(Wt-1)
对每一层k,前向计算各个节点的输出Ak
2. 后向传播
初始化输出层的激励梯度,使用梯度和权值Wb,反向计算上一层的梯度
3. 参数更新
根据激励梯度和激励,计算权值梯度和偏移梯度,更新权值和偏移



BinaryConnect的关键一点是binary方法只有在前向和后向传播的时候使用,在参数更新的时候不使用,此时仍然使用原来的实值权值。SGD算法要求在更新参数的时候保持精度的权值。通过梯度下降而取得的参数的改变是非常小的,SGD对大量的节点做很小的修改来得到训练目标。一种理解这种算法的方法是假设:在训练结束时,最重要的是权值的符号