--- tags: cs231 --- # Lecture 12 : Visualizing and Understanding --- ## 前言  Lecture 12主要講解的是對卷積神經網絡的可視化和解釋性的研究,從網絡層的特徵可視化開始到基於梯度提升方法的特徵匹配、特徵反演,進而衍生出紋理合成、圖像生成和風格轉移等。 ## Visualize Filters :::warning :confused: 到底原始圖片裡面的各項資訊跟結果有什麼關係:question: ::: ### 第一層 or 前幾層 * 神經網路中間都做些什麼事情?來看看這些 weights of filters長些什麼樣子? * 第一層:可以看到這些 weight 跟 input image 的關係,如線條、對比的顏色等等  * 第二層 or 更深:weights of filters 的圖會更複雜,原因是他是根據第一層的輸出再做一次卷積。因此他的解釋性其實是根據第一層。要從我們的理解來跟 input image 做關聯已經很難想像了 ### 最後一層 * 最後一層:在卷積層裡,輸出之前我們會有一個輸入圖片的 feature map ,決定這張圖被分類到的類別為何? * 在最開始的 K Nearest Neighbor 是用原始影像的 pixel data 來計算接不接近。就會造成那種暗暗的圖片或顏色接近的圖片被分到同一類,但其實根本就沒關係 * 不過在 CNN 所製造出來的 feature map 就會跟原始這種 raw data 接不接近無關。以大象為例......  * 最後一層 - 降維:用PCA or t-SNE,來將最後一層的 feature map(通常非常高維度)來降到低維度。以2維度為例,假設將成(x, y)這兩個數字,那麼一張圖片的feature就會被縮成(x, y)。我們把神經網路的一堆圖片的feature maps壓成(x, y),然後放到平面圖上,就可以看出這些圖片以feature上來看,誰跟誰像 * 來看看這些[圖片](https://cs.stanford.edu/people/karpathy/cnnembed/) * 參考文件:[某個 github](https://github.com/utkuozbulak/pytorch-cnn-visualizations) * CNN 可視化的參考[code](https://github.com/meet-minimalist/Visualize-CNN-Filters) :::info :question: **Question**:用不同的方式降維,畫出來的圖會差很多嗎?<br> :bulb: **Answer**:沒辦法回答差得多不多,但應該會不一樣。原因是不同的降維方式,就會是兩組不同的 vectors,就好像是兩種不同的坐標系,畫出來的圖肯定不一樣 :question: t-SEN是如何運作的呢? :bulb: **Answer**:You can see [this](https://mropengate.blogspot.com/2019/06/t-sne.html) ::: ## Visualizing Activations * 就是可以看在 activation 之前的features,哪些跟結果關係很大。 * [Jason Yosinski 的網站](http://yosinski.com/deepvis#toolbox) * [Jason Yosinski 的 github](https://github.com/yosinski/deep-visualization-toolbox) ## Maximally Activating Patches * 極大化訓練圖片的某個區塊:選定某個神經網路的 neuron,在CNN(以 AlexNet 為例),這個 neuron 其實圖片的某個區塊與上一層 filter 過濾完的值(<font color='red'>$value$</font>)。極大化的意思是,我去尋找 input image 的一塊一塊圖片,哪一塊在這個 neuron 的值(<font color='red'>$value$</font>)最大,把這些在這個 neuron 輸出最大(<font color='red'>$value$</font>)的圖片都收集起來,就可以大約看出這個 neuron 所要找的是什麼特徵的圖  ## Occlusion Experiments (遮擋實驗) 就是說,測試看看將 input image 的某些地方遮住(input image 的所有 pixel values 取平均),然後來預測看看。如果答案變了,那就代表遮住的那個地方對於預測提供重要的 features  ## Silancy Maps * 想知道哪些 pixel of input image 對最後分類是重要的 * 方式:如果我們針對這些 pixel 做些數值上的調整,那麼神經網路 output 出來的分數會不會有劇烈的改變? 分數的變化量除以pixel的變化量  - 計算Saliency Maps時首先要先計算圖片的像素梯度,如果圖片是(3, H, W),那梯度也會是(3, H, W) - 對於每個像素,他的梯度會告訴我們,這個像素發生些微變化的時候,對於正確分類的那張圖片,像素的幅度是多大 - 計算梯度的絕對值,取RGB三者的最大值,最後就會是(H,W)一個channel的灰階圖 Saliency Maps的應用  - 第一張是原圖 - 第二張是Saliency Maps - 第三張是設定了一個門檻值,超過表示是重要的部分(藍色是重要的) - 最後是和原圖合在一起,segmentation 參考文章:https://mathpretty.com/10683.html 程式碼:[github](https://mathpretty.com/10683.html) 老師這麼說:https://youtu.be/6wcs6szJWMY?list=PL3FW7Lu3i5JvHM8ljYj-zLfQRF3EO8sYv&t=33m40s ## Intermediate Features via backprop(guided) (引導式反向傳播) * 好想跳過:cry: 因為老師居然[這麼說](https://youtu.be/6wcs6szJWMY?list=PL3FW7Lu3i5JvHM8ljYj-zLfQRF3EO8sYv&t=2119) * 就是想要只留下好的地方( weight values ),對正確結果是影響的 ## Gradient Ascent ### 說明:用來可視化最大激活函數 我們想要嘗試在圖像的像素上嘗試最大化,並且這些 weight 保持固定。我們嘗試更改某些輸入圖像的像素,讓這個神經元的值最大化。 為了防止過度擬合,導致這些圖像的像素從適合變成特殊的像素,我們會加上正則項,讓生成的圖片比較自然。  - 生成圖像需要具備兩個屬性: - 1.最大程度地激活一些分數值或神經元的值 - 2.我們希望這個生成的圖像看起來是自然的,即我們想要生成的圖像具備在自然圖像中的統計數據。正則項讓生成的圖像看起來是自然的圖像。 ### 如何使用: - 1. 我們需要把初始圖像初始化為0,或是添加高斯噪聲 - 2. 然後重複進行前向傳播併計算當前分數值、通過反向傳播計算相對於圖像像素的神經元值的梯度 - 3. 對圖像像素執行一個小的梯度上升的更新,以使神經元分數值最大化,直到我們生成了一幅漂亮的圖像。  - 2. 依照上面的方法,你就會得到這些圖片。這些圖片就是代表某個神經元,他被激活時的樣子,具體來說,這個神經元就是在找尋這個特徵。為了讓生成的圖片更美更自然,我們會在正則項下功夫 (如果你沒正則項,那張生成的圖片長相可能會overfitting,就不會是你要的R,但[老師說](https://youtu.be/6wcs6szJWMY?t=2506)通常這樣做會什麼都不是,會變成隨機噪聲圖案)   檸檬、🦢都還滿酷的XD - 3.解決問題的另一個角度是通過改進正則化來改善可視化圖像。除了L2範數約束外,我們還定期在優化過程中對圖像進行高斯模糊處理,同時也將一些低梯度的小的像素值置0。可以看出這是一種投影梯度上升算法,定期投影具備良好屬性的生成圖像到更好的圖像集中。例如,進行高斯模糊處理後,圖像獲得特殊的平滑性,更容易獲得清晰的圖像。 現在我們可以不僅對類的最後分數值執行這個程序,也可以對中間神經元。例如,我們可以最大化某個中間層的其中一個神經元的分數值。 以下圖像都是不同隨機初始化圖像經過同一程序得到的結果。  ## Fooling Images / Adversarial Examples fooling images,顧名思義,就是指一張圖片,雖然上面通過肉眼看到的是松鼠(舉個例子),但是因為這張圖片加了一些特定的噪聲,所以神經網絡會將它誤識別為其他物體。 比如我們提取一張大象的圖像,然後告訴神經網絡最大化這張圖像中無尾熊的分數值,然後我們要做的是改變這個大象的形象,讓神經網絡將它歸類為無尾熊。 你可能希望的是這頭大象更像一隻無尾熊(被神經網路魔改?),有可愛的耳朵,BUT代誌並不是ㄚ捏。如果你提取這張大象的圖像,然後告訴神經網絡它是無尾熊,並且嘗試改變大象的圖像,你將會發現第二幅圖像會被歸類為無尾熊,但是它在我們看來和左邊第一幅圖是一樣的!WHY? 第一列和第二列圖像在像素上是沒有差異的,如果你放大這些差異,並不會真的在這些差異中看到ipod或者無尾熊的特徵,它們就像隨機的噪聲模式。但為何會這樣呢?老師埋了伏筆,請大家去聽特邀課程的[Lecture16](https://www.youtube.com/watch?v=CIfsB_EYsVI&list=PL3FW7Lu3i5JvHM8ljYj-zLfQRF3EO8sYv&index=16)XD  步驟如下:  用pytorch來實現吧 ## Deep Dream DeepDream是谷歌發布的對卷積神經網絡(CNN)進行可視化的方法,當然它的用途不僅限於此,我們可以通過它讓機器“做夢” (幾乎是為了娛樂,生成漂亮ㄉ圖片,當然同時也可以知道神經網路在找什麼特徵) 有一個網絡學習了分類貓和狗的任務,給這個網絡一張雲的圖像,這朵雲可能比較像狗,那麼機器提取的特徵可能也會像狗。假設對應一個特徵[0.6, 0.4], 0.6表示為狗的概率, 0.4表示為貓的概率,那麼採用L2範數可以很好達到放大特徵的效果。對於這樣一個特徵,L2 = x1^2 + x2^2,若x1越大,x2越小,則L2越大,所以只需要最大化L2就能保證當x1>x2的時候,迭代的輪數越多x1越大,x2越小,所以圖像就會越來越像狗。每次迭代相當於計算L2範數,然後用梯度上升的方法調整圖像。當然不一定要一張真實的圖像,也可以從一張噪聲圖像生成夢境,只不過生成的夢境會比較奇怪。 以上是DeepDream的基本原理,具體實現的時候還要通過多尺度、隨機移動等方法獲取比較好的結果 1. 將拍攝的圖片丟到神經網路的某一層 2. 回傳,並設置gradient=激活值 3. Backward 並計算gradient 4. 更新圖片  對於以上步驟的解釋:試圖放大神經網絡在這張圖像中檢測到的特徵,無論那一層上存在什麼樣的特徵,我們設置梯度等於特徵值,以使神經網絡放大它在圖像中所檢測到的特徵。這種方法同樣可用於最大化圖像在該層的L2範數。 重複上面的流程...你會得到   BTW為什麼會出現這麼多狗狗的圖案呢?剛好這份資料狗狗的圖案比較多 另外一張比較crazy的圖  參考:https://blog.csdn.net/u012614906/article/details/77882814 DeepDream的tensorflow實現:https://github.com/hjptriplebee/deep_dream_tensorflow  ## Feature Inversion 特徵逆向工程(feature inversion) 這兩類問題的基本思路。給定一個中間層特徵,我們希望通過迭代優化,產生一個特徵和給定特徵接近的圖像。此外,特徵逆向工程也可以告訴我們中間層特徵中蘊含了多少圖像中信息。可以看出,低層的特徵中幾乎沒有損失圖像信息,而高層尤其是全連接特徵會丟失大部分的細節信息。從另一方面講,高層特徵對圖像的顏色和紋理變化更不敏感。   左邊是原始圖像,我們通過VGG-16運行這個圖像,記錄這個神經網絡某一層的特徵,然後嘗試生成一個與那層記錄的特徵相匹配的新圖像,這讓我們了解到這張圖像在神經網絡不同層的這些特徵的信息存儲量。例如當我們嘗試基於VGG-16的relu2-2特徵重構圖像,可以看到圖像被完美地重構,即不會真正丟棄該層原始像素的許多信息。但是當我們向上移動到神經網絡的更深處,嘗試從relu4-3、relu5-1重構圖像,可以看到圖像的一般空間結構被保留了下來,但是很多低層次的細節並不是原始圖像真實的像素值,並且紋理的顏色也和原來不同。這些低層次的細節在神經網絡的較高層更容易損失。 這讓我們注意到隨著圖像在神經網絡中層數的上升,可能會丟失圖像真實像素的低層次信息,並且會試圖保留圖像的更多語義信息,對於類似顏色和材質的小的變化,它是會改變的。  --- ## Texture Synthesis 紋理合成 用一部分的小圖 用他的紋理產生一張大圖 ### 1 Nearest Neighbor 作法:最近鄰居法沒有使用神經網絡,而是運用一種簡單的算法 就是隨機採樣附近鄰居的圖生成的紋理,就是附近的圖複製貼上的概念  優點: - 簡單的紋路可以容易生成 - 因為用附近的區塊採樣生成效的紋理,所以可以有效生成高質量、自然的紋路 缺點: - 只適用於簡單的紋理,簡單紋路效果可能很好,但是複雜的紋路可能就不行 ### 2 Gram matrix 作法: - 每個CNN都有Cx H x W個向量 - 向量相乘得到CxC的gram matrix(對稱矩陣,對角線是自己的相乘) - 每個數字是兩倆特徵之間的關係,哪2個特徵同時出現,哪些不是 - 不同特徵間的緊密程度,論文中稱為不同風格 - 從某種意義上來説就相當於一名藝術家的風格,呈現一張臉的方式與呈現一棵樹、一幢房的方式有某種相關性,捕捉到了這種相關性就捕捉到了風格。   程式碼和範例參考:cnblogs.com/FUJI-Mount/p/12901291.html --- > 了解Gram matrix後接下來看 ### 3 Neural Texture Synthesis步驟  ``` 1 pretrain model: vgg19 2 input一張紋路圖到CNN,每一層的feature map of shape Ci × Hi × Wi 3 每一層都計算Gram matrix -> G ```  ``` 4 input一張noise到CNN,計算每層的Gram matrix -> G' 5 計算兩者的Gram matrix L2 loss -> E ```  ``` 6 算backprop 7 gradient descent產一張output 8 從5 開始繼續更新 ``` 每一層的產出長這樣:  --- ## Neural Style Transfer 風格轉換 Feature(提取特徵)+Gram(紋理分析+紋理合成)   講義只是個概念,以下是步驟說明: - 當我們要在圖片P(content)的內容上應用圖片A(style)的風格時,會使用梯度下降等算法更新目標圖片X(target)的內容  - 左側是風格圖片A(style),右側是內容圖片P(content),中間是目標圖片X(target) - X的初始值是一張白噪音圖片,通過SGD更新 ### 內容content: - 從右側開始,P(content)輸入VGG19中,我們假設提取第四層的feature map得到Pl(l:層數) - 如果X(target)的feature map Fl和Pl很接近,就表示圖的content很接近 (靠近輸出層包含越多content訊息) - 定義Lcontent  ### 風格style: - 計算方法和content不同的是,提取feature map後是Gram matix方法得到紋理 - 較淺的層得到的紋理比較粗糙,但可能很像畢卡索的風格(?) - 較深的層得到的紋理比較精細,會更像輸入的style圖,取決於自己想要什麼樣的風格 - 定義Lstyle   ### 最後: 得到Ltotal = a x Lcontent + b x Lstyle 加權和 可以通過調整阿發或是貝塔b來生成更偏向風格或偏向內容的圖  使用不同風格的圖在一張內容圖上:  調整風格多一點還是內容多點:  參考文章:https://zhuanlan.zhihu.com/p/55948352 keras提供風格轉換的程式碼:https://github.com/keras-team/keras/blob/fcf2ed7831185a282895dda193217c2a97e1e41d/examples/neural_style_transfer.py 還是有個問題,Style transfer需要很多VGG的forward backward計算,所以非常慢,因此出現Fast Style Transfer --- ## Fast Style Transfer  不把生成圖片當作一個**訓練**過程,而是**執行**過程! **分成兩個network:** ``` 1 image transform net生成網絡:接收一個輸入的圖片,輸出合成的圖片,這個net是先pretrain好的 2 loss network:只有loss計算 ``` **分成兩個階段:** ``` 1 訓練階段:跟前面style transfer一樣訓練net 2 執行階段:input -> output ``` 優點: - 不用每次都訓練,只要訓練過一次風格圖,就可以一直輸入content image合成圖片了! - 或是一張content image換各種不同pretrain好的風格圖! - 簡化loss的計算: pretrain 好的net已經有學習到一個程度了 loss network和image transfer net架構一致,只是不做參數更新,只有loss計算 不Fast和Fast Style Transfer前後比較: - 之前是更新像素的loss,得到最後合成圖,後者是多一個image transfer net,先pre-train loss - loss net只計算content loss和style loss(perceptual loss),然後只更新一次image transform net的參數 參考文章:https://my.oschina.net/u/4355830/blog/3953963 https://zhuanlan.zhihu.com/p/23651687 老師的github:https://github.com/jcjohnson/neural-style 結束!好可愛!  --- ## 問題 | 組別 |<center> 問題 </center>| |:-------------------:|----------------------| | 第一組 |1. 若用不同的降維方法降成2維,畫出來的圖會差很多嗎?<br>2. 有用 saliency maps 實作 semantic segmentation 的實例嗎?| | 第二組 |1. 老師說saliency maps可以做semantic segmentation,可以補充一下細節嗎?<br>2. t-SNE如何運作? <br>3. P.19 說可以用一個神經元來算相對於 image pixcels 的 gradient,有點抽象,可以解釋一下嗎?(通常不是會針對某個 loss 去 minimize 他)<br>4. gradient ascent 到底是什麼概念?| | 第三組 |<center>報告組</center>| | 第四組 ||
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up