首页 > 编程知识 正文

tensorflow官方文档,tensorflow自定义层

时间:2023-05-04 23:18:51 阅读:107491 作者:579

最近在tensorrt api中实现了refinedet。 试着记录一下中间过程吧。 主要参考以下仓库: https://github.com/Wang-Xinyu/tensor RTX

tensorrt api说明: https://docs.NVIDIA.com/deep learning/tensor rt/API/c _ API/index.html

vgg主体部分实现了与pytorch的精度一致,然后有定制L2norm层,我傻了。 也没有翻遍整个这个仓库。 tensorrt不习惯。 很难啊。

pytorch的L2norm层代码:

importtorchimporttorch.nnasnnfromtorch.autogradimportfunction # from torch.autogradimportvariableimporttorch.nn.initasinitclassl2norm (nn.module ) :def__init_(self, self(_init_ () self.n _ channels=n _ channels self.gamma=scaleornoneself.EPS=1e-10 self.weight self.relt 512、40、40 ) bb=x.pow(2).sum ) DIM=1,keepdim=True ) # [ 1,1,40,40 ] bb1=x.pow (2).sum ) dim ) keepdim=true(.sqrt ) ) self.EPS # [ 1,1,40,40 ] # x/=normx=torch.div (x,norm ) ) 1,512,40,40,40

self.con v4 _3_ L2 norm=L2 norm (512,10 ) self.conV5_3_L2norm=L2norm ) 512,8 )我们仔细研究了此代码。 这是self.weight=

这表明weight是一个可学习的参数。 最初不知道,因为初始化时初始化了常时点亮10、8。 加载权重后,权重发生了变化,9点多了,7点多了。 我注意到这些参数是可以学习的。

但是,tensorrt是怎么做的呢? 在小组里问了一下,一个叫“时”的小组里的大人物说加减乘除的运算可以在addScale,addElementWise上进行,官方也告诉我api已经实现了。 https://docs.NVIDIA.com/deeeplearnnom

我去看了。 我完全不知道使用方法。 没有例子。 在雾中。 再问一句,群里的大人物正在自己读文档。 是的。 一切都得靠自己。

然后看到项目中不支持的层自己写了plugin实现了,然后又去看了看plugin。 而且,tensorrt官方git有plugin的实现norm,https://github.com/NVIDIA/tensor RRT/tree/master/pluging。

在该文件夹下,实现了很多plugin,如nmsPlugin、priorBoxPlugin、batchedNMSPlugin等,感觉像是用于目标检测后的处理。 然后看了半天,不知道使用方法啊。

这似乎需要用源代码编译tensorrt库,并用cmakelist进行编译。 我试了一下,但没有报告错误。

我很难。

而且,从cuda编程的实现方法来看,都是在操作一维数组吗? 在某个维度上合计需要很多代码呢。 然后又有一天去看了cuda编程,读完了第五章,说到share共享内存那里。

第三天,我从早上开始就凝视着L2Norm的实现方式。

aa=x.pow(2) # [ 1,512,40,40 ] bb

= x.pow(2).sum(dim=1, keepdim=True) ## [1,1,40,40]# bb1 = x.pow(2).sum(dim=1)#[1,40,40]norm = x.pow(2).sum(dim=1, keepdim=True).sqrt()+self.eps # [1,1,40,40]

其实一开始为了方便了解过程我就把任务拆解了,所以思路就是先实现求平方。其实我知道
virtual IScaleLayer* addScale(ITensor& input, ScaleMode mode, Weights shift, Weights scale, Weights power) TRTNOEXCEPT = 0;这个函数完成的数学操作就是:
f(x)= (shift + scale * x) ^ power
求平方就是pow赋值2,scale=1,shift=0.就可以完成。恩!然后试了下。确实可以,和pytorch代码一致,然后再下一步:
x.pow(2).sum(dim=1, keepdim=True)
这个就不知道咋搞了,我去群里问,指定哪个维度求和怎么弄,有个群名叫sky的说addReduce,真感谢这位兄弟,确实是的。
virtual IReduceLayer* addReduce(ITensor& input, ReduceOperation operation, uint32_t reduceAxes, bool keepDimensions) TRTNOEXCEPT = 0;
然后我就去工程中搜索addReduce,确实有个工程用到了这个api


仔细一看代码也是和我需要实现的功能差不多: IScaleLayer* addInstanceNorm2d(INetworkDefinition *network, std::map<std::string, Weights>& weightMap, ITensor& input, const std::string lname, const float eps) { int len = weightMap[lname + ".weight"].count; IReduceLayer* reduce1 = network->addReduce(input, ReduceOperation::kAVG, 6, true); assert(reduce1); IElementWiseLayer* ew1 = network->addElementWise(input, *reduce1->getOutput(0), ElementWiseOperation::kSUB); assert(ew1); const static float pval1[3]{0.0, 1.0, 2.0}; Weights wshift1{DataType::kFLOAT, pval1, 1}; Weights wscale1{DataType::kFLOAT, pval1+1, 1}; Weights wpower1{DataType::kFLOAT, pval1+2, 1}; IScaleLayer* scale1 = network->addScale( *ew1->getOutput(0), ScaleMode::kUNIFORM, wshift1, wscale1, wpower1); assert(scale1); IReduceLayer* reduce2 = network->addReduce( *scale1->getOutput(0), ReduceOperation::kAVG, 6, true); assert(reduce2); const static float pval2[3]{eps, 1.0, 0.5}; Weights wshift2{DataType::kFLOAT, pval2, 1}; Weights wscale2{DataType::kFLOAT, pval2+1, 1}; Weights wpower2{DataType::kFLOAT, pval2+2, 1}; IScaleLayer* scale2 = network->addScale( *reduce2->getOutput(0), ScaleMode::kUNIFORM, wshift2, wscale2, wpower2); assert(scale2); IElementWiseLayer* ew2 = network->addElementWise(*ew1->getOutput(0), *scale2->getOutput(0), ElementWiseOperation::kDIV); assert(ew2); float* pval3 = reinterpret_cast<float*>(malloc(sizeof(float) * len)); std::fill_n(pval3, len, 1.0); Weights wpower3{DataType::kFLOAT, pval3, len}; weightMap[lname + ".power3"] = wpower3; IScaleLayer* scale3 = network->addScale( *ew2->getOutput(0), ScaleMode::kCHANNEL, weightMap[lname + ".bias"], weightMap[lname + ".weight"], wpower3); assert(scale3); return scale3; }

恩!我最擅长的就是依葫芦画瓢。很快,我把L2Norm也实现完了,并且精度一致。

IScaleLayer* L2norm(INetworkDefinition *network, std::map<std::string, Weights>& weightMap, ITensor& input, const std::string pre_name = "conv4_3_L2Norm.weight"){ //aa = x.pow(2) ## [1,512,40,40] const static float pval1[3]{0.0, 1.0, 2.0}; Weights wshift1{DataType::kFLOAT, pval1, 1}; Weights wscale1{DataType::kFLOAT, pval1+1, 1}; Weights wpower1{DataType::kFLOAT, pval1+2, 1}; IScaleLayer* scale1 = network->addScale( input, ScaleMode::kUNIFORM, wshift1, wscale1, wpower1); assert(scale1); //bb = x.pow(2).sum(dim=1, keepdim=True) ## [1,1,40,40] IReduceLayer* reduce1 = network->addReduce(*scale1->getOutput(0), ReduceOperation::kSUM, 1, true); assert(reduce1); //norm = x.pow(2).sum(dim=1, keepdim=True).sqrt()+self.eps # [1,1,40,40] const static float pval2[3]{0.0, 1.0, 0.5}; Weights wshift2{DataType::kFLOAT, pval2, 1}; Weights wscale2{DataType::kFLOAT, pval2+1, 1}; Weights wpower2{DataType::kFLOAT, pval2+2, 1}; IScaleLayer* scale2 = network->addScale( *reduce1->getOutput(0), ScaleMode::kUNIFORM, wshift2, wscale2, wpower2); assert(scale2); // x = torch.div(x,norm) IElementWiseLayer* ew2 = network->addElementWise(input, *scale2->getOutput(0), ElementWiseOperation::kDIV); assert(ew2); //out = self.weight.unsqueeze(0).unsqueeze(2).unsqueeze(3).expand_as(x) * x int len = weightMap[pre_name].count; float* pval3 = reinterpret_cast<float*>(malloc(sizeof(float) * len)); std::fill_n(pval3, len, 1.0); Weights wpower3{DataType::kFLOAT, pval3, len}; weightMap[pre_name + ".power3"] = wpower3; float* pval4 = reinterpret_cast<float*>(malloc(sizeof(float) * len)); std::fill_n(pval4, len, 0.0); Weights wpower4{DataType::kFLOAT, pval4, len}; weightMap[pre_name + ".power4"] = wpower4; IScaleLayer* scale3 = network->addScale( *ew2->getOutput(0), ScaleMode::kCHANNEL, wpower4, weightMap[pre_name], wpower3); assert(scale3); return scale3;}

然后再接着搭建后面的网络。
ps基金跌成狗了 <>

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。