#python #tensorflow #keras
#python #тензорный поток #keras
Вопрос:
Я немного смущен написанием слоя Keras, следуя лучшим методам. Такое ощущение, что есть немного дублирующегося кода и дублирующейся конфигурации.
В частности, моя цель — объединить несколько существующих слоев вместе. Объединение будет использоваться для облегчения обучения передаче и визуальной проверки / отладки модели. Примером кода является:
import tensorflow.keras as keras
class CategoricalEmbedding(keras.layers.Layer):
def __init__(self, vocabulary, embedding_dimensions, embedding_matrix, **kwargs):
self.lookup = keras.layers.experimental.preprocessing.IntegerLookup(
num_oov_indices=1, mask_value=None, vocabulary=vocabulary
)
self.embedding = keras.layers.Embedding(
len(vocabulary) 1, embedding_dimensions, input_length=1,
weights=[embedding_matrix]
)
super(CategoricalEmbedding, self).__init__(**kwargs)
def call(self, categorical_ids):
indexes = self.lookup(categorical_ids)
embeddings = self.embedding(indexes)
resized = K.squeeze(embeddings, -2)
return resized
def get_config(self):
return {
"vocabulary": self.lookup.get_vocabulary(),
"embedding_dimensions": self.embedding.output_dim,
"embedding_matrix": self.embedding.weights[0],
**super(CategoricalEmbedding, self).get_config()
}
Мои две проблемы с приведенным выше кодом — это требование написать get_config()
и дублирующаяся информация, которая уже содержится в weights / config подуровня. В частности, вся информация, необходимая для восстановления CategoricalEmbedding
слоя, существует в подуровнях IntegerLookup
и Embedding
. Ручная запись get_config()
может привести к дефектам. Кроме того, IntegerLookup.vocabulary
будет сериализован в двух местах — одно в weights / config IntegerLookup
и одно в config CategoricalEmbedding
. Поскольку vocabulary
значения могут составлять миллионы, дополнительные затраты на настройку не являются несущественными.
Другой способ — не используйте Keras Layer, вместо этого используйте Keras Model:
import tensorflow.keras as keras
def categorical_embedding(vocabulary, embedding_dimensions, embedding_matrix, name=None):
model_name = name if name is not None else "categorical_embedding"
lookup = keras.layers.experimental.preprocessing.IntegerLookup(
num_oov_indices=1, mask_value=None, vocabulary=vocabulary
)
lookup.weights[0].name = "lookup_weights" # fix for serialization issue
embedding = keras.layers.Embedding(
len(vocabulary) 1, embedding_dimensions, input_length=1, weights=[embedding_matrix]
)
squeeze = keras.layers.Lambda(lambda net: K.squeeze(net, -2), name="squeeze_to_one_embedding")
return keras.Sequential([lookup, embedding, squeeze], name=model_name)
Это лучший способ написать вышеупомянутый слой Keras? Следует ли использовать слой Keras для такой простой композиции? Есть ли лучший способ написать уровень Keras для снижения затрат на код и / или сериализацию / хранение? Следует ли использовать модели Keras таким образом? (Я упускаю что-то фундаментальное?)
Комментарии:
1. Сами вложения могут быть предварительно вычислены с помощью любого из нескольких алгоритмов, а затем использованы в любой заданной модели путем построения слоя встраивания с
weights=
иtrainable=false
2. Отличный момент — я добавил еще большие веса встраивания в пример кода. Инициализация происходит за счет использования предварительно подготовленных вложений word в руководстве по модели Keras .