CNN碎片记录

只有conv和fc层有权重和偏置。relu,pooling是固定函数,没有参数

每一个卷积层都是接受一个3D输入,给出一个3D输出。比如input 227*227*3 -> conv1 (kernal size:11*11, stride:4, kernals:96) -> 55*55*96 -> relu1 -> pool1 (kernal size: 3*3, stride:2) -> 27*27*96 

针对每个input的local receptive field做卷积,实际是11*11*3的input区域和11*11*3的权重做点积的结果,一共96个kernal那么,这个11*11*3的区域产生的输出就是1*1*96,整张图片走过一边的输出就是55*55*96, 每一个kernal的参数是11*11*3+1(bias)input 如果是27*27*96 -> conv2 (kernal size: 5*5, pad:2, kernals:256) -> 27*27*256 则每个kernal的参数是27*27*96+1

每个kernal用来提取一个特征,一个kernal内所有神经元的权值是共享的,因为需要提取的特征是一样的。conv1为例:一个神经元的权值是11*11*3+1, 则conv1的所有参数数量为: (11*11*3+1)*96 = 34944

卷积越往后,特征越多,空间越小,我个人的理解是把空间映射为特征组合,从基本特征向复杂的组合特征映射。

 

3D输出的大小由一下几个超参数来决定:

kernal size: 11*11 (每个kernal的大小)-> K

stride: 4 kernal滑动的步长 -> S

pad: 0 input图片四个边补多少个0像素 -> P

kernals: 96 一共有多少个kernal来抽取输入的特征, 决定3D output输出的深度 -> D1

设input 图片的3D表达W0*W0*D0,则output图片:

  • 宽度 W1=(W0+2P-K)/S+1,则output 3D表达:W1*W1*D1
  • 每个kernal的权重数量为 K*K*D0 + 1
  • conv层的权重数量 (K*K*D0+1)*D1

 

卷积的矩阵计算:

比如input 227*227*3 -> conv1 (kernal size:11*11, stride:4, kernals:96) -> 55*55*96

对于每一个kernal 11*11*3,在input上面做过滤,在第一行做过滤,每一个output的输出点,对应input是11*11*3=363的向量,那么第一行滑动过滤之后,input产生了363*55的矩阵,整个input滑动之后产生了363*(55*55)=363*3025的矩阵。

每个kernal的权重是一个11*11*3=363的向量,96个kernal则构成了一个96*363的矩阵。

np.dot([96*363], [363*3025))-> output是一个96*3025的矩阵,然后把矩阵还原成55*55*96

 

设计原则:

  • input size是2的倍数
  • 用多个小尺寸的卷积来替代一个大尺寸的卷积,这样可以更好的表达特征,同时有更少的参数。 
    • 因为一个大尺寸的卷积被多个小尺寸卷积来替代,则整体运算中由于引入了多次的relu,是一个单个大尺寸卷积的线性矩阵运算转换为多次的非线性运算。
    • 假定input和一个7x7的卷积,每一层的深度都是一样的C, 把7x7用三个3X3的卷积来替代。则7x7的卷积参数是 7*7*C*C=49C*C;而三个3*3的卷积参数为 3*(3*3*C*C)=27*C*C, 参数更少
  • conv的超参数推荐:kernal size 3*3, stride=1, 通过pad调整让输出和输入保持相同的size P=(K-1)/2
  • 通过pool来降低图片空间

 

posted @ 2017-07-07 15:57  怎么也得过啊  阅读(178)  评论(0编辑  收藏  举报