1.roi_pooling层是先利用spatial_scale将region proposal映射到feature map上,然后利用pooled_w、pooled_h分别将映射后的框的长度、宽度等分形成bin,最后对每个bin进行max_pooling,这其实就是一个spp-net的过程(只不过sppnet使用多个等分尺寸,这里只使用一个等分尺寸),因为他就是为了将不同大小的框都处理成相同的长方体(这也是roi_pooling的本质,对任何大小的框都是相同的输出,这样不用向rcnn那样resize图片或者resize region proposal),其实每一个点就是一个值,就有点像用固定长度进行编码。
2.roi_pooling层后面接的是一个全连接层,roi_pooling池化后生成的应该是一个固定大小的长方体(或者说正方体),即(a,b,c,d),因为pooling是在每个channel进行,pooling前和pooling后的channel应该不变;每个channel的大小变为pooled_w*pooled_h,因为roi_pooling将每个channel的宽度均分成pooled_w份,高度均分成pooled_h份,在每份里max_pooling,所以大小就变成pooled_w*pooled_h。
比如prototxt里roi_pooling的设置是这样:
roi_pooling_param {
pooled_w: 6
pooled_h: 6
spatial_scale: 0.0625 # 1/16
}
那输出的shape就是(batch,channel,6,6)
下面是roi_pooling的源码,可以看到roi_pooling的输出的shape是:
第一维:rois的个数
第二维:conv5的channel个数
第三维:pooled_height_,在高度上等分然后提取的个数
第四维:pooled_width_,在宽度上等分然后提取的个数
这个问题依旧没有解决,到底batch是怎么回事
这样一个长方体是不能和全连接层直接使用的,开始以为roi_pooling层将这个转换成了batch个vector,vector的大小是channel * w * h,但后来发现这个操作其实是在InnerProduct实现的。
这是InnerProduct的cpp源码,可以看到,会先从inner_product_param的axis读取一个值,这个值其实就是要进行flatten的维度的起点
去caffe.proto里面找InnerProduct这一层的参数,可以发现axis默认是1,也就是从channel那一维开始flatten。
也就是说roi_pooling后面接的那一层InnerProduct先把roi_pooling的输出转换成(roi的个数,channel*width*height),然后每个roi进行InnerProduct计算。
CanonicalAxisIndex这个函数在blob.hpp里面定义了。要寻找这个函数的定义,你可以看到是bottom在调用这个函数,那一定是在blob里面定义,只是看到底是在cpp还是hpp了
这个函数是提供负数也可以进行索引