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 и увидеть резюме.

Что делает этот пример:

  1. Преобразуйте последовательность индексов слов в последовательность векторов вложения слов.
  2. Применение плотного слоя с именем h 1 ко всем партиям (и всем элементам в последовательности); этот слой уменьшает размеры вектора вложения. Это не типичный элемент сети для обработки текста (изолированно). Но это, казалось, соответствовало вашему вопросу.
  3. Использование рекуррентного слоя для сокращения последовательности в один вектор для каждого примера.
  4. Предсказание одной метки из вектора "предложения".

Если я правильно понял проблему, вы можете повторно использовать слои или даже модели внутри другой модели.

Пример с плотным слоем. Допустим, у вас есть 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')

Вес этой модели распределяется между всеми входами.

Другие вопросы по тегам