简单加权嵌入网络

时间:2018-04-27 03:31:49

标签: deep-learning keras keras-layer

我有几个嵌入矩阵,假设E1矩阵用于手套,E2用于Word2vec。

我想建立一个简单的情感分类器,它采用这种嵌入的可训练加权和。

例如,对于" dog"我想得到x ["狗"] * E1 ["狗"] + y ["狗"] * E2 ["狗&#34 ;]当x和y是学习参数时(注意我想学习每个单词的x和y) 我知道我需要以某种方式学习X向量和Y向量并使用"添加",但我不知道如何实际操作,帮助将受到高度赞赏。

我的网络如下:

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 :(得分:1)

我使用过keras已经有一段时间了。但我会这样做:

Glove和Word2Vec你可能会使用gensim库加载。我假设您知道如何将这些加载到keras嵌入层。如果没有,请告诉我。

在这里,您将两个嵌入图层设置为 non-trainable

对于 X Y ,你可以像创建E1和E2一样创建另外两个嵌入层而不提供权重并将它们设置为 trainable ,这些将在培训过程中由网络学习。

您可能也可以使用Dense图层,但我认为使用嵌入图层会更容易。

对于乘法和添加,有一个如何使用它的示例,取自keras documentation

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)

<强>更新

  

例如,对于&#34; dog&#34;我想得到x [&#34;狗&#34;] * E1 [&#34;狗&#34;]   + y [&#34; dog&#34;] * E2 [&#34; dog&#34;]当x和y是学习参数时(注意我想学习x和y,因为我知道我需要以某种方式学习每个单词学习   X向量和Y向量并使用&#34;添加&#34;,但我不知道   如何真正做到这一点,帮助将受到高度赞赏。

所以,我还没有对此进行测试,也因为我没有数据,代码中可能存在一些错误 - 但一般情况下应该看起来像这样:

#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也必须相同才能发挥作用。

假设代码中的

w1w2是你的手套,而word2vec嵌入则加载了gensim。

所以,我希望这大致是你想要做的。 :)