2016-06-28 8 views
3

Я выполнил поиск основных ближайших соседей в моей учебной работе. Дело в том, что основная реализация numpy работает хорошо, но просто добавляет декоратор «@jit» (компиляция в Numba), выходы различаются (он дублирует некоторые соседи в конце по неизвестной причине ...)Различия в выводах numba

Вот основной алгоритм:

import numpy as np 
from numba import jit 

@jit(nopython=True) 
def knn(p, points, k): 
    '''Find the k nearest neighbors (brute force) of the point p 
    in the list points (each row is a point)''' 

    n = p.size # Lenght of the points 
    M = points.shape[0] # Number of points 
    neighbors = np.zeros((k,n)) 
    distances = 1e6*np.ones(k) 

    for i in xrange(M): 
     d = 0 
     pt = points[i, :] # Point to compare 
     for r in xrange(n): # For each coordinate 
      aux = p[r] - pt[r] 
      d += aux * aux 
     if d < distances[k-1]: # We find a new neighbor 
      pos = k-1 
      while pos>0 and d<distances[pos-1]: # Find the position 
       pos -= 1 
      pt = points[i, :] 
      # Insert neighbor and distance: 
      neighbors[pos+1:, :] = neighbors[pos:-1, :] 
      neighbors[pos, :] = pt 
      distances[pos+1:] = distances[pos:-1] 
      distances[pos] = d 

    return neighbors, distances 

Для тестирования:

p = np.random.rand(10) 
points = np.random.rand(250, 10) 
k = 5 
neighbors = knn(p, points, k) 

БЕЗ @jit декоратор, один получает правильный ответ:

In [1]: distances 
Out[1]: array([ 0.3933974 , 0.44754336, 0.54548715, 0.55619749, 0.5657846 ]) 

Но компиляция Numba дает странные результаты:

Out[2]: distances 
Out[2]: array([ 0.3933974 , 0.44754336, 0.54548715, 0.54548715, 0.54548715]) 

Кто-нибудь может помочь? Я не понимаю, почему это происходит ...

Спасибо.

+0

Вы можете быть заинтересованы в SciPy [KDTree] (http://docs.scipy.org/doc/scipy/ ссылка/сгенерированная/scipy.spatial.cKDTree.html). – Daniel

+0

@Ophion Спасибо за подсказку. Я играл с реализацией KDTree sklearn (я полагаю, они похожи), и они хороши для предварительной обработки данных для будущих кратных точек запроса. В моей работе мне нужно найти соседей, изменяющих список точек все время (в материалах обработки изображений), и этот тип реализаций становится слишком медленным. Похоже, что реализация KDTree не лучше грубой силы, когда размер пространства большой (например, больше 25). –

ответ

1

Я считаю, что проблема заключается в том, что Numba обрабатывает один фрагмент в другом по-разному, когда эти срезы перекрываются, чем при работе без него. Я не знаком с внутренностями numpy, но, возможно, есть специальная логика для обработки операций с энергозависимой памятью, подобных этому, которых нет в Numba. Измените следующие строки и результаты с JIT декоратором стать в соответствии с обычной версией Python:

neighbors[pos+1:, :] = neighbors[pos:-1, :].copy() 
... 
distances[pos+1:] = distances[pos:-1].copy() 
+0

Спасибо @JoshAdel! Это работает для меня. Я проверил до этого, что этот перекрывающий срез в Numpy не вызывает проблем, но по некоторым причинам Numba переводит его в другой алгоритм ... Во всех случаях он носит, что только дублирует некоторые из соседей, но не другие ... Еще раз спасибо! PD: Я поклонник python, но такие вещи заставляют меня серьезно подумать, чтобы узнать Юлию ... –

+0

@ MarioGonzález Я бы посоветовал вам опубликовать ваш пример как проблему в треевом журнале вопросов о Numba github. Команда разработчиков обычно очень отзывчива и хочет знать о ошибках или неожиданном поведении. – JoshAdel

+0

Спасибо @JoshAdel за совет. Он был опубликован [здесь] (https://github.com/numba/numba/issues/1960). –

 Смежные вопросы

  • Нет связанных вопросов^_^