Suche…


Einführung

Die 2D-Faltung wird auf ähnliche Weise berechnet, wie man die 1D-Faltung berechnen würde: Sie schieben Ihren Kern über die Eingabe, berechnen die elementweisen Multiplikationen und summieren sie auf. Anstatt dass Ihr Kernel / Ihre Eingabe ein Array ist, handelt es sich hier um Matrizen.

Keine Auffüllung, Schritte = 1

Dies ist das einfachste Beispiel mit den einfachsten Berechnungen. Nehmen wir an, Ihre input und Ihr kernel sind: Geben Sie hier die Bildbeschreibung ein

Wenn Sie Ihren Kernel haben, erhalten Sie folgende Ausgabe: Geben Sie hier die Bildbeschreibung ein , die auf folgende Weise berechnet wird:

  • 14 = 4 * 1 + 3 * 0 + 1 * 1 + 2 * 2 + 1 * 1 + 0 * 0 + 1 * 0 + 2 * 0 + 4 * 1
  • 6 = 3 * 1 + 1 * 0 + 0 * 1 + 1 * 2 + 0 * 1 + 1 * 0 + 2 * 0 + 4 * 0 + 1 * 1
  • 6 = 2 * 1 + 1 * 0 + 0 * 1 + 1 * 2 + 2 * 1 + 4 * 0 + 3 * 0 + 1 * 0 + 0 * 1
  • 12 = 1 * 1 + 0 * 0 + 1 * 1 + 2 * 2 + 4 * 1 + 1 * 0 + 1 * 0 + 0 * 0 + 2 * 1

Die conv2d- Funktion von TF berechnet die Faltungen in Batches und verwendet ein etwas anderes Format. Für eine Eingabe ist es [batch, in_height, in_width, in_channels] Für den Kernel ist es [filter_height, filter_width, in_channels, out_channels] . Daher müssen wir die Daten im richtigen Format bereitstellen:

import tensorflow as tf
k = tf.constant([
    [1, 0, 1],
    [2, 1, 0],
    [0, 0, 1]
], dtype=tf.float32, name='k')
i = tf.constant([
    [4, 3, 1, 0],
    [2, 1, 0, 1],
    [1, 2, 4, 1],
    [3, 1, 0, 2]
], dtype=tf.float32, name='i')
kernel = tf.reshape(k, [3, 3, 1, 1], name='kernel')
image  = tf.reshape(i, [1, 4, 4, 1], name='image')

Anschließend wird die Faltung berechnet mit:

res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 1, 1, 1], "VALID"))
# VALID means no padding
with tf.Session() as sess:
   print sess.run(res)

Und wird dem entsprechen, den wir von Hand berechnet haben.

Einige Polsterung, Strides = 1

Das Auffüllen ist nur ein ausgefallener Name: Umgeben Sie Ihre Eingabematrix mit etwas Konstanten. In den meisten Fällen ist die Konstante Null und deshalb wird sie als Nullfüllung bezeichnet. Wenn Sie also eine Auffüllung von 1 in unserer ursprünglichen Eingabe verwenden möchten (siehe erstes Beispiel mit padding=0, strides=1 ), sieht die Matrix wie folgt aus:

Geben Sie hier die Bildbeschreibung ein

Um die Werte der Faltung zu berechnen, machen Sie dasselbe Gleiten. Beachten Sie, dass in unserem Fall viele Werte in der Mitte nicht neu berechnet werden müssen (sie werden dieselben wie im vorherigen Beispiel sein. Ich werde auch hier nicht alle Berechnungen anzeigen, da die Idee einfach ist. Das Ergebnis ist:

Geben Sie hier die Bildbeschreibung ein

woher

  • 5 = 0 * 1 + 0 * 0 + 0 * 1 + 0 * 2 + 4 * 1 + 3 * 0 + 0 * 0 + 0 * 1 + 1 * 1
  • ...
  • 6 = 4 * 1 + 1 * 0 + 0 * 1 + 0 * 2 + 2 * 1 + 0 * 0 + 0 * 0 + 0 * 0 + 0 * 1

TF unterstützt keine willkürliche Auffüllung in der Funktion conv2d. Wenn Sie also eine Auffüllung benötigen, die nicht unterstützt wird, verwenden Sie tf.pad () . Zum Glück für unsere Eingabe ist die Auffüllung 'SAME' gleich Auffüllung = 1. Daher müssen wir in unserem vorherigen Beispiel fast nichts ändern:

res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 1, 1, 1], "SAME"))
# 'SAME' makes sure that our output has the same size as input and 
# uses appropriate padding. In our case it is 1.
with tf.Session() as sess:
   print sess.run(res)

Sie können überprüfen, ob die Antwort von Hand berechnet wird.

Polsterung und Schritte (der allgemeinste Fall)

Nun wenden wir eine schrittweise Faltung auf unser zuvor beschriebenes aufgefülltes Beispiel an und berechnen die Faltung mit p = 1, s = 2

Geben Sie hier die Bildbeschreibung ein

Früher haben wir bei strides = 1 unser Schiebefenster um 1 Position verschoben, bei strides = s bewegt es sich um s Positionen (Sie müssen s^2 Elemente weniger berechnen. In unserem Fall können wir jedoch eine Abkürzung nehmen und keine ausführen Berechnungen überhaupt. Da wir bereits die Werte für s = 1 berechnet haben, können wir in diesem Fall einfach jedes zweite Element ergreifen.

Also wenn die lösung bei s = 1 war

Geben Sie hier die Bildbeschreibung ein

im Falle von s = 2 es sein:

Geben Sie hier die Bildbeschreibung ein

Überprüfen Sie die Positionen der Werte 14, 2, 12, 6 in der vorherigen Matrix. Die einzige Änderung, die wir in unserem Code vornehmen müssen, ist die Änderung der Schritte von 1 in 2 für die Breiten- und Höhenbemaßung (2-nd, 3-rd).

res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 2, 2, 1], "SAME"))
with tf.Session() as sess:
   print sess.run(res)

Übrigens gibt es nichts, was uns daran hindert, unterschiedliche Schritte für unterschiedliche Dimensionen zu verwenden.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow