#python-3.x #tensorflow #keras #nlp #tensorflow2.0
#python-3.x #тензорный поток #keras #nlp #tensorflow2.0
Вопрос:
У меня проблема, когда, учитывая набор токенов, предсказать другой токен. Для этой задачи я использую слой встраивания с Vocab-size 1
as input_size
. Это 1
потому, что последовательности дополняются нулями. Например. учитывая Vocab-size
значение 10 000 и max_sequence_len=6
, x_train
похоже:
array([[ 0, 0, 0, 11, 22, 4],
[ 29, 6, 12, 29, 1576, 29],
...,
[ 0, 0, 67, 8947, 7274, 7019],
[ 0, 0, 0, 15, 10000, 50]])
y_train
состоит из целых чисел от 1 до 10000, другими словами, это становится проблемой классификации нескольких классов с 10000 классами.
Моя проблема: когда я указываю размер вывода в выходном слое, я хотел бы указать 10000, но модель будет предсказывать классы 0-9999, если я это сделаю. Другой подход заключается в том, чтобы установить размер вывода равным 10001, но тогда модель может предсказать 0-класс (заполнение), что нежелательно.
Поскольку y_train
отображается от 1 до 10000, я мог бы переназначить его на 0-9999, но поскольку они совместно используют сопоставление с вводом, это кажется ненужным обходным путем.
РЕДАКТИРОВАТЬ:
я понимаю, и на что @Andrey указал в комментариях, что я мог бы разрешить 10001 классов и просто добавить дополнение к словарю, хотя меня никогда не интересуют сетевые прогнозы 0
.
Как я могу указать модели прогнозировать метки 1-10000, в то же время имея 10000 классов, а не 10001?
Комментарии:
1. Я обычно устанавливаю vocab_size равным 10001, и я никогда не видел, чтобы модель предсказывала 0
2. На самом деле, мой vocab_size намного больше, и я использую вероятности top-k в своем варианте использования, поэтому на самом деле (очень редко) случается, что 0 является частью прогнозов top-k: (
3. Я бы добавил символ заполнения в конец vocab и исправил форму вывода как 10000 (не len (vocab) = 10001)
4. Или я бы добавил заполнение в качестве дополнительного ввода (вместо использования специального символа vocab)
Ответ №1:
Я бы использовал следующий подход:
import tensorflow as tf
inputs = tf.keras.layers.Input(shape=())
x = tf.keras.layers.Embedding(10001, 512)(inputs) # input shape of full vocab size [10001]
x = tf.keras.layers.Dense(10000, activation='softmax')(x) # training weights based on reduced vocab size [10000]
z = tf.zeros(tf.shape(x)[:-1])[..., tf.newaxis]
x = tf.concat([z, x], axis=-1) # add constant zero on the first position (to avoid predicting 0)
model = tf.keras.Model(inputs=inputs, outputs=x)
inputs = tf.random.uniform([10, 10], 0, 10001, dtype=tf.int32)
labels = tf.random.uniform([10, 10], 0, 10001, dtype=tf.int32)
model.compile(loss='sparse_categorical_crossentropy')
model.fit(inputs, labels)
pred = model.predict(inputs) # all zero positions filled by 0 (which is minimum value)
Комментарии:
1. Я ценю постоянные усилия, и это может быть наилучшим возможным решением, хотя я бы надеялся на то, что модификация будет связана с моделью keras, а не с данными. Это связано с тем, что, если я сохраняю модель для последующего использования мной или кем-то еще, пользователь должен помнить, что выходные и входные данные не совпадают, и не может забыть изменить прогнозы на
pred = 1
.2. Этот ответ мне нравится — первый (неиспользуемый) блок вывода всегда будет иметь вероятность 0. Получение argmax прогнозов приведет к получению желаемого класса.