我正在实现一个自定义的密集层,其权重维度为12x12
,但并非所有神经元都连接到另一层。因此,我定义了一个如下所示的投影矩阵:
projection_matrix = np.zeros((12, 12))connections = [[2, 6, 9], [4, 7, 10], [0, 6, 9], [5, 8, 11], [1, 7, 10], [3, 8, 11], [0, 2, 9], [1, 4, 10], [3, 5, 11], [0, 2, 6], [1, 4, 7], [3, 5, 8]]for i, connection in zip(range(projection_matrix.shape[0]), connections): for j in connection: projection_matrix[i, j] = 1
然后,我的想法是将权重矩阵与这个投影矩阵相乘:
new_weight_matrix = np.multiply(weight_matrix, projection_matrix) # 也可以是tf.multiply
我在查阅tf.layers.dense
的文档,来自这里。有一个名为kernel_constraint
的参数,其描述如下:
可选的投影函数,用于在优化器更新后应用到偏置上。
我的问题是,将projection_matrix
传递给这个参数(kernel_constraint
)是否能实现我想要的效果(仅连接由projection_matrix
定义的特定神经元)?
回答:
对你问题的回答是:不行。
这个参数在优化器更新后对你的内核(或偏置)应用投影。当你希望你的变量属于某个特定子域时使用。例如,在优化器更新后,变量会被重新投影到可行子域内。
例如,如果你希望你的内核在[0,1]
范围内,你可以构建一个这样的kernel_constraint
:
def custom_kernel_constraint(var): return tf.math.maximum(tf.math.minimum(var, 1.), 0.)
我不知道你的具体用例,但如果你需要在调用dense
时实现这种断开连接,你可以这样定义kernel_constraint
:
def disconnection_kernel_constraint(var): return tf.multiply(var, projection_matrix)
然而,你必须记得在初始化内核时,也要使用常量初始化器,将一个随机内核与你的投影矩阵相乘,否则第一次计算将不会有断开连接(因为投影仅在优化器更新之后应用)。
例如,作为参数
kernel_initializer= tf.constant_initializer(tf.multiply(tf.random_normal(shape=[12,12]),projection_matrix))
我认为这比在代码中显式使用tf.multiply
要稍微复杂一些,但这取决于你的需求。