2017-02-27 117 views
0

我正在用CNTK训练加权序列上的LSTM。我从语言理解下面的例子开始:https://github.com/Microsoft/CNTK/blob/master/Tutorials/CNTK_202_Language_Understanding.ipynb在CNTK中训练神经网络的加权采样序列

训练网络,它们产生CNTK文本格式(CTF)文件,如:

19 |S0 178:1 |# BOS  |S1 14:1 |# flight |S2 128:1 |# O 
19 |S0 770:1 |# show       |S2 128:1 |# O 
19 |S0 429:1 |# flights      |S2 128:1 |# O 
19 |S0 444:1 |# from       |S2 128:1 |# O 

我有一个重量关联到每个序列。因此,我产生了以下的输出:

19 |weight 10 |S0 178:1 |# BOS  |S1 14:1 |# flight |S2 128:1 |# O 
19 |weight 10 |S0 770:1 |# show       |S2 128:1 |# O 
19 |weight 10 |S0 429:1 |# flights      |S2 128:1 |# O 
19 |weight 10 |S0 444:1 |# from       |S2 128:1 |# O 

我想借此weight考虑网络训练时。考虑它的一种可能的方法是修改损失函数如下:我将交叉熵乘以实例的权重。

def create_criterion_function(model): 
    labels = Placeholder(name='labels') 
    weight = Placeholder(name='weight') 
    ce = weight * cross_entropy_with_softmax(model, labels) 
    errs = classification_error  (model, labels) 
    return combine ([ce, errs]) # (features, labels) -> (loss, metric) 

但是,当我有很多序列,网络似乎没有学习。有人告诉我,这是catastrophic forgetting情况:

灾难性遗忘(也:灾难性干扰)是一个术语,常常在联结文献中,描述与许多传统的人工神经网络模型的通病。它指的是以前学到的响应的灾难性损失,无论何时试图用单个新(额外)响应来训练网络。

另一种解决方案可能是我可以根据权重对minibatch中的实例进行采样:具有较高权重的序列应该更经常出现在minibatches中。有没有办法在CNTK中做到这一点?

+1

一个小提示:就像序列意图的S1字段一样,因为相同的权重适用于序列中的每个元素,所以只需将其放在每个序列的第一行上一次即可。 –

+0

所以它只是一个表示选项。这是否等同于重复重量:即每个字符的重量是多少?我也认为这实际上可以给予更长的序列更多的权重 – Simone

回答

1

我认为你的方法是正确的。但是,请注意,将这个目标放大10将会将这些样本的梯度放大10。在研究灾难性遗忘之前,我会先尝试将您的学习率降低10,以便将梯度步骤恢复到与之前相同的范围。

+0

所以我会减少一个常数的学习率?如果每个序列的重量不同,我怎么能找到这个因子? – Simone

+0

不幸的是,这仍然是一个尝试错误的问题。我会将学习率降低一个因素在平均体重范围内,然后试验该值* 2和/ 2,并查看三种配置中哪一种效果最好。 –