1 votos

Creando una capa convolucional por filas en Keras

Quiero crear una capa que sea casi exactamente igual que una capa Conv2D, pero básicamente tiene un kernel para cada fila de la imagen, de modo que cada fila de la salida se genere tomando el producto punto de la misma fila de la matriz de pesos con la misma fila de la matriz de entrada, y luego avanzando una columna hacia la derecha. O dicho de otra manera, es como Conv2D, pero una vez que has hecho la multiplicación elemento por elemento de la entrada con el filtro, solo sumas a lo largo de las filas, no de las columnas. (Ver imagen abajo)

introduce la descripción de la imagen aquí

Puedo pensar en un par de formas de hacer esto, pero estoy completamente perdido acerca de cuál sería la mejor. Y probablemente ni siquiera haya pensado en la mejor.

Podría usar tf.image.extract_patches para crear las ventanas y luego hacer una multiplicación elemento por elemento con una matriz de pesos apilada, y luego sumarla. Esto parece sencillo pero creo que consumirá mucha memoria.

Puedo literalmente crear miles de capas de recorte y filtros Conv2D para que las capas de recorte elijan una fila, y luego una capa Conv2D se ejecute a lo largo de ella. Eso suena como si debería funcionar, pero no parece muy elegante.

Se agradecen cualquier idea.

--EDIT--

No creo que la respuesta sea conv1d, o si lo es, estoy muy confundido.

Si ejecuto

x = tf.constant([[[0, 1],[0, 0],[1, 0], [0, 1]]], dtype='float32')
y = tf.keras.layers.Conv1D(1, 1, activation="linear", input_shape=(3,2), use_bias=False)
conv = y(x)

print(x)
print(y.weights[0])
print(conv)

entonces obtengo

tf.Tensor(
[[[0. 1.]
  [0. 0.]
  [1. 0.]
  [0. 1.]]], shape=(1, 4, 2), dtype=float32)

tf.Tensor(
[[[ 0.43913543]
  [ 0.        ]
  [-1.3466451 ]
  [ 0.43913543]]], shape=(1, 4, 1), dtype=float32)

Tengo un vector de pesos que se desplaza por la 1ra dimensión de la entrada (bien), pero la salida se está multiplicando con la 2da dimensión de la entrada (mal). El comportamiento esperado es obtener una salida de

[[[0, 0.4]
  [0, 0]
  [-1.3, 0]
  [0, 0.4]]]

Así que con un kernel 1D, espero solo una multiplicación elemento por elemento. Es una vez que se introduce la segunda dimensión del kernel que debería haber algún producto punto.

0voto

user777 Puntos 10934

Su ejemplo es simplemente semántica de transmisión. Esto es fácil de hacer usando PyTorch, y probablemente Keras o Tensorflow (pero no los uso).

x = torch.FloatTensor([[[0.0, 1.0], [0.0, 0.0], [1.0, 0.0], [0.0, 1.0]]])
y = torch.FloatTensor([[[0.43913543], [0.0], [-1.3466451], [0.43913543]]])
z = x * y
print(z)

Produce

tensor([[[ 0.0000,  0.4391],
     [ 0.0000,  0.0000],
     [-1.3466, -0.0000],
     [ 0.0000,  0.4391]]])

como se deseaba.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X