在Docker中部署使用Tensorflow && Docker基本用法介紹

最初聽說Docker這樣一個虛擬化工具是在幾年前上大三的時候, 當時我對這玩意是拒絕的. 你說我一個搞機器人的工程師, 怎麼就用上了這些web後端開發者的工具了呢. 最近實驗室要進新伺服器, 外加我有在AWS雲上部署tensorflow計算的需求, 就嘗試著用了一下Docker. 用Docker這個工具主要有以下幾點好:

  1. Docker相對虛擬機, 是一個比較輕量化的虛擬化平台. 個人感覺Docker利用系統資源的能力比虛擬機要好一點.
  2. Docker對各大雲計算平台的相性比較好, 其image形式能夠比較便利的部署在主流雲平台上(例如AWS, 阿里雲). Docker的鏡像也可以比較簡單的遷移到其他平台上.
  3. 在Windows下使用Docker進行虛擬化意味著我依然能用Windows下的一系列工具進行開發 (儘管這年頭用Windows做開發會給人一種弱者的氣息) . 並且在鏡像中可以重用Linux的一套工具鏈, 例如ROS, PCL之類的. 在這一方面, CygWin與MinGW還是要再學習一個.
  4. 省去了切虛擬機, 切雙系統的煩惱. 事實上docker鏡像完全可以不安裝桌面, 只在後台負責計算任務. 也可以一邊用LaTeX寫論文, 一邊訓練神經網路, 同時用Pycharm遠程ssh上去Debug. 其間用迅雷下載"數據集", 用網易雲音樂聽歌.
  5. 可以隨時隨地來一局守望先鋒(並不能, 顯卡被占著呢).

不過, Docker在以下方面還是要再提高一個:

  1. 在Docker的鏡像上跑神經網路的效率是要比原生系統來的慢的. 以跑VGG16, DeepLab為例, 大概能發揮到70%到80%吧. 所以一般只拿它做原型開發, 或者是部署到伺服器上.
  2. 關機之前千萬別忘了commit, 血的教訓. Commit到Github上和鏡像的commit都要做, 這是程序員的好習慣.
  3. 遠程調試還是不如在本地調試來的爽, 不過差別不大.

介紹下Docker上部署並使用tensorflow, keras的基本操作, 本機環境win10, docker鏡像是ubuntu16.04LTS:

(1): 上官網下exe安裝包安裝Docker. 注意Docker在Win10下的運行需要開啟Hyper-V服務, 如何開啟自行百度. 要使用顯卡的話, 首先要安裝Cuda和cudnn, 然後安裝nvidia-docker.

(2): 安裝並打開Setting, 手工指定一個地方存放Docker所下載, 維護的鏡像文件. 這些文件比較大, 不建議放在系統盤中. 此外, 設置一下分配給鏡像系統的CPU, 內存大小.

(3) 在windows的命令行中使用 docker pull 命令下載Tensorflow官方的Docker鏡像, 命令如下:

> docker pull tensorflow/tensorflown

(4) 用docker images命令能看到本機所有的docker鏡像.

(5) 運行該鏡像, 命令如下:

> docker run -it -p 8888:8888 tensorflow/tensorflown

該命令的一系列參數意義如下所示:

  1. -it: 讓docker使用互動式輸出, 即通過傳統的終端模式與docker鏡像進行交互. (然而這裡並不能夠這麼做, 終端被Jupyter Notebook的輸出阻塞了, 如何開啟終端見Q&A)
  2. -p 8888:8888 指定docker與主機通信的埠範圍, 如果因為埠被佔用原因不能開啟虛擬機, 就換一個吧.
  3. tensorflow/tensorflow: 虛擬機名稱

(6) 該命令運行後效果應如下圖所示, 複製最下面一行的URL, 用瀏覽器打開. 就能在Jupyter Notebook中以半互動式的方式運行Python, 並訓練神經網路:

(7) 工作完成以後不要忘記commit保存鏡像的狀態, 直接ctrl-C會導致之前的工作結果丟失! 保存方法見Q&A.


Q&A:

(1): Q: 如何開啟終端? 如何使用多個終端?

A: 有兩種方法開啟終端. 方法1: 在Jupyter Notebook 的新建中, 選擇terminal, 就能夠在瀏覽器中打開一個終端. 方法2: 使用docker exec命令. 該方法首先要在一個新命令行中使用 docker ps 命令獲取當前docker中運行的所有終端的ID. 該命令執行結果如圖所示:

上圖中我們開啟了一個名為 my_tf_env 的鏡像(是由原生tensorflow修改而來的, 也有可能名為tensorflow/tenosrflow). NAMES所對應的一串sha碼就是該容器的ID. 實際使用容器ID的時候不用全輸進去, 輸前2-3個字母就能唯一確定一個容器了(和Git很像吧).

然後使用docker exec命令:

> docker exec -it <container_ID> bash n

這樣就能在該命令行中連接docker的終端.

(2) Q: 如何保存鏡像中的工作? 我關閉了鏡像, 再打開的時候之前所做的工作就全丟了.

A: 用docker commit命令可以保存鏡像的狀態. 用法如下:

首先用docker ps 命令獲取當前容器的ID, 然後執行以下命令:

> docker commit -m="<info>" <container_ID> <container_name>n

該命令的一系列參數意義如下所示:

  1. commit -m="<info>" 用一段簡短的話壽命這次提交時對系統所做的改動. 這個參數不是必須的, 但是一旦鏡像被玩崩了, 通過這些描述可以有效確定要回滾鏡像的時間節點. 另外, 經常寫總結是好習慣. 對Git用戶尤其要注意-m參數是有等號的.
  2. <container_ID> : 容器的ID, sha碼, 寫前幾個字元就可以
  3. <container_name> 容器要保存的名稱, 該名稱可以與原來容器名稱一樣, 這會覆蓋當前的容器. 也可以與原來的容器名稱不一樣, 就相當於創建了一個額外的分支. 常用Git的同學應該對這樣的操作很熟悉了.

最後, 用docker images 命令檢查鏡像是否被保存了. 在我的機器上該命令執行結果如圖所示:

圖上 my_tf_env 這個鏡像就是我5秒前保存的鏡像, 而tensorflow/tensorflow這個鏡像是原本從 docker hub 上pull下來的鏡像(沒有改變). 我將對這個鏡像的改動保存為一個新的鏡像my_tf_env, 這樣玩一玩壞了這個鏡像, 還就不用重新下載1個多G的鏡像文件了. 另外, 當我在使用my_tf_env這個鏡像時, 我也可以commit我對改鏡像所做的更改為my_tf_env, 這就覆蓋了我當前鏡像的版本.


推薦閱讀:

YJango的TensorFlow整體把握
深度神經網路學習筆記
M.1.2 神經網路的數學基礎-度量、運動、變換和群
S 1.1 機器學習-樸素貝葉斯與單層神經網路關係

TAG:Docker | 深度学习DeepLearning | TensorFlow |