自制深度学习推理框架-实现我们的第一个算子Relu-第三课

2023-01-02 16:28:24 来源: 分享到:
我们的课程主页

https://github.com/zjhellofss/KuiperInfer 欢迎pr和点赞

手把手教大家去写一个深度学习推理框架 B站视频课程

Relu算子的介绍

Relu是一种非线性激活函数,它的特点有运算简单,不会在梯度处出现梯度消失的情况,而且它在一定程度上能够防止深度学习模型在训练中发生的过拟合现象。Relu的公式表达如下所示,「如果对于深度学习基本概念不了解的同学,可以将Relu当作一个公式进行对待,可以不用深究其背后的含义。」


(资料图)

我们今天的任务就是来完成这个公式中的操作,「值得注意的是,在我们的项目中,x和y可以理解为我们在第二、第三节中实现的张量类(tensor).」

Operator类

Operator类就是我们在第一节中说过的计算图中「节点」的概念,计算图的另外一个概念是数据流图,如果同学们忘记了这个概念,可以重新重新翻看第一节课程。

在我们的代码中我们先定义一个「Operator」类,它是一个父类,其余的Operator,包括我们本节要实现的ReluOperator都是其派生类,「Operator中会存放节点相关的参数。」例如在「ConvOperator」中就会存放初始化卷积算子所需要的stride, padding, kernel_size等信息,本节的「ReluOperator」就会带有「thresh」值信息。

我们从下方的代码中来了解Operator类和ReluOperator类,它们是父子关系,Operator是基类,OpType记录Operator的类型。

enumclassOpType{kOperatorUnknown=-1,kOperatorRelu=0,};classOperator{public:OpTypekOpType=OpType::kOperatorUnknown;virtual~Operator()=default;explicitOperator(OpTypeop_type);};

ReluOperator实现:

classReluOperator:publicOperator{public:~ReluOperator()override=default;explicitReluOperator(floatthresh);voidset_thresh(floatthresh);floatget_thresh()const;private:floatthresh_=0.f;};

Layer类

我们会在operator类中存放从「计算图结构文件」得到的信息,例如在ReluOperator中存放的thresh值作为一个参数就是我们从计算图结构文件中得到的,计算图相关的概念我们已经在第一节中讲过。

下一步我们需要根据ReLuOperator类去完成ReluLayer的初始化,「他们的区别在于ReluOperator负责存放从计算图中得到的节点信息,不负责计算」,而ReluLayer则「负责具体的计算操作」,同样,所有的Layer类有一个公共父类Layer. 我们可以从下方的代码中来了解两者的关系。

classLayer{public:explicitLayer(conststd::string&layer_name);virtualvoidForwards(conststd::vector>>&inputs,std::vector>>&outputs);virtual~Layer()=default;private:std::stringlayer_name_;};

其中Layer的Forwards方法是具体的执行函数,负责将输入的inputs中的数据,进行relu运算并存放到对应的outputs中。

classReluLayer:publicLayer{public:~ReluLayer()override=default;explicitReluLayer(conststd::shared_ptr&op);voidForwards(conststd::vector>>&inputs,std::vector>>&outputs)override;private:std::shared_ptrop_;};

这是集成于Layer的ReluLayer类,我们可以看到其中有一个op成员,是一个ReluOperator指针,「这个指针中负责存放ReluLayer计算时所需要用到的一些参数」。此处op_存放的参数比较简单,只有ReluOperator中的thresh参数。

我们再看看是怎么使用ReluOperator去初始化ReluLayer的,先通过统一接口传入Operator类,再转换为对应的ReluOperator指针,最后再通过指针中存放的信息去初始化「op_」.

ReluLayer::ReluLayer(conststd::shared_ptr&op):Layer("Relu"){CHECK(op->kOpType==OpType::kOperatorRelu);ReluOperator*relu_op=dynamic_cast(op.get());CHECK(relu_op!=nullptr);this->op_=std::make_shared(relu_op->get_thresh());}

我们来看一下具体ReluLayer的Forwards过程,它在执行具体的计算,完成Relu函数描述的功能。

voidReluLayer::Forwards(conststd::vector>>&inputs,std::vector>>&outputs){CHECK(this->op_!=nullptr);CHECK(this->op_->kOpType==OpType::kOperatorRelu);constuint32_tbatch_size=inputs.size();for(inti=0;iempty());conststd::shared_ptr>&input_data=inputs.at(i);input_data->data().transform([&](floatvalue){floatthresh=op_->get_thresh();if(value>=thresh){returnvalue;}else{return0.f;}});outputs.push_back(input_data);}}

在for循环中,首先读取输入input_data, 再对input_data使用armadillo自带的transform按照我们给定的thresh过滤其中的元素,如果「value」的值大于thresh则不变,如果小于thresh就返回0.

最后,我们写一个测试函数来验证我们以上的两个类,节点op类,计算层layer类的正确性。先判断Forwards返回的outputs是否已经保存了relu层的输出,输出大小应该assert为1. 随后再进行比对,我们应该知道在thresh等于0的情况下,第一个输出index(0)和第二个输出index(1)应该是0,第三个输出应该是3.f.

TEST(test_layer,forward_relu){usingnamespacekuiper_infer;floatthresh=0.f;std::shared_ptrrelu_op=std::make_shared(thresh);std::shared_ptr>input=std::make_shared>(1,1,3);input->index(0)=-1.f;input->index(1)=-2.f;input->index(2)=3.f;std::vector>>inputs;std::vector>>outputs;inputs.push_back(input);ReluLayerlayer(relu_op);layer.Forwards(inputs,outputs);ASSERT_EQ(outputs.size(),1);for(inti=0;iindex(0),0.f);ASSERT_EQ(outputs.at(i)->index(1),0.f);ASSERT_EQ(outputs.at(i)->index(2),3.f);}}

本期代码仓库位置

gitclonehttps://gitee.com/fssssss/KuiperCourse.gitgitcheckoutfouth

自制深度学习推理框架-实现我们的第一个算子Relu-第三课

来源: 2023-01-02 16:28:24

银行申请停息挂账的条件

来源: 2023-01-02 00:27:56

外媒:委反对派投票取消瓜伊多“临时政府”:环球关注

来源: 2023-01-01 08:39:33

迈克尔·杰克逊的仨儿女,久违团聚,20岁“毯毯”毛发浓密显沧桑 短讯

来源: 2022-12-31 16:38:14

【速看料】国美零售(00493)继续获控股股东提供1.3亿港元免息无抵押贷款以支持公司流动性

来源: 2022-12-30 22:55:34

深圳理想L9分期省钱攻略

来源: 2022-12-30 19:03:06

(小额应急)借款逾期9年会上征信吗

来源: 2022-12-30 16:18:08

沧州银行盈利能力持续增长 严守资产质量“生命线” 环球新资讯

来源: 2022-12-30 10:35:49

鄂尔多斯:融资净买入105.6万元,融资余额3.52亿元(12-29)|环球实时

来源: 2022-12-30 07:12:05

专家组成员下沉到分片科室 全科室投入 全身心救治|环球今亮点

来源: 2022-12-29 20:33:16

ppmoney贷款逾期1天延迟还款会影响征信吗

来源: 2022-12-29 18:24:48

凤凰网2021年秋季CEO迎新会“新起点、新格局、新机遇”

来源: 2022-12-29 16:30:44

天天速讯:中远海能:公司的外贸油轮目前以即期运输为主 其中VLCC的期租租出比例在15%以内

来源: 2022-12-29 14:15:12

大亚圣象:12月28日融券卖出金额1.21万元,占当日流出金额的0.09%_环球视点

来源: 2022-12-29 12:21:17

焦点报道:超越ConvNeXt!Transformer 风格的卷积网络视觉基线模型Conv2Former

来源: 2022-12-29 10:18:36

[快讯]美克家居发布质押公告

来源: 2022-12-28 18:07:23

支持开票 | Python实证指标构建与文本分析_全球焦点

来源: 2022-12-28 15:22:08

环球热门:哈尔滨市第五医院看病需要预约吗?附就诊须知

来源: 2022-12-28 11:14:14

中邮证券:给予煌上煌买入评级,目标价位16.38元_天天滚动

来源: 2022-12-28 08:09:38

环球热议:最高法发文明确居家办公或者灵活办公工资标准问题

来源: 2022-12-27 20:12:21

粽子做完煮多久才能吃 粽子做完煮多长时间才能吃

来源: 2022-12-27 16:27:05

ST星星:受疫情影响,项目试生产开始时间略有推迟,预计在元旦过后才能试生产:全球新要闻

来源: 2022-12-27 11:26:13

大连公众举报安全生产违法行为有奖

来源: 2022-12-27 06:44:19

女排联赛八强战打响-环球聚看点

来源: 2022-12-26 17:41:52

通讯!小金鱼A借款逾期5000还不起会上征信系统吗

来源: 2022-12-26 12:57:10

环球观察:记一次QQ找回经历

来源: 2022-12-26 07:16:00

深圳:1-11月规上工业增加值同比增长5.6%

来源: 2022-12-25 14:57:45

“虚猕数藏”赋能文化消费,带来全新体验 世界今日报

来源: 2022-12-24 16:07:06

中国金融国际(00721)今日股价下跌64.52% 执行董事杜林东连同Rightfirst被强制出售1100万股股份_观焦点

来源: 2022-12-23 22:48:07

绿豆粥高压锅需要煮多久 绿豆粥高压锅需要煮多长时间 今日聚焦

来源: 2022-12-23 15:48:01

Copyright   2015-2022 北冰洋知识产权网 版权所有  备案号:沪ICP备2020036824号-3   联系邮箱:562 66 29@qq.com