Suma de diferencias cuadradas (SSD) en números / seta

Estoy tratando de usar Python y Numpy / Scipy para implementar un algoritmo de procesamiento de imágenes. El generador de perfiles me dice que se está gastando mucho tiempo en la siguiente función (llamada a menudo), que me dice la sum de las diferencias cuadradas entre dos imágenes

def ssd(A,B): s = 0 for i in range(3): s += sum(pow(A[:,:,i] - B[:,:,i],2)) return s 

¿Cómo puedo acelerar esto? Gracias.

Sólo

 s = numpy.sum((A[:,:,0:3]-B[:,:,0:3])**2) 

(lo cual espero que sea una sum((AB)**2) justa sum((AB)**2) si la forma es siempre (,, 3))

También puede usar el método de la sum: ((AB)**2).sum()

¿Derecha?

Estoy confundido por qué estás tomando i in range(3) . ¿Se supone que eso es todo el conjunto, o solo parte?

En general, puede reemplazar la mayor parte de esto con operaciones definidas en números:

 def ssd(A,B): squares = (A[:,:,:3] - B[:,:,:3]) ** 2 return numpy.sum(squares) 

De esta manera, puede realizar una operación en lugar de tres y el uso de numpy.sum puede optimizar la adición mejor que la sum integrada.

No sé si la función pow () con potencia 2 será rápida. Tratar:

 def ssd(A,B): s = 0 for i in range(3): s += sum((A[:,:,i] - B[:,:,i])*A[:,:,i] - B[:,:,i]) return s 

Además de la respuesta de Ritsaert Hornstra que obtuvo 2 marcas negativas (es cierto que no la vi en su forma original …)

Esto es realmente cierto.

Para una gran cantidad de iteraciones, a menudo puede tomar el doble de tiempo usar el operador ‘**’ o el método pow (x, y) para multiplicar manualmente los pares juntos. Si es necesario, use el método math.fabs () si está eliminando los NaN (lo que a veces ocurre especialmente al usar int16s, etc.), y aún así solo toma aproximadamente la mitad del tiempo de las dos funciones dadas.

No es tan importante para la pregunta original que conozco, pero definitivamente vale la pena saberlo.

Puedes probar este:

 dist_sq = np.sum((A[:, np.newaxis, :] - B[np.newaxis, :, :]) ** 2, axis=-1) 

Puede encontrar más detalles aquí (el ejemplo de ‘k-vecinos más cercanos’): https://jakevdp.github.io/PythonDataScienceHandbook/02.08-sorting.html

En lenguaje Ruby puedes lograr esto de esta manera.

 def diff_btw_sum_of_squars_and_squar_of_sum(from=1,to=100) # use default values from 1..100. ((1..100).inject(:+)**2) -(1..100).map {|num| num ** 2}.inject(:+) end diff_btw_sum_of_squars_and_squar_of_sum #call for above method