【问题标题】:Add a Truncated layer in Functional API model在功能 API 模型中添加截断层
【发布时间】:2021-04-14 01:59:46
【问题描述】:

我正在尝试在以下代码中的 Conv2D 层之后添加截断层:

input_layer = Input(shape=(256, 256, 1))
conv = Conv2D(8, (5, 5), padding='same', strides=1, use_bias=False)(input_layer)
output_layer = Activation(activation='tanh')(lambda_layer)
output_layer = AveragePooling2D(pool_size= (5, 5), strides=2)(output_layer)
output_layer = BatchNormalization()(output_layer)

截断层必须满足:

−T if x < −T
x if −T ≤ x ≤ T
T  x > T 

where `T` is a threshold value, x= the output of convolution layer`

有人可以帮我建立这个层吗?

谢谢

【问题讨论】:

    标签: python tensorflow keras conv-neural-network keras-layer


    【解决方案1】:

    您可以使用tf.clip_by_valuetf.stop_gradient 来保留渐变,因为tf.clip_by_value 不可微分。最后,将其包裹在 Lambda 层中:

    import functools
    def clip_preserve_grad(inp, clip_min, clip_max):
      return inp + tf.stop_gradient(tf.clip_by_value(inp, clip_min, clip_max) - inp)
    
    T = 0.5
    trunc_func = functools.partial(clip_preserve_grad, clip_min=-T, clip_max=T)
    trunc = tf.keras.layers.Lambda(trunc_func)
    

    使用 Lambda 层:

    >>> a = tf.random.normal((1,10))
    >>> a
    <tf.Tensor: shape=(1, 10), dtype=float32, numpy=
    array([[-1.8041286 , -0.11153453, -0.84555113,  0.8489615 ,  0.12237629,
             1.3350475 ,  0.619644  , -0.5498301 , -0.6082269 ,  0.8465021 ]],
          dtype=float32)>
    >>> trunc(a)
    <tf.Tensor: shape=(1, 10), dtype=float32, numpy=
    array([[-0.5       , -0.11153453, -0.5       ,  0.5       ,  0.12237629,
             0.5       ,  0.5       , -0.5       , -0.5       ,  0.5       ]],
          dtype=float32)>
    

    【讨论】:

      【解决方案2】:

      您可以使用tensorflow.keras.backed.switch 构建所需的函数并将其包装在Lambda 层中

      构建和测试函数:

      T = 5
      X = tf.constant(np.random.uniform(-10, 10, (3,5)))
      
      def switch_func(X, T):
          
          zeros = tf.zeros_like(X)
          T_matrix = tf.ones_like(X) * T
      
          cond1 = K.switch(X < -T_matrix, -T_matrix, zeros)
          cond2 = K.switch(X > T_matrix, T_matrix, zeros)
          cond3 = K.switch(tf.abs(cond1 + cond2) == T, zeros, X)
          res = cond1 + cond2 + cond3
          return res
      
      switch_func(X, T)
      
      <tf.Tensor: shape=(3, 5), dtype=float64, numpy=
      array([[-5.        ,  0.65807168, -4.93481499, -5.        , -2.94954848],
             [-1.25114075, -5.        ,  2.97657545,  5.        , -0.8958152 ],
             [-1.26611956,  5.        , -3.38477137,  5.        , -3.53358454]])>
      

      模型内部的用法:

      X = np.random.uniform(0,1, (100,10))
      y = np.random.uniform(0,1, (100,))
      
      inp = Input((10,))
      x = Dense(8)(inp)
      x = Lambda(lambda x: switch_func(x, T=0.5))(x)
      out = Dense(1)(x)
      
      model = Model(inp, out)
      model.compile('adam', 'mse')
      model.fit(X,y, epochs=3)
      

      【讨论】:

      • 谢谢 Marco Cerliani,您的回答正是我所需要的。
      猜你喜欢
      • 2021-03-07
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-16
      • 2018-07-18
      • 2011-02-25
      相关资源
      最近更新 更多