1. 程式人生 > >Recent Trends in Deep Learning Based Natural Language Processing(arXiv)筆記

Recent Trends in Deep Learning Based Natural Language Processing(arXiv)筆記

深度學習方法採用多個處理層來學習資料的層次表示,並在許多領域中產生了最先進的結果。最近,在自然語言處理(NLP)的背景下,各種模型設計和方法蓬勃發展。本文總結了已經用於大量NLP任務的重要深度學習相關模型和方法,及回顧其演變過程。我們還對各種模型進行了總結、比較和對比,以及對NLP深度學習的過去、現在和未來的透徹理解。

I. 緒論

自然語言處理(NLP)是一種理論驅動的計算技術,用於人類語言的自動分析和表示。NLP研究已經從紙帶穿孔和批處理的時代演變而來,當時句子分析可能需要長達7分鐘,到谷歌及類似應用的時代,數百萬個網頁可以不到一秒就處理完成了[1]。NLP使計算機能夠在各個層面執行各種與自然語言相關的任務,從句法分析和詞性(POS)標註到機器翻譯和對話系統。

深度學習架構和演算法已經在計算機視覺和模式識別等領域取得了令人矚目的進步。沿著這一趨勢,最近NLP研究現在越來越關注使用新的深度學習方法(見圖1)。幾十年來,針對NLP問題的機器學習方法,一直基於在非常高維度和稀疏特徵上訓練的淺模型(例如,SVM和邏輯迴歸)。過去幾年中,基於稠密向量表示的神經網路已經在各種NLP任務上產生了優異的結果。這種趨勢是由詞嵌入[2,3]和深度學習方法[4]的成功引發的。深度學習可實現多層自動特徵表示學習。相比之下,傳統的基於機器學習的NLP系統在很大程度上依賴於人工特徵。這種人工特徵非常耗時且通常不完備。

在這裡插入圖片描述 Collobert等[5]證明了一個簡單的深度學習框架可以在很多NLP任務中表現優於大多數最先進的方法,例如命名實體識別(NER),語義角色標記(SRL)和詞性標註。從那時起,已經提出了許多基於複雜深度學習演算法來解決困難的NLP任務。我們回顧了應用於自然語言任務的主要深度學習相關模型和方法,例如卷積神經網路(CNN),迴圈神經網路(RNN)和遞迴神經網路。我們還討論了記憶增強策略,注意力機制以及無監督模型,強化學習方法以及最近的深度生成模型如何用於語言相關任務。

據我們所知,本文是第一個全面涵蓋當今NLP研究中最流行的深度學習方法的工作。Goldberg [6]的工作僅以教學方式介紹了將神經網路應用於NLP的基本原則。我們相信本文將為讀者提供有關該領域當前實踐的更全面的概念。論文的結構如下:第II節介紹了分散式表示的概念,是複雜深度學習模型的基礎;接下來,第III,IV和V節討論流行模型,如卷積,迴圈和遞迴神經網路,以及它們在各種NLP任務中的使用;接下來,第VI節列出了NLP中強化學習的最新應用以及無監督句子表示學習的新發展;然後,第VII節闡述了深度學習模型與記憶體模組結合的最新趨勢;最後,第VIII部分總結了一系列深度學習方法在主要NLP問題的標準資料集上的表現。

II. 分散式表示

統計NLP(代表人物Christopher Manning,著有同名教材)曾經建模複雜自然語言任務的主要選擇。然而,它初期經常在學習語言模型的聯合概率函式時遭遇”維度災難“。這是學習詞在低維空間中的分散式表示的動機[7]。

分散式表示(distributed representation):分散式(distributed)描述的是把資訊分散式地儲存在向量的各個維度中,與之相對的是區域性表示(local representation),如詞的on-hot表示(one-hot representation),在高維向量中 只有一個維度描述了詞的語義。一般來說,通過矩陣降維或神經網路降維可以將語義分散儲存到向量的各個維度中,因此,這類方法得到的低維向量一般都可以稱作分散式表示。

A.詞嵌入

分散式向量或詞嵌入(圖2)基本上遵循分散式假設,根據該假設,具有相似含義的詞傾向於在類似的上下文中出現。因此,這些向量試圖表示詞的鄰居這一特徵。分散式向量的主要優點是它們表示詞之間的相似性。可以使用餘弦相似度等度量方法來測量向量之間的相似性。詞嵌入通常用作深度學習模型中的第一個資料處理層。通常,通過優化大規模未標註語料庫中的輔助目標來預訓練詞嵌入,例如基於其上下文預測詞[8,3] (也就是說,通過基於上下文預測詞來訓練詞嵌入,認為如果預測詞的任務效果好,則詞嵌入訓練的效果也好),其中所學習的詞向量可以表示通用的句法和語義資訊。因此,已經證明這些嵌入在表示上下文相似性和類比方面是有效的,並且由於其較小的維度,在計算核心NLP任務時是快速且有效的。

在這裡插入圖片描述

多年來,建立這種嵌入模型一直是淺層神經網路,並且不需要深層網路來建立良好的嵌入。然而,基於深度學習的NLP模型總是使用這些嵌入來表示詞、短語甚至句子。這實際上是傳統的基於詞數的模型和基於深度學習的模型之間的主要區別。詞嵌入一直是各種NLP任務中最先進結果的原因[9,10,11,12]。

例如,Glorot等[13]在情感分類中使用嵌入和疊加去噪自動編碼器進行域自適應,Hermann和Blunsom [14]提出了組合分類自動編碼器來學習句子的組合性。在最近文獻中的廣泛使用表明它們在執行NLP任務的任何深度學習模型中的有效性和重要性。

分散式表示(嵌入)主要通過上下文來學習。在20世紀90年代,一些研究發展[15]標誌著分佈語義研究的基礎。[16,17]提供了這些早期趨勢的更詳細的總結。後來的發展是對這些早期工作的改編,由此建立了主題模型,如LDA(latent Dirichlet allocation)[18]和語言模型(language models, LMs)[7]。這些工作奠定了表示學習的基礎。

2003年,Bengio等[7]提出了一種神經語言模型,可以學習詞的分散式表示(圖3)。作者認為,一旦利用詞序列的聯合概率將詞表示編譯成句子表示,就得到了指數數量的語義相鄰句子。進而,這有助於泛化,因為如果已經看到具有相似詞(相似是指詞表示在低維空間中相鄰)的詞序列,則未見的句子現在可以得到更高的置信度。

在這裡插入圖片描述 [19]是首個展示預訓練詞嵌入實用性的工作。作者提出了一種神經網路架構,構成了許多當前方法的基礎。該工作還開創了將詞嵌入作為NLP任務的有用工具。然而,詞嵌入的廣泛推廣可以說歸功於[3],他們提出了連續詞袋模型(continuous bag-of-words, CBOW)和skip-gram模型來有效地構建高質量的分散式向量表示。推動其廣泛使用的是所表現出向量組合性這樣的意外副作用,即,兩個詞向量的和向量是這兩個詞的語義合成,例如“man”+“royal”=“king”。Gittens等[20]最近給出了這種情況的理論依據,指出僅在某些假設成立時才能看到組合性,例如,假設詞需要在嵌入空間中均勻分佈。

Pennington等[21]提出另一種著名的詞嵌入方法,它基本上是一種“基於計數”的模型。這裡,通過對計數進行歸一化並對它們進行對數平滑來預處理詞共現計數矩陣。然後對該矩陣進行分解以獲得較低維度的表示,這通過最小化“重建損失”來完成。

下面,我們提供Mikolov等人提出的word2vec方法的簡要描述[3]。

B. word2vec

詞嵌入由Mikolov等人革命化[8,3],提出了CBOW和skip-gram模型。給定圍繞目標詞的大小為k的視窗中的上下文詞,CBOW計算目標詞的條件概率。另一方面,與CBOW模型完全相反,skip-gram模型通過預測給定中心目標詞的周圍上下文詞。假設上下文詞對稱地位於前後兩個方向上視窗大小相等的距離內。在無監督情況,詞嵌入維度由預測的精確度決定。隨著嵌入維數的增加,預測的精確度也會增加,直到它在某個點收斂,則認為該點是最佳的嵌入維度,因為它在不影響精確度的情況下是最短的。

讓我們考慮CBOW模型的簡化版本,其中在上下文中僅考慮一個詞。這基本上覆制了一個二元語言模型(bigram)。這部分內容的詳細解釋見https://blog.csdn.net/boywaiter/article/details/83409636 在這裡插入圖片描述 如圖4所示,CBOW模型是一個簡單的全連線神經網路,有一個隱藏層。輸入層採用上下文詞的one-hot向量作為輸入,具有VV個神經元,而隱藏層具有NN個神經元。輸出層是詞彙表中所有詞的softmax。這些層分別通過權重矩陣WRV×N\textbf{W}\in \mathcal{R}^{V×N}WRH×V\textbf{W}'\in \mathcal{R}^{H\times V}連線。來自詞彙表的每個詞最終表示為兩個學習向量vc\textbf{v}_cvw\textbf{v}_w,分別對應於作為上下文和作為目標詞的表示。因此,詞彙表中的第kk個詞將具有

vc=W(k,.)andvw=W(.,k)\textbf{v}_c=\textbf{W}_{(k,.)}\ and \ \textbf{v}_w=\textbf{W}'_{(.,k)}

總的來說,對於任何詞wiw_i以及給定的上下文詞cc作為輸入,

P(wic)=yi=euij=1VeujP(\frac{w_i}{c})=y_i=\frac{e^{\textbf{u}_i}}{\sum_{j=1}^{V}e^{\textbf{u}_j}}

引數θ={W,W}\theta=\{\textbf{W},\textbf{W}'\}是以log似然作為目標函式,並計算梯度如下學習得到的

l(θ)=wVocabularylog(P(wc))l(\theta)=\sum_{w\in Vocabulary}\log(P(\frac{w}{c}))

l(θ)W=W(1P(wc))\frac{\partial{l(\theta)}}{\partial \textbf{W}'}=\textbf{W}(1-P(\frac{w}{c}))

在通用CBOW模型中,所有上下文詞的one-hot向量同時輸入,即

h=WT(x1++xc)\textbf{h}=\textbf{W}^\textrm{T}(\textbf{x}_1+\ldots +\textbf{x}_c)

單個詞嵌入的一個不足是它們無法表示短語Mikolov等[3],其中兩個或多個詞的組合(例如,像“hot potato”[燙手山芋]這樣的習語或是象“Boston Global”[波士頓環球報]這樣的命名實體)不代表單個詞的含義的組合。Mikolov等探討該問題的解決方案[3],基於詞共現來識別這些短語,並單獨訓練短語嵌入。最近的方法已經探索了直接從未標註資料中學習n-gram嵌入[23]。

另一個不足來自於僅基於周圍詞的小視窗學習嵌入,有些詞,例如goodgood的和badbad,共享幾乎相同的嵌入[24],如果用於情感分析這樣的任務[25]則有問題。有時這些嵌入會將語義上相似但具有相反情感的詞聚類到一起。這使得情緒分析任務的下游模型無法識別導致效能變差的這一原因。Tang等[26]通過提出情感特定詞嵌入(sentiment specific word embedding,SSWE)來解決這個問題。作者在學習嵌入時將損失函式中有監督情感標籤納入損失函式。

詞嵌入的普遍警告是其高度依賴於使用它的應用程式。Labutov和Lipson[27]提出了任務特定嵌入,它重新訓練詞嵌入以使它們在當前任務空間中對齊。這非常重要,因為從頭開始的訓練嵌入需要大量的時間和資源。Mikolov等[8]試圖通過提出負面取樣(negativenegative samplingsampling)來解決這個問題,負面取樣只是在訓練word2vec模型時基於頻率的負面詞采樣。

傳統的詞嵌入演算法為每個詞分配不同的向量。這使他們無法解釋多義詞。在最近的一項工作中,Upadhyay等[28]提供了一種解決這一缺陷的創新方法。作者利用多語言並行資料來學習多義詞嵌入。例如,英語詞bank,當翻譯成法語時,提供兩個不同的詞:banc和banque,分別代表財務和地理含義。這種多語種分佈資訊幫助他們解決了一詞多義問題。表I提供了現有框架的目錄,這些框架經常用於建立嵌入,並進一步結合到深度學習模型中。 在這裡插入圖片描述

C.字元嵌入

詞嵌入能夠表示語法和語義資訊,但對於諸如詞性標註和NER之類的任務,詞內形態和形狀資訊也非常有用。一般來說,在字元層面建立自然語言理解系統已引起一定的研究關注[29,30,31,32]。某些NLP任務中報告了形態豐富語言的更好結果。Santos和Guimaraes [31]應用了字元級表示,以及針對NER任務的詞嵌入,在葡萄牙語和西班牙語語料庫中實現了最先進的結果。Kim等[29]顯示僅使用字元嵌入構建神經語言模型的積極結果。Ma等[33]利用幾個嵌入,包括字元trigram,並結合原型和分層資訊,用於在NER任務中學習預訓練的標籤嵌入。

具有大詞彙量的語言的普遍現象是未知詞問題或未登入詞(out-of-vocabulary,OOV)問題。字元嵌入可以處理這個問題,因為詞不過是字母的組合。某些語言的文字不是由詞而是由字元構成,而且詞的語義含義對映為其構成字元(如中文),字元級別的構建系統是避免分詞的自然選擇[34]。因此,在這類語言中採用深度學習應用程式的工作往往傾向於在字元嵌入而不是詞向量[35]。例如,Peng等[36]證明偏旁部首(radical)級的處理可以大大提高情感分類的表現。特別是,作者提出了兩種型別的中文基於偏旁部首的分層嵌入,它不僅包括偏旁部首和字元層面的語義,還包含情感資訊。Bojanowski等[37]還試圖通過在形態豐富的語言中使用字元級資訊來改進詞的表示。他們將詞表示為字元袋(bag-of-character)n-gram,接近於skip-gram方法。因此,他們的工作具有skip-gram模型的有效性,同時解決了一些持久的詞嵌入問題。該方法也很快,可以快速地在大型語料庫上進行訓練。該方法通常被稱做FastTextFastText,在速度,可伸縮性和有效性方面比以前的方法更突出。

除了字元嵌入之外,還提出了用於OOV處理的不同方法。Herbelot和Baroni [38]通過將未知詞初始化為上下文詞的總和,以及提高學習率精煉這些詞,實時處理OOV。但是,他們的方法尚未在典型的NLP任務上進行測試。Pinter等[39]提供了一種有趣的方法來訓練基於字元的模型來重建預訓練的嵌入。這使他們能夠學習到從字元嵌入到詞嵌入的組合對映,從而解決OOV問題。

儘管分散式向量越來越受歡迎,但最近關於其長期相關性的討論已經出現。例如,Lucy和Gauthier[40]最近試圖評估詞向量表示概念含義必要方面的能力。作者發現了對詞背後概念的感知理解的嚴重不足,這些不足無法僅從分散式語義中推斷出來。緩解這些不足的可能方向將是基礎學習(grounded learning,類似於兒童學習語言的學習方式,在豐富的語言環境中學,無需標註),這在該研究領域中越來越受歡迎。

III. CNN

隨著詞嵌入的普及及其在分散式空間中表示詞的能力,需要一種有效的特徵函式,可以從構成句子的詞或n-gram中提取更高級別的特徵。這些抽象特徵將用於許多NLP任務,例如情感分析、摘要、機器翻譯和問答(QA)。CNNs因其在計算機視覺任務中的有效性而被證明是用於這些任務自然選擇[41,42,43]。

使用CNN進行句子建模追溯到Collobert和Weston [19]。這項工作使用多工學習來輸出NLP任務的多個預測,例如詞性標註、塊(chunk)、命名實體標籤、語義角色、語義相似的詞和語言模型。查詢表用於將每個單詞轉換為使用者定義維度的向量。因此,通過將查詢表應用於每個詞(圖5),輸入序列{s1,s2,,sn}\{s_1, s_2,\ldots ,s_n\}nn個單詞被轉換成一系列向量{ws1,ws2,,wsn}\{\textbf{w}_{s_1}, \textbf{w}_{s_2}, \ldots , \textbf{w}_{s_n}\}在這裡插入圖片描述

這可以被認為是最早的詞嵌入方法,其權重是在網路訓練中學習的。在[5]中,Collobert擴充套件了他的工作,提出了一個基於CNN的通用框架來解決大量的NLP任務。這兩項工作都引發了CNN在NLP研究人員中的大規模普及(截止2018年10月27日,google scholar引用分別2752和3625)。鑑於CNN已經展示了其在計算機視覺任務中的成功,人們更容易相信其(在NLP任務中的)表現。

CNN具有從輸入句子中提取顯著n-gram特徵的能力,為下游任務建立句子的富含資訊的潛在語義表示。該應用由Collobert等[5],Kalchbrenner等[44],Kim[45]開創,這使得後續文獻中基於CNN的網路大量增加。下面,我們描述一個簡單的基於CNN的句子建模網路的工作。

A. 基本CNN

1)句子建模:如圖6所示。 原始文字中句子參差不齊,需要進行預處理。按照預定義的兩個引數進行預處理。這兩個引數分別是max_len和max_features。max_len規定了每個句子的最大程度,或者句子中可以包含的word的最大個數。max_features表示只保留最常見的前max_features個詞。 經過預處理之後,輸入是一個(None, max_len)的張量,第1維表示句子數目,None表示可以接受任何數目,第2維是每個句子中包含的word的最大個數,這些word都屬於前max_features個最常見的詞。 在這裡插入圖片描述

  • Embedding層 – Embedding層的主要引數是Embedding(input_dim, out_dim, input_length)。其中input_dim=max_features,out_dim表示每個word嵌入的維度,input_length=max_len。 – Embedding層的輸出是(None, input_length, out_dim)的張量。 – 例如,圖中input_length=7,out_dim=5
  • 卷積層 – Conv1D(filters, kernal_size,activatation),其中filters代表filter的個數,kernal_size代表核的大小,activatation是啟用函式。 – 例如,圖中有三個Conv1D層,filters都是2, kernal_size自上而下分別是4,3,2, activatation沒有明說,可以是tanh或relu等。每個Conv1D兩個filter,一共6個filter。 – 輸入是Embedding層的輸出 – 輸出是(None, input_length-kernel_size+1, filters) – 例如,自上而下input_length-kernel_size+1分別是7-4+1=4,7-3+1=5,7-2+1=6
  • max-pooling層,在input_length-kernel_size+1維中取最大值,輸出(None,1,filters)即(None,filters)。 – 例如,自上而下共輸出3個(None,2) – 再將它們組合到一起,輸出(None, 6)
  • softmax層Dense(classes,activation=‘softmax’)是一個分類器,將輸入分為指定數目classes的類別 – 例如,圖中classes=2,可能是情感分析任務的positive和negative。 注意:公式(6)中kT\textbf{k}^\textrm{T}應為k\textbf{k},因為點積operation的兩個operand應該shape相同。另外還有個typo,"The filter kk is applied…“應為"The filter k\textbf{k} is applied…”

2)Window方法:基本CNN可以將整個句子建模為句子表示(由詞嵌入構成),但很多NLP任務,如NER、POS tagging,SRL(semantic role labeling),需要基於word的預測。Window方法用於解決這些任務,它假定一個word的標註只依賴於其周圍的word。 對上述模型的修改:卷積層的輸入不再是整個句子的表示,而是固定大小的以待標註詞為中心的視窗內的子句的表示。 結合CRF可以提升效果,因為CRF可以表示相鄰標註之間的依賴資訊。 結合TDNN(time-delay neural network)。Window方法中的CNN只考慮待標註詞所在視窗,而TDNN額外同時考慮所有視窗。

B. 應用

Kim [45]探索了將上述架構用於各種句子分類任務,包括情感,主觀性和問題型別分類,顯示出有競爭力的結果。 考慮到其簡單而有效的網路,這項工作很快被研究人員採用。 在針對特定任務進行訓練之後,隨機初始化的卷積核成為特定的n-gram特徵檢測器,對於該目標任務非常有用(圖7)。 然而,這個簡單的網路有許多缺點,是CNN所固有的,無法在模型中包含長距離依賴。

在這裡插入圖片描述 Kalchbrenner等[44]提出DCNN(Dynamic CNN),還提出一種dynamic k-max pooling策略,可以從序列中選擇最活躍的k個特徵,而且只保留k個特徵的順序而忽略其位置資訊。通過該策略與DCNN的結合,可以使得較小kernel_size的filter也可以覆蓋輸入句子的較大範圍,可以累積整個句子中的重要資訊。而基本CNN的較高卷積層特徵的覆蓋範圍是由最底層卷積層的kernel_size決定的。 在這裡插入圖片描述

針對情感分析任務,Ruder等[51]將句子表示與aspect向量(對應於不同情感的句子內容的表示)連線起來(concatenation)。 CNN方法通常在長文字上表現好於短文字[23]。Wang等[52]提出用CNN學習短文字的表示。因為短文字上下文較少,需要結合外部知識[53]。

Denil等[54]將DCNN用於將構成句子的詞的含義對映為從中提取摘要的文件的含義。DCNN在句子和文件兩個層次學習卷積filter,將低層的詞彙特徵合成為高層的語義概念。

CNN用於語義匹配[55]和資訊檢索[56]。CNN將查詢和文件投影到同一語義空間中,計算cosine相似度。CNN根據詞序列中的時間上下文視窗提取查詢和文件中的上下文結構,在詞的n-gram層次上表示上下文特徵。卷積層和最大池化層可以發現顯著的詞n-gram,聚合起來構成完整的句子向量。

QA領域,Yih等[57]提出通過計算查詢和知識庫中實體的語義近似度來確定知識庫中的哪些事實可以用來回答某個問題。Dong[58]提出MCCNN(multi-column CNN)來從多個方面分析和理解問題並建立其表示,利用MCCNN從構成回答型別的多個方面及問題的上下文來提取資訊。Severyn and Moschitti [59]用CNN建模問題和回答句子的優化表示,在嵌入中加入額外的問題和回答對中匹配的詞的關係資訊。

如果句子中包含多個重要事實,則最大池化會丟失資訊。為此,Chen等[60]提出DMCNN(Dynamic multi-pooling CNN)。

CNN固有的區域性連線性、權重共享和池化帶來某種程度的不變性。語音識別也需要這種不變性。Abdel-Hamid等[61]利用混合CNN-HMM模型為頻率軸上的頻移提供不變性。由於說話者的不同,經常會出現語音訊號的變化。採用有限權重共享減少了池化引數,計算複雜度降低。Palaz等[60]深入分析了以原始語音作為輸入的基於CNN的語音識別系統。

機器翻譯需要保留序列資訊和長期依賴,從結構上看CNN並不適合。Tu等[61]通過結合翻譯對的語義近似度和原文譯文各自上下文解決了這一問題。儘管沒有解決序列保留問題,但評測結果很好。

總的來說,CNN擅於從上下文視窗中發現語義線索,但包含大量訓練引數,需要大量訓練資料。另一個弱點是不能建模長距離上下文資訊,無法在表示中保留序列資訊[43, 61]。

IV. RNN

RNN [64]處理序列資訊,“迴圈”表示在序列的每個例項上執行相同的任務,輸出取決於先前的計算和結果。通常,通過將序列中的符號一個接一個送入迴圈單元,產生固定大小的序列的向量表示。在某種程度上,RNN對先前的計算有“記憶”並在當前處理中使用該資訊。該模式自然適用於許多NLP任務(因為自然語言是序列),如語言建模[2,65,66],機器翻譯[67,68,69],語音識別[70,71,72,73],影象字幕[74]。

A. RNN的特點

  • RNN序列處理的特點,使其適於表示語言的序列性
  • RNN可以建模變長文字[75, 76]
  • 對於需要建模整個句子的NLP任務,例如機器翻譯[77],RNN可以先將句子摘要為一個定長向量,再將其對映為變長的目標序列
  • RNN還支援時間分散式聯合處理。大多數像詞性標註這樣的序列標記[32]都屬於這個領域。更具體的例子包括多標籤文字分類[78],多模情感分析[79,80,81]和主觀性檢測[82]。

這並不意味RNN優於其他模型,在語言建模上,CNN也有著很有競爭力的表現[83]。CNN和RNN在建模句子時目標不同。

  • RNN試圖建立一個任意長句子與無限長上下文的組合,CNN則試圖提取最重要的n-gram。雖然CNN被證明可以有效表示n-gram特徵,這在某些句子分類任務中是近似充分的,但只有區域性的詞序敏感性,而通常忽略長期依賴性。

Yin等[84]提供了RNN和CNN之間效能比較。經過在多個NLP任務,包括情感分類,QA和詞性標註,得出的結論是沒有明顯的贏家:每個網路的效能取決於任務本身所需的全域性語義。

B. RNN模型

1)簡單RNN:Fig.9 是一個通用RNN按時間的展開圖,可以接受整個序列作為輸入。

  • xt\textbf{x}_ttt時刻的輸入
  • ht\textbf{h}_ttt時刻的隱藏狀態
  • ot\textbf{o}_tt