深度可分离卷积

深度可分离卷积

深度可分离卷积是一种高效的卷积操作,它将传统的卷积操作分解为两个部分:深度卷积和逐点卷积。

深度卷积

深度卷积涉及对输入特征图的每个通道独立应用单个卷积核。这与传统卷积不同,后者在所有输入通道上应用卷积核。深度卷积的输出是一组分离的特征图,每个通道一个。

逐点卷积

逐点卷积是一个 1x1 的卷积,用于将深度卷积的输出通道组合和混合。这可以看作是在深度卷积生成的每个像素点上应用一个全连接层。

优势

深度可分离卷积的主要优势在于它大幅减少了模型的参数数量和计算需求。深度卷积独立处理每个输入通道,而逐点卷积负责组合这些通道的特征,这样的分解方式比标准卷积更加高效。

深度可分离卷积的非零计算结果例子

我们考虑一个 4x4x2 的输入特征图,进行深度卷积和逐点卷积。

深度卷积的计算步骤

示例数据
  • 输入特征图(两个通道):
    通道 1 : [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ] , 通道 2 : [ 0 1 2 3 1 2 3 4 2 3 4 5 3 4 5 6 ] \text{通道 1}: \begin{bmatrix} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & 14 & 15 & 16 \\ \end{bmatrix}, \text{通道 2}: \begin{bmatrix} 0 & 1 & 2 & 3 \\ 1 & 2 & 3 & 4 \\ 2 & 3 & 4 & 5 \\ 3 & 4 & 5 & 6 \\ \end{bmatrix} 通道 1: 15913261014371115481216 ,通道 2: 0123123423453456

  • 卷积核(每个通道):
    [ − 1 0 1 − 2 0 2 − 1 0 1 ] \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \\ \end{bmatrix} 121000121

深度卷积是独立地在每个通道上应用卷积核。考虑通道 1,不使用填充,步长为 1,计算得到的输出特征图(只计算左上角的第一个元素)为:

( − 1 × 1 ) + ( 0 × 2 ) + ( 1 × 3 ) + ( − 2 × 5 ) + ( 0 × 6 ) + ( 2 × 7 ) + ( − 1 × 9 ) + ( 0 × 10 ) + ( 1 × 11 ) = − 1 + 3 − 10 + 14 − 9 + 11 = 8 \begin{aligned} & (-1 \times 1) + (0 \times 2) + (1 \times 3) \\ & + (-2 \times 5) + (0 \times 6) + (2 \times 7) \\ & + (-1 \times 9) + (0 \times 10) + (1 \times 11) \\ & = -1 + 3 - 10 + 14 - 9 + 11 = 8 \end{aligned} (1×1)+(0×2)+(1×3)+(2×5)+(0×6)+(2×7)+(1×9)+(0×10)+(1×11)=1+310+149+11=8

重复这个过程以计算其他元素,然后对通道 2 做相同的操作。

逐点卷积的计算步骤

假设我们有两个 1x1 卷积核,用于逐点卷积。

示例数据
  • 逐点卷积核:
    卷积核 1 : [ 1 ] , 卷积核 2 : [ − 1 ] \text{卷积核 1}: \begin{bmatrix} 1 \\ \end{bmatrix}, \text{卷积核 2}: \begin{bmatrix} -1 \\ \end{bmatrix} 卷积核 1:[1],卷积核 2:[1]

逐点卷积的计算是在深度卷积的每个通道上应用 1x1 卷积核,并将结果相加。每个 1x1 卷积核应用于所有通道的同一位置,产生新的特征图。例如,使用第一个 1x1 卷积核计算左上角第一个元素的输出(假设通道 2 的相应输出也是 8):

( 1 × 通道 1 的左上角元素 ) + ( 1 × 通道 2 的左上角元素 ) = ( 1 × 8 ) + ( 1 × 8 ) = 8 + 8 = 16 \begin{aligned} & (1 \times \text{通道 1 的左上角元素}) + (1 \times \text{通道 2 的左上角元素}) \\ & = (1 \times 8) + (1 \times 8) \\ & = 8 + 8 = 16 \end{aligned} (1×通道 1 的左上角元素)+(1×通道 2 的左上角元素)=(1×8)+(1×8)=8+8=16

使用第二个 1x1 卷积核进行相同的计算:

( − 1 × 通道 1 的左上角元素 ) + ( − 1 × 通道 2 的左上角元素 ) = ( − 1 × 8 ) + ( − 1 × 8 ) = − 8 − 8 = − 16 \begin{aligned} & (-1 \times \text{通道 1 的左上角元素}) + (-1 \times \text{通道 2 的左上角元素}) \\ & = (-1 \times 8) + (-1 \times 8) \\ & = -8 - 8 = -16 \end{aligned} (1×通道 1 的左上角元素)+(1×通道 2 的左上角元素)=(1×8)+(1×8)=88=16

代码

import numpy as np

def depthwise_conv2d(input, kernel):
    """深度卷积"""
    kernel_height, kernel_width, channels = kernel.shape
    input_height, input_width, _ = input.shape

    # 计算输出特征图的尺寸
    output_height = input_height - kernel_height + 1
    output_width = input_width - kernel_width + 1

    # 初始化输出特征图
    output = np.zeros((output_height, output_width, channels))

    # 深度卷积
    for c in range(channels):
        for i in range(output_height):
            for j in range(output_width):
                output[i, j, c] = np.sum(input[i:i+kernel_height, j:j+kernel_width, c] * kernel[:, :, c])
    return output

def pointwise_conv2d(input, kernel):
    """逐点卷积"""
    _, _, channels = input.shape
    num_kernels = kernel.shape[0]

    # 计算输出特征图的尺寸
    output_height, output_width, _ = input.shape

    # 初始化输出特征图
    output = np.zeros((output_height, output_width, num_kernels))

    # 逐点卷积
    for n in range(num_kernels):
        for c in range(channels):
            output[:, :, n] += input[:, :, c] * kernel[n, c]
    return output

# 输入特征图
input_feature_map = np.array([
    [[1, 0], [2, 1], [3, 2], [4, 3]],
    [[5, 1], [6, 2], [7, 3], [8, 4]],
    [[9, 2], [10, 3], [11, 4], [12, 5]],
    [[13, 3], [14, 4], [15, 5], [16, 6]]
])

# 深度卷积核
depthwise_kernel = np.array([
    [[-1, -1], [0, 0], [1, 1]],
    [[-2, -2], [0, 0], [2, 2]],
    [[-1, -1], [0, 0], [1, 1]]
])

# 逐点卷积核
pointwise_kernel = np.array([
    [1, 1],
    [-1, -1]
])

# 深度卷积
depthwise_output = depthwise_conv2d(input_feature_map, depthwise_kernel)
print("深度卷积输出:\n", depthwise_output)

# 逐点卷积
pointwise_output = pointwise_conv2d(depthwise_output, pointwise_kernel)
print("逐点卷积输出:\n", pointwise_output)

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

h52013141

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值