如何在 Keras 中创建多热嵌入层?

Abd*_*ani 5 lstm keras tensorflow keras-layer

我有顺序数据,其中每个元素都是一个向量,如下所示:

x_i = [ 0.        ,  0.        ,  0.        ,  0.03666667,  0.        ,
        0.        ,  0.95666667,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.00666667,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ]
Run Code Online (Sandbox Code Playgroud)

该向量表示用户在一组活动上花费的时间分布(例如超过 5 分钟的块)。任务是在给定前 N 步 (tN : t) 的情况下预测下一个时间步 t+1 中任务的分布。因此,我的输入形状是:

X.shape = (batch_size, timesteps, input_length),一个例子是 (32, 10, 41),我们有一个批次大小为 32,过去 10 个时间步长,每个元素的维度为 41。

为此,我使用了使用 Keras 构建的 LSTM。不过,在将此输入传递给 LSTM 之前,我想创建类似于嵌入层的东西,该层将此表示转换为类似于 NLP 中所做的密集高维向量,并将单热词向量嵌入到嵌入空间中使用嵌入层。然而,Keras 中的嵌入层只接受整数输入(或 one-hot 表示),在我的情况下,我想要实现的是输入向量 X 之间的矩阵乘积(它由几个 x_i 组成,因为它代表时间-系列数据)和嵌入矩阵 V。为了说明:

X.shape = (10, 41) 嵌入矩阵形状 = (41, 100)

作用是通过矩阵乘法将 X 中的每个元素从它的 41 维稀疏表示转换为 100 维,这应该对批处理输入中的所有元素完成。

为此,我已完成以下操作

class EmbeddingMatrix(Layer):

def __init__(self, output_dim, **kwargs):
    self.output_dim = output_dim
    super(EmbeddingMatrix, self).__init__(**kwargs)

def build(self, input_shape):
    # Create a trainable weight variable for this layer.
    self.kernel = self.add_weight(name='kernel', 
                                  shape=(input_shape[2], self.output_dim),
                                  initializer='uniform',
                                  trainable=True)
    super(EmbeddingMatrix, self).build(input_shape)  # Be sure to call this somewhere!


def call(self, x, mask=None):
    return K.dot(x, self.kernel)

def compute_output_shape(self, input_shape):
    return (input_shape[0], input_shape[1], self.output_dim)
Run Code Online (Sandbox Code Playgroud)

我使用的 LSTM 网络如下:

inputs = Input(shape=(FLAGS.look_back, FLAGS.inputlength))
inputs_embedded = EmbeddingMatrix(N_EMBEDDING)(inputs)

encoded = LSTM(N_HIDDEN, dropout=0.2, recurrent_dropout=0.2)(inputs_embedded)

dense = TimeDistributed(Dense(N_DENSE, activation='sigmoid'))(dropout)

dense_output = TimeDistributed(Dense(FLAGS.inputlength, activation='softmax'))(dense)

embedder = Model(inputs, inputs_embedded)
model = Model(inputs, dense_output)

model.compile(loss='mean_squared_error', optimizer = RMSprop(lr=LEARNING_RATE, clipnorm=5))
Run Code Online (Sandbox Code Playgroud)

但是,运行时出现以下错误:

       ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-24-5a28b4f3b6b9> in <module>()
      5 inputs_embedded = EmbeddingMatrix(N_EMBEDDING)(inputs)
      6 
----> 7 encoded = LSTM(N_HIDDEN, dropout=0.2, recurrent_dropout=0.2)(inputs_embedded)
      8 
      9 dense = TimeDistributed(Dense(N_DENSE, activation='sigmoid'))(dropout)

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/layers/recurrent.py in __call__(self, inputs, initial_state, **kwargs)
    260         # modify the input spec to include the state.
    261         if initial_state is None:
--> 262             return super(Recurrent, self).__call__(inputs, **kwargs)
    263 
    264         if not isinstance(initial_state, (list, tuple)):

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/engine/topology.py in __call__(self, inputs, **kwargs)
    567                                          '`layer.build(batch_input_shape)`')
    568                 if len(input_shapes) == 1:
--> 569                     self.build(input_shapes[0])
    570                 else:
    571                     self.build(input_shapes)

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/layers/recurrent.py in build(self, input_shape)
   1041                                         initializer=bias_initializer,
   1042                                         regularizer=self.bias_regularizer,
-> 1043                                         constraint=self.bias_constraint)
   1044         else:
   1045             self.bias = None

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
     85                 warnings.warn('Update your `' + object_name +
     86                               '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 87             return func(*args, **kwargs)
     88         wrapper._original_function = func
     89         return wrapper

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/engine/topology.py in add_weight(self, name, shape, dtype, initializer, regularizer, trainable, constraint)
    389         if dtype is None:
    390             dtype = K.floatx()
--> 391         weight = K.variable(initializer(shape), dtype=dtype, name=name)
    392         if regularizer is not None:
    393             self.add_loss(regularizer(weight))

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/layers/recurrent.py in bias_initializer(shape, *args, **kwargs)
   1033                         self.bias_initializer((self.units,), *args, **kwargs),
   1034                         initializers.Ones()((self.units,), *args, **kwargs),
-> 1035                         self.bias_initializer((self.units * 2,), *args, **kwargs),
   1036                     ])
   1037             else:

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py in concatenate(tensors, axis)
   1721         return tf.sparse_concat(axis, tensors)
   1722     else:
-> 1723         return tf.concat([to_dense(x) for x in tensors], axis)
   1724 
   1725 

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py in concat(concat_dim, values, name)
   1073       ops.convert_to_tensor(concat_dim,
   1074                             name="concat_dim",
-> 1075                             dtype=dtypes.int32).get_shape(
   1076                             ).assert_is_compatible_with(tensor_shape.scalar())
   1077       return identity(values[0], name=scope)

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/ops.py in convert_to_tensor(value, dtype, name, as_ref, preferred_dtype)
    667 
    668         if ret is None:
--> 669           ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
    670 
    671         if ret is NotImplemented:

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/constant_op.py in _constant_tensor_conversion_function(v, dtype, name, as_ref)
    174                                          as_ref=False):
    175   _ = as_ref
--> 176   return constant(v, dtype=dtype, name=name)
    177 
    178 

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/constant_op.py in constant(value, dtype, shape, name, verify_shape)
    163   tensor_value = attr_value_pb2.AttrValue()
    164   tensor_value.tensor.CopyFrom(
--> 165       tensor_util.make_tensor_proto(value, dtype=dtype, shape=shape, verify_shape=verify_shape))
    166   dtype_value = attr_value_pb2.AttrValue(type=tensor_value.tensor.dtype)
    167   const_tensor = g.create_op(

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/tensor_util.py in make_tensor_proto(values, dtype, shape, verify_shape)
    365       nparray = np.empty(shape, dtype=np_dt)
    366     else:
--> 367       _AssertCompatible(values, dtype)
    368       nparray = np.array(values, dtype=np_dt)
    369       # check to them.

/Users/asturkmani/anaconda3/lib/python3.5/site-packages/tensorflow/python/framework/tensor_util.py in _AssertCompatible(values, dtype)
    300     else:
    301       raise TypeError("Expected %s, got %s of type '%s' instead." %
--> 302                       (dtype.name, repr(mismatch), type(mismatch).__name__))
    303 
    304 

TypeError: Expected int32, got list containing Tensors of type '_Message' instead.
Run Code Online (Sandbox Code Playgroud)

什么可能导致这种情况,实现这种加权嵌入矩阵的最佳方法是什么?