2016-07-21 21 views
0

Ich würde gerne ein wenig über Faltung auf CNNs und Bild Filterung diskutieren ... Wenn Sie ein RGB-Bild (Abmessungen von sagen 3xIxI) und K haben Filter, jeder der Größe 3xFxF, dann würden Sie am Ende mit einer Kx(I - F + 1)x(I - F + 1) Ausgabe enden, vorausgesetzt, Ihr Schritt ist 1 und Sie betrachten nur vollständig überlappende Regionen (keine Polsterung).Scipy.Signal Convolve ist nicht faltend wie es sollte

Aus dem ganzen Material, das ich auf Convolution gelesen habe, schiebt man im Prinzip jeden Filter über das Bild und berechnet in jeder Phase eine große Anzahl von Punktprodukten und summiert sie dann zu einem einzigen Wert.

Zum Beispiel:

I -> 3x5x5 matrix 
F -> 3x2x2 matrix 
I * F -> 1x4x4 matrix 

(Angenommen * ist die Faltungsoperation.)

Jetzt, da beide den Kernel und Bild die gleiche Anzahl von Kanälen haben, werden Sie Ihre am Ende Trennung 3D-Faltung in eine Anzahl von parallelen 2D-Faltungen, gefolgt von einer Matrix-Summierung.

Daher soll das obige Beispiel für alle Absichten und Zwecke (vorausgesetzt, es gibt keine Polsterung und wir betrachten nur die überlappenden Bereiche) sein, die gleiche wie folgt aus:

I -> 3x5x5 matrix 
F -> 3x2x2 matrix 
(I[0] * F[0]) + (I[1] * F[1]) + (I[2] * F[2]) -> 1x4x4 matrix 

ich gerade jeden Kanal zu trennen und sie selbstständig falten. Bitte, sieh dir das sorgfältig an und korrigiere mich, wenn ich falsch liege.

Jetzt, in der Annahme, dass dies sinnvoll ist, habe ich das folgende Experiment in Python durchgeführt.

import scipy.signal 
import numpy as np 
import test 

x = np.random.randint(0, 10, (3, 5, 5)).astype(np.float32) 
w = np.random.randint(0, 10, (3, 2, 2)).astype(np.float32) 

r1 = np.sum([scipy.signal.convolve(x[i], w[i], 'valid') for i in range(3)], axis=0).reshape(1, 4, 4) 

r2 = scipy.signal.convolve(x, w, 'valid') 

print r1.shape 
print r1 

print r2.shape 
print r2 

Das gibt mir folgendes Ergebnis:

(1, 4, 4) 
[[[ 268. 229. 297. 305.] 
    [ 256. 292. 322. 190.] 
    [ 173. 240. 283. 243.] 
    [ 291. 271. 302. 346.]]] 
(1, 4, 4) 
[[[ 247. 229. 291. 263.] 
    [ 198. 297. 342. 233.] 
    [ 208. 268. 268. 185.] 
    [ 276. 272. 280. 372.]]] 

Ich möchte nur wissen, ob dies auf Ursachen zurückzuführen ist:

  • Ein Fehler in scipy (weniger wahrscheinlich)
  • Ein Fehler in meinem Programm (eher)
  • Mein Missverständnis der überlappenden Faltung (am wahrscheinlichsten)

Oder irgendeine Kombination der oben genannten. Danke fürs Lesen!

Antwort

3

Sie schrieb:

... die gleiche wie folgt aus:

I -> 3x5x5 matrix 
F -> 3x2x2 matrix 
(I[0] * F[0]) + (I[1] * F[1]) + (I[2] * F[2]) -> 1x4x4 matrix 

Sie vergessen haben, dass Faltung eines der Argumente umkehrt. Also das obige ist nicht wahr. Stattdessen sollte die letzte Zeile sein:

(I[0] * F[2]) + (I[1] * F[1]) + (I[2] * F[0]) -> 1x4x4 matrix 

Zum Beispiel

In [28]: r1 = np.sum([scipy.signal.convolve(x[i], w[2-i], 'valid') for i in range(3)], axis=0).reshape(1, 4, 4) 

In [29]: r2 = scipy.signal.convolve(x, w, 'valid') 

In [30]: r1 
Out[30]: 
array([[[ 169., 223., 277., 199.], 
     [ 226., 213., 206., 247.], 
     [ 192., 252., 332., 369.], 
     [ 167., 266., 321., 323.]]], dtype=float32) 

In [31]: r2 
Out[31]: 
array([[[ 169., 223., 277., 199.], 
     [ 226., 213., 206., 247.], 
     [ 192., 252., 332., 369.], 
     [ 167., 266., 321., 323.]]], dtype=float32) 
+0

Ein klassisches Doh! Moment. Danke vielmals. –