1

問題:如何加速比CAFFE用於在測試圖像滑動窗口對象檢測

我已經訓練的卷積神經網絡(CNN),以確定/檢測是否感興趣的對象存在或不存在於給定的圖像補丁。

現在給出一個大的圖像,我試圖通過將CNN模型應用到圍繞圖像中每個像素的補丁來以滑動窗口方式查找圖像中所有對象的出現位置。然而這很慢。

我的測試圖像的大小是(512 x 512)。而且,對於我的咖啡網,測試批量大小爲1024,補丁大小爲(65 x 65 x 1)。

我試圖在一批補丁(size = test_batch_size)上應用我的咖啡網,而不是一次一個補丁。即使這樣也很慢。

以下是我當前的解決方案,它非常慢。除了對我的測試圖像進​​行下采樣以加快速度之外,我會很感激任何其他建議。

目前的解決方案,這是非常緩慢:

def detectObjects(net, input_file, output_file): 

    # read input image 
    inputImage = plt.imread(input_file) 

    # get test_batch_size and patch_size used for cnn net 
    test_batch_size = net.blobs['data'].data.shape[0] 
    patch_size = net.blobs['data'].data.shape[2] 

    # collect all patches  
    w = np.int(patch_size/2) 

    num_patches = (inputImage.shape[0] - patch_size) * \ 
        (inputImage.shape[1] - patch_size) 

    patches = np.zeros((patch_size, patch_size, num_patches)) 
    patch_indices = np.zeros((num_patches, 2), dtype='int64') 

    count = 0 

    for i in range(w + 1, inputImage.shape[0] - w): 
     for j in range(w + 1, inputImage.shape[1] - w): 

      # store patch center index 
      patch_indices[count, :] = [i, j] 

      # store patch 
      patches[:, :, count] = \ 
       inputImage[(i - w):(i + w + 1), (j - w):(j + w + 1)] 

      count += 1 

    print "Extracted %s patches" % num_patches 

    # Classify patches using cnn and write result to output image 
    outputImage = np.zeros_like(inputImage) 
    outputImageFlat = np.ravel(outputImage) 

    pad_w = test_batch_size - num_patches % test_batch_size 
    patches = np.pad(patches, ((0, 0), (0, 0), (0, pad_w)), 
        'constant') 
    patch_indices = np.pad(patch_indices, ((0, pad_w), (0, 0)), 
          'constant') 

    start_time = time.time() 

    for i in range(0, num_patches, test_batch_size): 

     # get current batch of patches 
     cur_pind = patch_indices[i:i + test_batch_size, :] 

     cur_patches = patches[:, :, i:i + test_batch_size] 
     cur_patches = np.expand_dims(cur_patches, 0) 
     cur_patches = np.rollaxis(cur_patches, 3) 

     # apply cnn on current batch of images 
     net.blobs['data'].data[...] = cur_patches 

     output = net.forward() 

     prob_obj = output['prob'][:, 1] 

     if i + test_batch_size > num_patches: 

      # remove padded part 
      num_valid = num_patches - i 
      prob_obj = prob_obj[0:num_valid] 
      cur_pind = cur_pind[0:num_valid, :] 

     # set output 
     cur_pind_lin = np.ravel_multi_index((cur_pind[:, 0], 
              cur_pind[:, 1]), 
              outputImage.shape) 

     outputImageFlat[cur_pind_lin] = prob_obj 

    end_time = time.time() 
    print 'Took %s seconds' % (end_time - start_time) 

    # Save output 
    skimage.io.imsave(output_file, outputImage * 255.0) 

我希望與線

net.blobs['data'].data[...] = cur_patches 
    output = net.forward() 

朱古力將所有的補丁進行分類cur_patches使用並行GPU。不知道爲什麼它仍然很慢。

+0

你使用什麼網絡?將其轉換爲卷積網。 – Shai

+0

@Shai我正在使用CNN。我解決了這個問題。我使用的是net_test.prototxt而不是net_deploy.prototxt,這導致了一些奇怪的行爲。我以部署模式調整了批量大小,批量大小爲1000,我可以在9秒內對512 x 512圖像中的所有修補程序(〜200000)進行密集分類,現在我很滿意。非常感謝您爲net_deploy.prototxt的生成提供的幫助。 – cdeepakroy

回答

1

我認爲你在找什麼在Casting a Classifier into a Fully Convolutional Network of the "net surgery" tutorial部分有描述。
什麼此溶液基本上說是,代替CONV層後跟"InnerProduct"層分類,所述"InnerProduct"層可以轉化成一個等效 CONV層,具有充分卷積網可以處理任意大小的圖像所得並根據輸入尺寸輸出預測。移動到完全卷積體系結構將顯着減少您當前進行的重複計算的次數,並且應該顯着加快您的過程。


用於加速的另一種可能的方向是近似高維"InnerProduct"層由兩個較低秩矩陣的使用truncated SVD trick的產物。