我按照教程构建了一个用于解决我问题的孪生网络。我之前使用的是Tensorflow 2.4.1,现在进行了升级
之前这段代码运行得很好
base_cnn = resnet.ResNet50( weights="imagenet", input_shape=target_shape + (3,), include_top=False)flatten = layers.Flatten()(base_cnn.output)dense1 = layers.Dense(512, activation="relu")(flatten)dense1 = layers.BatchNormalization()(dense1)dense2 = layers.Dense(256, activation="relu")(dense1)dense2 = layers.BatchNormalization()(dense2)output = layers.Dense(256)(dense2)embedding = Model(base_cnn.input, output, name="Embedding")trainable = Falsefor layer in base_cnn.layers: if layer.name == "conv5_block1_out": trainable = True layer.trainable = trainable
现在,每个ResNet层或者MobileNet或EfficientNet(我都尝试过了)都会抛出这些错误:
WARNING:tensorflow:The following Variables were used a Lambda layer's call (tf.nn.convolution_620), butare not present in its tracked objects: <tf.Variable 'stem_conv/kernel:0' shape=(3, 3, 3, 48) dtype=float32>It is possible that this is intended behavior, but it is more likelyan omission. This is a strong indication that this layer should beformulated as a subclassed Layer rather than a Lambda layer.
它可以编译并且看起来可以拟合。
但是在2.5版本中,我们是否需要以某种不同的方式初始化模型?
感谢任何建议!
回答:
我不确定您的问题的主要原因是什么,因为它通常无法重现。但这里有一些关于该警告信息的说明。您的问题中显示的堆栈跟踪不是来自ResNet
,而是来自EfficientNet
。
现在,我们知道Lambda
层的存在是为了在构建顺序和功能API模型时,可以将任意表达式用作Layer
。Lambda
层最适合简单操作或快速实验。虽然可以将变量与Lambda层一起使用,但这种做法是被不鼓励的,因为它很容易导致错误。例如:
import tensorflow as tf x_input = tf.range(12.).numpy().reshape(-1, 4)weights = tf.Variable(tf.random.normal((4, 2)), name='w')bias = tf.ones((1, 2), name='b')# lambda custom layermylayer1 = tf.keras.layers.Lambda(lambda x: tf.add(tf.matmul(x, weights), bias), name='lambda1')mylayer1(x_input)
WARNING:tensorflow:The following Variables were used a Lambda layer's call (lambda1), butare not present in its tracked objects: <tf.Variable 'w:0' shape=(4, 2) dtype=float32, numpy=array([[-0.753139 , -1.1668463 ], [-1.3709341 , 0.8887151 ], [ 0.3157893 , 0.01245957], [-1.3878908 , -0.38395467]], dtype=float32)>It is possible that this is intended behavior, but it is more likelyan omission. This is a strong indication that this layer should beformulated as a subclassed Layer rather than a Lambda layer.<tf.Tensor: shape=(3, 2), dtype=float32, numpy=array([[ -3.903028 , 0.7617702], [-16.687727 , -1.8367348], [-29.472424 , -4.43524 ]], dtype=float32)>
这是因为mylayer1
层没有直接追踪tf.Variables
,因此这些参数不会出现在mylayer1.trainable_weights
中。
mylayer1.trainable_weights[]
一般来说,Lambda
层对于简单的无状态计算可能很方便,但任何更复杂的操作都应该使用子类Layer。从您的堆栈跟踪来看,似乎存在与step_conv
层类似的可能情况。
for layer in EfficientNetB0(weights=None).layers: if layer.name == 'stem_conv': print(layer)<tensorflow.python.keras.layers.convolutional.Conv2D object..
快速调查tf.compat.v1.nn.conv2d的源代码,发现了一个可能导致问题的lambda表达式。