tensorflow
Używając splotu 1D
Szukaj…
Podstawowy przykład
Aktualizacja: TensorFlow obsługuje teraz splot 1D od wersji r0.11, używając tf.nn.conv1d
.
Rozważ podstawowy przykład z wprowadzeniem długości 10
i wymiaru 16
. Wielkość partii wynosi 32
. Mamy zatem symbol zastępczy o kształcie wejściowym [batch_size, 10, 16]
.
batch_size = 32
x = tf.placeholder(tf.float32, [batch_size, 10, 16])
Następnie tworzymy filtr o szerokości 3 i pobieramy 16
kanałów jako dane wejściowe, a także wysyłamy 16
kanałów.
filter = tf.zeros([3, 16, 16]) # these should be real values, not 0
Na koniec tf.nn.conv1d
krokiem i wypełnieniem:
- krok : liczba całkowita
s
- dopełnienie : działa tak jak w 2D, możesz wybierać między
SAME
iVALID
.SAME
wyświetli tę samą długość wejściową, aVALID
nie doda dopełniania zerowego.
W naszym przykładzie bierzemy krok 2 i prawidłowe wypełnienie.
output = tf.nn.conv1d(x, filter, stride=2, padding="VALID")
Kształt wyjściowy powinien wynosić [batch_size, 4, 16]
.
Przy padding="SAME"
mielibyśmy kształt wyjściowy [batch_size, 5, 16]
.
W poprzednich wersjach TensorFlow można po prostu użyć splotów 2D, ustawiając wysokość wejść i filtrów na 1
.
Matematyka stojąca za splotem 1D z zaawansowanymi przykładami w TF
`Aby ręcznie obliczyć splot 1D, przesuwasz jądro nad wejściem, obliczasz mnożenia elementarne i sumujesz je.
Najprostszym sposobem jest wypełnienie = 0, krok = 1
Więc jeśli twój input = [1, 0, 2, 3, 0, 1, 1]
i kernel = [2, 1, 3]
wynikiem splotu jest [8, 11, 7, 9, 4]
, co jest obliczone w następujący sposób:
- 8 = 1 * 2 + 0 * 1 + 2 * 3
- 11 = 0 * 2 + 2 * 1 + 3 * 3
- 7 = 2 * 2 + 3 * 1 + 0 * 3
- 9 = 3 * 2 + 0 * 1 + 1 * 3
- 4 = 0 * 2 + 1 * 1 + 1 * 3
Funkcja conv1d TF oblicza sploty w partiach, więc aby to zrobić w TF, musimy podać dane we właściwym formacie (doc wyjaśnia, że dane wejściowe powinny być w [batch, in_width, in_channels]
, wyjaśnia również, jak powinno wyglądać jądro lubić). Więc
import tensorflow as tf
i = tf.constant([1, 0, 2, 3, 0, 1, 1], dtype=tf.float32, name='i')
k = tf.constant([2, 1, 3], dtype=tf.float32, name='k')
print i, '\n', k, '\n'
data = tf.reshape(i, [1, int(i.shape[0]), 1], name='data')
kernel = tf.reshape(k, [int(k.shape[0]), 1, 1], name='kernel')
print data, '\n', kernel, '\n'
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'VALID'))
with tf.Session() as sess:
print sess.run(res)
która da ci tę samą odpowiedź, którą obliczyliśmy wcześniej: [ 8. 11. 7. 9. 4.]
Splot z wyściółką
Wypełnienie jest tylko fantazyjnym sposobem na dodanie i dodanie danych wejściowych z pewną wartością. W większości przypadków ta wartość wynosi 0 i dlatego ludzie nazywają ją zerowaniem. TF obsługuje wypełnianie zerowe „VALID” i „SAME”, do dowolnego wypełniania należy użyć tf.pad () . „WAŻNE” wypełnienie oznacza brak wypełnienia, przy czym to samo oznacza, że dane wyjściowe będą miały taki sam rozmiar danych wejściowych. Obliczmy splot z padding=1
na tym samym przykładzie (zauważ, że dla naszego jądra jest to padanie SAME). Aby to zrobić, po prostu dołączamy naszą tablicę z 1 zerem na początku / na końcu: input = [0, 1, 0, 2, 3, 0, 1, 1, 0]
.
Tutaj możesz zauważyć, że nie musisz ponownie obliczać wszystkiego: wszystkie elementy pozostają takie same, z wyjątkiem pierwszego / ostatniego, które są:
- 1 = 0 * 2 + 1 * 1 + 0 * 3
- 3 = 1 * 2 + 1 * 1 + 0 * 3
Zatem wynik to [1, 8, 11, 7, 9, 4, 3]
który jest taki sam jak obliczony z TF:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'SAME'))
with tf.Session() as sess:
print sess.run(res)
Konwekcja krokami
Kroki pozwalają na pomijanie elementów podczas przesuwania. We wszystkich poprzednich przykładach slided 1 elementu, teraz można przesunąć s
elementów na raz. Ponieważ użyjemy poprzedniego przykładu, istnieje pewna sztuczka: przesunięcie o n
elementów jest równoważne przesunięciu o 1 element i zaznaczeniu każdego n-tego elementu.
Więc jeśli użyjemy naszego poprzedniego przykładu z padding=1
i zmienimy stride
na 2, po prostu weź poprzedni wynik [1, 8, 11, 7, 9, 4, 3]
i pozostaw każdy drugi element, co spowoduje [1, 11, 9, 3]
. Możesz to zrobić w TF w następujący sposób:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 2, 'SAME'))
with tf.Session() as sess:
print sess.run(res)