Caffe Python介面多程序提取特徵
原文地址:http://yongyuan.name/blog/caffe-python-extract-feature-parallel.html
https://thief.one/2016/11/24/Multiprocessing-Pool/
https://jingsam.github.io/2015/12/31/multiprocessing.html
想象這樣一個場景:伺服器上配備了很多GPU顯示卡,而你又使用的是Caffe,不幸的是,你還選用了Python來寫程式碼,不幸中的不幸是你還要在短時間內處理百萬千萬規模的圖片。那麼,問題來了,Caffe本身對多卡的支援就不是很好,而你還要用Python,而且即便你通過設定batch size的大小來加快處理速度,但你還是隻把一張顯示卡用起來。有沒有辦法把所有的GPU都用起來,並行提取特徵呢?
上面這個問題在實際中是一個經常會碰到並且繞不過的問題,小白菜在近期也遇到了此問題,並且上面那些設定的條件小白菜不幸都一一躺槍。雖然如此,問題還是要解決的。下面小白菜聊聊如何使用python 的multiprocessing多程序並行庫來把伺服器上的多張GPU都用起來,進行特徵的並行提取。在正式給出具體的解決方案之前,還是有必要了解multiprocessing多程序並行庫的。
multiprocessing多程序並行庫
multiprocessing對於程序的管理,是使用程序池pool進行管理的。pool允許使用者指定程序數目,線上程池未滿的時候,如果新的請求提交過來,則pool會建立新的程序來執行該請求,如果池中的程序數已經達到規定最大值,那麼該請求就會等待,直到池中有程序結束,才會建立新的程序來執行它。pool對於程序的管理,有兩種方式,分別是非同步方式(也稱非阻塞方式)和同步方式(也稱阻塞方式),對應的方法為apply_async()和apply()。
apply()
: 同步方式(也稱阻塞方式)。阻塞,顧名思義,在執行該任務的時候,把所有的介面資源都堵住了,其他的任務必須等待這個任務執行完後,再釋放資源後,才能執行其他的任務,所以非常的好理解。pool.apply_async()
: 非同步方式(也稱非阻塞方式)。有了上面阻塞的解讀,小白菜以為非同步方式已經非常直白了。
程序池管理pool還有一些其他的方法,這裡不再做詳細的展開了,更多關於Python的multiprocessing的解讀,可以參考Multiprocessing.Pool和正確使用 Multiprocessing 的姿勢,寫得直白易懂。
有了上面對Python的multiprocessing的認識,我們再回到使用python的multiprocessing多程序並行庫來把伺服器上的多張GPU都用起來這個問題上。根據對pool對程序池管理的方法,顯然pool.apply_async()
並行化方案
問題定義:假設需要處理的圖片有800萬,伺服器上有8塊GPU,如何使用python 的multiprocessing多程序並行庫來把伺服器上的多張GPU都用起來,進行特徵的並行提取。
對於上述給出的問題定義,小白菜設計的並行化方案為:將800萬分成8等分,啟動8個程序,每個程序使用一塊GPU,並且每一個程序載入一份預訓練的模型,這樣就可以把8塊GPU都用起來了。此種方案,可以最大限度的使用GPU,有多少塊GPU,就可以用多少GPU,下面是具體的編碼。
具體編碼
有了上面對multiprocessing和並行化方案後,在具體編碼的時候,要做的事情其實非常簡單,主要需要完成的就是兩件事:
- 把圖片資料按GPU的數目進行等量劃分,即寫一個
split_list()
函式 - 正常編寫特徵提取程式碼,寫一個
gpu_task
函式
具體程式碼如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: [email protected]
import multiprocessing
from multiprocessing import Process, freeze_support, Pool
import sys
import os
import caffe
import numpy as np
import scipy
import h5py
def split_list(alist, wanted_parts=1):
length = len(alist)
return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts]
for i in range(wanted_parts) ]
def gpu_task(prototxt, caffemodel, layer, path_images, out, gpu=0):
num_images = len(path_images)
h5f = h5py.File(out, 'w')
# set gpu card
caffe.set_device(gpu)
caffe.set_mode_gpu()
# init NN
net = caffe.Net(prototxt, caffemodel, caffe.TEST)
net.forward()
features = []
image_names = []
for i, path in enumerate(path_images):
print "%d(%d), %s"%((i+1), num_images, os.path.basename(path))
if os.path.splitext(os.path.basename(path))[0][-6:] != 'single':
img = ...
# extract feature
feat = ...
features.append(feat)
image_names.append(os.path.basename(path))
features = np.array(features)
h5f['feats'] = features
h5f['names'] = image_names
h5f.close()
print "gpu %d task has finished..." % (gpu)
if __name__ == '__main__':
multiprocessing.freeze_support()
pool = multiprocessing.Pool()
dir_images = '....'
path_images = [os.path.join(dir_images, f) for f in sorted(os.listdir(dir_images)) if f.endswith('.jpg')]
layer = '...'
prototxt = 'VGG_ILSVRC_16.prototxt'
caffemodel = 'VGG_ILSVRC_16_layers.caffemodel'
out = '...'
parts = 8 # 8個程序
out_files = []
for i in xrange(parts):
out_files.append(os.path.join(out, str(i) + '.h5'))
blocks = split_list(path_images, wanted_parts = parts)
for i in xrange(0, parts):
pool.apply_async(gpu_task, args = (prototxt, caffemodel, layer, blocks[i], out_files[i], i + (8 - parts),))
pool.close()
pool.join()
上面那些...
的部分,是小白菜刻意省略的,具體在實際使用的時候,可以結合自己的需要來做更改。另外一個pool.close()
和pool.join()
的次序一定不能反,否則會出錯。執行完close後不會有新的程序加入到pool,join函式等待所有子程序結束。
對於特徵的儲存,可以採用hdf5的格式進行儲存,上面每一個程序提取的特徵,儲存在一個h5(HDF5格式)檔案中,這樣對於八個程序,可以得到8份小檔案,每一份檔案裡存了影象檔名及其對應的特徵。
相關推薦
Caffe Python介面多程序提取特徵
原文地址:http://yongyuan.name/blog/caffe-python-extract-feature-parallel.html https://thief.one/2016/11/24/Multiprocessing-Pool/ https://jing
Python學習多程序併發寫入同一檔案
最近學習了Python的多程序,想到我的高德API爬蟲那個爬取讀寫速度我就心累,實在是慢,看到多程序可以充分利用CPU核數我就開始完善我的程式碼,不過過程是艱辛的,在此之中出現了很多問題,其中最大的問題是爬取的資料是正確的,但是讀寫到Excel中卻開啟是空,想了半天也沒解決,腦子笨沒辦法,不過我
python mutilprocessing多程序程式設計
`為了更好的理解本文內容,請務必先了解Synchronization、Asynchronization、Concurrent、Mutex等基本概念 multiprocessing是一個類似於Threading模組的由API產生程序的包,關於Threading模組可以參
python之多程序模組multiprocessing
程序: python裡程序是multiprocessing模組 用法和多執行緒沒有什麼區別(os.getpid()是獲得程序號,ppid是父程序號) import time ,os import multiprocessing def f(name): time.sleep(
程序與執行緒(2)- python實現多程序
python 實現多程序 參考連結: https://morvanzhou.github.io/tutorials/python-basic/multiprocessing/ python中實現多程序的模組:multiprocessing 注意:在windows系統下
python的多程序應用--讀取儲存圖片
例一 使用Pool.map函式實現多程序,稍微有點low,可用範圍較窄。 #coding=utf-8 from multiprocessing import Pool import scipy from scipy import misc import os impor
python使用多程序
python多執行緒適合IO密集型場景,而在CPU密集型場景,並不能充分利用多核CPU,而協程本質基於執行緒,同樣不能充分發揮多核的優勢。 針對計算密集型場景需要使用多程序,python的multiprocessing與threading模組非常相似,支援用程序池的方式批量建立子程序。 建立單個Proce
Python 之 多程序 multiprocessing.Pool 類
multiprocessing包是Python中的多程序管理包。它與 threading.Thread類似,可以利用multiprocessing.Process物件來建立一個程序。該程序可以允許放在Python程式內部編寫的函式中。該Process物件與Thread物件的用
Python multiprocessing 多程序鎖 程序間傳遞Lock 遇到的問題
無法傳遞 Lock物件 from multiprocessing import Pool,Lock def text(i,lock): print(i) lock.acquire() DOSOMETHING lock.release() if __na
多執行緒與多程序及Python實現【Python實現多程序】
上一篇部落格介紹了多執行緒與多程序的理論部分,這篇部落格將參考部落格以及各種教程完成Python多程序實現部分。 multiprocessing模組 Process 類 multiprocessing.Process(group=None, target=N
Caffe Python 介面 API
Caffe 有 Python 和 Matlab 介面,都可以用於直接呼叫底層的 Caffe 函式(C++ 實現)。而且 Python 介面可以用於編寫指令碼,生成自定義的 prototxt 檔案,即網路結構定義檔案。 一些大型網路比較深,而且結構複雜,比如 Re
keras tensorflow 在python下多程序執行
from multiprocessing import Process import os def training_function(...): import keras # 此處需要在子程序中 ... if __name__ == '__mai
Caffe-Python介面常用API參考
1、io.py原始碼解讀 主要是定義了一個transformer,preprocess和deprocess操作,完成caffe和python之間資料的格式轉換等, 注意caffe: BGR,0-255,C*H*W,而python是RGB, 0-1,H*W*C的資料格式,所以
python中多程序(multiprocessing)
python中多程序(multiprocessing) 一、multiprocessing中使用子程序概念 from multiprocessing import Process 可以通過Process來構造一個子程序 p = Process(target=fun,args=(arg
ubuntu14.04安裝caffe+python介面
1 ubuntu系統安裝 2 caffe環境安裝 General dependencies sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobu
python爬蟲——多程序multiprocessing
其實多程序相對來說不是特別適合用來做爬蟲,因為多程序比較適用於計算密集型,而爬蟲是IO密集型,因此多程序爬蟲對速度的提升不是特別明顯,但是將爬蟲改為多程序比較簡單,只需簡單的幾行程式碼即可搞定,所以在修改我的爬蟲提升效率時,我最先實現的是多程序爬蟲。(然而速度真
Python中多程序的使用 Python的多執行緒(threading)與多程序(multiprocessing )示例程式碼 Python多程序程式設計
程序:程式的一次執行(程式載入記憶體,系統分配資源執行)。每個程序有自己的記憶體空間,資料棧等,程序之間可以進行通訊,但是不能共享資訊。 執行緒:所有的執行緒執行在同一個程序中,共享相同的執行環境。每個獨立的執行緒有一個程式入口,順序執行序列和程式的出口。 執行緒的執行可以被強佔,中斷或者暫時被
python爬蟲入門八:多程序/多執行緒 python佇列Queue Python多執行緒(2)——執行緒同步機制 python學習筆記——多程序中共享記憶體Value & Array python 之 多程序 Python多程序 Python 使用multiprocessing 特別耗記
什麼是多執行緒/多程序 引用蟲師的解釋: 計算機程式只不過是磁碟中可執行的,二進位制(或其它型別)的資料。它們只有在被讀取到記憶體中,被作業系統呼叫的時候才開始它們的生命期。 程序(有時被稱為重量級程序)是程式的一次執行。每個程序都有自己的地址空間,記憶體,資料棧以及其它記錄其執行軌跡的輔助資料
caffe python介面訓練VGG
# -*- coding: utf-8 -*- """ @author: root """ #matplotlib是python最著名的繪相簿 import matplotlib.pyplot as plt import caffe #import cv2 from num
python-->多程序
pythn 多程序 python中的多執行緒無法利用多核優勢,若想要充分地使用多核CPU的資源(os.cpu_count()檢視),在python中大部分情況需要使用多程序。Python提供了multiprocessing模組用來開啟子程序,並在子程序中執行我們定製的任務(比如函式),該模組與多執行緒模組t