1. 程式人生 > >Keras入門(3)——磨刀不誤砍柴工

Keras入門(3)——磨刀不誤砍柴工

1. 前言

今天我們就正式進行Keras實驗。在早些時候,我們只是在PC上進行一些小實驗,能夠讓我們對於Keras有一定的直觀的認識。下面才是我們進入到最真實的開發環境。

2. 磨刀

2.1 硬體設施

當然真正的實驗不能夠在我們個人電腦上運行了。因此我們需要一個功能強大的遠端伺服器。以個人為例,我們假設目前已經擁有了一個2路的E5-2680V4和4路Tesla K40的Linux的伺服器。
E5-2680V4處理器具有14核心,價格在18000左右,而Tesla K40 具有12GB的視訊記憶體,價格在27000左右,2013年釋出時,號稱是地球上最強顯示卡,當然目前來看,仍然也處於頂尖水平。

顯示卡型號 單精度效能 雙精度效能
Tesla P100 10.6 5.3
QUADRO GP100 10.3 5.2
Tesla K80 8.74 2.91
Tesla K40 4.29 1.43
GTX 1080 8.7 0.2
GTX Titan x 7 0.2
GTX 980 4.6 0.15

2.2 軟體設施

2.2.1Linux登入

當然遠端連線少不了遠端工具,如果是Linux遠端的話,會容易很多,從命令列進入即可。例如:

  1. 遠端管理指定 Linux 伺服器
ssh 使用者名稱@ip

首次連線伺服器時,會提示下載伺服器的公鑰(通常使用 RSA 加密方式建立 SSH 金鑰,所以提示資訊一般是“RSA key…”),需要輸入 yes 確認。然後輸入使用者名稱對應的密碼,就可以登入伺服器了。要斷開與伺服器的連線,輸入 exit。

  1. 下載檔案
scp [-r] 使用者名稱@ip:檔案路徑 本地路徑
  1. 上傳檔案
scp [-r] 本地檔案 使用者名稱@ip:上傳路徑

2.2.2Windows登入

Windows雖然日常用起來很方便,但是如果是開發的話,還是比較麻煩的,因此我們需要兩個工具,分別是XshellWinscp。其中Xshell主要負責遠端命令列,而Winscp則負責傳輸檔案。具體配置我們這裡就不多講,比較傻瓜,只需要知道使用者名稱和密碼,就可以很方便的使用。

2.3 觀察環境

一般來講,一個伺服器環境至少需要以下幾個部分:python+Anaconda+Tensorflow+Keras。整體來講我們都介紹過,我們這裡主要提一下Tensorflow的編譯問題,具體的可以參考:《編譯Tensorflow》、《原始碼安裝Tensorflow》等。我們這裡不多講,我們這裡講一講如何檢視我們所使用的GPU和CPU資源。因為如果你對自己的所有效能都不瞭解的話,怎麼能夠充分發揮自己的效能呢。

2.3.1 GPU檢視

對於GPU來講,一般我們使用英偉達顯示卡,就如同上面我說的一樣,一般GTX1070起跳,好的話可以配置Tesla系列。那麼檢視英偉達系列顯示卡的使用情況的程式碼如下,在命令列中敲入以下命令:

nvidia-smi

沒錯,就是這麼簡單,回車後,應該看到類似的樣子:
這裡寫圖片描述
當然如果沒有看到這樣的話,一個可能原因就是你的伺服器裡沒有英偉達系列顯示卡。

2.3.2 CPU檢視

如果是檢視CPU的話,建議使用以下命令:

top

這個命令是用來檢視當前程序的,可以看到有哪個使用者的哪個程序在活動以及它的CPU使用情況。

lscpu

這個程式碼則是大致的展示以下CPU的概況。
這裡寫圖片描述

3. 小試牛刀

下面我們隨意使用一個程式來測試一下就像我們本機一樣就可以了。但是,我們這裡有4塊K40顯示卡,編號為0的顯示卡已經被佔用了。如果原封不動使用以下命令來執行:

python mnist.py

顯然,它會預設佔用編號為0的顯示卡。這和我們的想法不一致。我們想指定使用某一張顯示卡怎麼辦?

CUDA_VISIBLE_DEVICES=1 python train.py

或者是在檔案的程式碼里加入以下程式碼:

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "1"

這行程式碼就是指定編號為1的GPU來執行。由於太過興奮,我們衝昏了頭腦,以為可以使用以下程式碼來實現多個GPU執行:

CUDA_VISIBLE_DEVICES=1,2,3 python train.py

是的,沒錯,我們看到了在GPU上確實開了3個程序,但是我們發現只有1塊GPU上使用了加速,也就是Volatile GPU-Util的使用率只有1號顯示卡在執行,其他顯示卡的Volatile GPU-Util均為0。

後來我們冷靜了下來才發現,CUDA_VISIBLE_DEVICES其實指的是CUDA加速庫可見的裝置。也就是說,這其實是遮蔽某些編號的CPU的程式碼,而並非是並行程式碼。

同樣的,我們發現在原來的伺服器上,仍然有一個和我們有類似情況的程序,那麼他是不是也是這種情況呢?

沒錯,這種情況其實是偶然發生的,如果是全部都佔滿視訊記憶體,其實是由於TF的機制所致,它預設是佔用全部的視訊記憶體,而並非用多少拿多少。那麼這個該如何改變呢?
方法1,限制程式的視訊記憶體佔有量。我們可以使用以下程式碼:

import os
import tensorflow as tf
os.environ["CUDA_VISIBLE_DEVICES"] = "2"
from keras.backend.tensorflow_backend import set_session
config = tf.ConfigProto()
#限制最多GPU佔用為30%
config.gpu_options.per_process_gpu_memory_fraction = 0.3
set_session(tf.Session(config=config))

但是,其實當我們的程式真的需要比30%記憶體多的時候,還是會突破這個限制的。
方法2,使用增長型記憶體使用模式。

config = tf.ConfigProto()  
config.gpu_options.allow_growth=True  
sess = tf.Session(config=config)  

只需要在檔案中加入以上程式碼,就可以根據需求來呼叫視訊記憶體了。