การแบ่งคลาสย่อยเลเยอร์ Keras: ตัวแปรต่อไปนี้ใช้การเรียกของเลเยอร์ Lambda แต่ไม่มีอยู่ในออบเจ็กต์ที่ถูกติดตาม

ฉันกำลังสร้างเลเยอร์ Convolutional แบบกำหนดเองโดย คลาสย่อย Keras Layer ฉันทำสิ่งนี้กับ Tensorflow เวอร์ชันก่อนหน้า และไม่ได้รับคำเตือน:

import tensorflow as tf


class MyCustomLayer(tf.Module):
    def __init__(self, in_channels,
                 filters,
                 kernel_size,
                 padding,
                 strides,
                 activation,
                 kernel_initializer,
                 bias_initializer,
                 use_bias):
        super(MyCustomLayer, self).__init__()
        self.filters = filters
        self.kernel_size = kernel_size
        self.activation = activation
        self.padding = padding
        self.kernel_initializer = kernel_initializer
        self.bias_initializer = bias_initializer
        self.strides = strides
        self.use_bias = use_bias
        self.in_channels = in_channels

        self.w = tf.Variable(
            initial_value=self.kernel_initializer(shape=(*self.kernel_size,
                                                         in_channels,
                                                         self.filters),
                                 dtype='float32'), trainable=True)
        if self.use_bias:
            self.b = tf.Variable(
                initial_value=self.bias_initializer(shape=(self.filters,),
                                                    dtype='float32'),
                trainable=True)

    def __call__(self, inputs, training=None):
        x =  tf.nn.conv2d(inputs,
                          filters=self.w,
                          strides=self.strides,
                          padding=self.padding)
        if self.use_bias:
            x = tf.add(x, self.b)
        x = self.activation(x)
        return x


x = tf.keras.Input(shape=(28, 28, 3))
y = MyCustomLayer(
            in_channels=3,
            filters=16,
            kernel_size=(3, 3),
            strides=(1, 1),
            activation=tf.nn.relu,
            padding='VALID',
            kernel_initializer=tf.initializers.GlorotUniform(),
            bias_initializer=tf.initializers.Zeros(),
            use_bias=True)(x)
model = tf.keras.Model(inputs=x, outputs=y)

ฉันได้รับคำเตือนนี้ด้วย tf.__version__ == 2.4.1:

คำเตือน: เทนเซอร์โฟลว์: ตัวแปรต่อไปนี้ใช้การเรียกของเลเยอร์ Lambda (tf.compat.v1.nn.conv2d_12) แต่ไม่มีอยู่ในออบเจ็กต์ที่ถูกติดตาม: ‹tf.Variable 'Variable:0' shape=(3, 3, 3, 16) dtype=float32› อาจเป็นไปได้ว่านี่เป็นพฤติกรรมที่ตั้งใจไว้ แต่มีแนวโน้มว่าจะเป็นการละเลยมากกว่า นี่เป็นข้อบ่งชี้ที่ชัดเจนว่าเลเยอร์นี้ควรถูกกำหนดให้เป็นเลเยอร์ย่อยแทนที่จะเป็นเลเยอร์ Lambda

คำเตือน: เทนเซอร์โฟลว์: ตัวแปรต่อไปนี้ใช้การเรียกของเลเยอร์ Lambda (tf.math.add_2) แต่ไม่มีอยู่ในออบเจ็กต์ที่ถูกติดตาม: ‹tf.Variable 'Variable:0' shape=(16,) dtype=float32› It เป็นไปได้ว่านี่เป็นพฤติกรรมที่ตั้งใจไว้ แต่มีแนวโน้มที่จะเป็นการละเลยมากกว่า นี่เป็นข้อบ่งชี้ที่ชัดเจนว่าเลเยอร์นี้ควรถูกกำหนดให้เป็นเลเยอร์ย่อยแทนที่จะเป็นเลเยอร์ Lambda

สิ่งนี้หมายความว่า? ฉัน กำลัง ใช้เลเยอร์ย่อย


person Nicolas Gervais    schedule 30.03.2021    source แหล่งที่มา
comment
คุณได้แก้ไขปัญหานี้โดยบังเอิญหรือไม่?   -  person Rahil Kadakia    schedule 04.06.2021


คำตอบ (1)


นี่คือคำแนะนำบางอย่าง ฉันพบบล็อกที่มีการกล่าวถึงเรื่องนี้ . มันระบุ

tf.keras.Lambda: โปรดทราบว่าหากตัวแปรเกี่ยวข้องกับเลเยอร์ที่สร้างโดยวิธีนี้ ตัวแปรจะไม่ถูกเพิ่มลงในชุดตัวแปรสำหรับการคำนวณการไล่ระดับสีโดยอัตโนมัติ ดังนั้น หากมีพารามิเตอร์ที่ต้องฝึกในเลเยอร์ที่ผู้ใช้กำหนด ขอแนะนำให้ปรับแต่งเลเยอร์โมเดลตามคลาสพื้นฐาน

พวกเขาแสดงให้เห็น

weights = tf.Variable(tf.random.normal((4, 2)), name='w')
bias = tf.ones((1, 2), name='b')
print(bias)
x_input = tf.range(12.).numpy().reshape(-1, 4)

# lambda custom layer
mylayer1 = tf.keras.layers.Lambda(lambda x: tf.add(tf.matmul(x, weights),
                                                           bias), name='lambda1')
mylayer1(x_input)

tf.Tensor([[1. 1.]], shape=(1, 2), dtype=float32)
WARNING:tensorflow:
The following Variables were used a Lambda layer's call (lambda1), but
are not present in its tracked objects:
  <tf.Variable 'w:0' shape=(4, 2) dtype=float32, numpy=
array([[ 2.54332  ,  1.5078725],
       [ 0.5291851, -1.1049112],
       [ 1.475109 , -1.6525942],
       [ 1.593746 , -0.4049823]], dtype=float32)>
It is possible that this is intended behavior, but it is more likely
an omission. This is a strong indication that this layer should be
formulated as a subclassed Layer rather than a Lambda layer.
<tf.Tensor: shape=(3, 2), dtype=float32, numpy=
array([[  9.260641 ,  -4.6250463],
       [ 33.82608  , -11.243508 ],
       [ 58.391525 , -17.861969 ]], dtype=float32)>

พวกเขายังแสดงวิธีเลี่ยงคำเตือนด้วย แต่ฉันไม่แน่ใจ (ยัง) จะทำอย่างไรเพื่อหลีกเลี่ยงในกรณีของคุณ การสำรวจอย่างรวดเร็วเกี่ยวกับซอร์สโค้ดของ tf.compat.v1.nn.conv2d นำไปสู่ ​​lambda ที่อาจเป็นสาเหตุ

 def build_op(num_spatial_dims, padding):
    return lambda inp, _: op(inp, num_spatial_dims, padding)
person M.Innat    schedule 30.03.2021