yangheng95/LCF-ATEPC

请教关于lcf_atepc.py相关细节?

zhhhzhang opened this issue · 7 comments

def forward(self, input_ids_spc, token_type_ids=None, attention_mask=None, labels=None, polarities=None, valid_ids=None, attention_mask_label=None):

    if not self.args.use_bert_spc:  # args.use_bert_spc=false
        input_ids_spc = self.get_ids_for_local_context_extractor(input_ids_spc)
        labels = self.get_batch_token_labels_bert_base_indices(labels)

    global_context_out, _ = self.bert(input_ids_spc, token_type_ids, attention_mask)  
    polarity_labels = self.get_batch_polarities(polarities)  

问题1:
use_bert_spc = False,已经将convert BERT-SPC input to BERT-BASE format,如果一个句子包含了多个aspect,但是 BERT-BASE format得到的句子表示都是一样的,在ATE任务时,怎么区分出不同的aspect?
self.bert(input_ids_spc, token_type_ids, attention_mask)
但是此处的token_type_ids, attention_mask,并没有做任何修改,可以在计算attention的时候包含了第一个[SEP]后面的aspect的信息? 可以这么理解吗?,

问题2:
readme.md中,BERT-SPC不能被用于训练和测试ATE任务,这句话怎么理解?

问题3:
在做ATE任务的时候 ,为什么labels=["O", "B-ASP", "I-ASP", "[CLS]", "[SEP]"],为什么要加上cls和sep? 以及为什么num_labels = len(label_list) + 1 不太理解?

问题4:
report = classification_report(y_true, y_pred, digits=4)
tmps = report.split()
ate_result = round(float(tmps[7]) * 100, 2)

report 是各个类别评价指标,这里为什么只取tmps[7])?只取第一个类别? 这段代码该怎么理解?
不好意思,我看错了 from seqeval.metrics 这个函数直接算的就是f1?

问题有点多,还请不吝赐教!
谢谢啦

你好

问题1和问题2: 首先,如README所述,考虑ATE子任务的可靠性问题,不会使用BERT-SPC的输入形式具体原因是BERT-SPC要求在句尾添加aspect,但联合训练ATE时不能提供aspect,因为ATE的目的是标注aspect。因此[SEP]后不会有额外的aspect,即考虑ATE时只采用BERT-BASE的输入形式。而在做ATE时,会将所有的aspect一视同仁,不加区别。但是APC任务会考虑具体的apesct。

问题3: 标注aspcet时除了"O", "B-ASP", "I-ASP",三个标签,还考虑到了[CLS],[SEP]两个标签,这个属于方案设计问题,也可以将[CLS],[SEP]以“O”代替。

问题4:该评估代码会输出计算F1的matrices,ate_result = round(float(tmps[7]) * 100, 2)的作用是取出matrices中的F1值(tmps[7]),你可以尝试直接打印report查看。

没有问题,不需要刻意避免aspect在注意力中的训练。+1是考虑到可能存在的填充,因为相关代码中标注tag时从1开始

label_map = {label : i for i, label in enumerate(label_list,1)}
)
这个参考了大多数BERT模型做序列标注中的做法。

这两行代码在先前提交的版本中已经被修改,默认都替换为‘O’,请合并最新代码。经实验,替换为1或者’O‘不会直接影响模型效果。这两行代码。最开始模型输出的预测标签可能不在标签映射表中,例如输出0,而标签映射表从1开始映射。