【问题标题】:Output shape of lambda layer not right in Neural Net. How change it?神经网络中 lambda 层的输出形状不正确。怎么改?
【发布时间】:2020-07-13 00:14:25
【问题描述】:

这是我在 Stackoverflow 上的第一个问题,所以如果我错过了什么,请指出来。 我的 Lambda 层使用 keras 和 tensorflow 1 存在问题。在这个 Lambda 层中,我将 100 维手套向量作为输入并计算与其他 8 个向量的余弦相似度(我之前转换为张量)。作为输出,我希望将八个产生的余弦相似度作为张量(我认为这在张量流中是必要的?)。

我现在的问题是生成的张量的形状显然是 (8, 1),但实际上我认为我需要输出形状 (None, 8)。否则它将不匹配我的网络中的后续层,即输出层,应该输出六个类概率。

这是我输入 Lambda 层并取自 Sentence similarity using keras 的自定义函数的代码:

from keras import backend as K

def cosine_distance(ref_vector):
    sess = K.get_session()
    global emo_vec_array
    ref_vector = K.l2_normalize(ref_vector, axis=-1)

    cos_sim_list = []
    for emo_vector in emo_vec_array:
      emo_vector = K.l2_normalize(emo_vector, axis=-1)
      cos_sim = K.mean(ref_vector * emo_vector, axis=-1, keepdims=True)*100
      cos_sim_list.append(cos_sim[0])
    return tf.convert_to_tensor(cos_sim_list)

def cos_dist_output_shape(shapes):
    shape1, shape2 = shapes
    return (shape1, 8)

test_vector = tf.convert_to_tensor(embeddings_index['happy'], dtype='float32')

test_result = cosine_distance(test_vector)
array = sess.run(test_result)

这里输出,当打印测试结果,转换后的Tensor为:

Tensor("packed_53:0", shape=(8,), dtype=float32)
[0.5166239  0.2958691  0.317714   0.44583628 0.39608976 0.4195615 0.6432581  0.2618766 ]

结果如我所愿,但我的 NN 中的输出形状不正确。这些是最后几层,各自的输出形状如下:

hidden = Dense(vector_dimension, activation='relu')(attention)

distance = Lambda(cosine_distance)(hidden)

out = Dense(6, activation='softmax')(distance)


dense_41 (Dense)             (None, 100)               20100     
_________________________________________________________________
lambda_26 (Lambda)           (8, 1)                    0         
_________________________________________________________________
dense_42 (Dense)             (8, 6)                    12        

最后我想要的是:

dense_41 (Dense)             (None, 100)               20100     
_________________________________________________________________
lambda_26 (Lambda)           (None, 8)                    0         
_________________________________________________________________
dense_42 (Dense)             (None, 6)                    12        

我已经尝试过对张量进行 K.transpose-ing 并尝试使用 Output-shape-function,但这并没有达到预期的效果。 非常感谢任何帮助。

我希望我能弄清楚我的问题,并提前非常感谢您。

【问题讨论】:

    标签: tensorflow keras nlp


    【解决方案1】:

    只需将余弦计算更改为矢量化运算,

    def cosine_dist(inp):
      # I decided to have this as a variable within the function. 
      # But you can also define this outside and pass it as an input to the function.
      emo_vectors = tf.ones(shape=(8,100))
      def normalize(x):
        return x / K.sum(x**2, axis=1, keepdims=True)
    
      inp = normalize(inp)
      emo_vectors = normalize(emo_vectors)  
      cdist = K.dot(inp, K.transpose(emo_vectors))
    
      return cdist
    

    这是一个使用的例子,

    inp = layers.Input(shape=(100))
    hidden = layers.Lambda(lambda x: cosine_dist(x))(inp)
    model = models.Model(inputs=inp, outputs=hidden)
    model.summary()
    

    哪个给出,

    Model: "model_2"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    input_8 (InputLayer)         [(None, 100)]             0         
    _________________________________________________________________
    lambda_7 (Lambda)            (None, 8)                 0         
    =================================================================
    Total params: 0
    Trainable params: 0
    Non-trainable params: 0
    _________________________________________________________________
    

    如你所见,lambda 层的输出现在是(None, 8)

    【讨论】:

      【解决方案2】:

      过了一会儿,我也找到了第二个解决方案。诀窍是考虑灵活的批量大小。下面是余弦函数的修改代码:

      from keras import backend as K
      
      def cosine_distance(ref_vector):
          global emo_vec_array
          ref_vector = K.l2_normalize(ref_vector, axis=-1)
      
          cos_sim_list = []
          for emo_vector in emo_vec_array:
            emo_vector = K.l2_normalize(emo_vector, axis=-1)
            emo_vector = tf.reshape(emo_vector, [emo_vector.shape[0], 1])
            cos_sim = K.dot(ref_vector, emo_vector)
            cos_sim_list.append(cos_sim)
      
          result = tf.convert_to_tensor(cos_sim_list)
          result = tf.reshape(result, [len(emo_vec_array), -1])
          result = tf.transpose(result)
          return result
      
      

      【讨论】:

        猜你喜欢
        • 2017-12-05
        • 2020-12-28
        • 2018-01-24
        • 2021-11-25
        • 2020-08-14
        • 2019-08-02
        • 1970-01-01
        • 2018-04-03
        • 1970-01-01
        相关资源
        最近更新 更多