本文記錄一些對深度學習的思考總結.意識流寫法,想到哪寫到哪,日后不定期更新補充.
在沒有接觸深度學習的時候,覺得這是個非常高大上的技術,數學基礎要求非常多,上手門檻非常高.我想很多人和我有一樣的想法.這種對深度學習的印象,我想很大一部分來自鋪天蓋地的自媒體的有關AI的報道解讀,造成了一種深度學習,人工智能非常高大上的感覺. 實際上媒體人沒有相關的理論基礎,甚至沒有工科背景,文章寫出來又要吸引人能帶流量,有時又難免誇大,各種名詞什么神經網絡,人工智能,梯度爆炸,並行計算優化,對沒有接觸過相關技術的人來說,很容易造成一種很高大上很神秘的印象.
其實,神經網絡並不是什么新鮮的東西,早幾十年就有了,卷積也不是什么新鮮東西,在模式識別,圖像處理里也早就應用廣泛. 現如今,深度學習大紅大紫,還是因為時代發展到了這個階段,算力的發展,芯片的發展,更快的gpu的出現,更好的計算優化技術,互聯網時代我們有了大量的數據,這些都使得卷積神經網絡的訓練成為可能,而不是僅僅在理論層面.大量的訓練數據,使得深度學習在很多業務領域有了更好的表現,尤其是圖像處理方面。
深度學習的本質
先說結論:本質就尋找最合適的卷積核,最合適的特征權重,最大限度擬合訓練樣本。本質是計算。
以圖像處理為例,傳統的方法怎么做的? 手工提取特征 + 傳統機器學習. 深度學習怎么做的?端到端的學習,不再需要手工提取特征了,自己學習特征.
比如下面這幅圖,你很容易就認出來這是一只貓.
你有沒有想過,你的大腦是怎么識別出來這是一只貓的?通過眼睛,耳朵,嘴巴,尾巴,腿?還是通過這些的組合?這里的"耳朵,嘴巴,尾巴"等等就是所謂的"特征"。雖然你並沒有意識到你的大腦經過了一系列復雜的運算,但它確實是經過了一系列復雜的運算,然后告訴你這是一個貓。只不過神經元的速度太快了,你意識不到而已.
對計算機而言,上面的圖就是一堆數字而已,比如800*600的圖,就是一個800*600*3的矩陣,為了簡化表達,就用灰度圖來說吧,那就是800*600的矩陣,矩陣里相應元素的值代表着像素值.當然"像素值"這個概念,也是我們人為賦予的,計算機才不care什么像素值不像素值,對它來說,就是個數字而已.
那問題來了,什么樣的數字代表"貓的眼睛",什么樣的數字代表"貓的耳朵"?以前這個工作是手工去做的.現在是神經網絡自動去做的.
比如對連續5個像素,值為1,34,67,89,213,我就認為這5個像素代表貓頭,這個規則是我事先定義好的.(當然這是我瞎定義的,這5個像素當然不能代表貓頭)。手工去做的時候,你需要理解業務,比如識別車和識別貓,(1,34,67,89,213)在貓的圖片里可能代表貓頭,在車子圖片里可能代表車屁股,其含義是不同的.這就麻煩了,不同的領域,規則不同,而且,特征工程就是他娘的玄學啊,特征成千上萬,找也找不完,好的特征和壞的特征對最后的識別結果帶來的影響千差萬別,怎么衡量該重點考慮哪種特征?.
而對深度學習來說,輸入就是一堆數字而已,它不懂數字代表的業務含義,它也不需要懂,它只要嘗試出最合適的卷積矩陣,使得loss最小就行,前面也說了,本質是計算。
這里也可以看到,傳統的方法和深度學習的方法,在思路上就是完全兩種思路. 前者更看着規則的定義,也就是特征的提取. 后者則更看重輸入的數據,只要你輸入的數據夠多,質量夠好,我就能自動提取出有效的特征和權重.(當然,這個意義也是我們人為賦予的,學習出來的其實就是一堆數而已,我們把他們稱之為特征,這個時候,他們不再代表貓頭、耳朵等等了,可能就是一個點,一條線,肉眼看去已經無法理解了,如下圖)
這也是前面提到的,深度學習之所以站到了歷史的台前的兩大原因之一:海量的數據。
現在就涉及到卷積的概念了.
卷積
為什么
這個卷積核能起到邊緣檢測的作用?想想你是怎么去判斷圖像邊緣的?如果給你一副純色圖,有邊緣嗎?
比如
顯然沒有啊。因為純色圖,矩陣的每一個像素值都一樣的,所以分不出邊緣.看出來了吧,你通過判斷與周邊像素的差別來判斷是不是邊緣.差別越大越有可能是邊緣.現在在看上面的卷積核,很清楚了吧,經過卷積運算(不懂卷積運算的,先看看置頂的那篇https://www.cnblogs.com/sdu20112013/p/10149529.html) .每一個像素值x都變成了8*x + (-1)*周邊像素,即8*x -周邊像素。這可不就是在比較當前像素和周邊像素的差值嗎?所以卷積完的矩陣,繪圖繪制出來,就有了邊緣的效果.
按照這個思路,不難理解為什么不同的卷積核會有不同的效果了,也就是不同的特征被我們提取出來了.很多人設計好了很多卷積核,分別完成不同的功能.傳統的圖像處理,就是去使用這些卷積核,再配以規則,完成適配自己業務領域數據的特征提取.
好,重點來了.上面說了,"邊緣"這個特征被提取出來了,那對這個代表圖像邊緣的矩陣,叫matrix_a吧,繼續找一個卷積矩陣kenerl_a,對其做卷積,得到matrix_b,這個martrix_b什么意義呢?再對這個martrix_b做卷積,得到martrix_c,這個martix_c又代表啥呢?答案是我們不知道,像上面提到的,最終的矩陣繪制出來,可能已經是一個點,一條線了,我們已經無法肉眼識別他們在現實世界的對應物體了.但並不代表這是無意義的,不同於貓的眼睛,耳朵等等這些高級特征,這時候得到的這些點啊線啊,已經是非常抽象的低級特征了.而圖片正是由這些大量的低級特征組成的.
深度學習干的啥事?就是尋找成千上萬的卷積核,得到成千上萬的特征,然后用分類也好,回歸也罷,認為我們的目標=特征權重*特征之和.比如obj=0.3*feature1 + 0.5*feature2,obj=1代表貓,obj=2代表狗. 這樣拿到一個新的圖片,輸入給模型,模型通過卷積就計算出對應的feature1,feature2,然后計算obj,然后我們就知道了這張圖是貓和狗.
當然,卷積核不是瞎找的,卷積核矩陣里面的數字到底填幾,要是一個個瞎試,再牛逼的gpu,再牛逼的芯片也試不完啊.這里面就涉及到損失函數定義,梯度下降了.
詳細的去看我機器學習的文章吧,不想看的就知道模型學習的過程里,卷積核的值填什么不是隨機亂填的,每次反向傳播更新卷積核的時候都是朝着讓loss更小,也就是讓模型更准確(所謂更准確,是針對你的訓練數據來說的,同樣的網絡結構,你機器上跑出來的模型的參數和別人跑出來的模型參數是不一樣的,如果你們的訓練數據不一樣的話)這樣一個目標去更新的就完了.
怎么設計出一種濾波器/卷積核
比如上圖的卷積核可以識別右邊的曲線.道理也是很顯然的,上圖的卷積核的形狀就是類似我們想要的曲線的形狀的.如果遇到類似形狀的圖像,卷積(對應位置像素值相乘再相加)之后得到的數會很大,反之很小.這樣就把想要的形狀的曲線識別出來了.
與信號處理的關系
大學的時候,學信號處理,天天就是各種傅里葉變換,完全不知道有啥用.說實在的,大學的很多老師水平其實也不咋地,基本就是照本宣科,要么放萬年不變的PPT,可能自己都不能深刻理解,或者與產業界太脫離,完全不講這些理論的現實應用.其實講清楚這些現實意義也沒那么難么.所以還在上學的同學們,要好好學習啊,要好好學習啊,要好好學習啊,重要的事情說三遍,你現在以為沒用的東西,不知道哪天就派上用場了.
現在回頭看,卷積不就是離散的傅里葉變換嗎. 從信號的角度理解卷積,卷積核不就是濾波器嗎,卷積核對圖像的作用,不就是對圖像這種信號做濾波嗎.啥叫濾波,其實也就是特征提取。
傅里葉變換將時域和空域信息-->轉換到頻域上. 對圖像處理而言,我們處理的大部分時候是空域的信息.說人話就是空間信息,對單幀圖像而言,我們卷積出來的特征,點也好,線也罷,是一種形狀,是空間上的信息. 連續的圖像才存在這時間信息,多幀圖像是有聯系的,比如視頻,時域信息就很重要了.
https://www.zhihu.com/question/20099543/answer/13971906
首先說說圖像頻率的物理意義。圖像可以看做是一個定義為二維平面上的信號,該信號的幅值對應於像素的灰度(對於彩色圖像則是RGB三個分量),如果我們僅僅考慮圖像上某一行像素,則可以將之視為一個定義在一維空間上信號,這個信號在形式上與傳統的信號處理領域的時變信號是相似的。不過是一個是定義在空間域上的,而另一個是定義在時間域上的。所以圖像的頻率又稱為空間頻率,它反映了圖像的像素灰度在空間中變化的情況。例如,一面牆壁的圖像,由於灰度值分布平坦,其低頻成分就較強,而高頻成分較弱;而對於國際象棋棋盤或者溝壑縱橫的衛星圖片這類具有快速空間變化的圖像來說,其高頻成分會相對較強,低頻則較弱(注意,是相對而言)。
https://www.zhihu.com/question/29246532
圖像傅里葉變換如何理解?
所以對於數組來說,數字之間變化劇烈,代表高頻,柔和代表低頻.同理,對於圖像來說,那就是灰度變化快的是高頻,慢的是低頻.比如一個物體的邊緣,就是高頻信號,物體內部,就是低頻.而傅立葉變換無非是告訴你這副圖像上XXX頻率的信號有多少多少, YYY的頻率有多少多少.那換句話說就是,圖像的傅立葉變換可以讓你直觀的看到這幅圖總體上"劇烈"的變化有多少,"柔和"的變化有多少.一副整體很模糊的圖,傅立葉變換后顯示的低頻分量就很多一副整體灰度變化很劇烈的圖,傅立葉變換后顯示的高頻分量就很多同理,如果你在頻域上將高頻分量去掉,再反變換回去,那圖片就會變的模糊.
圖像的空間信息丟掉了是什么意思
先看CNN中全連接層參數是怎么來的.參考https://zhuanlan.zhihu.com/p/33841176.
以VGG-16舉例,在VGG-16全連接層中,對224x224x3的輸入,最后一層卷積可得輸出為7x7x512,如后層是一層含4096個神經元的FC,則可用卷積核為7x7x512x4096的全局卷積來實現這一全連接運算過程。
這樣做會有什么好處和問題?
好處和壞處是一樣的,就是去除掉位置信息的影響.主要看你處理的是什么問題.對分類來說,我們不關心位置,希望某種像素組合被識別為某種特征,我們不在乎這種像素組合在圖片矩陣的什么位置出現,我都要能識別它,這時候就是好處.
但是對於圖像分割來說,就是壞處了.因為我需要知道位置信息.比如需要知道圖片里的貓在左上角還是右下角,這樣才能准確分割.所以分割模型會用卷積層替代掉全連接層.
在我寫這篇文章的時候,我做了一點google,想看看有沒有人寫過類似的主題,發現有2篇文章寫的很好,我也引用了部分圖,推薦之。
- http://www.hankcs.com/ml/understanding-the-convolution-in-deep-learning.html
- https://blog.csdn.net/DL_CreepingBird/article/details/78574133
圖片和概率分布的關系
圖片是什么?是一堆像素.比如64 X 64 X 3的圖有大概12K個像素. 那我們可以把圖片理解為12K維空間里的一個點.
現在說回概率分布
以二維空間為例,當x=1的時候,可能對應着很多點.那最有可能的y是多少呢?其實也就是x=1時,最密集的點在什么位置. 顯然這個可以通過已有樣本統計得到.
擴展到高維空間,其實道理是一樣的.首先我們有了很多很多圖片,也就是說我們有了很多很多12K維的樣本,這樣的話我們就能得到概率分布,從而可以根據這個分布去填充馬賽克圖片里的馬賽克部分,使得數據最大程度地擬合前面統計出來的概率分布.
很有意思的文章,研究卷積核得到的輸出可視化是什么樣子的.cnn究竟是如何去組合不同的細節信息的.
https://blog.keras.io/how-convolutional-neural-networks-see-the-world.html