其他分享
首页 > 其他分享> > 记录一次给ncnn的pr(nihui真的可爱)

记录一次给ncnn的pr(nihui真的可爱)

作者:互联网

在ncnn群划水有一段时间了(nihui真的可爱),昨天up在群里说了一下,要重新写这个operators的文档,之前那个operation-param-weight-table有点草率。应该说这本该是一次简单的pr,奈何我没有深入阅读过ncnn的源码,正好借这次pr机会好好研究下。
废话不多说,先看看这个需求吧:

ncnn1.png

从图中可以看出,这是对op进行一些说明,分为参数和权重两类数据,ncnn的模型采用参数和权重分离的设计。那么只需要按照之前的operation-param-weight-table上的op列表以operators文档的方式补充完所有op的说明就算大功告成了。先来看看operators文档中现有的几个op,来初步理解一下参数和权重的具体意义。

先来看第一个op,absval这是计算绝对值的。我们在程序中找到这个,ncnn的所有op的实现都是在/ncnn/src/layer/下面的:

ncnn2.png

直接上代码:

absval.h

#ifndef LAYER_ABSVAL_H
#define LAYER_ABSVAL_H

#include "layer.h"

namespace ncnn {

class AbsVal : public Layer
{
public:
    AbsVal();

    virtual int forward_inplace(Mat& bottom_top_blob, const Option& opt) const;
};

} // namespace ncnn

#endif // LAYER_ABSVAL_H

absval.cpp

#include "absval.h"

namespace ncnn {

AbsVal::AbsVal()
{
    one_blob_only = true;
    support_inplace = true;
}

int AbsVal::forward_inplace(Mat& bottom_top_blob, const Option& opt) const
{
    int w = bottom_top_blob.w;
    int h = bottom_top_blob.h;
    int channels = bottom_top_blob.c;
    int size = w * h;

    #pragma omp parallel for num_threads(opt.num_threads)
    for (int q = 0; q < channels; q++)
    {
        float* ptr = bottom_top_blob.channel(q);

        for (int i = 0; i < size; i++)
        {
            if (ptr[i] < 0)
                ptr[i] = -ptr[i];
        }
    }

    return 0;
}

} // namespace ncnn

从上面operators文档中我们可以看到:

AbsVal::AbsVal()
{
    one_blob_only = true;
    support_inplace = true;
}

经查资料可知别人的blog

定义两个参数决定了输入输出的规则,one_blob_only表示该层为单输入单输出,support_inplace表示是否可以进行就地运算。比如说,卷积层是不能就地运算的,该方法表示可以在输入数据的基础上直接修改得到输出数据,但是卷积过程有重复部分,如果修改会对后面的计算产生影响。因此对于前向推理函数就会有两种方式,加上刚才的是否是单输入单输出,一共有四个推理函数。

    // implement inference
    // return 0 if success
    virtual int forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs, const Option& opt) const;
    virtual int forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const;

    // implement inplace inference
    // return 0 if success
    virtual int forward_inplace(std::vector<Mat>& bottom_top_blobs, const Option& opt) const;
    virtual int forward_inplace(Mat& bottom_top_blob, const Option& opt) const;

这个是Layer这个类里面的4个重载。

总之absval这个op的代码实现部分比较简单,没参数,没权重,只需要对张量的所有元素算一个绝对值就行了,即:

y = abs(x)

这样就完成了absval这个op的所有说明:

absval

y = abs(x)

这里先写到这,我觉得应该每个op分一期吧,关于pr已经不那么重要了,借这次机会好好看看ncnn的代码。



标签:pr,const,bottom,int,inplace,nihui,ncnn,blob
来源: https://www.cnblogs.com/Maii/p/13972200.html