1

在具有編碼器和解碼器的seq2seq模型中,在每個生成步驟,softmax層輸出整個詞彙表的分佈。在CNTK中,通過使用C.hardmax函數可以很容易地實現貪婪的解碼器。它看起來像這樣。使用CNTK通過在每個生成步驟採樣生成序列

def create_model_greedy(s2smodel): 
    # model used in (greedy) decoding (history is decoder's own output) 
    @C.Function 
    @C.layers.Signature(InputSequence[C.layers.Tensor[input_vocab_dim]]) 
    def model_greedy(input): # (input*) --> (word_sequence*) 
     # Decoding is an unfold() operation starting from sentence_start. 
     # We must transform s2smodel (history*, input* -> word_logp*) into a generator (history* -> output*) 
     # which holds 'input' in its closure. 
     unfold = C.layers.UnfoldFrom(lambda history: s2smodel(history, input) >> **C.hardmax**, 
            # stop once sentence_end_index was max-scoring output 
            until_predicate=lambda w: w[...,sentence_end_index], 
            length_increase=length_increase) 
     return unfold(initial_state=sentence_start, dynamic_axes_like=input) 
    return model_greedy 

但是,在每一步我都不想以最大概率輸出令牌。相反,我想要一個隨機解碼器,根據詞彙表的概率分佈生成一個標記。

我該怎麼做?任何幫助表示讚賞。謝謝。

回答

1

在採用hardmax之前,您可以在輸出端添加噪聲。特別是,您可以使用C.random.gumbelC.random.gumbel_like按比例對exp(output)進行採樣。這就是所謂的gumbel-max trickcntk.random模塊還包含其他分佈,但如果您有日誌概率,則最有可能希望在hardmax之前添加gumbel噪聲。有些代碼:

@C.Function 
def randomized_hardmax(x): 
    noisy_x = x + C.random.gumbel_like(x) 
    return C.hardmax(noisy_x) 

然後你hardmaxrandomized_hardmax取代。

+0

WOWWWWWWW,令人驚歎!非常感謝。你是如此的樂於助人! – meijiesky

+0

那麼你怎麼upvote我的答案呢? –

+0

我沒有15這個新帳戶的聲望...我現在在中國,我無法登錄到我的Gmail帳戶或使用Facebook帳戶。一回到美國,我會盡快回復您的答案。再次感謝你。 – meijiesky

0

非常感謝Nikos Karampatziakis。

如果您想要有一個隨機採樣解碼器來生成與目標序列長度相同的序列,那麼以下代碼可以工作。

@C.Function 
def sampling(x): 
    noisy_x = x + C.random.gumbel_like(x) 
    return C.hardmax(noisy_x) 

def create_model_sampling(s2smodel): 
    @C.Function 
    @C.layers.Signature(input=InputSequence[C.layers.Tensor[input_vocab_dim]], 
         labels=LabelSequence[C.layers.Tensor[label_vocab_dim]]) 
    def model_sampling(input, labels): # (input*) --> (word_sequence*) 
     unfold = C.layers.UnfoldFrom(lambda history: s2smodel(history, input) >> sampling, 
            length_increase=1) 
     return unfold(initial_state=sentence_start, dynamic_axes_like=labels) 
    return model_sampling