如何降低全连接(`“内积”`)层使用截短SVD如何降低全连接(`“内积”`)层使用截短SVD(How

2019-05-12 03:09发布

在纸Girshick,R 快速RCNN(ICCV 2015) ,章节“3.1截断SVD为更快的检测”中,作者提出了使用SVD特技减少完全连接层的尺寸和计算时间。

给定一个训练模型( deploy.prototxtweights.caffemodel ),我该如何使用这一招用截短一个更换一个完全连接层?

Answer 1:

一些线性代数的背景
奇异值分解( SVD )是任何基质的分解W分成三个矩阵:

W = U S V*

其中UV均为邻位正常矩阵, S是对角线与在降低对角大小的元件。 一个SVD有趣的特性是,它可以轻松地近似W以较低的秩矩阵:假设您截断S只具有其k领先的元素(而不是在对角线上的所有元素),那么

W_app = W S_trunc V*

是秩k的近似W

使用SVD来近似完全连接层
假设我们有一个模型deploy_full.prototxt具有完全连接层

# ... some layers here
layer {
  name: "fc_orig"
  type: "InnerProduct"
  bottom: "in"
  top: "out"
  inner_product_param {
    num_output: 1000
    # more params...
  }
  # some more...
}
# more layers...

此外,我们有trained_weights_full.caffemodel -对训练有素的参数deploy_full.prototxt模型。

  1. 复制deploy_full.protoxtdeploy_svd.protoxt和您选择的编辑器打开它。 用这些两层的完全连接层:

     layer { name: "fc_svd_U" type: "InnerProduct" bottom: "in" # same input top: "svd_interim" inner_product_param { num_output: 20 # approximate with k = 20 rank matrix bias_term: false # more params... } # some more... } # NO activation layer here! layer { name: "fc_svd_V" type: "InnerProduct" bottom: "svd_interim" top: "out" # same output inner_product_param { num_output: 1000 # original number of outputs # more params... } # some more... } 
  2. 在Python中,小净的手术 :

     import caffe import numpy as np orig_net = caffe.Net('deploy_full.prototxt', 'trained_weights_full.caffemodel', caffe.TEST) svd_net = caffe.Net('deploy_svd.prototxt', 'trained_weights_full.caffemodel', caffe.TEST) # get the original weight matrix W = np.array( orig_net.params['fc_orig'][0].data ) # SVD decomposition k = 20 # same as num_ouput of fc_svd_U U, s, V = np.linalg.svd(W) S = np.zeros((U.shape[0], k), dtype='f4') S[:k,:k] = s[:k] # taking only leading k singular values # assign weight to svd net svd_net.params['fc_svd_U'][0].data[...] = np.dot(U,S) svd_net.params['fc_svd_V'][0].data[...] = V[:k,:] svd_net.params['fc_svd_V'][1].data[...] = orig_net.params['fc_orig'][1].data # same bias # save the new weights svd_net.save('trained_weights_svd.caffemodel') 

现在,我们已经deploy_svd.prototxttrained_weights_svd.caffemodel与远不如乘法,和权重接近原净。



Answer 2:

事实上,罗斯Girshick的PY-快rcnn回购包括SVD的步骤实现: compress_net.py

顺便说一句,你通常需要微调压缩模式恢复精度(或更复杂的方式来压缩,例如参见“ 加快了分类和检测非常深卷积网络 ”,张某等人)。

另外,我scipy.linalg.svd工作比numpy的的SVD更快。



文章来源: How to reduce a fully-connected (`“InnerProduct”`) layer using truncated SVD