为了账号安全,请及时绑定邮箱和手机立即绑定

从keras dropout层中提取dropout mask?

从keras dropout层中提取dropout mask?

喵喵时光机 2022-06-02 11:07:45
我想在训练时从每个批次的顺序 Keras 模型中的丢失层中提取和存储丢失掩码 [1/0 数组]。我想知道在 Keras 中是否有直接的方法可以做到这一点,或者我是否需要切换到 tensorflow(如何在 Tensorflow 中获取 dropout 掩码)。将不胜感激任何帮助!我对 TensorFlow 和 Keras 很陌生。None我尝试使用但在调用前一层后 得到的 dropout 层有几个函数(dropout_layer.get_output_mask()、dropout_layer.get_input_mask()) 。model = tf.keras.Sequential()model.add(tf.keras.layers.Flatten(name="flat", input_shape=(28, 28, 1)))model.add(tf.keras.layers.Dense(    512,    activation='relu',    name = 'dense_1',    kernel_initializer=tf.keras.initializers.GlorotUniform(seed=123),    bias_initializer='zeros'))dropout = tf.keras.layers.Dropout(0.2, name = 'dropout') #want this layer's maskmodel.add(dropout)x = dropout.output_masky = dropout.input_maskmodel.add(tf.keras.layers.Dense(    10,    activation='softmax',    name='dense_2',    kernel_initializer=tf.keras.initializers.GlorotUniform(seed=123),    bias_initializer='zeros'))model.compile(...)model.fit(...)
查看完整描述

2 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

它在 Keras 中并不容易暴露。它深入到它调用 TensorFlow 辍学。


所以,虽然你使用的是 Keras,但它也将是图中的一个张量,可以通过名称获取(找到它的名称:在 Tensorflow 中,获取图中所有张量的名称)。


这个选项当然会缺少一些 keras 信息,您可能必须在 Lambda 层内执行此操作,以便 Keras 将某些信息添加到张量。而且您必须格外小心,因为即使不训练(跳过掩码),张量也会存在


现在,您还可以使用不那么 hacky 的方式,这可能会消耗一些处理:


def getMask(x):

    boolMask = tf.not_equal(x, 0)

    floatMask = tf.cast(boolMask, tf.float32) #or tf.float64

    return floatMask

用一个Lambda(getMasc)(output_of_dropout_layer)


Sequential但是,您将需要一个功能性 API,而不是使用模型Model。


inputs = tf.keras.layers.Input((28, 28, 1))

outputs = tf.keras.layers.Flatten(name="flat")(inputs)

outputs = tf.keras.layers.Dense(

    512,

    #    activation='relu', #relu will be a problem here

    name = 'dense_1',

    kernel_initializer=tf.keras.initializers.GlorotUniform(seed=123),

    bias_initializer='zeros')(outputs)


outputs = tf.keras.layers.Dropout(0.2, name = 'dropout')(outputs)

mask = Lambda(getMask)(outputs)

#there isn't "input_mask"



#add the missing relu: 

outputs = tf.keras.layers.Activation('relu')(outputs)

outputs = tf.keras.layers.Dense(

    10,

    activation='softmax',

    name='dense_2',

    kernel_initializer=tf.keras.initializers.GlorotUniform(seed=123),

    bias_initializer='zeros')(outputs)


model = Model(inputs, outputs)

model.compile(...)

model.fit(...)

训练和预测

由于您无法训练掩码(这没有任何意义),因此不应将其作为训练模型的输出。


现在,我们可以试试这个:


trainingModel = Model(inputs, outputs)    

predictingModel = Model(inputs, [output, mask])    

但是预测中不存在掩码,因为 dropout 仅应用于训练。所以这最终不会给我们带来任何好处。


训练的唯一方法是使用虚拟损失和虚拟目标:


def dummyLoss(y_true, y_pred):

    return y_true #but this might evoke a "None" gradient problem since it's not trainable, there is no connection to any weights, etc.    


model.compile(loss=[loss_for_main_output, dummyLoss], ....)


model.fit(x_train, [y_train, np.zeros((len(y_Train),) + mask_shape), ...)

不能保证这些会起作用。


查看完整回答
反对 回复 2022-06-02
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

通过简单地扩展提供的 dropout 层,我找到了一种非常 hacky 的方法。(几乎所有来自TF的代码。)


class MyDR(tf.keras.layers.Layer):

def __init__(self,rate,**kwargs):

    super(MyDR, self).__init__(**kwargs)


    self.noise_shape = None

    self.rate = rate



def _get_noise_shape(self,x, noise_shape=None):

    # If noise_shape is none return immediately.

    if noise_shape is None:

        return array_ops.shape(x)

    try:

        # Best effort to figure out the intended shape.

        # If not possible, let the op to handle it.

        # In eager mode exception will show up.

        noise_shape_ = tensor_shape.as_shape(noise_shape)

    except (TypeError, ValueError):

        return noise_shape


    if x.shape.dims is not None and len(x.shape.dims) == len(noise_shape_.dims):

        new_dims = []

        for i, dim in enumerate(x.shape.dims):

            if noise_shape_.dims[i].value is None and dim.value is not None:

                new_dims.append(dim.value)

            else:

                new_dims.append(noise_shape_.dims[i].value)

        return tensor_shape.TensorShape(new_dims)


    return noise_shape


def build(self, input_shape):

    self.noise_shape = input_shape

    print(self.noise_shape)

    super(MyDR,self).build(input_shape)


@tf.function

def call(self,input):

    self.noise_shape = self._get_noise_shape(input)

    random_tensor = tf.random.uniform(self.noise_shape, seed=1235, dtype=input.dtype)

    keep_prob = 1 - self.rate

    scale = 1 / keep_prob

    # NOTE: if (1.0 + rate) - 1 is equal to rate, then we want to consider that

    # float to be selected, hence we use a >= comparison.

    self.keep_mask = random_tensor >= self.rate

    #NOTE: here is where I save the binary masks. 

    #the file grows quite big!

    tf.print(self.keep_mask,output_stream="file://temp/droput_mask.txt")


    ret = input * scale * math_ops.cast(self.keep_mask, input.dtype)

    return ret


查看完整回答
反对 回复 2022-06-02
  • 2 回答
  • 0 关注
  • 189 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号