“大隐隐于市,深藏功与名”。
深度学习的强大能力想必大家都有所耳闻。而自编码网络就是深度学习近几年的研究分支,相关介绍可以见前面的文章比如《自编码降噪效果到底怎么样?我用对比实验告诉你 》《地震去噪新探索——无监督卷积神经网络实战 》等。
接下来,介绍一下自编码网络中的一个有用的技术——权重绑定。
01 什么是权重绑定?为什么这个技术有用?
权重绑定(tied weights)可以理解为参数共享,这是在自编码器独有的的概念。
由于DAE的编码层和解码层在结构上是互相镜像的,所以可以让编码器的某一层与解码器中相对应的一层tied weights,也就是参数共享,这样在网络学习的过程中只需要学习一组权重,解码权值是编码权值的转置。通常情况快下,比学习两个阶段的单独的权重更可靠。
主要好处有两点:一是减少了参数的数量,加速训练过程。二是tied weights可以被看作是一种正则化形式,在实践中能获得更好的性能。
02 权重绑定的关键实现方法
在Keras中实现DAE时,使用内置的Dense或CNN层类构建任意的DAE非常简单。然而,要使参数共享(捆绑权重)并非易事。实现权重绑定并不容易,你需要一种方法在这些不同的层之间共享这些信息。
这里最有效的方法就是自己重写Dense或Convolution类。而最关键的部分就是将前向传播过程中的权重转置后放到后面去。
比如在一个简单的神经网络结构中,代码可以是这样来写:
input_img = Input(shape=(1, 28, 28))
conv1 = Convolution2D(16, 3, 3, activation='relu', border_mode='same') # 这个地方为了绑定权重而进行了拆分
c1 = conv1(input_img) # then call the layer
m1 = MaxPooling2D((2, 2), border_mode='same')(c1)
c2 = Convolution2D(16, 3, 3, activation='relu', border_mode='same')(m1)
u1 = UpSampling2D((2, 2))(c2)
d1 = Convolution2D_tied(1, 3, 3, activation='sigmoid', border_mode='same', tied_to=conv1)(u1) #最后这个全连接卷积的权重就绑定了conv1
上面是一个简单的卷积神经网络结构,解码层就绑定了编码层的权重。
那Convolution2D_tied这个卷积需要大家对原来的卷积类进行重写。里面有关权重绑定的关键程序是这样的:
class Convolution2D_tied(Layer):
def call(self, x, mask=None):
W = tf.transpose(self.tied_to.W, (1, 0, 3, 2))
output = K.conv2d(x, W, strides=self.subsample,
border_mode=self.border_mode,
dim_ordering=self.dim_ordering,
filter_shape=self.W_shape)
上面的W = tf.transpose(self.tied_to.W, (1, 0, 3, 2))就是对编码层的权重转置来实现了权重的绑定。
03 小结
自编码网络以其自监督的特性,常常可以跳过复杂的监督学习而直接提取目标的特征。但是因为这个一边学习特征,一边提取特征的工作模式,比监督学习预测的速度慢。所以怎样提高自编码网络的速度成为了研究的一个热点。
还好自编码网络镜像的特点,使得权重绑定成为了一个可行的突破点。到底这个技术能提高多少的速度和质量呢?这还有待于未来的研究。
粉丝福利来了!这次,我整理了自编码深度学习的研究论文,包括了国内外许多专家学者研究的心得、论文,深入浅出,大家一起来学习交流。
如果喜欢请点赞,获取学习资料请关注我私信交流。
网友评论