Mensubklasifikasikan Lapisan Keras: Variabel berikut menggunakan panggilan lapisan Lambda, namun tidak ada dalam objek yang dilacaknya

Saya membuat lapisan konvolusional khusus dengan mensubklasifikasikan Lapisan Keras. Saya melakukan ini dengan Tensorflow versi sebelumnya, dan tidak menerima peringatan:

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)

Saya mendapat peringatan ini, dengan tf.__version__ == 2.4.1:

PERINGATAN:tensorflow: Variabel berikut digunakan panggilan lapisan Lambda (tf.compat.v1.nn.conv2d_12), tetapi tidak ada dalam objek yang dilacak: ‹tf.Variable 'Variable:0' shape=(3, 3, 3, 16) dtype=float32› Ada kemungkinan bahwa ini adalah perilaku yang disengaja, namun lebih mungkin merupakan kelalaian. Ini merupakan indikasi kuat bahwa lapisan ini harus diformulasikan sebagai Lapisan subkelas dan bukan lapisan Lambda.

PERINGATAN:tensorflow: Variabel berikut digunakan panggilan lapisan Lambda (tf.math.add_2), tetapi tidak ada dalam objek yang dilacak: ‹tf.Variable 'Variable:0' shape=(16,) dtype=float32› It Ada kemungkinan bahwa ini adalah perilaku yang disengaja, namun kemungkinan besar ini adalah kelalaian. Ini merupakan indikasi kuat bahwa lapisan ini harus diformulasikan sebagai Lapisan subkelas dan bukan lapisan Lambda.

Apa artinya ini? Saya saya menggunakan Lapisan subkelas.


person Nicolas Gervais    schedule 30.03.2021    source sumber
comment
Apakah Anda kebetulan memecahkan masalah ini?   -  person Rahil Kadakia    schedule 04.06.2021


Jawaban (1)


Berikut ini beberapa petunjuk. Saya menemukan blog yang membahas hal ini . Ini menyatakan

tf.keras.Lambda: Perhatikan bahwa jika variabel terlibat dalam lapisan yang dibuat dengan metode ini, variabel tersebut tidak akan secara otomatis ditambahkan ke kumpulan variabel untuk penghitungan gradien. Oleh karena itu, jika ada parameter yang akan dilatih pada lapisan yang ditentukan pengguna, disarankan untuk menyesuaikan lapisan model berdasarkan kelas dasar.

Mereka menunjukkan

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)>

Mereka juga menunjukkan cara untuk mengabaikan peringatan tersebut. Tapi saya (belum) yakin apa yang bisa dilakukan untuk mengatasi kasus Anda. Survei singkat tentang kode sumber tf.compat.v1.nn.conv2d, mengarah ke lambda yang mungkin menjadi penyebabnya.

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