如何利用Docker、AWS和深度學習偽裝成一個藝術家
“能工摹形,巧匠竊意(Good artists copy, great artists steal)” —— 畢加索
在英國第四頻道紀錄片系列之“Faking it”中,Paul O’Hare(一名來自利物浦的畫家和室內裝潢師)需要在四個星期的時間內,將自己偽裝成一個藝術家,並且嘗試著去欺騙倫敦美術館的評論家。我們將要展示如何利用Docker、AWS和深度學習來完成這個任務,並且完成任務所需的時間控制在半小時內,這甚至包含了你閱讀這篇文章的時間。此外,所需的費用不高於$10。
神來之筆
為了加速偽裝的速度,我們將會利用一個人工智慧系統。這個系統基於深度神經網路,該網路能夠創造出和某個藝術家風格一模一樣的藝術作品(至少我們是無法辨別的)。這是如何實現的?這是通過將一個圖片的內容(肖像畫或者風景畫)和另外一個圖片的樣式(這通常是某個知名藝術家的作品)整合在一起實現的。我們將會使用一個叫做neural-style的演算法來完成這個任務,它基於強大的深度網路來對圖片進行處理。
聽起來似乎很複雜,通過直接觀看我們新創作的圖片,就很容易認識到我們究竟在做什麼。看到這些圖片,也不枉我們花費上千小時來科研和寫程式碼啊:)。
這個演算法神祕的效果是通過複用一個預建立好的深度神經網路(VGG19)來實現的,這個網路是由牛津大學的研究人員和ImageNet Challenge 2014 image processing competition的獲勝者開發的。這個網路應用了多層卷積神經網路(CNNs),它能夠將一個圖片從原始畫素提煉成更高層次的、更概念化的表示。事實上,抽象層次之高足以將圖片的樣式原樣地表示出來。正是通過將原始畫素轉換成樣式的方式,系統才能以某個圖片的樣式來重畫另外一個圖片的畫素。
到目前為止,實現和部署這個演算法不是一個簡單的任務。我們將會在剩下的內容中解釋如何做到它,並且所要求執行的的命令不超過三個。不過在這之前,讓我們介紹些更細節的內容。除了VGG19,我們還需要:
- 一個畫板——torch 資料探勘庫,它能夠讓我們模擬一個畫家(基於Justin Johnson的工作)
- 以及一個加速我們製圖過程的方式,畢竟我們不想要花費幾天、幾個星期,甚至幾個月來等待結果。因此,我們將會使用圖形處理單元(GPU)加上一個傳統的CPU來加速我們的深度學習演算法,成功將等待的時間減低到幾分鐘。
問題
我們已經很接近目標了。但是我們還需要解決最後一個挑戰。工具、庫、演算法的創新、依賴和變化會使得執行環境被破壞。僅僅是大量的庫和依賴就給執行演算法帶來了許多問題:
- Nvidia GPU驅動,為了使用GPU
- CUDA開發套件,為了控制GPU
- Cudnn庫,為了使用GPU深度網路計算
- Torch7,一個深度網路開發的框架,以及它的依賴(protobuf)
- Loadcaffe lua 模組,為了載入預建立好的網路,這也是我們應用VGG19的方式。
為了獲得更加卓越的結果,我們需要用不同的圖片,樣式和引數來執行這個演算法,而以上的所有軟體是自動化這個過程的必需品。這帶來了一個非常脆弱的環境,因為只要有任何不可逆轉的更新被引入到GPU驅動或者torch庫中,整個系統就會停止工作。這意味著不僅僅第一次的環境搭建是繁重的,並且為了保持系統執行,我們還需要一次次地重複這個過程。這離我們的理想狀態非常遙遠:藝術家靈感出現時,畫布必須在手上。類似地,當我們創意迸發時,我們的工具必須能夠立馬執行,我們不能受制於一個永遠在變化的環境。
很明顯,Docker是解決這個問題的好辦法。但是,還有一個棘手的問題:Docker將我們的程序從環境分離,同時分離了宿主機上的特定硬體資源。不幸的是,我們的深度神經網路演算法需要對GPU的直接訪問。Docker是基礎方法,但是我們還需要其他的東西。
解決辦法是nvidia-docker,它對docker進行了封裝,允許容器利用NVIDIA GPU。通過這個命令,Docker會通過一個卷自動掛載宿主機上的GPU驅動到容器中,通過這個方式,任何Docker程序就能夠在宿主機的GPU上執行程式碼了。
有了Docker,現在,我們對宿主機的要求直線下降:我們只需要安裝Docker,nvidia-docker,以及正確的GPU驅動。剩下的依賴都包含在Docker映象中,這個映象通過Dockerfile建立,因此具有可重複建立的特性,同時這保證了所有不斷變化的依賴都被固定在某個能夠正確工作的版本上。
畫圖工具
現在我們所需要的僅僅是一個能夠執行我們系統的機器。我們使用了公有云,這裡選擇了AWS和它的GPU優化虛擬機器。AWS提供了兩個型別的GPU例項,但我們選擇了最新的P2 AWS EC2例項。這些例項是專門為了深度學習而設計的,和我們現在的專案很符合。讓我們開始構建它吧:
$ docker-machine create — driver amazonec2 \ -- amazonec2-instance-type p2.xlarge \ -- amazonec2-access-key *** \ -- amazonec2-secret-key *** nvidia-docker
在執行這個命令前,你需要:
- 安裝Docker on Mac,Docker on Windows,或者docker-machine。
- 建立AWS的賬戶。不幸的是,P2或G2例項不包含在AWS免費計劃中,但我們可以花費少於$10的金錢來創造大量的藝術品。如果你的電腦擁有一個NUIDA GPU,那麼你也能夠在本地執行我們的指令碼。
- 建立一個access/secret金鑰對
- 由於預設情況下你不允許使用P2和G2例項,因此你需要在AWS上開啟一個ticket來增加P2和G2例項的使用限制。完成這些只需要少於一小時的時間。
安裝NVIDIA驅動和nvidia-docker是第二個步驟。我們已經提供了一個簡單的指令碼來完成這些事情:
$ docker-machine ssh nvidia-docker $ git clone https://github.com/albarji/neural-style-docker $ cd neural-style-docker $ ./scripts/install-nvidia.sh
如果一切順利,你將會得到以下輸出結果:
上面命令僅僅是安裝了nvidia軟體包,並且輸出了GPU卡的資訊,以此確保一切正常。
畫畫之前,你必須閉上眼,輕聲吟唱……
畢加索如是說。但在閉上眼之前,我們還有最後一個步驟:部署我們的神奇演算法:
$ ./scripts/fake-it.sh goldengate.jpg vangogh.jpg
現在,你只需要下載產生的圖片,然後將它們釋出在藝術論壇,比如說Devianart,或者將它們展示在本地的藝術館中:) 從你的電腦執行以下命令:
$ docker-machine scp -r docker-nvidia:/home/ubuntu/neural-style-docker/output .
然後在當前的目錄下你就能看到新產生的圖片了(在這個例子中,圖片的名字是goldengate_by_vangogh.jpg)。
下面是更多的例子:
給我一個美術館……
我將能夠填滿它,畢加索如是說。現在,我們也能夠做到!並且不需要花費一生的時間。我們已經提供了一些風格和內容,因此你只需要坐下來,放輕鬆,閉上眼,然後輕聲吟唱。通過將不同的風格應用在同一幅畫上,我們將能夠清楚地看到不同的畫家是如何用不同的風格來繪製同一個場景或肖像的。
為了表達對Docker的感謝,為了我們生命中的點點滴滴,我們決定開放我們自己的Docker美術館:
Afremov imagining Docker
Docker was used in the Roman Empire, as this old mosaic proves
This alleyway depicts an urban graffiti of Docker
A modern dockerized city by Hundertwasser
A classic dockerized city by Renoir
Ancient greek pottery was distributed in containers
Picasso innovated a great deal using Docker
Van Gogh was impressed by Docker
Every math professor knows about the containerability theorem
Docker run potatoes
現在輪到你了。選擇你最喜歡的藝術家或者藝術作品,將你自己的圖片轉換成藝術品。請將你的成果分享給我們!並且關注我們的Twitter(@albarjip and @lherrerabenitez)。
PS:結束創作後,不要忘記停止和刪除你的P2例項。
$ docker-machine rm nvidia-docker
我們的藝術館:
- http://lherrerabenitez.deviantart.com/gallery/
- http://albarji.deviantart.com/gallery/60433505/neuralstyle
機器學習、資料探勘以及Docker的參考文獻
不瞭解機器學習、資料探勘和Docker的、並且想要了解它們的朋友,請點選下面的連結:
- https://arxiv.org/abs/1508.06576 —— A neural algorithm of style
- http://www.robots.ox.ac.uk/~vgg/publications/2015/Simonyan15/ ——Very Deep Convolutional Networks for Large-Scale Image Recognition (VGG19 network)
- https://github.com/jcjohnson/neural-style ——A torch implementation of the paper A Neural Algorithm of Artistic Style by Leon A. Gatys, Alexander S. Ecker, and Matthias Bethge.
- http://image-net.org/challenges/LSVRC/2014/ ——ImageNet 2014 Challenge
- https://www.coursera.org/learn/machine-learning —— Andrew Ng Machine Learning Course
- https://github.com/soumith/cvpr2015/blob/master/Deep%20Learning%20with%20Torch.ipynb ——Deep Learning with Torch
- https://github.com/docker/labs ——Docker Tutorials
- https://github.com/NVIDIA/nvidia-docker—— NVIDIA Docker
構建和優化Docker映象
我們想要優化和減少映象的體積。你能夠幫助我們嗎?
- 下載專案:
$ git clone https://github.com/albarji/neural-style-docker
- 修改專案檔案
- 構建新的映象:
$ sudo nvidia-docker build -t neural-style:2.0 .
- 執行測試程式碼:
$ sudo nvidia-docker run — rm -v $(pwd):/images — entrypoint python neural-style /neural-style/variants.py — contents img/docker.png — styles img/starryNight.jpg — outfolder 文章出處:Docker(訂閱號ID:dockerone)