从 OpenCV dnn 导出模型训练参数(按caffe格式)

先从Torch、tensorflow 等导入模型:

    String t7model="mosaic.t7";//Torch
	// 加载模型
	dnn::Net net = cv::dnn::readNetFromTorch(t7model.c_str());

然后读出各层名称:

	std::vector<String> lname=net.getLayerNames() ;

按名称得到id,:

	    int id=net.getLayerId(lname[i]);

按id得到各层训练参数:

	Mat blob=net.getParam(id, j);

然后按caffe格式保存。

完整cpp:

//从OpenCV导出风格模型训练参数: 加载模型 -> 取得各层名和参数 -> 导出成caffe 格式
#include <opencv2\opencv.hpp>
#include <opencv2\dnn.hpp>
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;
 
//字符串是否包含子串
bool endsWith(const String &str, const char *substr)
{
	int lc=str.length() - strlen(substr);
	if (lc>=0)//子串<母串(长度)
	{
		return str.rfind(substr) == lc;
	}
	else//子串>母串
		return false;
}



//保存一个参数,这里只有 2、4 维的情况
void save_mat (ofstream& fout,Mat& b)  
{  
	fout <<"  blobs {\n";
	if(b.isContinuous()) //连续
	{
		
		float* outData=b.ptr<float>(0);
		if(b.dims==2)
		{
			for (int i=0; i<b.size[0] * b.size[1]; ++i)
			{
				fout <<"    data: "<<*outData++ <<endl;;
			}
			fout <<"    shape {\n";
			fout <<"      dim: " <<b.size[0]<<endl;
			fout <<"      dim: " <<b.size[1]<<endl;
			fout <<"    }\n" ;
		}
		else if(b.dims==4)
		{
			for (int i=0; i<b.size[0] * b.size[1] * b.size[2] * b.size[3]; ++i)
			{
				fout <<"    data: "<<*outData++ <<endl;;
			}
			fout <<"    shape {\n";
			fout <<"      dim: " <<b.size[0]<<endl;
			fout <<"      dim: " <<b.size[1]<<endl;
			fout <<"      dim: " <<b.size[2]<<endl;
			fout <<"      dim: " <<b.size[3]<<endl;
			fout <<"    }\n" ;
		}
	}
	else
		cout<<"出错了,数据不连续!"<<endl;
	fout <<"  }\n";
} 

//导出参数
void saveModel(dnn::Net& net,String & t7model,String & filename)//文件中的名称,文件名
{
    ofstream fout (filename.c_str());  

	fout <<"name: \""<<t7model<<"\"\n" ; //第一行 名称

	std::vector<String> lname=net.getLayerNames() ;
    for (size_t i = 0; i != lname.size(); i++)
    {
        cout<<"层名:"<<lname[i]<<endl;

		fout <<"layer {\n";
		fout <<"  name: \""<<lname[i]<<"\"\n" ; //层名
	    int id=net.getLayerId(lname[i]);

		if(endsWith(lname[i], "Convolution")) //卷积层
		{
		    fout <<"  type: \"卷积\"\n";//类型
		}
		else if(endsWith(lname[i], "BatchNorm")) // 批归范化
		{
		    fout <<"  type: \"批归范\"\n";//类型
		}
		else if(endsWith(lname[i], "Deconvolution")) // 反卷积
		{
		    fout <<"  type: \"反卷积\"\n";//类型
		}

		//各层有没有训练参数呢?有几个?
		int layerBlobs_size=10;// 如何确定有多少个训练参数呢?CV dnn中有没有什么函数可用呢?
								//如何确定参数顺序呢?比如:批归范化4个(均值、方差、权重、偏移)
		try //j到哪步出错,说明有几个参数
		{
			for (size_t j = 0; j != layerBlobs_size; j++)
			{
				Mat blob=net.getParam(id, j);
				cout<<"dims:"<<blob.dims<<endl;
				cout<<"size:"<<blob.size<<endl;
				save_mat (fout,blob) ;//保存一个参数
			}
		}
		catch(...)
		{
			
		}
		
		fout <<"}\n";
    }

    fout.close ();  

}

int main(int argc, char *argv[])
{

    String t7model="mosaic.t7";//Torch
	// 加载模型
	dnn::Net net = cv::dnn::readNetFromTorch(t7model.c_str());

	//导出训练参数,大致按 caffe 方式存放
	String filename="style." + t7model +".txt";
	saveModel(net,t7model,filename);//导出所有层名和参数

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值