### MobileNet V1, V2 和 V3 的源码实现
MobileNet 是一种轻量级卷积神经网络架构,广泛应用于移动设备和嵌入式系统中的图像分类和其他视觉任务。以下是关于 MobileNet V1、V2 和 V3 的源码实现的相关信息。
#### MobileNet V1 实现
MobileNet V1 使用深度可分离卷积来减少计算复杂度并提高效率。官方 TensorFlow 实现提供了详细的代码结构[^3]:
```python
import tensorflow as tf
def depthwise_conv(input_tensor, kernel_size, strides=1, padding='same'):
return tf.keras.layers.DepthwiseConv2D(kernel_size, strides=strides, padding=padding)(input_tensor)
def pointwise_conv(input_tensor, filters, kernel_size=(1, 1), strides=1, padding='same'):
return tf.keras.layers.Conv2D(filters, kernel_size, strides=strides, padding=padding)(input_tensor)
def mobilenet_v1_block(input_tensor, filters, kernel_size=(3, 3)):
x = depthwise_conv(input_tensor, kernel_size)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.ReLU()(x)
x = pointwise_conv(x, filters)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.ReLU()(x)
return x
```
#### MobileNet V2 实现
MobileNet V2 引入了倒残差结构 (Inverted Residuals),通过扩展通道数后再压缩的方式提升性能。TensorFlow 提供了完整的实现[^4]:
```python
def inverted_residual_block(input_tensor, expansion_factor, output_channels, stride=1):
input_channels = input_tensor.shape[-1]
expanded_channels = int(expansion_factor * input_channels)
# Expansion phase
x = tf.keras.layers.Conv2D(expanded_channels, (1, 1))(input_tensor)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.ReLU(6.0)(x)
# Depthwise convolution
x = tf.keras.layers.DepthwiseConv2D((3, 3), strides=stride, padding="same")(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.ReLU(6.0)(x)
# Projection phase
x = tf.keras.layers.Conv2D(output_channels, (1, 1))(x)
x = tf.keras.layers.BatchNormalization()(x)
if stride == 1 and input_channels == output_channels:
x = tf.keras.layers.Add()([x, input_tensor])
return x
```
#### MobileNet V3 实现
MobileNet V3 进一步优化了模型设计,引入了 Squeeze-and-Excite 模块以增强特征表达能力。PyTorch 官方实现了该版本[^5]:
```python
class SEBlock(tf.keras.layers.Layer):
def __init__(self, input_channels, r=4):
super(SEBlock, self).__init__()
self.squeeze = tf.keras.layers.GlobalAveragePooling2D()
self.excitation = tf.keras.Sequential([
tf.keras.layers.Dense(input_channels // r, activation='relu'),
tf.keras.layers.Dense(input_channels, activation='sigmoid')
])
def call(self, inputs):
x = self.squeeze(inputs)
x = self.excitation(x)
return inputs * tf.reshape(x, [-1, 1, 1, inputs.shape[-1]])
def mobilenet_v3_block(input_tensor, expansion_factor, output_channels, use_se=False, stride=1):
x = inverted_residual_block(input_tensor, expansion_factor, output_channels, stride)
if use_se:
x = SEBlock(output_channels)(x)
return x
```
以上代码片段分别展示了 MobileNet 不同版本的核心模块实现方式。