python - 具有对角权重矩阵的自定义层
问题描述
我想实现一个带有稀疏输入层的分类器。我的数据有大约 60 个维度,我想检查特征的重要性。为此,我希望第一层有一个对角线权重矩阵(我想对其应用 L1 内核正则化器),所有非对角线都应该是不可训练的零。因此,每个输入通道的一对一连接,密集层将混合输入变量。我检查了Specify connections in NN (in keras)和Custom connections between layers Keras。后一个我不能使用,因为 Lambda 层没有引入可训练的权重。
然而,这样的事情不会影响实际的权重矩阵:
class MyLayer(Layer):
def __init__(self, output_dim,connection, **kwargs):
self.output_dim = output_dim
self.connection=connection
super(MyLayer, self).__init__(**kwargs)
def build(self, input_shape):
# Create a trainable weight variable for this layer.
self.kernel = self.add_weight(name='kernel',
shape=(input_shape[1], self.output_dim),
initializer='uniform',
trainable=True)
self.kernel=tf.linalg.tensor_diag_part(self.kernel)
self.kernel=tf.linalg.tensor_diag(self.kernel)
super(MyLayer, self).build(input_shape) # Be sure to call this at the end
def call(self, x):
return K.dot(x, self.kernel)
def compute_output_shape(self, input_shape):
return (input_shape[0], self.output_dim)
当我训练模型并打印权重时,我没有得到第一层的对角矩阵。
我究竟做错了什么?
解决方案
不太确定你到底想做什么,因为对我来说,diagonal
是方阵的东西,这意味着你的层输入和输出维度应该保持不变。
无论如何,我们先来说说方阵的情况。我认为有两种方法可以实现对角线外的所有零值的权重矩阵。
方法一:仅在概念上遵循方阵思路,用可训练的权重向量实现这一层如下。
# instead of writing y = K.dot(x,W),
# where W is the weight NxN matrix with zero values of the diagonal.
# write y = x * w, where w is the weight vector 1xN
方法2:使用默认Dense
层,但有自己的约束。
# all you need to create a mask matrix M, which is a NxN identity matrix
# and you can write a contraint like below
class DiagonalWeight(Constraint):
"""Constrains the weights to be diagonal.
"""
def __call__(self, w):
N = K.int_shape(w)[-1]
m = K.eye(N)
w *= m
return w
当然,您应该使用Dense( ..., kernel_constraint=DiagonalWeight())
.
推荐阅读
- php - 如何在下载文件时修复文件的奇怪编码?
- android - 如何使用非启动器应用启用信息亭模式?
- c - 错误:从类型“char **”分配给类型“struct XXX”时类型不兼容
- android - 覆盖常见的 XML 样式
- javascript - Foreach 验证基于 foreach 列表中的最后一个输入进行验证
- r - 为什么 tidyr extract 不尊重 ignore_case 标志?
- jquery - 带有 Jquery btn 的 HTML 动态滚动顶部
- python - Django:创建查询集?
- html - 设置边框宽度
- haskell - 推理引擎中的规则和事实(循环?)定义