laxiflora的小天地

前進軟體工程師的練功之路

0%

  • 明明只學填空,為何BERT有用?

  • you shall know a word by the company it keeps

  • 詞向量並非是BERT為祖先

    • BERT(contextualized word embedding) 、 CBOW(word embedding)
  • BERT會把各個詞彙變成一個詞向量,詞義越相近的詞彙,則他們的向量相似度會更像


BERT是否真的看得懂文章?

  • 基於語言學假設,知道詞彙的意思要看他的前後文

  • 但BERT真的只拿詞彙的前後文當判別依據嗎?

    • 拿BERT做DNA分類
  • 把DNA序列(A,T,C,G)變成好幾個英文詞彙(隨機對)然後直接丟入BERT 做fine-tune training

    • BERT pretrained by English
    • ex. ATTACG -> He She She He It Us
  • 出乎意料的用有pretrain的BERT命中率比直接用隨機參數的transformer encoder模型還高 (Reference)

    • 這個實驗可以發現就算這整串文章毫無邏輯,BERT也可以表現的比完全隨機還好,表示機器就算看不懂文章,也學到了某些東西
         - 關於BERT學習過程仍待研究

   
關於BERT的研究(變形)


Multi-lingual BERT

Train BERT with different languages

  • 用多國語言訓練(pretrain)BERT,就可以解中文的資料集

  • 或許對於不同語言之間差異不大? (仍有待研究)

    • ex. 兔跟rabbit相近、游跟swim相近

老師的lab一開始也是嘗試train自己的multi-lingual BERT以查清BERT學習的方法

  • 實驗結果顯示multi-lingual BERT需要的dataset很大

    Reference

  • 但是既然語言特性並非BERT的學習重點,為何不會輸入中文,吐出日文?
    • 表示BERT還是會注意語言之間的差異
    • 那如果抵銷掉語言之間的差異呢?

   
 

  • 老師的lab實際把英文丟入BERT模型內,再加上一個向量,這個向量是英文與中文詞向量平均之間的差距,可以得出輸入英文,輸出中文的填空結果

  • 芝麻街家族與模型有很多關聯

  • BERT有340M個parameters,非常巨大

  • 下面課程主要講BERT與GPT系列

    BERT 就是transformer encoder


BERT learning technique

Semi-supervised?

- BERT用在下游任務需要labeled data做一些fine-tune,是supervised learning
- BERT pretrain過程卻不需要labeled data,是unsupervised learning

$\rightarrow$ 所以合起來稱為semi-supervised

Self-supervised?

  • 雖然是supervised learning,但是卻不需要人工標記,這種方法將訓練資料本身作為label
  • 我們會切割一部分的資料x’作為輸入,一部分的資料x’’則做為label
    • 在沒有資料的情況下,自己想辦法supervised (故在人工方面可以看做是一種unsupervised)
  • BERT的pretrain任務,就是self-supervised learning

Pretrain(Self-supervised learning)

  • 不同於supervised,self-supervised的資料沒有標註,我們會切割一部分的資料x’作為輸入,一部分的資料x’’則做為label
    • 在沒有資料的情況下,自己想辦法supervised (是一種unsupervised)

Pretrain任務1:masking input

- 會隨機把input sequence中隨機一個vector蓋掉,稱為masking input,然後讓BERT去訓練猜中原本蓋掉的詞(token)是甚麼
- mask / random
- 很像分類問題,類別量 = token總數
- BERT出來會有一個linear的matrix,做完softmax以後輸出  

Pretrain任務2:Next sentence prediction

- 任取兩個sequence,在開頭跟句子之間加入分隔符號

   - BERT要訓練去辨認這兩個例子是否相接
   - 這招不是很有效,Robustly optimized BERT approach
  - 一種可能是這個任務過於簡單

  • 另外一招:sentence order prediction(SOP)
    • 2句子本來就接在一起但亂序,要分辨誰是前面誰是後面
    • ALBERT中使用

How to use BERT

  • BERT雖然只做上述兩個訓練,但【卻可以使用在不同的任務上面 (downstream tasks)】
    • 針對不同任務,BERT仍需要做一點微調(一些些的labeled data),稱為Fine-Tune
  • 我們會讓BERT去做各種任務(任務集)取各種任務的成績以後平均

BERT 表現in GLUE

  • 1.0的基準線是人類的成績(指標不一定是正確率)

BERT實務

Case 1

  • 輸入一個sequence,輸出一個class (ex. sentiment analysis)
  • 使用pretrained data後,BERT的參數已經被初始化了(一個會做填空題的BERT),而線性層則是仍然要隨機初始化

Case 2

  • 輸入一個sequence,輸出一樣長度的sequence (詞性標註 POS tagging)

  • 處理過程同case 1

Case 3

  • 輸入兩個句子,輸出一個類別 (NLI)
    • NLI : 從前提要能推出假設

Case 4 (作業7)

  • 問答系統:給機器讀文章,問他問題要能回應
  • 但是機器只能從文章中給出答案(抓取文章的特定序列)
    • 輸出兩個正整數

  • 輸入的形狀跟case 3很像,只是後面改成文章,前面改成問題

  • 黃色向量輸出分別對橘、藍vector做內積,然後過softmax

  • 答案會是($d_i,d_j)$,其中i來自橘色,j來自藍色

Training BERT is challenging

  • google訓練最早的BERT的時候用了3 billions words

  • 訓練非常花時間,但是微調很快(colab GPU約1 hr)

  • 既然BERT都已經被訓練過了,為何還會有人想要重新訓練他?

    • 實際上訓練BERT的過程中,BERT到底學到了甚麼仍有待研究
         - 為了學習BERT的胚胎學,所以會需要重新訓練

如果今天要解的任務是seq2seq呢

  • BERT只有pretrain encoder,有沒有辦法pretrain decoder? 可以。

  • Encoder看到corrupted的data,decoder則是要想辦法把他還原

    • 弄壞資料的方法:旋轉、空白、mask…

Learning from unpaired data

  • 把GAN用在unsupervised learning
  • 如何用沒標註的資料做semi-supervised learning
    • 2021 HW3,HW5都有用到
        - 不過他們仍然需要一些paired data

影像風格轉換

  • 以影像風格轉換,要把三次元真人的圖片轉成二次元的輸出,不可能先幫3次元訓練資料畫一個二次元的圖片來pair,所以任何一筆成對資料都沒有

  • 我們可否把輸入的真人圖片變成一個distribution,輸出的圖片也是一個distribution呢?

First approach

  • 套用原本GAN的想法,只要能從x domain sample即可

    • 從domain x sample,輸出以後跟y domain做discriminator,最後輸出向量
  • 問題:

    • generator可以只訓練通過discriminator的照片,然後完全忽略輸入
      • 所以我們需要condition,但又因為沒有paired data,我們不能用condition GAN

-> 既然這樣,就用兩次GAN,看輸出能不能還原原本的圖片 -> 使用cycle GAN

Cycle GAN

同樣以影像風格轉換為例(輸入3次元人臉,輸出二次元人臉)

  • 在原本的GAN網路中再新增一個GAN,把第一個generator的輸出丟進第二個generator的輸入,第二個GAN用於產生跟原始的輸入x盡量相似的圖片    

  • 即讓$G_{x \rightarrow y}越接近G_{y\rightarrow x}$越好

  • 問題2: 機器有沒有可能亂學,「串通作弊」呢

    • EX: 機器gen1學到真人戴眼鏡,就會把眼鏡拿掉變成痣;gen2則學到看到二次元痣,就把痣拿掉換回眼鏡
    • EX2: gen1跟gen2互相對稱旋轉圖片
  • 不過在實作上這個問題發生率不高,因為network is lazy,看到眼鏡就輸出眼鏡了

  • 相反來說,我們也會需要一個discriminator來看$G_{y\rightarrow x}$(就是生成的3次元頭像是否跟原始圖像很像)

  • 如上圖,這兩個合起來就會是cycle GEN

其他做影像風格轉換的GAN

  • Disco GAN

  • Dual GAN

  • Cycle GAN

    • 這三個想法幾乎一模一樣,只是團隊不同
  • StarGAN則是可以在多種風格間轉換(Cycle只能兩種風格)

  • 進階版GAN,以及應用他的網站

文字風格轉換

  • 輸入一個句子,輸出另一個句子 (此例是把負面句子變成正面句子)

    • 依樣畫葫蘆,收集一堆負面/正面的句子(同樣沒有成對資料)
  • 套用Cycle GAN作法

  • 問題: 文字的相似度如何計算?
    自行研究

  • 輸出如果是文字接給discriminator會有問題,需要用RL做

文字風格轉換應用(除了負面轉正面的句子)

  1. Unsupervised Abstractive Summarization (摘要練習)
  2. Unsupervised Translation (翻譯)
  3. Unsupervised ASR (語音辨識)

       

  • GAN的訓練仍然困難,gen跟dis有一個卡住了,就整個卡住了
    • Generator跟Discriminator需要互相match each other

More training GEN tips

GAN for Sequence generation

  • 前面講的都是影像的GAN

  • Decoder變成了generator

  • Decoder的輸出一樣丟入discriminator訓練,產生分數

  • 問題在於,decoder不能用梯度下降去train

    • 微不出decoder weight變化對discriminator的影響(distribution不變)
  • 碰到很難train的地方,可以用用看RL

    • RL很難train,且GAN也很難train,不好用
  • 完整的GAN課程:連結

  • More generative models: VAE、FLOW-based Model

可否用supervised learning做

Quality of GAN

  • 如何衡量GAN的好壞

  • 以往都是直接真人去看效果,但可能不客觀且價格昂貴

  • 在某些任務的確可以衡量

    • (作業6)提供一個動畫,看GAN能抓出幾張是人臉
  • 分類系統,把GAN輸出的影像作為分類系統的輸入,讓這個系統分類

    • Ex. GAN產生班馬,給分類系統分類該圖像是否班馬類
    • 當分類越集中,則GAN的輸出「可能」越好
    • 問題:Mode Collapse

Mode Collapse

  • 可能GAN輸出的圖片來來去去就那幾張,過度單一,但那些圖片都剛好分類成功
  • GAN知道discriminter的盲點了,就集中攻擊這個點
  • 上圖的人臉過度單一
  • 目前暫時無解,但看得出來

Mode Dropping

  • GAN輸出的圖片看起來有一些變化性,看不出問題
  • 但可能輸出的圖片只是真實圖片的一小個子集
  • 不容易偵測出來

Diversity

  • 衡量GAN輸出的多樣性分布

upload successful

  • 與quality差別在於,quality衡量只看一張圖片,分類越集中越好

  • diversity則是看一堆圖片,輸出的平均越均衡,代表多樣性越好

  • Inception score(IS):若good quality, diversity,則large IS

  • 但作業不會用inception score

    • 輸出都是人臉,對於IS來說diversity會很小
  • 作業採用Frechet inception distance(FID)

    • 把輸出丟入CNN,再把進入softmax前的那個vector拿出來作為輸入
    • 假設真實圖片跟產生的圖片都是gaussian distribution
    • 對他們算Frechet inception distance
      • 越小品質越高
  • 問題:需要很多samples,且不知道輸出分佈是否為gaussian

    • 所以不能只看這個,作業會FID跟IS都參考
  • 有時候,FID很好(低)而且人臉也做得很真實,也未必是一個很好的model

    • memory GAN: 如果這個GAN可能是直接照抄訓練資料的,剛好符合diversity跟classification
    • 可否比對訓練資料跟輸出的相似度?
      • 也可能GAN剛好輸出都是輸入資料的左右反轉,相似度又比不出來
        -> GAN的evaluation仍為可深入研究的題目
  • 目前的GAN evaluation的作法列舉

Conditional Generation

  • 到目前為止GAN都只講隨機的輸入

  • 若給定一個x(條件),產生y

    • Text to image任務
  • 根據Sample的z不同,會產生滿足x條件的不同輸出

Discriminator

  • 必須也知道文字敘述的條件,不然GAN只會產生清晰圖片,忽略條件
  • Discriminator除了看圖片是否好,還要看是否吻合條件

  • text-image的training data通常會需要成對的資料(condition,image)

  • 但是這樣通常訓練的結果不會很好

    • 還是要mix一些label = 0(故意塞錯的) 的資料(清晰圖片+錯誤描述)

conditional GAN其他應用

sound to image

  • 給聲音,然後畫出圖片

    • 給sound一些label其實不難收集,可以爬影片然後get sound以及相關畫面
    • (sound, “a dog barking sound”)
    • (sound, “river sound”)
  • 參考網站

talking head generation

相關文獻

image to image

  • Conditional GAN也可以做image translation(輸入圖片,輸出吻合條件的圖片)

    • pix2pix
  • 老樣子,image 2 image用supervisied learning,可能會學習到類似的情況下,圖片輸入很多種,導致輸出模糊(同GAN一開始小精靈的例子)

    • 所以還是要用GAN
      • 但GAN可能還是會有想像力過度豐富的問題
      • 兩者需要同時使用
  • 相關文獻

訓練的目標

  • 訓練到底要min/max甚麼東西呢?

一維的範例

  • 要找的最佳化G參數就是
    $$
    G^* = arg\ min_GDiv(P_G,P_{data})
    $$

  • 其中Div()表示兩個distribution之間的距離(相似度)公式

  • 問題在不知道怎麼計算divergence

  • GAN可以在只有Sample的情況下,估計出div()是多少

    • 需要從$P_G、P_{data}$取樣,$P_{data}$取自圖庫,而$P_G$則取自generator產生的圖片
         - 這部分就要交給Discriminator,他要max一個objective function,公式有很多種

JS divergence

公式如下(我們要取Max)
   $$
V(G,D) = E_{y\ from\ P_{data}}[logD(y)] + E_{y\ from\ P_G}[log(1-D(y)]
   $$

  • 我們會需要來自data的D(y)越大越好,來自G的D(y)越小越好

Note: 若加上一點自由度,簡化上述公式,可以得到
$$
J^D = -D(x) + D(G(z)), for\ all\ D(x),\ D(G(z))\ \in \ [0,1]
$$
且生成器的損失函數:
$$
J^G = -J^D
$$
因為他們之間彼此對抗,所以他們兩者之間的損失只差一個負號,稱為min-max GAN

  • 其實 $D^*$ 等同於(-1) x cross entropy
    • 早年這麼設計的理由是因為,希望objective function可以跟二元分類扯上關係

  • 參考

  • small divergence,data跟G的圖很像,則hard to discrininate,則small max V(D,G)

  • 因為$max_D\ V(D,G)$與JS divergence有關聯,所以我們可以把Div()換掉,變成
    $$
    G^* = arg\ min_G [max_DV(G,D)] \\\
    D^* = arg\ max_DV(D,G)
    $$
    //D的max objetive value跟JS divergence有關

其他的divergence

  • 當然,我們也可以用不同的divergence

訓練GAN的小技巧

JS divergence 的問題

  • $P_G、P_{data}$重疊的地方往往很少

    • pf1. 圖片是高維空間裡面,低維的manifold
        - 就像在一個平面空間中的兩條線一樣,重合的地方很少
          - 在高維空間內隨便sample的點都不會是圖片
          - 所以他們相交的部分幾乎可以忽略
    • pf2.若$P_G、P_{data}$sample的點不夠多,很容易劃出一個界線把他們切開
      -> $P_G、P_{data}$重疊範圍非常少
  • 若兩個分布沒有重疊的地方,算出來的Div就會永遠都是log 2,看不出差距

WGAN

  • 換一個衡量divergense來衡量2 distribution之相似度

Wasserstein distance

  • 假設一個distribution P為一坨土,而另一個distribution Q為目的地

  • 把土堆P挪到Q所需要的移動距離平均就是Wasserstein distance

  • 因為可能的挪法很多,所以d會有不同

    • 定義: 窮舉所有的moving plan,找出最小的移動距離當作wasserstein distance
      • 計算麻煩
  • 假設我們能計算Wasserstein distance,帶來的優點:

    • 就可以解決JS divergence看不出上圖的好壞比較的問題  

Evaluate Wasserstein distance

  • 解下面的Optimization問題(下圖),解出來就會是Wasserstein distance

    [、]是期望值,D(x)就是剛剛的D(y)
  • D必須是1-Lipschitz function (Discriminator不可變化劇烈)
    • 如果沒有這個constraint,則D的training不會收斂
         - 讓D保持smooth強迫D(x)變成無窮與負無窮
    • 基本上就是保證real跟generated的data距離不會太遠

how to 確保這個式子可用

  • 原始GAN方法

    • 強迫network的parameters w bound在[c,-c]
         - 在梯度下降的para更新後,若w>c , w=c ; if w<-c , w = -c
         - 可能可以讓function平滑一點,但沒有解決問題
  • 有一篇 paper : improved WGAN 做的處理方法:

    • 在real data取sample,在fake data取一個sample,在中間再取一個sample,這個sample的梯度需要接近1 (?)

     

  • 相關方法很多,可以多查查

Q & A

Q1: 在discriminator訓練時,可否加入GAN以往的輸出

A1: 可。實務上跑的時候不會真的讓discriminator被maximize,太花時間,所以通常幾個iteration後就會轉換到generator

  • 到目前為止的network都是一個function
  • 這次則是把network當作generator使用
    • 現在的network會加入一個new variable z,現在network就有兩筆輸入了
  • z由某個simple distribution生成(distribution必須夠簡單 ex. uniform)
  • 初代GAN

Why 需要輸出是一個分布

  • 以video prediction「小精靈」為例說明
    • 給定previous frames,輸出預測下一個frame會出現的畫面
    • 但是在類似畫面下,有時候小精靈往左轉,有時候他往右轉,導致分裂(機器選擇兩面討好,這樣對兩個case的loss最小)
         -> 讓機器的輸出不再單一,而是一個機率性的分佈  

   

在機器的輸出需要創造性的時候(同一輸入可能有多種輸出),就會需要distribution
- ex. 繪圖、寫文章、對話

Generative Adversarial Network(GAN)

Anime face ganeration

  • 先把x輸入拿掉,並假設z輸入是normal distribution
  • 其實二次元人物的臉(圖片)就只是一個高維向量
  • 輸入的distribution複雜性其實影響不大,因generator會想辦法把它變複雜

Discriminator

  • 在GAN中會有這樣一個神經網路,用於判別輸出的東西是否真實
  • 輸入是產生的圖片,而輸出則是一種純量[0.1]
  • 可用CNN、transformer…等都可以

Basic Idea of GAN

示意圖:

  • 就像物競天擇的演化一樣,discriminator會去除掉得分低的GAN成品,而GAN成品就會「天擇」成discriminator比較能接受的情況

  • 但是discriminator也會進化,讓GAN必須再繼續進行進化

  • discriminator與generator通常互相視為敵人
    GAN版示意圖(毛圖注意)

Algorithm

  1. Init gen and discriminator

  2. 固定住Generator (G),輸入一陀random sampled vector,吐出成品,更新discriminator (D)

    • 拿一些「ground truth」 (ex. 真正的二次元人物),互相比較相似度,並且更新D
    • 對D來說這是一個分類問題,或是regression問題 (正確圖片標1,錯的標0),總之就是看個人想怎麼做
  3. 固定D,更新G,G要練習把D的acc升到最高(去欺騙D)

    • 把兩個neural network接起來,就會變成「輸入是一個向量,而輸出會是一個分數」,所以現在情況等同於maximize score (gradient ascent)
         - 當然固定D,所以「評分系統」不可變動
  4. LOOP,反覆訓練G、D


現代GAN

  • 接續5-2,講論文的transformer中的decoder區塊
  • Decoder有兩種
    • autoregressive(AT)
    • non-autoregressive(NAT)
  • 這堂課主講AT

Transformer:Decoder的運作 (語音辨識為範例)

  • 輸入一段聲音,輸出一段文字

  • encoder收到聲音訊號(seq)以後,輸出一排vector(seq)

  • Decoder用於產生語音辨識的結果

  • 輸出會是一個向量(one-hot vector),他的長度就是整個語料庫的大小

    • 中文通常就是一個字為單位,英文有可能以詞為單位,也可能以字根字首為單位(subwords)
  • 第一步驟的時候,decoder會輸入一個token(BEGIN),一種特殊符號

  • 接下來第二及之後的步驟,會把前面步驟輸出的字母丟入decoder作為輸入

    • 這樣的問題就是,如果前面辨識產生的結果是錯的,那後面的輸出也會受到錯誤的結果影響 (error propagation)

Transformer:Decoder結構

  • 暫且忽略來自encoder的輸入

upload successful

  • 撇除圈起來的地方不看,可以發現decoder跟encoder的差別沒有很大

masked self-attention

  • 注意到decoder第一格有一個”masked multi-head attention”
  • 相對於原始的self-attention,decoder只能參考前面的vector,不能參考之後的
  • 因為token是一個一個產生,不能考慮右邊

Determine output length

  • 目前的decoder運作機制,不知道甚麼時候該停下來 (無限自動選字的概念)
  • 需要有一個「斷」的token,塞在輸出的vector class內

Non-autoregressive(NAT)

upload successful

  • AT會把上一個字輸出出來,才產生下一個字元
  • NAT則是一次給好幾個START token,一次性產生整個sequence

Determine NAT output length

  • 如何知道NAT decoder的長度哩?
    • 另外做一個pridictor去預測NAT該輸出的長度
    • 假設一個句子的長度上限,看哪段輸出了END,就把字串砍到那個位置

NAT優點

  • 相對於AT更平行化
  • 可控的輸出長度(可以不用被動等到有END)
    • 可以發現AT是有點RNN、LSTM的思維
    • NAT是熱門的研究主題
  • 目前NAT的performance還是比較差

Transformer:Encoder-Decoder

  • 現在焦點放到剛剛圖中圈起來的地方,這裡是encoder與decoder交會的地方(cross attention)

圖示如下:

  • 做法很像一層self-attention在做的事情,只是q來自於decoder,而k,v來自於encoder

  • cross attention的相關論文

    • 這個方法不是來自transformer
         - 是先有cross才有self
  • 在原始論文內,decoder每一層cross attention都會拿encoder最後一層的輸出當輸入

    • 當然也有其他種連接方式,參考

以上是模型訓練好以後,模型怎麼去跑,接下來來談seq2seq類模型在training中碰到的小問題

Seq2Seq:Training

Teacher forcing

下圖為Transformer的最終訓練展示圖

  • 每一次預測一個單位字,就是做一次的分類問題
  • 每一個字視為一個分類問題,所以要minimize 這些所有預測+BEGIN、END各自的cross entropy
  • 在訓練的時候會給decoder看ground truth
    • 這樣做法叫做Teacher forcing

Copy mechanism

  • 很多任務不一定要decoder產生東西,而是從輸入中複製東西出來
    • Ex. User: 你好,我是庫洛洛
        Machine: 庫洛洛你好,很高興認識你
         - 機器不需要知道庫洛洛是誰,只要判別出人名複製就好
  • 機器聽不懂的話,也可以直接copy user input來再次詢問user是甚麼意思
  • 應用: 閱讀文章的摘要
  • Pointer Network、Copy network

Guided Attention

  • TTS as example(語音合成)
  • 看到過短的句子可能沒念完整,但讓她念好幾次卻發音成功
    • 嘗試強迫機器把所有看到的東西都看一遍 -> guided attention
  • 在輸出嚴格的任務中頗好用(語音合成、辨識)
  • 如果機器的觀看順序顛三倒四,表示這種attention可能會出問題
  • Guided attention就是強迫機器的attention有規範(ex.由左向右)
  • 相關參考:Monotonic attention、Location-aware attention

  • 假設這個decoder只可能產生兩個token,要輸出一段sequence,前面都是直接輸出該輪概率最高的token,稱為「Greedy decoding」

  • 但有沒有可能前面選擇非最佳的token,反倒導致後續的decode命中率更集中呢

  • Beam search找一個非最佳也不用爆搜的作法

  • 關於這個演算法,有兩方論戰:The curious case of neural test degeneration

    • Randomness is needed for decoder when generating seq in some tasks (ex.TTS)
  • 老師認為在針對答案較為單一的任務,Beam search會表現比較好;而如果需要機器的想像力(空間大)的任務,則建議需要一些隨機性(故意加一些noise)

  • TTS任務中,需要在測試集加入雜訊

    • true beauty lies in the crackks of imperfection

Optimizing evalyation metrics?

  • 作業用BLEU Score作為判斷依據
    • Decoder產生輸出以後,跟正確的句子做比較
  • 但訓練的時候資料分開計算,只能用cross entropy。這兩者之間未必正相關
  • 不一定要挑decoder cross entropy效果最好的那個模型
    • 可否在training用BLEU score?
          - 不容易,BLEU本身很複雜,不易微分
             - 當遇到opti無法解決的問題,就用RL(強化學習)硬train一發

Exposure bias

  • 因為decoder在train的時候,前面的vector是看著ground truth在做,所以不會有「一步錯,步步錯的問題」

  • 但當然在測試時不可能這麼做

  • 可以故意在training裡面加入錯的ground truth來讓模型習慣前面有錯誤輸出的應對方式 -> Scheduled Sampling

  • 在transformer中會有所變化,參考

  • Transformer與BERT之間關係密切
  • Transformer是一種seq2seq的model

seq2seq簡介

  • 由模型來決定輸出要多長
  • 語音辨識、機器翻譯、speech translation就是應用(Hw4做的是分類模型)
  • speech translation不一定是speech recognition + machine translation,因為很多語言其實並沒有文字,或不普及(ex.台語:母湯?不行?)
  • 其實有機會直接輸入台語的聲音資料,直接輸出中文(省略再翻譯的過程)

seq2seq應用

台語範例

  • 直接台語轉中文不是沒有可能
  • 但是對於倒裝(文法)上的不同會有問題

Text-to-speech(TTS) synthesis

  • 相反的,也有可能輸入中文然後合成出台語的聲音訊號作為輸出(範例是分為兩步驟,先把中文翻譯為台語羅馬拼音,之後再把他轉成聲音)

seq2seq for chatbot

  • Seq2seq也可以用在聊天機器人,輸入是一段文字,輸出則是response
    • 學習大量的日常對話(來自影集、連續劇等)

seq2seq in NLP

  • 大多數的NLP應用,都可以想成是QA問題,而QA的問題,又可以透過seq2seq model來解決
  • 不過對於NLP的任務,通常還是會針對任務特性做一個客製化的模型,seq2seq就像是瑞士刀一樣,對大多問題都可用,但不是最佳模型

seq2seq in others

  • seq2seq也可以在一些輸出看似不像是seq的問題套用

syntactic parsing

- ex. 文法解析(syntactic parsing)  


- 把一個樹狀的結構用括號硬解成一個sequence,參考

multi-label classification

  • 不同於multi-class,multi-label可以屬於多個class(同時屬於好幾類)
  • 每個data對應的label個數可能不同,不能直接用分類模型輸出前n名
  • 硬做seq2seq,輸出sequence就是class

object detection

- 物件偵測也可以用seq2seq硬做  


- 參考連結:End-to-End Object Detection with Transformers    

Seq2seq結構

encoder

  • 給定一排向量(input),輸出一樣長度的向量
  • transformer中block用的技巧就是self-attention,好幾個block就是作好幾次self-attention
    upload successful
  • self-attention詳細的執行過程請參考CH4
    • 避免見樹不見林,這裡解釋一下encoder步驟,下方再分開講解每個區塊在幹嘛。encoder就是先把輸入轉成vectors(input embedding),做完positional encoding以後,連續做好幾個block
    • 每一個block做:self-attention -> residual connection -> layer norm -> FC

Residual connection

  • 原因暫且不討論,不過這種架構在DL被廣泛應用
  • 做完self-attention之後在輸入到下一個block之前,需要進行一次的residual connection,就是把self-attention的輸出再加上自己原本的輸入

Layer norm

  • 原始transformer做完residual以後做layer norm,把單一feature的每個dimantion計算標準化

❗️ 與Batch norm的差別:
batch norm是把batch內不同筆data的同一個dimantion做標準化(橫向);
而layer norm則是把同一筆data內不同dimantion做標準化(豎向)

Fully connected layer

  • 上述做完以後,輸出丟入FC訓練,然後『再做一次residual network以及norm』以後,輸出的結果,是一個block的計算

其他形狀的encoder

作業題目

可進行的目標

  • Medium : 0.70375 (train 1~1.5 hr)
  • Strong : 0.77750 (train 3~4 hr)
  • Boss : 0.86500 (train 2~2.5 hr )

調整transformer參數與pred_layer模型

  • 包括降低multi-head數量、feedforward dropout rate等等
  • 降低pred-layer的linear connect layer層數 (這個問題複雜度不高,線性聯階層不用到兩層)

實作conformer

  • 把原本的 self.encoder_layer改掉,套用conformer模型
  • conformer來源
  • 記得修改Classifier的forward

更動transformer/comformer encode層數

  • 原本只有一層(就是self.encoder_layer),可以改成呼叫self.encoder並修改Classifier的forward

寫作業歷程

2022/7/22

這次作業transformer(self-attention)在NLP與語音辨識領域運用廣泛,是我想要好好學好的章節,不過這次作業給我挫敗感很大…
這份作業寫一整天,白天的時候在查comformer的paper,但是因為對於transformer的觀念也不甚熟悉,所以照著李宏毅老師給的reference查到了這篇paper(中文心得版),在大略的瞭解了transformer家族以後,最後回去看了一下別人看「Attention is all you need」的心得,對照上課的筆記這才更有了概念

到了晚上終於要開始著手改code,首先在torchaudio document查到了他支援的conformer model API,開始套用以後才開始發現他的問題:看似簡單的forward修改其實困難重重!

首先是最基礎的問題,因為是pytorch菜雞,我甚至連forward的意涵是什麼都不知道,後來查到原來他是__call__會呼叫的函數,通常進行一個step(單位為一batch)的計算,而這份code在訓練時會呼叫model_fn

model_fn用意在於
- 先做mels與labels的分類
- 把資料放到GPU上
- 呼叫model.forward()以及計算loss
- 最後進行predict以後算出該step之acc

搞懂了forward以後,開始著手修改forward內部的code使他貼合conformer,但因為這樣所以我也必須去查torchaudio.models.Conformer這個class裡面的forward會怎麼運作(巢狀模型),查到的資料如下:

註解寫到lengths with shape(B,),因此我很直觀的直接打了

1
2
# out: (batch size, length, d_model)
self.encoder(out,(out[0],) )

這麼做跳了一個錯誤:他抓不到out[0]的shape,我這才發現他要的是torch.Tensor type,於是我改成

1
self.encoder(out, torch.tensor(out[0],) )

仔細研究torch.tensor用法以後終於可以正確地塞tensor進去,但是我卻鬼打牆的一直卡在lengths這個參數的shape不對,從錯誤碼發現跟ket_padding_mask有關,幾經波折以後看到這篇才發現他要吃的參數是(batch size,sequence length),最後修正成了這樣

1
out = self.encoder(out,torch.tensor([out[0],out[1]]))

卻碰到了新的錯誤碼:

留待明天處理…


2022/7/23

果然是昨天腦袋昏到不好思考,把out.size(0)跟out[0].size()搞混,雖說後來修正了,但還是套不進去。對於tensor dim的掌握力太差了…

後來改用這個conformer來實作,多了很多我不知道幹嘛用的參數,而且看似不能增加layer數orz…,先求能跑吧,感覺達不到strong base line了,參數如下

1
2
3
4
5
6
7
8
9
10
11
self.encoder_layer = ConformerBlock(
dim = d_model,
dim_head = 64,
heads = 2,
ff_mult = 4,
conv_expansion_factor = 2,
conv_kernel_size = 31,
attn_dropout = 0.,
ff_dropout = 0.,
conv_dropout = 0.
)

要注意的是他的forward吃的參數是(length, batch size, d_model),所以permute那行註解要拿掉,這方面沒有統一真的很煩人,最後Classifier forward code如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def forward(self, mels):
"""
args:
mels: (batch size, length, 40)
return:
out: (batch size, n_spks)
"""
# out: (batch size, length, d_model)
out = self.prenet(mels)
# out: (length, batch size, d_model)
out = out.permute(1, 0, 2)
# The encoder layer expect features in the shape of (length, batch size, d_model).
#out = self.encoder_layer(out)
# Do 2 conformer layer
# out = self.encoder_layer(out)
out = self.encoder_layer(out)
# out: (batch size, length, d_model)
out = out.transpose(0, 1)
# mean pooling
stats = out.mean(dim=1)

# out: (batch, n_spks)
out = self.pred_layer(stats)
return out


中間有個out = self.encoder_layer(out)被註解了,我原本是想說既然參數不能設定layer數,那就讓他跑兩次也可以是兩輪,不過我想太美了,因為GPU多線程的關係,讓整個tqdm的log大暴走,正確性也打個問號,搞不好會碰到race condition…,因為這是這個模型設計者沒設計到的部分(或是我菜到沒發現QQ),所以最後決定讓他就單層去跑


作業結果

Train了70000 step (大約1 hr),跟strong差一點點,但acc還在上升,感覺是練不夠久

補了以下的code讓他繼續撿剛剛的模型train

1
2
3
4
5
if exists("./model.ckpt"):
model.load_state_dict(torch.load("./model.ckpt"))
print("Exist model detected, continue training...")
if model.training() == False:
model.train()

得到命中率=79%

但提交的時候卻出了大問題,測試的結果非常差

有查到一篇心得(下圖)也是成績暴跌,推測測試集跟訓練集的分布差很多(不過那篇作者是碰到切割長度的問題,這我沒有改不該有影響才對),這份作業做到這吧,沒力氣修正了orz,再修也會淪為調參之流,感覺學不到甚麼。
結論姑且下在data mismatch,不過模型參數與notebook我會保留在github,將來靈光乍現的時候再來看看

Report

  1. 因為卡住所以我有多看幾個varient

    • linformer : 藉由attention matrix在做sorftmax轉化以後非行滿秩的特性,降低attention matrix的維度,使得transformer的複雜度可以降到線姓
         - Sparse Attention (FP/LP) : 因為傳統transformer的複雜度過高,所以藉由讓self-attention關注的範圍由全局變成局部性,降低計算時間。FP(fixed patterns)是固定self-attention窗口大小,LP則是把它的大小變成一個可學習的參數
  2. 因為transformer雖然可以考慮sequence的全局性,但對於自己的重視程度較為有限,而CNN則可以對局部性的特徵著重關注,兩者混合起來可以達到互補提高準確性的效果。

本篇論文主要介紹Transformer的各種變體,以及他的優缺點

What is Transformer?

  • Transformer採用了Self-attention技術,並屏棄了以往對於序列資料所採用的RNN
  • 序列資料得以考慮全局性,不再像RNN那樣是序列依賴性
  • Transformer可以看作是CNN,只是每一個vector考慮的依賴性是整張圖片(把一個sequence鋪成平面,每一個vector視為一個pixel,vector維數=channel)

Transformer的問題

  • 目前的計算複雜度過高,是$O(n^2)$,使得transformer難以在輕模型下使用
  • 目前為了解決transformer過度肥大的問題,出現了許多的變種

Dense Transformer

  • transformer的起源
  • 待補

Sparse Attaention

  • 這裡開始是為了降低複雜度而延伸的變種
  • 限制self-attention的參考範圍,使全面參考變成部分參考

Fixed patterns(FP)

  • 參考範圍作為hyper-parameter存在,是訓練前先決定好的固定值
  • 常見方法有
    • Blockwise pattern : 把輸入序列切成block(batch),複雜度降為$O(B^2)$,變成$(\frac{N}{B}*B^2)$
      • 導致序列不連貫,效果”可能”有限
    • Strided pattern : 變得真的非常像CNN,採用滑動kernel的的方式,每個vector只attention自己的那塊kernel
      • 建立在假設NLP在多數情況下都是具備局部相關的前提下,免去過度參考太遠的vector所浪費的計算
    • Compressed pattern : 超級無敵像CNN(欸),用把vector壓成平面的角度會更好思考,其實就是pooling,把幾個token池化,變成一個vector後才做attention,個人認為複雜度會降為$O(\frac{N^2}{kernel_size})$

Learnable patterns(LP)

  • 相對於FP,LP是把參考範圍也作為weight給機器去學習
  • 比如routing transformer是對token向量進行k-means來將整體序列切成多個子序列

Memory

這裡看不太懂,先貼原文

memory乍一听好像有点让人摸不着头脑,其实想法也很简单。最开始是在19年的set transformer上使用。一般来说做multihead self-attention时,Q=K=V=X(X为输入序列,长度为n),而在set transformer中,作者先单独设置了m个向量(m是超参数),然后这m个向量与X做multihead attention,得到m个临时向量(这些个临时变量我们就称作“temporary memory”),接着把X与这m个临时向量再做一次multihead attention得到输出。这个过程其实就是利用这m个向量将输入序列X的信息先通过attention进行压缩,再通过attention还原,达到抽取输入序列的特征的目的。但是在压缩编码解码的过程中肯定会有信息损失,所以后来的改进方法是引入全局记忆,即设置一些token,它们可以与所有的token进行注意力交互,比如bert的[CLS],由于这些token的数目远小于序列长度,因此也不会给计算带来负担,而且往往携带了整个输入序列的信息,这就是我们可以在bert上用[CLS]作文本分类任务的原因。

Low rank methods

  • Attention matrix在經過softmax轉化以後會是不滿秩的(存在linear dependent,rank != N),所以我們可以把矩陣降維
  • k,v向量可以因此映射到kxd維,因為k為hyper-parameter,複雜度可降至 $O(nk)$
  • 範例:linformer
  • 相關論文