深度学习FCN代码查漏补缺笔记(一)

torch.rand() 是均匀采样,采样范围为0~1,torhc.randn是正太分布,均值为0,方差为1

函数 分布 均值 方差 取值范围
torch.rand 均匀分布 U(0,1) 0.5 1/12 ≈ 0.083 [0, 1)
torch.randn 标准正态分布 N(0,1) 0 1 (−∞, +∞)
python 复制代码
X = torch.rand(size=(1, 3, 320, 480))

✅ 正确的部分:

  • 形状解释是对的:
    • 1:batch size(批量大小)
    • 3:通道数(例如 RGB 图像的 3 个通道)
    • 320:高度(height)
    • 480:宽度(width)
      所以这是一个典型的 单张彩色图像 的张量表示(batch=1)。

X = torch.rand(size=(1, 3, 320, 480)) 创建了一个形状为 (1, 3, 320, 480) 的张量,其中每个元素是独立地从 [0, 1) 区间上的均匀分布 中随机采样的。它常用于模拟一张 batch size 为 1、3 通道、高 320、宽 480 的图像数据,但像素值范围是 [0,1),而非标准正态分布。

降低通道数量,不改变高宽的代码(增加1x1卷积网络层,)

python 复制代码
net.add_module('final_conv', nn.Conv2d(512, num_classes, kernel_size=1)) 
  • 向网络 net 中添加了一个名为 'final_conv' 的 1×1 卷积层。
  • 该层将 输入的 512 个通道 映射为 21 个输出通道(对应 21 个类别)。
  • 空间分辨率(H × W)保持不变,因为卷积核大小为 1×1 且默认无 padding/stride 改变尺寸。
  • 批量大小(batch size)由输入数据决定,不是卷积层的参数。

补充说明(应用场景):

这种结构常见于全卷积网络(FCN)用于语义分割:

  • 主干网络(如 ResNet)提取出 (B, 512, H, W) 的高层特征;

  • 最后的 1×1 卷积将通道数变为类别数,得到 logits (B, 21, H, W);

  • 后续通常接 softmax 或 cross_entropy_loss 进行像素级分类。

转置卷积的代码

复制代码
net.add_module('transpose_conv', 
               nn.ConvTranspose2d(num_classes, num_classes,
                                  kernel_size=64, padding=16, stride=32))

nn.ConvTranspose2d(num_classes, num_classes, kernel_size=64, padding=16, stride=32)

  • 是一个通道数保持不变(in=out=num_classes)的转置卷积层;
  • 用于将空间分辨率放大 32 倍(高和宽都 ×32);
  • 参数经过精心设计,使得输出尺寸恰好为输入的 32 倍,常用于语义分割模型的最后一层上采样(如 FCN-32s);
  • 批量大小(batch size)仍然由输入决定,不是该层的参数。

📝 补充建议:

虽然这种大核转置卷积在早期 FCN 中使用,但现代方法(如 DeepLab、U-Net)更倾向于使用:

  • 双线性插值 + 小卷积

  • 或多个小步长转置卷积堆叠(如 stride=2 多次)

    以减少计算量和伪影。

双线性插值核(初始化转置卷积核权重,节省训练时间)

这是一个 用于初始化转置卷积(ConvTranspose2d)权重的双线性插值核(bilinear upsampling kernel),常用于语义分割中替代随机初始化的上采样层,以实现平滑、可学习但初始为插值行为的上采样。

python 复制代码
def bilinear_kernel(in_channels, out_channels, kernel_size):
    factor = (kernel_size + 1) // 2
    if kernel_size % 2 == 1:
        center = factor - 1
    else:
        center = factor - 0.5
    og = (torch.arange(kernel_size).reshape(-1, 1),
          torch.arange(kernel_size).reshape(1, -1))
    filt = (1 - torch.abs(og[0] - center) / factor) * \
           (1 - torch.abs(og[1] - center) / factor)
    weight = torch.zeros((in_channels, out_channels,
                          kernel_size, kernel_size))
    weight[range(in_channels), range(out_channels), :, :] = filt
    return weight
  • 这个函数生成一个双线性插值上采样核,用于初始化 ConvTranspose2d 的权重。
  • og 是坐标网格的行/列索引(用于构建二维位置)。
  • filt 是一个非负的、中心对称的、峰值在中心的二维核,值域为 0, 1
  • 没有负数,不是 -1 到 1,也不是"先正后负"。因为先算括号里面的,再计算除法,再计算减法
  • 当用作转置卷积权重时,它能实现近似双线性插值的上采样效果(尤其当 stride = kernel_size / 2 时)。

📌 应用场景示例:

假设我们有一个 1/8 下采样的特征图,想上采样回原图尺寸

复制代码
conv_trans = nn.ConvTranspose2d(21, 21, kernel_size=16, stride=8, padding=4, bias=False)
conv_trans.weight.data = bilinear_kernel(21, 21, 16)

这样初始化后,该层初始行为就是双线性插值,训练时还可微调。

增加批量维度

复制代码
X = img.unsqueeze(0)

unsqueeze(0):在张量的形状中,在指定的位置(这里是第0位)添加一个维度。由于原始的 img 形状为 (3, H, W),执行这行代码后,X 的形状变为了 (1, 3, H, W)。这里的 1 表示批量大小,即我们只有一个样本。

调整维度顺序 permute

.permute(1, 2, 0):调整维度顺序

Y0 的形状是 (C, H, W)

.permute(1, 2, 0) 表示:

新的第 0 维 = 原来的第 1 维(H)

新的第 1 维 = 原来的第 2 维(W)

新的第 2 维 = 原来的第 0 维(C)

结果形状:(H, W, C)

✅ 为什么这么做?

因为 PyTorch 和深度学习模型内部使用 (C, H, W) 格式(通道在前),但 大多数图像处理库(如 Matplotlib、PIL、OpenCV)期望 (H, W, C) 格式(通道在后)。

所以为了可视化,必须转成 (H, W, C)。

返回最大值对应的索引

argmax()

分割的交叉熵损失函数

python 复制代码
def loss(inputs, targets):
    return F.cross_entropy(inputs, targets, reduction='none').mean(1).mean(1)

输入为channel,h,w的数据,跟标注的targets进行注意像素的比较,得到一个均值。其实targets的像素里的类别。告诉他应该选择第几个channel。得到channel之后。通过softmax得到一个最大概率的类别,但是从中选择真实类别对应的概率进行-log,再讲每个像素计算的-loss加在一起求得一个均值。得到损失

获得颜色分类

python 复制代码
 def label2image(pred):
    colormap = torch.tensor(d2l.VOC_COLORMAP, device=devices[0])
    X = pred.long()
    return colormap[X, :]

colormap是一个颜色图,

X是H,W的大小,得到了每个类别的ID值。返回的是让每个像素,从同ID值得到不同的颜色值

相关推荐
米小虾25 分钟前
Loop Engineering —— 循环的设计与自主执行
人工智能·agent
米小虾38 分钟前
Harness Engineering —— 系统的安全护栏
人工智能·agent
火山引擎开发者社区1 小时前
积分当钱花,火山引擎开发者激励计划首月消费双倍回馈
人工智能
aqi001 小时前
15天学会AI应用开发(十)把文本嵌入模型换成国产模型
人工智能·python·ai编程
MobotStone2 小时前
为什么在AI时代,“好奇心”成了最值钱的能力?
人工智能
武子康3 小时前
调查研究-200 llama.cpp b9754:一次很小但很关键的 Agent 工具调用修复
人工智能·agent·llama
Ralph_Salar3 小时前
从0到1搭建AI智能支付风控助手Stage1-RAG知识库升级 — 元数据让检索更精准
人工智能
武子康3 小时前
调查研究-199 MCP Zero-Touch OAuth:为什么它是 MCP 进入企业生产的关键门槛?
人工智能·agent·mcp