【问题标题】:Highlighting important words in a sentence using Deep Learning使用深度学习突出句子中的重要单词
【发布时间】:2018-12-30 20:34:51
【问题描述】:

我试图在 imdb 数据集中突出显示最终有助于情绪分析预测的重要词。

数据集是这样的:

X_train - 评论作为字符串。

Y_train - 0 或 1

现在,在使用 Glove 嵌入来嵌入 X_train 值后,我可以将其输入神经网络。

现在我的问题是,我怎样才能明智地突出最重要的单词?就像 deepmoji.mit.edu 一样?

我尝试了什么:

  1. 我尝试将输入句子拆分为二元组并使用 1D CNN 对其进行训练。稍后当我们想找到 X_test 的重要词时,我们只需将 X_test 拆分为双元组并找到它们的概率。它有效但不准确。

  2. 我尝试使用预构建的分层注意网络并成功。我得到了我想要的东西,但我无法从代码中找出每一行和每一个概念。这对我来说就像一个黑盒子。

我知道神经网络是如何工作的,我可以使用 numpy 从头开始​​手动反向传播对其进行编码。我详细了解了 lstm 的工作原理以及忘记、更新和输出门实际输出的内容。但我仍然无法弄清楚如何提取注意力权重以及如何将数据制作为 3D 数组(我们的 2D 数据中的时间步长是多少?)

所以,欢迎任何类型的指导

【问题讨论】:

标签: python tensorflow keras lstm pytorch


【解决方案1】:

这是一个带有 Attention(不是 Hierarchical)的版本,但您应该能够弄清楚如何使其也适用于层次结构 - 如果不是,我也可以提供帮助。诀窍是定义 2 个模型并使用 1 个用于训练(模型),另一个用于提取注意力值(model_with_attention_output):

# Tensorflow 1.9; Keras 2.2.0 (latest versions)
# should be backwards compatible upto Keras 2.0.9 and tf 1.5
from keras.models import Model
from keras.layers import *
import numpy as np

dictionary_size=1000

def create_models():
  #Get a sequence of indexes of words as input:
  # Keras supports dynamic input lengths if you provide (None,) as the 
  #  input shape
  inp = Input((None,))
  #Embed words into vectors of size 10 each:
  # Output shape is (None,10)
  embs = Embedding(dictionary_size, 10)(inp)
  # Run LSTM on these vectors and return output on each timestep
  # Output shape is (None,5)
  lstm = LSTM(5, return_sequences=True)(embs)
  ##Attention Block
  #Transform each timestep into 1 value (attention_value) 
  # Output shape is (None,1)
  attention = TimeDistributed(Dense(1))(lstm)
  #By running softmax on axis 1 we force attention_values
  # to sum up to 1. We are effectively assigning a "weight" to each timestep
  # Output shape is still (None,1) but each value changes
  attention_vals = Softmax(axis=1)(attention)
  # Multiply the encoded timestep by the respective weight
  # I.e. we are scaling each timestep based on its weight
  # Output shape is (None,5): (None,5)*(None,1)=(None,5)
  scaled_vecs = Multiply()([lstm,attention_vals])
  # Sum up all scaled timesteps into 1 vector 
  # i.e. obtain a weighted sum of timesteps
  # Output shape is (5,) : Observe the time dimension got collapsed
  context_vector = Lambda(lambda x: K.sum(x,axis=1))(scaled_vecs)
  ##Attention Block over
  # Get the output out
  out = Dense(1,activation='sigmoid')(context_vector)

  model = Model(inp, out)
  model_with_attention_output = Model(inp, [out, attention_vals])
  model.compile(optimizer='adam',loss='binary_crossentropy')
  return model, model_with_attention_output

model,model_with_attention_output = create_models()


model.fit(np.array([[1,2,3]]),[1],batch_size=1)
print ('Attention Over each word: ',model_with_attention_output.predict(np.array([[1,2,3]]),batch_size=1)[1])

输出将是每个单词的注意力值的numpy数组 - 值越高,单词越重要

编辑:您可能希望用 embs 替换乘法中的 lstm 以获得更好的解释,但这会导致更差的性能......

【讨论】:

  • 我明白了这个概念,但是在运行代码时遇到了一个奇怪的错误。 pastebin.com/BnheCkuv - 我的代码版本。错误是:-'Node' 对象没有属性 'output_masks'
  • 能否给出github或pastebin中完整代码的链接?我遇到了很多错误。谢谢!
  • 还有一件事,lstm 的输出维度为(?,?,10),而对于 attention_vals,它的维度为(?,?,1),因为 softmax 层的时间分布密集输出 this。因此,在根据文档进行乘法时, keras.backend.Multiply() 接受所有相同维度的输入张量。我错过了什么吗?
  • 很确定您得到的错误是因为您将 Keras 操作切换到了 Tensorflow 操作——尤其是乘法层是有问题的,因为您甚至没有将它包装到 lambda 层中。混合使用 Tensorflow 和 Keras 操作很危险,因为 Keras 构建了自己的图形,并且经常将任意 Tensorflow 代码插入其中是行不通的。
  • Multiply docs 可能没有指定这种行为,但它确实可以正常工作:10 个输出中的每一个都从各自的注意力时间步乘以 1 个值 - 类似于 numpy 操作的工作原理
猜你喜欢
  • 2020-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-05
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多