opencv c++ caffe模型加载,自定义一个permute层

1、定义层结构

因为不知道如果同名可不可以覆盖掉原来的层,所以我同名试试,证明可以覆盖

第78行用于读取参数

83行用于创建整个层

87行是定义输出数据的结构

102层是层的具体方法,在基类Layer中是一个纯虚函数,一定要重定义

121层我也不知道干啥的,但是在基类Layer中是一个纯虚函数,一定要重定义

如果基类中的纯虚函数没有在派生类中全部被重新定义,那么派生类会是以一个抽象类,抽象类不能实例化。

129行是后面的CV_DNN_REGISTER_LAYER_CLASS的头文件,没有的话,会报错

134行是对新层permute的声明,没有的话,层就不会在编译的时候被加载

2、参数输入

原来的层参数都叫order,但是这样,我不知道怎么读取,所以就干脆写成了四个参数

然后读出来就是这样的

发现,输入的参数可以少于目标的四个,就是需要几个输入几个,然后红色的框子里面的就是没有输入的情况下的默认值,也是最小值,就是如果你输入参数是-1之类的,他就直接给你改成0了。

 

3、输出数据格式

在这个函数里面定义,输入参数不理解可以参考这个链接https://blog.csdn.net/Diana_Z/article/details/98613363

在写这个过程的时候遇到一个坑

开始打算使用-1作为空白维度的标识,但是调试的时候发现,-1会自动变成1,没有输入也会自动变成1

然后尝试将正常维度里面的1使用10来代替,-1或者没有输入变成了0

最后干脆将正常维度从10开始,正常维度0参数10,正常维度1参数11,类推

上面这个问题找到参数位置了,在参数读取部分

遇到第二个坑,

我重写这个参数的目的根源是想要让lstm可以读3维甚至二维的矩阵,当前我的矩阵没有设置卷积,数据直接就lstm层。

然后,我发现blob的数据读取自动就是B*C*H*W的

所以这里我需要的可能不是重写一个permute层,而是重写一个降维层。

不过在降维层之前,因为2维3维的转置总是有的,所以还是有用的吧。

static cv::Ptr<cv::dnn::Layer> create(cv::dnn::LayerParams& params)
	{
		return cv::Ptr<cv::dnn::Layer>(new PermuteLayer(params));
	}
	virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
		const int requiredOutputs,
		std::vector<std::vector<int> > &outputs,
		std::vector<std::vector<int> > &internals) const CV_OVERRIDE
	{
		CV_UNUSED(requiredOutputs); CV_UNUSED(internals);
		cout << "start PermuteLayer getMemoryShapes" << endl;
        //将四个输入放入数组
		std::vector<int> order(4);
		order[0] = order1;
		order[1] = order2;
		order[2] = order3;
		order[3] = order4;
		
        //第一次循环,计算维度,恢复维度下标
		int dim = 0;
		for (int i = 0; i < 4; i++) {
			if (order[i] <10) {
				break;
			}
			else {
				dim++;
				order[i] = order[i] % 10;
			}
		}

        //第二次循环,将input的size都放在数组里面去
		std::vector<int> newShape;
		for (int i = 0; i < dim; i++) {
			newShape.push_back(inputs[0][i]);
		}

        //第三次循环,将input中的数字按照order的顺序放入output
		std::vector<int> outShape; 
		for (int i = 0; i < dim; i++) {
			outShape.push_back(newShape[order[i]]);
		}
		outputs.assign(1, outShape);
		return false;
	}

 

4、计算过程

virtual void forward(std::vector<cv::Mat*> &inputs, std::vector<cv::Mat> &outputs, std::vector<cv::Mat> &internals) CV_OVERRIDE
	{
		CV_UNUSED(internals);
		cout << "start PermuteLayer forward1" << endl;
		cv::Mat& inp = *inputs[0];
		cv::Mat& out = outputs[0];

		if (order3 == -1) {
			vector<int> sq(2);
			int H = inp.size[0];
			int W = inp.size[1];
			for (int i = 0; i < H; i++) {
				sq.push_back(i);
				for (int j = 0; j < W; j++) {
					sq.push_back(j);
					cout << sq[order1] << "  " << sq[order2] << endl;
					out.at<float>[sq[order1]][sq[order2]] = inp.at<float>[i][j];
					sq.pop_back();
				}
				sq.pop_back();
			}
		}

		if (order4 == -1) {
			vector<int> sq(2);
			int H = inp.size[0];
			int W = inp.size[1];
			int C = inp.size[2];
			for (int k = 0; k < C; k++) {
				sq.push_back(k);
				for (int i = 0; i < H; i++) {
					sq.push_back(i);
					for (int j = 0; j < W; j++) {
						sq.push_back(j);
						out.at<float>[sq[order1]][sq[order2]][sq[order3]] = inp.at<float>[k][i][j];
						sq.pop_back();
					}
					sq.pop_back();
				}
				sq.pop_back();
			}
		}
		if (order4 > 0) {
			vector<int> sq(2);
			int H = inp.size[0];
			int W = inp.size[1];
			int C = inp.size[2];
			int B = inp.size[3];
			for (int l = 0; l < B; l++) {
				sq.push_back(l);
				for (int k = 0; k < C; k++) {
					sq.push_back(k);
					for (int i = 0; i < H; i++) {
						sq.push_back(i);
						for (int j = 0; j < W; j++) {
							sq.push_back(j);
							out.at<float>[sq[order1]][sq[order2]][sq[order3]][sq[order4]] = inp.at<float>[l][k][i][j];
							sq.pop_back();
						}
						sq.pop_back();
					}
					sq.pop_back();
				}
				sq.pop_back();
			}
		}
	}

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值