閱讀547 返回首頁    go 阿裏雲 go 技術社區[雲棲]


有監督相似性學習:基於相似問題數據的對稱關係學習

首發地址:https://yq.aliyun.com/articles/79584


https://yq.aliyun.com/cloud

基於文本對分類的監督模型,可以根據它們之間的某些關係創建一個軟件,該軟件為這兩個文本分配標簽。當這種關係是對稱的,將該約束並入模型是有用的。本文將展示孿生卷積神經網絡是如何在兩個重複的問題數據集上執行的效果,演示結果見此

檢測重複內容這一任務會在許多不同的平台上發生,可以github網站Explosion AI資源庫下的SpaCy問題跟蹤器看到同樣的問題被反複詢問。幸運的是,現在有兩個大型社區問答站點標有數據集——Quora數據集和來自墨爾本大學的研究人員編譯的StackExchange語料庫

8d69e9df5c41014a81a151ca0faa98905bdcf958

try the demo

為了比較,演示中包含了一個無監督的基線,該基線使用來自GloVe通用Crawl模型的向量來計算一個簡單的字矢量平均值。有監督的模型從這種無監督的基線學習了非常不同的相似性定義,它大致表示文檔之間主題的重疊。有監督使用了標簽數據,這通常被認為是其缺點然而,這也是一個關鍵的優勢:它允許使用標記數據自定義被分類的關係沒有監督就會陷入任何無監督算法恢複默認關係


         Quora和StackExchange數據集根據兩個問題是否重複進行標記這種關係既可交換也可傳遞的。對於is_dup(A, B) 和 is_dup(B, A)兩個同樣的問題而言希望得到兩種計算不同的結果——因為該模型應該把這兩種問題看作一樣。同樣,如果知道is_dup(A, B)is_dup(B, C)應該得到結論is_dup(A, C)
         可以通過使用“孿生”架構來學習遵守這些約束的函數,之前討論的非對稱模型的架構差異很小。如前所述,首先對句子進行編碼,使用距離函數來產生預測而不是任意的非線性。下麵簡述孿生網絡

孿生網絡框架

def Siamese(text2vec, similarity_metric):
    def forward(text1, text2):
        vec1, bp_vec1 = text2vec(text1)
        vec2, bp_vec2 = text2vec(text2)
        # If we were doing an asymmetric model, we'd have:
        # sim, bp_sim = multi_layer_perceptron(concatenate(vec1, vec2))
        # cat(vec1, vec2) differs from cat(vec2, vec1) -- hence the asymmetry.
        sim, bp_sim = similarity_metric(vec1, vec2)

        def backward(d_sim, optimize):
            d_vec1, d_vec2 = bp_sim(d_sim, optimize)
            d_text1 = bp_vec1(d_vec1, optimize)
            d_text2 = bp_vec2(d_vec2, optimize)
            return d_text1, d_text2
        return sim, backward
    return forward

上述Siamese函數調用了兩個函數——text2vecsimilarity_metric使用text2vec函數對輸入中的每個文本進行單獨編碼,然後使用similarity_metric進行比較。假設每個函數返回一個回調以完成其反傳過程。鑒於此,孿生網絡的反向傳播邏輯非常簡單。每個回調返回相對於原始函數輸入的梯度,給定原始函數輸出的梯度。對於相似性度量,一直在使用Chen(2013)的距離函數(推薦閱讀該碩士論文)Cauchy Similarity介紹如下

Cauchy Similarity

def ChenCauchy(length):
    '''Create a trainable similarity function, that will return the similarity
    and a callback to compute the backward pass given the gradient.

    An optimizer can be passed to the callback to update the weights, e.g.
    Adam, SGD momentum, etc.
    '''
    weights = numpy.ones((1, length,))

    def forward(x1, x2):
        diff = x1-x2
        dist_vec = diff**2
        weighted_dist = weights.dot(l1_vector)
        weighted_dist *= weighted_dist > 0
        sim = 1. / (1+weighted_dist)

        def backward(d_sim, optimize):
            d_weighted_dist = d_sim * (-1 / (weighted_dist+1)**2)
            d_weighted_dist *= weighted_dist > 0
            d_weights  = d_weighted_dist * dist_vec
            d_dist_vec = d_weighted_dist * weights
            d_diff = 2 * d_dist_vec * diff
            d_x1 = d_diff
            d_x2 = -d_diff
            optimize(weights, d_weights)
            return d_x1, d_x2
        return sim, backward
    return forward

對於text2vec函數一直使用之前發布的博客——Maxout Window Encoding引入的卷積層。MWE層與BiLSTM具有相同的目標:提取更好的特征。它會根據周圍的上下文重寫每個單詞的向量。這是有用的,因為它繞過了字矢量的主要限製。我們知道像duck這樣的詞可以有多個含義(鴨子、躲避、人名等),我們想要一個反映上下文意義的向量。

3c5cb5d9f3d1398270ea34d32cbff033f9278b62

將鼠標懸停在向量上以查看哪些單詞用於計算:懸停在單詞上,看看它們影響的向量去原文嚐試
        上圖顯示了單個MWE塊如何重寫每個單詞的向量。可以將輸出視為三角形向量——它們基於三字窗口中的信息構建每一層越深接收域加寬下麵是完整的模型定義,使用的是SpaCy 2.0的神經網絡模型開發庫Thinc


def build_siamese_network(width, depth):
    embed = StaticVectors('en', width)
    pooling = concatenate(mean_pool, max_pool)
    mwe_encode = chain(ExtractWindow(nW=1), Maxout(width))

    # Define a little DSL for block, for convenience.
    with Model.define_operators({'>>': chain, '**': clone}):
        sent2vec = (
            get_word_ids(Model.ops)
            >> flatten_add_lengths
            >> with_getitem(0, embed >> mwe_encode ** depth)
            >> pooling
        )
    model = Siamese(sent2vec, CauchySimilarity(Model.ops, width*2))
    return model

在MWE層之後,獲得兩個矩陣,每個文本對應其中的一個。矩陣可以具有不同的長度,並且需要輸出單個相似性得分。下一步是模型中最弱的部分:為了比較這些矩陣,通過采用它們的元素均值及其元素最大值來將矩陣減少為兩個向量。在這兩個操作中,最大趨向於具有更多信息——但是使用兩者往往比僅使用最大更好。
結果和顯著例子
       下表顯示了Quora和StackExchange數據的開發集精度。既然沒有一個指定的訓練/驗證/測試拆分語料庫,因此我一直將數據集隨機分成對應的10%30%、60%三部分下表仍然是初步結果,並且模型的超參數還沒有得到很好的調整。

9468aa5b61ffd4941f938ea26a5181579568ae56

盡管有這些附加說明,但對稱網絡的準確性得到提高是非常一致的。在Quora數據中,準確度提高了2.3%——比我之前看到任何改變的進步都大。最大窗口編碼層也似乎有幫助,雖然結果的不一致使得這點難以確定。
比較兩個模型的輸出是有趣的,特別是與分配給每個單詞的GloVe向量的簡單未加權平均值相比較。在交互演示中,看看下麵的例子:

2a9c9ae0eb7c6e0ab556ef1ac8137c01cedef33f

在嚐試的大多數示例中,默認的相似度模型(其采用簡單的向量平均)偏高。Quora和StackExchange模型的輸出差異大部分可以通過培訓文本的不同領域來解釋。另外還可以看到協調策略的效果,因為它控製重複項的定義。例如在Quora數據中,細節不同的問題(例如地點)被視為重複問題,因此該模型學習注意單個命名實體。

這些模型中沒有一個揭示他們正在分類的文本對的“真實”相似性因為均值是多維的,以至於文本段在某些方麵總是相似的,而在其他方麵是不同的。因此,需要的標簽將始終取決於些對應用程序很重要關係。
         如果嚐試相似性分數中獲取一個意圖標簽,可能將兩個句子視為相同的動詞但不同的類似對象——它們都將觸發同一個函數。或者,如果嚐試在產品評論中集中意見,則該對象可能是決定性的維度。使用示例數據算法無法猜出你想要什麼,除非你告訴它,這就是為什麼監督的方法是如此有用。

AI技術的領先專家,以其研究、軟件和著作而聞名;他於2009年完成博士學位,並再度進行了長達5年的研究發表了最先進的自然語言理解係統;在2014年離開學術界,開發了SpaCy——用於工業級NLP的開源庫。

Email:matt@explosion.ai

twitter:https://twitter.com/honnibal

github:https://github.com/honnibal

scholar:https://www.semanticscholar.org/search?q=Matthew%20Honnibal

本文由北郵@愛可可-愛生活老師推薦,阿裏雲雲棲社區組織翻譯。

文章原標題《》,作者,譯者:海棠,審閱:

附件為原文的pdf

文章為簡譯,更為詳細的內容,請查看原文

最後更新:2017-07-12 22:11:38

  上一篇:go  Top100論文導讀:深入理解卷積神經網絡CNN(Part Ⅰ)
  下一篇:go  神經網絡常用激活函數對比:sigmoid VS sofmax(附python源碼)