当前位置: 首页 > article >正文

从0开始深度学习(25)——多输入多输出通道

之前我们都只研究了一个通道的情况(二值图、灰度图),但实际情况中很多是彩色图像,即有标准的RGB三通道图片,本节将更深入地研究具有多输入和多输出通道的卷积核。

1 多输入通道

当输入包含多个通道时,需要构造一个与输入数据具有相同输入通道数的卷积核,以便与输入数据进行互相关运算。

当有多个通道时,我们可以对每个通道输入的二维张量和卷积核的二维张量进行互相关运算,再对通道求和得到二维张量,如下图所示:

在这里插入图片描述
下面是通过代码实现:

import torch
from d2l import torch as d2l

def corr2d_multi_in(X, K):
    # 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起
    return sum(d2l.corr2d(x, k) for x, k in zip(X, K))

X = torch.tensor([[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]],
               [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]])

K = torch.tensor([[[0.0, 1.0], [2.0, 3.0]], 
                  [[1.0, 2.0], [3.0, 4.0]]])

X = X.unsqueeze(0)  # 增加一个维度,形状变为 (1, 2, 3, 3)               
K = K.unsqueeze(0)  # 增加一个维度,形状变为 (1, 2, 2, 2)

conv2d = nn.Conv2d(in_channels=2, out_channels=1, kernel_size=2, bias=False)
conv2d.weight.data =K
# 执行卷积操作
Y = conv2d(X)

# 输出卷积结果的形状
print("Output shape:", Y.shape)

# 如果需要查看具体的卷积结果,可以打印出来
print("Output tensor:")
print(Y)

运行结果
在这里插入图片描述

2 多输出通道

到目前为止,我们还只有一个输出通道。在最流行的神经网络架构中,随着神经网络层数的加深,我们常会增加输出通道的维数,通过减少空间分辨率以获得更大的通道深度。直观地说,我们可以将每个通道看作对不同特征的响应。
在这里插入图片描述
代码如下:

import torch
from d2l import torch as d2l


def corr2d_multi_in(X, K):
    # 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起
    return sum(d2l.corr2d(x, k) for x, k in zip(X, K))

X = torch.tensor([[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]],
               [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]])

K = torch.tensor([
    [[[0.0, 1.0], [2.0, 3.0]], 
     [[1.0, 2.0], [3.0, 4.0]]],  # K
    [[[1.0, 2.0], [3.0, 4.0]], 
     [[2.0, 3.0], [4.0, 5.0]]],  # K + 1
    [[[2.0, 3.0], [4.0, 5.0]], 
     [[3.0, 4.0], [5.0, 6.0]]]   # K + 2
])


X = X.unsqueeze(0)  # 增加一个维度,形状变为 (1, 2, 3, 3)               


conv2d = nn.Conv2d(in_channels=2, out_channels=2, kernel_size=2, bias=False)
conv2d.weight.data =K
# 执行卷积操作
Y = conv2d(X)

# 输出卷积核的形状,第一个是参数输出通道,第二个参数是输入通道,后面两个是卷积的高度和宽度
print("kernle shape:", K.shape)

# 如果需要查看具体的卷积结果,可以打印出来
print("Output tensor:")
print(Y)

运行结果
在这里插入图片描述

3 1 × \times × 1 卷积核

1 × 1 1\times1 1×1的卷积核看似没有作用,实则可以起到一些对输入图像的通道进行一些操作

3.1 通道变换

使用 1x1 卷积核将通道数从 64 变为 128。

import torch
from torch import nn

# 输入特征图形状为 (1, 64, 28, 28)
x = torch.randn(1, 64, 28, 28)

# 使用 1x1 卷积核将通道数从 64 变为 128
conv1x1 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=1)

# 执行卷积操作
y = conv1x1(x)

# 输出形状为 (1, 128, 28, 28)
print(y.shape)  # torch.Size([1, 128, 28, 28])

3.2 特征融合

1x1 卷积核可以用来融合不同通道的特征,使用 1x1 卷积核将通道数从 32 变为 16。

# 输入特征图形状为 (1, 32, 32, 32)
x = torch.randn(1, 32, 32, 32)

# 使用 1x1 卷积核将通道数从 32 变为 16
conv1x1 = nn.Conv2d(in_channels=32, out_channels=16, kernel_size=1)

# 执行卷积操作
y = conv1x1(x)

# 输出形状为 (1, 16, 32, 32)
print(y.shape)  # torch.Size([1, 16, 32, 32])

3.3 提升计算效率

使得 1x1 卷积核在深度网络中可以高效地减少参数数量和计算成本,假设我们有一个大通道数的特征图,使用 1x1 卷积核可以显著减少后续层的计算负担,最后在进行升维。

# 输入特征图形状为 (1, 256, 14, 14)
x = torch.randn(1, 256, 14, 14)

# 使用 1x1 卷积核将通道数从 256 减少到 64
conv1x1_reduce = nn.Conv2d(in_channels=256, out_channels=64, kernel_size=1)
x = conv1x1_reduce(x)

# 应用 3x3 卷积核
conv3x3 = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding=1)
x = conv3x3(x)

# 使用 1x1 卷积核将通道数从 64 恢复到 256
conv1x1_expand = nn.Conv2d(in_channels=64, out_channels=256, kernel_size=1)
x = conv1x1_expand(x)

# 输出形状为 (1, 256, 14, 14)
print(x.shape)  # torch.Size([1, 256, 14, 14])

http://www.kler.cn/a/388788.html

相关文章:

  • Rust 所有权机制
  • jmeter常用配置元件介绍总结之后置处理器
  • 第74期 | GPTSecurity周报
  • C++单例模式实现
  • Flink_DataStreamAPI_输出算子Sink
  • 实验一:自建Docker注册中心
  • Logrus入门
  • python练习-可视化
  • xss的过滤和绕过(2)
  • 船舶AIS轨迹聚类算法(附python源码)
  • unity下添加c#脚本
  • Seldon Core大模型部署详解
  • 如何在vscode中安装git详细新手教程
  • 快速上手 muduo
  • 【iOS】知乎日报第三周总结
  • 金融市场中的量化分析:正大科技如何赋能投资者决策
  • 期权懂|你知道期权策略有哪些核心策略吗?
  • 保护Kubernetes免受威胁:容器安全的有效实践
  • 力扣力扣力:动态规划入门(1)
  • solo博客使用非docker方式进行https部署
  • Android 文件带进度的下载功能实现与封装
  • 2024年11月6日Github流行趋势
  • 【计网不挂科】计算机网络期末考试——【选择题&填空题&判断题&简述题】试卷(2)
  • 蓝桥杯:编程爱好者的试炼场
  • 运维的目标管理:以业务为核心,驱动运维价值最大化
  • 实时高效,全面测评快递100API的物流查询功能