【问题标题】:Multiple issues with axes while implementing a Seq2Seq with attention in CNTK在 CNTK 中实现 Seq2Seq 时的多个轴问题
【发布时间】:2018-02-20 12:40:44
【问题描述】:

我正在尝试在 CNTK 中实现一个带有注意力的 Seq2Seq 模型,与CNTK Tutorial 204 非常相似。但是,几个小的差异会导致各种问题和错误消息,我不明白。这里有很多问题,可能是相互关联的,都源于我不明白的某件事。

注意(如果它很重要)。我的输入数据来自MinibatchSourceFromData,由适合 RAM 的 NumPy 数组创建,我不将其存储在 CTF 中。

ins = C.sequence.input_variable(input_dim, name="in", sequence_axis=inAxis)
y = C.sequence.input_variable(label_dim, name="y", sequence_axis=outAxis)

因此,形状为[#, *](input_dim)[#, *](label_dim)

问题 1: 当我运行 CNTK 204 Tutorial 并使用 cntk.logging.plot 将其图形转储到 .dot 文件中时,我看到它的输入形状是 [#](-2,)。这怎么可能?

  • 序列轴 (*) 在哪里消失了?
  • 维度怎么可能是负数?

问题 2: 在同一个教程中,我们有 attention_axis = -3。我不明白这一点。在我的模型中,有 2 个动态轴和 1 个静态轴,因此“倒数第三个”轴将是 #,即批处理轴。但是绝对不应该在批处理轴上计算注意力。
我希望查看教程代码中的实际坐标轴可以帮助我理解这一点,但上面的[#](-2,) 问题让这更加令人困惑。

attention_axis 设置为-2 会出现以下错误:

RuntimeError: Times: The left operand 'Placeholder('stab_result', [#, outAxis], [128])'
              rank (1) must be >= #axes (2) being reduced over.

在创建训练时模型期间:

def train_model(m):
    @C.Function
    def model(ins: InputSequence[Tensor[input_dim]],                  
              labels: OutputSequence[Tensor[label_dim]]):
        past_labels = Delay(initial_state=C.Constant(seq_start_encoding))(labels)
        return m(ins, past_labels)  #<<<<<<<<<<<<<< HERE
    return model

其中stab_result 是解码器中最后Dense 层之前的Stabilizer。我可以在点文件中看到,AttentionModel 实现的中间出现了大小为 1 的虚假尾随维度。

attention_axis 设置为-1 会出现以下错误:

RuntimeError: Binary elementwise operation ElementTimes: Left operand 'Output('Block346442_Output_0', [#, outAxis], [64])'
              shape '[64]' is not compatible with right operand 
              'Output('attention_weights', [#, outAxis], [200])' shape '[200]'.

其中 64 是我的 attention_dim,而 200 是我的 attention_span。据我了解,注意模型中的元素* 绝对不应该将这两者混为一谈,因此-1 绝对不是这里的正确轴。

问题3:我上面的理解正确吗?什么应该是右轴,为什么它会导致上述两个异常之一?

感谢您的解释!

【问题讨论】:

    标签: python cntk sequence-to-sequence attention-model


    【解决方案1】:

    首先,有一些好消息:在最新的 master 中,AttentionModel 中已经修复了一些问题(几天后将在 CNTK 2.2 中普遍可用):

    • 您无需指定attention_spanattention_axis。如果您不指定它们并将它们保留为默认值,则会在整个序列上计算注意力。事实上,这些论点已被弃用。
    • 如果您执行上述操作,204 笔记本的运行速度会提高 2 倍,因此 204 笔记本不再使用这些参数
    • AttentionModel 中的一个错误已得到修复,它现在忠实地实现了 Bahdanau 等。人。纸。

    关于您的问题:

    维度不是负数。我们在不同的地方使用某些负数来表示某些事情:-1 是根据第一个 minibatch 推断一次的维度,-2 是我认为占位符的形状,-3 是将推断的维度每个小批量(例如当您将可变大小的图像输入卷积时)。我认为如果您在第一个 minibatch 之后打印图表,您应该会看到所有形状都是具体的。

    attention_axis 是一个应该隐藏的实现细节。基本上attention_axis=-3 将创建一个 (1, 1, 200) 的形状,attention_axis=-4 将创建一个 (1, 1, 1, 200) 的形状,依此类推。一般来说,任何大于 -3 的东西都不能保证工作,小于 -3 的东西只会增加更多的 1,没有任何明显的好处。好消息当然是你可以在最新的大师中忽略这个论点。

    TL;DR:如果您是 master(或几天后从 CNTK 2.2 开始),请将 AttentionModel(attention_dim, attention_span=200, attention_axis=-3) 替换为 AttentionModel(attention_dim)。它更快,并且不包含令人困惑的论点。从 CNTK 2.2 开始,不推荐使用原始 API。

    【讨论】:

    • 感谢 Nikos 的澄清!快速的问题:如果我现在想尝试这个,并且我不想从源代码构建 CNTK(还),复制 AttentionModel 的新 Python 实现就足够了,或者它是否还需要在本机中进行一些最近的修复代码?
    • 本机代码中有一些错误修复。复制新的实现是不够的。
    猜你喜欢
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    相关资源
    最近更新 更多