deep-learning - 如何在caffe中卷积两个blob

标签 deep-learning caffe convolution

在咖啡中,convolution层采用一个底部blob,并将其与学习过滤器(使用权重类型初始化 - “Xavier”、“MSRA”等)进行卷积。但是,我的问题是我们是否可以简单地卷积两个底部 Blob 并产生顶部 Blob 。这样做最优雅的方式是什么?这样做的目的是:底部 blob 之一将是 data另一个将是由先前层产生的动态过滤器(根据 data 变化)(我正在尝试实现 dynamic convolution )。

我的尝试:

我想到的一种方法是修改 filler.hpp并将底部 blob 分配为 filler矩阵本身(而不是“Xavier”、“MSRA”等)。然后我认为卷积层会从那里开始。我们可以设置lr = 0表示不应更改由我们的自定义填充器初始化的权重。但是,看了源码之后,还是不知道怎么弄。另一方面,我不想破坏 caffe 的工作流程。如果我想要的话,我仍然希望卷积层能够正常运行。

显然更繁琐的方法是使用 Slice 的组合。 , tile和/或 Scale层从字面上实现卷积。我认为它会起作用,但结果会很困惑。还有其他想法吗?

编辑 1:

我通过修改caffe的卷积层写了一个新层。特别是在 src/caffe/layers/conv_layer.cpp ,在第 27 行,它采用 filler 定义的权重并将其与底部 blob 进行卷积。因此,不要从 filler 填充该 blob ,我修改了图层,使其现在需要两个底部。底部之一直接分配给填充物。现在我不得不做一些其他的改变,比如:

  • weight blob 对于所有样本具有相同的值。在这里,对于不同的样本,它将具有不同的值。所以我将第 32 行从:

  • this->forward_cpu_gemm(
        bottom_data + n * this->bottom_dim_, 
        weight, 
        top_data + n * this->top_dim_);
    

    到:

    this->forward_cpu_gemm(
        bottom_data + n * bottom[1]->count(1),
        bottom[0]->cpu_data() + n * bottom[0]->count(1), 
        top_data + n * this->top_dim_);
    

    为了方便起见,我假设不涉及偏差项,步幅始终为 1,填充始终为 0,组始终为 1 等等。但是,当我测试前向传递时,它给了我一些奇怪的答案(与一个简单的卷积核 = np.ones((1,1,3,3))。这个内核的学习率设置为零,因此它不会改变。但是,我无法得到正确的答案。任何建议将不胜感激。

    请不要提出使用现有层的解决方案,例如 Slice, Eltwise, Crop .我已经实现了——它有效——但它非常复杂且内存效率低下。

    最佳答案

    我认为您总体上走在正确的道路上。

    对于“奇怪”的卷积结果,我猜这个错误最有可能是:

    考虑二维卷积

    并假设 bottom[1]的形状是 (num, channels, height, width) ,

    由于 caffe 中的卷积执行为 2 矩阵的乘法,weight (代表卷积核)和col_buffer (从要卷积的数据重组)和weight属于 num_out行和 channels / this->group_ * kernel_h * kernel_w列,col_buffer属于 channels / this->group_ * kernel_h * kernel_w行和 height_out * width_out列,如 weight动态卷积层的blob,bottom[0]的形状最好是 (num, num_out, channels/group, kernel_h, kernel_w)为了满足

    bottom[0]->count(1) == num_out * channels / this->group_ * kernel_h * kernel_w
    

    , 其中 num_out是动态卷积层输出特征图的数量。

    这意味着,使卷积函数
    this->forward_cpu_gemm(bottom_data + n * bottom[1]->count(1) 
                         , bottom[0]->cpu_data() + n * bottom[0]->count(1)
                         , top_data + n * this->top_dim_);
    

    正常工作,您必须确保
    bottom[0]->shape(0) == bottom[1]->shape(0) == num
    bottom[0]->count(1) == num_out * channels / this->group_ * kernel_h * kernel_w
    

    所以最有可能是简单的 4 维卷积核 np.ones((1,1,3,3))您使用的可能不满足上述条件并导致错误的卷积结果 .

    希望它很清楚,并会帮助你。

    ##########更新1,北京时间2016年10月10日##########

    我添加了一个动态卷积层here但还没有单元测试。该层不会破坏 caffe 的工作流程,只是将 BaseConvolution 类的一些私有(private)成员更改为 protected 。

    涉及的文件有:
    include/caffe/layers/dyn_conv_layer.hpp,base_conv_layer.hpp
    src/caffe/layers/dyn_conv_layer.cpp(cu)
    

    它与 caffe 中的卷积层增长几乎相同,区别主要有:
  • 覆盖函数 LayerSetUp()初始化 this->kernel_dim_ , this->weight_offset_等适用于卷积并忽略初始化this->blobs_卷积层通常用于包含权重和偏差;
  • 覆盖函数 Reshape()检查 bottom[1]作为内核容器具有适当的卷积形状。

  • 因为我没有时间测试它,可能会有错误,我会很高兴看到你的反馈。

    ##########更新2,北京时间2016年10月12日##########

    我更新了 dynamic convolution 的测试用例现在。涉案文件为src/caffe/test/test_dyn_convolution_layer.cpp .它似乎工作正常,但可能需要更彻底的测试。

    你可以通过 cd $CAFFE_ROOT/build && ccmake .. 建立这个 caffe , cmake -DBUILD_only_tests="dyn_convolution_layer" ..make runtest检查它。

    关于deep-learning - 如何在caffe中卷积两个blob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38680318/

    相关文章:

    python - 如何 reshape 3 channel 数据集以输入神经网络

    deep-learning - 为什么MXNet中代价函数和最后激活函数是绑定(bind)的?

    computer-vision - 使用卷积神经网络 (CNN) 时如何忽略纯色图像背景?

    machine-learning - 他们如何计算 Caffe 中这个卷积网络示例的输出量?

    matlab - 从数据创建传递函数并将其应用于音频信号

    python - TensorFlow/Sklearn 深度神经网络分类器类型错误

    machine-learning - 不同分辨率的迁移学习深度CNN

    android - 无法在android中构建caffe

    caffe - 应用 MAX 池化时 Caffe 和 Keras 之间的差异

    keras - 如何将掩码值输入到 Convolution1D 层