深度學習入門實戰(一):像Prisma一樣演算法生成梵高風格畫像

qcloud發表於2019-01-04

本文由雲+社群發表

作者:董超

導語:現在人工智慧是個大熱點,而人工智慧離不開機器學習,機器學習中深度學習又是比較熱門的方向,本系列文章就從實戰出發,介紹下如何使用MXnet進行深度學習~ 既然是實戰而且本文是入門級別的我們就不講那麼多大家都聽不懂的數學公式啦~

0x00 深度學習簡介

雖然吧,我們不講哪些深奧的數學原理,但是基本的原理還是要掌握下的~

在介紹深度學習之前我們要先了解兩個概念,機器學習和神經網路。

機器學習:

在介紹深度學習之前,我們先簡單介紹下機器學習,我們引用下維基百科上機器學習的定義:

機器學習是人工智慧的一個分支。人工智慧的研究是從以“推理”為重點到以“知識”為重點,再到以“學習”為重點,一條自然、清晰的脈絡。顯然,機器學習是實現人工智慧的一個途徑,即以機器學習為手段解決人工智慧中的問題。機器學習在近30多年已發展為一門多領域交叉學科,涉及概率論、統計學、逼近論、凸分析、計算複雜性理論等多門學科。

機器學習理論主要是設計和分析一些讓計算機可以自動“學習”的演算法。機器學習演算法是一類從資料中自動分析獲得規律,並利用規律對未知資料進行預測的演算法。因為學習演算法中涉及了大量的統計學理論,機器學習與推斷統計學聯絡尤為密切,也被稱為統計學習理論。演算法設計方面,機器學習理論關注可以實現的,行之有效的學習演算法。很多推論問題屬於無程式可循難度,所以部分的機器學習研究是開發容易處理的近似演算法。

簡單的說機器學習就是讓機器去分析資料找規律,並通過找到的規律對新的資料進行處理。

神經網路:

神經元:

img

以影像為例子,每個資料或者輸入就是一張圖片,而裡面的每個x可以是圖片中的每個畫素。對於每個畫素我們都賦予一個權重,然後經過轉換函式(Transfer Function, 這裡是線性疊加)得到一個數值。簡單來說,我們對所有畫素做個線性加權疊加。得到的數值會經過啟用函式得到新的數值。這個啟用函式(Activation Function)往往是那幾個符合某些特性的非線性函式。為什麼需要非線性的轉換呢?舉個簡單的例子,在同一個平面你和你的影子是重疊是分不開的,在立體的空間你們卻能分開了。非線性的轉換有類似的作用。常用的啟用函式有relu, softmax, tanh。

簡單的說一個神經元是一個簡單的分類器,你輸入一個

比如我們有一大堆貓、狗照片,把每一張照片送進一個機器裡,機器需要判斷這幅照片裡的東西是貓還是狗。我們把貓狗圖片處理一下,左邊是狗的特徵向量,右邊是貓的

img

大家想想,最簡單地把這兩組特徵向量分開的方法是啥?當然是在兩組資料中間畫一條豎直線,直線左邊是狗,右邊是貓,分類器就完成了。以後來了新的向量,凡是落在直線左邊的都是狗,落在右邊的都是貓。

一條直線把平面一分為二,一個平面把三維空間一分為二,一個n-1維超平面把n維空間一分為二,兩邊分屬不同的兩類,這種分類器就叫做神經元。

當然,上面那幅圖我們是開了上帝視角才知道“一條豎直線能分開兩類”,在實際訓練神經元時,我們並不知道特徵是怎麼抱團的。神經元模型的一種學習方法稱為Hebb演算法:

先隨機選一條直線/平面/超平面,然後把樣本一個個拿過來,如果這條直線分錯了,說明這個點分錯邊了,就稍微把直線移動一點,讓它靠近這個樣本,爭取跨過這個樣本,讓它跑到直線正確的一側;如果直線分對了,它就暫時停下不動。因此訓練神經元的過程就是這條直線不斷在跳舞,最終跳到兩個類之間的豎直線位置。

神經網路:

神經網路簡單點將就是由好多個神經元組成的系統。

神經元一個缺點是:它只能切一刀!你給我說說一刀怎麼能把下面這兩類分開吧。

img

解決辦法是多層神經網路,底層神經元的輸出是高層神經元的輸入。我們可以在中間橫著砍一刀,豎著砍一刀,然後把左上和右下的部分合在一起,與右上的左下部分分開;也可以圍著左上角的邊沿砍10刀把這一部分先挖出來,然後和右下角合併。

每砍一刀,其實就是使用了一個神經元,把不同砍下的半平面做交、並等運算,就是把這些神經元的輸出當作輸入,後面再連線一個神經元。這個例子中特徵的形狀稱為異或,這種情況一個神經元搞不定,但是兩層神經元就能正確對其進行分類。

只要你能砍足夠多刀,把結果拼在一起,什麼奇怪形狀的邊界神經網路都能夠表示,所以說神經網路在理論上可以表示很複雜的函式/空間分佈。但是真實的神經網路是否能擺動到正確的位置還要看網路初始值設定、樣本容量和分佈。

深度學習:

那什麼是深度學習呢?深度學習簡單點說就是一種為了讓層數較多的多層神經網路可以訓練,能夠執行起來而演化出來的一系列的新的結構和新的方法。

就像下圖

img

普通的神經網路可能只有幾層,深度學習可以達到十幾層。深度學習中的深度二字也代表了神經網路的層數。現在流行的深度學習網路結構有"CNN(卷積神經網路)、RNN(迴圈神經網路)、DNN(深度神經網路)的等。

當然我們是以實戰為主,可以直接使用現在市面上的一些現有深度學習框架,現在流行的深度學習框架有MXnet,tensorflow,caffe等,本文主要介紹MXnet這個開源的優秀深度學習框架。

0x01 安裝MXnet

這裡我們安裝的是CPU版的MXnet,為什麼不安裝GPU版?因為偶的Macbook是AMD的卡啊,MXnet只支援CUDA

1.下載原始碼

新建一個目錄,到那個目錄下執行

git clone --recursive https://github.com/dmlc/mxnet

2.編譯安裝

執行setup-utils目錄下的install-mxnet-osx.sh指令碼,中間要編譯些東西,要多等會,再輸入個密碼,就自動編譯安裝完成啦。

注意一下:

1.因為要讀取make目錄下的檔案,所以這裡要在MXnet原始碼的根目錄執行安裝指令碼~

比如在mxnet的原始碼根目錄執行

sh ./setup-utils/install-mxnet-osx.sh

2.以後執行指令碼可能需要一些python模組,建議安裝下pip

mac下安裝的方法也很簡單: sudo easy_install pip

0x02 樣例執行

我們可以試著執行下MXnet自帶的一些樣例,這裡我們試下Neural art這個樣例

Neural art是個讓機器模仿已有畫作的繪畫風格來把一張照片重新繪畫的演算法。

比如我們輸入

img

img

最終生成

img

1.首先開啟example/neural-style目錄,大部分樣例都是有README的,大家在執行之前可以先看看

這個樣例的README有說

First use download.shto download pre-trained model and sample inputs Then run python nstyle.py, use-h to see more options

那我們就要執行這個目錄下的download.sh

指令碼會自動下載訓練模型vgg19.params到Model目錄,輸入的素材到input目錄

2.執行Demo

因為我們執行的是CPU版,所以要這麼輸入

python nstyle.py --gpu -1 --max-num-epochs 150 --output_dir ~/Desktop/

--gpu:使用哪個一個GPU,-1代表使用CPU

--max-num-epochs:最大迭代次數,這裡我們迭代150次

--output_dir:結果輸出路徑

可能大家一次執行不起來,會出現No module named for xxx的提示,一般是相應的python模組沒有安裝,在google搜下No module named for xxx一般都能找到安裝方法,大部分都能通過pip安裝~

執行結果

我們看下不同迭代次數時的結果是什麼樣的

10次:

img

50次:

img

100次:

img

150次:

img

可以看出迭代次數越多效果越好~當然由於深度學習是有很多層神經網路組成,需要的運算量巨大,使用CPU即使是i7,150次迭代也需要好幾十分鐘了,有條件的看官可以嘗試使用GPU版,可以將時間縮短到幾分鐘,甚至在雲平臺上跑。

樣例的具體原理可以參考參考附錄的第二個連結。

參考附錄:

http://www.leiphone.com/news/201608/wh8osGY4vg28XlvM.html http://phunter.farbox.com/post/mxnet-tutorial2 https://zhuanlan.zhihu.com/p/20634163 http://www.cnblogs.com/peizhe123/p/4641149.html

此文已由作者授權騰訊雲+社群在各渠道釋出

獲取更多新鮮技術乾貨,可以關注我們騰訊雲技術社群-雲加社群官方號及知乎機構號

相關文章