back to index
GAN Lecture 4 (2017): From A to Z

link |
好,那接下來要講什麼呢?接下來要講一下,實作上,你是怎麼implement game的。
link |
那首先呢,你有兩個參數,一個是theta d,一個是theta g,也就是你有discriminator跟generator的參數。
link |
接下來在每一個training的iteration,你會做什麼事情呢?
link |
你首先呢,你會去你的data base裏面呢,sample m比data,x1到xn出來。那從data base裏面sample m比data就是等同於是看作是從pdata這個distribution裏面sample data出來。
link |
接下來呢,你從你的generator的predistribution,通常可能是一個normal distribution,可能是一個uniform distribution,sample m比data出來,這個寫作z1到zn,他們是n個low dimensional vector。
link |
把這n個low dimensional vector丟到generator裏面產生x tilde,代表generator產生出來的n個object,x1 tilde到xn tilde。
link |
接下來你要調整你的discriminator,你用gradient descent或gradient ascent的方法去learn你的discriminator,去maximize下面這一個式子。
link |
你要做的事情就是讓x的d of x越大越好,讓x tilde的d of x越小越好。
link |
好,那你就用gradient ascent。好,那接下來呢,你train完了discriminator以後,接下來要train generator,那有時候你discriminator的training process會重複k次。
link |
好,接下來呢,要train generator,怎麼train generator呢?你在從你的predistribution裏面去sample n個pred出來。
link |
接下來你要調整你的generator的參數g set,讓它可以minimize下面這一個式子。那minimize下面這一個式子是什麼意思呢?
link |
因為你只能夠調generator的參數,而這一個式子的第一項只跟discriminator有關,所以可以把它拿掉。
link |
你做的事情就是去,你要讓這一個式子越小越好,因為我們是解一個minimax的problem,所以這個地方是要越大越好,這個地方是要越小越好。
link |
要讓這個式子越小越好,就是希望d的值越大越好。那你就希望說調整generator的參數,使得把z丟到generator,然後它產生出來的東西,generator會給它的值越大越好。
link |
你只能從gradient descent去optimize你的generator,這樣你就可以learn一個generator。
link |
好,那我們也知道說呢,在一開始Ian Goodfellow最原始的paper裏面他就提到一件事,他說理論上我們在update generator的時候,我們是minimize這一個式子。
link |
但實際上他發現說log1-dx的曲線,它長得是這個樣子。這個曲線有什麼問題呢?這個曲線在實作的時候,感覺對training造成一些問題。
link |
什麼樣的問題呢?因為一開始在training的時候,通常你的update generator出來的東西都非常的弱,所以你的d of x的值通常都很小。所以一開始呢,你的這個d of x的值都弱在這個地方。
link |
那這個地方因為對這整個紅色曲線來說,這個地方是比較平坦的,會讓你在開始的時候呢,算出來的gradient比較小,導致你的training的速度比較慢。所以Ian Goodfellow他就propose了另外一個想法,他說我們不要optimize這個式子,我們不要minimize這個式子,改成minimize另外一個式子,改成minimize-log d of x。
link |
log-d of x它的長相是這個樣子。那改成minimize這個式子以後,因為在d of x很小的地方斜率比較大,然後在d of x很大的地方斜率比較小,所以也許train起來就會比較順利。那實際上他是用下面這個式子來implement他的gain的。
link |
那Ian Goodfellow後來就寫了一篇paper提到說,因為大家每次提到gain的時候都會說原始的那個gain,但是原始的那個gain其實有兩個,你到底指的是哪一個gain呢?所以他說應該要證明一下,應該要把他們的名字說清楚。所以上面這個gain叫做minimax gain,縮寫就是NN gain。下面這個gain叫做non-saturating gain,它的縮寫就是NS gain。
link |
好,那原來的gain有什麼問題呢?一開始在train gain的時候發現說很容易產生non-collapse的現象,也就是說你今天雖然你的圖片有很豐富的diversity,但是generator的output卻非常的單一。
link |
那一開始人們認為說,也許是因為這個pdata和pg之間的divergence選的不好。什麼意思呢?我們知道所有各種不同的方法可以衡量兩個不同的distribution。當你用不同的divergence來衡量兩個distribution的時候,最接近的那個distribution會是不一樣的。
link |
舉例來說,假設現在藍色的線是pdata的distribution,綠色的虛線是pg的distribution。pdata有兩個mixture,pg只有一個mixture。所以今天pg不管你再怎麼調它的參數,它都沒有辦法跟pdata一模一樣。
link |
在pg沒有辦法跟pdata一模一樣的情況之下,你選擇哪一個divergence來衡量pg和pdata的差異,就會給你不同的結果。我們要找一個pg和pdata越近越好。但是假設你的model capacity不夠大,pg永遠沒有辦法跟pdata一模一樣,這個時候你怎麼衡量pg和pdata之間的差異就會變得非常重要。
link |
假設你現在用的是KL divergence,跟reverse KL divergence,它的結果就會非常的不一樣。詳細的細節、式子我們就不跟大家討論,但是假設你用KL divergence的話,那你的pg會想要盡量把這兩個mixture都蓋住。
link |
那你如果用reverse KL divergence的話,你的pg會盡量希望產生在pdata這個density特別大的地方。如果你今天是用KL divergence,那你會發現說你的pg的形狀是這個樣子。
link |
如果你從pg去做sample,你可能都sample到這兩個pdata的density很高的區域中間,你都sample到這個其實data的density沒有很高的地方。這樣子對應到的現象就是你產生出來的data,假設你是做image generation的話,你產生出來的image就會是比較模糊的,因為你的p的generator、pg產生出來的object其實是data裡面不存在的。
link |
如果是reverse KL divergence,你就會發現說,雖然pdata有兩個mode,但是pg總是只產生一個mode。
link |
那因為JS divergence跟reverse KL divergence比較像,所以過去人們覺得說,之所以game會有一些more collapse的情形,可能是因為divergence沒有選好。
link |
那既然是因為divergence沒有選好,那我們能不能夠換別的divergence呢?既然JS divergence按照我們原來的想法,JS divergence也許不是一個特別好的divergence,那能不能夠換一下divergence呢?確實是可以的。
link |
Fgame那篇paper告訴我們說,其實你可以用game來minimize任何的fdivergence,不限於JS divergence。JS divergence是fdivergence的一種,那剛才typical的game,原來influential proposal的game只說要minimizeJS divergence。
link |
但是Fgame這篇paper告訴我們說,事實上任何fdivergence你都可以去minimize它。
link |
好,那我們先來說一下fdivergence是什麼。fdivergence是什麼呢?fdivergence是說,假設你有兩個distribution P跟Q,你可以用下面這個式子來衡量P和Q這兩個distribution之間的差異。
link |
這個式子長什麼樣子呢?這個式子對所有的,就給兩個distribution P跟Q,然後你對所有的X做積分,然後計算Q of X乘上F of P of X除以Q of X。
link |
F是什麼?F是一個convex的function,那另外我們有一個限制是F of E要等於0。F是一個convex的function,F of E要等於0。當你用不同的convex的function來表示這個F的時候,你就得到了不同的fdivergence。
link |
這邊F你可以選一個自己喜歡的,只要滿足這邊這些我們對F下的條件,這一個式子就是衡量P和Q之間的差異。
link |
那這個何以見得這個證明呢?因為時間的關係,也許我們就把它略過。你只要記得說,我們可以替換任何的F的function,只要它是convex,只要F of E等於0。那代入這個式子以後,我們就是在衡量P和Q這兩個distribution之間的差異。
link |
舉例來說,如果我們今天的F of X,我們設成F of X等於X log X。X log X是一個convex function,如果你把E代進去,它的值也是0。
link |
那你現在把F換成X log X,那你就把F of P除以G換成P除以G乘上log P除以G。你就把F of P除以G換成P除以G乘上log P除以G。
link |
然後你把這個Q把它消掉,那你得到的東西就是這個樣子。那這個式子是什麼?這個式子就是KL divergence。那接下來,如果你F of X代負log X,如果你F of X代負log X,那你把F of PQ與Q變成負log P除以Q,那你得到的是什麼?
link |
你得到的就是reverse KL divergence。那這邊可能有點快,不過沒有關係,反正你就記得說,代什麼F進去,你就得到一個不同的divergence。
link |
舉例來說,F of X,你代X減1的平方,那你得到的就是chi-square的divergence。就這樣。
link |
好,那接下來,我們要突然天外飛來一筆,說一個感覺有點不相關的東西,但是對等於價的推導是重要的。
link |
那今天要講告訴大家什麼事情呢?要告訴大家的事情是說,每一個convex的function呢,它都有一個conjugate。就每一個convex的function呢,它都有一個夥伴。
link |
這個夥伴長什麼樣子?這個夥伴長得一個非常奇形怪狀的樣子。這個F of X,它有一個conjugate的function叫F star。這個F star長什麼樣子呢?這個F star是max Xt-F of X。
link |
你把Xt-F of X,再對X取max。那這個東西大家可能也覺得有點複雜,這跟什麼意思呢?假設你現在要求F star of t1,那你要做的事情就是先算出Xt1-F of X。
link |
那X你可以代不同的值,那你再看說,哪一個X可以讓大括號裡面的值最大?哪一個X可以讓大括號裡面的值最大?那就是F star of t1。
link |
然後同理呢,如果你今天要找t2,如果你今天要找F star of t2,那你就把t2代進去。然後呢,你再看說,哪一個X的值,比如說這一次X3的值,可以讓Xt2-F of X的值最大?
link |
那F star of t2的值,就是X3t2-F of X3。好,這樣大家可以接受嗎?這個大家有問題嗎?好,假設你可以接受這個式子的話,那實際上F star of t長什麼樣子呢?
link |
我們先把Xt-F of X畫出來。現在,呃,呃,Xt-F of t是什麼東西呢?這個Xt-F of t啊,這個X啊,你可以代不同的X。
link |
就如果你X代X1,它是一條直線。因為它只有,假設你的橫軸坐標是t的話,那只有t呢,是未知的。啊,那X呢,是給定的。所以Xt-F of X呢,它就是一條直線。
link |
你代不同的X,你就得到了不同的直線。哦,你代X1得到這一條直線,代X2得到這一條直線,代X3呢,得到這一條直線。接下來,你在給定t的前提之下,你要找一個X可以讓藍色框框裡面的值最大。
link |
你在給定t的前提之下,你要找一個X可以讓藍色框框裡面的值最大。那其實你找出來的是哪裡呢?如果你選X1這個地方,你就把這個線畫上來,就看誰的值最大就選他。
link |
如果是在X2這個地方,你就把線畫上來,你看誰的值最大就選他。那你把所有最大的值串起來,你就得到F star of t。所以F star of t呢,它其實也是convex的。
link |
所以一個convex的function,它的franchise的conjugate,F star也是一個convex的function。好,那說了這麼多,我想要唯一告訴大家的事情就是,假設前面的東西你有點沒聽懂的話,其實就算了。
link |
我要告訴大家的事情是說,假設給你一個function F of X,那它有一個partner叫做F star,那F star如果把它做一模一樣的operation,它會變回F of X。這樣了解吧?
link |
F star跟F,它們是互為conjugate的。就如果F of X做這個operation以後,它會得到F star。同理,F star做這個operation以後,它會得到F of X。那前提就是F必須要是一個convex function,這個結果才成立。
link |
好,所以接下來,我們說我們的F divergence寫做這個樣子,而F是一個convex function。那我們知道說一個convex function,你可以把它寫成這個式子。一個convex function,你可以把它寫成這個式子。
link |
所以本來F of P除以Q,我們就可以把右邊的這個式子裡面的X通通換成P除以Q,把X通通換成P除以Q。把X換成P除以Q以後,我們得到的式子就是這個樣子。
link |
所以P跟Q,它們的F divergence等於對X做積分,Q of X乘上括號,這邊有一個大括號,P除以Q乘T減F star of T,然後選一個T的值,可以讓大括號裡面的值最大,然後再乘上Q,再對所有的X做積分,就是P和Q之間的這個KL divergence。
link |
好,那現在我們要做一個轉換。本來我們要讓這個大括號裡面的值最大嘛,對不對?這個小括號裡面的值是什麼呢?這個小括號裡面的值就是窮舉所有的T,看哪一個T可以讓這個大括號裡面的值最大,那就是小括號裡面的值。
link |
那我們現在說,我們找到了一個function D,這個function呢,你給它一個X,它就會output一個T給你。
link |
那我們說,本來我們要找一個T讓大括號裡面的值最大,我們現在說,我們不要解這個max的problem,我們不要做解這個optimization的problem,我們說,不知道哪裡來了一個D,你把X帶進去。因為現在不同的T,這邊大括號裡面會選不同的T,其實只跟X有關嘛,對不對?大括號裡面會選不同的T,其實只跟X有關。
link |
現在不知道哪裡來了一個function大D,我們把X帶進去以後,它會產生T。我們本來要解argmax的problem,現在想想算了,我們直接拿D的output來當作我們要找的那個T。
link |
所以我們現在可以把T都換成D of X。把T換成D of X會造成什麼現象呢?會造成說,這一項把T換成D of X的結果一定會小於原來的T,對不對?
link |
有人反對的嗎?都可以接受嗎?因為想想看,我們本來是要找一個T讓大括號裡面的值最大,現在你說,我們另外找到了一個functionD,丟進X以後它會output一個T,我們要用那個D的output來取代原來的T。
link |
那除非那個D很厲害,它找出來的就是那個最好的T,不然一定是上面這個大括號裡面的值大於下面這個大括號裡面的值,對嗎?好,那如果是這樣子的話,那這一項它就會小於等於這一項,它就會小於等於KL divergence。
link |
所以這一項就會小於等於KL divergence。好,那接下來呢,我們把這個式子展開,簡單就把Q乘進去,把Q乘進去,那我們得到的式子就是這個樣子。
link |
所以我們說呢,這個P跟Q之間的divergence一定會大於等於什麼呢?P跟Q之間的F divergence一定會大於等於P of X乘上D of X對所有的X做積分,減掉Q of X乘上X大D of X對所有的X做積分。
link |
好,那我們說,如果你隨便找一個function D,因為它output的T不是會讓這個值最大的的T,所以這一項一定會小於F divergence。
link |
那接下來,我們希望讓這一項可以跟F divergence越逼近越好,如果可以讓這一項跟F divergence越接近越好,我們就可以用這一項來approximate F divergence。
link |
那你怎麼讓這兩項越接近越好呢?你就是去找一個function D,使得這個式子的值最大。你找一個D,使得這個式子的值最大。如果這件事情可以辦得到的話,那意味著什麼?
link |
如果這件事情可以辦得到的話,那就意味著說你可以讓這一項跟這一項是相等的。假設你的D的能力是無窮大的話,
link |
假設你的D的function的capacity的能力是無窮大的話,那你input什麼X,只要它想它可以output你想要的T的話,那你就可以讓這兩個式子是相等的。
link |
那我們現在有了這一個式子以後,那接下來呢,我們就可以把P跟Q的F divergence的式子寫出來。
link |
那這個式子長什麼樣子呢?這個式子做的事情就是,對X做積分P of X,D of X,這件事是什麼意思呢?這件事情就是從P這個distribution裡面去sample X出來,然後再算D of X的期望值。
link |
那右邊這個式子是什麼意思呢?是從Q這個distribution去sample X出來,再對F star,D of X去取期望值。把這兩個期望值相減,然後我們說找一個D讓這兩個期望值之間的差最大,那我們就可以得到F divergence。
link |
好,那接下來我們要做的事情,我們已經知道說F divergence長什麼樣子,那接下來要做的事情是找一個G讓F divergence越小越好。那怎麼找一個G讓F divergence越小越好呢?你就是解下面這一個minimax的problem。
link |
那我們可以把這個式子就寫成V of GD,那你就會發現說,其實這跟原來的Gan是一模一樣的。唯一不一樣的地方只是原來的Gan有一個他自己的V of GD的定義方式,現在在F Gan裡面有另外一個這個V of GD的定義方式。
link |
那你要如果隨著你要量的那個F divergence不同,那你就有不同的V of GD。所以你今天要量什麼F divergence,你就把它拿出來,找出它的conjugate,然後把這個式子算一下,你就知道要怎麼minimize任何的F divergence。那這個就是這個F Gan告訴我們的事情。
link |
所以今天這個F Gan告訴我們說,今天如果你有一個你想要量的F divergence,你有一個你想要minimize的F divergence,假設你今天用某一個F divergence來衡量data和generator output的差異的話,那假設你今天要使用某一個F divergence的話,你就帶這個式子就可以了。
link |
你的discriminator要maximize的就是後面這一個式子。那世界上有各式各樣的F divergence,它們的式子就列在這邊,它們的這個F的function就列在這邊,那它們的conjugate就列在這邊。
link |
那你也可以推一下看說這個Gan的F divergence它是長什麼樣子。總之,現在有了這個F Gan以後,它給我們的好處就是,任何的F divergence你都可以去minimize它。
link |
那有了這個F Gan以後,它其實就破解了一個迷思,因為過去相信說Gan做不好是因為你選了JS divergence,也許選了別的,比如說KL divergence,你就可以做得好了。那事實上最後的結果發現說,選了不同的F divergence對結果的影響好像沒有特別大。
link |
那所以這就告訴我們說,也許Gan做得不好不是因為選了不好的divergence,而是有其他的原因。至於是什麼原因,這個還沒有完全被破解,至少知道說不同的divergence之間並沒有造成非常關鍵性的影響。
link |
那不過F Gan它的這個理論還是非常的漂亮,它告訴我們說,其實任何的F divergence我們都是可以想辦法去minimize的,不是只有JS divergence是可以minimize的。好,那在這個F divergence之後呢,在F Gan之後呢,就有了W Gan,那我相信W Gan也許是大家都耳熟能詳的。
link |
那W Gan做的事情是什麼呢?我們說一般的Gan,最早的Gan,它是要minimizeJS divergence,那後來F Gan是可以minimize任何F divergence。那W Gan它想要minimize的是Earth movers的distance。
link |
那什麼是Earth movers的distance呢?Earth movers就是那個推土機,就是那個推土機。Earth movers distance就是說,想像你有兩個distribution P跟Q,那它們之間的Earth movers的distance就是,想像你有一台推土機把P這個distribution的土鏟到Q的位置去,
link |
就P是一堆土,Q呢是你要放土的位置,那把P的土鏟到Q的位置去,distance的平均就是Earth movers的distance。
link |
舉例來說,假設以下面這個圖為例,假設P這個distribution通通集中在這個地方,假設Q這個distribution通通集中在這個地方,那假設P和Q這兩個distribution都是一個點,那這兩個點的距離是d,那Earth movers的distance就是d。
link |
因為假設你有一個推土機,要把土從P移到Q,那這個推土機走的平均距離就是d,所以P和Q這兩個distribution,它們的Earth movers distance你就可以寫作d。
link |
那Earth movers的distance呢,又叫做vessel stand的distance,那雖然vessel stand的distance呢,它開頭呢是w,但是它並不是念成water stand,而是念成vessel stand,這是一個沒什麼用的冷知識就是了。
link |
那我們用w、P、Q來代表這個vessel stand的distance。好,那但是你可能會想說,Earth movers的distance在剛才那個P跟Q都是一個點的狀況,你可以非常明確的把它算出來,但是現在假設P跟Q都是比較複雜的distribution,那你要怎麼計算Earth movers的distance呢?
link |
為什麼P跟Q是複雜的distribution會造成問題呢?因為假設你要把P的土鏟到Q的位置,你要把P這堆土用一個推土機去挪動土的位置讓它變成跟Q一樣,那你會發現說你其實有不只一種移動方式。
link |
舉例來說,你現在看一下P跟Q之間的差異,Q是這個地方的土特別高,你可以把這個地方的土搬到左邊來,然後這個地方的土也比較高,你可以把這個地方的土搬過來,把這個地方的土搬過來變成這樣,把這個地方的土搬過來變成這樣。
link |
那你也可以說捨近求遠,把這個地方的土搬過來,把這個地方的土搬過來。那你用不同的搬土的方法,其實你的推土機走的平均距離就是不一樣的。
link |
如果是用左邊這個搬法,推土機走的距離比較少,用右邊這個搬法,推土機走的距離比較大。所以這兩個distribution,如果用Earth Movers的distance,在不同的搬法之下好像就會定義出不同的distance。
link |
所以Earth Movers的distance的定義是說,在所有可能的moving plan裡面,在所有可能的搬土的方式裡面,距離算起來最小的那個搬土的方式,距離最小的那個搬土的plan才是Earth Movers的distance。
link |
所以Earth Movers的distance,這個distance要計算它其實還蠻麻煩的。就一般的distance,你拿兩個distribution,比如F-divergent distance,你拿兩個distribution量出來,怎樣就是怎樣。
link |
但是Earth Movers的distance不是這樣,你要量量的distribution之間的差異,你居然需要先解一個optimization problem,你必須要先解一個optimization problem,看看怎麼樣搬土的方式可以讓distance最小。那個最小的distance才是Earth Movers的distance,才是Fastest Standard Distance。這樣大家知道我的意思嗎?
link |
舉例來說,在今天這個P跟Q的例子下,什麼樣的搬土的方式是最好的呢?其實是右邊這個搬土的方式是最好的。我們假設把這些土都染上顏色,所以今天它搬動之後,你可以知道它原來是從哪裡來的。
link |
如果你把這堆土搬到這個地方,然後你把這堆土搬到這個地方,你把這堆土搬到比如說這個地方,用這樣子的方式來搬動你的土,它的推土機走的距離才是最小的。最小的距離才是Earth Movers的distance,最好的moving plane算出來的距離才是Earth Movers的distance。
link |
那相較於之前的JS Divergence,換成Earth Movers的distance有什麼好處呢?在原來的JS Divergence裡面,它說,假設這個紅色的線是data的distribution,藍色的線是某一個generator,G0產生的distribution。
link |
現在假設我們有三個generator,一個是G0,一個是G50,一個是G100。如果問你說這三個generator哪一個比較好,你一定會說當然是G100最好,因為它產生出來的distribution和p-data是一模一樣的,然後G50次之,G0再次之。
link |
為什麼G50算是比G0好呢?因為至少G50產生出來的distribution和p-data是比較接近的。然而現在問題是說,如果你是量JS Divergence的話,這三個不同的generator,它們量出來的JS Divergence,當然這個G100它的JS Divergence最小算出來是0,但是G50跟G0它的JS Divergence是一模一樣的。
link |
如果你今天按照JS Divergence的定義,代入JS Divergence的式子去計算,只要兩個distribution沒有重合,它們的JS Divergence算出來就是log2,不管這樣的distribution實際上的距離有多大。
link |
它們的G0跟p-data距離比較大,但算出來還是log2,p-G50跟p-data距離比較小,但算出來還是log2,這樣就會造成一些問題。因為今天你在train generator的時候,可能一開始你的generator其實是p-G0,離real的distribution很遠。
link |
這個很合理,一開始如果你random initialize你的參數,它當然是離真正的data很遠的。那你希望透過你不斷地調整參數,那你的generator generate出來的output要跟real的data越接近越好。
link |
你並沒有辦法一步從p-G0直接跳到p-G100,你必須要從p-G0可能先調整一下參數變成p-G50,再跳到p-G100。
link |
如果今天p-G50其實沒有比p-G0還要好的話,那如果還有one的話就是p-G1這樣子。好,算了,這個太無聊了。假設今天你必須要從p-G0變成p-G1,再變成p-G2,然後再變成p-G50,最後才能夠變到p-G100。
link |
如果今天p-G50其實沒有比p-G0好的話,那你在train你的generator的時候,它就不會從p-G0變成p-G50,最後就不會跑到p-G100。
link |
如果用演化來比喻的話,就好像是說,今天在演化的時候,生物的子代和青代之間只能夠有非常微小的差距,你沒有辦法透過一次的變異就產生非常複雜的器官,所以每一次的變異都必須是有好處的。
link |
舉例來說,假設人要產生翅膀的話,你可能沒有辦法一下子就產生像天使一樣的翅膀變成鳥人,你可能只能夠產生沒有辦法讓你飛行的很小的翅膀。
link |
那假如很小的翅膀沒有辦法給你帶來好處,沒有辦法讓你的生存機率變高的話,人類的演化就沒有辦法朝那個產生翅膀的方向走。
link |
所以今天假設要產生,比如說我們知道說眼睛是一個非常複雜的器官,但是生物並不是憑著一次的突變就憑空產生眼睛這種器官,而是經過不斷的累積,而每一步的累積,每一次的突變都比前一次好,那天則才會往產生眼睛這種器官的方向走。
link |
舉例來說,在右上角這邊放了一個眼睛演化的歷史,一開始生物只是在皮膚上出現了一些感光細胞,接下來感光細胞出現的位置就變得低一點,就下線了。
link |
下線的好處是,可以知道說光是從哪一個方向來的。接下來,因為下線的地方很容易累積髒東西,所以就產生體液把它包裹起來,然後再產生鈣質把它蓋起來,最後就變成眼球、變成眼睛這種器官。
link |
那在這整個演化的過程中,每一步都比前一步更好,所以演化的方向才會從左邊到右邊。那對generator來說也是一樣,如果從左邊到右邊每一步的變化並沒有比較好的話,那它就會沒有辦法從左邊的distribution變到右邊的distribution。
link |
這是Jays divergence的問題,所以我們會需要另外一個divergence。如果今天使用的是Phasor Standard Distance,你就不會有這個問題了。如果你使用Phasor Standard Distance,它會衡量這兩個distribution之間的距離,就算是這兩個distribution它們沒有重疊,你還是可以衡量它們之間的距離。
link |
所以Pg0和Pdata之間的距離可以寫成D0,Pg50跟Pdata之間的距離你可以寫成D50,而Pg100跟Pdata之間的距離可以寫成D。
link |
從左邊到右邊,Phasor Standard Distance量起來是越來越小越來越好,那你在調整generator的參數的時候,才有可能從Pg0一直變到Pg100。
link |
好,那現在假如我們要從F divergence換成這個Phasor Standard Distance怎麼做呢?那其實Phasor Standard Distance它並不是F divergence的一種啦,所以你沒有辦法直接套用下面這個式子。
link |
那這邊就直接告訴大家答案,如果你今天要衡量Pg和Pdata的Phasor Standard Distance的話,那你要找一個discriminator去maximize下面這個function。
link |
好,那怎麼做呢?今天如果我們先看這個大括號裡面的式子,那我們先從Pdata裡面sampleX出來,然後計算Dx的期望值,從Pg裡面sampleX出來,計算Dx的期望值。
link |
那你要maximize這個式子,也就是要讓Dx如果從Pdatasample出來的話,它的值越大越好,Dx如果X是從Gsample出來的話,它的值越小越好。
link |
但是光maximize這個式子是不夠的,這邊還有一個constraint是說,D不是任何的function都可以,D必須要是一個one-distance function才可以。
link |
什麼是distance function呢?distance function的定義長得像是這個樣子。distance function是說,假設你的input從x1變成x2,假設你的input從x1變成x2,那你的output從f of x1變成f of x2。
link |
那x1減x2的差距的k倍,一定要大於等於f of x1減f of x2的差距。
link |
那如果我們今天k代1的話,它就是one-distance function。那假設你覺得這個式子沒有很直觀的話,它直觀的解釋就是說,如果今天所謂的distance function的意思,直觀的解釋就是說,這個function是比較平滑的。當它的輸入有變化的時候,輸出的變化會小於輸入的變化。
link |
當它輸入有變化的時候,輸出的變化會小於輸入的變化。所以,如果有一個function非常的平滑,它輸出的變化是比輸入的變化小的,而你輸入有一個比較大的變化,輸出的變化是比較小的,那它是one-distance function。
link |
那如果今天它變化非常的齊居,輸入的變化跟輸出的變化比起來是輸出的變化比較大的話,那它就不是one-distance function。
link |
那這個是告訴我們說,one-distance function的定義是怎樣。總之我們要找一個discriminator,它符合one-distance function的定義,然後去maximize後面這個式子。最後算出來的結果就是這兩個distribution之間的resistance distance。
link |
好,那接下來我們可以非常的直觀的來解釋說,為什麼一定要有這個one-distance function的限制。你想想看,假設沒有這個one-distance function的限制的話,會發生什麼事?
link |
假設沒有one-distance function的限制,我們現在有Pg這個distribution,有Pdata這個distribution,它們的距離是d。假設沒有one-distance function的限制,你要去maximize右邊這個式子的話,會發生什麼事呢?
link |
會發生說,Pdata的地方我們希望d of x越大越好,那可以多大?無限大。那x2這個地方,就是Pg這個data所在的地方,我們希望把這個x2代到d of x以後,它的值越小越好,那可以多小?可以是負無限大。
link |
這樣,你算出來的,你把這一項減這一項算出來的resistance distance,不是就變成無限大了嗎?它就變成說,你有兩個distribution,假設沒有前面這個one-distance function的限制,會變成說,只要你有兩個distribution,這兩個distribution只要沒有重合,它們算出來的distance就是無窮大。
link |
那這個不是resistance distance。那所以怎麼辦?你一定要有one-distance function的限制。有one-distance function的限制會造成什麼樣的結果呢?
link |
one-distance function的限制會告訴我們說,假設你真的這個地方給它正無窮大,這個地方給它負無窮大,那它的變化就太快了,它就不是one-distance function。
link |
記得,one-distance function的定義就是,它的變化不可以太快。如果你這邊給它正無窮大,這邊負無窮大,它變化就太快了,這個不叫one-distance function。所以你就只能說,這邊我們給它k加d,然後這邊給它k,然後讓它們的差距是d,這樣它才能夠符合one-distance function的定義。
link |
如果這邊是k加d,這邊是k,代進去以後,你就可以算出,它們的resistance distance確實就是d。好,那這就是想要解釋說,為什麼我們一定要有這個one-distance function的限制。沒有,你算不出resistance distance。
link |
好,那再來的問題又來了。我們之前,我們就是要用gradient ascent去maximize,找一個d去maximize這個式子,對不對?但是現在的問題就是說,我們說d的這個function是有限制的,它一定要是一個one-distance function。
link |
那你想一下,它在做這個gradient ascent的時候,你其實很難把一個constraint下進去。你在做那個gradient ascent的時候,你就是順著gradient的方向去maximize某一個objective function。
link |
如果今天告訴你說,你現在在optimize objective function的過程中又要給參數某一個限制的話,其實是很難處理的。那所以怎麼辦?在WGAN的paper裡面,它並沒有說,我一定要想個方法,真的optimize這個problem,我們才做接下來的事情。
link |
沒有,它就說,我們先隨便想個方法應急。這個胡亂應急的方法是什麼呢?這個胡亂應急的方法是說,今天假如在training的過程中,我們發現說,train出來的network裡面的參數的weight w,它假設大過c的話,就把它設成c,小於負c的話,就把它設成負c,這個就叫做weight clipping。
link |
設出來的weight大於某一個threshold,就把它設成那個threshold,小於某一個threshold,就把它設成那個threshold。那你可不可以說,用這個方法真的可以讓你找出來的第一次one-dimensional function嗎?結論就是不可以這樣子。
link |
那你說,那為什麼還能用呢?不然也沒有別的方法,先隨便弄個應急一下,看看做不做得起來。那最後結果是,確實做得起來了,就沒事。
link |
好,那你可能會說,這個weight clipping這個方法好像沒有辦法真的給你one-dimensional function,那沒有關係,等一下有另外一個improved argument,它有比較好的方法,限制你的discriminator是一個one-dimensional function,這個我們等一下再講。
link |
我們現在先來講說,假設我們把game變成wgame以後,需要做什麼樣的改變。那這個改變呢,是非常簡單的,我們這邊先很快的秀一下原來的game的式子,原來的game的流程。
link |
那它會非常卡,是因為這是電腦的關係,就我每次按了它都沒什麼反應,然後有時候又跳很多,慢慢的跳出來。
link |
好,那wgame做什麼樣的變化呢?本來是要讓log d of x 的值越大越好,log 1-d of x 的值越大越好,也就是讓d of x 的值越小越好。
link |
如果現在改成wgame,那你要做的第一件事情呢,就是把log d of x 換成d of x,然後本來的加log 1-d of x 換成-d of x tilde。
link |
那這個式子其實非常非常直觀,就是d of x 是real的image的分數,那它的值就越大越好,d of x tilde 是fake image的分數,它的值就越小越好。
link |
好,然後不要忘了要做weight clipping,然後那個在generator的地方呢,你也要有一個相應的變化就是了。好,那有了這個wgame以後有什麼好處呢?
link |
過去因為你量的distance是jsdivergence,所以在training的過程中,你光看那個jsdivergence的值的變化,也就是discriminator loss的變化,你是看不出什麼東西的,它的值每次你train下去幾乎都是一樣。
link |
因為你在training的過程中,一開始你的generator的output跟你的real data它們之間的差異是很大的,它們是幾乎沒有任何overlap。
link |
那這是很合理的,今天你通常產生的東西是,你要產生的這個object的space通常很大,比如說你要產生image,就算是100x100 image,它還是一個1萬個dimension的space。
link |
所以你產生出來的,你的real image它產生出來的東西都是這個非常大的space的一個非常小的區塊,通常它們是幾乎沒有任何交集的。
link |
那甚至在,這個是理論上可能沒有任何交集,但實際上你仔細想想,本來你的data和你的,就本來你的real data就是從data base裡面sample出來的點,
link |
而你的generate,你的pg就是從generator generate出來的點,除非你真,那你通常你在generate的時候,在sample的時候,你都只能sample非常有限的值,比如說500d,
link |
那它們其實,就算它們原來的distribution有overlap,你做完sample以後,它們其實也沒有overlap了,對不對?
link |
因為你sample到,因為本來兩個distribution就算是有overlap,那你sample的東西是discrete的啊,所以它們其實,你sample完以後,就沒有overlap了。
link |
所以今天在整個game的training的過程中,pdata通常跟pg都是一直沒有overlap的,所以你算這些distribution的時候,算出來的值永遠都是一樣的,所以導致今天training的過程中,training的結果到底有沒有變得更好,你不知道。
link |
那怎麼辦?你只能夠一邊train,一邊坐在電腦旁邊看這樣子,就一邊吃飯一邊看,然後每過一個iterate,每過一次update,你就叫它put一些東西出來,
link |
那如果看覺得結果越變越差,就把它cut掉再重新做這樣子,這樣就很痛苦。那怎麼辦?那怎麼辦呢?現在有了Wgame以後,因為我們說這個vector-strand-distance確實可以反映pdata和pg之間的差異,如果pg和pdata越接近,它的vector-strand-distance就越小。
link |
所以當你從Wgame的時候,你就可以看vector-strand-distance,也就是discriminator的loss來決定說,現在你的model到底做得好還是不好。那在Wgame原始的文獻裡面,它就舉了一些例子,告訴我們說,確實可以從discriminator的loss看出現在generate出來的object好壞的變化。
link |
這個縱軸代表的是vector-strand-distance,也就是discriminator經過歸根descent或歸根ascent計算出來的值。那隨著這個vector-strand-distance越來越小,那產生出來的圖片就越來越好,隨著vector-strand-distance越來越小,產生出來的圖片就越來越好。
link |
如果vector-strand-distance非常的大的話,那意味著說你產生出來的image其實也是很糟糕的。那這個呢,就是Wgame的妙用。
link |
那我們講完improve Wgame以後再休息。好,那麼剛才講說Wgame遇到的一個問題就是,不知道要怎麼限制你的discriminator一定要是一個one-listed function。所以怎麼辦?什麼樣的function是one-listed function?
link |
你知道one-listed function它的意思就是說,這個function它是非常的平滑的,它是不是會變化很快的,它是比較平坦的。一個one-listed function,它if and only if,它在每一個位置算出來的gradient的num都是小於2的。
link |
就假設有一個function,就是說one-listed function跟下面這個敘述是等價的。這個敘述是說,假設有一個function,它在每一個位置算出來的gradient的num都小於等於1的話,那它一定就是one-listed function。
link |
所以雖然我們不知道在做gradient descent的時候怎麼限制我們的discriminator,它一定是要one-listed function。但是我們可以限制說,我們今天在認我們的discriminator的時候,這個discriminator它的gradient的num對所有的x來說一定都要小於等於1。
link |
如果我們今天認出一個discriminator,它對所有x算出來的gradient的num都小於等於1的話,那它就是一個one-listed function。
link |
好,那要怎麼做到這件事呢?要如何把這個條件加到optimization裡面呢?你可以在原來的vector-stem-distance的式子後面加上另外一個像是regularization的式子。
link |
比如本來我們在train的時候,我們限制d是屬於one-listed function,現在我們不給d做限制,但是我們在maximize這個數值的過程中,我們加上了一個regularization,加上了一個regularization的constraint。
link |
這regularization的constraint是什麼呢?它是說我們要減ln,ln是一個你可以調的參數,然後summation over所有的x,對每一個x我們都去算它gradient的num,然後減掉1。
link |
如果算它gradient的num減掉1,而這個值小於0的話就沒事,也就是說如果這個gradient的num小於1的話,這一項的值就是0,就不會減掉任何東西。
link |
但是如果今天gradient的num大於1的話,這一項的值就是正的,那這邊乘上一個負號,那就是給你的objective function一個penalty。
link |
今天在找這個w的時候,為了不要有penalty,為了要讓這個值越大越好,為了要讓這一項的值變成0,今天每一個x的gradient,每一個x它的gradient的num就會小於等於1。
link |
好,那這個是improve w game基本的想法。但是現在問題來了,你沒有辦法真的做積分summation over所有可能的x,怎麼辦呢?
link |
我們說我們定了一個distribution,等一下我們會講這個distribution是什麼,定了一個distribution,這個distribution叫做epenalty。我們從這個distribution裡面sample x出來,然後我們希望我們sample出來的x,至少我們sample出來的x,它算gradient的num可以小於1。
link |
本來是希望所有的x,它的gradientnum都小於1,但這件事你做不到,你沒有辦法去check所有的x,它的gradientnum是不是都小於1。但至少我們找一個distribution epenalty,從這個distribution裡面sample x出來,然後我們希望從在這個distribution的範圍之內,至少它的gradient是小於1的。
link |
再來就是怎麼定這個distribution。那在improve w game這篇paper裡面,它說epenalty這個distribution在哪裡呢?它在p data和p g之間,它在p data和p g之間。
link |
這個epenalty這個distribution怎麼定呢?你就從p data裡面sample一個點出來,從p g裡面sample一個點出來,做interpolation,然後把這個interpolation的結果從這一條直線,假設左邊是0,右邊是1,你從0到1之間sample一個值,sample出來,就是x。
link |
假設你今天做image的生成,那p data就是real的image,p g就是生成的image,你把real的image跟生成的image兩張imageinterpolate起來,那interpolate的位是0到1之間的某一個值,是隨機產生的。
link |
那你把隨機產生的image拿出來,你希望那一張image它對你的discriminator算gradient的時候,它的non應該要小於1。那這個epenalty,你這個data你可以sample在不同的位置,p g你可以sample在不同的位置,然後它們合起來就定義了epenalty。
link |
所以epenalty是在p data和p g之間。好,那為什麼定義在p data跟p g之間呢?Hackers裡面是這麼寫的。
link |
Given that enforcing the leastest constraint everywhere is intractable,就我剛才講說,你要把leastest的constraint,也就是gradient node的constraint放在所有的x上面,是不可能的。好,那enforcing that only along this straight line, since sufficient and experimentally result in good performance,反正實驗做出來就是可以的,就這樣子。
link |
那其實之後有不同的方法,比如說有一個方法叫做dragon,就是龍的意思,它其實主要就是改變了epenalty的定義,改變了epenalty的定義,所以你就得到一個新的不同的方法就是了。
link |
那其實把這個epenalty定義在p data和p g之間,其實也是口為直覺的,也是make sense的,因為你想想看,今天你到時候你定好了你的discriminator認好之後,你不是要調整你的p g,讓這個p g去maximize discriminator的值嗎?
link |
那你希望這個p g隨著maximize discriminator的值,它會跑到p data這個地方。所以其實只有p g跟p data中間這個區域可能會影響這個p g的權利,跟p g和p data很遠的地方,可能p g根本就不會走到那裡,所以那些地方也許根本就不重要。
link |
所以,把你的epenalty定義在p data和p g之間,其實仔細想想,在直覺上也是make sense的。
link |
好,那接下來呢,在input w get裡面它又做了另外一個改變,它說,本來我們是希望說gradient的值小於1,對不對?這個max0,gradient的none減1的這個式子就是希望gradient的值小於1,它說把這個式子改掉,改成gradient的none減1的平方。
link |
那本來是希望gradient的值小於1,那現在是要希望改成說gradient的值越接近1越好。
link |
好,那為什麼這麼做呢?那paper裡面又這樣告訴我們,它是說,one may wonder why we penalize the none of the gradient differently from 1,就為什麼我們今天在penalize的時候是希望gradient越接近1越好,不是小於1嗎?不是應該小於1嗎?為什麼越接近越好?
link |
So instead of just penalizing large gradient,它說,the reason is that the optimal critic actually has gradients with none 1 almost everywhere under pr,pr就是p data and pg,那你可以看一下它的paper的appendix裡面的proof,
link |
就是說,假設你已經有了p data跟p g,最好的,就是你可以maximize versus distance的那個discriminator,它有一個性質,它的性質是說,在pr和p g的範圍內,它的這個none,它的gradient算起來是1。
link |
那這邊它又多加了一句,它說,simply penalizing overly large gradient also works in theory,在理論上,你可以penalize就是大於1的gradient,but experimentally, we found that this approach converge faster and to better optimal,至少,反正就是實驗做起來這樣子有比較好就是了,所以反正就是這麼做就是了,這樣子。
link |
好,那這個部分呢,improve w gain的這個部分呢,我們最後就看一下這個實驗,那實驗結果其實頗為驚人,就它比較了這個dc gain,ls gain,其實ls gain有兩個,一個是least square gain,一個是low sensitive gain,這邊是least square gain,而一個是原來的w gain,另外是improve w gain。
link |
而這些東西,它發現說,它故意製造各種極端的狀況,讓不同的gain壞掉,但是最後improve w gain仍然是屹立不搖的,舉例來說,它故意generator跟discriminator弄101層,那這個其實就是胡搞這樣子。
link |
然後這樣dc gain,ls gain跟原來的gain都會壞掉,都train不起來,但是improve w gain是train得起來的。好,那我們在這邊呢,就休息一下,我們大概就,因為時間完畢,我們大概五分鐘後就。
link |
好,接下來我們來講這個energy base gain吧。那energy base gain是什麼呢?energy base gain啊,它其實做的事情,就是在training的process跟原來的gain幾乎是一樣,唯一不同的地方是,它換了它的discriminator的network架構,所以它最主要的不同是換了discriminator計算一個input的image好或壞的方式。
link |
那在energy base gain裡面呢,它的discriminator是一個autoencoder。那在energy base gain裡面,本來我們說discriminator的目標就是給它一張圖片,它的輸出一個值,告訴我們說這張圖片是好還是不好。
link |
那在energy base gain裡面,在這個eb gain裡面呢,它是,它有一個autoencoder,只要把一張image丟進去,我們知道autoencoder就是會做reconstruct嘛,把一張image變成code,再把code變回image,你可以算一個reconstruction的error。
link |
在eb gain裡面它說,如果一張image它的reconstruction error越小,就代表這張image越好。我們這邊用圖示的方法來說明一下,那generator的部分完全沒有改變,唯一有動的是discriminator。
link |
我們說discriminator的工作就是輸入一張圖片,輸出一個分數,代表這個圖片的好壞。那今天在energy base gain裡面,本來的gain的discriminator就是一個一個的hidden layer,但是在energy base gain裡面呢,它有一個autoencoder。
link |
它把image丟進來,encode以後變成code,然後再code或decode把它還原,然後接下來去計算encoder的輸入和輸出之間的差異,大家知道說這個就是autoencoder的reconstruction error。
link |
那這個reconstruction error怎麼計算呢?你就可以用你自己喜歡的方法,舉例來說,輸入的image跟輸出的image的L1node,或輸入的image和輸出的image它們在pixel上的L2node等等。好,那你計算出它的reconstruction error以後,假設我們現在計算出來的reconstruction error是0.1,那在這個energy base gain裡面,它說reconstruction error越小代表圖片越好,reconstruction error越大代表圖片越差。
link |
所以你會把reconstruction error乘上負1,正負顛倒之後,當作是discriminator的output。所以對energy base gain來說,最好的圖片是完全可以reconstruction的圖片,是reconstruction error一模一樣,reconstruction error是0,也是autoencoder的輸入和輸出一模一樣的圖片。
link |
這種圖片,它的得到的分數就是0,然後如果有reconstruction error,那得到的分數就是負值。所以在energy base gain裡面,discriminator最大的output是0,那如果是比較差的image的話,它的output就小於0。
link |
所以energy base gain實際上做的事情是,這條紅色的線就是discriminator的output,也就是reconstruction的loss取一個負號。那今天在train這個discriminator的時候,希望real的data,它的reconstruction loss越大越好,也就是越接近0越好。
link |
那希望fake的data,generated的data,它的reconstruction error越小越好,越負越好。然而今天在做energy base gain的時候,有一件事情你是需要注意的。什麼事情需要注意呢?
link |
因為我們知道說,創造是比較困難的,破壞是比較容易的,對不對?我們知道說,破壞是比較容易的,創造是比較困難的。
link |
那我想到亞路加,如果要修復一個東西的話,要實際上接觸那個東西才能夠修復。但是如果它要破壞的話,它是不需要實際上接觸那個東西的,雖然沒有人知道我在講什麼,這樣。
link |
所以怎麼辦呢?如果你今天只是告訴他說,real的data你要能夠reconstruct,fake的data你都要破壞,他最後就會想說,創造這麼難,我們都通通破壞就好,反正fake的data那麼多,我們就盡情的破壞。
link |
破壞很容易啊,你要怎麼讓reconstruction error很大?很簡單,無視input,你今天input什麼東西,我output都是random node,像reconstruction error不是很大嗎?
link |
所以要弄大reconstruction error太容易了,所以如果你只是說reconstruction error越大越好的話,那最後disconnection就學到說只把reconstruction error弄大。
link |
所以怎麼辦?你為了要避免這個問題,你會加一個margin,叫做n。這個margin的意思是說,今天reconstruction error不是越大越好,只要reconstruction error大過一個threshold n以後,再大就沒有幫助了。
link |
這個reconstruction error大過n以後再大,就不會說這個disconnection是比較好的。所以今天當disconnection把這些generated image的reconstruction error都弄得大過n以後,他接下來就要回頭過來,把real的data,他的reconstruction error變小。
link |
好,那有人會問說,這樣子的energy-based game有什麼好處呢?我覺得在實作上它有一個非常大的好處。不知道大家在train game的時候有沒有注意到,一開始你的generator跟discriminator都是隨機的,對不對?
link |
你可能會先想要,來,我們先train discriminator。怎麼train discriminator? 你有一堆real的image,但只有real image你無法train discriminator。你要有real的image,有fake的image,你才能train discriminator。
link |
但是一開始那些fake的image,generator產生出來的image,它是真的很差,因為你的generator是隨機的。所以今天你就拿一堆隨機的image跟real的image,叫discriminator分辨它的差異。
link |
這對discriminator來說,這個問題不是一個很好的問題,因為generator產生出來的image都是隨機的,所以discriminator在這種很爛的generator image之下,他沒有辦法學得很好。
link |
那你說,啊,我不要那些很爛的generator image可以嗎?不行,因為今天discriminator它是個binary classifier,你一定要有real的data跟fake的data。
link |
但energy-based game有一個很大的好處就是,你train autoencoder的時候,你記得嗎?你是不需要fake的data的,對不對?你就把你data-based裡面的real data統統拿出來,你就可以train autoencoder了。
link |
autoencoder training的時候,你只要minimize reconstruction error就好,你根本就不需要那些fake的data。
link |
所以你今天在做EV game的時候,你可以一開始就先把你的discriminatorpre-train得很強,怎麼pre-train你的discriminator呢?把data-based image拿出來,然後你就用這些real的image去train autoencoder,
link |
train完autoencoder以後,你就有你的discriminator了。那這個discriminator它是拿一堆real的image去train的,所以它可以train得很好。接下來呢,你再用這個pre-train好的discriminator再去train generation,然後再去traindiscriminator,再反覆地繼續下去。
link |
那因為你一開始的discriminator就train得很好,所以它很容易最後就可以train起來。所以我認為相較於energy-based game,相較於其他的game,energy-based game在training的時候是比較穩定的。
link |
好,那接下來呢,就講一些define and conquer還有assemble的方法。第一個東西叫做patch game。patch game是什麼呢?他們說,一般我們如果要處理image的時候,比如說在做image generation的時候,那你就是把整張image丟到discriminator裡面,那個discriminator會給它一個分數。
link |
discriminator呢,會需要大量的參數才能夠把它train起來,因為它要吃整張image作為input。如果你image很大的話,那你的discriminator呢,它的參數量就會很多。
link |
那所謂patch game的意思是說,如果我們的discriminator呢,只吃image的其中一小塊,然後呢,就給一個分數。只吃image的其中一小塊,然後呢,就給一個分數。
link |
那這個patch game的patch的大小呢,你當然是需要調的,就像一個hyperparameter一樣,你要調。如果你調得太大的話,那就跟原來的game一樣。如果你調得太小的話,那它就沒有什麼作用。
link |
舉例來說,在原始的patch game,proposed patch game的patch,其實那個patch game它就是用在那個image translation那篇paper裡面。所以在image translation那篇paper裡面,它甚至用了一個非常極端的patch game,它叫做pixel game。就它的discriminator呢,就只看一個pixel而已。
link |
那你說只看一個pixel有什麼用呢,就是沒有什麼用這樣子。只看一個pixel,它就只看到顏色嘛,所以它只能夠調整這張image的顏色,然後產生出來的output呢,就會非常的糊。但它發現說,用最大的patch,把整張image丟到discriminator裡面,得到的結果也不是最好的。你要調一下那個patch的大小,你才能夠得到最好的結果。
link |
那這個呢,就是patch game。就如果你的image太大,你可以讓你的discriminator只檢查image,一次只檢查image的其中一部分。
link |
那還有另外一個,可能很多同學的作業裡面都已經有用到的技巧,叫做spread game。spread game是說,假設要你一次產生一張非常大的圖片,你可能會覺得很痛苦,那不如分階段來產生。先產生比較小張、比較模糊的圖片,再根據比較小張、比較模糊的圖片,產生比較大的圖片。
link |
那下面這個圖呢,是來自於spread game原始的paper。這個圖的意思是說,它終極的目標是要產生一個256x256的解析度的圖片,但是我們先產生64x64的圖片,再把64x64的圖片變成256x256的圖片。
link |
怎麼做呢?一開始有一個最簡單的第一階的generator,第一階的generator它吃一個文字,這個spread game它一開始就是用在文字產生影像,就跟大家作業一模一樣的task上面,先把文字吃進來,然後產生一張64x64的圖片,然後有一個discriminator去check說,根據這個文字還有這個64x64的圖片,它是不是一個好的結果。
link |
然後有了這個64x64的圖片以後,接下來你有第二個generator,這個第二個generator它的condition是一段文字的敘述加上64x64的小張的圖片,根據文字的敘述和小張的圖片,再產生256x256的圖片。
link |
而有第二個discriminator,它看說這個256x256的圖片跟這個文字的敘述match起來是不是對的。總之它的概念很簡單,先產生小張的圖片,再根據小張的圖片產生大張的圖片。
link |
後來StateGate還有一個進化版,就是StateGate++。從這個圖上面,你也可以很輕易地看出這個StateGate++的概念是什麼。它就是說,我們一樣是要做這個文字產生影像的application,輸入一樣是文字的embedding。
link |
把文字的embedding這個綠色的vector輸入以後,先通過前面幾個hidden layer產生64x64的圖片,然後把64x64的圖片丟到discriminator裡面。
link |
當然這個discriminator除了吃圖片以外,它也會吃condition。這邊所有的discriminator除了吃圖片以外,也都會吃condition。
link |
先產生64x64的圖片,再根據64x64的圖片產生128x128的圖片,再產生256x256的圖片,中間都會檢查說128x128的圖片有沒有比較好,256x256的圖片像不像是真的。
link |
在training的時候,這整個從0到64x64到128x128到256x256的這整個process是jointly trained的。
link |
在StateGame++裡面,它有稍微設計了一下它的discriminator。我覺得它的discriminator其實是蠻特別的。它這個discriminator先吃image進來,然後它會根據吃進來的image決定它是real的image還是fake的image。
link |
然後呢,它會把這個image吃進來以後得到一個embedding,再把這個embedding跟condition,這C代表condition,這是文字敘述的embedding,它再把image的embedding跟文字敘述的embedding再丟到另外一個綠色的network裡面,再決定說這個文字的敘述跟這個圖片它們合起來是不是好的。
link |
那你可能說,為什麼要把一張圖片是不是好的跟文字敘述和圖片是不是match這兩件事情分開來衡量呢?
link |
就在原來的conditional game裡面,在大家作業實作的時候,頭腦裡都是discriminator,就是image跟文字的敘述拋出一個數值就結束了。
link |
那我說那個數值代表兩個含義,一個是這張圖片好不好,另外一個是圖片跟文字的敘述是不是match在一起的。
link |
而在second++裡面,它把一張圖片好不好跟文字圖片的敘述是不是應該match在一起這件事情分開來考慮。
link |
那分開來考慮有什麼好處呢?我覺得有一個好處是,我們說在做conditional game的時候,我們有兩種negative example,對不對?
link |
有一種negative example是圖片是對的,但文字敘述是錯的。
link |
你給機器一張看起來非常清晰的貓,但跟它說這是火車,你給它看一個非常清晰的火車,但輸入的文字是貓,這個時候那張圖片其實是對的,只是文字敘述跟圖片match起來不一樣。
link |
那一種negative example丟到這種discriminator裡面,在training的時候,我們可能就會希望它如果只有輸入image的時候得到的分數是高的,在輸入image跟文字一起輸入的情況下,它的分數是低的。
link |
因為假設你只有一個數值,然後你說給它一張清晰的圖片,加上不對的敘述,那你告訴discriminator說你應該給它很低的分數,
link |
那discriminator會不知道說你給它低的分數到底是因為它圖片化得很模糊,還是圖片跟文字的敘述不對,也許discriminator會誤以為說你輸入這張很清晰的圖片,是這個圖片其實仍然是很模糊,
link |
那它就會學到奇怪的東西,就會做錯誤的事情。但是如果是state game++的這種discriminator,它把文字敘述,它把一張圖片是不是好的,還有文字敘述跟圖片是否匹配這件事情,拆開來衡量,
link |
那我覺得它把這兩種分數拆開來衡量,應該會得到比較好的performance。
link |
今天還有一個東西叫做progressive growing of game,我們就叫它progressive game好了。在這個progressive game裡面,這是NVIDIA做的,它們可以產生非常巨大的圖片,比如說產生1024x1024的巨大的人臉圖片,這些人臉是用progressive game來產生的。
link |
那progressive game怎麼做呢?那想法也非常的直覺,就是我們一開始先train一個game,它只能夠產生4x4的圖片,接下來再把乘以產生4x4的圖片的game當作initialization,再疊一層,讓它產生8x8的圖片。
link |
就這樣一直疊上去,一直疊上去,都把前面的train好,可以讓它產生小的圖以後,再讓它產生比較大的圖,疊很多層以後,直到它可以產生1024x1024的巨大圖片,那些圖片非常的巨大,連毛細孔都看得清楚了那一種。
link |
接下來我們要講game的ensemble。我知道大家在做作業的時候,你可能做到後來會發現一個問題,什麼樣的問題呢?你發現說,你的game生成出來的圖片,它的diversity其實是蠻低的,那在文件上也常常出現這種狀況。
link |
舉例來說,你的generator任到後來,可能在某一個epa,它產生的圖片都是接近綠色的,在另外一個epa,它產生的圖片都是接近藍色的。
link |
你可能發現說,你的generator隨著training的不斷進行,它產生的圖片已經沒有越來越好了,它只是在不同的mode,比如綠色藍色的圖片間不斷的做變化。
link |
或者這個是某個同學train energy-based game得到的結果,在某一個epa,產生出來的人臉都是白人,然後接下來discriminator就說,你這個diversity怎麼這麼低,不能夠只產生白人,產生別的顏色。
link |
然後generator接下來在下一個epa,產生的臉就通通變黃色,然後在下一個epa,它產生的臉又通通變成黑色,然後discriminator知道黑色臉是不對的,那generator又跑回去產生白色的臉,就會陷入臉的顏色就是不斷的變換。
link |
但是這些人臉並沒有做得更好了,只是在不同的臉的顏色間做切換。
link |
如果只是這樣做的話,那你就會覺得說,你知道我們作業裡面就是要求大家一次產生五張圖片嘛,那個產生出來的五張圖片都非常的一致,那這樣可能這個結果不太好。
link |
怎麼辦呢?有一個大招,這個大招就是ensemble。人在這個世界上,如果你不知道要做什麼的時候,你就做ensemble,總是會比較好的。
link |
ensemble的做法就是,今天假設叫你產生兩張圖片,你就trade兩個generator。雖然這兩個generator,它們各自都只能夠產生非常類似的圖片,但是每一個generator各產生一張,然後跟人家說這個是同一個generator產生的,他就會覺得你的generator產生的image非常的diverse這樣。
link |
這個多個generator,還有多個discriminator的這個gain,在training的時候也是有幫助的,這招叫做generative adversarial parallelization,縮寫是GAP。
link |
這個圖啊,我本來第一次看到的時候,我以為是網友自己畫的,後來我實際看了paper又發現說,paper裡面真的是用這張圖,我一直想知道說,這作者到底有多喜歡七龍珠。
link |
這個圖的意思是說,這邊所有的悟空都是generator,他應該用不同的角色吧,應該有一些是悟空,有一些是悟犯,這樣感覺是比較make sense的,但沒有關係,反正每一個悟空都是一個generator,然後每一個generator都有一個師父,比如說他的師父是龜仙人,他的師父是比克大魔王等等。
link |
而在training的過程中,每次train了幾個epa以後呢,每一個generator就會交換師父,本來他都是跟比克大魔王練習,後來就改成跟龜仙人練習,然後再train了幾個epa又改成這個我老實說我已經不記得他是誰的練習。
link |
那就這樣子透過每一個generator他們會互相交換彼此的discriminator,這樣可以讓每一個generator都認得更好,這招叫做generative adversarial parallelization。
link |
還有一招也可以看作是用到多個discriminator,只是他用到的是未來的discriminator,這個我就不細講了,這個叫做unroll game,它可以用來處理你產生出來的東西非常集中的問題,細節我就不講了。
link |
為什麼還要放unroll game在這邊呢,等一下你就知道為什麼了。好,那接下來要講說怎麼用game來抽更好的feature。好,那我們先講info game,我們知道用game我們可以秤出一個generator,然後這個generator給他input一個vector他就可以output一張image,我們調整input的vector就可以改變output的image。
link |
我們通常期待input的vector的每一個dimension有某種特別的含義,更動某一個dimension,你就可以看到某一種特徵,你就看到輸出的圖片的某一種特徵的變化,但事實上看起來未必是這個樣子,這個是一個文獻上的結果。
link |
那從左到右呢,代表的是輸入game的那個vector,輸入game的那個code的某一個維度的變化,你發現更動某一個維度的時候,其實沒什麼變化,就這樣子。
link |
你會想說,更動這個維度到底造成什麼改變呢?也是有一些改變,比如說這個地方C突然跑出一行,但你要說這個到底是在幹什麼,其實也是不知道的。因為今天你的generator是一個非常複雜的東西,它是一個很linear的function,所以你的input的某一個維度的改變可能對output的影響是非常奇怪的,非常不直覺的。
link |
那其實我們在train neural network的時候常常會遇到這種狀況,因為大家其實常常會想說,你train完一個neural network以後,你想要分析說這個network的每一個hidden layer的每一個neural是在做什麼,但是往往你會分析不出東西來。
link |
那我認為這個分析不出來有一個理由是因為通常有很多時候,一個neural的output的變化對結果是沒有什麼影響的。通常可能是好幾個neural組合起來,而它們有correlation,就是你可能第一個neural值變大,對output沒什麼影響,要一三五的值同時變大的時候,對output才會有一個顯著的影響。
link |
那今天neural和neural之間可能有某些很強的correlation,它們一起值變化的時候才會對結果造成一些影響,所以當你分析單一neural的時候,你通常沒有辦法得到什麼特別有趣的結果,但是如果要分析neural變化它們之間的correlation的話,又覺得太過複雜。
link |
那Infogang是這樣,Infogang想要做的事情是,它希望說,今天你看好一個generator以後,input一個code,這個code每一回改變的時候,對產生出來的image它的特質有非常顯著的變化。
link |
那Infogang是怎麼做的呢?Infogang的做法是說,我們一樣有一個generator,一樣是輸一個code的Z,它就會產生一個imageX,一樣有一個discriminator,這個discriminator會去看這個generator產生出來的X,它是不是一個好的image。
link |
那現在這個Infogang,它會把它的input的code分成兩部分,一部分叫做C,一部分叫做Z',它希望C對output的image會造成合理而顯著的特質的變化,也就是C的每一個dimension都對應到輸出的imageX的某一種特質。
link |
而Z'呢?Z'它的影響對X是一些比較隨機的影響,比較不清楚的影響。那怎麼做到這件事呢?你就要加一個classifier,這個classifier做的事情是,給它一張imageX,它要根據這張imageX猜出說input的這個C是什麼樣的東西,input這個C的值是什麼樣。
link |
那實際上它背後有比較深的理論,它當然是有用到information theory,所以叫做Infogang,那我們這邊就是用比較直觀的方法來跟大家說明什麼是Infogang。
link |
好,所以classifier要做的事情是,根據這個灰色的imageX,然後預測說這個X是從什麼樣的C產生出來的。那你可以把你的generator看作是一個encoder,把你的classifier看作是一個decoder,那這個generator加classifier就可以看成是一個有趣特別的autoencoder。
link |
不過它跟一般的autoencoder是相反的,一般的autoencoder給一個image,把image變成code,再把code變回image,但是今天在這個特別的autoencoder裡面,你是給它一個code,然後把code變成image,再把image變回code,所以跟一般的autoencoder是相反的。
link |
一般在做Infogang的時候,discriminator跟classifier的參數通常可以把它拼在一起,只讓它們在output的地方不一樣,一個output一個scalar,一個output一個vector。
link |
但是這個discriminator,它的存在其實是必要的。可能你仔細想一下,假設沒有這個discriminator,只有這個classifier會發生什麼事。假設沒有這個discriminator,只有這個classifier,我們說generator要做的事情是產生一張image,而這個classifier做的事情是要根據這一張image判斷說它是來自於什麼樣的C。
link |
假設沒有這個discriminator阻撓的話,我認為generator會學到一件事情,直接把C貼到image裡面,貼在左上角,然後discriminator就看左上角長什麼樣子,它就知道C是什麼了,那這樣顯然就等於沒做事了。
link |
所以你一定要有這個discriminator,discriminator會防止generator做一些奇怪的事情,就把訊息用太簡單的方式透露給classifier,它一定要把這個訊息包在image的特性裡面,它產生出來的X一定要讓discriminator看起來還是image,只是它把這個C包在image的特性裡面,然後再給classifier看。
link |
我們把這句解釋,為什麼需要這個C,這個classifier會做什麼事呢?因為這個C一定要對X有非常顯著合理的影響,而且有規律的影響,這樣classifier才能夠根據image的特徵去猜出說它是用什麼C產生的。
link |
有同學可能會問說,我們怎麼知道,比如說自己有二十維,那我們可能前十維當作是C,我們怎麼知道前十維這些C就是對X的特徵是有影響的C呢?
link |
這個你要反過來想,這是一個很有哲理的東西,這個雖然我已經講過了,但是我再講一次。這些C並不是因為它們對產生image的特徵有影響,所以被選為C,而是因為它們被選為C,所以它們會對generator產生的alpha image會有影響。這樣大家聽得懂嗎?
link |
反正就是這麼回事。好,我們來講一下info-gap的實驗結果,這文件上的結果,右上角就是我剛才看到一般的gap會給我們的結果。
link |
info-gap是怎樣呢?如果你用info-gap train的話,你可能改動了C的第一維以後,你會發現看到這個數字從0跳到9。你改變了C的第二維以後,發現數字從左傾變到右傾。你改變了第三維以後,發現你產生的數字從筆劃很細變到筆劃很粗。好,這個是info-gap。
link |
info-gap更動的是generator input的那一個code,我們可以把它想成是一種feature。好,另外還有一個vae-gap,那vae-gap可以想成是在強化你的auto-encoder,我們可以想成它是在強化auto-encoder。
link |
那本來我們知道在train一個auto-encoder的時候,你有一個encoder,它會把imageX變成codeZ,你有一個generator或一個decoder,它會把Z變成X。那你會希望輸入的image通過encoder再通過decoder以後,輸入和輸出越接近越好。
link |
那你可能會train一個vae,你在trainvae的時候,你還會對中間的這個latent的code做一下限制,希望它的分布是高懸的。好,但是你在train這個auto-encoder的時候,有時候你會遇到一個問題,就是你不知道怎麼衡量輸入和輸出的image之間的差異。
link |
那我們通常會量比如說L1的差異,可能會量L2的差異,但是L1和L2的差異往往不能夠完全反映兩張圖片真正的差異,這其實會導致如果你train一個vae,你不是用gain的方法,你直接train一個vae,把它的generator拿出來產生的image往往會很模糊。
link |
那就是因為這些模糊的image,其實他們的L1和L2的loss,他們的reconstruction error其實很低,但是他們從人的觀點來看並不是真實的。
link |
所以怎麼辦?vae gain是把原來的vae再加上一個gain,再加上一個discriminator,就把這個decoder想成一個generator,然後再加上一個discriminator。那在training的時候,encoder會想要minimize它的input還有decoder的output的reconstruction error。
link |
那如果你是vae的話,同時encoder又希望它的output的code,它的distribution是一個固定的形狀。那decoder呢?decoder一方面它會想要這個minimize reconstruction error,但是另外一方面它又希望說,它產生出來的image不只是跟input在pixelwise的像。
link |
通常這個reconstruction error就是一個一個pixel去比對pixelwise的像,在pixel level下看起來不見得像,它只是在pixel level下而已。它另外一方面又希望說,它產生的image不是只和input image在pixel level下,它還要讓discriminator覺得它產生的image是real的image。
link |
那discriminator做的工作就是要分辨一張圖片是real的image還是fake的image。那在vae game裡面,你就會同時train你的encoder,train你的generator,train你的discriminator。
link |
這個是怎樣?我們說錯誤的image有兩種,一種是reconstruction後的image,本來原本real的image做完reconstruction後的image,這個是第一種錯的image。那這種錯的image,我們寫作x tilde,所以前面先產生x tilde。
link |
然後有一種是decoder自己產生的image,那這邊寫作x hat。那通常reconstruction image就算它有點模糊,有點差,其實也不會真的很爛。那decoder產生的image有時候真的可以很爛。
link |
那我們先怎麼產生第一種假的、第一種錯的image呢?你先從data frame裡面sample一大堆real的image,把這些real的image通通丟到encoder裡面去,把real的image通通丟到encoder裡面去產生code,這邊寫成z tilde。
link |
那再把z tilde丟到decoder裡面去產生reconstruct回來的image,這邊寫成x tilde,這是第一種錯的image。第二種錯的image是從prior distribution裡面samplen個code,然後把這些code的產生image變成x hat,然後這些x hat是generator自己產生的fake image,所以有兩種fake image。
link |
那接下來要做什麼事呢?你要update你的encoder,這個encoder做的事情是,你要update你的encoder,那這個encoder一方面希望minimize reconstruction error,另外一方面呢,它對它的這個z的distribution是有所限制的。
link |
然後再來要updatediscriminator,discriminator也要minimize reconstruction error,同時呢,它會想要騙過discriminator,讓discriminator覺得說,x tilde,reconstruct回來的image,還有x hat,也就是它自己產生的image,都是好的。
link |
然後discriminator做的事情當然是,給它好的image要給它高分,給它不好的image,不管是reconstruct還是decoder自己生成,generator自己生成都要給它低分。好,這個就是VAE game。
link |
那其實在VAE game的這個scenario下,還有另外一種discriminator,這種discriminator它output有三個東西,反正我們discriminator只需要output一維,然後決定說好的image就高分,壞的image就給它低分。
link |
但是有另外一種discriminator,它輸出三個值,在輸入一個x的時候,它會去分類說,這張x是屬於real的image,還是屬於generator的image,還是屬於reconstruct的image。
link |
它會去分辨是real的image,還是generator,還是reconstruct。那decoder要做的事情就是,如果不管今天是generator的image,還是reconstruct的image,通常讓discriminator誤判成real的image。
link |
那這樣做的好處是,因為實際上generate出來的image和reconstruct的image,它們的distribution差異其實也還是頗大的。所以讓discriminator把generate出來的image和reconstruct出來的image分成兩類分開去考慮。
link |
另外還有一個東西叫做bygand。那我可能講過,bygand跟ali其實是一模一樣的東西,它們只是取了不同的名字而已。那bygand做的事情是什麼呢?bygand做的事情是,一樣它train的東西一樣有一個encoder,一樣有一個decoder。
link |
那本來encoder跟decoder湊起來就可以train一個autoencoder。但是bygand不是這樣做。bygand說,它要把image變成code,那decoder把code變成image。
link |
但它並不直接來encoder decoder接起來,而是訓練另外一個discriminator。這個discriminator做的事情是,給它一個image,給它一個code,給它一個image,給它一個code。它要去鑑別說,這個image跟code,它們是從encoder來的還是從decoder來的。
link |
這個discriminator的工作是要去分別說,今天給它一個image跟code的pair,它到底是從encoder來的還是從decoder來的。這個演算法的部分,也許我們可以略過,反正大家應該都可以想像是怎麼做的。
link |
反正就是一方面discriminator要分辨說,現在image跟code的pair是來自於encoder還是decoder。另外一方面,encoder和decoder要想辦法去聯手騙過discriminator。
link |
那這麼做有什麼好處呢?假設現在encoder的input和output是xz的join distribution是p of xz,假設decoder的z跟x的join distribution是q of xz,那discriminator就是希望把p of xz跟q of xz拉得越近越好,最好是它們是一模一樣。
link |
那在Bagen那篇paper裡面,它就有證明告訴你說,假設可以讓p跟q的distribution一模一樣,那意味著什麼?那意味著說,當你把一張imagex'丟到encoder裡面得到z'的時候,你在把z'丟到decoder得到x'的時候,
link |
這個encoder的輸入跟decoder的輸出會是一模一樣。或者是,你先把一個x丟到encoder裡面得到x,再把x丟到encoder裡面得到z,這個decoder的輸入和encoder的輸出會是一模一樣。
link |
那你可能會覺得說,這個好像也沒什麼特別的,因為如果你今天希望encoder丟一個東西進去變成code,decoder再把這個code解回來,input跟output一模一樣,你永遠可以train一個一般的autoencoder。
link |
那你說你需要一個code丟到decoder進去變成image,image再通過encoder要產生一個code,這個輸入跟輸出一模一樣,你可以train一個像剛才infogang講的一樣,反過來的autoencoder。怎麼不直接train而需要依靠一個discriminator呢?
link |
我覺得說,今天假設我們使用的是bygap,跟autoencoder比起來,如果兩種model都可以train到optimal的情況,他們可能真的都會得到一模一樣的結果。
link |
但是雖然他們在optimal的情況下會得到一模一樣的結果,但是我們知道我們在train network的時候並不真的可以得到optimal的結果。
link |
而我相信說當使用bygap的時候,因為有加入了discriminator,discriminator在做這個recon,因為如果我們今天在做autoencoder的時候,你就是訓練希望input的image跟output的image,他們L1或L2的distance越小越好。
link |
那這樣不見得能夠讓我們去真的學到image的比較high level的內容,因為autoencoder它只有學說能不能夠recontract image而已。
link |
但是如果是bygap的話,透過一個discriminator,我們知道discriminator其實有generalize的能力,對它來說,兩張圖片就算長得不一樣,但是如果它們裡面的object是一樣的,它們的semantics是一樣的,discriminator其實也會判斷說它們是一樣的東西。
link |
那藉由這個特性,也許就可以讓encode跟decode這件事情做得更好。
link |
好,那這個是bygap。還有一個東西叫做triplegap,那我們就沒有要仔細細講triplegap啦,我們沒有要細講triplegap,那你還可以知道說為什麼我們還是要列一下triplegap。
link |
那其實triplegap跟bygap非常的像,bygap是有一個encoder輸入image變成code,有一個decoder輸入code變成image,那triplegap是有一個classifier,classifier就是輸入object產生class,然後有一個generator就是輸入class產生object,
link |
然後有一個discriminator,discriminator知道說真正的object跟class的distribution是怎麼樣,所以triplegap其實是一個需要label的game,它是一個semi-supervised game。
link |
然後它會希望說分別出現在一個object跟它的label到底是被生成出來的還是真正data裡面的,然後generator跟classifier要去想辦法騙過discriminator,總之這個東西叫做triplegap。
link |
然後用game的技術還可以做domain adversarial的training,domain adversarial training也許大家都知道細節了,我們就不要細講,那在另外一門machine learning的課其實已經講過domain adversarial training。
link |
如果你還不記得的話,我們就很快的複習一下,domain adversarial training做的事情是說,假設你的training set跟你的testing set的distribution不一樣,我們在做machine learning的時候最害怕這種問題,training set跟testing set的distribution不一樣,training在training的data上,testing在testing上,結果當然會爛掉。
link |
那你希望任一個generator,這個generator把training data吃進去以後抽出來的feature跟把testing data吃進去以後抽出來的feature,它的distribution是一樣的。
link |
而怎麼讓這兩個不同的data set抽出來的distribution一樣呢?那就必須要憑藉著discriminator的力量,讓generator丟兩種不同的image,都output一樣distribution的data。那細節的部分就請大家自行參看文獻。
link |
Domain adversarial training就是過去有講過的。好,那還有另外一個沒有要細講的東西是,現在你有了game的技術,你就可以有各式各樣的想像。比如說game可以做一個東西叫做feature disentangle。
link |
那過去比如說你做autoencoder的時候,你把一個東西變成data representation,然後再把它寄回來。data representation的每一個dimension在做什麼事情,你不知道。但是今天有了game的技術以後,你可以把不同的dimension做的事情是不一樣的,你可以把不同的特徵把它拆開。
link |
舉例來說,這邊就是文獻上一個例子,細節你再去check一下文獻。舉例來說,有了feature disentangle的技術以後,那這個是用game做的,那主要怎麼做我們就不細講。
link |
feature disentangle的技術以後,你給你的encoder比如說一張椅子的圖片,它可以把它產生出來的code分成兩部分,一部分對應到椅子的角度,另外一部分對應到椅子的形狀。
link |
這樣做的好處是說,假設你有這五張椅子,它們只有一種角度,你有這一把椅子,它有各式各樣的角度。你可以用那個encoder去把跟角度有關的feature抽出來,去把跟椅子的形狀有關的feature抽出來。
link |
接下來你把角度的feature加上椅子形狀的feature丟到decoder裡面去,那它就會產生各種不同角度的椅子。雖然說這些角度的椅子在training data裡面可能沒有出現,你只有這種椅子,但是你有不同的角度,所以你把這些角度綜合這些椅子的形狀,你就可以製造出各種不同的椅子出來。
link |
在講style transfer之前,我們在這邊休息一下。
link |
現在大家已經有看到滿坑滿谷用game做style transfer的結果。舉例來說,在上課的時候,我們已經講過cycle game,就可以把碼轉斑馬,斑馬轉碼的那個東西。
link |
另外兩個東西跟cycle game非常像,一個叫discogame,一個叫duogame。它們跟cycle game有什麼不同呢?基本上沒有什麼不同,它們就是一毛一樣的東西。你仔細看一下它們的圖,你會發現根本就是一毛一樣的東西。
link |
這個跟cycle game根本是一樣的東西,不同的人在同一個時間幾乎想出一毛一樣的方法。金髮的圖片丟進去,要變黑髮的,黑髮要把它變回原來金髮的圖片,然後discriminator看說這個黑髮的圖片是不是真的是黑髮的圖片。
link |
discogame這個圖都很小,但是它們跟cycle game講的是一毛一樣的。duogame是說,你看你這邊有素描的圖片,你把這個素描的圖片丟到generator以後產生寫實的圖片,把寫實的圖片再通過generator產生原來素描的圖片,input和輸出會越近越好。
link |
discriminator看說這個圖片是不是真的像是寫實的圖片。它們跟cycle game其實意思都是一樣的。我在網絡上找到有一個人,他用cycle game的技術把所有動漫的角色從正常的髮色統統變成銀髮。
link |
技術大家都知道,我一想問的問題就是他到底對銀髮有什麼樣的執著。除了cycle game以外,還有一些非常像是cycle game的東西,比如說couple game。
link |
couple game的縮寫就是core game。couple game它做的事情就是,它train了兩個generator,這兩個generator它們前面幾個layer是被tie在一起的,所以當你丟一個code z進去的時候,因為前面幾個layer是被tie在一起,它們會是一模一樣的,所以前面幾個layer的output會是一模一樣的。
link |
它們到最後幾個layer的時候才會分道揚鑣,最後幾個layer的東西是不一樣的。你input一個z以後,可能一邊產生的就是真實人物的照片,另外一邊它就是產生動畫人物的照片。
link |
真實人物的照片跟動畫人物的照片,它們會是非常接近的,因為你input的是一樣的z,然後最後前面幾個layer是被tie在一起的。但是怎麼讓其中一邊的輸出是真實的圖片,另外一邊是動畫的畫風呢?你就需要兩個discriminator。
link |
一個discriminator,它看過很多真實的圖片,所以希望它第一個generator的輸出看起來是真實的圖片,可以騙過discriminator。原來discriminator它是要偵測一個圖片是不是動畫的圖片,那generator就要輸出動畫的圖片,讓discriminator覺得它畫的是動畫的圖片,就這樣。
link |
那你說如果用couple game,也就是口game怎麼做style transfer呢?有一點點難做。如果說用couple game有一點點難做,怎麼做?給一張圖片,反推原來的z,再用z去生成另外一邊的圖片,給一張圖片,用歸顛assent的方法看說哪一個z最有可能產生這張圖片,然後再把這個z丟進去,在另外一邊產生另外一個風格的圖片,就這樣。
link |
這個叫做口game。因為口game做style transfer其實沒有很容易,所以後來又有一個口game的進階版,叫做uni,uni就是unsupervised image-to-image translation的縮寫。
link |
這個uni做的事情是,它很複雜,有兩個encoder,有兩個generator,有兩個discriminator。那這個uni做的事情是什麼呢?它會做四件事。假設你有一個寫實的圖片,通過第一個encoder變成code,再把這個code丟給第一個generator,那你要產生寫實的圖片。
link |
那怎麼知道它是不是寫實的圖片呢?有一個寫實圖片的discriminator去盯著說generator的output是不是寫實的圖片。第一個generator它output的圖片必須要讓第一個discriminator覺得它是真實的圖片。
link |
另外一邊有一個動畫的圖片進來,變成code,丟到第二個generator,要產生動畫的圖片。第二個discriminator會判說這張圖片是不是動畫的圖片。接下來,你真實的圖片進來,通過第一個encoder,再把這個code丟給第二個generator,必須產生動畫的圖片。
link |
然後你把一個動畫的圖片丟進來,丟到第二個encoder,產生一個code,再丟到generator,你必須要產生真實的圖片。這個就是unit。
link |
在unit裡面還附了一個表格,告訴你說它這個技術跟其他的方法間有什麼樣的關係。舉例來說,如果你看E1跟G1合起來,它是一個autoencoder,輸入image變成code,再output一模一樣的image,輸入image變成code,再output一模一樣的image。E1、G1是一個autoencoder,E2、G2是一個autoencoder。
link |
如果你今天把整個networktrain好以後,你從這邊input一張image,你從這邊輸出來,你就可以做style transfer。你從這邊input一張image,你從這邊輸出來,你就可以做style transfer。
link |
如果看G1、D1,它們是一組game。如果看G2、D2,它們是一組game。如果你看E1、G1、D1,它們是一個VAE game。我們講過VAE game對不對?autoencoder加上discriminator就是VAE game。所以E1、G1、D1是個VAE game,E2、G2、D2是個VAE game。
link |
如果你沒有這個encoder,只有G1、G2、D1、D2,那你是一個code game,就是couple game,所以就是這麼複雜。
link |
還有別的東西,比如說domain transfer network,這個我們就不要講。還有另外一個,最近Google投到ICLR的,叫做Xgame。為什麼我們要講Xgame,才要把它特別拿出來呢?等一下你就知道。
link |
還有一個stargame,stargame做的事情是,它可以在多個domain間互轉。舉例來說,你有一張這個人的圖片,你可以把它變成金髮的,可以把它轉換性別,從男的變女的。
link |
可以把它變老人,可以把它皮膚變白,可以把角色的髮色改了、性別改了、年紀改了,然後皮膚顏色改了。或者是這邊有一堆人,你可以讓他們看起來都很生氣,你可以讓他們看起來都很高興,你也讓他們看起來都很恐懼。
link |
這個東西叫做stargame。原來如果你沒有用stargame的技術,其實你也可以做不同domain間的轉換,只是如果你有四個domain,那你就需要C4取二個不同的transformation的transformer才能夠做這個stargame,才能做這種不同的domain間的轉換。
link |
但stargame厲害的地方就是,它只需要一個generator就好了。就假設你有五個domain,但是它只需要一個generator,就可以讓你在不同的domain間進行互相的轉換。
link |
其實stargame那個paper是蠻清楚的,裡面那個圖也畫得蠻精緻的,我這邊只是就把圖放在這邊留給大家自己看。然後我還發現說,有人用style transfer的方式做了一個幫動畫人物自動上色的網站。
link |
怎麼evaluate你的generator生成的結果?那我們知道說,其實要evaluate generator生成的結果,目前還沒有一個非常好的方法,那像我們作業裡面就只好請大家幫忙用peer review的方式來看你的generator生成出來的結果是什麼樣子的。
link |
那怎麼衡量一個generator呢?如果是傳統的方法,傳統的,不是deep的generator,一般的generator,我們怎麼量它的好壞呢?我們會算它產生data的likelihood。
link |
也就是,你有一個generator,那你把這個generator認好之後,接下來你拿一堆的real data,testing data過來,當然這些testing data,generator在訓練的時候是沒有看過的,然後去計算這個generator產生這組data的likelihood。
link |
generator產生這組data的likelihood越大,就代表這個generator越好,因為它越容易產生這些real data,代表它越是一個好的generator。
link |
但現在問題來了,對deep的generator來說,對用gantt圈圈的generator來說,它是一個deep neural network,你沒辦法算它的likelihood。我們一開始,這堂課一開始的時候告訴你說,給你一個real的data,問你說從這個generator產生這個real data的機率有多少,likelihood有多大,你不會算。
link |
如果今天這個generator它只是一個簡單的,比如說,Gaussian mixture model,叫你給你一個Gaussian mixture model,每一個mixture都給你它的weight跟mean跟variance,叫你算它產生某一data的機率,其實likelihood,你其實會,但問題就是,PG它是一個很複雜的東西,它並不是一個Gaussian的mixture model,所以你沒辦法算,你能夠做的事情是說,我可以去sample一大堆的data出來。
link |
但問題就是,你sample來sample去,你很難恰好就sample到跟real data一模一樣的東西,所以就算不出說,這個generator產生real data的likelihood到底是多少。
link |
所以怎麼辦?一個方法是說,雖然generator我們沒辦法拿generator來算likelihood,我們只能拿mixture model來算likelihood,那我們就想辦法把generator的distribution,這個PG,轉成一個Gaussian的mixture model。
link |
怎麼把它轉成Gaussian的mixture model呢?你就用這個generator去sample一大堆的data,那你再說,這每一筆data就代表了一個Gaussian的mixture的mean,那variance你就自己隨便調一個,每一筆data代表一個Gaussian的mean,那variance你就自己稍微手調一下,就設個variance。
link |
然後你就可以把這個PG轉成一個Gaussian的mixture model,把PG轉成一個Gaussian的mixture model以後,你就可以去算它的likelihood,就這樣。
link |
那當然說,這是一個好方法,這可能不是一個特別好的方法,它會給你一些奇奇怪怪的結果。
link |
首先第一個問題就是,把PG轉成Gaussian的mixture model未必有那麼容易,首先你必須要sample非常多的data,才有可能真的估出PG的形狀。就PG很複雜啊,你可能要sample很多的data,才能夠真的估出PG的形狀。
link |
所以,既然你估不出PG的形狀,你沒有辦法sample夠多的data,那你得到的這個distribution可能是很弱的,可能根本就跟原來的PG不像,你根本就不知道要sample多少data,你產生的distribution才跟原來的PG像,那你當然就算不出正確的likelihood。
link |
所以這只是一個方法,但未必是最好的方法。再來還有更麻煩的問題,就算你可以估測likelihood,你也無法知道image的quality,就假設你做影像的生成,或是你做其他東西的生成也一樣。
link |
likelihood跟quality並不是等價的。你很有可能今天你有很低的likelihood,但是你產生出來的object quality是很高的。什麼樣的情況你會有低的likelihood,但是產生出來的東西quality很高呢?
link |
假設你有一個generator,那這個generator其實它只會產生良工春日而已,這些角色都是良工春日。一個generator它其實只會產生良工春日的圖,但它其實產生得非常好,它專長就是畫良工春日。
link |
那你去計算,這個generator產生其他角色,比如說長門的likelihood,它永遠都不會畫長門,所以它產生長門的likelihood是很低的。但是你不能夠說它畫得不好,它畫得很好,只是它產生你要拿來testing的那一組data,你拿一組data叫它,問它說你產生這組data的likelihood是多少,它的likelihood很低,但它其實畫得很好。
link |
那有另外一個可能是likelihood很高,但是quality很差。今天我們假設有一個generator,它很會產生好的image,估測說它產生每一張image的機率,也可以估測說它的likelihood,它的likelihood就是對所有image的log probability的summation再去平均,假設我們可以做到這件事情。
link |
接下來,我們假設說有另外一個generator,這個generator它有1%的機率會跟generator 1產生一模一樣的東西,但是它有99%的機率會產生random的noise。
link |
就G2有1%的機率是跟這個generator一樣,有99%的機率就是產生random的東西。那今天這個G2的likelihood是多少呢?我們已經知道G1的likelihood是多少,是L。
link |
那我們知道G1它產生每一筆data Xi的機率就是Pg of Xi,那G2它有1%的機率會跟G1一樣,那G2它產生Xi的機率就是100%Pg of Xi,對不對?
link |
好,那假設G2的likelihood是這樣寫的,那我們知道說log裡面相除,可以把它提出來變成相減。所以呢,除100這件事情等於減log100,而後面這一項不動,後面這一項就是原來G1的likelihood。
link |
G2只有1%跟G1一樣,有99%都跟G1不同,所以它減掉log100。但減掉log100很大嗎?其實減掉log100是很小的,其實這樣算一下,減掉log100才減4.6而已。
link |
如果你真的去量那個likelihood,你通常量它的likelihood都很大,都數百數千,差4.6,其實是沒差多少,但是實際上如果你看這樣的generator,這個G1 generator應該是比G2 generator好100倍的。
link |
好,所以在evaluate的時候有種種的問題。那近年來呢,為了要大量的evaluate各種不同的model,我們不能夠只能再靠人來看這些image,我們需要用一種自動的方法來衡量generation的結果。
link |
那所以怎麼辦呢?我們可以拿一個已經train的很好的CNN來,假設你要衡量影像的好壞的話,那你就拿一個很好的CNN來,把一張image丟給這個CNN,根據這個CNN的output來決定說這張圖片是好還是不好。
link |
那怎麼根據這個CNN的output來決定這張圖片是好還是不好呢?假設這個CNN就是一個分類器,比如說它是Google Map,Inception Map,它印了一張image,它會告訴你說這張image是狗的機率有多少,是貓的機率有多少,是猴子的機率有多少,怎樣叫做它是一張好的image呢?
link |
如果這張image,今天你的CNN可以非常肯定的說它有99%的機率是狗,它不太可能是其他的圖片,就代表說今天輸的這張image是很清楚的,所以CNN才能夠很明確的判斷它應該是哪一個類別。
link |
所以今天如果一張圖片進來,CNN有100%的機率確定它是一隻貓,那就代表說今天產生的圖片真的很像貓,所以CNN才可以正確判斷它是屬於哪一個類別,是屬於哪一種動物。
link |
所以今天用CNN你可以量出你輸的圖片到底畫得好不好,但是另外一方面呢,我們也希望說今天我們的model不要有那種某collapse的狀況,它不要只產生某幾類的圖,而是希望它的輸出越多樣化越好。
link |
你不希望說,你今天假設你的data變成有狗有貓有猴,但是訓練完以後,你的model只會產生狗,它其實從來不會產生別的動物,你希望它的產出是比較diverse的。
link |
怎麼衡量它的輸出是不是diverse的呢?一個簡單的方法就是,你叫你本來在上半部我們只衡量一張圖片,看看機器人可不可以非常confident知道一張圖片它是屬於哪一個類別。
link |
但是在下半部呢,我們輸入一把圖片,你讓generator產生一萬張圖片,然後通通丟給CNN,那怎樣的狀況叫做好呢?
link |
假設今天各種不同的類別都有被產生到,就今天你把一萬張圖片丟給CNN,CNN就判斷說,這一萬張圖片每一張屬於什麼樣的label,而各種不同的label都有被產生到,各種不同的class都有被產生到,那就代表今天這個generator產生出來的東西是比較多樣化的。
link |
好,那based上這些技術,Google就定了一個measure叫做Inception Scope,之所以叫Inception Scope,當然就是因為使用的是InceptionNet,那這個InceptionNet就是一個CNN的class,把你錄一張image,然後它會告訴你這張image屬於某個class的機率。
link |
那Inception Scope是怎麼定的呢?假設你現在產生了一把的imageX,那你把這一把的imageX通通丟到InceptionNet裡面去計算,根據這個X它產生某一個class Y的機率,然後你再計算summation over所有的Y,P of Y given X log P of Y given X。
link |
你去計算summation over所有的Y,P of Y given X log P of Y given X,這一項是什麼?這一項其實就是負的entropy,它其實就是負的entropy。
link |
那我們知道說entropy越大,代表說產生的distribution越低,所以我們今天會希望說這一項的值越大越好,也就是負的entropy越大越好,也就是entropy越小越好。
link |
那如果P of Y given X的entropy越小越好,意味著什麼呢?意味著現在產生出來的distribution,給它一張image的時候,machine非常confident說這張image屬於某個class,而不屬於其他的class。
link |
這是Inception score的第一項,Inception score還有第二項,第二項是P of Y的entropy,P of Y是什麼意思?P of Y是說我們現在把你產生出來的image,通通都丟到這個Inception net裡面,
link |
然後每一次丟一張image的時候,Inception net就會產生一個distribution,它把所有的distribution通通平均起來,叫做P of Y,或者是講得比較直觀一點,就是給一把image通通丟到Inception net裡面,
link |
這把image中某一個class有出現的機率是多少,比如說狗有出現的機率是多少,貓有出現的機率是多少。我們會希望說,今天如果是給一整個distribution,算某一個class出現的機率是多少,
link |
這一個distribution應該要越平越好,對不對,越uniform越好,因為我們希望說,今天給一整個set裡面,每一種動物都要,假設你是產生動物的話,每一種動物都要出現,有狗有貓有猴子有大象有老虎猩猩,每一種動物都要出現。
link |
所以你希望今天P of Y這個entropy,它越大越好。這邊是有加,這邊entropy本身就有負號,所以包括負號這一項是P of Y的entropy,那紅色這一項是P of Y given X的negative entropy,這兩項加起來就是Inception score。
link |
那你希望Inception score越大越好,就是希望說,P of Y given X的entropy越小越好,但是P of Y本身的entropy越大越好。這兩件事情聽起來有點矛盾,但是你仔細想想看,前面這一項是evaluate一張image,後面這一項是evaluate所有產生出來的image。
link |
比如說用這個分數,你就可以去比較不同model之間的差別。舉例來說,在原來的improveW-gain那篇paper裡面,它就比較了說,如果我們現在用,Freudian penalty就是那個improveW-gain,用improveW-gain產生image,那個縱軸是Inception score,所以值越大越好。
link |
那藍色的線顯然特別差,藍色的線是什麼?藍色的線是原來的W-gain,用vecating來找one basic function的W-gain,那performance其實是比較差的。那黃色和綠色是improveW-gain,那你看,紅色的線其實才是最強的,紅色的線是原來的DC-gain,所以根據Inception score,其實原來的DC-gain是最強的。
link |
那W-gain它的強項其實是它比較穩。那大家最近可能都有知道一篇paper,就是Google比較了各式各樣不同的gain,然後得到了一個農場文比較喜歡的結論,就是所有的gain是差不多的。
link |
那它比較了各種不同的gain,NN-gain、NS-gain、W-gain,W-gain GP就是improveW-gain,LS-gain、DRE-gain,還有BE-gain。BE-gain,我們剛才有講energy-based gain是EB-gain,那EB-gain有一個improve版本就是BE-gain。
link |
那它比較了各種不同的gain,它用的這個分數叫做FIT,那我們今天甚至還沒有講FIT。FIT是什麼?FIT是說,你準備一個CNN,那你把real的image都丟到CNN裡面,那你再把CNN的hidden layer取出來。
link |
每張image不是hidden layer都可以取出一個vector嘛,所有的real image取出來的hidden vector你當作一個Gaussian distribution。那你把generated image也通通丟到discriminator裡面,每一張generated image也會得到一個vector,所以generated image也是一個Gaussian distribution。
link |
雖然這兩個Gaussian distribution之間的距離就叫做FIT,但直覺講就是,你generated image如果跟real image越像,但它的像並不是人眼看的像或者是pixel size的像,而是根據某一個CNN它們看起來像不像。
link |
而如果它們越像,當然結果就越好,所以FIT的值是越低越好的。就得到一個農場人喜歡的結論,就是不同的game其實是沒差多少。但是我覺得這邊還是有一些重要的訊息,就是最右邊這個結果特別不一樣。
link |
雖然你坐得比較遠,可能看不清楚這個字,但最右邊的結果,這個值是越低代表產生出來的image越好,每一張圖其實代表不同的corpus。
link |
你會發現,最右邊這個方法特別跟別的方法不一樣。最右邊那個方法其實不是game,它是VAE。你會發現,VAE最好可以產生的圖片就是它的最低點,沒有辦法像其他的game做得一樣好。
link |
所以顯然,在產生image的情況下,其他game如果它可以做到最好的話,它是可以贏過VAE。其他game如果它竭盡全力的話,它們就可以贏過VAE。
link |
但是VAE,你會發現它的range特別小。這邊這個range是怎麼來的?就是試不同的參數。試各種不同的參數,每一組game,我記得好像也許是試一百組種不同的參數得到一個range。你會發現VAE的range特別小,顯然它特別穩定,但它如果要做到最好的話,它沒有辦法像其他game做到那麼好。
link |
那布洛丹·培爾就得到一個結論說,所有的game既然它的range那麼大,就好像那個比斯級跟奇亞獎的,就是每個人的能力其實都是一個range,所以假設B的能力其實平均起來沒有A好,但是在最終極的,在某些特定的情況下,B也其實可以贏過A的。
link |
所以也許我們今天在propose不同game的時候,那些不同game並沒有performance比較好,只是你一直sample,你一直調參數,然後某一個你自己propose的game,你就調比較多參數,讓它做得比較好,就可以打爆另外一個平常,打爆另外一個你的baseline,那你就可以說,我產生的圖是比其他的baseline還要清楚的。
link |
那這是這篇paper得到的一個有趣的想法。不過從這個圖我們還是知道說,我覺得game明顯是可以贏過VAE的。那game還有另外一個問題,就是mocalex的問題。
link |
這個是我們之前已經看過的產生動畫人物的頭像,那我們勸在我做了五萬次update的時候就停止了,為什麼不繼續做下去呢?因為再繼續做下去就會爆炸,每一個人臉通通都會變成一樣,就會通常變成被下巴很尖的角色dominate,而且這個角色就會越來越多,而且他有不同的髮色,他就會不斷地繁殖。
link |
那這個問題就叫做mocalex。那有另外一個問題,它比mocalex輕微,但是它沒有像mocalex那麼容易被發現。mocalex一看就知道這是怪怪的,所以一看就會知道說有問題,重做這樣子。
link |
那有另外一個問題叫做missing mode,missing mode是說,今天你的data base裡面,你的real data吸收很多不同的mode,但是你的generator它只會產生某些可能比較常見的mode。那些沒有出現的東西,你搞不清楚說是generator其實永遠都產生不出來,還是你只是沒有sample到而已。
link |
舉例來說,在這些圖片裡面,我就發現說,它從來沒有sample過眼鏡娘這樣子,不知道說是generator產生不了眼鏡娘,還是只是sample得不夠多,所以沒有看到眼鏡娘。那搞不好眼鏡娘是一個missing mode,generator沒有學到可以產生長門,這樣。
link |
好,那另外一個要注意的事情是,我們不希望churn出來的game是一個memory game這樣。什麼叫做memory game?memory game就是說,它其實沒有產生新的圖,它就故意硬背,把data base背起來。
link |
等一下你要產生一個東西的時候,它就從data base裡面直接挑一個東西說是它產生的。它其實沒有generator的能力,它是一個memory game,它就只有把它在看過的東西硬背下來。那怎麼check說你的game是不是一個memory game呢?其實也沒有非常好的方法。
link |
有一個你可以做的事情是,比對你產生出來的image和data base裡面的image它們之間的差異。比如說,你把兩張image拿來量它們的L1或L2的distance,但是這個方法其實也不是最好的。
link |
舉例來說,假設你的generator產生了一個看起來像羊的東西,那你把這個羊拿到data base裡面去,假設data base裡面正好有一模一樣的羊,那最像的當然就是一模一樣的圖片。
link |
但是你把這個羊往左移動一個pixel,結果你就會發現data base裡面最像的圖片變成這一張,再往左移動兩個pixel就變成這一張,再往左移動三個pixel就變成這一張。這樣會變成說你的game搞不好其實還是memory game,它只是學到說我們把data base裡面的pixel都往左移一個。
link |
你就檢查不出來了,因為你算的是pixelwise的相似度。你把所有的image往左邊移動一個pixel,它確實看起來從pixel來看非常的不一樣,但是人一看,在high level上就會發現說它們其實是一樣的東西。
link |
總之就是,這個也沒有很非常好的solution,只是告訴大家說,你在train game的時候,這其實也是一個你要注意的問題。也許你的game看起來產生的圖很漂亮,但是它只是從data base裡面copy一張圖出來而已。
link |
最後是game的conclusion,game from A to Z。我也講過很多次,世界上有非常非常多的game。每當你發明一個新的game的時候,就在game前面加上幾個字母,你會發現說字母很快就不夠用了。
link |
比如說有一篇paper叫做variational approaches for autoencoder-generated adversarial networks,照理說它應該叫做AE game或者是A game,但是它叫做alpha game。為什麼叫alpha game呢?作者在文章裡面有解釋說,我們把它叫做alpha game,因為別的字母通通已經被選完了,所以只能叫做alpha game。
link |
剩下這個conclusion remark,我們在英文裡面from A to Z的意思就是從頭到尾的意思,但是我這邊的from A to Z是字面上的from A to Z。我們就來講講說,從A到Z分別有什麼樣的game,我們只講在這門課裡面有提到的game而已,沒提到的我們還不講。
link |
A有什麼?其實你可以跟你的同學玩這個遊戲,只是沒有人要跟你玩而已,我只好自己跟自己玩。
link |
A有什麼?A有AC game,這助教投影片上有提到。B有什麼?白game,好,那大家回答,C有什麼?conditional game,太好了,我其實沒想到conditional game,我想到的是psycho game,但我還想到couple game。
link |
D有什麼?DC game,E有什麼?還有dual game,沒錯,還有dual game。E有什麼?有EV game,沒錯,EV game其實有個變形叫DE game,不過它的開頭是B就是了。
link |
F有什麼?F game,G有什麼?game就是G,但我這邊列額型是GMP,它其實不是一個game。那H有什麼?這課沒有講到捨近遊戲,其實沒有。
link |
文獻上應該是有的,我相信你仔細找,一定找到什麼hierarchical game之類的,只是這門課沒有提到而已。I有什麼?info game,IC game,IC game是什麼?我們有講,invertible conditional game,等一下你下課告訴我那個是什麼。
link |
可能是有的,真的真的,我相信是有的。這個世界上的game實在太多了。J有什麼?J沒有,真的是沒有J,你可以想想看,你可以propose什麼用J開頭的game。
link |
K有嗎?K其實也沒有,我相信應該文獻上是有的,我覺得K應該很容易湊吧,但是反正這門課沒有提到。L呢?Ls game,沒錯,Ls game還有兩個。
link |
N呢?很難想對不對。Nn game,minimax game。N呢?Ns game對不對,non-saturation game,就是一開始Ian Goodfellow提了Nn game的一個變形。
link |
O呢?O其實沒有,有一個,就是我也看game的書裡面有什麼object reinforcement game什麼之類的,但我沒有提到這樣子。
link |
那P呢?P應該有吧。Pixel game,對,有pixel game,我剛才講了一個pixel game,其實還有一個patch game,那其實還有progressive game,我這次只有列progressive game而已。
link |
Q呢?Q沒有,我覺得Q還蠻難湊梗的,可以想一下。R呢?R其實是有的,但不是今天講的,但之前有講過。
link |
好,其實有個rank game這樣子。S,S應該很容易,rank game之前講過啦,這S太容易想了對不對,star game,stay game,star game,還有sequence game這樣子。
link |
那T呢?T呢?有人想得起來嗎?我們在這門課裡面不是講了很多game,列了很多game,但其實是沒有講的,就只是為了要湊這個字母而已。
link |
那triple game,那U呢?為了湊梗才放的,unlaw game,那V呢?VAE game,W就不用講了,就W game對不對。
link |
那versus and distance,對,W game。X呢?就X game,特別就放了X game,就是為了要湊這個。X很難湊的,所以我認為X開頭game目前應該是只有X game而已。
link |
那Y其實真的就沒有了。其實我覺得因為Y的字實在太少了,所以你可能難以湊。那我覺得可以從形狀來想,如果你propose一個game,input一個東西,然後output有兩個,你就可以說它是Y game這樣子。
link |
那Z真的是沒有,有一個Z內game。有一個Z內game,那這門課沒有講到就是了。
link |
好,那game的複習就到這邊,這就是game的A to Z。你可以跟你的同學玩這個遊戲,但我相信沒有人要跟你玩就是了。
link |
好,那今天上課就上到這邊,謝謝大家。