Как правильно передать разделенную функцию на уровень TextVectorization

python #tensorflow #keras

#python #tensorflow #keras #nlp

Вопрос:

Я определяю пользовательский вызываемый разделитель для TextVectorization следующим образом:

 import tensorflow as tf
from tensorflow import keras
@tf.function
def split_slash(input_str):
  return tf.strings.split(input_str, sep="/")
inputs = ["text/that/has/a","lot/of/slashes/inside","for/testing/purposes/foo"]
input_text_processor = keras.layers.TextVectorization(max_tokens=13, split = split_slash)
    
input_text_processor.adapt(inputs)
example_tokens = input_text_processor(inputs)
print(example_tokens)
for x in inputs:
  print(split_slash(x))
 

в результате:

 tf.Tensor(
[[2]
 [3]
 [4]], shape=(3, 1), dtype=int64)
tf.Tensor([b'text' b'that' b'has' b'a'], shape=(4,), dtype=string)
tf.Tensor([b'lot' b'of' b'slashes' b'inside'], shape=(4,), dtype=string)
tf.Tensor([b'for' b'testing' b'purposes' b'foo'], shape=(4,), dtype=string)
 

как видно выше, функция разделения корректно работает вне уровня TextVectorization, но завершается сбоем при передаче в качестве вызываемого

Ответ №1:

Ваша split_slash функция, похоже, неправильно маркирует фразы.

 print(f"Vocabulary:tt{input_text_processor.get_vocabulary()}")
'''
Vocabulary:['', 
           '[UNK]', 
           'textthathasa', 
           'lotofslashesinside', 
           'fortestingpurposesfoo']
'''
 

Вероятно, это связано с тем, что ваш TextVectorization слой удаляет из ваших фраз все знаки препинания, в том числе / по умолчанию, перед вызовом вашей split_slash функции. Настройка standardize=None в вашем TextVectorization слое сделает все за вас.

В качестве альтернативы вы также можете попробовать следующий фрагмент.

 import tensorflow as tf

def custom_standardization(input_data):
  return tf.strings.regex_replace(input_data, '/', ' ')

inputs = ["text/that/has/a","lot/of/slashes/inside","for/testing/purposes/foo"]

input_text_processor = tf.keras.layers.TextVectorization(max_tokens=13, standardize=custom_standardization) #split = split_slash)

input_text_processor.adapt(inputs)
print(f"Vocabulary:tt{input_text_processor.get_vocabulary()}")
example_tokens = input_text_processor(inputs)

print(example_tokens)
for x in inputs:
  print(split_slash(x))
 

Обратите внимание, что ваши фразы разделяются whitespace по умолчанию после удаления косых черт.

 '''
Vocabulary:     ['', '[UNK]', 'that', 'text', 'testing', 'slashes', 'purposes', 'of', 'lot', 'inside', 'has', 'for', 'foo']
tf.Tensor(
[[ 3  2 10  1]
 [ 8  7  5  9]
 [11  4  6 12]], shape=(3, 4), dtype=int64)
tf.Tensor([b'text' b'that' b'has' b'a'], shape=(4,), dtype=string)
tf.Tensor([b'lot' b'of' b'slashes' b'inside'], shape=(4,), dtype=string)
tf.Tensor([b'for' b'testing' b'purposes' b'foo'], shape=(4,), dtype=string)
'''
 

Для получения дополнительной информации ознакомьтесь с документацией.