Keras: разделить весовые коэффициенты между примерами обучения (не между слоями)
Проблема в следующем. У меня есть категорическое задание на прогноз словарного запаса размером 25К. На одном из них (входной словарь 10K, выходной дим, т.е. вложение 50) я хочу ввести обучаемую матрицу весов для умножения матриц между входным вложением (форма 1,50) и весами (форма (50,128)) (без смещения) и полученная векторная оценка является входом для задачи прогнозирования наряду с другими функциями.
Суть в том, я думаю, что обучаемая матрица весов варьируется для каждого входа, если я просто добавлю ее. Я хочу, чтобы эта матрица весов была общей для всех входов.
Я должен уточнить - под вводом здесь я подразумеваю учебные примеры. Таким образом, все примеры будут изучать некоторые примеры конкретных вложений и умножаться на общую матрицу весов.
После каждых стольких эпох я собираюсь выполнить пакетное обновление, чтобы узнать эти общие веса (или использовать другие целевые переменные для многократного прогнозирования выходных данных).
LSTM? Это то, что я должен посмотреть здесь?
2 ответа
За исключением слоя Embedding, слои применяются ко всем примерам в пакете.
Возьмем для примера очень простую сеть:
inp = Input(shape=(4,))
h1 = Dense(2, activation='relu', use_bias=False)(inp)
out = Dense(1)(h1)
model = Model(inp, out)
Это простая сеть с 1 входным слоем, 1 скрытым слоем и выходным слоем. Если мы возьмем скрытый слой в качестве примера; этот слой имеет матрицу весов формы (4, 2,). На каждой итерации входные данные, представляющие собой матрицу формы (batch_size, 4), умножаются на веса скрытого слоя (фаза прямой связи). Таким образом, активация h 1 зависит от всех образцов. Потери также рассчитываются на основе размера batch_size. Выходной слой имеет форму (batch_size, 1). Учитывая, что в прямой фазе все выборки партии влияли на значения весов, то же самое относится и к фоновым и градиентным обновлениям.
Когда кто-то имеет дело с текстом, часто проблема определяется как предсказание определенной метки из последовательности слов. Это моделируется как форма (batch_size, sequence_length, word_index). Давайте возьмем очень простой пример:
from tensorflow import keras
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model
sequence_length = 80
emb_vec_size = 100
vocab_size = 10_000
def make_model():
inp = Input(shape=(sequence_length, 1))
emb = Embedding(vocab_size, emb_vec_size)(inp)
emb = Reshape((sequence_length, emb_vec_size))(emb)
h1 = Dense(64)(emb)
recurrent = LSTM(32)(h1)
output = Dense(1)(recurrent)
model = Model(inp, output)
model.compile('adam', 'mse')
return model
model = make_model()
model.summary()
Вы можете скопировать и вставить это в colab и увидеть резюме.
Что делает этот пример:
- Преобразуйте последовательность индексов слов в последовательность векторов вложения слов.
- Применение плотного слоя с именем h 1 ко всем партиям (и всем элементам в последовательности); этот слой уменьшает размеры вектора вложения. Это не типичный элемент сети для обработки текста (изолированно). Но это, казалось, соответствовало вашему вопросу.
- Использование рекуррентного слоя для сокращения последовательности в один вектор для каждого примера.
- Предсказание одной метки из вектора "предложения".
Если я правильно понял проблему, вы можете повторно использовать слои или даже модели внутри другой модели.
Пример с плотным слоем. Допустим, у вас есть 10 входов
import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
# defining 10 inputs in a List with (X,) shape
inputs = [Input(shape = (X,),name='input_{}'.format(k)) for k in
range(10)]
# defining a common Dense layer
D = Dense(64, name='one_layer_to_rule_them_all')
nets = [D(inp) for inp in inputs]
model = Model(inputs = inputs, outputs = nets)
model.compile(optimizer='adam', loss='categorical_crossentropy')
Этот код не будет работать, если входные данные имеют разные формы. Первый вызов D определяет его свойства. В этом примере выходы устанавливаются непосредственно в сети. Но, конечно, вы можете объединить, сложить или что угодно.
Теперь, если у вас есть обучаемая модель, вы можете использовать ее вместо D:
import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
# defining 10 inputs in a List with (X,) shape
inputs = [Input(shape = (X,),name='input_{}'.format(k)) for k in
range(10)]
# defining a shared model with the same weights for all inputs
nets = [special_model(inp) for inp in inputs]
model = Model(inputs = inputs, outputs = nets)
model.compile(optimizer='adam', loss='categorical_crossentropy')
Вес этой модели распределяется между всеми входами.