部分重叠批次的映射预测

时间:2019-08-16 14:20:19

标签: python keras scikit-learn nlp pytorch

我正在根据此处提供的实现使用pytorch_pretrained_bert for NER:https://github.com/kamalkraj/BERT-NER

在对较长的文本进行预测时,其中predict中的bert.py函数将返回索引不足错误。我目前的理解是,这是由于伯特令牌的nr个(不一定相同,而且实际上在许多情况下与ex。nltk.word_tokenize()返回的令牌数目不同)导致输入文本。如果超过512(如果我正确理解的话,这是预训练模型的默认长度),它将返回此错误(并且对于较短的输入也适用)。 因此,我决定实施一个包装器,以防万一我拥有的bert令牌(即bert自己的令牌生成器返回的东西)多于512个,则会生成部分重叠的批处理。需要重叠,因为只是将其切成小块,填充最后一个(因为不太可能将我的令牌的nr数除以512,因此最后一个较短的令牌将需要填充)会丢失上下文。但是,这意味着我必须分批进行预测,然后再将它们放回去。

将其切成批次(长度为512)非常简单。我目前正在将预测部分放在一起。 为此,我编写了以下代码:

def map_batches(batches, blen):
    master = []
    for i in range(len(batches)-1):
        appendbatch = []
        # if first round, append first bit of current batch with only one prediction
        if i == 0:
            appendbatch = batches[0][:int(blen/2)-1]
        thisbatch = batches[i]
        nextbatch = batches[i+1]
        offset = int(blen/2)-1 # think -1 is needed for zero offsetting, but not sure, test/debug!
        for j in range(offset, blen-offset+2): # and debug +2 here too!
            thistuple = thisbatch[j]
            nexttuple = nextbatch[j-offset]
            if thistuple[1] > nexttuple[1]:
                thisbatch[j] = thistuple
            else:
                thisbatch[j] = nexttuple
        appendbatch.extend(thisbatch[int(blen/2)-1:])
        # and at end add last bit of last batch with only one prediction
        if i == len(batches)-2:
            appendbatch.extend(nextbatch[int(blen/2)+1:])
        master.append(appendbatch)
    return master

blen = 6
a = [('I-LOC', 0.1),
     ('O', 0.2),
     ('I-LOC', 0.5),
     ('O', 0.2),
     ('I-LOC', 0.9),
     ('O', 0.1)]

b = [('B-LOC', 0.6),
     ('O', 0.7),
     ('I-LOC', 0.8),
     ('O', 0.9),
     ('O', 0.99),
     ('O', 0.99)]
correct = [[('I-LOC', 0.1), ('O', 0.2), ('B-LOC', 0.6), ('O', 0.7), ('I-LOC', 0.9), ('O', 0.9), ('O', 0.99), ('O', 0.99)]]
batches = [a, b]
master = map_batches(batches, blen)
print('mapped: ', master)
print('correct:', correct)

函数map_batches应该可以解决问题。输入列表仅部分重叠;对于列表a中的前2个项目,我只有一个预测(本身的预测)。然后对于接下来的6个令牌,我有两个预测,分别对应于a[2:]b[:6]。最后2个,我只有b个。该函数应该将它们放在一起,基于它的可能性最高(在这里,组成数字,在真实代码中,这些当然是标签的置信度得分)。

检查一下我的玩具示例a和b,它是否有效,即上面的输出是:

  

映射:[[('I-LOC',0.1),('O',0.2),('B-LOC',0.6),('O',0.7),('I-LOC', 0.9),('O',0.9),('O',0.99),('O',0.99)]]

     

正确:[[('I-LOC',0.1),('O',0.2),('B-LOC',0.6),('O',0.7),('I-LOC', 0.9),('O',0.9),('O',0.99),('O',0.99)]]

很抱歉,很长的介绍。

现在是问题:

首先,将它们放在一起很快。虽然它适用于我的玩具示例,但我有点担心它可能在所有情况下(批次大小不同等)都是不正确的(因此提供了调试/测试的注释),并且我计划进行更多调试。尽管如此,对此问题的任何想法或建议都将受到欢迎!

第二,我猜是一个真正的问题:我怀疑这是一个很早就已经有人解决的问题(可能以一种更好,更有效的方式)。谁会知道在keras,tensorflow,numpy,sklearn或任何其他常见嫌疑犯中对此实现的任何实现吗?

0 个答案:

没有答案