Отображение текстовых данных через токенизатор huggingface - PullRequest
2 голосов
/ 02 мая 2020

У меня есть моя функция кодирования, которая выглядит следующим образом:

from transformers import BertTokenizer, BertModel

MODEL = 'bert-base-multilingual-uncased'
tokenizer = BertTokenizer.from_pretrained(MODEL)

def encode(texts, tokenizer=tokenizer, maxlen=10):
#     import pdb; pdb.set_trace()
    inputs = tokenizer.encode_plus(
        texts,
        return_tensors='tf',
        return_attention_masks=True, 
        return_token_type_ids=True,
        pad_to_max_length=True,
        max_length=maxlen
    )

    return inputs['input_ids'], inputs["token_type_ids"], inputs["attention_mask"]

Я хочу закодировать свои данные на лету, выполнив это:

x_train = (tf.data.Dataset.from_tensor_slices(df_train.comment_text.astype(str).values)
           .map(encode))

Однако, это бросает ошибка:

ValueError: Input is not valid. Should be a string, a list/tuple of strings or a list/tuple of integers.

Теперь, насколько я понимаю, когда я установил точку останова внутри encode, это произошло потому, что я отправлял массив не numpy. Как заставить преобразователи с обнимающимися лицами хорошо играть со строками тензорного потока в качестве входных данных?

Если вам нужен фиктивный фрейм данных, вот он:

df_train = pd.DataFrame({'comment_text': ['Today was a good day']*5})

Что я пробовал

Итак Я попытался использовать from_generator, чтобы я мог разобрать строки в функции encode_plus. Однако это не работает с TPU.

AUTO = tf.data.experimental.AUTOTUNE

def get_gen(df):
    def gen():
        for i in range(len(df)):
            yield encode(df.loc[i, 'comment_text']) , df.loc[i, 'toxic']
    return gen

shapes = ((tf.TensorShape([maxlen]), tf.TensorShape([maxlen]), tf.TensorShape([maxlen])), tf.TensorShape([]))

train_dataset = tf.data.Dataset.from_generator(
    get_gen(df_train),
    ((tf.int32, tf.int32, tf.int32), tf.int32),
    shapes
)
train_dataset = train_dataset.batch(BATCH_SIZE).prefetch(AUTO)

Информация о версии:

transformers.__version__, tf.__version__ => ('2.7.0', '2.1.0')

1 Ответ

1 голос
/ 02 мая 2020

Когда вы создаете набор данных tenorflow с помощью: tf.data.Dataset.from_tensor_slices(df_train.comment_text.astype(str).values) тензор потока преобразует ваши строки в тензоры типа строки, который не является допустимым вводом tokenizer.encode_plus . Как сообщение об ошибке говорит, что он принимает только a string, a list/tuple of strings or a list/tuple of integers. Вы можете проверить это, добавив print(type(texts)) внутри вашей функции кодирования (Выход: <class 'tensorflow.python.framework.ops.Tensor'>).

Я не уверен, каков ваш план последующих действий и почему вам нужен tf.data.Dataset, но вы необходимо кодировать ваш вход, прежде чем превратить его в tf.data.Dataset:

import tensorflow as tf
from transformers import BertTokenizer, BertModel

MODEL = 'bert-base-multilingual-uncased'
tokenizer = BertTokenizer.from_pretrained(MODEL)

texts = ['Today was a good day', 'Today was a bad day',
       'Today was a rainy day', 'Today was a sunny day',
       'Today was a cloudy day']


#inputs['input_ids'], inputs["token_type_ids"], inputs["attention_mask"]
inputs = tokenizer.batch_encode_plus(
        texts,
        return_tensors='tf',
        return_attention_masks=True, 
        return_token_type_ids=True,
        pad_to_max_length=True,
        max_length=10
    )

dataset = tf.data.Dataset.from_tensor_slices((inputs['input_ids'],
                                              inputs['attention_mask'],
                                              inputs['token_type_ids']))
print(type(dataset))

Выход:

<class 'tensorflow.python.data.ops.dataset_ops.TensorSliceDataset'>
...