Обнимающее лицо: токенизатор для вопроса в маске lm

Я использую для своего проекта трансформатор версии 3.0.0, и у меня есть вопросы.

Я хочу использовать модель Берта с замаскированной предтренингом ПМ для последовательностей белков. Чтобы получить токенизатор уровня персонажа, я получил от BertTokenizer

from transformers import BertTokenizer
class DerivedBertTok(BertTokenizer):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def tokenize(self, text):
        if isinstance(text, np.ndarray):
            assert len(text) == 1
            text = text[0]
        return [x if x in self.vocab else self.unk_token for x in text]

мой словарь выглядит так

[PAD]
[CLS]
[SEP]
[UNK]
[MASK]
A
R
N
D
B
C
E
Q
Z
G
H
I
L
K
M
F
P
S
T
W
Y
V

Использование похоже на то, что я видел в документации:

d_tokenizer = DerivedBertTok(
    vocab_file=vocab_path,
    do_lower_case=False,
    do_basic_tokenize=False,
    tokenize_chinese_chars=False
)
d_tokenizer.encode_plus(np.array(["AXEF"])[0], 
                      max_length=20,
                      pad_to_max_length=True,
                      add_special_tokens=True,
                      truncation=True,
                      return_tensors='pt')

Исходя из этого, я создавал набор данных pytorch с настраиваемой функцией сопоставления. все, что делает функция сопоставления, берет все входные тензоры и складывает их

from transformers import BatchEncoding
    def collate_fn(self, batch):
        # this function will not work for higher dimension inputs
        elem = batch[0]
        elem_type = type(elem)
        if isinstance(elem, BatchEncoding):
            new_shapes = {key: (len(batch), value.shape[1]) for key, value in elem.items()}
            outs = {key: value.new_empty(new_shapes[key]) for key, value in elem.items()}
            if torch.utils.data.get_worker_info() is not None:
                [v.share_memory_() for v in outs.values()]
            return {key: torch.stack(tuple((d[key].view(-1) for d in batch)), 0, out=outs[key]) for key in elem.keys()}
        else:
            raise ValueError(f"type: {elem_type} not understood")

Вопрос 1. Мне было интересно, может ли BatchEncoding или другой класс уже это делать (и, возможно, делать это лучше?). Или вообще использовать другой класс Dataset / DataLoader.

Вопрос 2: Кроме того, я хочу замаскировать некоторые входы, как это требуется для замаскированного LM, однако мне не удалось найти какую-либо реализацию в библиотеке преобразователя. Есть какие-то рекомендации по этому поводу?


person sheming    schedule 06.07.2020    source источник


Ответы (1)


Еще немного покопавшись, я нашел DataCollator, который реализует замену токена случайным образом токеном маски по адресу: https://github.com/huggingface/transformers/blob/615be03f9d961c0c9722fe10e7830e011066772e/src/transformers_collator/data/data/data/#L69. Поэтому я изменил свой DataSource, чтобы он возвращал необработанный текст вместо BatchEncoding в методе __getitem__, а затем выполнял кодирование и маскирование в функции сопоставления.

person sheming    schedule 17.07.2020