在 python 中使用 keras 在输入矩阵的列上局部连接层
locally connected layer on the columns of an input matrix using keras in python
我有一个维度为 [10000, k=5, m=1024] 的 3D 数据集(10000 是数据的数量),我想训练一个网络在第一层有一个局部连接层。我在下图中显示了第一层。如何在 python 中使用 keras 实现此网络?
一个可能的实现可能是这样的:
class LocallyDenseLayer(tf.keras.layers.Layer):
def __init__(self, k, m, *args, **kwargs):
super().__init__(args, kwargs)
# alternatively, you can move that setup in the build method
# and infer the shape from the input
# this is left as an exercise to the reader
self.w = self.add_weight(name="weight", shape=(k,m))
def call(self, inputs):
# assuming input has shape [batch, k, m]
dotp = tf.linalg.diag_part(tf.tensordot(inputs, self.w, axes=[[1],[0]]))
return tf.nn.relu(dotp)
使用 tf.tensordot
在维度 k
上进行点积并仅提取包含我们想要的内容的对角线。
一个简单的用法示例:
X = tf.random.normal((100,5,1024))
y = tf.random.normal((100,1))
model = tf.keras.Sequential(
[
tf.keras.Input((5,1024)),
LocallyDenseLayer(5,1024),
tf.keras.layers.Dense(512, activation="relu"),
tf.keras.layers.Dense(1, activation="sigmoid")
]
)
model.compile(loss="mse",optimizer="sgd")
model.fit(X,y)
好吧,首先我严重误解了你的问题,很抱歉。但是如果我没理解错的话,你想用
keras.layers.LocallyConnected1D 与 kernel_size=1 和数据格式='channels_first'
这将为每个 (batch_size, k, 1) 张量提供不同的内核。
我可以用更简单的方法解决问题。假设我们有一个维度为 [10000, 5, 1024] 的 3D 数据集。我首先将它重塑为一个矩阵,其中对于原始数据集中 0 到 10000 之间的输入,我使用以下代码将矩阵 [5, 1024] 的列中的 5 个元素放在一起:
mat = np.reshape(mat,(mat.shape[0],mat.shape[1]*mat.shape[2]),'F')
所以 mat
矩阵有 [10000, 5120] 维度。最后,我在 tensorflow.keras:
中使用了 LocallyConnected1D
预定义层
model.add(tf.keras.layers.LocallyConnected1D(filters=1, kernel_size=5, strides=5, data_format='channels_first', input_shape=(1,5120), activation='relu'))
我有一个维度为 [10000, k=5, m=1024] 的 3D 数据集(10000 是数据的数量),我想训练一个网络在第一层有一个局部连接层。我在下图中显示了第一层。如何在 python 中使用 keras 实现此网络?
一个可能的实现可能是这样的:
class LocallyDenseLayer(tf.keras.layers.Layer):
def __init__(self, k, m, *args, **kwargs):
super().__init__(args, kwargs)
# alternatively, you can move that setup in the build method
# and infer the shape from the input
# this is left as an exercise to the reader
self.w = self.add_weight(name="weight", shape=(k,m))
def call(self, inputs):
# assuming input has shape [batch, k, m]
dotp = tf.linalg.diag_part(tf.tensordot(inputs, self.w, axes=[[1],[0]]))
return tf.nn.relu(dotp)
使用 tf.tensordot
在维度 k
上进行点积并仅提取包含我们想要的内容的对角线。
一个简单的用法示例:
X = tf.random.normal((100,5,1024))
y = tf.random.normal((100,1))
model = tf.keras.Sequential(
[
tf.keras.Input((5,1024)),
LocallyDenseLayer(5,1024),
tf.keras.layers.Dense(512, activation="relu"),
tf.keras.layers.Dense(1, activation="sigmoid")
]
)
model.compile(loss="mse",optimizer="sgd")
model.fit(X,y)
好吧,首先我严重误解了你的问题,很抱歉。但是如果我没理解错的话,你想用
keras.layers.LocallyConnected1D 与 kernel_size=1 和数据格式='channels_first'
这将为每个 (batch_size, k, 1) 张量提供不同的内核。
我可以用更简单的方法解决问题。假设我们有一个维度为 [10000, 5, 1024] 的 3D 数据集。我首先将它重塑为一个矩阵,其中对于原始数据集中 0 到 10000 之间的输入,我使用以下代码将矩阵 [5, 1024] 的列中的 5 个元素放在一起:
mat = np.reshape(mat,(mat.shape[0],mat.shape[1]*mat.shape[2]),'F')
所以 mat
矩阵有 [10000, 5120] 维度。最后,我在 tensorflow.keras:
LocallyConnected1D
预定义层
model.add(tf.keras.layers.LocallyConnected1D(filters=1, kernel_size=5, strides=5, data_format='channels_first', input_shape=(1,5120), activation='relu'))