c++序列化方法
- 暂时使用boost 序列化, 目前我的测试基本都ok 只是对于c++11 shared ptr 没有测试成功,只能手工写下shared ptr 部分的序列化,也就是目前我对指针都不直接序列化,自己管理,例如下面样子
Load_(modelFile); //model直接序列化
string normalizerName = read_file(OBJ_NAME_PATH(_normalizer));
if (!normalizerName.empty())
{ //由于没有利用shared ptr直接序列化,不知道具体信息,所以我save的时候写了normalzier类型名字到文本,load时候通过这个确定类型
_normalizer = NormalizerFactory::CreateNormalizer(normalizerName, OBJ_PATH(_normalizer));
}
string calibratorName = read_file(OBJ_NAME_PATH(_calibrator));
if (!calibratorName.empty())
{
_calibrator = CalibratorFactory::CreateCalibrator(calibratorName, OBJ_PATH(_calibrator));
}
static NormalizerPtr CreateNormalizer(string name)
{
boost::to_lower(name);
if (name == "minmax" || name == "minmaxnormalizer")
{
return make_shared<MinMaxNormalizer>();
}
if (name == "gaussian" || name == "gaussiannormalizer")
{
return make_shared<GaussianNormalizer>();
}
if (name == "bin" || name == "binnormalizer")
{
return make_shared<BinNormalizer>();
}
LOG(WARNING) << name << " is not supported now, do not use normalzier, return nullptr";
return nullptr;
}
static NormalizerPtr CreateNormalizer(string name, string path)
{
NormalizerPtr normalizer = CreateNormalizer(name);
if (normalizer != nullptr)
{
normalizer->Load(path); //normalzier直接序列化
}
return normalizer;
}
@TODO 确认下是否没有办法直接序列化shared ptr,
另外可以尝试下开源的专门序列化库creal,creal仿照boost 序列化 同时boost序列化只支持binary,文本,xml三种序列化,文本序列化可读性不强,binary速度最快,xml可读性最高速度慢一些。我一般只用binary和xml格式。而creal 支持json格式的输出,号称支持shared ptr
同一个模型boost序列化速度
|
Binary |
Text |
Save |
1.8 |
2.29 |
Load |
1.9 |
2.67 |
- 如果需要xml输出,boost的序列化写法和只需要binary输出不一样,建议采用支持xml输出的写法这样互相都兼容。
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
/* ar & boost::serialization::base_object<Predictor>(*this);
ar & _weights;
ar & _bias;*/ //这种写法只支持binary
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Predictor);
ar & BOOST_SERIALIZATION_NVP(_weights); //这样宏比较方便 如果需要改名字比如_weights->weights可以使用原函数
ar & BOOST_SERIALIZATION_NVP(_bias);
}
- 采用python脚本自动生成序列化部分的代码。因为和c#不一样 c#是默认都可以序列化,如果不需要序列化,你可以类似#define指定,而boost默认都不序列化,需要序列化的地方需要显示都写上
Predictors]$ get-lines.py LinearPredictor.h 98 99 | gen-boost-seralize-xml.py
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(_weights);
ar & BOOST_SERIALIZATION_NVP(_bias);
}
4. 对于Predictor 默认是Save二进制,可选的SaveXml方式这个自动支持,可选的SaveText这个是特定的Precitor子类型如果有需要手动写的文本输出格式。
xml输出类似这样
转换为json
xml2json.py model.xml > model.json
more model.json
采用json pretty print来查看json文件
jpp.py model.json | more
Xml2tojson.py 利用xmltodict 进行向json的转换
import sys,os
import xmltodict, json
doc = xmltodict.parse(open(sys.argv[1]), process_namespaces=True)
print json.dumps(doc)
Jpp.py
import sys,os
import json
s = open(sys.argv[1]).readline().decode('gbk')
print json.dumps(json.loads(s),sort_keys=True, indent=4, ensure_ascii=False).encode('gbk')
- 如何更方便的查看输出的模型?
小的模型输出直接看xml文本就好,如果数据比较多处理xml不是很方便,json好一些 用python,
但是如果转换为json的map也不是很方便因为你要按照key去访问string类型是没有自动提示的
In [6]: import json
In [7]: m = json.loads(open('./model.json').readline())
In [8]: m.keys()
Out[8]: [u'boost_serialization']
In [9]: m['boost_serialization'].keys()
Out[9]: [u'@version', u'@signature', u'data']
In [18]: m['boost_serialization']['data']['_trees']['item'][0].keys()
Out[18]:
[u'_gainPValue',
u'@tracking_level',
u'@class_id',
u'_lteChild',
u'_gtChild',
u'_maxOutput',
u'_leafValue',
u'NumLeaves',
u'_splitGain',
u'_splitFeature',
u'_previousLeafValue',
u'_threshold',
u'@version',
u'_weight']
In [19]: m['boost_serialization']['data']['_trees']['item'][0]['_splitGain']['item'][10]
Out[19]: u'3.89894126598927926e+00'
由于python提示的时候_开头的作为private默认是不提示的,因此做了修改
#include "conf_util.h"
#include <boost/serialization/nvp.hpp>
#define GEZI_SERIALIZATION_NVP(name)\
boost::serialization::make_nvp(gezi::conf_trim(#name).c_str(), name)
这样展示的就是gainPvalue这样没有_开头了
利用python的自省功能可以把json解析得到的dict数据,string作为key的转为一个python object方便访问如下
def h2o(x):
if isinstance(x, dict):
return type('jo', (), {k: h2o(v) for k, v in x.iteritems()})
elif isinstance(x, list):
l = [h2o(item) for item in x]
return l
else:
return x
def h2o2(x):
if isinstance(x, dict):
return type('jo', (), {k: h2o2(v) for k, v in x.iteritems()})
elif isinstance(x, list):
return type('jo', (), {"i" + str(idx): h2o2(val) for idx, val in enumerate(x)})
return l
else:
return x
def xmlfile2obj(path):
import xmltodict
doc = xmltodict.parse(open(path), process_namespaces=True)
return h2o(doc)
def xmlfile2obj2(path):
import xmltodict
doc = xmltodict.parse(open(path), process_namespaces=True)
return h2o2(doc)
这样对于序列化之后的xml文件可以直接使用 m = xmlfile2obj('*.xml') 或者 m = xml2obj2('*.xml')
建议是用第一种,是标准转换,提供第二个接口主要是python的自动提示对于list的item就没有了,只能dir()查看。。
第二种将[3]这样转为了.i3也就是去掉了所有list都用dict表示。
m = xmlfile2obj('./model.xml')
In [14]: m.boost_serialization.data.trees.item[0].splitGain.item[13]
Out[14]: u'3.26213753939964946e+00'
m = xmlfile2obj2('./model.xml')
In [16]: m.boost_serialization.data.trees.item.i0.splitGain.item.i13
Out[16]: u'3.26213753939964946e+00'
c++序列化方法的更多相关文章
- Django的DRF序列化方法
安装rest_framework -- pip install djangorestframework -- 注册rest_framework序列化 -- Python--json -- 第一版 用v ...
- jquery字符串序列化方法总结
在jquery中字符串序列化方法包括有param() .serialize() .serializeArray(),在这里对其常用做法进行总结. $.param()方法这是serialize()方法的 ...
- (转)C# 的三种序列化方法
序列化是将一个对象转换成字节流以达到将其长期保存在内存.数据库或文件中的处理过程.它的主要目的是保存对象的状态以便以后需要的时候使用.与其相反的过程叫做反序列化. 序列化一个对象 为了序列化一个对象, ...
- C# 的三种序列化方法
序列化是将一个对象转换成字节流以达到将其长期保存在内存.数据库或文件中的处理过程.它的主要目的是保存对象的状态以便以后需要的时候使用.与其相反的过程叫做反序列化. 序列化一个对象 为了序列化一个对象, ...
- django drf 10大请求序列化方法
## 整体单改 路由层.模型层.序列化层不需要做修改,只需要处理视图层:views.py ```python"""1) 单整体改,说明前台要提供修改的数据,那么数据就需要 ...
- 自已写的Json序列化方法,可以序列话对象的只读属性
/* * by zhangguozhan 2015/1/5 * P2B.Common.CJson.ConvertJson.ObjectToJson<SenderDomainModel>方法 ...
- 分享一个 jquery serializeArray()序列化方法
http://www.365mini.com/page/jquery-serializearray.htm http://www.365mini.com/diy.php?f=jquery-serial ...
- Redis 数据序列化方法 serialize, msgpack, json, hprose 比较
最近弄 Redis ,涉及数据序列化存储的问题,对比了:JSON, Serialize, Msgpack, Hprose 四种方式 1. 对序列化后的字符串长度对比: 测试代码: $arr = [0, ...
- 配置spring cache RedisCacheManager的序列化方法
通过查看autoconfigure源码 org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration; 部分源码如下: pr ...
随机推荐
- Android6.0以后动态增加权限
private void test() throws IOException { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { in ...
- BestCoder Round #61 1002 Game
Problem Description XY is playing a game:there are N pillar in a row,which numbered from 1 to n.Each ...
- css position属性
absolute, 屏幕为参照, 但固定在页面上,随页面滚动而动. fixed, 父元素没有指定position属性(或position属性为static时)==>屏幕为参照,固定在屏幕的某个位 ...
- django xadmin自定义菜单
1. 自定义菜单 adminx.py class GlobalSetting(object): site_title = u'xxx后台' def kuF_site_menu(self): retur ...
- Python连接MySQL的准备工作
首先要安装MySQL,64位的win7可以安装64或者32位的MySQL版本,安装之后,python需要一个工具才能连接MySQL,这个工具叫MySQL-python,去这里或者这里下载1.2.3版本 ...
- php 使用redis锁限制并发访问类
1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功. 例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制 ...
- openstack 常用命令
转自: docs.openstack.org $ nova boot --image ubuntu-cloudimage --flavor 1 --user-data mydata.file
- crontab命令
前一天学习了 at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个 ...
- 使用SharePoint 2010 母版页
SharePoint 2010母版页所用的还是ASP.NET 2.0中的技术.通过该功能,实现了页面框架布局与实际内容的分离.虽然在本质上自定义母版页的过程和以前版本的SharePoint大致相同,但 ...
- ios 转发一篇对于6 plus的分辨率模式的说明
http://segmentfault.com/q/1010000002545515 分为兼容模式和高分辨率模式. 兼容模式 当你的 app 没有提供 3x 的 LaunchImage 时,系统默认进 ...