對抗生成網路GAN系列——WGAN原理及實戰演練
theme: hydrogen highlight: atelier-dune-dark
本文為稀土掘金技術社群首發簽約文章,14天內禁止轉載,14天后未獲授權禁止轉載,侵權必究!
🍊作者簡介:禿頭小蘇,致力於用最通俗的語言描述問題
🍊往期回顧:對抗生成網路GAN系列——GAN原理及手寫數字生成小案例 對抗生成網路GAN系列——DCGAN簡介及人臉影象生成案例 對抗生成網路GAN系列——AnoGAN原理及缺陷檢測實戰 對抗生成網路GAN系列——EGBAD原理及缺陷檢測實戰
🍊近期目標:寫好專欄的每一篇文章
🍊支援小蘇:點贊👍🏼、收藏⭐、留言📩
對抗生成網路GAN系列——WGAN原理及實戰演練
寫在前面
在前面我已經寫過好幾篇關於GAN的文章,感興趣的可以點選下列連結瞭解詳情:
- [1]對抗生成網路GAN系列——GAN原理及手寫數字生成小案例 🍁🍁🍁
- [2]對抗生成網路GAN系列——DCGAN簡介及人臉影象生成案例🍁🍁🍁
- [3]對抗生成網路GAN系列——CycleGAN原理🍁🍁🍁
- [4] 對抗生成網路GAN系列——AnoGAN原理及缺陷檢測實戰 🍁🍁🍁
- [5]對抗生成網路GAN系列——EGBAD原理及缺陷檢測實戰🍁🍁🍁
在文章[5]的最後,我們從訓練結果中可以看出效果並不是很理想,其實難以訓練是GAN網路訓練普遍存在的問題。本篇文章將為大家帶來WGAN(Wasserstein Generative Adversarial Networks ),旨在解決GAN難train的問題。這篇論文中有大量的理論推導,我不會帶著大家一個個推,當然很多我也不會,但是我儘可能的把一些關鍵部分給大家敘述清楚,讓大家從心底認可WGAN,覺得WGAN是合理的,是美妙的。
準備好了嗎,就讓我們一起來學學WGAN吧!🚖🚖🚖
WGAN原理詳解
GAN為什麼訓練困難
上文我們談到GAN普遍存在訓練困難的問題,而WGAN是用來解決此問題的。所謂對症下藥,我們第一步應該要知道GAN為什麼會存在訓練難的問題,這樣我們才能從本質上對其進行改進。下面就跟隨我的步伐一起來看看吧!!!🌼🌼🌼
還記得我們在[1]中給出的GAN網路的損失函式嗎?如下圖所示:
為了方便表述,對上圖公式做如下調整:
$$\mathop {\min }\limits_G \mathop {\max }\limits_D V = {E_{x \sim {{\rm{p}}r}}}[\log D(x)] + {E{x \sim {{\rm{p}}_g}}}[\log (1 - D(x))]$$
即把後一項的$G(z)$用x來表示,x為生成器生成的分佈。
我們現在希望求得生成器固定是最大化的判別器D。首先,我們對於一個隨機的樣本,它可能是真實樣本,也可能是生成的樣本,那麼對於這個樣本的損失為:
$${{\rm{P}}_r}(x)\log D(x) + {P_g}(x)\log [1 - D(x)]$$
預求最大化的D,則對上式的D(x)
求導,並讓上式導函式為0,即:
$$\frac{{{{\rm{P}}_r}(x)}}{{D(x)}} - \frac{{{{\rm{P}}_g}(x)}}{{1 - D(x)}} = 0$$
化簡上式,得最優的D表示式為:
$${D^*}(x) = \frac{{{{\rm{P}}_r}(x)}}{{{{\rm{P}}_r}(x) + {{\rm{P}}_g}(x)}}$$ ———— 式1
我們可以來看看這個式1是否符合我們的直覺。若$p_r(x)=0、p_g(x)\ne 0$表示x完全服從生成分佈,是假影象,所以最優判別器D給出的概率為0;若$p_r(x) \ne 0、p_g(x)= 0$表示x完全服從真實分佈,是真影象,所以最優判別器D給出的概率為1;若$p_r(x)=p_g(x)$,表示x服從生成分佈和服從真實分佈的資料一樣多,因此最優判別器D給出的概率為50%。
如今我們已經找到了最大化的D,現要將其固定,尋找最小化的G,即求下式:
$$\mathop {\min }\limits_G V = {E_{x \sim {{\rm{p}}r}}}[\log D(x)] + {E{x \sim {{\rm{p}}_g}}}[\log (1 - D(x))]$$ ———— 式2
將最大化的D即式1的$D^*(x)$代入式2得:
$$\mathop {\min }\limits_G V = {E_{x \sim {{\rm{p}}r}}}[\log (\frac{{{{\rm{p}}_r}(x)}}{{{{\rm{p}}_r}(x) + {{\rm{p}}_g}(x)}})] + {E{x \sim {{\rm{p}}_g}}}[\log (\frac{{{{\rm{p}}_g}(x)}}{{{{\rm{p}}_r}(x) + {{\rm{p}}_g}(x)}})]$$
再化簡一步得式3:
$$\mathop {\min }\limits_G V = {E_{x \sim {{\rm{p}}r}}}[\log (\frac{{{{\rm{p}}_r}(x)}}{{\frac{1}{2}{{\rm{p}}_r}(x) + {{\rm{p}}_g}(x)}})] + {E{x \sim {{\rm{p}}_g}}}[\log (\frac{{{{\rm{p}}_g}(x)}}{{\frac{1}{2}{{\rm{p}}_r}(x) + {{\rm{p}}_g}(x)}})] - 2\log 2$$ ———— 式3
化簡成式3的形式是為了和KL散度和JS散度相聯絡。我們先來介紹KL散度和JS散度的定義:【大家不要覺得散度這個詞好像很高大上一樣,大家其實就可以理解為距離】
- KL散度
$$KL(P_1||P_2)=E_{x \sim P_1}log \frac {P_1}{P_2}$$
上式是用期望來表示KL散度的,我們也可以用積分或求和形式來表達,如下:
$$KL(P_1||P_2)=\int\limits_x {{P_1}\log \frac{{{P_1}}}{{{P_2}}}} dx$$ 或 $$KL(P_1||P_2)= \sum {{p_1}\log } \frac{{{P_1}}}{{{P_2}}}$$
我來大致的解釋一下KL散度的含義,用$KL(P_1||P_2)=\sum {{P_1}( - log{P_2} - ( - log{P_1}))}$解釋,如下圖:
關於KL散度我就介紹這麼多,它還有一些性質,像非對稱性等等,我這裡就不過多介紹了,感興趣的可以自己去閱讀閱讀相關資料。
- JS散度 $$JS({P_1}||{P_2}) = \frac{1}{2}KL({P_1}||\frac{{{P_1} + {P_2}}}{2}) + \frac{1}{2}KL({P_2}||\frac{{{P_1} + {P_2}}}{2})$$
可以看出,JS散度是根據KL散度來定義的,它具有對稱性。
有了JS散度的定義,我們就可以將式3變換成如下形式:
$$\mathop {\min }\limits_G V = 2JS({P_r}||{P_g}) - 2\log 2$$ ———— 式4
這時候肯定很多人會想了,為什麼我們需要把式3化成式4這個JS散度的形式,這是因為我們的GAN訓練困難很大原因就是這個JS散度搗的鬼。🍵🍵🍵
為什麼說訓練困難是JS散度搗的鬼呢?通過上文我們知道,我們將判別器訓練的越好,即判別器越接近最優判別器,此時生成器的loss會等價為式4中的JS散度的形式,當我們訓練生成器來最小化生成器損失時也就是最小化式4中的JS散度。這這過程看似非常的合理,只要我們不斷的訓練,真實分佈和生成分佈越來越接近,JS散度應該越來越小,直到兩個分佈完全一致,此時JS散度為0。
但是理想很豐滿,現實很骨感,JS散度並不會隨著真實分佈和生成分佈越來越近而使其值越來越小,而是很大概率保持$log2$不變。
如上圖所示,隨著$p_g$和$p_{data}$(也就是上文中所述的$p_r$)越來越近,它們的JS散度卻不發生變化,一直等於log2,只有當$p_g$和$p_{data}$有重疊時才會發生變化,當完全重疊時,JS散度的值為0。也就是說,不論$p_g$和$p_{data}$相距多遠,只要它們沒有重疊,那麼它們的JS散度就一直是常數log2,也就是在訓練過程中loss一直不發生變化,這也意味著生成器的梯度一直為0,即生成器產生了梯度消失的現象。
讀了上文,我覺得你至少應該有兩個疑問,其一是為什麼兩個分佈不重合,它們JS散度一直為log2,其二為既然只要$p_g$和$p_{data}$有重疊,那麼它們的JS散度就不是log2,這樣我們是不是就可以更新梯度了呢?那麼它們重疊的概率大嗎?我們一個一個的來解決大家的疑惑。🥂🥂🥂
- 什麼兩個分佈不重合,它們JS散度一直為log2
這個其實是由JS散度的性質來決定的,這裡帶大家推一推。首先JS散度的表示式如下:
$$JS({P_1}||{P_2}) = \frac{1}{2}KL({P_1}||\frac{{{P_1} + {P_2}}}{2}) + \frac{1}{2}KL({P_2}||\frac{{{P_1} + {P_2}}}{2})$$
上文我也給出了KL散度的公式,將KL散度公式代入上式,得:
$$JS({P_1}||{P_2}) = \frac{1}{2}\sum {{p_1}(x)\log } \frac{{2{p_1}(x)}}{{{p_1}(x) + {p_2}(x)}} + \frac{1}{2}\sum {{p_2}(x)\log } \frac{{2{p_2}(x)}}{{{p_1}(x) + {p_2}(x)}}$$
再化簡上式,將log2提出來,注意這裡可以提是因為$\sum {{p_1}(x) = } \sum {{p_2}(x) = } 1$,提取後公式如下:
$$JS({P_1}||{P_2}) = \frac{1}{2}\sum {{p_1}(x)\log } \frac{{{p_1}(x)}}{{{p_1}(x) + {p_2}(x)}} + \frac{1}{2}\sum {{p_2}(x)\log } \frac{{{p_2}(x)}}{{{p_1}(x) + {p_2}(x)}} + \log 2$$
現在大家注意到上式已經有一個log2了,為證明我們的結論,我們只需證明兩個分佈不重合時上式左側兩項為0即可。我們以下圖為例進行講解:
對於上圖中的兩個分佈$P_1和P_2$,可以看出它們沒有重疊部分。我們設$p_1(x)$為x落在$P_1$分佈上的概率,設$p_2(x)$為x落在$P_2$分佈上的概率,我們來看$JS(P_1||P_2)$的左邊兩項,即$\frac{1}{2}\sum {{p_1}(x)\log } \frac{{{p_1}(x)}}{{{p_1}(x) + {p_2}(x)}} + \frac{1}{2}\sum {{p_2}(x)\log } \frac{{{p_2}(x)}}{{{p_1}(x) + {p_2}(x)}}$ ,
當$x<5$時,$p_2(x)$近似為0,則:
$\frac{1}{2}\sum {{p_1}(x)\log } \frac{{{p_1}(x)}}{{{p_1}(x) + {p_2}(x)}} + \frac{1}{2}\sum {{p_2}(x)\log } \frac{{{p_2}(x)}}{{{p_1}(x) + {p_2}(x)}} = \frac{1}{2}\sum {{p_1}(x)\log } \frac{{{p_1}(x)}}{{{p_1}(x) + 0}} + \frac{1}{2}\sum {0\log } \frac{0}{{{p_1}(x) + 0}} = 0$
當$x \ge 5$時,$p_1(x)$近似為0,則:
$\frac{1}{2}\sum {{p_1}(x)\log } \frac{{{p_1}(x)}}{{{p_1}(x) + {p_2}(x)}} + \frac{1}{2}\sum {{p_2}(x)\log } \frac{{{p_2}(x)}}{{{p_1}(x) + {p_2}(x)}} = \frac{1}{2}\sum {0\log } \frac{0}{{0 + {p_2}(x)}} + \frac{1}{2}\sum {{p_2}(x)\log } \frac{{{p_2}(x)}}{{0 + {p_2}(x)}} = 0$
因此對於任意的x都會有$\frac{1}{2}\sum {{p_1}(x)\log } \frac{{{p_1}(x)}}{{{p_1}(x) + {p_2}(x)}} + \frac{1}{2}\sum {{p_2}(x)\log } \frac{{{p_2}(x)}}{{{p_1}(x) + {p_2}(x)}}=0$ ,進而會有$JS(P_1||P_2)=log2$。🌱🌱🌱
這部分主要參考了這篇文章,我認為其對JS散度為什麼等於log2解釋的非常清楚🍦🍦🍦
- 任意的兩個分佈$p_g$和$p_{data}$重疊的概率有多大
首先,我直接給大家明確結論,重疊概率很小,特別小。我說明一下這裡所說的重疊概率指的是重疊部分不可忽略的概率,也就是說$p_g$和$p_{data}$可能會重疊,但是往往重疊部分都是可以忽略的。這部分大家可以參考這篇文章,寫的非常好,對於這部分的解釋也比較全面。
我從兩個角度幫助大家理解,其一,$p_g$和$p_{data}$假設為一條曲線,$p_g$開始往往都是隨機生成的,所以很難和$p_{data}$重合,往往都是有一些交點,而這些交點是可以忽略的。實際上,$p_g$和$p_{data}$的維度往往很高,它們完全重疊的概率非常之低。
其二,我們往往是從$p_g$和$p_{data}$中取樣一些點出來訓練,即使$p_g$和$p_{data}$有重疊,但是經過取樣後,它們很大可能就沒有重疊了。
解釋了這麼多,大家應該知道為什麼GAN會訓練困難了吧。最後總結一下,這是因為當判別器訓練最優時,生成器的損失函式等價於JS散度,其梯度往往一直為0,得不到更新,所以很難train。
我不知道大家是否會有這樣的疑問,既然說生成器梯度得不大更新,為什麼我們在訓練GAN時還是能得到一些較好的圖片呢,不應該什麼也得不到呢。我是這樣認為的,我們上述的推導都是建立在最優判別器的基礎上的,但是在我們實操過程中往往一開始判別器效能是不理想的,所以生成器還是有梯度更新的。還有一點,就是我之前的文章程式碼中生成器的損失其實使用的$-logD(x)$,這種損失函式也會存在一些問題,往往出現梯度不穩定,模式崩潰問題,但是梯度消失問題出現比較少,所以還是能訓練的。關於使用這種損失函式帶來的缺陷我這裡也不敘述了,大家感興趣的可以看看這篇文章。🍹🍹🍹
EM distance(推土機距離)的引入
我們上文詳細分析了普通GAN存在的缺陷,主要是由於和JS散度相關的損失函式導致的。大佬們就在思考能否有一種損失能夠代替JS散度呢?於是,WGAN應運而生,其提出了一種新的度量兩個分佈距離的標準——Wasserstein Metric,也叫推土機距離(Earth-Mover distance)。下面就讓我們來看看什麼是推土機距離吧!!!🌶🌶🌶
【這部分參考此篇文章】
下圖左側有6個盒子,我們期望將它們都移動到右側的虛線框內。比如將盒子1從位置1移動到位置7,移動了6步,我們就將此步驟的代價設為6;同理,將盒子5從位置3移動到位置10,移動了7步,那麼此步驟的代價為7,依此類推。
圖1 EM distance示例
很顯然,我們有很多種不同的方案,下圖給出了兩種不同的方案:
上圖中右側的表格表示盒子是如何移動的。比如在${\gamma _1}$中,其第一行第一列的值為1,表示有1個框從位置1移動到了位置7;第一行的第四列的值為2,表示有2個框從位置1移動到了位置10。上圖中給出的兩種方案的代價總和都為42,但是對於一個問題並不是所有的移動方案的代價都是固定的,比如下圖:
在這個例子中,上圖展示的兩種方案的代價是不同的,一個為2,一個為6。,而推土機距離就是窮舉所有的移動方案,最小的移動代價對應的就是推土機距離。對應本列來說,推土機距離等於2。
相信通過上文的表述,你已經對推土機距離有了一定了瞭解。現給出推土機距離是數學定義,如下:
$${\rm{W}}({P_r},{P_g}) = \mathop {\inf }\limits_{\gamma \in \prod ({P_r},{P_g})} {E_{(x,y)}}[||x - y||]$$
看到這個公式大家是不是都懵逼了呢,這裡做相關的解釋。${\prod ({P_r},{P_g})}$表示邊緣分佈$P_r和P_g$所有組合起來的聯合分佈$\gamma(x,y)$的集合。我們還是用圖1中的例子來解釋,${\prod ({P_r},{P_g})}$就表示所有的運輸方案$\gamma$,下圖僅列舉了兩種方案:
${E_{(x,y)}}[||x - y||]$ 可以看成是對於一個方案$\gamma$ 移動的代價,$\mathop {\inf }\limits_{\gamma \in \prod ({P_r},{P_g})} {E_{(x,y)}}[||x - y||]$ 就表示在所有的方案中的最小代價,這個最小大家就是$W(P_r,P_g)$,即推土機距離。🍄🍄🍄
現在我們已經知道了推土機距離是什麼,但是我們還沒解釋清楚我們為什麼要用推土機距離,即推土機距離為什麼可以代替JS散度成為更優的損失函式?我們來看這樣的一個例子,如下圖所示:
上圖有兩個分佈$P_1和P_2$,$P_1$線上段AB上均勻分佈,$P_2$在CD上均勻分佈,引數$\theta$可以控制兩個分佈的距離。我們由前文對JS散度的解釋,可以得到:
$$JS({P_1}||{P_2}) = \left{ \begin{array}{l} \log 2{\rm{ }} \quad \theta \ne {\rm{0}}\ 0{\rm{ }} \quad \quad \ \ \theta {\rm{ = 0}} \end{array} \right.$$
而對於推土機距離來說,可以得到:
$$W(P_1,P_2)=|\theta|$$
這樣對比可以看出,推土機距離是平滑的,這樣在訓練時,即使兩個分佈不重疊推土機距離仍然可以提高梯度,這一點是JS散度無法實現的。🍋🍋🍋
WGAN的實現
現在我們已經有了推土機距離的定義,同時也解釋了推土機距離相較於JS散度的優勢。但是我們想要直接使用推土機距離來定義生成器的損失似乎是困難的,因為這個式子${\rm{W}}({P_r},{P_g}) = \mathop {\inf }\limits_{\gamma \in \prod ({P_r},{P_g})} {E_{(x,y)}}[||x - y||]$ 是難以直接求解的,但是呢,作者大大用了一個定理將上式變化成了如下形式:
$${\rm{W}}({P_r},{P_g}) = \frac{1}{k}\mathop {\sup }\limits_{||f|{|L} \le K} {E{x \sim {{\rm{P}}r}}}[f(x)] - {E{x \sim {{\rm{P}}_g}}}[f(x)]$$
注意上式中的f有一個限制,即${||f|{|_L} \le K}$,我們稱為lipschitz連續條件。這個限制其實就是限制了函式f的導數。它的定義如下:
$$|f(x_1)-f(x_2)| \le K|x_1-x2|$$
即:
$$\frac{|f(x_1)-f(x_2)|}{|x_1-x2|} \le K$$
很顯然,lipschitz連續就限制了f的斜率的絕對值小於等於K,這個K稱為Libschitz常數。我們來舉個例子幫助大家理解,如下圖所示:
上圖中log(x)的斜率無界,故log(x)不滿足lipschitz連續條件;而sin(x)斜率的絕對值都小於1,故sin(x)滿足lipschitz連續條件。
這樣,我們只需要找到一個lipschitz函式,就可以計算推土機距離了。至於怎麼找這個lipschitz函式呢,就是我們搞深度學習的那一套啦,只需要建立一個深度學習網路來進行學習就好啦。實際上,我們新建立的判別器網路和之前的的基本是一致的,只是最後沒有使用sigmoid函式,而是直接輸出一個分數,這個分數可以反應輸入影象的真實程度。
呼呼呼~~,WGAN的原理就為大家介紹到這裡了,大家掌握了多少呢?其實我認為只看一篇文章是很難把WGAN的所有細節都理解的,大家可以看看本文的參考文獻,結合多篇文章看看能不能幫助大家解決一些困惑。🧅🧅🧅
WGAN程式碼實戰
WGAN的程式碼實戰我不打算貼出一堆程式碼了,只說明一下WGAN相較於普通GAN做了哪些改變。首先我們給出論文中訓練WGAN的流程圖,如下:
其實WGAN相較於原始GAN只做了4點改變,分別如下:
- 判別器最後不使用sigmoid函式
- 生成器和判別器的loss不取log
- 每次更新判別器引數後將判別器的權重截斷
- 不適應基於動量的優化演算法,推薦使用RMSProp
現在程式碼中分別對上述的4點做相關解釋:【很簡單,所以大家想要將原始GAN修改為WGAN就按照下列的幾點來修改就好了】
- 判別器最後不使用sigmoid函式
這個我們一般只需要刪除判別器網路中的最後一個sigmoid層就可以了,非常簡單。但是我還想提醒大家一下,有時候你在看別人的原始GAN時,他的判別器網路中並沒有sigmoid函式,而是在定義損失函式時使用了BCEWithLogitsLoss
函式,這個函式會先對資料做sigmoid,相關程式碼如下:
python
# 定義損失函式
criterion = nn.BCEWithLogitsLoss(reduction='mean')
如果這時你想刪除sigmoid函式,只需將BCEWithLogitsLoss
函式修改成BCELoss
即可。關於BCEWithLogitsLoss
和BCELoss
的區別我這篇文章有相關講解,感興趣的可以看看。🌽🌽🌽
- 生成器和判別器的loss不取log
我們先來看原始GAN判別器的loss是怎麼定義的,如下:
python
d_loss_real = criterion(d_out_real.view(-1), label_real)
d_loss_fake = criterion(d_out_fake.view(-1), label_fake)
d_loss = d_loss_real + d_loss_fake
原始GAN使用了criterion
函式,這就是我們上文定義的BCEWithLogitsLoss
或BCELoss
,其內部是一個log函式,不清楚的同樣可以參考我的這篇文章。
而WGAN判別器的損失直接是兩個期望(均值)的差,就對應理論中${E_{x \sim {{\rm{P}}r}}}[f(x)] - {E{x \sim {{\rm{P}}_g}}}[f(x)]$ 這部分啦【但是需要加個負號,因為我們都是使用的梯度下降方法,要最小化這個損失,上式是最大化的公式】,我們來看看程式碼中的實現:
python
d_loss = -(torch.mean(d_out_real.view(-1))-torch.mean(d_out_fake.view(-1)))
看完判別器的損失,我們再來看生成器的損失:
```python g_loss = criterion(d_out_fake.view(-1), label_real) #原始GAN損失
g_loss = -torch.mean(d_out_fake.view(-1)) #WGAN損失 ```
- 每次更新判別器引數後將判別器的權重截斷
首先來說說沒什麼要進行權重截斷,這是因為lipschitz連續條件不好確定,作者為了方便直接簡單粗暴的限制了權重引數在[-c,c]這個範圍了,這樣就一定會存在一個常數K使得函式f滿足lipschitz連續條件,具體的實現程式碼如下:
python
# clip D weights between -0.01, 0.01 權重剪裁
for p in D.parameters():
p.data.clamp_(-0.01, 0.01)
注意這步是在判別器每次反向傳播更新梯度結束後進行的。還需要提醒大家一點,在訓練WGAN時往往會多訓練幾次判別器然後再訓練一次生成器,論文中是訓練5次判別器後訓練一次生成器,關於這一點在上文WGAN的流程圖中也有所體現。為什麼要這樣做呢?我思考這樣做可能是想把判別器訓練的更好後再來訓練生成器,因為在前面的理論部分我們的推導都是建立在最優判別器的前提下的。🍵🍵🍵
- 不適應基於動量的優化演算法,推薦使用RMSProp
這部分就屬於玄學部分了,作者做實驗發現像Adam這類基於動量的優化演算法效果不好,然後使用了RMSProp優化演算法。我決定這部分大家也不要糾結,直接用就好。同樣我們來看看程式碼是怎麼寫的,如下:
python
optimizerG = torch.optim.RMSprop(G.parameters(), lr=5e-5)
optimizerD = torch.optim.RMSprop(D.parameters(), lr=5e-5)
這樣,WGAN的程式碼實戰我就為大家介紹到這裡,不管你前文的WGAN原理聽明白了否,但是WGAN程式碼相信你是一定會修改的,改動的非常之少,大家快去試試吧。🍄🍄🍄
小結
這部分的理論確實是有一定難度的,我也看了非常非常多的視訊和部落格,寫了很多筆記。我覺得大家不一定要弄懂每一個細節,只要對裡面的一些關鍵公式,關鍵思想有清晰的把握即可;而這部分的實驗較原始GAN需要修改的僅有四點,非常簡單,大家都可以試試。最後希望大家都能夠有所收穫,就像WGAN一樣穩定的進步,一起加油吧!!!🥂🥂🥂
參考連結
GAN — Wasserstein GAN & WGAN-GP 🍁🍁🍁
如若文章對你有所幫助,那就🛴🛴🛴
- 兔年到了,一起來寫個春聯吧
- CV攻城獅入門VIT(vision transformer)之旅——VIT程式碼實戰篇
- 對抗生成網路GAN系列——GANomaly原理及原始碼解析
- 對抗生成網路GAN系列——WGAN原理及實戰演練
- CV攻城獅入門VIT(vision transformer)之旅——近年超火的Transformer你再不瞭解就晚了!
- 對抗生成網路GAN系列——DCGAN簡介及人臉影象生成案例
- 對抗生成網路GAN系列——CycleGAN簡介及圖片春冬變換案例
- 對抗生成網路GAN系列——AnoGAN原理及缺陷檢測實戰
- 目標檢測系列——Faster R-CNN原理詳解
- 目標檢測系列——Fast R-CNN原理詳解
- 目標檢測系列——開山之作RCNN原理詳解
- 【古月21講】ROS入門系列(4)——引數使用與程式設計方法、座標管理系統、tf座標系廣播與監聽的程式設計實現、launch啟動檔案的使用方法
- 使用kitti資料集實現自動駕駛——繪製出所有物體的行駛軌跡
- 使用kitti資料集實現自動駕駛——釋出照片、點雲、IMU、GPS、顯示2D和3D偵測框
- 基於pytorch搭建ResNet神經網路用於花類識別
- 基於pytorch搭建GoogleNet神經網路用於花類識別
- 基於pytorch搭建VGGNet神經網路用於花類識別
- UWB原理分析
- 論文閱讀:RRPN:RADAR REGION PROPOSAL NETWORK FOR OBJECT DETECTION IN AUTONOMOUS
- 凸優化理論基礎2——凸集和錐