好的,以下是使用 TensorFlow 定义一个 CBAM 模型的示例代码:
```python
import tensorflow as tf
def channel_attention(inputs, ratio=8):
# 获取输入张量的形状
shape = tf.keras.backend.int_shape(inputs)
# 计算通道数
channels = shape[-1]
# 平均池化
avg_pool = tf.keras.layers.GlobalAveragePooling2D()(inputs)
# 全连接层1
fc1 = tf.keras.layers.Dense(channels // ratio, activation='relu')(avg_pool)
# 全连接层2
fc2 = tf.keras.layers.Dense(channels, activation='sigmoid')(fc1)
# 重塑张量形状
fc2 = tf.keras.layers.Reshape((1, 1, channels))(fc2)
# 相乘
output = tf.keras.layers.multiply([inputs, fc2])
return output
def spatial_attention(inputs, kernel_size=7):
# 空间最大池化
max_pool = tf.keras.layers.MaxPool2D(pool_size=(kernel_size, kernel_size), strides=(1, 1), padding='same')(inputs)
# 空间平均池化
avg_pool = tf.keras.layers.AveragePooling2D(pool_size=(kernel_size, kernel_size), strides=(1, 1), padding='same')(inputs)
# 拼接池化结果
concat = tf.keras.layers.Concatenate(axis=-1)([max_pool, avg_pool])
# 全连接层
output = tf.keras.layers.Conv2D(filters=1, kernel_size=(1, 1), activation='sigmoid', padding='same')(concat)
return output
def cbam_block(inputs, ratio=8, kernel_size=7):
# 通道注意力机制
channel = channel_attention(inputs, ratio)
# 空间注意力机制
spatial = spatial_attention(inputs, kernel_size)
# 相乘
output = tf.keras.layers.multiply([channel, spatial])
return output
def cbam_model(input_shape=(224, 224, 3), num_classes=1000):
# 输入层
inputs = tf.keras.layers.Input(shape=input_shape)
# 卷积层1
x = tf.keras.layers.Conv2D(filters=64, kernel_size=(7, 7), strides=(2, 2), padding='same', activation='relu')(inputs)
# 池化层1
x = tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x)
# CBAM模块1
x = cbam_block(x, ratio=16, kernel_size=7)
# 卷积层2
x = tf.keras.layers.Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(x)
# CBAM模块2
x = cbam_block(x, ratio=16, kernel_size=7)
# 池化层2
x = tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x)
# 卷积层3
x = tf.keras.layers.Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(x)
# CBAM模块3
x = cbam_block(x, ratio=16, kernel_size=7)
# 卷积层4
x = tf.keras.layers.Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(x)
# CBAM模块4
x = cbam_block(x, ratio=16, kernel_size=7)
# 池化层3
x = tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x)
# 卷积层5
x = tf.keras.layers.Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(x)
# CBAM模块5
x = cbam_block(x, ratio=16, kernel_size=7)
# 卷积层6
x = tf.keras.layers.Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(x)
# CBAM模块6
x = cbam_block(x, ratio=16, kernel_size=7)
# 池化层4
x = tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x)
# 卷积层7
x = tf.keras.layers.Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(x)
# CBAM模块7
x = cbam_block(x, ratio=16, kernel_size=7)
# 卷积层8
x = tf.keras.layers.Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(x)
# CBAM模块8
x = cbam_block(x, ratio=16, kernel_size=7)
# 池化层5
x = tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x)
# 全局平均池化
x = tf.keras.layers.GlobalAveragePooling2D()(x)
# 全连接层1
x = tf.keras.layers.Dense(2048, activation='relu')(x)
# 全连接层2
x = tf.keras.layers.Dense(2048, activation='relu')(x)
# 输出层
outputs = tf.keras.layers.Dense(num_classes, activation='softmax')(x)
# 定义模型
model = tf.keras.models.Model(inputs=inputs, outputs=outputs)
return model
```
以上代码定义了一个简单的 CBAM 模型,包括通道注意力机制和空间注意力机制。在模型中,我们使用了 8 个 CBAM 模块,每个模块包含两个注意力机制。模型输入形状为 (224, 224, 3),输出为 num_classes 个类别的概率分布。