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)
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.