赞
踩
前面大致总结了一下ncnn模型载入的流程,模型载入之后,就是新建一个Extractor,然后设置输入,获取输出:
- ncnn::Extractor ex = net.create_extractor();
- ex.set_num_threads(4);
-
- ex.input("data", in);
-
- ncnn::Mat out;
- ex.extract("detection_out", out);
现在可以看一下Extractor的定义了:
- class Extractor
- {
- public:
- // enable light mode
- // intermediate blob will be recycled when enabled
- // enabled by default
- // 设置light模式
- void set_light_mode(bool enable);
-
- // set thread count for this extractor
- // this will overwrite the global setting
- // default count is system depended
- // 设置线程数
- void set_num_threads(int num_threads);
-
- // set blob memory allocator
- // 设置blob的内存分配器
- void set_blob_allocator(Allocator* allocator);
-
- // set workspace memory allocator
- // 设置工作空间的内存分配器
- void set_workspace_allocator(Allocator* allocator);
-
-
- #if NCNN_STRING
- // set input by blob name
- // return 0 if success
- // 设置网络输入:字符串layer名
- int input(const char* blob_name, const Mat& in);
-
- // get result by blob name
- // return 0 if success
- // 设置提取器的输入:得到对应输出
- int extract(const char* blob_name, Mat& feat);
- #endif // NCNN_STRING
-
- // set input by blob index
- // return 0 if success
- // 设置int类型blob索引及输入
- int input(int blob_index, const Mat& in);
-
- // get result by blob index
- // return 0 if success
- // 设置int类型blob索引及输出
- int extract(int blob_index, Mat& feat);
-
- protected:
- // 对外提供create_extractor接口
- friend Extractor Net::create_extractor() const;
- Extractor(const Net* net, int blob_count);
-
- private:
- // 网络
- const Net* net;
- // blob的mat
- std::vector<Mat> blob_mats;
- // 选项
- Option opt;
-
- };
将vulkan部分代码剔除掉,不难发现,Extractor里面就这么多内容,除了设置option的接口之外,就只剩下我们需要使用的几个接口函数了:
- // 创建Extractor
- Extractor Net::create_extractor() const
- {
- return Extractor(this, blobs.size());
- }
内部调用了接口为,就是将blob_mat数组resize到网络的blob数目大小,然后设置了一下选项:
- // 执行器
- Extractor::Extractor(const Net* _net, int blob_count) : net(_net)
- {
- blob_mats.resize(blob_count);
- opt = net->opt;
- }
然后就是input接口:
- // 设置输入
- int Extractor::input(const char* blob_name, const Mat& in)
- {
- // 获取输入模块对应index
- int blob_index = net->find_blob_index_by_name(blob_name);
- if (blob_index == -1)
- return -1;
-
- // 调用直接用index的设置input方法
- return input(blob_index, in);
- }
内部调用的接口为:
- // 输入为index的输入接口
- int Extractor::input(int blob_index, const Mat& in)
- {
- if (blob_index < 0 || blob_index >= (int)blob_mats.size())
- return -1;
-
- // 设置blob_index对应Mat
- blob_mats[blob_index] = in;
-
- return 0;
- }
这里就是设置输入对应blob值。
最后一个接口就是extract接口:
- // 将输入string类型name转换成对应的索引
- int Extractor::extract(const char* blob_name, VkMat& feat, VkCompute& cmd)
- {
- int blob_index = net->find_blob_index_by_name(blob_name);
- if (blob_index == -1)
- return -1;
-
- return extract(blob_index, feat, cmd);
- }
这里调用的接口为:
- // 提取特征
- int Extractor::extract(int blob_index, Mat& feat)
- {
- if (blob_index < 0 || blob_index >= (int)blob_mats.size())
- return -1;
-
- int ret = 0;
-
- // 如果输出blob为空
- if (blob_mats[blob_index].dims == 0)
- {
- // 查找输出blob对应的生产者
- int layer_index = net->blobs[blob_index].producer;
-
- // 前向推理
- ret = net->forward_layer(layer_index, blob_mats, opt);
- }
-
- // 输出特征
- feat = blob_mats[blob_index];
-
- if (opt.use_packing_layout)
- {
- // 对特征进行unpack
- Mat bottom_blob_unpacked;
- convert_packing(feat, bottom_blob_unpacked, 1, opt);
- feat = bottom_blob_unpacked;
- }
-
- return ret;
- }
这里就是调用各层前向推理forward_layer方法来进行推理的,这个对应于特定层的推理过程,后面总结各个层的时候再说。
参考资料:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。