微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用多层权重的正则化函数?

如何解决使用多层权重的正则化函数?

我不知道这是否可行,但我只是问以防万一。这是我的模型的(简化)架构。

Layer (type)           Output Shape        Param  #Connected to
==========================================
input_1 (InputLayer)   [(None,7,1024)  0
conv (Conv2D)          (None,10)     10240 input_1[0][0]

其中“conv”中的 10 个过滤器中的每一个都是 1x1x1024 卷积过滤器(没有偏差,但与此特定问题无关)。 我目前在“conv”上使用自定义正则化函数来确保 (1x1)x1024x10 滤波器权重矩阵具有很好的属性(基本上所有向量都是成对正交的),到目前为止,一切都按预期工作。 现在,我还希望能够禁用对这 10 个过滤器中的一些过滤器的训练。我知道如何做到这一点的唯一方法是独立实现 10 个过滤器,如下所示

Layer (type)                    Output Shape         Param #     Connected to                     
=========================================================
input_1 (InputLayer)            [(None,1024) 0
conv_1 (Conv2D)          (None,1)     1024       input_1[0][0]
conv_2 (Conv2D)          (None,1)     1024       input_1[0][0]
conv_3 (Conv2D)          (None,1)     1024       input_1[0][0]
...
conv_10 (Conv2D)          (None,1)     1024       input_1[0][0]

接着是一个连接层,然后在我认为合适的每个 conv_i 层上将“可训练”参数设置为 True/False。但是,现在我不知道如何实现我的正则化函数,该函数必须同时而不是独立地对所有层 conv_i 的权重进行计算。 有什么技巧可以用来实现这样的功能吗?或者相反,有没有办法只冻结卷积层的部分权重? 谢谢!

解决方

对于那些有兴趣的人,这是按照@LaplaceRicky 提供的建议解决我的问题的工作代码

class SpecialRegularization(tf.keras.Model):
   """ In order to avoid a warning message when saving the model,I use the solution indicated here 
   https://github.com/tensorflow/tensorflow/issues/44541
   and Now inherit from tf.keras.Model instead of Layer
   """
    def __init__(self,nfilters,**kwargs):
        super().__init__(**kwargs)
        self.inner_layers=[Conv2D(1,(1,1)) for _ in range(nfilters)]

    def call(self,inputs):
        outputs=[l(inputs) for l in self.inner_layers]
        self.add_loss(self.define_your_regularization_here())
        return tf.concat(outputs,-1)

    def set_trainable_parts(self,trainables):
        """ Set the trainable attribute independently on each filter """
        for l,t in zip(self.inner_layers,trainables):
            l.trainable = t

    def define_your_regularization_here(self):
        #reconstruct the original kernel
        large_kernel=tf.concat([l.kernel for l in self.inner_layers],-1)
        return tf.reduce_sum(large_kernel*large_kernel[:,:,::-1])
        

解决方法

实现这一目标的一种方法是拥有一个自定义 keras 层,该层包含所有小的 conv 层并负责计算正则化损失。

示例代码:

import tensorflow as tf

def _get_losses(model,x):
    model(x)
    return model.losses

def _get_grads(model,x):
  with tf.GradientTape() as t:
    model(x)
    reg_loss=tf.math.add_n(model.losses)
  return t.gradient(reg_loss,model.trainable_weights)

class SpecialRegularization(tf.keras.layers.Layer):
    def __init__(self,**kwargs):
        self.inner_layers=[tf.keras.layers.Conv2D(1,(1,1)) for i in range(10)]
        super().__init__(**kwargs)

    def call(self,inputs,training=None):
        outputs=[l(inputs,training=training) for l in self.inner_layers]
        self.add_loss(self.define_your_regularization_here())
        return tf.concat(outputs,-1)

    def define_your_regularization_here(self):
      #reconstruct the original kernel
      large_kernel=tf.concat([l.kernel for l in self.inner_layers],-1)
      #just giving an example here
      #you should define your own regularization using the entire kernel
      return tf.reduce_sum(large_kernel*large_kernel[:,:,::-1])

tf.random.set_seed(123)
inputs = tf.keras.Input(shape=(7,7,1024))
outputs = SpecialRegularization()(inputs)
model = tf.keras.Model(inputs=inputs,outputs=outputs)

#get_losses,get_grads are for demonstration purpose
get_losses=tf.function(_get_losses)
get_grads=tf.function(_get_grads)
data=tf.random.normal((64,1024))
print(get_losses(model,data))
print(get_grads(model,data)[0])
print(model.layers[1].inner_layers[-1].kernel*2)
model.summary()
'''
[<tf.Tensor: shape=(),dtype=float32,numpy=-0.20446025>]
tf.Tensor(
[[[[ 0.02072023]
   [ 0.12973154]
   [ 0.11631528]
   ...
   [ 0.00804012]
   [-0.07299817]
   [ 0.06031524]]]],shape=(1,1,1024,1),dtype=float32)
tf.Tensor(
[[[[ 0.02072023]
   [ 0.12973154]
   [ 0.11631528]
   ...
   [ 0.00804012]
   [-0.07299817]
   [ 0.06031524]]]],dtype=float32)
Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None,1024)]      0         
_________________________________________________________________
special_regularization (Spec (None,10)          10250     
=================================================================
Total params: 10,250
Trainable params: 10,250
Non-trainable params: 0
_________________________________________________________________
'''

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?