从keras dropout层中提取dropout mask?

我想在训练时从每个批次的顺序 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 mask


model.add(dropout)

x = dropout.output_mask

y = dropout.input_mask

model.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(...)


喵喵时光机
浏览 190回答 2
2回答

千万里不及你

它在 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), ...)不能保证这些会起作用。

哈士奇WWW

通过简单地扩展提供的 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 = ratedef _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_shapedef build(self, input_shape):    self.noise_shape = input_shape    print(self.noise_shape)    super(MyDR,self).build(input_shape)@tf.functiondef 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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python