-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathneural-machine-translation-with-transformer-and-tensorflow2.html
8016 lines (7622 loc) · 575 KB
/
neural-machine-translation-with-transformer-and-tensorflow2.html
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<!--[if lt IE 9 ]><html class="no-js oldie" lang="zh-hant-tw"> <![endif]-->
<!--[if IE 9 ]><html class="no-js oldie ie9" lang="zh-hant-tw"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!-->
<html class="no-js" lang="zh-hant-tw">
<!--<![endif]-->
<head>
<!--- basic page needs
================================================== -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="author" content="Lee Meng" />
<title>LeeMeng - 淺談神經機器翻譯 & 用 Transformer 與 TensorFlow 2 英翻中</title>
<!--- article-specific meta data
================================================== -->
<meta name="description" content="本文分為兩大部分。前半將帶讀者簡單回顧 Seq2Seq 模型、自注意力機制以及 Transformer 等近年在機器翻譯領域裡頭的重要發展與概念;後半段則將帶著讀者實作一個可以將英文句子翻譯成中文的 Transformer。透過瞭解其背後運作原理,讀者將能把類似的概念應用到如圖像描述、閱讀理解以及語音辨識等各式各樣的機器學習任務之上。" />
<meta name="keywords" content="自然語言處理, NLP, Tensorflow" />
<meta name="tags" content="自然語言處理" />
<meta name="tags" content="NLP" />
<meta name="tags" content="Tensorflow" />
<!--- Open Graph Object metas
================================================== -->
<meta property="og:image" content="https://leemeng.tw/theme/images/background/Tour_de_babel.jpg" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://leemeng.tw/neural-machine-translation-with-transformer-and-tensorflow2.html" />
<meta property="og:title" content="淺談神經機器翻譯 & 用 Transformer 與 TensorFlow 2 英翻中" />
<meta property="og:description" content="本文分為兩大部分。前半將帶讀者簡單回顧 Seq2Seq 模型、自注意力機制以及 Transformer 等近年在機器翻譯領域裡頭的重要發展與概念;後半段則將帶著讀者實作一個可以將英文句子翻譯成中文的 Transformer。透過瞭解其背後運作原理,讀者將能把類似的概念應用到如圖像描述、閱讀理解以及語音辨識等各式各樣的機器學習任務之上。" />
<!-- mobile specific metas
================================================== -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS
================================================== -->
<!--for customized css in individual page-->
<link rel="stylesheet" type="text/css" href="https://leemeng.tw/theme/css/bootstrap.min.css">
<!--for showing toc navigation which slide in from left-->
<link rel="stylesheet" type="text/css" href="https://leemeng.tw/theme/css/toc-nav.css">
<!--for responsive embed youtube video-->
<link rel="stylesheet" type="text/css" href="https://leemeng.tw/theme/css/embed_youtube.css">
<!--for prettify dark-mode result-->
<link rel="stylesheet" type="text/css" href="https://leemeng.tw/theme/css/darkmode.css">
<link rel="stylesheet" type="text/css" href="https://leemeng.tw/theme/css/base.css">
<link rel="stylesheet" type="text/css" href="https://leemeng.tw/theme/css/vendor.css">
<link rel="stylesheet" type="text/css" href="https://leemeng.tw/theme/css/main.css">
<link rel="stylesheet" type="text/css" href="https://leemeng.tw/theme/css/ipython.css">
<link rel="stylesheet" type="text/css" href='https://leemeng.tw/theme/css/progress-bar.css' />
<!--TiqueSearch-->
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400">
<link rel="stylesheet" href="https://leemeng.tw/theme/tipuesearch/css/normalize.css">
<link rel="stylesheet" href="https://leemeng.tw/theme/tipuesearch/css/tipuesearch.css">
<!-- script
================================================== -->
<script src="https://leemeng.tw/theme/js/modernizr.js"></script>
<script src="https://leemeng.tw/theme/js/pace.min.js"></script>
<!-- favicons
================================================== -->
<link rel="shortcut icon" href="../theme/images/favicon.ico" type="image/x-icon"/>
<link rel="icon" href="../theme/images/favicon.ico" type="image/x-icon"/>
<!-- Global Site Tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-106559980-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments)};
gtag('js', new Date());
gtag('config', 'UA-106559980-1');
</script>
</head>
<body id="top">
<!-- header
================================================== -->
<header class="s-header">
<div class="header-logo">
<a class="site-logo" href="../index.html"><img src="https://leemeng.tw/theme/images/logo.png" alt="Homepage"></a>
</div>
<!--navigation bar ref: http://jinja.pocoo.org/docs/2.10/tricks/-->
<nav class="header-nav-wrap">
<ul class="header-nav">
<li>
<a href="../index.html#home">Home</a>
</li>
<li>
<a href="../index.html#about">About</a>
</li>
<li>
<a href="../index.html#projects">Projects</a>
</li>
<li class="current">
<a href="../blog.html">Blog</a>
</li>
<li>
<a href="https://demo.leemeng.tw">Demo</a>
</li>
<li>
<a href="../books.html">Books</a>
</li>
<li>
<a href="../index.html#contact">Contact</a>
</li>
</ul>
<!--<div class="search-container">-->
<!--<form action="../search.html">-->
<!--<input type="text" placeholder="Search.." name="search">-->
<!--<button type="submit"><i class="im im-magnifier" aria-hidden="true"></i></button>-->
<!--</form>-->
<!--</div>-->
</nav>
<a class="header-menu-toggle" href="#0"><span>Menu</span></a>
</header> <!-- end s-header -->
<!--TOC navigation displayed when clicked from left-navigation button-->
<div id="tocNav" class="overlay" onclick="closeTocNav()">
<div class="overlay-content">
<div id="toc"><ul><li><a class="toc-href" href="#" title="淺談神經機器翻譯 & 用 Transformer 與 TensorFlow 2 英翻中">淺談神經機器翻譯 & 用 Transformer 與 TensorFlow 2 英翻中</a><ul><li><a class="toc-href" href="#一些你需先具備的基礎知識" title="一些你需先具備的基礎知識">一些你需先具備的基礎知識</a></li><li><a class="toc-href" href="#機器翻譯近代史" title="機器翻譯近代史">機器翻譯近代史</a><ul><li><a class="toc-href" href="#統計機器翻譯:基於短語的翻譯" title="統計機器翻譯:基於短語的翻譯">統計機器翻譯:基於短語的翻譯</a></li><li><a class="toc-href" href="#神經機器翻譯:Encoder-Decoder-模型" title="神經機器翻譯:Encoder-Decoder 模型">神經機器翻譯:Encoder-Decoder 模型</a></li><li><a class="toc-href" href="#Encoder-Decoder-模型-+-注意力機制" title="Encoder-Decoder 模型 + 注意力機制">Encoder-Decoder 模型 + 注意力機制</a></li><li><a class="toc-href" href="#Transformer:Seq2Seq-模型-+-自注意力機制" title="Transformer:Seq2Seq 模型 + 自注意力機制">Transformer:Seq2Seq 模型 + 自注意力機制</a></li></ul></li><li><a class="toc-href" href="#師傅引進門,修行在個人_1" title="師傅引進門,修行在個人">師傅引進門,修行在個人</a></li><li><a class="toc-href" href="#11-個重要-Transformer-概念回顧" title="11 個重要 Transformer 概念回顧">11 個重要 Transformer 概念回顧</a></li><li><a class="toc-href" href="#安裝函式庫並設置環境" title="安裝函式庫並設置環境">安裝函式庫並設置環境</a></li><li><a class="toc-href" href="#建立輸入管道" title="建立輸入管道">建立輸入管道</a><ul><li><a class="toc-href" href="#下載並準備資料集" title="下載並準備資料集">下載並準備資料集</a></li><li><a class="toc-href" href="#切割資料集" title="切割資料集">切割資料集</a></li><li><a class="toc-href" href="#建立中文與英文字典" title="建立中文與英文字典">建立中文與英文字典</a></li><li><a class="toc-href" href="#前處理數據" title="前處理數據">前處理數據</a></li></ul></li><li><a class="toc-href" href="#理解-Transformer-之旅:跟著多維向量去冒險_1" title="理解 Transformer 之旅:跟著多維向量去冒險">理解 Transformer 之旅:跟著多維向量去冒險</a><ul><li><a class="toc-href" href="#視覺化原始句子" title="視覺化原始句子">視覺化原始句子</a></li><li><a class="toc-href" href="#視覺化-3-維詞嵌入張量" title="視覺化 3 維詞嵌入張量">視覺化 3 維詞嵌入張量</a></li><li><a class="toc-href" href="#遮罩:Transformer-的祕密配方" title="遮罩:Transformer 的祕密配方">遮罩:Transformer 的祕密配方</a></li><li><a class="toc-href" href="#Scaled-dot-product-attention:一種注意函式" title="Scaled dot product attention:一種注意函式">Scaled dot product attention:一種注意函式</a></li><li><a class="toc-href" href="#直觀理解遮罩在注意函式中的效果" title="直觀理解遮罩在注意函式中的效果">直觀理解遮罩在注意函式中的效果</a></li><li><a class="toc-href" href="#Multi-head-attention:你看你的,我看我的" title="Multi-head attention:你看你的,我看我的">Multi-head attention:你看你的,我看我的</a></li></ul></li><li><a class="toc-href" href="#打造-Transformer:疊疊樂時間_1" title="打造 Transformer:疊疊樂時間">打造 Transformer:疊疊樂時間</a><ul><li><a class="toc-href" href="#Position-wise-Feed-Forward-Networks" title="Position-wise Feed-Forward Networks">Position-wise Feed-Forward Networks</a></li><li><a class="toc-href" href="#Encoder-layer:Encoder-小弟" title="Encoder layer:Encoder 小弟">Encoder layer:Encoder 小弟</a></li><li><a class="toc-href" href="#Decoder-layer:Decoder-小弟" title="Decoder layer:Decoder 小弟">Decoder layer:Decoder 小弟</a></li><li><a class="toc-href" href="#Positional-encoding:神奇數字" title="Positional encoding:神奇數字">Positional encoding:神奇數字</a></li><li><a class="toc-href" href="#Encoder" title="Encoder">Encoder</a></li><li><a class="toc-href" href="#Decoder" title="Decoder">Decoder</a></li><li><a class="toc-href" href="#第一個-Transformer" title="第一個 Transformer">第一個 Transformer</a></li></ul></li><li><a class="toc-href" href="#定義損失函數與指標_1" title="定義損失函數與指標">定義損失函數與指標</a></li><li><a class="toc-href" href="#設置超參數" title="設置超參數">設置超參數</a></li><li><a class="toc-href" href="#設置-Optimizer" title="設置 Optimizer">設置 Optimizer</a></li><li><a class="toc-href" href="#實際訓練以及定時存檔" title="實際訓練以及定時存檔">實際訓練以及定時存檔</a></li><li><a class="toc-href" href="#實際進行英翻中" title="實際進行英翻中">實際進行英翻中</a></li><li><a class="toc-href" href="#視覺化注意權重" title="視覺化注意權重">視覺化注意權重</a></li><li><a class="toc-href" href="#在你離開之前" title="在你離開之前">在你離開之前</a></li></ul></li></ul></div>
</div>
</div>
<!--custom images with icon shown on left nav-->
<!--the details are set in `pelicanconf.py` as `LEFT_NAV_IMAGES`-->
<div id="leftNavImage_transformer" class="overlay" style="background-color:white" onclick="closeLeftNavImage('leftNavImage_transformer')">
<div class="overlay-content">
<img src="https://leemeng.tw/theme/images/left-nav/transformer.jpg">
</div>
</div>
<article class="blog-single">
<!-- page header/blog hero, use custom cover image if available
================================================== -->
<div class="page-header page-header--single page-hero" style="background-image:url(https://leemeng.tw/theme/images/background/Tour_de_babel.jpg)">
<div class="row page-header__content narrow">
<article class="col-full">
<div class="page-header__info">
<div class="page-header__cat">
<a href="https://leemeng.tw/tag/zi-ran-yu-yan-chu-li.html" rel="tag">自然語言處理</a>
<a href="https://leemeng.tw/tag/nlp.html" rel="tag">NLP</a>
<a href="https://leemeng.tw/tag/tensorflow.html" rel="tag">Tensorflow</a>
</div>
</div>
<h1 class="page-header__title">
<a href="https://leemeng.tw/neural-machine-translation-with-transformer-and-tensorflow2.html" title="">
淺談神經機器翻譯 & 用 Transformer 與 TensorFlow 2 英翻中
</a>
</h1>
<ul class="page-header__meta">
<li class="date">2019-06-17 (Mon)</li>
<li class="page-view">
87,662 views
</li>
</ul>
</article>
</div>
</div> <!-- end page-header -->
<div class="KW_progressContainer">
<div class="KW_progressBar"></div>
</div>
<div class="row blog-content" style="position: relative">
<div id="left-navigation">
<div id="search-wrap">
<i class="im im-magnifier" aria-hidden="true"></i>
<div id="search">
<form action="../search.html">
<div class="tipue_search_right"><input type="text" name="q" id="tipue_search_input" pattern=".{2,}" title="想搜尋什麼呢?(請至少輸入兩個字)" required></div>
</form>
</div>
</div>
<div id="toc-wrap">
<a title="顯示/隱藏 文章章節">
<i class="im im-menu" aria-hidden="true" onclick="toggleTocNav()"></i>
</a>
</div>
<div id="social-wrap" style="cursor: pointer">
<a class="open-popup" title="訂閱最新文章">
<i class="im im-newspaper-o" aria-hidden="true"></i>
</a>
</div>
<div id="social-wrap">
<a href="https://www.facebook.com/sharer/sharer.php?u=https%3A//leemeng.tw/neural-machine-translation-with-transformer-and-tensorflow2.html" target="_blank" title="分享到 Facebook">
<i class="im im-facebook" aria-hidden="true"></i>
</a>
</div>
<div id="social-wrap">
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A//leemeng.tw/neural-machine-translation-with-transformer-and-tensorflow2.html&title=%E6%B7%BA%E8%AB%87%E7%A5%9E%E7%B6%93%E6%A9%9F%E5%99%A8%E7%BF%BB%E8%AD%AF%20%26%20%E7%94%A8%20Transformer%20%E8%88%87%20TensorFlow%202%20%E8%8B%B1%E7%BF%BB%E4%B8%AD&summary=%E6%9C%AC%E6%96%87%E5%88%86%E7%82%BA%E5%85%A9%E5%A4%A7%E9%83%A8%E5%88%86%E3%80%82%E5%89%8D%E5%8D%8A%E5%B0%87%E5%B8%B6%E8%AE%80%E8%80%85%E7%B0%A1%E5%96%AE%E5%9B%9E%E9%A1%A7%20Seq2Seq%20%E6%A8%A1%E5%9E%8B%E3%80%81%E8%87%AA%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%A9%9F%E5%88%B6%E4%BB%A5%E5%8F%8A%20Transformer%20%E7%AD%89%E8%BF%91%E5%B9%B4%E5%9C%A8%E6%A9%9F%E5%99%A8%E7%BF%BB%E8%AD%AF%E9%A0%98%E5%9F%9F%E8%A3%A1%E9%A0%AD%E7%9A%84%E9%87%8D%E8%A6%81%E7%99%BC%E5%B1%95%E8%88%87%E6%A6%82%E5%BF%B5%EF%BC%9B%E5%BE%8C%E5%8D%8A%E6%AE%B5%E5%89%87%E5%B0%87%E5%B8%B6%E8%91%97%E8%AE%80%E8%80%85%E5%AF%A6%E4%BD%9C%E4%B8%80%E5%80%8B%E5%8F%AF%E4%BB%A5%E5%B0%87%E8%8B%B1%E6%96%87%E5%8F%A5%E5%AD%90%E7%BF%BB%E8%AD%AF%E6%88%90%E4%B8%AD%E6%96%87%E7%9A%84%20Transformer%E3%80%82%E9%80%8F%E9%81%8E%E7%9E%AD%E8%A7%A3%E5%85%B6%E8%83%8C%E5%BE%8C%E9%81%8B%E4%BD%9C%E5%8E%9F%E7%90%86%EF%BC%8C%E8%AE%80%E8%80%85%E5%B0%87%E8%83%BD%E6%8A%8A%E9%A1%9E%E4%BC%BC%E7%9A%84%E6%A6%82%E5%BF%B5%E6%87%89%E7%94%A8%E5%88%B0%E5%A6%82%E5%9C%96%E5%83%8F%E6%8F%8F%E8%BF%B0%E3%80%81%E9%96%B1%E8%AE%80%E7%90%86%E8%A7%A3%E4%BB%A5%E5%8F%8A%E8%AA%9E%E9%9F%B3%E8%BE%A8%E8%AD%98%E7%AD%89%E5%90%84%E5%BC%8F%E5%90%84%E6%A8%A3%E7%9A%84%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92%E4%BB%BB%E5%8B%99%E4%B9%8B%E4%B8%8A%E3%80%82&source=https%3A//leemeng.tw/neural-machine-translation-with-transformer-and-tensorflow2.html" target="_blank" title="分享到 LinkedIn">
<i class="im im-linkedin" aria-hidden="true"></i>
</a>
</div>
<div id="social-wrap">
<a href="https://twitter.com/intent/tweet?text=%E6%B7%BA%E8%AB%87%E7%A5%9E%E7%B6%93%E6%A9%9F%E5%99%A8%E7%BF%BB%E8%AD%AF%20%26%20%E7%94%A8%20Transformer%20%E8%88%87%20TensorFlow%202%20%E8%8B%B1%E7%BF%BB%E4%B8%AD&url=https%3A//leemeng.tw/neural-machine-translation-with-transformer-and-tensorflow2.html&hashtags=zi-ran-yu-yan-chu-li,nlp,tensorflow" target="_blank" title="分享到 Twitter">
<i class="im im-twitter" aria-hidden="true"></i>
</a>
</div>
<!--custom images with icon shown on left nav-->
<div id="left-nav-image-wrap-transformer">
<a title="顯示/隱藏 Transformer 架構圖">
<i class="im im-picture-o" aria-hidden="true" onclick="toggleLeftNavImage('leftNavImage_transformer')"></i>
</a>
</div>
</div>
<div class="col-full blog-content__main">
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<style>
pre {
overflow-x: auto;
word-wrap: break-word;
}
</style>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
那時,全世界的語言都一樣。人們說:『來吧,我們要建一座塔,塔頂通天,為了揚我們的名,免得我們被分散到世界各地。』耶和華說:『看哪!他們成爲一樣的人民、用同樣的語言。如今既蓋起塔來,以後就沒有他們無法完成的事情了。我們下去!在那裏變亂他們的口音,使他們的言語彼此不通。』
<br/>
<span style="float:right;margin-right: 1.5rem">─ 《創世記》第十一章</span>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>這是聖經中著名的<a href="https://zh.wikipedia.org/wiki/%E5%B7%B4%E5%88%A5%E5%A1%94">巴別塔</a>橋段,用來解釋為何當今世上有那麼多種語言。當年的上帝或許過於杞人憂天,但近年多虧了<a href="https://zh.wikipedia.org/zh-hant/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0">深度學習</a>,<a href="https://zh.wikipedia.org/wiki/%E6%9C%BA%E5%99%A8%E7%BF%BB%E8%AF%91">機器翻譯</a>的快速發展讓人不禁覺得,或許巴別塔很快就不再只是虛幻傳說了。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<video autoplay="" loop="" muted="" playsinline="" poster="https://leemeng.tw/images/transformer/google-translate.jpg" style="mix-blend-mode: initial;">
<source src="https://leemeng.tw/images/transformer/google-translate.mp4" type="video/mp4"/>
您的瀏覽器不支援影片標籤,請留言通知我:S
</video>
<center>
以往被視為非常困難的中 -> 英翻譯如今在深度學習的加持下也有不錯的水準
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>機器翻譯的研究之所以如此重要且迷人,是因為它將有機會讓未來任何人都不受語言的限制,獲得世界上任何他或她想要的資訊與知識。</p>
<p>在這篇文章的前半部分,我們會先花點時間來回顧<a href="https://en.wikipedia.org/wiki/Neural_machine_translation">神經機器翻譯</a>裡頭的一些重要概念。接著在具備這些概念以及<a href="#%E5%B8%AB%E5%82%85%E5%BC%95%E9%80%B2%E9%96%80%EF%BC%8C%E4%BF%AE%E8%A1%8C%E5%9C%A8%E5%80%8B%E4%BA%BA">其他背景知識</a>的前提之下,利用最新的 <a href="https://www.tensorflow.org/">TensorFlow 2</a> 來實作一個可以將英文句子翻譯成中文的神經網路架構:<a href="https://www.tensorflow.org/beta/tutorials/text/transformer">Transformer</a>。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/transformer-high-level-view.png" style="mix-blend-mode: initial;"/>
</center>
<center>
利用 Transformer 將法文句子翻譯成英文
(<a href="http://jalammar.github.io/illustrated-transformer/" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>這是一個非常簡化的示意圖。Transformer 實際上是一種基於自注意力機制的 <a href="https://youtu.be/ZjfjPzXw6og?t=3208">Seq2Seq 模型</a>,近年在<a href="https://paperswithcode.com/task/image-captioning">圖像描述</a>、<a href="https://zh.wikipedia.org/wiki/%E8%81%8A%E5%A4%A9%E6%A9%9F%E5%99%A8%E4%BA%BA">聊天機器人</a>、<a href="https://zh.wikipedia.org/zh-hant/%E8%AF%AD%E9%9F%B3%E8%AF%86%E5%88%AB">語音辨識</a>以及機器翻譯等各大領域大發異彩。但因為其相對複雜,到現在還是有種現象:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
了解 Transformer 相關技術的人已經用了好一陣子且用得很開心,不知道的人還是不知道。
<br/>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>當然這並不僅限於 Transformer,因為深度學習牽涉的研究範圍實在太廣了。透過這篇文章,我希望能幫助你開始了解神經機器翻譯以及 Transformer 的相關知識。</p>
<p>當我們完成實作並訓練出一個 Transformer 以後,除了可以英翻中以外,我們還能清楚地了解其是如何利用強大的<a href="https://www.youtube.com/watch?v=jd9DtlR90ak&feature=youtu.be">注意力機制</a>(我們在 <a href="#Encoder-Decoder-模型-+-注意力機制">Encoder-Decoder 模型 + 注意力機制</a>一節會仔細探討此概念)來做到精準且自然的翻譯。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/en-to-ch-attention-map.png"/>
</center>
<center>
Transformer 在將英文句子翻譯成中文時會「關注」需要注意的英文詞彙來生成對應的中文字詞
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>除了翻譯出來的中文正確無誤以外,從上圖你可以發現很有趣的現象。</p>
<p>給定左側的英文,Transformer 在生成其對應的中文翻譯時都會給每個英文詞彙不同的「注意程度」。小方格越亮則代表模型在生成某中文字時放越多的注意力在左側對應的英文詞彙上。</p>
<p>仔細看你會發現這個已經訓練好的 Transformer 在翻譯:</p>
<ul>
<li>「必」、「須」時會關注「must」</li>
<li>「希」、「望」時會關注「hope」</li>
<li>「公」、「民」時會關注「citizens」</li>
</ul>
<p>乍看之下好像稀鬆平常,但事實上我們在訓練模型時並不會告訴它這些詞彙之間的對應關係或是任何語言學的知識。我們就只是餵給它多組相同意思的中英句子,並讓它自己學會怎麼做翻譯。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
好黑魔法,不學嗎?
<br/>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>在英翻中的情境下,神經網路要做的事情就是讀入左側的英文句子,接著生成右側的中文句子(繁中對英文的翻譯資料集稀少,此文將以簡體為例)</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/en-zh-training-sentences.jpg" style="mix-blend-mode: initial;"/>
</center>
<center>
訓練資料是多組相同語義的成對中英句子(當然仍需前處理)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="一些你需先具備的基礎知識">一些你需先具備的基礎知識<a class="anchor-link" href="#一些你需先具備的基礎知識">¶</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>我在文中會盡量言簡意賅地介紹所有你需要了解的深度學習概念,並附上相關連結供你參考。但就像在<a href="https://leemeng.tw/how-to-generate-interesting-text-with-tensorflow2-and-tensorflow-js.html">天龍八部</a>或是眾多武俠小說都有提過的重要準則:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
武功修習有先後順序,勿求一步登天。
<br/>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>儘管在 <a href="https://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf">2017 年就已被提出</a>,本文即將探討並實作的 <a href="https://papers.nips.cc/paper/7181-attention-is-all-you-need.pdf">Transformer</a> 仍算是相當進階的神經網路架構。因此具備以下的基礎知識能幫助你更順利地理解本文內容:</p>
<ul>
<li>一點點<a href="https://demo.leemeng.tw/">卷積神經網路</a>的概念</li>
<li>清楚理解<a href="https://leemeng.tw/shortest-path-to-the-nlp-world-a-gentle-guide-of-natural-language-processing-and-deep-learning-for-everyone.html">循環神經網路</a>的運算方式</li>
<li>基本的<a href="http://research.sinica.edu.tw/nlp-natural-language-processing-chinese-knowledge-information/">自然語言處理</a>知識</li>
<li>基本的<a href="https://youtu.be/uUrt8xgdMbs?list=PLJV_el3uVTsNmr39gwbyV-0KjULUsN7fW">線性代數</a>如矩陣相乘運算</li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/nlp-intro.jpg" style="mix-blend-mode: initial;"/>
</center>
<center>
中研院這篇文章清楚地說明了自然語言處理在中文上的研究與應用
(圖片來源:<a href="http://research.sinica.edu.tw/nlp-natural-language-processing-chinese-knowledge-information/" target="_blank">研之有物</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>希望這樣的要求沒把你嚇跑,因為事實上你大約需要好幾倍的相關知識來成功實作 Transformer。<a href="#%E5%B8%AB%E5%82%85%E5%BC%95%E9%80%B2%E9%96%80%EF%BC%8C%E4%BF%AE%E8%A1%8C%E5%9C%A8%E5%80%8B%E4%BA%BA">儘管在實作前你會看到一些額外要求</a>,本文的前半部分還是相當平易近人的,還請放心閱讀。</p>
<p>當你想要深入了解某些細節的時候,可以參考這節附上的連結或是文內說明概念時附上的圖片來源。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
想更深入了解文中講述的各種概念,點擊相關的「圖片來源」就對了。
<br/>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>前言很長,但好戲才在後頭。如果你已經準備好進入神經機器翻譯的世界的話,現在就讓我們正式開始這趟旅程吧!</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="機器翻譯近代史">機器翻譯近代史<a class="anchor-link" href="#機器翻譯近代史">¶</a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>鑑往知來。了解一點機器翻譯的歷史以及 Transformer 是怎麼跑出來的會對實作很有幫助。</p>
<p>機器翻譯(<strong>M</strong>achine <strong>T</strong>ranslation)本身的概念<a href="https://zh.wikipedia.org/zh-tw/%E6%9C%BA%E5%99%A8%E7%BF%BB%E8%AF%91#%E6%AD%B7%E5%8F%B2">最早可追溯到 17 世紀</a>。自從那開始,人們嘗試並研究了各式各樣的方法,寫了一大堆規則、蒐集了數以萬計的翻譯結果來嘗試自動化翻譯。隨著時代演進,我們有了:</p>
<ul>
<li>基於規則的機器翻譯 RBMT</li>
<li>基於範例的機器翻譯 EBMT</li>
<li>統計機器翻譯 SMT</li>
<li>近年的神經機器翻譯 NMT</li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/mt-history.jpg" style="mix-blend-mode: initial;"/>
</center>
<center>
近代機器翻譯發展簡史
(<a href="https://www.freecodecamp.org/news/a-history-of-machine-translation-from-the-cold-war-to-deep-learning-f1d335ce8b5/" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>很多遠古時代的東西我們不會討論,而 NMT 當然是本文的重點。不過在那之前讓我們非常簡短地看一下 SMT。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="統計機器翻譯:基於短語的翻譯">統計機器翻譯:基於短語的翻譯<a class="anchor-link" href="#統計機器翻譯:基於短語的翻譯">¶</a></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>機器翻譯的歷史很長,但一直要到 21 世紀初期<a href="https://zh.wikipedia.org/wiki/%E7%BB%9F%E8%AE%A1%E6%9C%BA%E5%99%A8%E7%BF%BB%E8%AF%91">統計機器翻譯(<strong>S</strong>tatistical <strong>M</strong>achine <strong>T</strong>ranslation,簡稱 SMT)</a>技術成熟以後,機器翻譯的品質才稍微使人滿意。其中最知名的例子當屬 <a href="https://ai.googleblog.com/2006/04/statistical-machine-translation-live.html">Google 在 2006 年發布的 SMT 翻譯系統</a>。</p>
<p>不限於 Google,當時不少最先進的 SMT 系統都採用了<a href="https://en.wikipedia.org/wiki/Statistical_machine_translation#Phrase-based_translation">基於短語的機器翻譯(Phrase-Based MT)</a> 演算法。PBMT 最大的特色是先將來源語言(Source Language)的句子切成短語或是詞彙,接著大致上獨立地將這些詞彙翻譯成目標語言(Target Language)。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/pbmt.jpg" style="mix-blend-mode: initial;"/>
</center>
<center>
基於短語的 SMT(Phrase-Based SMT)
(<a href="https://www.freecodecamp.org/news/a-history-of-machine-translation-from-the-cold-war-to-deep-learning-f1d335ce8b5/" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>PBMT 的翻譯結果相較於早年基於規則(Rule-Based)的手法已經進步很多,但仍然需要大量的<a href="https://zh.wikipedia.org/wiki/%E5%B9%B3%E8%A1%8C%E8%AF%AD%E6%96%99">平行語料</a>、對齊語料來取得較好的結果。且因為是以短語為單位在做翻譯,這些短語拼湊出來的句子仍然不夠自然。</p>
<p>如果你跟我一樣有用過早年的 Google 翻譯,應該還能隱約記得當年那些充斥著「機械感」的翻譯結果。</p>
<p>(如果你有當年 Google 翻譯結果的截圖的話歡迎提供)</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="神經機器翻譯:Encoder-Decoder-模型">神經機器翻譯:Encoder-Decoder 模型<a class="anchor-link" href="#神經機器翻譯:Encoder-Decoder-模型">¶</a></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>顧名思義,神經機器翻譯 NMT 即代表使用<a href="https://zh.wikipedia.org/wiki/%E4%BA%BA%E5%B7%A5%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C">類神經網路(Neural Network)</a>來做機器翻譯。</p>
<p>不管是英文、法文還是中文,一個自然語言的句子基本上可以被視為一個有時間順序的序列數據(Sequence Data)。而<a href="https://leemeng.tw/shortest-path-to-the-nlp-world-a-gentle-guide-of-natural-language-processing-and-deep-learning-for-everyone.html#%E6%9C%89%E8%A8%98%E6%86%B6%E7%9A%84%E5%BE%AA%E7%92%B0%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF_1">我們曾提過 RNN 很適合用來處理有時間關係的序列數據</a>。給定一個向量序列,RNN 就是回傳一個一樣長度的向量序列作為輸出。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/nlp-kaggle-intro/rnn-animate.gif" style="mix-blend-mode: initial;"/>
</center>
<center>
RNN 很適合拿來處理具有時間順序的序列數據(下方的詞在丟入 RNN 前會被轉成詞向量)
(<a href="https://leemeng.tw/shortest-path-to-the-nlp-world-a-gentle-guide-of-natural-language-processing-and-deep-learning-for-everyone.html#%E6%9C%89%E8%A8%98%E6%86%B6%E7%9A%84%E5%BE%AA%E7%92%B0%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF_1" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>當我們把來源語言以及目標語言的句子都視為一個獨立的序列以後,機器翻譯事實上就是一個<a href="https://youtu.be/ZjfjPzXw6og">序列生成(Sequence Generation)</a>任務:對一個輸入序列(來源語言)做些有意義的轉換與處理以後,輸出一個新的序列(目標語言)。</p>
<p>而在深度學習時代,我們一般會使用以 RNN 為基礎的 <a href="https://youtu.be/ZjfjPzXw6og?t=3208">Encoder-Decoder 架構(又被稱作 Sequence to Sequence / Seq2Seq 模型)</a>來做序列生成:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<video autoplay="" loop="" muted="" playsinline="" poster="https://leemeng.tw/images/transformer/seq2seq-animate.jpg" style="mix-blend-mode: initial;">
<source src="https://leemeng.tw/images/transformer/seq2seq-animate.mp4" type="video/mp4"/>
您的瀏覽器不支援影片標籤,請留言通知我:S
</video>
<center>
一個以 RNN 為基礎的 Encoder-Decoder / Seq2Seq 模型將法文翻譯成英文的步驟
(<a href="https://jalammar.github.io/visualizing-neural-machine-translation-mechanics-of-seq2seq-models-with-attention/" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Seq2Seq 模型裡頭 Encoder 跟 Decoder 是各自獨立的 RNN。Encoder 把輸入的句子做處理後所得到的隱狀態向量(圖中的 <code>Hidden State#3</code>)交給 Decoder 來生成目標語言。</p>
<p>你可以想像兩個語義相同的法英句子雖然使用的語言、語順不一樣,但因為它們有相同的語義,Encoder 在將整個<strong>法文</strong>句子濃縮成一個嵌入空間(Embedding Space)中的向量後,Decoder 能利用隱含在該向量中的語義資訊來重新生成具有相同意涵的<strong>英文</strong>句子。</p>
<p>這樣的模型就像是在模擬人類做翻譯的<a href="https://zh.wikipedia.org/zh-tw/%E6%9C%BA%E5%99%A8%E7%BF%BB%E8%AF%91#%E7%BF%BB%E8%AD%AF%E6%B5%81%E7%A8%8B">兩個主要過程</a>:</p>
<ul>
<li>(Encoder)解譯來源文字的文意</li>
<li>(Decoder)重新編譯該文意至目標語言</li>
</ul>
<p>當然人類在做翻譯時有更多步驟、也會考慮更多東西,但 Seq2Seq 模型的表現已經很不錯了。</p>
<p>有些人閱讀到這裡可能會問:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
如果我們利用 Seq2Seq 模型將多種語言的句子都轉換到某個嵌入空間裡頭,該空間會長成什麼樣子呢?是相同語言的句子靠得比較近,還是不同語言但擁有同語義的句子會靠得比較近呢?
<br/>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>這是一個很好的研究問題。</p>
<p>而如果我們試著把這個問題圖像化,則結果可能長得像這樣:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/multi-lang-emb.jpg" style="mix-blend-mode: initial;"/>
</center>
<center>
大哉問:神經網路將句子轉換完所形成的向量空間比較靠近左邊還是右邊?
(<a href="https://youtu.be/ulLx2iPTIcs?list=PLtBw6njQRU-rwp5__7C0oIVt26ZgjG9NI&t=1035" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>圖中的點代表不同句子,不同顏色則代表不同語言。如果結果是左邊,代表神經網路並沒有創出一個「語義」空間,而只是把不同語言都投射到該嵌入空間裡頭的不同位置,接著才在該空間裡進行不同語言之間的轉換(中轉英、英轉法 etc.)。</p>
<p>我們比較想要的是右邊的情況:無關語言,只要句子的語義接近,彼此的距離就相近的語義空間。</p>
<p>而 <a href="https://aclweb.org/anthology/Q17-1024">Google 在 2016 年的研究結果</a>發現,在此空間裡頭語言相異但擁有同語義的句子之間的距離 <code>d1</code>,要比同語言但不同語義的句子之間的距離 <code>d2</code> 要小得多(即 <code>d1 << d2</code>)。</p>
<p>換句話說,在此空間中同語義的句子會靠得比較近,我們實際得到的空間比較像右邊。</p>
<p>而如果我們將這些句子做 <a href="https://distill.pub/2016/misread-tsne/">t-SNE</a> ,甚至可以得到這樣的結果:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<video autoplay="" loop="" muted="" playsinline="" poster="https://leemeng.tw/images/transformer/gnmt-multilingual.jpg" style="mix-blend-mode: initial;">
<source src="https://leemeng.tw/images/transformer/gnmt-multilingual.mp4" type="video/mp4"/>
您的瀏覽器不支援影片標籤,請留言通知我:S
</video>
<center>
在 Seq2Seq 模型創造出來的「語義」空間裡頭,不同語言但同語義的句子彼此相當接近
(<a href="https://projector.tensorflow.org/" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>此研究告訴我們,只要對自然語言做正確的轉換,就能將語言相異但同語義的句子都轉換成彼此距離相近的語義向量,並以此做出好的翻譯。</p>
<p>以下是我隨意挑選出來的一組句子,它們在該空間裡的距離相近:</p>
<div class="highlight"><pre><span></span>英文:
From low-cost pharmacy brand moisturizers to high-priced cosmetics brand moisturizers, competition is fierce.
日文:
低価格の薬品ブランドの保湿剤から高価な百貨店の化粧品ブランドのためには, 競争が激しい
韓文:
싸구려백화점화장품브랜드 moisturizers 에 저렴한약국브랜드 moisturizers 에서 , 경쟁이큰있습니다
</pre></div>
<p>這些句子都代表著類似的意思:「從低價的保濕劑到高價的化妝品牌,競爭都十分激烈」。</p>
<p>如果你想進一步了解這個視覺化結果,可以閱讀 <a href="https://youtu.be/ulLx2iPTIcs?list=PLtBw6njQRU-rwp5__7C0oIVt26ZgjG9NI&t=789">Google Brain 的詳細解說</a>或是上 <a href="https://projector.tensorflow.org/">Embedding Projector</a> 自己試看看。</p>
<p>另外值得注意的是,機器翻譯本身是一種<a href="https://youtu.be/ZjfjPzXw6og?t=2816">有條件的序列生成任務(Conditional Sequence Generation)</a>:給定一個特定的輸入句子(文字序列),依此條件輸出另外一個句子(文字序列)。這跟在<a href="https://leemeng.tw/how-to-generate-interesting-text-with-tensorflow2-and-tensorflow-js.html">讓 AI 寫點金庸</a>一文中會隨機生成天龍八部文章的<a href="https://zh.wikipedia.org/wiki/%E8%AA%9E%E8%A8%80%E6%A8%A1%E5%9E%8B">語言模型(Language Model)</a>是有所差異的:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<video autoplay="" loop="" muted="" playsinline="" poster="https://leemeng.tw/images/transformer/lstm-sequence-generation.jpg" style="mix-blend-mode: initial;">
<source src="https://leemeng.tw/images/transformer/lstm-sequence-generation.mp4" type="video/mp4"/>
您的瀏覽器不支援影片標籤,請留言通知我:S
</video>
<center>
隨機序列生成的例子:一個以 LSTM 實作的簡單語言模型
(<a href="https://leemeng.tw/how-to-generate-interesting-text-with-tensorflow2-and-tensorflow-js.html" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>一般來說,語言模型可以在不給定任何輸入的情況下生成非常隨機的文字序列;但針對機器翻譯這種有條件的序列生成任務,我們通常希望給定相同輸入,輸出的結果越穩定越好(或是每次都一模一樣)。</p>
<p>我們在<a href="#TODO">實作的時候</a>會看到怎麼達成這件事情。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Encoder-Decoder-模型-+-注意力機制">Encoder-Decoder 模型 + 注意力機制<a class="anchor-link" href="#Encoder-Decoder-模型-+-注意力機制">¶</a></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>好啦,你現在應該已經了解如何使用 Seq2Seq 模型來做 NMT 了,不過現在讓我們再次複習其運作方式。這次我們把用 RNN 實作的 Encoder / Decoder 在每個時間點做的事情從左到右一字排開:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<video autoplay="" loop="" muted="" playsinline="" poster="https://leemeng.tw/images/transformer/seq2seq-unrolled-no-attention.jpg" style="mix-blend-mode: initial;">
<source src="https://leemeng.tw/images/transformer/seq2seq-unrolled-no-attention.mp4" type="video/mp4"/>
您的瀏覽器不支援影片標籤,請留言通知我:S
</video>
<center>
以 RNN 為基礎的 Seq2Seq 模型做 NMT 的流程
(<a href="https://jalammar.github.io/visualizing-neural-machine-translation-mechanics-of-seq2seq-models-with-attention/" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>基本款的 Seq2Seq 模型表現得不錯,但其實有可以改善的地方。你有看出來了嗎?上圖的輸入句子只有 3 個詞彙,但如果我們想輸入一個很長的句子呢?</p>
<p>我們前面曾提過 Seq2Seq 模型裡的一個重要假設是 Encoder 能把輸入句子的語義 / 文本脈絡全都壓縮成<strong>一個</strong>固定維度的語義向量。之後 Decoder 只要利用該向量裡頭的資訊就能重新生成具有相同意義,但不同語言的句子。</p>
<p>但你可以想像當我們只有一個向量的時候,是不太可能把一個很長的句子的所有資訊打包起來的。</p>
<p>這時候怎麼辦呢?</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
與其只把 Encoder 處理完句子產生的最後「一個」向量交給 Decoder 並要求其從中萃取整句資訊,不如將 Encoder 在處理每個詞彙後所生成的「所有」輸出向量都交給 Decoder,讓 Decoder 自己決定在生成新序列的時候要把「注意」放在 Encoder 的哪些輸出向量上面。
<br/>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>這事實上就是<a href="https://www.youtube.com/watch?v=jd9DtlR90ak&feature=youtu.be">注意力機制(Attention Mechanism)</a>的中心思想:提供更多資訊給 Decoder,並透過類似資料庫存取的概念,令其自行學會該怎麼提取資訊。兩篇核心論文分別在 <a href="https://arxiv.org/abs/1409.0473">2014 年 9 月</a>及 <a href="https://arxiv.org/abs/1508.04025">2015 年 8 月</a>釋出,概念不難但威力十分強大。</p>
<p>以下就是將注意力機制加到 Seq2Seq 模型後的結果:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<video autoplay="" loop="" muted="" playsinline="" poster="https://leemeng.tw/images/transformer/seq2seq-unrolled-with-attention.jpg" style="mix-blend-mode: initial;">
<source src="https://leemeng.tw/images/transformer/seq2seq-unrolled-with-attention.mp4" type="video/mp4"/>
您的瀏覽器不支援影片標籤,請留言通知我:S
</video>
<center>
注意力機制讓 Decoder 在生成新序列時能查看 Encoder 裡所有可能有用的隱狀態向量
(<a href="https://jalammar.github.io/visualizing-neural-machine-translation-mechanics-of-seq2seq-models-with-attention/" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>你可以拉回去跟沒有注意力機制的 Seq2Seq 模型比較一下差異。</p>
<p>現在你會看到 Encoder 把處理完每個詞彙所產生的向量都交給 Decoder 了。且透過注意力機制,Decoder 在生成新序列的每個元素時都能<strong>動態地</strong>考慮自己要看哪些 Encoder 的向量(還有決定從中該擷取多少資訊),因此這種運用注意力機制的 Seq2Seq 架構又被稱作<a href="https://youtu.be/ZjfjPzXw6og?t=3528">動態的條件序列生成(Dynamic Conditional Generation)</a>。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<video autoplay="" loop="" muted="" playsinline="" poster="https://leemeng.tw/images/transformer/seq2seq_detail.jpg" style="mix-blend-mode: initial;">
<source src="https://leemeng.tw/images/transformer/seq2seq_detail.mp4" type="video/mp4"/>
您的瀏覽器不支援影片標籤,請留言通知我:S
</video>
<center>
法翻英時,Decoder 在生成每個英文詞彙時都在 Encoder 的每個輸出向量上放不同的注意程度
(<a href="https://jalammar.github.io/visualizing-neural-machine-translation-mechanics-of-seq2seq-models-with-attention/" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>實際構想並證明其有效的研究者們十分厲害,且其概念也挺符合人類直覺的,對吧?</p>
<p>為了方便讀者理解,上面動畫實際上隱藏了一些細節:</p>
<ul>
<li>呈現算好的注意程度而不是計算過程</li>
<li>Encoder / 跟 Decoder 的實際架構</li>
</ul>
<p>既然是深度學習,Encoder / Decoder 一般來說都是由多個 <a href="http://colah.github.io/posts/2015-08-Understanding-LSTMs/">LSTM</a> / <a href="https://en.wikipedia.org/wiki/Gated_recurrent_unit">GRU</a> 等 RNN Layers 所疊起來的。而注意力機制在這種情境下實際的運作方式如下:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/attention_mechanism_luong.jpg" style="mix-blend-mode: initial;"/>
</center>
<center>
英翻法情境下,Decoder 在第一個時間點進行的注意力機制
(<a href="https://github.com/tensorflow/nmt#background-on-the-attention-mechanism" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>左右兩邊分別是 Encoder 與 Decoder ,縱軸則是多層的神經網路區塊 / 層。</p>
<p>雖然上張動畫是法翻英(這邊是英翻法),但該動畫也是以一樣的概念將圖中的注意權重(attention weights )視覺化出來(注意權重和為 1)。</p>
<p>現在讓我們看一下注意力機制實際的計算步驟。在 Decoder 的每個時間點,我們都會進行注意力機制以讓 Decoder 從 Encoder 取得語境資訊:</p>
<ol>
<li>拿 Decoder 當下的紅色隱狀態向量 <code>ht</code> 跟 Encoder 所有藍色隱狀態向量 <code>hs</code> 做比較,利用 <code>score</code> 函式計算出 <code>ht</code> 對每個 <code>hs</code> 的注意程度</li>
<li>以此注意程度為權重,<strong>加權平均</strong>所有 Encoder 隱狀態 <code>hs</code> 以取得上下文向量 <code>context vector</code></li>
<li>將此上下文向量與 Decoder 隱狀態結合成一個注意向量 <code>attention vector</code> 並作為該時間的輸出</li>
<li>該注意向量會作為 Decoder 下個時間點的輸入</li>
</ol>
<p>定義 <code>score</code> 函式的方式不少,現在就先讓我們假設有這麼一個函式。</p>
<p>至此為止,你應該已經能夠看懂注意力機制的計算公式:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/attention-equation.jpg" style="mix-blend-mode: initial;"/>
</center>
<center>
注意力機制前 3 步驟的數學式子
(<a href="https://github.com/tensorflow/nmt#background-on-the-attention-mechanism" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>而之所以稱為注意權重(attention weights),是因為注意力機制可以被視為是一個學習來源語言和目標語言<strong>每一個單詞之間關係</strong>的小型神經網路,而這些權重是該神經網路的參數。</p>
<p>我們在<a href="#TODO">後面的章節</a>會實際看到,在訓練還沒開始前,這些權重都是隨機且無意義的。是透過訓練,神經網路才知道該為這些權重賦予什麼值。</p>
<p>你也會發現我在文中提及多次的「注意程度」就是這裡的「注意權重」,而前者是一種擬人化的說法。你可以想像這些權重值讓當下的 Decoder 曉得該放多少關注在 Encoder 個別的隱狀態身上,並依此從它們身上取得上下文資訊(步驟 2)。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
而事實上神經網路並沒有意識,因此也不會有感知層次上的「注意」。它學到的是讓注意力機制產生最好結果的「參數權重」,而不是我們人類想像的「注意程度」。只有人類可以賦予神經網路裡頭的計算意義。
<br/>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>有點扯遠了,畢竟這裡應該沒有人文學系的讀者。</p>
<p>讓我們拉回注意力機制。</p>
<p>將此機制加入 Seq2Seq 模型後,NMT 系統的翻譯水準再次起飛。Google 在 2016 年推出的 <a href="https://ai.googleblog.com/2016/09/a-neural-network-for-machine.html">Google Neural Machine Translation system(GNMT)</a> 是一個知名的案例。除了注意力機制以外,GNMT <a href="https://arxiv.org/abs/1609.08144">在 Encoder 跟 Decoder 都採用了多達 8 層的 LSTM 神經網路</a>,讓更多人見識到深度學習的威力。</p>
<p>跟 Google 10 年前推出的 PBMT 系統比起來,翻譯錯誤率平均下降了 60 %。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<video autoplay="" loop="" muted="" playsinline="" poster="https://leemeng.tw/images/transformer/nmt-model-fast.jpg" style="mix-blend-mode: initial;">
<source src="https://leemeng.tw/images/transformer/nmt-model-fast.mp4" type="video/mp4"/>
您的瀏覽器不支援影片標籤,請留言通知我:S
</video>
<center>
利用注意力機制的 GNMT 讓 Decoder 在生成「Knowledge」時能放注意力在 Encoder 處理完「知」與「識」的兩個輸出向量 e0 & e1
(<a href="https://ai.googleblog.com/2016/09/a-neural-network-for-machine.html" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>上圖為 GNMT 做中翻英的過程。Encoder 跟 Decoder 之間的線條代表注意力(Attention),線條越粗代表下面的 Decoder 在生成某英文字時越關注上方的某些中文字。模型自己學會在翻譯時該看來源句子中的哪些資訊,很聰明,不是嗎?</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>因為其卓越的翻譯品質,在 GNMT 推出的那段時間,搭配注意力機制的 Seq2Seq 模型基本上就是拿來做 NMT 系統的不二人選。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/nmt-vs-pbmt.png" style="mix-blend-mode: initial;"/>
</center>
<center>
NMT、PBMT 以及人類在中英翻譯時的結果比較
(<a href="https://ai.googleblog.com/2016/09/a-neural-network-for-machine.html" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>話說當年 Google 導入 GNMT 時釋出了 8 個語言之間的對應翻譯,<a href="https://blog.google/products/translate/found-translation-more-accurate-fluent-sentences-google-translate/">涵蓋了約 1/3 的世界人口以及超過 35 % 的 Google 翻譯查詢</a>,是機器翻譯發展的一個重要里程碑。</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Transformer:Seq2Seq-模型-+-自注意力機制">Transformer:Seq2Seq 模型 + 自注意力機制<a class="anchor-link" href="#Transformer:Seq2Seq-模型-+-自注意力機制">¶</a></h3>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>好酒沉甕底,萬眾矚目的時刻來了。</p>
<p>標題已經破梗。你已經知道我們將探討本文主角 Transformer,且理論上越後面出來的 BOSS 越強。</p>
<p>但你現在可能在想:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<blockquote>
<p>
Seq2Seq 模型搭配注意力機制感覺已經很猛了,難道還有什麼可以改善的嗎?
<br/>
<br/>
</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>答案是肯定的 Yes。</p>
<p>不過這次問題不是出在 Encoder 跟 Decoder 中間交換的資訊不夠,也不是 Seq2Seq 架構本身有什麼問題,問題是出在我們是用 <strong>RNN</strong> 來實作 Encoder 以及 Decoder。</p>
<p><a href="http://colah.github.io/posts/2015-09-NN-Types-FP/">循環神經網路 RNN</a> 時常被拿來處理序列數據,但其運作方式存在著一個困擾研究者已久的問題:無法有效地平行運算。以一個有 4 個元素的輸入序列為例:</p>
<div class="highlight"><pre><span></span>[a1, a2, a3, a4]
</pre></div>
<p>要獲得最後一個時間點的輸出向量 <code>b4</code> 得把整個輸入序列跑過一遍才行:</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<center>
<img src="https://leemeng.tw/images/transformer/rnn-vs-self-attn-layer.jpg" style="mix-blend-mode: initial;"/>
</center>
<center>
自注意層可以做到跟雙向 RNN 一樣的事情,還可以平行運算
(<a href="https://www.youtube.com/watch?v=ugWDIIOHtPA" target="_blank">圖片來源</a>)
<br/>
<br/>
</center>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">