Closed YourThomasLee closed 4 years ago
你好! 一,只要能生成所有模型需要的文件并可以执行训练就可以,没有特定的顺序。你的问题可能在于使用cpu训练,这是我们没有考虑过的情况。我建议尝试使用mxnet1.1.0版本和cuda8.0的gpu环境进行训练。 二,预处理部分事实上你只需要阅读mat_data.py的genTurnData_nbest函数就好,因为*tagged.json这类文件合并了tagged的数据和没有tagged的数据,而我们在训练时事实上并没有使用tagged部分的数据,只是作为legacy data被保留了下来。
非常感谢作者大大的回应,在环境配置方面,今日我在服务器上创建了python2的虚拟环境,因为cuda驱动版本10.1,所以配置了mxnet-cu101==1.5.1.post0(小的心里暗自揣摩应该不影响的)。之后生成了模型依赖的文件,之后就是执行train_dstc(0):
执行train_dstc(1)的结果:
我发现在模型进行初始化后第0个epoch和第1个epoch上在custom accuarcy上是有变化的,但是经历一个轮次的训练后发现训练测试上的custom accuracy上再也没变化过了,由于我也没有深入去看整个模型的代码,是否有可能在我生成*_nbest.json上出现了问题呢?在生成相应依赖文件上是否有需要注意的地方呢?再次谢谢作者大大的回应
事实上你可以直接查看*_nbest.json和embed_vN3.npy的内容,如果有明显的能导致训练无法进行的问题,你应该立即可以发现。mxnet自从加入Amazon开始每一代的变动都很大,当初我们也遇到过升级到1.2版本后模型预测精度发生变化的问题,所以framework的版本事实上会很有影响。我现在苦于没有cuda8.0环境而无法对代码进行维护(因为该项目开源是在我离开交大实验室环境之后),因此我的建议是首先请你确认生成的依赖文件没有肉眼可见的问题,然后配置一个cuda8.0环境,如果在这种情况下仍无法复现模型,请务必联系我,我可以提供在线debug。 之前也有大量同行通过邮件询问我复现相关的问题,然而在我一一回复后,他们也并未告知是否复现成功。非常感谢你能提出这个issue,我也希望这次对复现的问题能有一个清晰的答复,能将问题就此终结。 保持联系!
得到作者大大的回复,简单查看了下_nbest.json文件没有发现问题后,我立刻搞了一波docker,得到docker镜像容器环境配置如下 而后执行train_dstc(1)运行结果截图如下 customAcc确实有变化,但是大概从epoch6左右后就再也没有变化了,不知道咋回事,开始秃头
等一下,所以你是使用的_nbest.json文件吗?如果是的话,请尝试使用_nbest_tagged.json文件。因为在mat_io.py中会索引前半部分未tagged的文件,如果使用_nbest.json, 那么只会在一个sample上训练。https://github.com/renll/StateNet/blob/a1e41c0f7b1b885e8832f4e53f54e97bb01219f4/mat_io.py#L117
我猜测应该是数据配置的问题,稍后仔细看下模型中数据的配置吧,代码写有点乱,看的有点头晕,谢谢作者大大的回复
看了下,modSel=1,相应配置如下: elif modSel==1: offline_config_dict = { 'nn_type': 'doublelstm', 'model_dir': os.path.join(cur_dir, 'models_dstc_caplstmSCLT'), 'train_json': os.path.join(cur_dir, 'train_nbest_tagged.json'), 'dev_json': os.path.join(cur_dir, 'dev_nbest_tagged.json'), 'test_json': os.path.join(cur_dir, 'test_nbest_tagged.json') } 细致查看作者大大指示的函数代码并在末尾增加代码如下: 输出如下: 可以看到各项变量长度为1612,确实是dstc2数据集中训练部分数据的长度。看了下doblelstm模型代码的调用有点乱,因为我做的也是对话状态跟踪,近期打算写个repo复现下这个模型,如果有不懂的可以请教作者大大么?
没问题,辛苦你了!
作者大大好,我来请教问题了,关于输入输出有几个地方上理解有些不清楚。先把架构图放上来 $r_u^n$是用户话语的表示,$r_a^m$是机器动作的表示,$s$是槽的表示,$V_s$是槽s可取的值集合
输入主要三部分组成,用户话语,机器动作,槽位状态。我的疑问挺多的,作者大大有空解答就行,我不急,再次谢谢作者大大
stateNet模型的输入为nbest_tagged.json文件,该文件内容生成的入口代码
elif output_type == 'nbest_tagged':
data = []
res_data1 = gen_data(genTurnData_nbest)
data.append(res_data1)
res_data2 = gen_data(genTurnData_nbest_tagged)
data.append(res_data2)
res_data = data
tagged.json文件与非tagged文件内容的差异之处由于多调用了genTurnData_nbest_tagged, 方便作者大大查看,直接贴函数代码到这里了:
def genTurnData_nbest_tagged(turn, labelJson):
turnData = genTurnData_nbest(turn, labelJson)
turnData = tagTurnData_matFS(turnData, ontologyDict)
return turnData
该函数中调用的第二个函数tagTurnData_matFS函数,该函数的内容如下
def tagTurnData_matFS(turnData, ontology):
"""将一个turn的数据进行tag替换"""
tagged_turnData = copy.deepcopy(turnData)
tag_dict = {}
for slot in ["food", "name"]:
for slot_val in ontology["informable"][slot]:
if slot_val.startswith("#%s"%slot):
continue
cur_tag = "#%s#" % (slot,)
replace_flag = False
# process user_input
for i in xrange(len(tagged_turnData["user_input"])):
sentence = tagged_turnData["user_input"][i]['asr-hyp']
tag_sentence = sentence.replace(slot_val, cur_tag)
if tag_sentence != sentence:
tagged_turnData["user_input"][i]['asr-hyp'] = tag_sentence
tag_dict[cur_tag] = slot_val
replace_flag = True
# process machine_output
for act in tagged_turnData["machine_output"]:
for pair in act["slots"]:
if len(pair) >= 2 and pair[0] == slot and pair[1] == slot_val:
pair[0] = "#slot#"
pair[1] = cur_tag
tag_dict[cur_tag] = slot_val
replace_flag = True
for i in xrange(len(tagged_turnData["user_input"])):
sentence = tagged_turnData["user_input"][i]['asr-hyp']
tag_sentence = sentence.replace(slot, "#slot#")
return tagged_turnData
我主要想确认下该函数是否将所有轮次对话数据中的ASR模块输出内容、策略模块输出的动作与food、name槽有关的信息打上标记,如果是的话,从代码上可以看出打上标签的数据是直接缀加到未打标记数据上的,那么在训练中是否有使用到这部分标签呢?如果使用了是如何使用的呢(因为没有仔细看后面的模型,复现时候又需要用到,所以来问作者大大了)。
这里主要是确认下,例如对于food槽位,那么架构图中的s就是food的词向量,对于pricerange槽位,架构图中的s就是price的词向量和range的词向量的和
论文中对于动作表示的描述如下,我对字典是怎么做的没有看明白,the m order n-gram of bag of words这个东西不咋明白,对于bag of words来说应该是无序的,可是前面的the m order n-gram我觉得是在有序的基础上的定义的概念,不太明白,我猜词典应该是vocab_actN.dict文件,可我不太清楚咋处理出来的。
总结下:请教对话动作是怎么表示的?vocab_actN.dict是怎么构建的呢?对应的py文件和相应的函数是哪一个呢?顺便请教作者大大vocab_matNN.dict的生成方法和相应的函数
对于dstc2数据,该数据包含三种标签,分别是goal(food, pricerange, name, area),method,request slots, 在代码里我看到将goal,method的标签值转化成了ontology里的下标索引,而对于request slots则采用了one-hot的编码。在论文中对于目标槽的描述如下:
架构图中的$V_s$的设定在文中描述是使用槽可取值的词向量,词向量的维度是300维
我在这里确认下stateNet中是否将request slot和method作为了预测目标之一。如果将request slot和method作为了预测目标,假设将method和request slots看作是槽,那么request slots的可取值的表示使用了one hot编码,与method、goal_food的槽值对应的词向量维度存在不一致在模型中是如何解决的呢?
谢谢作者大大的回应一定要加粗!【手动配图 :)】
1.1 没有用到tagged数据, dataIdx我们只用了0,就是没有tagged的部分。https://github.com/renll/StateNet/blob/a1e41c0f7b1b885e8832f4e53f54e97bb01219f4/mat_io.py#L79 1.2 对 1.3 这个就是m-gram词袋, 这里我们使用m=3。已上传extract_vocab.py,当初没有上传的原因是unicode编码格式有点问题,所以使用时请首先确认生成的文件和repo中已有的dict是匹配的。
作者大大新年好!我这边使用了上传后的extract_vocab.py成功生成了vocab_matNN.dict, 目前在处理生成vocab_actN.dict上遇到了困难,使用代码如下
#生成mat_actN.dict代码,使用训练集上的act生成act_words然后输出
act_bag=dict()
for call in train_data:
for turn, label in call:
# dialog acts
# act: {'slots': [['pricerange', 'moderate'], ['food', 'swedish']], 'act': 'canthelp'}
# act_words: canthelp pricerange moderate food swedish
machine_act_words = []
for act_item in turn["output"]["dialog-acts"]:
if "act" in act_item:
machine_act_words.append(act_item["act"])
if "slots" in act_item:
for item in act_item["slots"]:
for item_val in item:
machine_act_words.append(item_val)
machine_act = ' '.join(machine_act_words)
act_bag=add_words_2_vocab(machine_act,act_bag,N=3)
joblib.dump(word_bag,CUR_DIR+'/vocab_act_3_gram.dict')
def add_word_2_vocab(word:str,vocab:dict)->dict:
vocab[word]=vocab.get(word,0)+1 # word, frequency
return vocab
def add_words_2_vocab(words:str,vocab:dict,N=1)->dict:
words=words.strip()
if len(words)==0: return vocab
word_list=words.split()
for word in [' '.join(word_list[i:min(i+N,len(word_list))]) for i in range(max(1,len(word_list)-N+1))]:
add_word_2_vocab(word,vocab)
return vocab
vocab_act3=joblib.load(CUR_DIR+'/vocab_act_3_gram.dict')
vocab_actN=pickle.load(open(CUR_DIR+'/vocab_actN.dict','rb'))#项目中的文件
print(len(vocab_actN),len(vocab_act3))
print(vocab_act3.keys()==vocab_actN.keys())
输出如下
1273 1417 False
请教的问题有两个,第一个是vocab_actN.dict生成方法和流程是怎样的呢;第二个是我想确认对话动作表示是否就是基于构造词典的one-hot编码表示,还是使用n-gram中所有单词对应的词向量之和作为对话动作的表示(主要是论文里动作$r_a^m$表示和用户话语$r_u^n$表示上特别相似,所以特意问下)
您好
我最近也遇到类似问题,训练的结果没有变化,且测试和验证上的结果都为零。
目前我使用的环境是 python 2.7 mxnet-cu80==1.1.0 其他没有太大的 变化。
数据是dstc2, 运行get_embedding.py获取到embed_vN3.npy词向量文件文件后,执行mat_data.py获取了test_nbest.json、test_nbest_tagged.json、train_nbest.json、train_nbest_tagged.json、dev_nbest.json、dev_nbest_tagged.json后
您在上面的回答中提到,对比*_nbest.json, 和embed_vN3.npy 的内容,这里不明白如何去对比。请指教。
不知道我为啥不能上传图片, 总之结果和上面的小哥很相似。
@BrickLee 1.通过修改extract_vocab.py就可以生成。取消注释64-68行并注释掉106-118行大概就可以了。 2.与词向量无关,就是个vocab大小的词袋。具体可以查看如下函数: https://github.com/renll/StateNet/blob/d0860408a4541f5212f4ac48c9974a1806c9c815/mat_io.py#L178
@igorhuangchao 没有对比,就是简单查看一下这两个文件有没有明显不合理的地方(比如词向量都是零之类的)。
作者大大好,我直接下载了整个项目,运行get_embedding.py获取到embed_vN3.npy词向量文件文件后,执行mat_data.py获取了test_nbest.json、test_nbest_tagged.json、train_nbest.json、train_nbest_tagged.json、dev_nbest.json、dev_nbest_tagged.json后,运行offline_model_dstc中的函数train_dstc2(1),更改设置了变量ctx='cpu',但运行多个epoch后发现评价指标并没有发生变化,以下为运行的部分输出:
我现在有两个请求,如果能够得到作者的回应对我的研究有莫大的帮助!如下 第一,能简述下复现模型的步骤么?(先执行哪一个文件后执行哪一个文件) 二,能简述下项目中数据预处理的文件么?(数据预处理的大致功能效果) 不论是否能够得到解答,感谢作者的代码贡献和分享!