back to index

【機器學習2021】類神經網路訓練不起來怎麼辦 (四):損失函數 (Loss) 也可能有影響


link |
00:00.000
好,那接下來呢,我們要講有關分類怎麼做這件事情。
link |
00:10.000
這邊講的是一個短的版本,因為時間有限的關係,
link |
00:15.000
所以我們就講一個可以在20分鐘內講完的短的版本。
link |
00:19.000
既然有短的版本,就是有長的版本。
link |
00:22.000
如果你想要看長的版本的話,可以看一下過去上課的錄影,
link |
00:26.000
可能是花兩個小時到三個小時的時間才講完分類這件事情。
link |
00:32.000
我們這邊用一個最快的方法,直接跟你講分類是怎麼做的。
link |
00:38.000
分類是怎麼做的呢?我們已經講了regression,
link |
00:43.000
就是輸入一個項量,然後輸出一個數值,
link |
00:47.000
我們希望輸出的數值跟某一個label,
link |
00:51.000
也就是我們要學習的目標,越接近越好。
link |
00:54.000
有同學會問說,為什麼目標label有加head,
link |
00:59.000
而不是輸出有加head呢?
link |
01:01.000
你可能在別的地方有看過輸出有加head。
link |
01:04.000
那這邊的notation,它的使用並沒有一定的規定,
link |
01:08.000
如果你先上過我的機器學習的話,
link |
01:10.000
你就會去問別的老師說,為什麼model的輸出有加head,
link |
01:15.000
然後你的label沒有加head。
link |
01:17.000
所以我們這門課呢,如果是正確的答案就有加head,
link |
01:22.000
model的輸出沒有加head。
link |
01:25.000
那有一個可能,假設你會用regression的話,
link |
01:30.000
我們其實可以把classification當作是regression來看。
link |
01:35.000
怎麼說呢?那這個方法不一定是一個好方法,
link |
01:38.000
這是一個比較奇妙的方法。
link |
01:40.000
你可以說,一樣輸入一個東西以後,
link |
01:43.000
我們的輸出仍然是一個scalar,它叫做y。
link |
01:48.000
然後這個y,我們要讓它跟正確答案的class越接近越好。
link |
01:54.000
但是y是一個數字啊,我們怎麼讓它跟class越接近越好呢?
link |
01:59.000
我們必須把class也變成數字。
link |
02:03.000
舉例來說,class1就是編號1,class2就是編號2,class3就是編號3。
link |
02:12.000
然後接下來呢,我們要做的事情就是希望y可以跟class的編號越接近越好。
link |
02:21.000
但是,這會是一個好方法嗎?
link |
02:24.000
如果你仔細想想的話,這個方法也許在某些狀況下是會有瑕疵的。
link |
02:30.000
因為如果你假設說class1就是編號1,class2就是編號2,class3就是編號3,
link |
02:36.000
意味著說你覺得class1跟class2它是比較像的。
link |
02:41.000
然後class1跟class3它是比較不像的。
link |
02:45.000
那像這樣子的表示class的方式,有時候可行,有時候不可行。
link |
02:53.000
假設你的class1,2,3真的有某種關係,
link |
02:56.000
舉例來說,你想要根據一個人的身高跟體重,
link |
03:00.000
然後預測他是幾年級的小學生,一年級、二年級還是三年級。
link |
03:05.000
那可能一年級真的跟二年級比較接近,一年級真的跟三年級比較沒有關係。
link |
03:10.000
但是假設你的三個class本身並沒有什麼特定的關係的話,
link |
03:14.000
你說class1是1,class2是2,class3是3,那就很奇怪了,
link |
03:18.000
因為你這樣預設說1,2有比較近的關係,1,3有比較遠的關係。
link |
03:23.000
所以怎麼辦呢?當你在做分類的問題的時候,
link |
03:26.000
比較常見的做法是把你的class用one-half vector來表示。
link |
03:34.000
那one-half vector我們在作業1的時候有看過,對不對?
link |
03:39.000
我們在作業1的時候說,我們把美國的州用one-half vector來表示。
link |
03:44.000
那同樣的道理,我們也可以把每一個class用一個one-half vector來表示。
link |
03:49.000
如果有三個class,我們的label這個whitehead就是一個三維的向量。
link |
03:55.000
然後呢,如果是class1就是100,如果是class2就是010,如果是class3就是001。
link |
04:03.000
所以每一個class你都用一個one-half vector來表示,
link |
04:06.000
而且如果你用one-half vector來表示的話,就沒有說class1跟class2比較接近,
link |
04:12.000
class1跟class3比較遠這樣子的問題。
link |
04:15.000
如果你把one-half vector拿來算距離的話,class之間兩兩他們的距離都是一樣的。
link |
04:23.000
好,那接下來呢,如果我們今天的目標whitehead是一個向量,
link |
04:29.000
比如說這邊whitehead是有三個element的向量,三個數值的向量,
link |
04:35.000
那我們的network也應該要output三個數值才行。
link |
04:40.000
那到目前為止我們講的network其實都只output一個數值,
link |
04:44.000
因為我們過去做的都是regression的問題,所以只output一個數值。
link |
04:48.000
那怎麼把它改成output三個數值呢?
link |
04:51.000
其實從一個數值到三個數值它是沒有什麼不同的啦。
link |
04:55.000
怎麼說呢?你可以output一個數值,你就可以output三個數值。
link |
04:59.000
所以把本來output一個數值的方法重複三次,你把a1、a2、a3乘上三個不同的位加上bias得到y1,
link |
05:08.000
再把a1、a2、a3乘上另外三個位再加上另外一個bias得到y2,
link |
05:13.000
把a1、a2、a3再乘上另外一組位再加上另外一個bias得到y3,
link |
05:18.000
你就可以產生三組數值。
link |
05:20.000
所以你就可以input一個feature的vector,然後產生y1、y2、y3,
link |
05:25.000
然後期待y1、y2、y3跟我們的目標越接近越好。
link |
05:30.000
所以我們現在知道了regression是怎麼做的。
link |
05:34.000
input x, output y, yout跟label y hat越接近越好。
link |
05:38.000
如果是classification呢?我們剛才說input x可能乘上一個w再加上b,
link |
05:45.000
再通過activation function再乘上w'再加上b'得到y。
link |
05:51.000
我們現在的y它不是一個數值,它是一個向量。
link |
05:56.000
但是在做classification的時候,
link |
05:59.000
我們往往會把y再通過一個叫做softmax的function得到y'.
link |
06:09.000
然後我們才去計算y'跟y hat之間的距離,
link |
06:14.000
才去說我們要讓y'跟y hat越接近越好。
link |
06:19.000
為什麼要加上softmax呢?
link |
06:21.000
一個比較簡單的解釋,
link |
06:25.000
這一段到底要怎麼在數十分鐘內講完,
link |
06:28.000
我其實想了很久。
link |
06:30.000
如果是在過去的課程裡面,
link |
06:32.000
我們會花很長一段時間告訴你說,
link |
06:35.000
這裡為什麼要加softmax?
link |
06:38.000
它背後有什麼樣的假設?
link |
06:40.000
我們會先從generative的model開始講起,
link |
06:43.000
然後一路講到logistic regression,
link |
06:45.000
你就會知道為什麼這邊放個softmax,它有什麼樣的歷史淵源。
link |
06:50.000
我們現在已經不是從那個角度切入,
link |
06:52.000
所以就有點不知道要怎麼解釋說為什麼要放softmax。
link |
06:57.000
那這邊有一個騙小孩的解釋就是,
link |
07:00.000
這個y hat它裡面的值都是0跟1,對不對?
link |
07:04.000
它是one-hot vector,所以裡面的值只有0跟1。
link |
07:08.000
那y呢?y裡面有任何值?
link |
07:11.000
y裡面有任何值。
link |
07:13.000
既然我們的目標只有0跟1,
link |
07:15.000
但是y有任何值,
link |
07:17.000
那我們能不能夠就先把這個任何值,
link |
07:20.000
先把它normalize,移到0到1之間,
link |
07:25.000
這樣才好跟label的計算相似度。
link |
07:29.000
這是一個比較簡單的講法,
link |
07:31.000
如果你真的想要知道說為什麼要用softmax的話,
link |
07:35.000
你可以參考過去的上課錄影。
link |
07:38.000
那如果你不想知道的話,
link |
07:39.000
你就記得一件事,
link |
07:41.000
softmax要做的事情就是把
link |
07:43.000
本來y裡面可以放任何值這件事情,
link |
07:45.000
改成0到1之間。
link |
07:50.000
那softmax它裡面是怎麼運作的呢?
link |
07:54.000
這是這個softmax的block,
link |
07:56.000
輸入y1、y2、y3,
link |
07:58.000
它會產生y1'、y2'、y3'。
link |
08:02.000
它裡面運作的模式是這個樣子的。
link |
08:06.000
我們會先把所有的y取一個exponential,
link |
08:11.000
所以本來不管y是正的還是負的,
link |
08:13.000
反正取完exponential以後,
link |
08:15.000
就都變成正的,對不對?
link |
08:17.000
就算是負數,負小於0的值,
link |
08:19.000
取exponential以後,也變成正的。
link |
08:22.000
然後你再對它做normalize,
link |
08:24.000
除掉所有y的exponential值的和,
link |
08:27.000
然後你就得到y'.
link |
08:30.000
或是用圖示化的方法是這個樣子,
link |
08:32.000
y1取exponential、y2取exponential、y3取exponential,
link |
08:36.000
把它全部加起來,得到一個summation,
link |
08:40.000
得到一個summation,放在分母地方的summation。
link |
08:42.000
接下來再把exponential y1除掉summation,
link |
08:46.000
exponential y2除掉summation,
link |
08:48.000
exponential y3除掉summation,
link |
08:49.000
就得到y1'、y2'、y3'。
link |
08:53.000
有了這個式子以後,
link |
08:54.000
你就會發現說這個y1'、y2'、y3'
link |
09:01.000
它們都是介於0到1之間。
link |
09:03.000
然後這個y1'、y2'、y3'
link |
09:06.000
它們的和會是1。
link |
09:12.000
如果舉一個例子的話,
link |
09:14.000
本來y1等於3、y2等於1、y3等於負3。
link |
09:18.000
取完exponential的時候,
link |
09:20.000
就變成exponential3就是20,
link |
09:23.000
exponential1就是2.7,
link |
09:25.000
exponential負3就是0.05。
link |
09:27.000
做完normalization以後,
link |
09:29.000
它就變成0.88、0.12跟0。
link |
09:32.000
所以這個summax它要做的事情
link |
09:35.000
除了normalize以外,
link |
09:37.000
除了讓y1'、y2'、y3'
link |
09:39.000
變成0到1之間還有和為1以外,
link |
09:42.000
它還有一個附帶的效果是
link |
09:44.000
它會讓大的值跟小的值
link |
09:47.000
它們的差距更大。
link |
09:49.000
所以本來負3,
link |
09:50.000
然後通過這個exponential
link |
09:52.000
再做normalize以後,
link |
09:53.000
最後會變成趨近於0的值。
link |
09:56.000
然後這個summax的輸入
link |
09:59.000
往往就叫它logic,
link |
10:01.000
它是有名字的,
link |
10:02.000
有時候就叫它logic。
link |
10:05.000
那這邊是考慮了三個class的狀況。
link |
10:09.000
那如果兩個class會是怎麼樣呢?
link |
10:12.000
如果是兩個class,
link |
10:13.000
你當然可以直接套summax這個function,
link |
10:17.000
沒有問題。
link |
10:18.000
但是也許你更常聽到的是
link |
10:21.000
當有兩個class的時候,
link |
10:22.000
我們就不套summax了,
link |
10:25.000
直接取sigmoid。
link |
10:28.000
那當兩個class用sigmoid
link |
10:31.000
跟summax兩個class
link |
10:33.000
它們之間的關係是什麼呢?
link |
10:35.000
你其實可以自己想一想。
link |
10:37.000
你如果推一下的話會發現說
link |
10:39.000
這兩件事情是得價的。
link |
10:43.000
我知道說我這邊講summax,
link |
10:45.000
那summax當然做在兩個class上
link |
10:47.000
一定是沒有問題的。
link |
10:48.000
但你更常看到的是
link |
10:49.000
兩個class的時候就用sigmoid,
link |
10:51.000
你可能會問說
link |
10:52.000
這兩者有什麼不同,
link |
10:53.000
哪一個比較好呢?
link |
10:54.000
那我這邊告訴你
link |
10:55.000
它們是一模一樣的。
link |
10:56.000
你自己推一下會發現說
link |
10:57.000
這兩件事情是同一件事情。
link |
11:02.000
那所以呢,
link |
11:03.000
我們把x丟到一個network裡面
link |
11:05.000
產生y以後,
link |
11:07.000
我們會通過summax得到y'
link |
11:09.000
再去計算y'跟y'之間的距離,
link |
11:12.000
這個寫作D。
link |
11:14.000
那計算y'跟y'之間的距離
link |
11:17.000
有不只一種做法。
link |
11:19.000
舉例來說,你可以說
link |
11:21.000
如果我喜歡的話,
link |
11:22.000
我要讓這個距離是mean squared error
link |
11:24.000
跟作業用的一模一樣。
link |
11:26.000
就是把y'裡面的每一個element拿出來,
link |
11:31.000
把y'裡面的每一個element拿出來,
link |
11:34.000
然後計算它們的平方和,
link |
11:36.000
然後當作我的error。
link |
11:38.000
這也是一個做法。
link |
11:39.000
這樣也是計算兩個向量之間的距離,
link |
11:42.000
你也可以做到說
link |
11:44.000
當minimize mean squared error的時候,
link |
11:46.000
我們可以讓y'等於y'。
link |
11:50.000
但是有另外一個更常用的做法,
link |
11:54.000
叫做cross entropy。
link |
11:57.000
那這個cross entropy
link |
11:58.000
它的式子乍看之下
link |
11:59.000
會讓你覺得有點匪夷所思,
link |
12:02.000
怎麼是這個樣子呢?
link |
12:03.000
我們先來看看這個cross entropy的式子
link |
12:05.000
長什麼樣子。
link |
12:06.000
它是summation over所有的i,
link |
12:09.000
然後把y'的第i位拿出來,
link |
12:13.000
乘上y'的第i位取natural log,
link |
12:18.000
然後再全部加起來,
link |
12:20.000
這個是cross entropy。
link |
12:23.000
那當y'跟y'一模一樣的時候,
link |
12:26.000
你也可以minimize cross entropy的值。
link |
12:30.000
當y'跟y'一模一樣的時候,
link |
12:33.000
NSE會是最小的,
link |
12:34.000
cross entropy也會是最小的。
link |
12:38.000
但是為什麼會有cross entropy
link |
12:41.000
這麼奇怪的式子出現呢?
link |
12:44.000
那如果要講得長一點的話,
link |
12:46.000
這整個故事我們可以把它講成
link |
12:49.000
minimize cross entropy
link |
12:51.000
其實就是maximize likelihood這個東西,
link |
12:54.000
那你可能在很多地方都聽過
link |
12:56.000
likelihood這個詞彙。
link |
12:58.000
但是因為這堂課裡面
link |
12:59.000
我們even把likelihood拿掉了,
link |
13:01.000
所以我們現在根本就沒有
link |
13:02.000
likelihood這個東西,
link |
13:03.000
所以我們就不能往這個方向解釋,
link |
13:05.000
我們就不能說minimize cross entropy
link |
13:08.000
為什麼是maximize likelihood,
link |
13:09.000
因為其實不知道likelihood是什麼。
link |
13:11.000
但是這兩件事情其實是等價的啦,
link |
13:14.000
所以如果有一天有人問你說
link |
13:16.000
如果我們今天在做分類問題的時候,
link |
13:18.000
maximize likelihood跟minimize cross entropy
link |
13:22.000
有什麼關係的時候,
link |
13:23.000
你不要回答說
link |
13:24.000
他們其實很像,
link |
13:25.000
但是其實又有很微妙的不同。
link |
13:27.000
不是這樣,他們兩個就是
link |
13:28.000
一模一樣的東西,
link |
13:30.000
只是同一件事,
link |
13:31.000
不同的講法而已。
link |
13:33.000
所以假設你可以接受說
link |
13:35.000
我們在訓練一個classifier的時候
link |
13:37.000
應該要maximize likelihood,
link |
13:38.000
你就可以接受
link |
13:39.000
我們應該要minimize cross entropy。
link |
13:41.000
但是我們沒有講這件事,
link |
13:44.000
所以我要怎麼說服你
link |
13:45.000
我們應該要用cross entropy呢?
link |
13:48.000
下一頁投影片
link |
13:49.000
是從optimization的角度
link |
13:51.000
來告訴你說
link |
13:52.000
cross entropy比mean squared error
link |
13:55.000
更加適合用在分類上。
link |
13:59.000
那cross entropy真的
link |
14:00.000
相較於mean squared error
link |
14:02.000
是更常用在classification上面的。
link |
14:05.000
所以它常用到什麼地步呢?
link |
14:07.000
它常用到在PyTorch裡面
link |
14:10.000
cross entropy跟softmax
link |
14:12.000
它們是被綁在一起的
link |
14:14.000
它們是一個set
link |
14:16.000
你只要call cross entropy
link |
14:19.000
裡面就自動內建了softmax
link |
14:22.000
所以如果你看
link |
14:23.000
助教作業2的程式的話
link |
14:25.000
你會找不到softmax在哪裡
link |
14:28.000
就本來softmax應該是
link |
14:30.000
network的一部分
link |
14:31.000
照理說你在定義network的時候
link |
14:33.000
你應該也定義了softmax這個function
link |
14:36.000
但是你發現在助教程式裡面
link |
14:37.000
你找不到softmax
link |
14:38.000
為什麼?它放在cross entropy裡面
link |
14:41.000
當你使用cross entropy
link |
14:43.000
這個loss function的時候
link |
14:44.000
PyTorch自動幫你把softmax
link |
14:46.000
加到你的network的最後一層
link |
14:49.000
所以如果你今天在用PyTorch
link |
14:51.000
你自己在network加softmax的時候
link |
14:53.000
你用cross entropy
link |
14:55.000
就會變成加了兩次softmax
link |
14:57.000
就這個一個PyTorch
link |
14:58.000
一個有趣的設計
link |
15:01.000
所以這顯示說
link |
15:02.000
softmax跟cross entropy
link |
15:04.000
它們往往是被綁在一起的
link |
15:06.000
它們是一個set
link |
15:08.000
總是會被一起使用
link |
15:10.000
那接下來呢
link |
15:12.000
我從optimization的角度
link |
15:14.000
來告訴你說
link |
15:15.000
為什麼相較於
link |
15:18.000
mean square error
link |
15:20.000
cross entropy
link |
15:21.000
是更備常用在分類上
link |
15:25.000
那這個部分
link |
15:26.000
你完全可以在數學上面做證明
link |
15:30.000
但是我這邊是直接用
link |
15:31.000
舉例的方式來跟你說明
link |
15:34.000
如果你真的非常想看數學證明的話
link |
15:36.000
我把連結放在這邊
link |
15:38.000
你可以看一下過去上課的錄影
link |
15:40.000
但如果你不想知道的話
link |
15:41.000
那我們就是舉個例子來告訴你說
link |
15:44.000
為什麼cross entropy比較好
link |
15:47.000
好那現在我們要做一個
link |
15:48.000
三個class的分類
link |
15:50.000
我們的network先輸出
link |
15:51.000
y1 y2 y3
link |
15:52.000
再通過softmax以後
link |
15:54.000
產生y1' y2' 跟 y3'
link |
15:57.000
好接下來
link |
15:58.000
假設我們的正確答案就是100
link |
16:01.000
我們要去計算100這個向量
link |
16:03.000
跟y1' y2' 跟 y3'
link |
16:05.000
他們之間的距離
link |
16:07.000
那這個距離我們用1來表示
link |
16:09.000
1可以是mean square error
link |
16:11.000
也可以是cross entropy
link |
16:13.000
好那我們看一下
link |
16:14.000
如果我們這個1
link |
16:15.000
設定為mean square error
link |
16:17.000
跟cross entropy的時候
link |
16:18.000
算出來的error surface
link |
16:20.000
會有什麼樣不一樣的地方
link |
16:23.000
我們現在假設y1的變化
link |
16:25.000
是從-10到10
link |
16:28.000
y2的變化也是從-10到10
link |
16:31.000
y3我們就固定設成-1000
link |
16:34.000
因為y3設很小啊
link |
16:36.000
y3設-1000
link |
16:37.000
所以過softmax以後
link |
16:38.000
y3'就是非常趨近於0
link |
16:40.000
那他跟正確答案非常接近
link |
16:42.000
所以他對我們的結果影響很少
link |
16:44.000
總之我們y3設一個定值
link |
16:46.000
我們只看y1跟y2
link |
16:47.000
有變化的時候
link |
16:49.000
對我們的1
link |
16:50.000
對我們的loss
link |
16:52.000
你知道把很多個1加起來
link |
16:53.000
就變成loss嘛
link |
16:54.000
對我們的loss
link |
16:55.000
有什麼樣的影響
link |
16:57.000
底下這兩個圖啊
link |
16:59.000
而且在我們1是mean square error
link |
17:01.000
跟cross entropy的時候
link |
17:02.000
y1 y2
link |
17:04.000
y1 y2的變化
link |
17:06.000
對loss的影響
link |
17:08.000
對error surface的影響
link |
17:10.000
那如果今天y1很大
link |
17:12.000
y2很小
link |
17:13.000
y1很大
link |
17:14.000
y2很小
link |
17:15.000
那y1很大
link |
17:16.000
y2很小
link |
17:17.000
就代表y1'會很接近1
link |
17:18.000
y2'會很接近0
link |
17:20.000
所以不管是對mean square error
link |
17:22.000
還是cross entropy而言
link |
17:23.000
y1大
link |
17:24.000
y2小的時候
link |
17:25.000
loss都是小的
link |
17:27.000
我們這邊是用紅色代表loss大
link |
17:29.000
藍色代表loss小
link |
17:30.000
那左上角這邊
link |
17:31.000
y1小 y2大的時候
link |
17:33.000
y1小 y2大的時候
link |
17:35.000
如果y1小 y2大的話
link |
17:37.000
這邊y1'就是0
link |
17:38.000
y2'就是1
link |
17:39.000
所以這個時候
link |
17:40.000
loss會比較大
link |
17:42.000
所以這兩個圖
link |
17:43.000
都是左上角loss大
link |
17:45.000
右下角loss小
link |
17:47.000
所以我們就期待說
link |
17:48.000
我們最後在training的時候
link |
17:50.000
我們的參數
link |
17:51.000
可以走到右下角的地方
link |
17:53.000
那假設我們開始的地方
link |
17:55.000
都是左上角的地方
link |
17:56.000
會有什麼問題呢
link |
17:57.000
你會發現說
link |
17:58.000
如果我們選擇cross entropy
link |
18:00.000
左上角這個地方
link |
18:01.000
它是有斜率的
link |
18:03.000
所以你有辦法
link |
18:04.000
透過gradient
link |
18:05.000
一路往右下的地方走
link |
18:08.000
但如果你選mean square error的話
link |
18:11.000
你就卡住了你知道嗎
link |
18:13.000
mean square error
link |
18:14.000
在這種loss很大的地方
link |
18:16.000
它是非常平坦的
link |
18:18.000
它的gradient
link |
18:19.000
是非常小趨近於0的
link |
18:21.000
如果你初始的時候
link |
18:22.000
在這個地方
link |
18:23.000
離你的目標非常遠
link |
18:25.000
但它gradient很小
link |
18:26.000
你就會沒有辦法
link |
18:28.000
用gradient descent
link |
18:29.000
順利的走到
link |
18:31.000
右下角的地方去
link |
18:33.000
所以如果你今天
link |
18:34.000
自己在做classification
link |
18:36.000
你選mean square error的時候
link |
18:38.000
你有非常大的可能性
link |
18:40.000
會trap不起來
link |
18:42.000
當然這個是
link |
18:43.000
在你沒有好的optimization
link |
18:45.000
好的optimizer的情況下
link |
18:47.000
今天如果你用added
link |
18:49.000
這個地方
link |
18:50.000
gradient很小
link |
18:52.000
那gradient很小
link |
18:53.000
它learning rate會自動幫你調大
link |
18:55.000
也許你還是有機會
link |
18:56.000
走到右下角
link |
18:57.000
不過這會讓你的training
link |
18:58.000
比較困難一點
link |
19:00.000
讓你的training起步
link |
19:01.000
比較慢一點
link |
19:03.000
所以這邊有一個
link |
19:04.000
很好的例子是告訴我們說
link |
19:06.000
就算是loss function的定義
link |
19:09.000
都可能影響training
link |
19:12.000
是不是容易這件事情
link |
19:15.000
我們剛才說
link |
19:16.000
要用神羅天真
link |
19:17.000
直接把error surface炸平
link |
19:19.000
這邊就是一個好的例子
link |
19:20.000
告訴你說
link |
19:21.000
你可以改loss function
link |
19:23.000
居然可以改變optimization的難度