Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 部分重叠批次的映射预测_Python_Keras_Scikit Learn_Nlp_Pytorch - Fatal编程技术网

Python 部分重叠批次的映射预测

Python 部分重叠批次的映射预测,python,keras,scikit-learn,nlp,pytorch,Python,Keras,Scikit Learn,Nlp,Pytorch,我正在与pytorch_pretrained_bert for NER合作,基于此处提供的实现: 当对较长文本进行预测时,bert.py中的predict函数返回索引外错误。我目前的理解是,这是由于bert标记的nr(不一定相同,事实上在许多情况下与例如nltk.word_tokenize()returns)的标记数量不同)由输入文本组成。如果超过512(因为这是预先训练的模型的默认长度,如果我理解正确的话),它将返回此错误(并且对于较短的输入工作正常)。 因此,我决定实现一个包装器,如果我有比

我正在与pytorch_pretrained_bert for NER合作,基于此处提供的实现:

当对较长文本进行预测时,
bert.py
中的
predict
函数返回索引外错误。我目前的理解是,这是由于bert标记的nr(不一定相同,事实上在许多情况下与例如
nltk.word_tokenize()
returns)的标记数量不同)由输入文本组成。如果超过512(因为这是预先训练的模型的默认长度,如果我理解正确的话),它将返回此错误(并且对于较短的输入工作正常)。 因此,我决定实现一个包装器,如果我有比512更多的bert标记(即bert自己的标记器返回的东西),它将生成部分重叠的批。重叠是需要的,因为只需将其分割成几块,填充最后一块(因为我的标记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\u batches
应该可以做到这一点。输入列表仅部分重叠;对于列表
a
中的前两项,我只有一个预测(a本身的预测)。然后对于接下来的6个标记,我有两个预测,分别对应于
a[2://code>和
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或其他常见的可疑软件中有哪些实现吗