使用Tensorflow 2.0模型子类化访问层的输入/输出

2024-05-26 20:47:26 发布

您现在位置:Python中文网/ 问答频道 /正文

在一次大学练习中,我使用了TF2.0的模型子分类API。以下是我的代码(这是Alexnet架构,如果你想知道的话…):

class MyModel(Model):
    def __init__(self):
        super(MyModel, self).__init__()
        # OPS
        self.relu = Activation('relu', name='ReLU')
        self.maxpool = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='valid', name='MaxPool')
        self.softmax = Activation('softmax', name='Softmax')

        # Conv layers
        self.conv1 = Conv2D(filters=96, input_shape=(224, 224, 3), kernel_size=(11, 11), strides=(4, 4), padding='same',
                            name='conv1')
        self.conv2a = Conv2D(filters=128, kernel_size=(5, 5), strides=(1, 1), padding='same', name='conv2a')
        self.conv2b = Conv2D(filters=128, kernel_size=(5, 5), strides=(1, 1), padding='same', name='conv2b')
        self.conv3 = Conv2D(filters=384, kernel_size=(3, 3), strides=(1, 1), padding='same', name='conv3')
        self.conv4a = Conv2D(filters=192, kernel_size=(3, 3), strides=(1, 1), padding='same', name='conv4a')
        self.conv4b = Conv2D(filters=192, kernel_size=(3, 3), strides=(1, 1), padding='same', name='conv4b')
        self.conv5a = Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding='same', name='conv5a')
        self.conv5b = Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding='same', name='conv5b')

        # Fully-connected layers

        self.flatten = Flatten()

        self.dense1 = Dense(4096, input_shape=(100,), name='FC_4096_1')
        self.dense2 = Dense(4096, name='FC_4096_2')
        self.dense3 = Dense(1000, name='FC_1000')

        # Network definition

    def call(self, x, **kwargs):
        x = self.conv1(x)
        x = self.relu(x)
        x = tf.nn.local_response_normalization(x, depth_radius=2, alpha=2e-05, beta=0.75, bias=1.0)
        x = self.maxpool(x)

        x = tf.concat((self.conv2a(x[:, :, :, :48]), self.conv2b(x[:, :, :, 48:])), 3)
        x = self.relu(x)
        x = tf.nn.local_response_normalization(x, depth_radius=2, alpha=2e-05, beta=0.75, bias=1.0)
        x = self.maxpool(x)

        x = self.conv3(x)
        x = self.relu(x)
        x = tf.concat((self.conv4a(x[:, :, :, :192]), self.conv4b(x[:, :, :, 192:])), 3)
        x = self.relu(x)
        x = tf.concat((self.conv5a(x[:, :, :, :192]), self.conv5b(x[:, :, :, 192:])), 3)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.flatten(x)

        x = self.dense1(x)
        x = self.relu(x)
        x = self.dense2(x)
        x = self.relu(x)
        x = self.dense3(x)
        return self.softmax(x)

我的目标是访问任意层的输出(为了最大化特定神经元的激活,如果你必须确切知道的话:)。问题是,试图访问任何层的输出时,都会得到一个属性错误。例如:

^{pr2}$

我在SO中发现了一些与此错误有关的问题,所有这些问题都声称我必须在第一层定义输入形状,但是正如您所见-已经完成了(请参见__init__函数中self.conv1的定义)!在

我确实发现,如果我定义一个keras.layers.Input对象,我确实能够得到conv1的输出,但是尝试访问更深层的层失败了,例如:

^{3}$

我在谷歌上搜索了路上遇到的所有例外情况,但没有找到答案。在这种情况下,如何访问任何层的输入/输出(或者顺便说一下,输入/输出形状属性)?在


Tags: nameselfsizeinittfkernelfiltersrelu
1条回答
网友
1楼 · 发布于 2024-05-26 20:47:26

在子类模型中没有层图,它只是一段代码(modelscall函数)。创建模型类的实例时未定义层连接。因此,我们需要首先通过调用call方法来构建模型。

请尝试以下操作:

model = MyModel()
inputs = tf.keras.Input(shape=(224,224,3))
model.call(inputs)
# instead of model(I) in your code.

完成此操作后,将创建模型图。在

^{pr2}$

相关问题 更多 >

    热门问题