| areal 的个人资料iamcrf日志列表 | 帮助 |
|
|
6月25日 快速排序vs.冒泡排序最近两个星期的时间,我被chinese gigaword corpus的处理难住了:我原来的程序居然不能正确处理超过一亿汉字的文本,每次都在几分钟甚至几个小时后崩溃。硬邦邦的linux只会报告segment fault。不知道问题出在哪里。
昨天的时候灵机一动,会不会是数据太大,导致表示指标的数据类型越界了?看了下,果然是用的是int型,改成unsigned long型,居然跑通了几个。继续检查剩下的几个segment fault,发现问题出在快速排序那一段,因为用了递归函数,不知道哪里有问题,今天临时改为冒泡排序,再也没有segment fault了。但是出了新问题:到现在为止,一个原来15分钟quick sort掉的样本集(包含1.2亿汉字),几个小时都没有冒泡完。 2月1日 Stallman征婚了-ztCraigslist是全球最大和最早的分类广告网站,近日有人发现开源软件运动的领军人物Richard Stallman在其上发布了一则征婚启事: “本人是单身白人无神论者,54岁,众所周知地聪明,非同寻常地热衷于政治、科学、音乐和跳舞。 希望寻找一位兴趣广泛、对世界充满好奇、性格直爽爱憎分明(我讨厌猜来猜去)的温柔女性,能把乐趣、真理、美和正义看得比“成就”更重要......我花费很多时间在欧洲、亚洲和拉美演讲,如果能有时间与我一同旅行就最好不过了。” 同时RMS还附上了自己的照片。 本贴来源 http://news.mydrivers.com/1/99/99243.htm 评论:Stallman还是蛮谦虚的。 11月6日 crf++为什么浪费内存:都是stl惹的祸利用休假读了下crf++代码,特别是有关存储训练数据的内存结构部分。很久以前,我就通过匆匆扫过一遍的映像,认为crf++这部分的浪费非常严重。近期的阅读证实了这一观点。我还是用去年发布的0.44版。
一般来说,系统训练需要缓存两部分的内容,一部分是关于训练数据的信息,主要包括特征的表达式以及相应的频率,另外一部分用来LBFGS训练的矩阵缓存,包括lambda权值向量。后面一部分内容是不可或缺的。如果要节省内存耗费,可以考虑把第一部分内容在记录到磁盘后,仅仅留下特征的代号和对应的频率信息在内存中。
问题是,我发现, crf++没有这么做。所有的信息都保留在内存中,直到训练结束的时候一口气写入model文件。当然,crf++也不是什么都没有做。crf++在开始训练前,函数
bool TaggerImpl::shrink()
{ CHECK_FALSE(feature_index_->buildFeatures(*this)) << feature_index_->what(); std::vector <std::vector <const char *> >(x_).swap(x_);
std::vector <std::vector <Node *> >(node_).swap(node_); std::vector <unsigned short int>(answer_).swap(answer_); std::vector <unsigned short int>(result_).swap(result_); return true;
} 中,
第一句对特征进行编码,后边4句企图释放掉已经无用的训练数据缓存。taku使用了标准的swap方式来释放stl管理的内容。不幸的是,这些内存其实根本就没有得到释放。注释掉这4句后,内存的使用也不会增长。简单来说,这组内存没有得到释放。
由于对stl不熟悉---实际上,我还不会用allocator---我使用标准c替代了相关部分。
首先,我用一个简单的自己管理的char *代替了std::vector <const char *> > TaggerImpl::x_,结果期望中的内存强制释放马上获得了10%的内存减少。
然后,我把model存盘分为两次,第一次在最开始的时候存下特征的表达式及其id,第二次在训练结束的时候存下lambda向量。在第一次存盘结束后,就释放掉特征表达式的缓存。这个缓存原始的crf++使用std::map <std::string, std::pair<int, unsigned int> > EncoderFeatureIndex::dic_;来管理的。我自己用标准c++ without stl重写了一个map。存盘结束后的内存释放又获得了10%的内存减少。
现在,主要的问题是,虽然只是影响训练数据装载的速度,但是我自己写的map在插入数据的时候比stl的要慢10倍。难道我要去偷看一遍stl? 困挠中。。。
11月2日 pocket crf的二阶crf特征的结果及其讨论重复一下试验的设置。
语料:ctb segmented corpus from bakeoff-4,
训练语料 642246词
测试语料 80700词
6-标注集,b,b2,b3,m,e,s for each character in corpus
6-特征模版:C_{-1}, C_0,C_1, C_{-1}C_0,C_0C_1,C_{-1}C_1
一律用f-score度量结果
运行的cpu是core duo T7600, 2.33G, 3.2G mem
pocket crf ver 0.30 给出的结果
(a) +1阶状态转移特征 %y[-1]%y[0]: 0.949298
(b) +1,2阶状态转移特征 %y[-1]%y[0]+%y[-2]%y[-1]%y[0]: 0.949590
(c) +1,2阶状态转移特征 %y[-1]%y[0] +%y[-2]%y[0]: 0.949636
(d) +2阶状态转移特征 +%y[-2]%y[-1]%y[0]: 0.949661
注意到,按照pocket crf的结果,2阶CRF对于分词学习的贡献微乎其微。(a)运行时间大约3小时,(b),(c),(d)大约运行20-24小时。
内存使用,均为450M左右。
crf++ ver 0.44 给出的结果
(e) +1阶状态转移特征 %y[-1]%y[0]: 0.963407 运行时间,pocket crf和 crf++ 相当。内存使用,crf++在(e)上要1G。
注:
ctb语料的bakeoff-4官方结果最好成绩为0.9596
我注意到,pocket crf生成的model文件远远小于crf++,大约只有后者的1/3。难道这就是 crf++ 保持精度领先的秘诀?
pocket crf作者的blog
上面报告了msra2005/bakeoff-2语料上的结果
“ 原来是1order CRF, 训练5小时,消耗内存836M,测试结果0.959
加了一个%y[-2]%y[0]模板,训练18小时,消耗内存988M,测试结果0.961 ”
我猜测,2阶crf之所以在作者报告的这一情形导致显著的改进的原因是n-gram学习在这一语料上没有达到性能饱和,msra2005语料上bakeoff-2的最好成绩是0.964,使用我上面的6-tag+6-feature templates,性能可以轻易达到0.972.
作者的这一结果我理解为,当基线性能很低的时候,所获得改进不是实质性的。
10月21日 新东方的罗老师骂苹果公司产品的粉丝以下是转载,我有一个ipod, 但是我一直拿它作移动硬盘,所以我转了这篇文章出出气。
史蒂夫.乔布斯早年把苹果的系统设计成封闭式的时候,苹果粉丝们说他有性格,酷,后来他为了迁就市场开始有所妥协的时候,他们说他成熟稳健,牛X。 |
|
|