用于非图像矩阵的 Keras CNN

Keras CNN for non-image matrix

我最近开始学习深度学习和强化学习,我正在尝试弄清楚如何使用 Keras 为 10 行 3 列的 0 和 1 矩阵编写卷积神经网络。

输入矩阵例如如下所示

[
 [1, 0, 0], 
 [0, 1, 0], 
 [0, 0, 0], 
 ...
]

输出应该是另一个0和1的矩阵,不同于前面提到的输入矩阵,并且具有不同的行数和列数。

输出矩阵中 0 和 1 的位置取决于输入矩阵中 0 和 1 的位置。

还有第二个输出,一个数组,其中的值取决于输入矩阵中 1 的位置。

我在 Internet 上搜索了代码示例,但找不到任何有用的东西。

编辑:

神经网络的输入是一个二维数组,有 10 行,每行有 3 列。 输出(至少现在)是一个有 12 行的二维数组,每行有 10 列(与输入二维数组中的行数相同)。

这是我到目前为止的想法,我不知道它是否正确。

nbre_users = 10 # number of rows in the input 2D matrix
nbre_subchannels = 12 # number of rows in the output 2D matrix

model = Sequential()
model.add(Dense(50, input_shape=(nbre_users, 3), kernel_initializer="he_normal" ,activation="relu"))
model.add(Dense(20, kernel_initializer="he_normal", activation="relu"))
model.add(Dense(5, kernel_initializer="he_normal", activation="relu"))
model.add(Flatten())
model.add(Dense(nbre_subchannels))
model.add(Dense(nbre_users, activation = 'softmax'))
model.compile(optimizer=Adam(learning_rate=1e-4), loss='mean_squared_error')

这是模型摘要:

如果你想在单个空间中进行卷积,你可以使用 1D convolutional layers,根据我的理解,这是你想要的。

例如

# assuming 3x10 matrix with single batch
input_shape = (1, 3, 10)
y = tf.keras.layers.Conv1D(32, 3, activation='relu',input_shape=input_shape[1:])(x)

经过澄清,这是我的答案。

您要解决的问题似乎是一个将大小为 (10,3,1) 的二维灰度图像转换为大小为 (12,10,1) 的二维灰度图像的神经网络。

二维灰度图像只不过是一个额外轴设置为 1 的二维矩阵。

a = np.array([[0,1,0],
              [1,0,1],
              [0,1,0]])

a.shape

#OUTPUT = (3,3)

a.reshape((3,3,1)) #reshape to 3,3,1

#OUTPUT - 
#array([[[0],
#        [1],
#        [0]],
#
#       [[1],
#        [0],
#        [1]],
#
#       [[0],
#        [1],
#        [0]]])

所以(10,3)的2D矩阵可以称为单通道(10,3,1)的3D图像。这将使您能够正确地将卷积应用于您的输入。

如果这部分清楚了,那么在网络的前向计算中,既然要保证1和0的空间位置都被捕获,就要用到卷积层。在这里使用密集层不是正确的步骤。

然而,一系列的卷积操作有助于Downsample和图像。由于您需要输出 2D 矩阵(灰度图像),因此您也需要 Upsample。这样的网络称为 Deconv 网络。

第一个系列层对输入进行卷积,'flattening'它们成为通道向量。下一组图层使用 2D Conv Transpose 操作将通道更改回 2D 矩阵(灰度图像)

参考此图片 -

这是一个示例代码,向您展示了如何使用反卷积网络将 (10,3,1) 图像转换为 (12,10,1) 图像。

from tensorflow.keras import layers, Model

inp = layers.Input((10,3,1))     ##
x = layers.Conv2D(2, (2,2))(inp) ##  Convolution part
x = layers.Conv2D(4, (2,2))(x)   ##

x = layers.Conv2DTranspose(4, (3,4))(x)   ##
x = layers.Conv2DTranspose(2, (2,4))(x)   ##  Deconvolution part
out = layers.Conv2DTranspose(1, (2,4))(x) ##

model = Model(inp, out)
model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_33 (InputLayer)        [(None, 10, 3, 1)]        0         
_________________________________________________________________
conv2d_49 (Conv2D)           (None, 9, 2, 2)           10        
_________________________________________________________________
conv2d_50 (Conv2D)           (None, 8, 1, 4)           36        
_________________________________________________________________
conv2d_transpose_46 (Conv2DT (None, 10, 4, 4)          196       
_________________________________________________________________
conv2d_transpose_47 (Conv2DT (None, 11, 7, 2)          66        
_________________________________________________________________
conv2d_transpose_48 (Conv2DT (None, 12, 10, 1)         17        
=================================================================
Total params: 325
Trainable params: 325
Non-trainable params: 0
_________________________________________________________________

显然,可以随意添加激活、丢弃、池化层等等。上面的代码只是展示了如何使用下采样和上采样从给定的单通道图像到另一个单通道图像。


On a side note - I would really advise that you spend some time understanding how CNNs work. Deconv nets are complex and if you are solving a problem that involves them, before properly understanding how 2D CNNs work, it may cause some foundational problems especially if you are starting to learn this domain.