tensorflow
Usando la convolución 1D
Buscar..
Ejemplo basico
Actualización: TensorFlow ahora admite la convolución 1D desde la versión r0.11, usando tf.nn.conv1d
.
Considere un ejemplo básico con una entrada de longitud 10
y dimensión 16
. El tamaño del lote es de 32
. Por lo tanto, tenemos un marcador de posición con forma de entrada [batch_size, 10, 16]
.
batch_size = 32
x = tf.placeholder(tf.float32, [batch_size, 10, 16])
Luego creamos un filtro con ancho 3, tomamos 16
canales como entrada y también emitimos 16
canales.
filter = tf.zeros([3, 16, 16]) # these should be real values, not 0
Finalmente aplicamos tf.nn.conv1d
con un paso y un relleno:
- zancada : entero
s
- Relleno : esto funciona como en 2D, puede elegir entre
SAME
yVALID
.SAME
emitirá la misma longitud de entrada, mientras queVALID
no agregará relleno de cero.
Para nuestro ejemplo, tomamos un paso de 2 y un relleno válido.
output = tf.nn.conv1d(x, filter, stride=2, padding="VALID")
La forma de salida debe ser [batch_size, 4, 16]
.
Con el padding="SAME"
, tendríamos una forma de salida de [batch_size, 5, 16]
.
Para versiones anteriores de TensorFlow, puedes usar convoluciones en 2D al establecer la altura de las entradas y los filtros en 1
.
Matemáticas detrás de la convolución 1D con ejemplos avanzados en TF
`Para calcular la convolución 1D a mano, desliza tu kernel sobre la entrada, calcula las multiplicaciones de elementos y las resume.
La forma más fácil es para el relleno = 0, zancada = 1
Entonces, si su input = [1, 0, 2, 3, 0, 1, 1]
y kernel = [2, 1, 3]
el resultado de la convolución es [8, 11, 7, 9, 4]
, que es Calculado de la siguiente manera:
- 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
La función conv1d de TF calcula las convoluciones en lotes, por lo que para hacer esto en TF, debemos proporcionar los datos en el formato correcto (el documento explica que la entrada debe estar en [batch, in_width, in_channels]
, también explica cómo debe verse el kernel me gusta). Asi que
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)
que le dará la misma respuesta que calculamos previamente: [ 8. 11. 7. 9. 4.]
Convolución con relleno.
El relleno es solo una forma elegante de agregar y agregar un poco de valor a tus comentarios. En la mayoría de los casos, este valor es 0, y esta es la razón por la que la mayoría de las personas lo denominan cero-relleno. TF es compatible con 'VALID' y 'SAME', sin relleno, para un relleno arbitrario que necesita usar tf.pad () . El relleno 'VÁLIDO' significa que no hay ningún tipo de relleno, donde el mismo significa que la salida tendrá el mismo tamaño que la entrada. Calculemos la convolución con el padding=1
en el mismo ejemplo (observe que para nuestro núcleo este es el relleno 'MISMO'). Para hacer esto, simplemente agregamos nuestra matriz con 1 cero al principio / final: input = [0, 1, 0, 2, 3, 0, 1, 1, 0]
.
Aquí puede observar que no necesita volver a calcular todo: todos los elementos permanecen iguales, excepto el primero / el último, que son:
- 1 = 0 * 2 + 1 * 1 + 0 * 3
- 3 = 1 * 2 + 1 * 1 + 0 * 3
Entonces el resultado es [1, 8, 11, 7, 9, 4, 3]
que es el mismo que se calcula con TF:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'SAME'))
with tf.Session() as sess:
print sess.run(res)
Convolución con zancadas
Las zancadas te permiten saltar elementos mientras te deslizas. En todos nuestros ejemplos anteriores, deslizamos 1 elemento, ahora puede deslizar s
elementos a la vez. Debido a que usaremos un ejemplo anterior, hay un truco: deslizar por n
elementos es equivalente a deslizar por 1 elemento y seleccionar cada n-ésimo elemento.
Entonces, si usamos nuestro ejemplo anterior con el padding=1
y cambiamos la stride
a 2, simplemente toma el resultado anterior [1, 8, 11, 7, 9, 4, 3]
y deja cada elemento 2-nd, lo que resultará en [1, 11, 9, 3]
. Puedes hacer esto en TF de la siguiente manera:
res = tf.squeeze(tf.nn.conv1d(data, kernel, 2, 'SAME'))
with tf.Session() as sess:
print sess.run(res)