Простая взвешенная встраиваемая сеть - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть несколько матриц вложений, допустим, матрица E1 предназначена для Glove, а E2 для Word2vec.

Я бы хотел построить простой классификатор настроений, который бы брал в расчет взвешенную сумму этих вложений.

Например, для слова "собака" я хотел бы получить x ["собака"] * E1 ["собака"] + y ["собака"] * E2 ["собака"], когда x и y выучены параметры (обратите внимание, что я хочу узнать х и у для каждого слова Я знаю, что мне нужно как-то выучить вектор X и вектор Y и использовать слияние с «add», но я понятия не имею, как на самом деле это сделать, помощь будет высоко оценена.

Моя сеть выглядит следующим образом:

embd = Sequential()
embd.add(Embedding(topWords + 2, embedding_vecor_length, 
input_length=max_review_len, weights=[embedding_weights],trainable=False))
sent_model = Sequential()
sent_model.add(embd)
sent_model.add(Conv1D(filters, kernel_size, border_mode='valid', 
activation='relu', input_shape=(max_review_len, embedding_vecor_length)))
sent_model.add(Dense(1, activation='sigmoid'))

1 Ответ

0 голосов
/ 27 апреля 2018

Я давно использовал керас. Но я бы сделал это так:

Перчатку и Word2Vec вы, вероятно, загрузите, используя библиотеку gensim. Я предполагаю, что вы знаете, как загрузить их в слой внедрения keras. Если нет, пожалуйста, дайте мне знать.

Здесь вы установите оба встраиваемых слоя на не обучаемые .

Для X и Y вы можете создать два других встраиваемых слоя, как вы бы это сделали для E1 и E2, без указания весов и установки их на обучаемый , эти будет изучаться сетью в процессе обучения.

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

Для умножения и сложения есть пример, как его использовать, взятый из документации keras :

import keras

input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8, activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)
added = keras.layers.Add()([x1, x2])  # equivalent to added = keras.layers.add([x1, x2])

out = keras.layers.Dense(4)(added)
model = keras.models.Model(inputs=[input1, input2], outputs=out)

UPDATE:

Например, для слова "собака" я хотел бы получить x ["собака"] * E1 ["собака"] + y ["собака"] * E2 ["собака"], когда x и y - изученные параметры (обратите внимание, что я хочу выучить x и y для каждого слова, которое я знаю, мне нужно как-то выучить вектор X и вектор Y и использовать слияние с «добавить», но я понятия не имею, как на самом деле это сделать, помощь будет высоко ценится.

Итак, я не проверял это, а также потому, что у меня нет данных, в коде могут быть некоторые ошибки - но в целом это должно выглядеть примерно так:

#input
sequence_input = Input(shape=(max_review_len,), dtype='int32')

# loading your Glove embedding
layer_E1 = Embedding(w1.shape[0],w1.shape[1],
                            weights=[w1],
                            input_length=max_review_len,
                            trainable=False)
# loading your Word2Vec embedding
layer_E2 = Embedding(w2.shape[0],w2.shape[1],
                            weights=[w2],
                            input_length=max_review_len,
                            trainable=False)
# applying embeddings
embedded_E1 = layer_E1(sequence_input)
embedded_E2 = layer_E2(sequence_input)

# creating learnable embedding layer X and Y
layer_X = Embedding(vocab_size, embedding_vecor_length, input_length=max_review_len)
layer_Y = Embedding(vocab_size, embedding_vecor_length, input_length=max_review_len)

# your weights X and Y
embedded_X = layer_X(sequence_input)
embedded_Y = layer_Y(sequence_input)

# Multiplying X*E1 (x["dog"]*E1["dog"])
layer_E1_X = keras.layers.Multiply()([embedded_E1, embedded_X])
# Multiplying Y*E2 (y["dog"]*E2["dog"])
layer_E2_Y = keras.layers.Multiply()([embedded_E2, embedded_Y])

# merging the results with add
added = keras.layers.Add()([layer_E1_X, layer_E2_Y])

# …
# some other layers
# … 

your_final_output_layer = Dense(1, activation='sigmoid')(previous_layer)

model = Model(sequence_input, your_final_output_layer)
model.compile(…)
model.fit(…)

Редактировать: Я забыл применить вложение X и Y, я добавил его сейчас.

(Пожалуйста, подумайте об этом как о грубой идее или наброске, возможно, вам придется изменить некоторые вещи)

Здесь важно, чтобы размеры совпадали, поэтому оба вложения E1 и E2 должны иметь одинаковый размер вложения. embedding_vecor_length должно быть таким же, чтобы это работало.

Предполагается, что

w1 и w2 в коде являются вашими вложениями перчаток и word2vec, загруженными с помощью gensim.

Итак, я надеюсь, что это примерно то, что вы хотели сделать. :)

...