[英]ELMo Embedding layer with Keras
我一直在我的體系結構中使用Keras默認嵌入層和單詞嵌入。 建築看起來像這樣-
left_input = Input(shape=(max_seq_length,), dtype='int32')
right_input = Input(shape=(max_seq_length,), dtype='int32')
embedding_layer = Embedding(len(embeddings), embedding_dim, weights=[embeddings], input_length=max_seq_length,
trainable=False)
# Since this is a siamese network, both sides share the same LSTM
shared_lstm = LSTM(n_hidden, name="lstm")
left_output = shared_lstm(encoded_left)
right_output = shared_lstm(encoded_right)
我想用ELMo嵌入替換嵌入層。 所以我使用了一個自定義嵌入層-在此倉庫中找到-https: //github.com/strongio/keras-elmo/blob/master/Elmo%20Keras.ipynb 。 嵌入層看起來像這樣-
class ElmoEmbeddingLayer(Layer):
def __init__(self, **kwargs):
self.dimensions = 1024
self.trainable=True
super(ElmoEmbeddingLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.elmo = hub.Module('https://tfhub.dev/google/elmo/2', trainable=self.trainable,
name="{}_module".format(self.name))
self.trainable_weights += K.tf.trainable_variables(scope="^{}_module/.*".format(self.name))
super(ElmoEmbeddingLayer, self).build(input_shape)
def call(self, x, mask=None):
result = self.elmo(K.squeeze(K.cast(x, tf.string), axis=1),
as_dict=True,
signature='default',
)['default']
return result
def compute_mask(self, inputs, mask=None):
return K.not_equal(inputs, '--PAD--')
def compute_output_shape(self, input_shape):
return (input_shape[0], self.dimensions)
我更改了新嵌入層的體系結構。
# The visible layer
left_input = Input(shape=(1,), dtype="string")
right_input = Input(shape=(1,), dtype="string")
embedding_layer = ElmoEmbeddingLayer()
# Embedded version of the inputs
encoded_left = embedding_layer(left_input)
encoded_right = embedding_layer(right_input)
# Since this is a siamese network, both sides share the same LSTM
shared_lstm = LSTM(n_hidden, name="lstm")
left_output = shared_gru(encoded_left)
right_output = shared_gru(encoded_right)
但是我出錯了-
ValueError:輸入0與層lstm不兼容:預期ndim = 3,找到的ndim = 2
我在這里做錯了什么?
Elmo嵌入層為每個輸入輸出一個嵌入(因此輸出形狀為(batch_size, dim)
),而您的LSTM期望一個序列(即形狀(batch_size, seq_length, dim)
)。 我認為在Elmo嵌入層之后再添加LSTM層沒有多大意義,因為Elmo已經使用LSTM嵌入了單詞序列。
我還使用該存儲庫作為構建CustomELMo + BiLSTM + CRF模型的指南,並且需要將dict查詢更改為“ elmo”而不是“ default”。 正如Anna Krogager指出的那樣,當dict查找為“ default”時,輸出為(batch_size,dim),這對於LSTM而言還不夠。 但是,當dict查找為['elmo']時,該層將返回正確尺寸的張量,即形狀(batch_size,max_length,1024)。
自定義ELMo層:
class ElmoEmbeddingLayer(Layer):
def __init__(self, **kwargs):
self.dimensions = 1024
self.trainable = True
super(ElmoEmbeddingLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.elmo = hub.Module('https://tfhub.dev/google/elmo/2', trainable=self.trainable,
name="{}_module".format(self.name))
self.trainable_weights += K.tf.trainable_variables(scope="^{}_module/.*".format(self.name))
super(ElmoEmbeddingLayer, self).build(input_shape)
def call(self, x, mask=None):
result = self.elmo(K.squeeze(K.cast(x, tf.string), axis=1),
as_dict=True,
signature='default',
)['elmo']
print(result)
return result
# def compute_mask(self, inputs, mask=None):
# return K.not_equal(inputs, '__PAD__')
def compute_output_shape(self, input_shape):
return input_shape[0], 48, self.dimensions
該模型的構建如下:
def build_model(): # uses crf from keras_contrib
input = layers.Input(shape=(1,), dtype=tf.string)
model = ElmoEmbeddingLayer(name='ElmoEmbeddingLayer')(input)
model = Bidirectional(LSTM(units=512, return_sequences=True))(model)
crf = CRF(num_tags)
out = crf(model)
model = Model(input, out)
model.compile(optimizer="rmsprop", loss=crf_loss, metrics=[crf_accuracy, categorical_accuracy, mean_squared_error])
model.summary()
return model
我希望我的代碼對您有用,即使它不是完全相同的模型也是如此。 請注意,在拋出之時,我不得不注釋掉compute_mask方法
InvalidArgumentError: Incompatible shapes: [32,47] vs. [32,0] [[{{node loss/crf_1_loss/mul_6}}]]
其中32是批處理大小,47比我指定的max_length小1(大概意味着它是在填充令牌本身)。 我還沒有找出導致該錯誤的原因,因此對您和您的模型都可以。 但是,我注意到您正在使用GRU,並且在存儲庫中有一個尚未解決的有關添加GRU的問題。 因此,我很好奇您是否也有這種想法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.