Skip to main content
 首页 » 编程设计

python之Tensorflow 2.0 Keras 中过激激活值的正则化

2024年08月12日37pander-it

对于一个特定的问题,我想在我的 Keras 模型中对一个层的过度兴奋激活进行正则化。因此,我创建了一个基于高于特定阈值的激活值数量的自定义损失。

损失出现了,但没有被优化器减少。只有分类损失最小化。

使用最新版本的 tensorflow 2.0 和 Keras 构建模型。我当前的尝试添加了第二个输出,其中包含依赖于特定层的自定义损失。 我已经尝试将损失作为第二个输入提供,并将其添加到密集损失中,这给了我相同的结果,自定义损失没有最小化。

我想无法计算第二个损失的梯度,但我在 PyTorch 中有一个工作示例,这似乎可行。

import tensorflow as tf 
import numpy as np 
 
from tensorflow.keras.models import Model 
from tensorflow.keras.layers import Dense, Conv2D, Flatten, MaxPooling2D, SpatialDropout2D, Input 
from tensorflow.keras.optimizers import SGD 
 
import tensorflow.keras.backend as K 
from tensorflow.python.keras.layers import Layer 
 
import get_prepare_dataset 
 
# config 
REGULARIZATION_HYPERP = 0.01 
(train_images, train_labels), (test_images, test_labels) = get_prepare_dataset.mnist10() 
 
 
class Taboo(Layer): 
    def compute_output_signature(self, input_signature): 
        pass 
 
    def __init__(self, thresholds, **kwargs): 
        super(Taboo, self).__init__(**kwargs) 
        self.thresholds = thresholds 
 
    def call(self, x, mask=None): 
        return x 
 
 
def taboo_loss(y_true, y_pred): 
    above_threshold = tf.math.greater(y_pred, y_true[0]) 
    return REGULARIZATION_HYPERP * K.mean(tf.reduce_sum(tf.cast(above_threshold, tf.float32))) 
 
 
if __name__ == "__main__": 
    y_input = Input(shape=(28, 28, 1)) 
    layer1 = Conv2D(filters=10, kernel_size=(5, 5), strides=(1, 1), activation='relu', padding="same")(y_input) 
    layer2 = MaxPooling2D(pool_size=(2, 2), strides=(1, 1), padding='valid')(layer1) 
    layer3 = Conv2D(filters=20, kernel_size=(5, 5), strides=(1, 1), activation='relu', padding="valid")(layer2) 
    layer4 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid')(layer3) 
    layer5 = SpatialDropout2D(0.5)(layer4) 
    layer6 = Flatten()(layer5) 
    output_layer = Dense(units=10, activation='softmax')(layer6) 
 
    thresholds = [0.5] 
 
    cr = Taboo(thresholds)(layer3) 
    model = Model(inputs=y_input, outputs=[output_layer, cr]) 
    model.compile(optimizer=SGD(lr=0.1), loss=[K.binary_crossentropy, taboo_loss]) 
 
    model.fit(train_images, [train_labels, np.asarray([thresholds] * len(train_images))], 
              validation_data=[test_images, [test_labels, np.asarray([thresholds] * len(test_images))]], epochs=40) 
 

分类损失减少了,而第二个损失变大了。 我希望第二个损失最小化。

请您参考如下方法:

您的自定义损失在重要的点上不可区分:当值超过阈值时,您的损失就会跳跃。这意味着它不能通过基于梯度的方法最小化。但是,如果您使损失与超出阈值的数量成正比,那么它将是可区分的,因此可以通过基于梯度的方法将其最小化。