2 回答

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超9個(gè)贊
它在 Keras 中并不容易暴露。它深入到它調(diào)用 TensorFlow 輟學(xué)。
所以,雖然你使用的是 Keras,但它也將是圖中的一個(gè)張量,可以通過(guò)名稱獲?。ㄕ业剿拿Q:在 Tensorflow 中,獲取圖中所有張量的名稱)。
這個(gè)選項(xiàng)當(dāng)然會(huì)缺少一些 keras 信息,您可能必須在 Lambda 層內(nèi)執(zhí)行此操作,以便 Keras 將某些信息添加到張量。而且您必須格外小心,因?yàn)榧词共挥?xùn)練(跳過(guò)掩碼),張量也會(huì)存在
現(xiàn)在,您還可以使用不那么 hacky 的方式,這可能會(huì)消耗一些處理:
def getMask(x):
boolMask = tf.not_equal(x, 0)
floatMask = tf.cast(boolMask, tf.float32) #or tf.float64
return floatMask
用一個(gè)Lambda(getMasc)(output_of_dropout_layer)
Sequential但是,您將需要一個(gè)功能性 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(...)
訓(xùn)練和預(yù)測(cè)
由于您無(wú)法訓(xùn)練掩碼(這沒有任何意義),因此不應(yīng)將其作為訓(xùn)練模型的輸出。
現(xiàn)在,我們可以試試這個(gè):
trainingModel = Model(inputs, outputs)
predictingModel = Model(inputs, [output, mask])
但是預(yù)測(cè)中不存在掩碼,因?yàn)?dropout 僅應(yīng)用于訓(xùn)練。所以這最終不會(huì)給我們帶來(lái)任何好處。
訓(xùn)練的唯一方法是使用虛擬損失和虛擬目標(biāo):
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), ...)
不能保證這些會(huì)起作用。

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超6個(gè)贊
通過(guò)簡(jiǎn)單地?cái)U(kuò)展提供的 dropout 層,我找到了一種非常 hacky 的方法。(幾乎所有來(lái)自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
添加回答
舉報(bào)