臉部辨識
臉部辨識是一個日益普及的技術,它可以識別圖像或視頻中的人臉,並在各種應用中派上用場。例如,你可能已經在社交媒體上使用過臉部辨識功能,來標記照片中的朋友,或者在手機上使用臉部辨識功能來解鎖設備。此外,臉部辨識技術在行人偵測、工業影像處理等領域也有廣泛應用,例如,在製造業中,臉部辨識技術可以用來識別工人,並根據他們的身份進行安全訪問控制。
目前,主流的臉部辨識開源套件包括Yolov3和MobileNetV2,兩者均基於深度學習技術。Yolov3以其精準的物體辨識能力而脫穎而出,特別擅長小物體檢測,並提供了物體在圖像中的精確位置、所屬類別以及模型對預測的確信程度。相對而言,MobileNetV2專為移動設備優化,其輕量化結構使其適用於資源有限的手機或嵌入式裝置,特別適合應用在相機和智能手機等移動設備上的即時影像處理。
如果您對臉部辨識領域抱有濃厚興趣,我們期望這些介紹的工具和套件將對您打造個人臉部辨識系統提供實質協助!
我們目前擷取人臉使用的開源套件為 yolov3。
Yolo 系列 (You only look once, Yolo) 是關於物件偵測 (object detection) 的類神經網路演算法,以小眾架構 darknet 實作,實作該架構的作者 Joseph Redmon 沒有用到任何著名深度學習框架,輕量、依賴少、演算法高效率,在工業應用領域很有價值,例如行人偵測、工業影像偵測等等。
Yolo 最大的特色是直接 end-to-end 做物件偵測,利用整張圖片作為神經網路的輸入,直接預測 bounding box 坐標位置、bounding box 含物體的 confidence 和物體所屬的類別。
(1) Yolov3 的基底網路為 Darknet-53,有 53 層,隨著網絡層數不斷加深 (數量級從 20~30 層到 ~50 層),採用了一般類神經網路加深時常用的 ResNet 結構來解決梯度問題。
(2) 使用多層級預測架構以提升小物體預測能力,特徵層從單層 13x13 變成了多層 13x13、26x26 和 52x52,單層預測 5 種 bounding box 變成每層 3 種 bounding box (共 9 種),詳見網路結構圖。使用 FPN 的架構可以讓低層較佳的目標位置和高層較佳的語義特徵融合,並且在不同特徵層獨立進行預測,使得小物體檢測改善效果十分明顯。
使用 MobilenetV2 實現人臉的辨識
MobileNetV2是以第一代為基礎來改善,延續了第一代透過深度可分離卷積(Depthwise Separable Convolution)的方式,來達到壓縮模型的目的,減少參數並提升運算速度,還新增了2項特性,層間的線性轉換方式(Linear bottleneck),以及Bottleneck之間的捷徑連接(Shortcut connections)。
MobileNetV2在深度可分離卷積方法前,增加了1X1的擴張層,來增加Channel數量,進而製造更多特徵,最後輸出時則不用線性整流單元(Rectified Linear Unit,ReLU)函數,為了避免特徵被破壞,改採用線性轉換的方式。 另一個特性則是,MobileNetV2與傳統的ResNet不同,ResNet是先壓縮維度,透過卷積萃取特徵,最後再擴張,而MobileNetV2則是相反的結構(Inverted residuals),先擴張,萃取特徵,最後再壓縮,因此,捷徑連接的是維度縮減後的結果。
MobileNetV2在深度可分離卷積方法前,增加了1X1的擴張層,來增加Channel數量,進而製造更多特徵,最後輸出時則不用線性整流單元(Rectified Linear Unit,ReLU)函數,為了避免特徵被破壞,改採用線性轉換的方式。 另一個特性則是,MobileNetV2與傳統的ResNet不同,ResNet是先壓縮維度,透過卷積萃取特徵,最後再擴張,而MobileNetV2則是相反的結構(Inverted residuals),先擴張,萃取特徵,最後再壓縮,因此,捷徑連接的是維度縮減後的結果。
實作步驟:
(1)首先由 Yolo 將影像中的人臉擷取出來,並儲存其照片
(2)再使用 MoblieNetv2 對這張照片作特徵的提取,將其格式轉換成 embedding
(3)最後將得到的 embedding 由 PLDA 對其作分類,判斷是哪位已註冊的成員或是未註冊者
參考資料:
Yolov3 論文:YOLOv3: An Incremental Improvement
Yolov3 源碼:https://github.com/AlexeyAB/darknet
ModlieNet 論文:MobileNetV2: Inverted Residuals and Linear Bottlenecks
PLDA 論文Probabilistic Linear Discriminant Analysis
1.收集資料:
(1) 原始資料集 - WIDER FACE dataset
images : 12,880
faces : 159,420
(2) 以 dlib 擷取 - WIDER FACE dataset
training images : 18,880
faces : 10,921
2.YOLO V3 tiny - 訓練參數
width : 256
height : 256
batch size : 64
steps : 220,000
3.YOLO V3 tiny - results
FPS : 50
擷取結果 :
3.MobileNet V2 - 訓練參數
(1) 訓練集 - CASIA WebFACE
以 YOLO 擷取人臉
160*160*3
圖片 : 462,120張
(2) 參數設定
epoch : 150
batch size : 32
optimizer : Adam
learning rate :
( epoch : 0, learning rate : 0.001 )
( epoch : 100, learning rate : 0.0001 )
4.訓練結果
LFW 正確率:0.87
人臉反詐欺
人臉識別技術已廣泛應用在我們生活的各個角落,例如手機解鎖、安全驗證等等。不過,這項技術也面臨著安全上的挑戰。有些不肖份子可能會利用影印出來的照片、數位影像、錄製影像或甚至是3D面具來試圖騙過人臉識別系統,藉此非法取得存取權限。在機房重地這類需要門禁控制的場所,通常得防範這類資安攻擊問題。
為了防範這類問題,學界和業界都在積極研究「人臉反欺詐」(face anti-spoofing)技術,希望幫助人臉識別系統區分出真實的人臉和那些偽造或仿造的攻擊手段。使用時透過輸入圖片或是使用鏡頭攝影,人臉反欺詐的程式會判斷輸入的人臉是否屬於「活體」,也就是直接拍攝出沒有經過處理的人臉,例如沒有濾鏡、沒有經處理過而拍出的人臉。
以往的作法都是輸入圖片,設計特徵提取鏡像反射、圖像失真、顏色等統計量特徵,合併後直接送入SVM或傳統分類器進行二分類。傳統的方式難以區別高清影像或高品質影像且泛化不佳。
傳統⽅法採⽤⼿⼯製作的特徵,如 LBP、HOG 和 SIFT 來提取紋理資訊並使⽤淺分類器,對決策邊界進行建模。這種⽅法使⽤的特徵沒有⾜夠的判別力,並且分類器的性能是有限的。這些⽅法往往會在預定義的資料集上overfitting,並且不能很好地泛化。

Learning Generalized Spoof Cues由⼀個 spoof cue generator和⼀個 aux classifier 組成,在 spoof cue generator 採⽤ U-Net 架構,在多個尺度上建⽴從編碼器到解碼器的連接以⽣成 spoof cue。選擇在 ImageNet 上預訓練的 ResNet18 作為編碼器 E,其中包含四個編碼器 Residual block。在編碼器 E 之後,由五個解碼器 Residual block組成的解碼器 D 將資訊解碼回以⽣成 spoof cue。在每個解碼器 Residual block 中,前⼀層的特徵圖透過最近鄰插值進行上採樣,然後我們加入⼀個 2×2 卷積。最後第四個解碼 Block 輸出使用 activation Tanh 使其正規化 -1到1。Decoder的五個block輸出進行三元组度量學習,輸出 spoof cue map 進行L1回歸正則化,最后將 spoof cue map 加回到原始圖像進行二分類。
-
收集資料:
(1)原始資料集 - FaceForensics++ Dataset (人臉視頻)
Actors - 基於 DeepFakeDetection 的正常原始人臉。
Youtube - 正常的人臉。
DeepFakeDetection - 加入 mask。
Deepfakes - 加入 mask,三種壓縮程度及泊松圖像編輯過的影像/圖像,基本上就是加上一些雜訊紋路,像截圖或是影印的樣子。
Face2Face - 加入 mask,臉部表情轉移到另一人。
FaceSwap - 加入 mask,換臉。
NeuralTextures - 加入 mask,材質紋路還有陰影的變化。
(2) 以 MTCNN 擷取視頻中人臉 - FaceForensics++ Dataset -
LGSC模型訓練參數
-
loss_coef
- clf_loss:5.0
- reg_loss:5.0
- trip_loss:1.0
- lr:0.00008
- epoch:73
- optimizer:SGD
- batch size:16
- use_balance_sampler:True
- use_focal_loss:False
-
loss_coef
-
訓練結果
(1) FaceForensics++ Dataset
APCER(%):3.1
BPCER(%):2.25
ACER(%):2.675
Loss:2.12
Accuracy:0.99873
(2) 以 Oulu-NPU dataset 驗證泛化結果
Oulu-NPU 資料集中的真實和攻擊影片,是用六台移動裝置 (Samsung S6 edge, HTC Desire EYE, MEIZU X5, ASUS Zenfone Selfie, Sony XPERIA C5 Ultra Dual 和 OPPO N3) 的鏡頭錄製。共有三種不同的光照條件和背景場景 (Session 1, Session 2, Session 3),在本資料集中考量的攻擊方式為print 與 video-replay,這些攻擊是由兩台印表機 (Print 1, Print2) 和兩台螢幕 (Display1, Display 2) 創建。其中分成四個 protocol 做泛化性評估。
Protocol 1(光照及背景):
APCER(%):1.5
BPCER(%):1.86
ACER(%):1.68
Protocol 2(不同影印機及螢幕):
APCER(%):1.84
BPCER(%):1.91
ACER(%):1.875
Protocol 3(不同攝像頭):
APCER(%):2.732
BPCER(%):3.81
ACER(%):3.271
Protocol 4(綜上三個protocol):
APCER(%):7.97
BPCER(%):3.42
ACER(%):5.695
智能 AI 畫家
生成對抗網路 (Generative Adversarial Network, GAN) 模型是種非監督式的機器學習方法,藉由兩個或多個網路相互博弈的方式學習解決問題。常見的商務應用除了單純的不同主題或風格的圖片生成外,近年來也有文字轉譯生成圖片 (Text-to-image) 的應用。在商務應用方面,以 DALL.E 模型為例,它是基於 GPT-3 模型所開發出的一個 Text-to-image 模型,可以藉由讀取使用者輸入的一段文字,如輸入「一張酪梨外型的椅子。」、「一個臥室裡擺著白色的床,床旁邊有床頭櫃及一個魚缸。」、「一隻水豚的特寫畫面。」等,即可產生相對應的圖片:





圖1:DALL-E 架構(來源:https://www.zhihu.com/question/447757686)
訓練主要分成三個階段, 前兩個階段對應到論文中提到的 Stage One 和 Stage Two。
- 第一階段: 訓練一個dVAE模型, 將每張 256x256 的圖片 encode 成 32x32(1024) 個token 表示。
- 第二階段: 用 BPE-encoder 對 text 進行編碼, 上限為 256 個token, 如果編碼後 token 不滿 256, 就會用 padding 去補滿。接著就有如圖1中間的部分, 將Stage1 圖片的 token(1024) 和 text 的 token (256) 合併, 得到總長 1280 的 token。最後將 token 輸入到 Transformer, 去生成圖片。
- 第三階段: 對生成的圖像做採樣, 並使用 CLIP 對採樣結果做排序, 得到與文本最符合的圖像。

圖2: Style Transfer 架構 (來源: https://arxiv.org/pdf/1603.08155.pdf)
分為兩個 component:
- Image Transform Net : 將 input 轉換成想要的 output image (yhat)。
- Loss Network : 對輸出的 image (yhat) 計算 loss 。除了對照與 target 內容的特徵是否相似外, 也看是否和預期的 style (如: 顏色,文理等) 相似。
將文字透過 DALL-E 轉換成圖片後, 再輸入到 Fast-Neural-Style, 對圖片加上想要的style。

參考資料:
- DALL-E 論文 : https://arxiv.org/pdf/2102.12092.pdf
- Fast-Neural-Style-Transfer 論文 : https://arxiv.org/pdf/1603.08155.pdf
- Pretrain 模型(DALL-E) : https://github.com/lucidrains/DALLE-pytorch/discussions/131
- Pretrain 模型(Fast-Neural-Style-Transfer): https://github.com/eriklindernoren/Fast-Neural-Style-Transfer

- Optimizer: Adam
- Learning rate: 從0.00045 * 8(gpu) 開始, 並使用 ReduceLROnPlateau
- Apply loss weighting (PR: Add loss weighting by following DALLE paper #134)
- No gradient clipping for better loss convergence
- However, for the larger dataset, gradient clipping is necessary to avoid NaN.
- Batch size: 110 * 8 (gpus)
-
CUB200
Text:這隻鳥有粉藍色的翅膀、紅色的腹部。
Style:Starry Night
-
COCO
Text:兩個男人坐在一張桌子的附近。
Style: Mosaic
- 智能 AI 畫家 -
本系統將展示透過 Dall.e 模型針對輸入的文字產生相對應的圖片,並將產生的圖片套上 Style Transfer 的效果(本系統提供三種效果 Starry Night、Cuphead及 Mosaic),最後呈現結果給使用者觀看;此外,若使用者想根據自己的句子產生圖片,亦可填寫連結內的表單,即可使用本系統產生對應圖片並進行下載,歡迎大家踴躍嘗試!
圖像修復
圖像修復(Image Inpainting)是一項用來修補損壞或不完整圖片的技術,目的是通過填補缺失或受損的部分,使圖像恢復原本的外觀或改善其視覺效果。這種技術廣泛應用於藝術作品的修復、舊照片的重建、甚至在電影製作中去除不想要的物體。舉例如果一張珍貴的舊照片被撕破或弄髒了,圖像修復技術可以被用來消除這些破損,使照片看起來像重新拍攝的。
我們使用 Stable Diffusion 來做圖像修復,Stable Diffusion是一種圖像生成式模型,透過學習大量圖像數據,來理解圖像的結構和內容。使用時將圖片需修復地方塗白,讓模型預測缺失部分的內容,並生成與原圖協調一致的圖像,從而達到修復的效果。

- 此模型的作用是為了將圖片轉換成維度更低的潛在表徵, 可以想成把圖片重要的資訊壓縮成更低緯度的資料, 再把它傳到下個步驟。
- 在inference的部分, 會從去噪後的潛在表徵, 透過解碼去生成一張圖片。
- 輸入是已經加入噪音的圖片, 並學習如何將圖片去噪, 還原成原本沒有噪音的圖片。
- 將文字編碼後傳入 U-Net, 去控制圖片生成的分佈。這裡的作用,是要讓圖像生成時能依文字的語意去生成。
- Stable Diffusion 論文 : High-Resolution Image Synthesis with Latent Diffusion Models
- Pretrained 模型 : Stable Diffusion Image Inpainting
- 先上傳想要的圖片(圖片格式: JPG, PNG JPEG)
- 輸入您要的文字條件
-
設定參數 guidance scale 以及 Inference steps
- Guidance scale(引導尺度) : 控制模型遵循prompt的程度, 尺度越低, 模型的創造力越強, 尺度的越高, 創造力越低。
- Inference steps(推論步驟) : 模型降噪的步數, 步數越高, 會花越多時間(50steps/4secs) , 高的值可能會有好的效果, 但超過某個值後, 有可能會開始多出新的資訊。在30-50 的範圍通常會有不錯的效果。
-
選擇遮罩方式, 並生成圖片
- 刷子: 可以自由塗上想要遮罩的部分, 然後點選畫布左下角的下載按鈕, 再點擊 “Generate Image”。
- 自行準備: 自己上傳準備遮罩圖片, 再點擊 “Generate Image”。

語音合成與辨識
隨著科技發展,人機互動的情況已經越來越普及,像是Google小姐、智能導航、有聲書讀物等等,接已還繞在我們生活,而這些應用當中,語音合技術就扮演了相當重要的角色。
雖然語音合成的產品眾多,且能產生中文語音的技術也已成熟,但合成的中文語音大多數為『大陸腔調中文語音』,此結果的原因主要是因為可大量取得的中文訓練語料,皆由大陸腔調的語者錄製而成。因此我們希望透過不同的訓練資料、不同的訓練方式,用現有的中文訓練語料,合成好的語音品質、接近人類自然語音的『台灣腔調中文語音』。
一個完整的語音合成系統(Text-to-Speech),是由合成器與聲碼器所組成,合成器是將 我們輸入的文字輸出一個梅爾頻譜圖,聲碼器則將梅爾頻譜圖作為輸入,最後輸出一 個語音訊號,而目前我們所使用的合成器模型為Google提出的Tacotron-2,聲碼器模 型為ESPnet團隊開發的Parallel WaveGAN,兩者皆為可訓練的神經網路。
在合成器Tacotron-2,先使用訓練資料Biaobei(單一女性語者,12小時,大陸腔中文,3-5秒)加上將Biaobei的資料分割出短句(單一女性語者,37分鐘,大陸腔中文,0-1秒)加入資料集中當成預訓練,接著使用部份經過人工處理的NER(單一女性語者,2.2小時,台灣腔中文,5-8秒)加上將NER資料分割出短句(單一女性語者,12分鐘,台灣中文腔,0-1秒)繼續訓練。
• -語音辨識
現今語音辨識已經成為我們生活中常見的應用,並且可以帶來許多便利,例如 Siri、Google Assistant,我們可以透過講話使人工智慧 (AI) 來為我們做事。目前我們使用的開源套件為 ESPnet,它是一個專門處理語音任務的工具,主要是用 pytorch撰寫,並結合 kaldi進行前處 理。使用深度學習的方法替代了傳統自動語音辨識的訓練方式,用單個模型替換傳統自動語音 辨識的多個模塊,移除了對語音處理的方法使用,包含對音檔文本的強制對齊 。
傳統語音識別可由三個部分組成,聲學模型、詞典、語言模型,聲學模型通常代表的是我們說話的聲音,而一個詞可以分為多個音節組成,還需要詞典提供文字對應的音節,因此我們訓練聲學模型和詞典可以知道文字該對應哪些音節,擁有聲學模型後,語言模型包含了各個詞彙之間順序的機率大小,可以幫助我們知道怎樣排序詞彙可以更加通順,而其中的聲學模型和語言模型是分別訓練的,各自有各自的目標函數,由於各個模塊間不能互相取長補短,往往也使得最後所訓練出的網絡不能達到最優化。
語音合成架構由合成器與聲碼器組成,合成器使用的是Tacotron-2模型,聲碼器使用 的是Parallel WaveGAN模型。以下將各別簡單介紹。
Tacotron-2由Google Brain於2018年提出,模型主要由 Encoder、Location Sensitive Attention、Decoder構成。資料進行訓練前必須做前處理,中文文本會經過轉換得到 漢語拼音,聲音訊號也會截取出梅爾頻譜圖。在訓練過程,文本作為Encoder的輸入 ,梅爾頻譜圖作為Decoder的輸入。整個神經網路由多層Convolution、LSTM、Fully Connected組成,透過對文字編碼、將與之成對的梅爾頻譜圖解碼,一次解碼出一個 frame,直至Stop token機制觸發,梅爾頻譜圖則產生完畢,如下圖一。
產生的梅爾頻譜圖透過聲碼器產生聲音訊號,這邊使用可訓練的神經網路Parallel WaveGAN代替演算法Griffin-Lim,藉此提升合成的語音品質。Parallel WaveGAN是 一個生成對抗網路,由一個Generator(這邊使用Waveglow)及一個Discriminator兩個 網路來生成語音。輸入為聲音訊號擷取出的梅爾頻譜圖以及高斯分佈所產生的random noise經由Generator生成出語音檔。而生成出的語音檔會與ground truth語音檔作為 Discriminator的輸入,並透過最小化Adversarial loss以及計算STFT loss來訓練 Generator網路生成出語音檔的品質,以及最小化Discriminator loss來訓練 Discriminator判別語音檔為真或假的能力進而加強Generator所生成因檔的品質,如下 圖二。
圖一、Tacotron-2模型架構(自行繪製)

圖二、Parallel WaveGAN(參考原始論文圖)

參考資料: Tacotron-2論文: https://arxiv.org/pdf/1712.05884.pdf
Tacotron-2源碼: https://github.com/NVIDIA/tacotron2
Parallel WaveGAN論文: https://arxiv.org/pdf/1910.11480.pdf
Parallel WaveGAN源碼: https://github.com/kan-bayashi/ParallelWaveGAN
• 語音辨識
目前使用的模型為混合 CTC-Conformer 的 End-to-End 架構。 在連續性時序分類( Temporal Classification, CTC )的訓練前,不需要將每個音框強制對齊到 label,因此 CTC 適用於輸入特徵與輸出標籤之間關係不確定的時間序列問題。
Conformer 為合併Transformer架構以及CNN module的架構,此作法是因為Transformer中 擅長在全域(global)的交互作用下抓取資訊,而CNN對於鄰近的(local)區域下有較好的效果, 因此合併這兩個架構而得到Conformer。
混合CTC-Conformer架構中,CTC以及Transformer Decoder會共享Conformer Encoder,並 且會結合CTC以及Transformer Decoder的loss function進行參數更新。網路架構如下圖三

參考資料: Conformer : https://arxiv.org/pdf/2005.08100.pdf
Improving Transformer-based End-to-End Speech Recognition withConnectionist Temporal Classification and Language Model Integration: https://www.isca-speech.org/archive/Interspeech_2019/pdfs/1938.pdf
ESPnet: https://github.com/espnet/espnet
語音合成的架構由合成器Tacotron-2與聲碼器Parallel WaveGAN組成 以下將簡單介紹兩個模型的訓練資料及訓練方式,訓練資料參考表1。
在合成器Tacotron-2方面,使用Biaobei作為預訓練的訓練資料,為大陸腔中文,由單一女性語者錄製,而為了生成出品質較好的短音檔加入由資料集切割出的短語音檔加入資料一併訓練,總時長約12小時加上37分鐘,每筆音檔由5~7秒以及0~1秒組成,共11112筆音檔,接著使用NER的部份資料集繼續訓練,只使用部份資料的原因,第一原因是此為多語者資料集,容易導致訓練出來的合成品質較差,第二則是因為此資料集的每筆音檔皆為30秒,較長的音檔對於模型不易訓練,因此利用人工方式對音檔進行裁切,並對文本內容再次校正對齊,以致能產生的新資料量有限,這也是導致使用預訓練方式的原因。經過處理後並實際使用的資料為台灣腔中文,單一女性語者,總時長為2.5小時,每筆音檔約略8~10秒,前面提到為了生成出品質叫好的短音檔,將處理後的台灣腔中文資料在細切割出短音檔,共1870筆音檔。整體的訓練時間為2~3天。
在聲碼器Parallel WaveGAN的部份,是直接使用Biaobei資料集,為大陸腔中文,由 單一女性語者錄製,共10000筆音檔來做訓練。
表1、模型使用的資料集與訓練方式

• 語音合成
我們使用此架構自行訓練中文語音模型,使用 NER、Aishell 及科技大擂台做為訓練資料,約 221 小時,共85,106筆音檔(如表2)。
目前有兩個測試集文本,其中一個測試集為FSRC2018這個比賽所提供的測試集。
另一個測試集為自行錄製的音檔,三位語者,約0.75小時,共1008筆音檔。測試集文本內容 為中山無人書店聊天機器人中使用者常用的語句 (如表3)。
目前模型準確率在這兩個測試集下可以達到88.8%以及80.9% (如表4、5)。
準確率為( 1 - CER ) %,CER (Character Error Rate) 計算方式為 (辨認錯誤的中文字數量 (插入+刪除+替換) / 答案的總中文字數量 * 100%。
表2、

表3、

表4、

表5、

試玩程式說明:
此 Web 程式可開啟麥克風進行錄音,可將語音 (中文) 轉換成文字內容。
操作流程:
- 按下 Record 開始錄音 (若要暫停則按下 Pause,恢復錄音請按 Resume)
- 錄完音後按下 Stop 可結束錄音
- 出現剛才錄製的音檔
- 點選底下 Save to disk 可下載音檔
- 按下 Recognize 並稍待幾秒後將出現辨識後的文字

• 語音合成
試玩程式說明:
此網頁可進行語音合成。在『請輸入文字』處,輸入想要合成的文字,按下"合成"按鈕,即可將文字合成語音。播放音檔的右邊處,可下載此合成音檔。
有三種合成方式:
- 台灣腔語音:支援中文文字合成
- 北京腔語音:支援中文文字合成
- 多語言語音:支援中英混合文字合成

聊天機器人
電腦和人類之間互動的方式,隨著時代進步越趨於自動化、智慧化,因而逐漸發展出以模擬人類對話情境,取代既有人力的對話系統、聊天機器人,來解決商業上或其他領域上的任務。
如 Google 的 dialogflow、Facebook 的 wit.ai、Microsoft 的 LUIS,都有推出類似的對話系統平台,提供使用者在上面建立聊天機器人,但如果你想對你對話系統的訓練資料,做客制化的訓練模型或其他相關的更動,是沒有辦法辦到的,對於開發者來說靈活度不高,因此我們找了許多軟體或套件,最後選擇了 Rasa NLU 和 Rasa Core,功能成熟度高、架構完整性高、也能很好的整合到其他系統上,也因為它在 Github 上關於對話系統的開源專案,是最多人在關注的。
Rasa NLU 以及 Rasa Core 此兩個工具,是以機器學習 (Machine Learning) 的方式為基礎來建構對話系統的開源套件,Rasa NLU用以將使用者輸入的句子解析,找出句子的意圖、辨識句子中有提到的實體/對象,讓後續對話系統能以此為基礎,正確的回覆使用者。而Rasa Core 則是整個對話系統的核心,紀錄整個對話過程、預測並決定聊天機器人下一個該採取的動作/回覆應該是什麼,與使用者對談互動。
目的希望能提供儘管不是此領域、但有興趣開發實作聊天機器人的使用者們,能夠透過上述工具/套件來踏出第一步,建構自己的聊天機器人!
Rasa NLU:
為自然語言理解的模組,裡面結合了許多可以處理自然語言的套件和機器學習的函式庫,透過將這些個別處理自然語言不同部份的功能,依需要加入到 pipeline 當中,來解析輸入的句子,得到我們所需要的使用者意圖、關鍵詞/實體和其他資訊。
Rasa Core:
為對話管理的模組,主要在建構聊天機器人,為整個形成對話系統的關鍵。有別於一般對話系統,以建立 state machine 的方式 (if/else),來達成機器人回覆內容或採取動作的改變,Rasa Core 是以故事 (stories) 當作其訓練資料,用來模擬真實對話的情境,每則故事當中都記錄了使用者輸入怎樣的意圖時,機器人該採取怎樣的動作,也就是對話一問一答的流程。所以在 Rasa Core 的部分會藉由 Tracker 所記錄的前幾次所採取的動作、目前的對話流程、得到的使用者意圖和關鍵詞/實體,把所有這些資訊傳送到 Policy 的部分,轉成特徵向量以單層的 LSTM,來訓練一個 Keras policy model,會得到所有動作的機率分布,便可以拿來預測機器人最有可能的下一個動作是什麼。
架構圖:
ref : https://arxiv.org/abs/1712.05181
- 使用者輸入的句子傳輸到 Rasa NLU 解析器 (Interpreter),辨識出意圖和提取出實體,或其他資訊。
- Rasa Core 部份裡面的追蹤器 (Tracker) 會去記錄使用者狀態和輸入進來的句子中的資訊,以及整個對話流程。
- 政策 (Policy) 的部分,會去接收追蹤器 (Tracker) 中當前對話流程所擁有的資訊,轉成特徵向量來訓練一個機率模型,回傳各個動作的機率後,依此來預測。
- 選取機率最大的動作 (Action),作為對話系統回覆使用者的下一個動作。
- 將選定的動作記錄到追蹤器 (Tracker) 當中。
- 最後執行動作並輸出訊息回覆給使用者。
說明:
目前常見的聊天機器人 (chatbot) 主要分為兩大類,一種為任務導向 (Task-oriented) 的聊天機器人,以數位助理為其主要定位,幫助使用者完成特定的任務,而另一種則為社交型、純聊天 (Chit-chat) 的聊天機器人,沒有要解決特定面向的問題,以閒聊、互動為其主要目的。
以下將介紹利用 Rasa NLU 以及 Rasa Core,來建置一個任務導向的數位助理時的訓練過程、需要提供什麼類型的資料,以及當建置完成數位助理後,可以整合到哪些社群平台。
如果可以不用打電話,只需線上詢問就能簡單完成餐廳的預訂,是不是方便許多?因此當我們想建置一個餐廳搜尋預訂的數位助理的時候,首先,我們需要去制定數位助理所處在的迷你世界,才能讓數位助理可以辨識使用者輸入句子,使得它可以給予使用者正確的回覆,不會答非所問。
在一開始定義領域 (Domain) 的時候,需要來定義下述表格中五個部份的內容,以用來在 Rasa NLU 中建構可以解析使用者輸入進來的訊息的解析器。
intents (意圖) | 使用者輸入的句子所想表達的意圖。(意圖 : 預訂餐廳) |
entities (實體) | 使用者輸入的句子中有哪些資訊。(可以是人數.地點.餐點類型等等) |
actions (動作) | 機器人可以採取的動作和回覆。 |
slots (暫存槽) | 在對話過程中會追蹤同一使用者輸入的資訊,暫存在一個 slot 當中。 |
templates (模板) | 定義機器人該回覆什麼對話內容。 |

在 Rasa NLU 當中,定義的領域 (Domain) 格式如下方 domain.yml 範例所示,能讓你更了解該如何定義你的數位助理的領域:

2. 訓練資料準備及格式要求。
定義好領域 (Domain) 的檔案之後,接下來需要準備訓練資料,以下分為兩個部份來介紹:
◎ 自然語言理解 (Natural Language Understanding):
用來訓練在 Rasa NLU 的解析器,使得能正確的解析使用者輸入的訊息,在準備此訓練資料的時候,需要注意的是要為輸入的訊息,標籤上正確的意圖和實體,才不會在後續與數位助理對話時,有混淆語意、無法辨識的情況發生。
- 格式:
以 json 形式儲存,包含意圖和實體在訊息當中的位置資訊。 - 使用工具:
Rasa NLU 官方套件有提供一個視覺化的圖形介面:Rasa NLU Online Trainer,可以讓使用者在介面上,為每一個輸入訊息,標籤上其所屬的意圖和擁有的實體,讓準備自然語言理解的訓練資料上,能夠更加方便。
網址:https://rasahq.github.io/rasa-nlu-trainer/
◎ 對話情境故事 (Stories):
使用者要和數位助理產生對話互動,需要仰賴建立對話情境故事 (Stories),訓練資料中會有多則的故事 (Stories),當中定義著當使用者輸入的是怎樣意圖的訊息時,該回應怎麼樣的動作,在訓練對話模型的時候,便是依賴這些資料來建立預測數位助理下一步最該採取什麼動作的機率模型,所以如果能有大量的故事 (Stories) 來訓練,預測的效能會更好,也能回覆使用者回覆得更精確。
- 格式:
每一則故事的定義格式如下所示,就像模擬現實世界人與人的對話流程,以一個意圖對應一個數位助理要採取的動作,一問一答的方式,建構整個對話系統。 - 使用工具:
當要建置少量的故事 (Stories) 時,是可以使用手動的方式來達成,但是,如果想要讓回覆更精確,勢必需要大量的故事來訓練整個模型,這個時候就不可能一一用手工的方式來建置,此處是接觸建置功能完善的數位助理,最困難麻煩的地方,要取得這樣的故事 (Stories) 格式資料,或是自己轉成 Rasa Core 可以接受的格式,都是一件不容易的事,需要耗費的時間和成本最大。
雖然,Rasa Core 上有提供一個 Interactive Learning 的功能,可以透過終端機視窗,以和系統邊互動邊學習的模式,校對故事的對話流程,是否合乎邏輯,耗費的時間相比起來稍少,但一樣需要人類在旁監督、除錯,是否能完整的包含常見的對話型態,也是一個問題,因為這會影響到數位助理在判斷下一步該採取什麼動作的時候之預測準確率。
◎ 自然語言理解模型 (NLU Model):在 Rasa NLU 中要建構一個解析器解析輸入的訊息,而解析器是由一系列的單元元件所組成的,包括提取實體、意圖分類、文字的前處理等等的流程,因此,需要定義組合一個流程管道 (processing pipeline),訂定 config.yml,挑選一系列單元元件,取得訓練資料的特徵,來建立模型。
因為其他許多語言已經有預先訓練好通用且大量的詞向量,所以能夠利用這些預先訓練好的詞向量,建立模型來為訊息分類,但由於中文部份尚未有這麼大量的預先訓練好的詞向量,所以如果採用此種方式建立模型,分類的效能會差許多。
因此,中文的部分是使用 tensorflow_embedding 為主體,來建立模型,此種方式不需要預先訓練的詞向量,而且因為是從訓練資料中去擷取特徵,所以他可以很好的配適該領域的資料,分類的效能佳。
以下範例為一個用以解析中文訊息的 NLU 模型,所需訂定的 config.yml 和挑選的 pipeline:
- 以JIEBA斷詞,再以訓練資料來建立意圖的特徵向量,然後透過將使用者輸入的訊息和意圖的標籤映射到相同維度空間,進行模型分類:
◎ 對話政策模型 (Dialogue Policy Model):
在 Rasa Core 當中,會以 Tracker 所記錄的前幾次所採取的動作、目前為止的歷史對話、以及從 NLU 模型的輸出所得到的使用者意圖和關鍵詞/實體,當作訓練的資料。將所有訓練的資料都傳送到政策 (Policy),設定參數、參考前多少個的歷史對話,轉成特徵向量以單層的LSTM,來訓練一個Keras policy model,然後會得到所有動作 (Action) 的機率分布,便可以拿來預測數位助理最有可能的下一個動作是什麼,回覆使用者正確的語句。
透過建立上述兩個模型,你已經有一個NLU模型可以判斷使用者輸入訊息的意圖和實體,以及一個對話政策模型根據使用者輸入的訊息和到目前為止的對話狀態,來預測數位助理下一步該做些什麼動作,如此一來,將這兩個模型結合在一起,成為一個數位助理的核心思想中樞,即可以完成一個線上餐廳預訂的數位助理了!
除了可以將建構好的數位助理,串接到個人網頁上,也可以串接到其他社群平台,為使用者解決問題、提供協助,給予不同領域或商業上的應用,以下為有支援整合的社群平台:
- Slack
- Mattermost
- Telegram
- Twilio
- RocketChat
- Microsoft Bot Framework
參考資料:
1. https://rasa.com/
2. https://github.com/RasaHQ/
3. https://github.com/RasaHQ/rasa-nlu-trainer
4. ”Rasa: Open Source Language Understanding and Dialogue Management”, Tom Bocklisch, Joey Faulkner, Nick Pawlowski, Alan Nichol, 2017 NIPS. (https://arxiv.org/abs/1712.05181)
結果說明:
我們透過對資料來擴充來補足資料的不足。除了我們原有的資料外,我們另外用了rule based方式對模板進行填詞。用pmi和word2vec從文章翠取關鍵字來當作我們填入的詞。
資料原有為542筆,擴充後達到了 6500 多筆。同時我們也對測試資料也做了一樣的擴充
在f1 score上由於我們是階層式的分類任務,採用的基於集合重疊程度的計算方式。使用者意圖分類任務的結果: f1 分數達到 0.934。如圖1
圖1

圖2

Demo 影片:
時間序列數據分析
簡介:
現實生活中許多變動可以透過時間的遞延來作觀察,而時間序列分析是指將某一現象所發生的變化作為分析,依照時間先後順序排列的資料點,可以用來觀察隨著時間移動此現象的變化規律,進而預測未來此現象發展的方向。當今常見的時間序列資料如:股票、國民生產毛額 (GDP)、空氣懸浮粒子指數、車站流量...等。
功能:
將資料整理成 Predictor Variable (自變數) 與 Target Variable (依變數),並指定相關參數 (參考幾個時間點前、要預測多少個時間點...等),模型會將預測的結果輸出出來。
目前只要使用長短期記憶(Long Short-Term Memory,LSTM)這種遞歸神經網路(Recurrent Neural Network)來進行時間序列分析即可達到不錯的效果,因此我們選擇自行撰寫這個功能。
LSTM 是一種神經網路模型,為 RNN 的變形,適合處理和預測時間序列資料、文字資料...等。
我們使用 LSTM 來進行預測,LSTM 為 RNN 的變形,RNN 透過將輸入與前一個時間點的輸出合併進行運算,用以預測時序相關資料,但單時間一拉長,便容易有梯度消失的問題,而 LSTM 的出現解決了此問題,讓模型能記憶到更長久前的訊息,使得預測更加準確。

參考來源:
https://colah.github.io/posts/2015-08-Understanding-LSTMs/
傳統方法:
- 自回歸模型 (Autoregressive Model,AR):
先根據預測目的和要求,對預測目標的時間序列資料加以整理,並將這些數列劃分為應變數和自變數數列。應變數序列的週期長度(即項數),可以根據所要反映的周期變動規律。自變數數列則可用原時間數列向後逐期推移取得。
再來計算各個自變數數列的自相關係數,自相關係數的計算方法如同一般相關係數的計算方法。根據自相關係數的大小,選擇自相關係數較大的自變數數列,來擬合回歸模型。自回歸模型可以是線性或是非線性的;如果自回歸模型中只有一個自變數,稱為一階自回歸模型;兩個自變數則稱為二階自回歸模型。
而回歸模型參數的求法,和其它回歸模型一樣。要預測的自變數,就是自變數數列的下一期數值。除此之外,對於預測值的可靠性檢驗,也與其它回歸模型相同。 - 移動平均模型 (Moving Average Model,MA):
一個MA(q)模型,稱為 q 階移動平均模型,過去我們說的移動平均線是指過去的價格加權平均所得到的估計值,但在這裡我們要針對一個隨機過程去預測,隨機過程的估計是現在到過去 q 期的隨機衝擊之加權平均:
簡而言之:
AR 模型是通過分析研究歷史資料對當前資料的影響進行建模。
MA 模型是用過去各個時期的隨機干擾或預測誤差的線性組合來表達當前預測值。
- 自回歸移動平均模型 (Autoregressive Integrated Moving Average Model,ARIMA):
ARIMA 模型是由 George Box 和 Gwilym Jenkins 於 1970 年提出的時間序列預測方法,全稱為 ARIMA(p, d, q) 模型,p 與 q 分別為 AR 與 MA 的參數。相較於 ARMA 模型只是單純結合 AR 與 MA, ARIMA 多了一個參數 d,而在時間序列的穩定態處理中,可以透過差分使得資料變得更為穩定。但有時候並不是一階差分資料就會完美的呈現定態,這時候 ARIMA 中的 d 參數代表的就是使時間序列成為平穩所需做的差分次數。ARIMA 模型在預測時,不僅考慮該現象在時間序列上的依存性,還考慮隨機波動的干擾,對於短期趨勢的預測準確率較高,是近年應用比較廣泛的方法之一。 - 廣義自回歸條件異方差模型 (Generalized Autoregressive Conditional Heteroskedasticity,GARCH):
GARCH 模型是一個專門針對金融資料的回歸模型,除了和普通回歸模型的相同之處,GARCH 對誤差的方差做了進一步的建模。特別適用於波動性的分析和預測。 - prophet:
由 Facebook 所開發的套件,基於疊加模型(Additive Model)來預測時間序列資料,將趨勢按照週期與使用者自己定義的重要節日結合,適用於具有明顯季節性影響和多個季節歷史資料的時間序列。除此之外,prophet 能夠應對資料缺失和趨勢變化,並妥善處理異常值。
※ 我們實作的程式碼的下載網址: https://github.com/RexMao/ibtb_timeseries
以 2013 年 4 月 18 日到 2018 年 6 月 15 日的台積電股價為資料來做評估,變數有:開盤價、最高價、最低價、收盤價以及交易量。
收盤價的走勢圖如下圖,我們使用所有變數的過去值,來預測下個時間點的收盤價,2013 年 4 月 18 日到 12 月 31 日的資料作為訓練資料,2018 年後的資料作為測試資料,用來比較傳統模型與 LSTM 的差別。用過去所有來去預測下個時間點的收盤價結果如下表,MAE 越小表示預測精確,可以看到在股票這種較為隨機的時間序列資料上,LSTM 的表現較為傳統模型突出許多。

結果如下表,可以看到 LSTM 的表現較為傳統模型突出許多。
LSTM | prophet | egarch | arima | |
---|---|---|---|---|
MAE | 0.126649 | 0.9840268 | 0.6122634 | 1.504293 |

◎ 高雄車站進站人數 from 2005/1/1 to 2018/6/30 , per day a datapoint, 4748 rows of data. (univariable)
由觀察高雄車站進出站人數資料可知,週末搭乘人數較多,平日較少,形成每週一個週期的短季節性資料,因此我們用高雄車站進站人數來評估各種時間序列模型在短季節性資料的效果,收集資料時間為 2005/1/1 至 2018/6/30 每日進站人數,我們使用 2015~2017 年的資料進行訓練,2018/1/1 ~ 2018/6/30 的資料進行評估,結果如下表,MAE 的值越大表示模型預測出來的值和實際值差距越大,可以看到在短季節性資料上 LSTM 的表現仍為最佳。
LSTM | prophet | garch(1,1) | arima(4,1,2) | |
---|---|---|---|---|
MAE | 1557.897 | 1679.424 | 3595.586 | 3396.617 |
◎ 高雄(前金區) pm2.5 Data from 2017/1/1 ~ 2017/12/31, a data point per hour, 8084 rows of data. (multivariable)
使用 2017 年 1 月 1 日 到 12 月 31 日高雄前金區的 pm2.5 資料來進行評估。pm2.5 的資料有較長的季節性變化(冬天較高,夏天較低),我們以此資料來評估各種時間序列預測模型在長季節性資料上的表現如何。我們使用 2017 年 1 月 1 日 到 11 月 30 日的資料進行訓練,2017 年 12 月的資料進行預測來評估結果。

為了評估模型的效果,我們這裡使用用過去所有變數 (例如SO2,CO...等) 來預測下個時間點的 pm2.5,結果如下表,MAE 的值越小表示模型閱測出來的值和實際值差距越小,可以看到在季節性資料上 LSTM 的表現較為傳統模型突出許多。
LSTM | prophet | garch(1,1) | arima(4,1,4) | |
---|---|---|---|---|
MAE | 5.883804 | 13.13367 | 23.98893 | 21.18558 |
◎ Evaluation of Multi-step LSTM :
LSTM 模型也支援多步的預測,常見的多步預測方法有4種:
- Direct Multi-step Forecast Strategy:每預測一個時間點都建一個模型。例如:
- Recursive Multi-step Forecast Strategy:將預測出來的值加入原始資料並用同個模型進行多步預測。例如:
- Direct-Recursive Hybrid Multi-step Forecast Strategies:將預測出來的值加入原始資料並用不同模型進行多步預測。例如:
- Multiple Output Forecast Strategy:直接用過去的值進行多步預測。例如:
我們進行預測多步評估的方法為 Recursive Multi-step Forecast Strategy,將預測出來的值丟入原始資料並用同個模型進行多步預測,結果如下,可以看到預測的步數越遠 (預測的時間點距離現在越久),MSE 越高,表示模型預測的越不精準,可以發現精準度隨著時間推進而降低。

推薦系統
隨著電子商務規模的不斷擴大,商品個數和種類快速增長,顧客需要花費大量的時間才能找到自己想買的商品,這種瀏覽大量無關的訊息和產品過程會使消費者不斷流失。由此推薦系統應運而生,推薦系統是一種資訊過濾系統,透過用戶對於不同項目的評分紀錄,能夠預測用戶對於其他項目的評分或是偏好,進而向用戶推薦更可能感興趣的項目。
推薦系統的強大威力因此備受矚目,漸漸地出現在非電子商務的應用場合,隨後逐漸佔領各行各業,線上影音串流平台 Netflix 將過去用戶觀看的紀錄訓練出推薦模型,進一步推薦更適切用戶偏好類型的電影、影集;社群交友軟體 Tinder 藉由個人的擇友偏好來推薦你更適配的好友;論文搜尋平台 Google Scholar 甚至能夠推薦你更多相關的論文,讓學者更能夠掌握研究趨勢。
推薦系統分類主要為以下三者:- 基於內容的推薦系統 (Content-based Recommender System):
通過相關特徵來定義用戶或是項目,依據用戶資料與待預測項目的批配程度進行推薦,盡力向用戶推薦類似於過去喜歡的項目,例如:用戶喜歡看動作片,而推薦系統則會盡力去推薦用戶喜歡的動作片。基於內容的推薦系統的優點是簡單且有效;缺點是提取特徵的能力有限,就算過分細化特徵,依舊無法為用戶推薦不同種類的項目,只能推薦用戶已有興趣的項目。這種推薦系統被限制在容易分析內容的項目推薦。 - 協同過濾推薦系統 (Collaborative Filtering Recommender System):
相較於傳統的基於內容的方法透過直接分析內容來進行推薦,協同過濾推薦系統分析用戶的興趣,在用戶群中找到與指定用戶有相似興趣的用戶群,綜合興趣相投、擁有共同經驗的用戶對於所有項目的喜好程度預測來作喜好預測排序再推薦。近年研究發展出許多數學運算方法讓電腦在計算協同過濾推薦的效率提升,協同過濾推薦系統又分為以使用者為基礎(User-based)的協同過濾跟以項目為基礎(Item-based)的協同過濾,後續將會有詳細介紹。協同過濾推薦系統的優點是能夠過濾難以自動內容分析的資訊,像是音樂或是藝術品,由於是興趣相投方式的推薦,也往往能夠找出用戶意想不到的項目;缺點則是系統對於新用戶掌握度不高,難以推薦相關興趣的項目,推薦品質會較差,而當用戶以及項目過大,也會產生評分矩陣過於稀疏延伸矩陣分解的問題。 - 混合推薦系統 (Hybrid Recommender System):
綜合以上兩種主要的推薦系統方法,混合推薦系統組合以上兩種推薦系統方法以彌補彼此間的優缺點,混合推薦系統組合的方式又分為「循序組合」、「線性組合」,循序組合是在不同用戶使用階段,使用不同推薦方法,來產生該階段所需的協果,例如:先利用基於內容的方式找出相似的使用者,接著再利用協同過濾方式來作推薦;而線性組合是同時使用兩種以上的推薦系統方法,分別產生個別的推薦結過,在賦予各個方法個別不同權重,加權之後即可得到最後的推薦結果。
本篇範例以第二種方法「協同過濾推薦系統」為主的演算法,因為協同過濾推薦系統對於資料格式要求低,方便各位使用者實現應用。將會以 R 的套件 RecommenderLab 來運行基於用戶的協同過濾(User-based CF)和基於項目的協同過濾(Item-based CF),除此之外也會介紹透過 Python PyTorch 實作的 DeepRecommender 深度學習演算法來進行協同過濾推薦。
功能:將N個用戶對於M個項目評分的歷史資料整理成以下資料表形式,而用戶對於項目列表至少給予一筆以上的評分。透過歷史評分資料,推薦系統會將資料轉換成 N * M 的評分矩陣,再去學習用戶跟項目之間的連結關係。後續預測時,您可以輸入一名新用戶對於多筆不同項目的評分,系統將會推薦給適合的項目給這位新用戶。

基於用戶協同過濾先尋找與目標用戶有相同喜好的鄰近用戶,然後根據目標用戶的鄰近用戶的喜好產生對目標用戶的推薦。基本原理就是利用用戶喜好行為的相似性來互相推薦用戶可能感興趣的項目,如下圖所示,用戶 A 喜歡項目 A 跟 C,用戶 B 喜歡項目 B ,用戶 C 喜歡項目 A、C 跟 D,從這些用戶的歷史偏好資訊中,我們可以發現用戶 A 跟用戶 C的偏好很類似,而用戶 C 還同時喜歡項目 D,那麼我們可以推斷用戶 A 也可能喜歡項目 D,因此將項目 D 推薦給用戶 A。
基於項目的協同過濾(Item-based CF)技術描述:
根據所有用戶對於項目的評價,發現項目彼此之間的相似度,然後根據目標用戶的歷史偏好資訊將類似的項目推薦給該用戶,如下圖所示,用戶 A 喜歡項目 B 跟 C,用戶 B 喜歡項目 A、B 跟 C,用戶 C 喜歡項目 A,從這些用戶的偏好資料中可以認為項目 A 跟項目 C 比較類似,喜歡項目 A 的都會喜歡項目 C,基於這個案段用戶 C 也可能喜歡項目 C,所以推薦項目 C 給用戶 C。
DeepRecommender 提出的 DeepAutoencoder 演算法技術描述:
DeepRecommemder 為 NVIDIA 於 2017 年 8 月 5 日發表於 arXiv 。使用的程式語言為 Python 3.6,另外使用 PyTorch 作為深度學習模型框架。而 DeepRecommemder 是屬於協同過濾式推薦系統。 DeepAutoencoder 藉由多層的 Autoencoder 來訓練用戶跟項目間的評分關係。DeepAutoencoder 會將 M 個維度的資料壓縮成 L 個維度,再將其推回 M 個維度,試圖還原原本 M 個維度的原始資料,如下圖所示。由於 DeepAutoencoder 學習到用戶跟項目的關係,您可以輸入一名新用戶對於多筆不同項目的評分,接著 DeepAutoencoder 會試著還原所有的評分矩陣,換句話說,能夠自動填上它認為新用戶對於不同項目各自該有的評分,再以還原的評分進行推薦即可。
訓練參數為:DeepAutoencoder 之網路層數、神經元數量跟激勵函式及位於 z 層的 Dropout 率。
原始資料中會有用戶對不同項目的評分,DeepRecommender 會將這些評分切成 90% 部分為訓練資料用以訓練 DeepAutoencoder,5% 為驗證集,用以驗證訓練的 DeepAuencoder 之水準,剩餘 5% 為測試集,作為最後測試結果。


參考資料:
1. RecommenderLab 2. DeepRecommender
- Movielens:
包含 6,040 位用戶對 3,706 部電影,總共一百萬筆的評分紀錄,評分矩陣稀疏率約為 95.5326%。 - Netflix:
包含 67,878 位用戶對 10,677 部電影,總共一千萬筆的評分紀錄,評分矩陣稀疏率約為 98.6202% 評分紀錄從 1999-12-01 到 2005-11-31。
- RecommenderLab, User-based Collaborative Filtering.
- RecommenderLab, Item-based Collaborative Filtering.
- DeepRecommender, DeepAutoencoder.

◎ 實驗一:
測試資料:Movielens,包含 6,040 位用戶對 3,706 部電影,總共一百萬筆的評分紀錄,評分矩陣稀疏率約為 95.5326%。
測試結果:
DeepRecommender (1080ti * 1) | IBCF | UBCF | |
---|---|---|---|
RMSE | 0.950686 | 1.2904 | 0.9518 |
Training Time | 46 sec | 12 min 7 sec | 0.2 sec |
◎ 實驗二:
測試資料:Netflix,包含 67,878 位用戶對 10,677 部電影,總共一千萬筆的評分紀錄,評分矩陣稀疏率約為 98.6202%。
測試結果:
DeepRecommender (1080ti * 1) | IBCF | UBCF | |
---|---|---|---|
RMSE | 0.9121 | NA | 0.9612 |
Training Time | 35 min 21 sec | NA | 2.15 sec |
模型壓縮的工具探索
近年來深度學習受到了大量的關注,也在許多領域的應用上得到了令人驚呼的準確度。然而,深度學習模型龐大的參數數量限制了在算力有限的行動設備與邊緣設備上的應用。為克服這個挑戰,「模型壓縮」成為研究重點。這方向追求在壓縮模型大小、提升推論速度的同時,保持模型原本的高準確度。解決這一實務難題對未來深度學習應用至關重要。
我們團隊所使用的模型壓縮工具分別是由Tencent騰訊開發的PocketFlow和Microsoft開發的NNI。PocketFlow運用「通道剪枝」,去除模型中不必要的部分;「權重稀疏化」,讓模型中的一些權重變得更輕;以及「參數量化」,將模型的參數表示方式做更有效率的轉換,透過此三種方法使模型更加輕盈。另外,NNI的獨特之處在於自動化,它能智能選擇最佳的壓縮方法,無需手動調整。NNI還提供直觀的可視化介面,方便使用者了解模型壓縮效果,即使對機器學習不太熟悉的人也能輕鬆應用。
期望透過上述介紹,為那些欲進行深度學習研究卻受限於硬體設備的使用者提供一條清晰的指導,能夠更輕鬆且充分地探索深度學習領域。
本文主要介紹兩款主流的模型壓縮工具的使用經驗:
以及 4 個我們測試過的模型壓縮演算法,包括:
Tencent 騰訊 - PocketFlow

sourse: https://pocketflow.github.io/
PocketFlow 是一套由騰訊開發,基於 TensorFlow 的模型壓縮工具,主要框架是結合了模型壓縮演算法、模型蒸餾與參數微調。而模型壓縮演算法的部分包含了 3 個壓縮方法,分別是:Channel Pruning、Weight Sparsification 與 Parameter Quantization。
Microsoft - NNI ( Neural Network Intelligence )

Microsoft 開發的 NNI 相對於 PocketFlow,是一套更加完整與易用的工具,除了模型壓縮演算法之外,NNI 也結合了模型架構搜尋、特徵工程等等在建立深度學習模型時可以使用的工具,建立了一套完整的從建模到模型壓縮的工具生態系。此外,NNI 也相容 Pytorch 框架,更在 Pytorch 框架上開發出能夠真正刪除模型壓縮後冗餘的參數,使模型的檔案大小與運算時間實際減少的套件。
演算法:
PocketFlow - Channel Pruning
Channel Pruning 的演算法是從各個卷積層之中選出比較重要的 Filter,這個壓縮器實現了 He et al. [3] 在 2017 年提出的方法,先用 LASSO 計算出各個 Channel 的重要性,在最小化壓縮前後的 feature map 的重建誤差的條件下依序選擇要保留的 filter。

PocketFlow - Discrimination-aware Channel Pruning
Discrimination-aware Channel Pruning 使用了不同的方式來選擇重要的 Filter,這個壓縮器根據 Zhuang et al. [4] 在 2018 年提出的方法,提出DCP (Discrimination-aware channel pruning) 方法一方面在中間層添加額外的 discrimination-aware loss (用以強化中間層的判斷能力),另一方面也考慮特徵重建誤差的 loss,綜合兩方面 loss 對於參數的梯度資訊,決定哪些為需要被裁剪的 channel。
PocketFlow - Uniform Quantization
精度削減 ( Quantization ) 透過使用較少的位元來表示每個參數與權重的方法,來達到減少模型的記憶體佔用的目的。這種方法雖然無法減少模型的計算量 ( FLOPs 浮點運算次數 ),不過卻是一種相對直覺且壓縮過程非常簡單的方法。例如,TensorFlow 預設的浮點數精度為 32 位元,我們可以透過將權重的浮點數精度降低為 8 位元,使得模型的權重只需要原先的四分之一左右的儲存空間。
NNI - Lottery Ticket Hypothesis Algorithm
NNI 的這個壓縮器實現了 ICLR 2019 最佳論文「The Lottery Ticket Hypothesis: Finding The Sparse, Trainable Neural Network」[5] 的概念:一個大型類神經網路包含了大量的子網路,這些子網路當中有些在原本的模型中具有影響力,有些則否。因此只要找出這些對預測具有影響力的子網路,去除影響力低的子網路,那麼保留的子網路的集合也能夠具有與完整模型相同的能力。
這個壓縮方法使用了迭代的權重剪枝過程,意即重複的找出要保留的參數子集合之後,再從這個子集合繼續找出要保留的子集合的循環,直到剩餘的參數量滿足一開始設定的參數稀疏度。
References:[1] https://pocketflow.github.io/
[2] https://nni.readthedocs.io/en/latest/index.html
[3] https://arxiv.org/abs/1707.06168
[4]https://arxiv.org/abs/1810.11809
[5]https://arxiv.org/abs/1803.03635
PocketFlow 測試結果:
我們使用 PocketFlow 來壓縮以 CASIA webface dataset 訓練的 Mobilenet v2 模型,我們測試的壓縮方法有 Channel Pruning、Discrimination-aware Channel Pruning 以及 Uniform Quantization。
其中,測試的條件控制為:
Channel Pruning

由上表可以看出在使用 Channel Pruning 的情況下,保留的參數量在 50% 以上時,可以維持與原始模型接近的準確度。
比較不同壓縮演算法
為了探討不同壓縮方法在相同壓縮比率下的表現,我們比較了 Channel Pruning、Discrimination-aware Channel Pruning 在保留 3 成的權重,Uniform Quantization 在 8 bit 的情況下的準確度與模型檔案大小。

雖然模型的 .ckpt 檔大小在壓縮之後有變小,但是實際檢視模型參數量時,會發現壓縮後的模型的浮點運算次數減少的原因在於 PocketFlow 會產生一個 Mask File 紀錄需要被刪掉的參數,在載入模型時同時載入這些遮罩,來避免這些被遮罩的參數參與運算。
NNI 測試結果:
Lottery Ticket Hypothesis Pruner
由於 Lottery Ticket Hypothesis Pruner 使用了 Fine-grained 的壓縮方式,這種 parameter-wised 的壓縮方法會造成模型架構的不規則化,因此經過 Lottery Ticket Hypothesis Pruner 壓縮後的模型無法套用 NNI 的 speed up 功能,所以即使這種壓縮方式可以只保留 10% 參數的清況下仍然能維持與原始模型接近的準確度。
實驗設計:

Speed Up Function
由於 PocketFlow 目前只能做到「找出不重要的參數」並且加上遮罩,使這些參數不會在運算時被使用,卻不能真正的修改模型結構,將這些參數從模型中真正的移除。而 NNI 開發了一個基於 pytorch 框架,用於刪除這些被遮罩住的參數的工具,所以我們在 NNI 的測試項目主要在於刪除參數功能的部分。
實驗設計:
