從字符級的語言建模開始,了解語言模型與序列建模的基本概念

2020-12-04 機器之心Pro

你有沒有想過 Gmail 自動回復是如何進行的?或者手機在你輸入文本時如何對下一個詞提出建議?生成文本序列的通常方式是訓練模型在給定所有先前詞/字符的條件下預測下一個詞/字符出現的概率。此類模型叫作統計語言模型,這種模型會嘗試捕捉訓練文本的統計結構,本文從字符級語言模型和名字預測出發向讀者介紹了語言建模的核心概念。

循環神經網絡(RNN)模型常用於訓練這種語言模型,因為它們使用高維隱藏狀態單元處理信息的能力非常強大,建模長期依賴關係的能力也非常強。任意語言模型的主要目的都是學習訓練文本中字符/單詞序列的聯合概率分布,即嘗試學習聯合概率函數。例如,如果我們試圖預測一個包含 T 個詞的單詞序列,那麼我們試圖獲取令聯合概率 P(w_1, w_2, …, w_T) 最大的詞序列,等價於所有時間步 (t) 上條件概率的累乘:

本文描述了字符級的語言模型,其中幾乎所有概念都適用於其它語言模型,如單詞級的語言模型等。字符級語言模型的主要任務是根據之前的所有字符預測下一個字符,即逐個字符地生成文本內容。更正式地來說,給出訓練序列 (x^1,…,x^T),RNN 使用輸出向量序列 (o^1,…,o^T) 來獲取預測分布 P(x^t|x^t1)=softmax(o^t)。

下面我用我的姓氏(imad)為例介紹字符級語言模型的運行過程(該示例的詳情見圖 2)。

1. 我們首先用語料庫中所有名字的字母(去掉重複的字母)作為關鍵詞構建一個詞彙詞典,每個字母的索引從 0 開始(因為 Python 的索引也是從零開始),按升序排列。以 imad 為例,詞彙詞典應該是:{「a」: 0,「d」: 1,「i」: 2,「m」: 3}。因此,imad 就變成整數列表:[2, 3, 0, 1]。

2. 使用詞彙詞典將輸入和輸出字符轉換成整型數列。本文中,我們假設所有示例中

。因此,y=「imad」,

。換言之,x^t+1=y^t,y=[2,3,0,1],

3. 對於輸入中的每一個字符:

將輸入字符轉換成 one-hot 向量。注意第一個字符

的轉換過程。計算隱藏狀態層。計算輸出層,然後將計算結果傳入 softmax 層,獲得的結果就是概率。把時間步 (t) 的目標字符作為時間步 (t+1) 的輸入字符。返回步驟 a,重複該過程,直到結束名字中的所有字母。

模型的目標是使概率分布層中的綠色數值儘可能大,紅色數值儘可能小。原因在於概率趨近於 1 時,真正的索引具備最高的概率。我們可以使用交叉熵來評估損失,然後計算損失函數關於所有參數損失的梯度,並根據與梯度相反的方向更新參數。不斷重複該過程并迭代地調整參數,這樣模型就能夠使用訓練集中的所有名字,根據之前的字符預測後一個字符。注意:隱藏狀態 h^4 具備所有之前字符的信息。

圖 2:使用 RNN 的字符級語言模型圖示。

注意:為簡潔起見,我刪除了所有 Python 函數的文檔注釋,也沒有包含一些無益於理解主要概念的函數。

notebook 和 script 地址:https://nbviewer.jupyter.org/github/ImadDabbura/blog-posts/blob/master/notebooks/Character-LeveL-Language-Model.ipynb

https://github.com/ImadDabbura/blog-posts/blob/master/scripts/character_level_language_model.py

訓練

我們使用的數據集有 5163 個名字:4275 個男性名字,以及 1219 個女性名字,其中有 331 個名字是中性的。我們將使用多對多的 RNN 架構來訓練字符級語言模型,其中輸入(T_x)的時間步等於輸出(T_y)的時間步。換句話說,輸入和輸出的序列是同步的(詳見圖 3)。

數據集地址:http://deron.meranda.us/data/census-derived-all-first.txt

圖 3:多對多的 RNN 架構。

該字符級語言模型將在名字數據集上訓練,然後我們可以使用該模型生成一些有趣的名字。

在這一節中,我們將介紹 4 個主要內容:

1 前向傳播

2 反向傳播

3 採樣

4 擬合模型

前向傳播

我們將使用隨機梯度下降(SGD),其中每個 Batch 只包含一個樣本。也就是說,RNN 模型將從每個樣本(名字)中分別進行學習,即在每個樣本上運行前向和反向傳播,並據此更新參數。以下是前向傳播所需步驟:

使用全部小寫字母(無重複)構建詞彙詞典:創建不同字符的索引詞典,使每個字符以升序對應索引。例如,a 的索引是 1(因為 Python 的索引是從 0 開始,我們將把 0 索引保存為 EOS「\n」),z 的索引是 26。我們將使用該詞典將名字轉換成整數列表,其中的每個字母都用 one-hot 向量來表示。創建一個字符詞典的索引,使索引映射至字符。該詞典將用於將 RNN 模型的輸出轉換為字符,然後再翻譯成名字。初始化參數:將權重初始化為從標準正態分布中採樣的較小隨機數值,以打破對稱性,確保不同的隱藏單元學習不同的事物。另外,偏置項也要初始化為 0。W_hh:權重矩陣,連接前一個隱藏狀態 h^t1 和當前的隱藏狀態 h^t。W_xh:權重矩陣,連接輸入 x^t 和隱藏狀態 h^t。b:隱藏狀態偏置項向量。W_hy:權重矩陣,連接隱藏狀態 h^t 與輸出 o^t。c:輸出偏置項向量。將輸入 x^t 和輸出 y^t 分別轉換成 one-hot 向量:one-hot 向量的維度是 vocab_size x 1,除了在字符處的索引是 1,其他都是 0。在我們的案例中,x^t 和 y^t 一樣需要向左移一步

。例如,如果我們使用「imad」作為輸入,那麼 y=[3,4,1,2,0],

。注意:

,索引不是 0。此外,我們還使用「\n」作為每個名字的 EOS(句子/名字末尾),這樣 RNN 可以將「\n」學習為任意其它字符。這會幫助網絡學習什麼時候停止生成字符。因此,所有名字的最後一個目標字符都將是表示名字末尾的「\n」。使用以下公式計算隱藏狀態:

注意我們使用雙曲正切

作為非線性函數。主要優勢是雙曲正切函數在一定範圍內近似於恆等函數。

用以下公式計算輸出層:

將輸出傳輸至 softmax 層,以歸一化輸出,這樣我們可以將它表達為概率,即所有輸出都在 0 和 1 之間,總和為 1。以下是 softmax 公式:

softmax 層和輸出層的維度相同,都是 vocab_size x 1。因此,y^t[i] 表示時間步 (t) 下索引 i 對應字符為預測字符的概率。

如前所述,字符級語言模型的目標是最小化訓練序列的負對數似然。因此,時間步 (t) 的損失函數和所有時間步的總損失為:

由於我們使用 SGD,因此損失函數的一階導作為下降方向會帶有噪聲,且會存在振蕩現象,因此使用指數加權平均法消除噪聲是一個不錯的方法。

將目標字符 y^t 作為下一個輸入 x^t+1,直到完成該序列。

# Load packagesimport osimport numpy as np os.chdir("../scripts/")from character_level_language_model import (initialize_parameters, initialize_rmsprop, softmax, smooth_loss, update_parameters_with_rmsprop) def rnn_forward(x, y, h_prev, parameters): """Implement one Forward pass on one name.""" # Retrieve parameters Wxh, Whh, b = parameters["Wxh"], parameters["Whh"], parameters["b"] Why, c = parameters["Why"], parameters["c"] # Initialize inputs, hidden state, output, and probabilities dictionaries xs, hs, os, probs = {}, {}, {}, {} # Initialize x0 to zero vector xs[0] = np.zeros((vocab_size, 1)) # Initialize loss and assigns h_prev to last hidden state in hs loss = 0 hs[-1] = np.copy(h_prev) # Forward pass: loop over all characters of the name for t in range(len(x)): # Convert to one-hot vector if t > 0: xs[t] = np.zeros((vocab_size, 1)) xs[t][x[t]] = 1 # Hidden state hs[t] = np.tanh(np.dot(Wxh, xs[t]) + np.dot(Whh, hs[t - 1]) + b) # Logits os[t] = np.dot(Why, hs[t]) + c # Probs probs[t] = softmax(os[t]) # Loss loss -= np.log(probs[t][y[t], 0]) cache = (xs, hs, probs) return loss, cache

反向傳播

在基於 RNN 的模型上使用的基於梯度的技術被稱為隨時間的反向傳播(Backpropagation Through Time,BPTT)。我們從最後的時間步 T 開始,計算關於全部時間步的所有參數的反向傳播梯度,並將它們都加起來(如圖 4 所示)。

圖 4:隨時間的反向傳播(BPTT)。

此外,由於已知 RNN 有很陡峭的梯度變化,梯度可能會突然變得非常大然後使原來訓練得到的進展功虧一簣,即使使用了適應性學習方法如 RMSProp。其原因是梯度是損失函數的線性近似,可能無法捕捉在評估的點之外的其它信息,例如損失曲面的曲率。因此,通常在實踐中會將梯度限制在 [-maxValue, maxValue] 區間內。在這裡,我們將把梯度限制在 [-5,5] 上。這意味著如果梯度小於-5 或者大於 5,它將分別被截斷為-5 和 5。以下是所有時間步上用於計算損失函數對所有參數的梯度所需的公式。

注意,在最後的時間步 T,我們將初始化 dh_next 為 0,因為其無法在未來得到任何更新值。由於 SGD 可能存在很多振蕩,為了在每個時間步穩定更新過程,我們將使用其中一種適應性學習率的優化方法。具體來說,我們將使用 RMSProp,該方法能夠獲得可接受的性能。

def clip_gradients(gradients, max_value):""" Implements gradient clipping element-wise on gradients to be between the interval [-max_value, max_value]. """ for grad in gradients.keys(): np.clip(gradients[grad], -max_value, max_value, out=gradients[grad]) return gradients def rnn_backward(y, parameters, cache): Implements Backpropagation on one name. # Retrieve xs, hs, and probs xs, hs, probs = cache # Initialize all gradients to zero dh_next = np.zeros_like(hs[0]) parameters_names = ["Whh", "Wxh", "b", "Why", "c"] grads = {} for param_name in parameters_names: grads["d" + param_name] = np.zeros_like(parameters[param_name]) # Iterate over all time steps in reverse order starting from Tx for t in reversed(range(len(xs))): dy = np.copy(probs[t]) dy[y[t]] -= 1 grads["dWhy"] += np.dot(dy, hs[t].T) grads["dc"] += dy dh = np.dot(parameters["Why"].T, dy) + dh_next dhraw = (1 - hs[t] ** 2) * dh grads["dWhh"] += np.dot(dhraw, hs[t - 1].T) grads["dWxh"] += np.dot(dhraw, xs[t].T) grads["db"] += dhraw dh_next = np.dot(parameters["Whh"].T, dhraw) # Clip the gradients using [-5, 5] as the interval grads = clip_gradients(grads, 5) # Get the last hidden state h_prev = hs[len(xs) - 1] return grads, h_prev

採樣

正是採樣過程使得用 RNN 在每個時間步生成的文本變得有趣和有創造性。在每個時間步 (t),給定所有的已有字符,RNN 可輸出下一個字符的條件概率分布,即 P(c_t|c_1,c_2,…,c_t1)。假設我們在時間步 t=3,並嘗試預測第三個字符,其條件概率分布為 P(c_3/c_1,c_2)=(0.2,0.3,0.4,0.1)。其中有兩種極端情況:

最大熵:字符會使用均勻概率分布進行選取;這意味著詞彙表中的所有字符都是同等概率的。因此,我們最終將在選取下一個字符的過程中達到最大隨機性,而生成的文本也不會有意義。最小熵:在每個時間步,擁有最高條件概率的字符將會被選取。這意味著下一個字符的選取將基於訓練中的文本和已學習的參數。因此,生成的命名將是有意義的和有真實性的。

隨著隨機性的增大,文本將逐漸失去局部結構;然而,隨著隨機性的減小,生成的文本將變得更具真實性,並逐漸開始保留其局部結構。在這裡,我們將從模型生成的分布中採樣,該分布可被視為具有最大熵和最小熵之間的中等級別的隨機性(如圖 5 所示)。在上述分布中使用這種採樣策略,索引 0 有 20% 的概率被選取,而索引 2 有 40% 的概率被選取。

圖 5:採樣:使用字符級語言建模預測下一個字符的圖示。因此,採樣過程將在測試時用於一個接一個地生成字符。

def sample(parameters, idx_to_chars, chars_to_idx, n):

Implements sampling of a squence of n characters characters length. The sampling will be based on the probability distribution output of RNN. # Retrienve parameters, shapes, and vocab size Whh, Wxh, b = parameters["Whh"], parameters["Wxh"], parameters["b"] n_h, n_x = Wxh.shape vocab_size = c.shape[0] # Initialize a0 and x1 to zero vectors h_prev = np.zeros((n_h, 1)) x = np.zeros((n_x, 1)) # Initialize empty sequence indices = [] idx = -1 counter = 0 while (counter <= n and idx != chars_to_idx["\\n"]): # Fwd propagation h = np.tanh(np.dot(Whh, h_prev) + np.dot(Wxh, x) + b) o = np.dot(Why, h) + c probs = softmax(o) # Sample the index of the character using generated probs distribution idx = np.random.choice(vocab_size, p=probs.ravel()) # Get the character of the sampled index char = idx_to_chars[idx] # Add the char to the sequence indices.append(idx) # Update a_prev and x h_prev = np.copy(h) x = np.zeros((n_x, 1)) x[idx] = 1 counter += 1 sequence = "".join([idx_to_chars[idx] for idx in indices if idx != 0]) return sequence

擬合模型

在介紹了字符級語言建模背後的所有概念/直覺思想之後,接下來我們開始擬合模型。我麼將使用 RMSProp 的默認超參數設置,并迭代地運行模型 100 次。在每次迭代中,我們將輸出一個採樣的命名,並平滑損失函數,以觀察生成的命名如何(隨著迭代數的增加和梯度的下降)變得越來越有趣。當模型擬合完成後,我們將畫出損失函數並生成一些命名。

def model(file_path, chars_to_idx, idx_to_chars, hidden_layer_size, vocab_size, num_epochs=10, learning_rate=0.01):Implements RNN to generate characters.""" # Get the data with open(file_path) as f: data = f.readlines() examples = [x.lower().strip() for x in data] # Initialize parameters parameters = initialize_parameters(vocab_size, hidden_layer_size) # Initialize Adam parameters s = initialize_rmsprop(parameters) # Initialize loss smoothed_loss = -np.log(1 / vocab_size) * 7 # Initialize hidden state h0 and overall loss h_prev = np.zeros((hidden_layer_size, 1)) overall_loss = [] # Iterate over number of epochs for epoch in range(num_epochs): print(f"\\033[1m\\033[94mEpoch {epoch}") print(f"\\033[1m\\033[92m=======") # Sample one name print(f"""Sampled name: {sample(parameters, idx_to_chars, chars_to_idx, 10).capitalize()}""") print(f"Smoothed loss: {smoothed_loss:.4f}\\n") # Shuffle examples np.random.shuffle(examples) # Iterate over all examples (SGD) for example in examples: x = [None] + [chars_to_idx[char] for char in example] y = x[1:] + [chars_to_idx["\\n"]] # Fwd pass loss, cache = rnn_forward(x, y, h_prev, parameters) # Compute smooth loss smoothed_loss = smooth_loss(smoothed_loss, loss) grads, h_prev = rnn_backward(y, parameters, cache) # Update parameters parameters, s = update_parameters_with_rmsprop( parameters, grads, s) overall_loss.append(smoothed_loss) return parameters, overall_loss

# Load namesdata = open("../data/names.txt", "r").read()# Convert characters to lower casedata = data.lower() # Construct vocabulary using unique characters, sort it in ascending order,# then construct two dictionaries that maps character to index and index to# characters.chars = list(sorted(set(data)))chars_to_idx = {ch:i for i, ch in enumerate(chars)}idx_to_chars = {i:ch for ch, i in chars_to_idx.items()} # Get the size of the data and vocab sizedata_size = len(data)vocab_size = len(chars_to_idx)print(f"There are {data_size} characters and {vocab_size} unique characters.") # Fitting the modelparameters, loss = model("../data/names.txt", chars_to_idx, idx_to_chars, 100, vocab_size, 100, 0.01) # Plotting the lossplt.plot(range(len(loss)), loss)plt.xlabel("Epochs")plt.ylabel("Smoothed loss");

 

There are 36121 characters and 27 unique characters.Epoch 0=======Sampled name: NijqikkgzstSmoothed loss: 23.0709 Epoch 10=======Sampled name: MiltonSmoothed loss: 14.7446 Epoch 30=======Sampled name: DangelynSmoothed loss: 13.8179 Epoch 70=======Sampled name: LaciraSmoothed loss: 13.3782 Epoch 99=======Sampled name: CathrandaSmoothed loss: 13.3380

圖 6:平滑化的損失函數

經過 15 個 epoch 之後,生成的命名開始變得有意義。在這裡,為簡單起見,我並沒有展示所有 epoch 的結果;然而,你可以在我的 notebook 裡查看完整的結果。其中一個有趣的命名是「Yasira」,這是一個阿拉伯名字。

結論

統計語言模型在 NLP 中非常重要,例如語音識別和機器翻譯。我們在此文章中展示了字符級語言模型背後的主要概念。該模型的主要任務是使用一般數據中的命名按字符生成預測命名,該數據集包含 5136 個名字。以下是主要思考:

如果我們有更多數據、更大模型、更長的訓練時間,我們可能會得到更有趣的結果。然而,為了得到更好的結果,我們應該使用更深層的 LSTM。有人曾使用 3 層帶有 dropout 的 LSTM,應用到莎士比亞詩上獲得了很好的結果。LSTM 模型因其獲取更長依存關係的能力,性能上比簡單的 RNN 更強。

在此文章中,我們使用每個名字作為一個序列。然而,如果我們增加 Batch 的大小,可能會加速學習速度且得到更好的結果。比如從一個名字增加到 50 個字符的序列。

我們可以使用採樣策略控制隨機性。在這篇文章中,我們在模型考慮的正確字符與隨機性之間做了權衡。

相關焦點

  • 自然語言處理起源:馬爾科夫和香農的語言建模實驗
    他想要找到通過概率化的分析對這些事件進行建模的方法。馬爾科夫認為,語言就是這種系統的一個例子:過去出現的字符在一定程度上決定了現在的結果。為了確認這一點,他想證明在普希金小說這樣的文本中,某個字母在文本中出現的機率在某種程度上是取決於之前出現的字母的。因此才出現了本文開頭馬爾科夫統計「尤金·奧涅金」中元音的那一幕。
  • 從經典結構到改進方法,神經網絡語言模型綜述
    因此,對於像 LM 這樣的序列建模任務,FFNN 必須使用定長的輸入。受到 N 元語言模型的啟發(見公式 2),FFNNLM 將前 n-1 個單詞作為了預測下一個單詞的上下文。如圖 1 所示,Bengio 等人於 2003 年提出了原始 FFNNLM 的架構。
  • 學界| 並行運算,Facebook提出門控卷積神經網絡的語言建模
    選自arxiv.org機器之心編譯參與:李澤南摘要目前語言建模的主要方法都是基於循環神經網絡的。在本研究中,我們提出了一種使用卷積方式處理的語言建模方式。因為可以並行運算,在對延遲敏感的任務中,我們的模型的速度相較其他模型提升了一個數量級。目前為止,這是第一次出現非訓話方式在此類任務中超越了循環方式。用於語言建模的門控卷積網絡架構引言:統計語言模型被用於估算詞序列的概率分布。這相當於給定一個詞,對下一個詞的概率進行建模,例如:其中 wi 是詞彙表中的離散字索引。
  • 洞察|一文帶你全面了解自然語言處理發展史上的8大裡程碑
    最近,前饋神經網絡已經被用於語言建模的遞歸神經網絡和長期短期記憶網絡所取代。近年來已經提出了許多擴展經典LSTM的新語言模型。儘管有這些發展,但經典的LSTM仍然是一個強大的基礎模型。更好地理解語言模型究竟捕捉了哪些信息,也是當今一個活躍的研究領域。語言建模是無監督學習的一種形式,Yann LeCun也將預測性學習稱為獲取常識的先決條件。
  • 機器之心GitHub項目:從循環到卷積,探索序列建模的奧秘
    本文討論並實現了用於序列模型的基本深度方法,其中循環網絡主要介紹了傳統的 LSTM 與 GRU,而卷積網絡主要介紹了最近 CMU 研究者提出的時間卷積網絡與實證研究。相比於我們熟知的經典循環網絡方法,用 CNN 實現序列建模可能會更有意思,因此本文的實現部分重點介紹了時間卷積網絡的實現。
  • ACL論文 | 深度學習大神新作,神經網絡的自然語言翻譯應用
    這主要是因為數據稀疏性的問題,這當句子表徵為一系列字符而非詞語時這個問題更為嚴重,尤其是針對 n-gram,由於序列的長度大大增加了。除了數據稀疏性之外,我們經常先入為主地相信詞語——或其分割出的詞位——是語義最基本的單位,使我們很自然地認為翻譯就是將一系列的源語言詞語匹配為一系列的目標語言詞語。
  • 大牛講堂 | 語音專題第二講,語言模型技術
    負責百度超大語言模型訓練,語音交互技術研發以及語音搜索、語音輸入法、語音助手等產品的語音識別優化。現在地平線負責語音識別、自然語言處理等相關技術算法研究。語言模型技術語言模型技術廣泛應用於語音識別、OCR、機器翻譯、輸入法等產品上。語言模型建模過程中,包括詞典、語料、模型選擇,對產品的性能有至關重要的影響。
  • AI浪潮下,語音識別建模技術的演進 | 雷鋒網公開課
    也正是因為如此,語音識別的模型也層出不窮,其中語言模型包括了N-gram、RNNLM等,在聲學模型裡面又涵蓋了HMM、DNN、RNN等模型...簡單來說,聲學模型的任務就是描述語音的物理變化規律,而語言模型則表達了自然語言包含的語言學知識。
  • 時間序列基本概念
    平穩時間序列是時間序列中一類重要的時間序列,對於該時間序列,有一套非常成熟的平穩序列建模方法,這也是本節中將重點介紹的部分。對於非平穩序列,可以通過差分、提取確定性成分等方法,將轉化成平穩序列,再運用平穩序列建模方法進行建模。在實際操作中,由於樣本數據的匱乏,要根據樣本數據要找到生成樣本的真實隨機過程基本是不太可能的。
  • ACL 2018|西北大學:RNN語言模型的重要訓練數據抽樣
    引言統計語言建模的任務是學習自然語言單詞序列上的聯合概率分布。近年來,遞歸神經網絡(RNN)語言模型在句子級語言建模中產生了很多困惑度(perplexity),遠遠低於傳統的n-gram模型。在大型、多樣化的基準語料庫上訓練的模型,如Billion Word Corpus和Wikitext-103,困惑度分別低至23.7和37.2。
  • 自然語言生成的演變史
    可以通過使用語言模型來解決。語言模型是對詞序列的概率分布。 語言模型可以在字符級別,短語級別,句子級別甚至段落級別構建。 例如,為了預測「我需要學習如何___」之後出現的下一個單詞,模型為下一個可能的單詞分配概率,這些單詞可以是「寫作」,「開車」等。神經網絡的最新進展如RNN和LSTM允許處理長句,顯著提高語言模型的準確性。
  • 乾貨|時間序列預測類問題下的建模方案探索實踐
    隨著機器學習和深度學習的興起,時間序列預測類問題越來越多的被抽象為回歸問題,從而可以使用機器學習和深度學習的相關模型,不需要受到基本假設的限制,適用範圍更廣,更受到人們青睞。它的基本思想是:某些時間序列是依賴於時間t的一組隨機變量,構成該時間序列的單個序列值雖然具有不確定性,但整個序列的變化卻有一定的規律性,可以用相應的數學模型近似描述。通過對該數學模型的分析研究,能夠更本質地認識時間序列的結構與特徵,達到最小方差意義下的最優預測,其具體建模流程如圖4所示。
  • R時間序列分析學習筆記(二十四)—— ARIMA建模和模擬(十六)
    本筆記中原始數據及代碼均來源於李東風先生的R語言教程,在此對李東風先生的無私分享表示感謝。
  • UML建模工具中的五大視圖
    本節和大家一起學習一下UML建模工具方面的知識,本節主要包括面向對象建模概念和UML中的五大視圖等內容,相信通過本節的介紹你對UML建模工具有一定的認識。下面讓我們一起來學習UML建模工具吧。
  • 《科學》:利用語言模型分析病毒如何變異以逃避免疫系統
    現在,麻省理工學院的研究人員設計了一種新的方法,根據最初開發的分析語言的模型,對病毒逃逸進行計算建模。 該模型可以預測病毒表面蛋白質的哪些部分更容易變異,從而使病毒能夠逃脫。該方法還可以識別不太可能變異的部分,使它們成為新疫苗的目標之一。
  • BERT模型:自然語言處理最新裡程碑完整詳解!
    對於解碼器的自注意,在此使用縮放的點積注意,並且添加填充掩碼和序列掩碼作為attn_mask。在其他情況下,attn_mask等於填充掩碼。另一個細節是解碼器輸入將向右移動一個位置。這樣做的一個原因是不希望模型在訓練期間學習如何複製解碼器輸入,但還是想要了解給定編碼器序列和模型已經看到的特定解碼器序列,從而預測下一個單詞/字符。
  • 自然語言處理深度學習的7個應用
    自然語言中仍有許多具有挑戰性的問題需要解決。然而,深度學習方法在一些特定的語言問題上取得了最新的成果。這不僅僅是深度學習模型在基準問題上的表現,基準問題也是最有趣的;事實上,一個單一的模型可以學習詞義和執行語言任務,從而消除了對專業手工製作方法渠道的需要。在這篇文章中,你會發現7個有趣的自然語言處理任務,也會了解深度學習方法取得的一些進展。
  • 大數據分析為什麼要學習R中的線性建模
    對於大數據分析師來說,能夠建立線性模型是絕對必要的,但是數據分析人員甚至業餘愛好者也可以從線性建模的功能中受益匪淺。R中的線性建模,這是大數據分析師中的新課程,它將從頭開始教你此技能。你準備好動手開始建模嗎?
  • DL時代的代碼補全利器,北大出品,效果遠超語言模型
    據李戈教授介紹,aiXcoder 很早就試過了語言模型,將代碼視為一種語言從而直接建模,這就和 Deep TabNine 一樣。但是研究者很快發現,只有語言模型是行不通的,它總會提出一些毫無意義、很不科學的補全建議。為此,aiXcoder 融合了基於序列的程序代碼語言模型、基於抽象語法樹和程序邏輯關係的圖神經網絡等方法,共同打造一個完整的系統。
  • r語言檢驗序列相關 - CSDN
    時間序列概述按照時間的順序把隨機事件變化發展的過程記錄下來就構成了一個時間序列對時間序列進行觀察、研究,找尋它變化發展的規律,預測它將來的走勢就是時間序列分析時間序列建模基本步驟:解釋建模的基本步驟:通過read.table()收集數據,ts()繪製時序圖根據觀察時序圖以及白噪聲檢驗Box.test(),進行平穩性判別的檢驗若得到平穩的非白噪聲序列