1

질문 : 내가 결정하는 길쌈 신경 네트워크 (CNN)을 훈련 한테스트 이미지 창 물체 감지 슬라이딩 CAFFE 속도를 높이는 방법

/관심의 대상이 주어진 존재인지 아닌지 감지 이미지 패치.

큰 이미지가 주어지면 이미지의 각 픽셀을 둘러싼 패치에 내 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() 

CAFFE 병렬 사용하여 GPU에 cur_patches의 모든 패치를 분류 할 것이라고 기대했다. 왜 아직도 느린지 궁금합니다.

+0

너 네트는 무엇을 사용합니까? 길쌈 그물로 개조하십시오. – Shai

+0

@Shai CNN을 사용하고 있습니다. 나는 그 문제를 알아 냈다. net_deploy.prototxt 대신 net_test.prototxt를 사용하여 펑키 한 행동을 유도했습니다. 배포 모드에서 배치 크기를 조정하고 배치 크기가 1000 인 경우 512 x 512 이미지의 모든 패치 (~ 200000)를 9 초 동안 고밀도로 분류 할 수 있습니다. 현재 만족합니다. net_deploy.prototxt 생성에 도움을 주셔서 감사합니다. – cdeepakroy

답변

1

찾고있는 내용이 Casting a Classifier into a Fully Convolutional Network of the "net surgery" tutorial 섹션에 설명되어 있다고 생각합니다.
란 용액 기본적 말한다 대신 분류하는 "InnerProduct" 층 뒤에 전환 층은 "InnerProduct" 층은 어떤 크기의 이미지를 처리 ​​할 수있는 완전 컨볼 루션 그물 결과 등가 전환 층으로 변형 될 수 있다는 입력 된 크기에 따라 예측을 출력 할 수있다.
완전히 컨볼 루션 아키텍처로 이동하면 현재 수행중인 중복 계산의 수를 크게 줄이고 프로세스 속도를 크게 향상시킬 수 있습니다. 고속화를위한


다른 가능한 방향 truncated SVD trick을 사용하여 두 낮은 ​​랭크 행렬들의 곱으로 대략 고차원 "InnerProduct" 층이다.