Closed solemnrole closed 4 years ago
- 有,请参考:https://github.com/hankcs/HanLP/blob/5e37067791abca9b676bc4c127294aa08343b92d/src/test/java/com/hankcs/demo/DemoEvaluateCWS.java
- 更详细的对比可参考第三方评测:http://blog.zongwu233.com/hanlp-vs-ltp/
- 有很多手段可以让分数变得更漂亮,但跑分高的未必体验好,一些论文中的分数水分也不少;目前的想法是平衡效率,简洁为主。
赞!(很想夸夸你,哈哈)
我也测试了您另外一篇关于Bi_LSTM+CRF模型在多标准数据集上的表现,单从分词精确度上看深度方法比hanlp是要好的。但是我在测试自己的数据集时发现了一些问题。望请指教。
1、测试阶段为什么需要同时测试多个数据集,单独测试某个数据集会报错;同时测试多个数据集的测试集但不包含全部标准的数据集(如10个多标准数据集的联合训练结果,测试数据集个数<10),每个数据集的结果并不能达到论文结果。
2、因为自己的数据集不知道更符合哪个标准些,然而在测试阶段需要指定测试集所属哪个tag(例如
感谢反馈,那一版代码赶时间写的,没有模块化,给您造成了不便。
感谢反馈,那一版代码赶时间写的,没有模块化,给您造成了不便。
- 因为写代码方便吧,一张表什么结果都有。正确操作的话不可能存在你说的情况,你可以阅读解码部分。如果你修改了源码或数据集请保证小心操作(训练时限定句子长度、数据集都有自己的tag、数字英文的预处理等等,这些逻辑都在make_dataset.py里面)。作为作者也只能保证论文结果与代码在给定数据集上的运行结果一致(可复现),不可能保证第三方修改后的代码或数据一定稳定。
- 你的情况看上去像是说测试阶段模型会随测试数据变动,但我写的解码部分并没有back propagation,模型是不可能变化的。我的代码训练和测试放在一个文件中,你一定修改了代码才能分离训练和测试。否则每次训练随机数不同,结果自然不同。
第二个问题如果是随机数导致的,那就没什么问题啦!感谢!
针对第一个问题,我重现下结果比较好解释。
麻溜溜的重现了一下结果。训练集混合了10个训练集。参数设置与源码一致。 情况一:测试sighan2005。测试10个测试集中的4个测试集。 bash ./script/test.sh joint-sighan2005 [dynet] random seed: 3098 [dynet] allocating memory: 512MB [dynet] memory allocation done. test.py --dataset dataset/joint-sighan2005/dataset.pkl --num-epochs 60 --word-embeddings data/embedding/character.vec --log-dir result/joint-sighan2005 --dropout 0.2 --learning-rate 0.01 --learning-rate-decay 0.9 --hidden-dim 100 --dynet-seed 3098 --bigram --test --old-model result/model.bin
Namespace(always_model=False, batch_size=20, bigram=True, char_embedding_dim=100, char_embeddings=None, char_hidden_dim=100, clip_norm=None, dataset='dataset/joint-sighan2005/dataset.pkl', debug=False, dropout=0.2, dynet_autobatch=None, dynet_gpus=None, dynet_mem=None, dynet_seed=3098, dynet_weight_decay=None, hidden_dim=100, learning_rate=0.01, learning_rate_decay=0.9, log_dir='result/joint-sighan2005', lowercase_words=False, lstm_layers=1, no_model=False, no_we=False, no_we_update=False, num_epochs=60, old_model='result/model.bin', python_seed=1121087516941010692, skip_dev=False, subset=None, task_name='2018-10-18-02-25-47', test=True, tie_two_embeddings=False, use_char_rnn=False, word_embeddings='data/embedding/character.vec') Python random seed: 1121087516941010692
Number test instances: 52535 cityu 96.05 95.70 95.88 msr 97.06 97.16 97.11 pku 95.54 96.30 95.92 AVG 96.10 95.93 96.02 Error in `python3': munmap_chunk(): invalid pointer: 0x00007fa40ee90010 ./script/test.sh: line 14: 13801 Aborted (core dumped) python3 test.py --dataset dataset/$1/dataset.pkl --num-epochs 60 --word-embeddings data/embedding/character.vec --log-dir result/$1 --dropout 0.2 --learning-rate 0.01 --learning-rate-decay 0.9 --hidden-dim 100 --dynet-seed $RANDOM --bigram --test --old-model result/model.bin ${@:2}
情况二:测试全部数据集。 bash ./script/test.sh joint-10in1 [dynet] random seed: 28155 [dynet] allocating memory: 512MB [dynet] memory allocation done. test.py --dataset dataset/joint-10in1/dataset.pkl --num-epochs 60 --word-embeddings data/embedding/character.vec --log-dir result/joint-10in1 --dropout 0.2 --learning-rate 0.01 --learning-rate-decay 0.9 --hidden-dim 100 --dynet-seed 28155 --bigram --test --old-model result/model.bin
Namespace(always_model=False, batch_size=20, bigram=True, char_embedding_dim=100, char_embeddings=None, char_hidden_dim=100, clip_norm=None, dataset='dataset/joint-10in1/dataset.pkl', debug=False, dropout=0.2, dynet_autobatch=None, dynet_gpus=None, dynet_mem=None, dynet_seed=28155, dynet_weight_decay=None, hidden_dim=100, learning_rate=0.01, learning_rate_decay=0.9, log_dir='result/joint-10in1', lowercase_words=False, lstm_layers=1, no_model=False, no_we=False, no_we_update=False, num_epochs=60, old_model='result/model.bin', python_seed=5079087346137412977, skip_dev=False, subset=None, task_name='2018-10-18-02-26-29', test=True, tie_two_embeddings=False, use_char_rnn=False, word_embeddings='data/embedding/character.vec') Python random seed: 5079087346137412977
Number test instances: 179053 100/100 [==============================] - 333s - f1: 96.6188 as 95.93 94.89 95.40 cityu 96.32 96.09 96.20 cnc 96.80 97.15 96.97 ctb 96.52 96.76 96.64 msr 97.21 97.36 97.29 pku 95.62 96.40 96.00 sxu 96.41 96.39 96.40 udc 94.55 94.54 94.54 wtb 92.53 90.67 91.59 zx 95.32 95.63 95.47 AVG 96.53 96.71 96.62
情况三:测试10个测试集中的1个测试集。 bash ./script/test.sh msr [dynet] random seed: 19804 [dynet] allocating memory: 512MB [dynet] memory allocation done. test.py --dataset dataset/msr/dataset.pkl --num-epochs 60 --word-embeddings data/embedding/character.vec --log-dir result/msr --dropout 0.2 --learning-rate 0.01 --learning-rate-decay 0.9 --hidden-dim 100 --dynet-seed 19804 --bigram --test --old-model result/model.bin
Namespace(always_model=False, batch_size=20, bigram=True, char_embedding_dim=100, char_embeddings=None, char_hidden_dim=100, clip_norm=None, dataset='dataset/msr/dataset.pkl', debug=False, dropout=0.2, dynet_autobatch=None, dynet_gpus=None, dynet_mem=None, dynet_seed=19804, dynet_weight_decay=None, hidden_dim=100, learning_rate=0.01, learning_rate_decay=0.9, log_dir='result/msr', lowercase_words=False, lstm_layers=1, no_model=False, no_we=False, no_we_update=False, num_epochs=60, old_model='result/model.bin', python_seed=5374290607303740261, skip_dev=False, subset=None, task_name='2018-10-18-02-27-16', test=True, tie_two_embeddings=False, use_char_rnn=False, word_embeddings='data/embedding/character.vec') Python random seed: 5374290607303740261
Number test instances: 15433 ./script/test.sh: line 14: 13813 Segmentation fault (core dumped) python3 test.py --dataset dataset/$1/dataset.pkl --num-epochs 60 --word-embeddings data/embedding/character.vec --log-dir result/$1 --dropout 0.2 --learning-rate 0.01 --learning-rate-decay 0.9 --hidden-dim 100 --dynet-seed $RANDOM --bigram --test --old-model result/model.bin ${@:2}
以上三种情况采用的都是公共数据集,也未对源码进行修改。
另外,想请教一下,在测试阶段为什么必须要加载训练集,我尝试了在make_dataset.py中只加载了测试集,在model.py中也删除关于训练集的操作,结果会报与上述情况三一样的错误。
这些问题产生的原因我找了很久,还是没有找到,依靠自己的能力解决不了了,烦请指教,非常非常非常感谢~
# ===-----------------------------------------------------------------------===
# Read in dataset
# ===-----------------------------------------------------------------------===
dataset = pickle.load(open(options.dataset, "rb"))
w2i = dataset["w2i"]
t2i = dataset["t2i"]
c2i = dataset["c2i"]
i2w = utils.to_id_list(w2i) # Inverse mapping
i2t = utils.to_id_list(t2i)
i2c = utils.to_id_list(c2i)
你如果将这些东西从dataset分离,当然可以不加载整个dataset。
在此基础上,我有很大的把握确定你加载了不同的模型。一个数据集和一个模型是一一对应的,否则映射表错乱你根本不可能拿到96%以上的准确率。如果映射到不存在的id,就会发生Segmentation fault ,所以你后来根本跑不出结果。
默认的逻辑不允许用join10的模型跑join-sighan2005的数据,除非你懂得怎么将映射表改过去。你所说的一切问题,都是由此引起的。
- 我没有提供test.py或test.sh,你在这里面是否加载了不同的模型?
- 由于字符串映射表属于dataset的一部分,所以必须全部加载。
# ===-----------------------------------------------------------------------=== # Read in dataset # ===-----------------------------------------------------------------------=== dataset = pickle.load(open(options.dataset, "rb")) w2i = dataset["w2i"] t2i = dataset["t2i"] c2i = dataset["c2i"] i2w = utils.to_id_list(w2i) # Inverse mapping i2t = utils.to_id_list(t2i) i2c = utils.to_id_list(c2i)
你如果将这些东西从dataset分离,当然可以不加载整个dataset。
在此基础上,我有很大的把握确定你加载了不同的模型。一个数据集和一个模型是一一对应的,否则映射表错乱你根本不可能拿到96%以上的准确率。如果映射到不存在的id,就会发生Segmentation fault ,所以你后来根本跑不出结果。
默认的逻辑不允许用join10的模型跑join-sighan2005的数据,除非你懂得怎么将映射表改过去。你所说的一切问题,都是由此引起的。
这三种情况我均采用了joint.10n1训练出来的模型,模型,test.py与tes与py与test.sh文件对应文件对应着对应着train.py tra py train.sh文件,我文件,我只是在share文件中修改了一部分参数,方便离线测试测试集.
如果你保证模型一样,那么所有问题都是由映射表造成的。
虽然是子集,但由于make dataset时读取顺序不同,导致映射表也不同(用一个字符对应两种id)。你之所以第一个实验能出部分结果(缺少AS),是因为恰好在make dataset时读取语料的顺序部分相同,但该次程序也发生了异常退出。再次道歉,这份代码是赶时间写的,怎么快怎么写,没有任何设计。
如果你保证模型一样,那么所有问题都是由映射表造成的。
虽然是子集,但由于make dataset时读取顺序不同,导致映射表也不同(用一个字符对应两种id)。你之所以第一个实验能出部分结果(缺少AS),是因为恰好在make dataset时读取语料的顺序部分相同,但该次程序也发生了异常退出。再次道歉,这份代码是赶时间写的,怎么快怎么写,没有任何设计。
抱歉太严重啦,这不是你的义务,O(∩_∩)O。很感谢你的分享。
那我想要复用它的话,就只能修改映射表了? 下面是根据我对代码的认知程度对‘’映射表‘’进行的修改,结果还是不行,想不通了,烦请指教,以下修改只针对测试阶段。 1、在make_dataset.py中,我直接屏蔽了关于training,dev两方面的字符集到w,t,c字典中。 output["training_instances"], output["training_vocab"] = read_file(options.training_data, w2i, t2i, c2i) print('Making dev dataset') output["dev_instances"], output["dev_vocab"] = read_file(options.dev_data, w2i, t2i, c2i)
2、model.py中 dataset = pickle.load(open(options.dataset, "rb")) w2i = dataset["w2i"] t2i = dataset["t2i"] c2i = dataset["c2i"] i2w = utils.to_id_list(w2i) # Inverse mapping i2t = utils.to_id_list(t2i) i2c = utils.to_id_list(c2i) 这一块读取的信息,其实就是把train,dev与test隔离开来了。因为我的dataset没有包含关于train,dev的字符集,以及映射关系。
expand_instances(test_instances) bigram_embeddings = np.random.uniform(-0.8, 0.8, (len(b2i), word_embeddings.shape[1])) for (pre, cur), id in b2i.items(): bigram_embeddings[id] = (word_embeddings[pre] + word_embeddings[cur]) / 2
这块我将关于训练验证集屏蔽了,是对bigram_embeddings的削弱,这块是导致了指针指向错误的主要原因吧?
bigram_embeddings的使用是在BiLSTM_CRF模型构建时使用
if options.bigram: self.bigram_lookup = self.model.add_lookup_parameters((len(b2i), word_embedding_dim)) self.bigram_lookup.init_from_array(bigram_embeddings)
对bigram_embeddings的修改导致了测试集中的字符id并没有与训练集中的字符id完全匹配,最终抛出指针异常? 1、可是这里是否也存在着巧合,只要保证测试集的字符set与训练集的字符set吻合,就可以保证不会抛出异常?
不知道我理解的有没有问题,烦请忙里偷闲指教~
@solemnrole @hankcs 能提供下链接么,thx。 《另外一篇关于Bi_LSTM+CRF模型在多标准数据集上的表现》
@solemnrole @hankcs 能提供下链接么,thx。 《另外一篇关于Bi_LSTM+CRF模型在多标准数据集上的表现》
@wchnjstar123 https://github.com/hankcs/multi-criteria-cws
感谢您对HanLP1.x的支持,我一直为没有时间回复所有issue感到抱歉,希望您提的问题已经解决。或者,您可以从《自然语言处理入门》中找到答案。
时光飞逝,HanLP1.x感谢您的一路相伴。我于东部标准时间2019年12月31日发布了HanLP1.x在上一个十年最后一个版本,代号为最后的武士。此后1.x分支将提供稳定性维护,但不是未来开发的焦点。
值此2020新年之际,我很高兴地宣布,HanLP2.0发布了。HanLP2.0的愿景是下一个十年的前沿NLP技术。为此,HanLP2.0采用TensorFlow2.0实现了最前沿的深度学习模型,通过精心设计的框架支撑下游NLP任务,在海量语料库上取得了最前沿的准确率。作为第一个alpha版本,HanLP 2.0.0a0支持分词、词性标注、命名实体识别、依存句法分析、语义依存分析以及文本分类。而且,这些功能并不仅限中文,而是面向全人类语种设计。HanLP2.0提供许多预训练模型,而终端用户仅需两行代码即可部署,深度学习落地不再困难。更多详情,欢迎观看HanLP2.0的介绍视频,或参与论坛讨论。
展望未来,HanLP2.0将集成1.x时代继承下来的高效率务实风范,同时冲刺前沿研究,做工业界和学术界的两栖战舰,请诸君继续多多指教,谢谢。
注意事项
请确认下列注意事项:
版本号
当前最新版本号是: 我使用的版本是:
我的问题
请问有没有对比hanlp的分词效果在sighan2005公共数据集上的表现?谢谢~