Class 使用迁移学习激活地图
Class map activation with transfer learning
我正在使用 Resnet50 构建一个 CNN 模型来识别 classify 5 个对象。这些物体的图像是在我的桌子上拍摄的,所以每个物体都有我桌子的一部分。初始化模型的代码是这样的,
model = Sequential()
pretrained_model= tf.keras.applications.ResNet50(include_top=False,
input_shape=(180,180,3),
pooling='avg',classes=5,
weights='imagenet')
for layer in pretrained_model.layers:
layer.trainable=False
model.add(pretrained_model)
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(2, activation='softmax'))
我编译了模型并对其进行了拟合,它按预期工作。
模型运行不佳,预测不是很准确。我怀疑模型是在我办公桌的那部分进行训练的,我想使用 class 激活图来了解这是否属实。
我看过的教程有 class 个从头开始构建的模型的激活图代码。我知道我们需要添加一个全局平均池化层,然后添加一个具有 softmax
激活的致密层以启用 class 激活。
Resnet50 模型以我通过 运行、
发现的全局平均池化层结尾
pretrained_model.layers
所以我只需要添加由 运行、
添加的致密层
model.add(pretrained_model)
model.add(Dense(2, activation='softmax'))
但是当我打印出这个模型的摘要时,我得到,
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50 (Functional) (None, 2048) 23587712
_________________________________________________________________
dense_3 (Dense) (None, 2) 4098
=================================================================
Total params: 23,591,810
Trainable params: 4,098
Non-trainable params: 23,587,712
我正在关注 Laurence Moroney 的 example,他说我们必须从全局平均池化层和密集层中提取权重,而我无法使用我刚刚创建的模型。
有没有办法扩展resnet50 (Functional)
层来访问全局平均池化层?
编辑
我在这里继续我的查询,因为它是我实际问题的一部分,即启用 class 具有迁移学习的激活图。
如评论中所述,我可以通过提供获得最后一个卷积层,
model.layers[0].layers[-5]
获得密集层和最后一个卷积层的权重后,我尝试创建cam_model,像这样,
cam_model = Model(inputs=(model.layers[0].layers[0].input), outputs=(model.layers[0].layers[-5].output, model.layers[1].output))
导致此错误,
ValueError: Graph disconnected: cannot obtain value for tensor KerasTensor(type_spec=TensorSpec(shape=(None, 180, 180, 3), dtype=tf.float32, name='resnet50_input'), name='resnet50_input', description="created by layer 'resnet50_input'") at layer "resnet50". The following previous layers were accessed without issue: ['conv1_pad', 'conv1_conv', 'conv1_bn', 'conv1_relu', 'pool1_pad', 'pool1_pool', 'conv2_block1_1_conv', 'conv2_block1_1_bn', 'conv2_block1_1_relu', 'conv2_block1_2_conv', 'conv2_block1_2_bn', 'conv2_block1_2_relu', 'conv2_block1_3_conv', 'conv2_block1_0_conv', 'conv2_block1_0_bn', 'conv2_block1_3_bn', 'conv2_block1_add', 'conv2_block1_out', 'conv2_block2_1_conv', 'conv2_block2_1_bn', 'conv2_block2_1_relu', 'conv2_block2_2_conv', 'conv2_block2_2_bn', 'conv2_block2_2_relu', 'conv2_block2_3_conv', 'conv2_block2_3_bn', 'conv2_block2_add', 'conv2_block2_out', 'conv2_block3_1_conv', 'conv2_block3_1_bn', 'conv2_block3_1_relu', 'conv2_block3_2_conv', 'conv2_block3_2_bn', 'conv2_block3_2_relu', 'conv2_block3_3_conv', 'conv2_block3_3_bn', 'conv2_block3_add', 'conv2_block3_out', 'conv3_block1_1_conv', 'conv3_block1_1_bn', 'conv3_block1_1_relu', 'conv3_block1_2_conv', 'conv3_block1_2_bn', 'conv3_block1_2_relu', 'conv3_block1_3_conv', 'conv3_block1_0_conv', 'conv3_block1_0_bn', 'conv3_block1_3_bn', 'conv3_block1_add', 'conv3_block1_out', 'conv3_block2_1_conv', 'conv3_block2_1_bn', 'conv3_block2_1_relu', 'conv3_block2_2_conv', 'conv3_block2_2_bn', 'conv3_block2_2_r...
我的model.summary
是这样的,
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50 (Functional) (None, 2048) 23587712
_________________________________________________________________
dense (Dense) (None, 5) 10245
=================================================================
Total params: 23,597,957
Trainable params: 10,245
Non-trainable params: 23,587,712
我的model.layers[0].summary()
的前几层是这样的,
Model: "resnet50"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_2 (InputLayer) [(None, 180, 180, 3) 0
__________________________________________________________________________________________________
conv1_pad (ZeroPadding2D) (None, 186, 186, 3) 0 input_2[0][0]
__________________________________________________________________________________________________
conv1_conv (Conv2D) (None, 90, 90, 64) 9472 conv1_pad[0][0]
__________________________________________________________________________________________________
我认为图表在 resnet50
层断开连接,但我不知道在哪里可以找到它。有人可以帮忙吗
要打印出 resnet
模型的图层,试试这个:model.layers[0].summary()
。如果你想访问 GlobalAveragePooling
层,它恰好是模型的最后一层,那么试试这个:
global_max_pooling = model.layers[0].layers[-1]
。但是请注意,GlobalAveragePooling
层本身没有任何权重。
我正在使用 Resnet50 构建一个 CNN 模型来识别 classify 5 个对象。这些物体的图像是在我的桌子上拍摄的,所以每个物体都有我桌子的一部分。初始化模型的代码是这样的,
model = Sequential()
pretrained_model= tf.keras.applications.ResNet50(include_top=False,
input_shape=(180,180,3),
pooling='avg',classes=5,
weights='imagenet')
for layer in pretrained_model.layers:
layer.trainable=False
model.add(pretrained_model)
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(2, activation='softmax'))
我编译了模型并对其进行了拟合,它按预期工作。
模型运行不佳,预测不是很准确。我怀疑模型是在我办公桌的那部分进行训练的,我想使用 class 激活图来了解这是否属实。
我看过的教程有 class 个从头开始构建的模型的激活图代码。我知道我们需要添加一个全局平均池化层,然后添加一个具有 softmax
激活的致密层以启用 class 激活。
Resnet50 模型以我通过 运行、
发现的全局平均池化层结尾pretrained_model.layers
所以我只需要添加由 运行、
添加的致密层model.add(pretrained_model)
model.add(Dense(2, activation='softmax'))
但是当我打印出这个模型的摘要时,我得到,
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50 (Functional) (None, 2048) 23587712
_________________________________________________________________
dense_3 (Dense) (None, 2) 4098
=================================================================
Total params: 23,591,810
Trainable params: 4,098
Non-trainable params: 23,587,712
我正在关注 Laurence Moroney 的 example,他说我们必须从全局平均池化层和密集层中提取权重,而我无法使用我刚刚创建的模型。
有没有办法扩展resnet50 (Functional)
层来访问全局平均池化层?
编辑
我在这里继续我的查询,因为它是我实际问题的一部分,即启用 class 具有迁移学习的激活图。
如评论中所述,我可以通过提供获得最后一个卷积层,
model.layers[0].layers[-5]
获得密集层和最后一个卷积层的权重后,我尝试创建cam_model,像这样,
cam_model = Model(inputs=(model.layers[0].layers[0].input), outputs=(model.layers[0].layers[-5].output, model.layers[1].output))
导致此错误,
ValueError: Graph disconnected: cannot obtain value for tensor KerasTensor(type_spec=TensorSpec(shape=(None, 180, 180, 3), dtype=tf.float32, name='resnet50_input'), name='resnet50_input', description="created by layer 'resnet50_input'") at layer "resnet50". The following previous layers were accessed without issue: ['conv1_pad', 'conv1_conv', 'conv1_bn', 'conv1_relu', 'pool1_pad', 'pool1_pool', 'conv2_block1_1_conv', 'conv2_block1_1_bn', 'conv2_block1_1_relu', 'conv2_block1_2_conv', 'conv2_block1_2_bn', 'conv2_block1_2_relu', 'conv2_block1_3_conv', 'conv2_block1_0_conv', 'conv2_block1_0_bn', 'conv2_block1_3_bn', 'conv2_block1_add', 'conv2_block1_out', 'conv2_block2_1_conv', 'conv2_block2_1_bn', 'conv2_block2_1_relu', 'conv2_block2_2_conv', 'conv2_block2_2_bn', 'conv2_block2_2_relu', 'conv2_block2_3_conv', 'conv2_block2_3_bn', 'conv2_block2_add', 'conv2_block2_out', 'conv2_block3_1_conv', 'conv2_block3_1_bn', 'conv2_block3_1_relu', 'conv2_block3_2_conv', 'conv2_block3_2_bn', 'conv2_block3_2_relu', 'conv2_block3_3_conv', 'conv2_block3_3_bn', 'conv2_block3_add', 'conv2_block3_out', 'conv3_block1_1_conv', 'conv3_block1_1_bn', 'conv3_block1_1_relu', 'conv3_block1_2_conv', 'conv3_block1_2_bn', 'conv3_block1_2_relu', 'conv3_block1_3_conv', 'conv3_block1_0_conv', 'conv3_block1_0_bn', 'conv3_block1_3_bn', 'conv3_block1_add', 'conv3_block1_out', 'conv3_block2_1_conv', 'conv3_block2_1_bn', 'conv3_block2_1_relu', 'conv3_block2_2_conv', 'conv3_block2_2_bn', 'conv3_block2_2_r...
我的model.summary
是这样的,
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50 (Functional) (None, 2048) 23587712
_________________________________________________________________
dense (Dense) (None, 5) 10245
=================================================================
Total params: 23,597,957
Trainable params: 10,245
Non-trainable params: 23,587,712
我的model.layers[0].summary()
的前几层是这样的,
Model: "resnet50"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_2 (InputLayer) [(None, 180, 180, 3) 0
__________________________________________________________________________________________________
conv1_pad (ZeroPadding2D) (None, 186, 186, 3) 0 input_2[0][0]
__________________________________________________________________________________________________
conv1_conv (Conv2D) (None, 90, 90, 64) 9472 conv1_pad[0][0]
__________________________________________________________________________________________________
我认为图表在 resnet50
层断开连接,但我不知道在哪里可以找到它。有人可以帮忙吗
要打印出 resnet
模型的图层,试试这个:model.layers[0].summary()
。如果你想访问 GlobalAveragePooling
层,它恰好是模型的最后一层,那么试试这个:
global_max_pooling = model.layers[0].layers[-1]
。但是请注意,GlobalAveragePooling
层本身没有任何权重。