1

für Schiebe Frage:Wie caffe zur Beschleunigung Fensterobjekterkennung in einem Testbild

I ein Faltungs neuronales Netz trainiert habe (CNN), um zu bestimmen/erfassen, ob ein interessierendes Objekt vorhanden ist oder nicht in einem gegebenen Bildkorrektur.

Nun gebe ich ein großes Bild, ich versuche, alle Vorkommen des Objekts in dem Bild in einem gleitenden Fenster zu finden, indem ich mein CNN-Modell auf den Patch um jedes Pixel im Bild anwenden. Dies ist jedoch sehr langsam.

Die Größe meiner Testbilder ist (512 x 512). Und für mein Kaffeenetz ist die Testgröße 1024 und die Größe des Patches (65 x 65 x 1).

Ich habe versucht, meine Caffe net auf einen Stapel von Patches (size = test_batch_size) anstelle von einem einzigen Patch auf einmal anwenden. Auch dann ist es langsam.

Unten ist meine aktuelle Lösung, die sehr langsam ist. Ich würde mich über alle anderen Vorschläge freuen, anstatt mein Testbild herunterzusampeln, um dies zu beschleunigen.

Aktuelle Lösung, die sehr langsam ist:

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) 

Ich hatte gehofft, dass mit den Linien

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

caffe alle Patches in cur_patches parallel mit GPU einstufen würde. Ich frage mich, warum es immer noch langsam ist.

+0

Welches Netz verwenden Sie? wandeln Sie es in ein Faltungsnetz um. – Shai

+0

@Shai Ich benutze ein CNN. Ich habe das Problem herausgefunden. Ich habe net_test.prototxt anstelle von net_deploy.prototxt verwendet, was zu etwas unkonventionellem Verhalten geführt hat. Ich habe die Stapelgröße im Bereitstellungsmodus eingestellt, und mit einer Stapelgröße von 1000 kann ich eine dichte Klassifizierung aller Patches (~ 200000) in einem 512 x 512 Bild in 9 Sekunden vornehmen, womit ich jetzt zufrieden bin. Vielen Dank für Ihre Hilfe bei der Erstellung von net_deploy.prototxt. – cdeepakroy

Antwort

1

Ich denke, was Sie suchen, wird in Abschnitt Casting a Classifier into a Fully Convolutional Network of the "net surgery" tutorial beschrieben.
Was im Grunde diese Lösung so ist, dass anstelle conv Schichten durch eine "InnerProduct" Schicht zur Klassifizierung folgte, kann die "InnerProduct" Schicht in eine Schicht äquivalente conv transformiert werden, mit einem vollständig Faltungs net führt, die Bilder jeder Größe verarbeiten kann, und gibt eine Vorhersage gemäß der Eingabegröße aus.
Der Wechsel zu einer vollständig konvolutionellen Architektur wird die Anzahl der Redun- dent-Berechnungen, die Sie derzeit durchführen, erheblich reduzieren und Ihren Prozess erheblich beschleunigen.


Eine weitere mögliche Richtung für die Beschleunigung ist approximate hochdimensionalen "InnerProduct" Schichten durch ein Produkt aus zwei niedrigeren Rangs Matrizen truncated SVD trick.

Verwandte Themen