2016-03-02 69 views
2

如何分類的圖像我使用來自Caffe做圖像分類,可我使用的MAC OS X,Pyhton。使用Spark和來自Caffe

現在我知道如何使用來自Caffe星火蟒蛇的圖像列表進行分類,但如果我想讓它快,我想使用的火花。

因此,我試圖施加RDD,從IMAGE_PATH的列表中創建的RDD的每個元件上的圖像的分類。但是,Spark不允許我這樣做。

這是我的代碼:

這是用於圖像分類的代碼:這此代碼生成來自Caffe參數並應用classify_image方法的RDD中的每個元素

# display image name, class number, predicted label 
def classify_image(image_path, transformer, net): 
    image = caffe.io.load_image(image_path) 
    transformed_image = transformer.preprocess('data', image) 
    net.blobs['data'].data[...] = transformed_image 
    output = net.forward() 
    output_prob = output['prob'][0] 
    pred = output_prob.argmax() 

    labels_file = caffe_root + 'data/ilsvrc12/synset_words.txt' 
    labels = np.loadtxt(labels_file, str, delimiter='\t') 
    lb = labels[pred] 

    image_name = image_path.split(images_folder_path)[1] 

    result_str = 'image: '+image_name+' prediction: '+str(pred)+' label: '+lb 
    return result_str 

def main(): 
    sys.path.insert(0, caffe_root + 'python') 
    caffe.set_mode_cpu() 
    model_def = caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt' 
    model_weights = caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel' 

    net = caffe.Net(model_def, 
       model_weights, 
       caffe.TEST) 

    mu = np.load(caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy') 
    mu = mu.mean(1).mean(1) 

    transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) 

    transformer.set_transpose('data', (2,0,1)) 
    transformer.set_mean('data', mu) 
    transformer.set_raw_scale('data', 255) 
    transformer.set_channel_swap('data', (2,1,0)) 

    net.blobs['data'].reshape(50, 
          3, 
          227, 227) 

    image_list= [] 
    for image_path in glob.glob(images_folder_path+'*.jpg'): 
     image_list.append(image_path) 

    images_rdd = sc.parallelize(image_list) 
    transformer_bc = sc.broadcast(transformer) 
    net_bc = sc.broadcast(net) 
    image_predictions = images_rdd.map(lambda image_path: classify_image(image_path, transformer_bc, net_bc)) 
    print image_predictions 

if __name__ == '__main__': 
    main() 

正如你所看到的,在這裏我嘗試播放咖啡參數transformer_bc = sc.broadcast(transformer)net_bc = sc.broadcast(net) 錯誤是:

RuntimeError: Pickling of "caffe._caffe.Net" instances is not enabled

之前我做廣播,錯誤是:

Driver stacktrace.... Caused by: org.apache.spark.api.python.PythonException: Traceback (most recent call last):....

所以,你知道,有沒有什麼辦法可以分類使用來自Caffe和星火圖像,而且還利用Spark?

回答

1

當您使用複雜的,非本地對象初始化工作有直接搬到了工人例如用單模塊:

net_builder.py

import cafe 

net = None 

def build_net(*args, **kwargs): 
    ... # Initialize net here 
    return net  

def get_net(*args, **kwargs): 
    global net 
    if net is None: 
     net = build_net(*args, **kwargs) 
    return net 

main.py

import net_builder 

sc.addPyFile("net_builder.py") 

def classify_image(image_path, transformer, *args, **kwargs): 
    net = net_builder.get_net(*args, **kwargs) 

這意味着你必須分發所有必需的文件。它可以通過手動或using SparkFiles機制完成。

在一個側面說明,你應該看一看的SparkNet包。