注意:翻译需要符合中文语序、流程、通顺
重要更新
2022年2月24日,俄罗斯宣布开战并入侵了和平的乌克兰。在吞并克里米亚和占领顿巴斯地区后,普京政权决定摧毁乌克兰的民族身份。乌克兰人民展示了顽强的抵抗,并向全世界展示了争取国家独立的模样。
乌克兰政府启动了一个网站,帮助俄罗斯的母亲、妻子和姐妹找到在乌克兰被杀或被俘的亲人——https://200rf.com 和 https://t.me/rf200_now(Telegram频道)。我们的目标是向仍在俄罗斯和白俄罗斯的人们传达信息,以便他们拒绝攻击乌克兰。
帮助我们最大限度地揭露在乌克兰发生的暴力和俄罗斯世界带来的不人道恐怖行为。这是一个关于如何帮助结束这场战争的全面维基:https://how-to-help-ukraine-now.super.site/
官方渠道:
荣耀属于乌克兰!
Pytorch-toolbelt
pytorch-toolbelt
是一个Python库,包含了一套用于PyTorch的工具,适用于快速研发原型和Kaggle比赛:
内部组件
- 通过灵活的编码器-解码器架构轻松构建模型。
- 模块:CoordConv,SCSE,Hypercolumn,深度可分离卷积等。
- 对于分割和分类,支持GPU友好的测试时增强(TTA)。
- 对超大图像(5000x5000)的GPU友好推理。
- 每日常用的例程(修复/恢复随机种子、文件系统工具、指标)。
- 损失函数:二值焦点损失、焦点损失、减小焦点损失、Lovasz损失、Jaccard损失和Dice损失、Wing损失等。
- 为Catalyst库提供的额外功能(批次预测可视化、附加指标)。
展示案例:Catalyst, Albumentations, Pytorch Toolbelt例子:语义分割@CamVid
背景
老实说,“我需要一种方便的方式来复用我的Kaggle代码”。在2018年,我获得了Kaggle大师徽章,这一路走来十分不易。我经常发现自己反复使用以前的流水线。在某个时刻,这些东西结晶为这个库。
这个库不是为了取代catalyst/ignite/fast.ai等高层框架,而是为了补充它们。
安装
pip install pytorch_toolbelt
如何实现...
模型创建
创建编码器-解码器U-Net模型
下面是一个创建用于二值分割的经典U-Net模型的代码片段。设计上,编码器和解码器都会生成一个张量列表,从细(高分辨率,索引为0
)到粗(低分辨率)特征图。如果你想在它们上应用深度监督损失或编码器-解码器的目标检测任务时,访问所有中间特征图是有益的。
from torch import nn
from pytorch_toolbelt.modules import encoders as E
from pytorch_toolbelt.modules import decoders as D
class UNet(nn.Module):
def __init__(self, input_channels, num_classes):
super().__init__()
self.encoder = E.UnetEncoder(in_channels=input_channels, out_channels=32, growth_factor=2)
self.decoder = D.UNetDecoder(self.encoder.channels, decoder_features=32)
self.logits = nn.Conv2d(self.decoder.channels[0], num_classes, kernel_size=1)
def forward(self, x):
x = self.encoder(x)
x = self.decoder(x)
return self.logits(x[0])
创建具有预训练编码器的FPN模型
与之前的例子类似,你可以将解码器更改为带有连接的FPN。
from torch import nn
from pytorch_toolbelt.modules import encoders as E
from pytorch_toolbelt.modules import decoders as D
class SEResNeXt50FPN(nn.Module):
def __init__(self, num_classes, fpn_channels):
super().__init__()
self.encoder = E.SEResNeXt50Encoder()
self.decoder = D.FPNCatDecoder(self.encoder.channels, fpn_channels)
self.logits = nn.Conv2d(self.decoder.channels[0], num_classes, kernel_size=1)
def forward(self, x):
x = self.encoder(x)
x = self.decoder(x)
return self.logits(x[0])
更改编码器的输入通道数
所有来自pytorch_toolbelt
的编码器都支持更改输入通道数。只需调用encoder.change_input_channels(num_channels)
,第一个卷积层将被更改。只要有可能,卷积层的现有权重将被重用(如果新的通道数大于默认值,则新的权重张量将用随机初始化的权重填充)。类方法返回self
,因此此调用可以被链接。
from pytorch_toolbelt.modules import encoders as E
encoder = E.SEResnet101Encoder()
encoder = encoder.change_input_channels(6)
杂项
计算编码器/解码器及其他模块中的参数数量
在设计模型并优化神经网络特征数时,我发现打印高级块(如encoder
和decoder
)中的参数数量非常有用。以下是如何使用pytorch_toolbelt
实现这一点:
from torch import nn
from pytorch_toolbelt.modules import encoders as E
from pytorch_toolbelt.modules import decoders as D
from pytorch_toolbelt.utils import count_parameters
class SEResNeXt50FPN(nn.Module):
def __init__(self, num_classes, fpn_channels):
super().__init__()
self.encoder = E.SEResNeXt50Encoder()
self.decoder = D.FPNCatDecoder(self.encoder.channels, fpn_channels)
self.logits = nn.Conv2d(self.decoder.channels[0], num_classes, kernel_size=1)
def forward(self, x):
x = self.encoder(x)
x = self.decoder(x)
return self.logits(x[0])
net = SEResNeXt50FPN(1, 128)
print(count_parameters(net))
# 输出 {'total': 34232561, 'trainable': 34232561, 'encoder': 25510896, 'decoder': 8721536, 'logits': 129}
组合多个损失
有多种方法可以组合多个损失,高级DL框架如Catalyst提供了更灵活的方法来实现这一点,但以下是我100%纯PyTorch的实现:
from pytorch_toolbelt import losses as L
# 创建一个损失函数,它是焦点损失和Lovasz损失的加权和,权重分别为1.0和0.5。
loss = L.JointLoss(L.FocalLoss(), L.LovaszLoss(), 1.0, 0.5)
TTA / 推理
对模型应用测试时增强(TTA)
测试时增强(TTA)可以在训练和测试阶段使用。
from pytorch_toolbelt.inference import tta
model = UNet()
# 通过水平翻转进行图像分类的真正功能性TTA:
logits = tta.fliplr_image2label(model, input)
# 通过D4增强进行图像分割的真正功能性TTA:
logits = tta.d4_image2mask(model, input)
对超大图像进行推理:
经常需要对超大图像(5000px及以上)进行图像分割。这么大的像素阵列有几个问题:
- CUDA张量的最大尺寸有限制(具体数值取决于驱动和GPU版本)。
- 在推理相对较小的1024x1024图像时,重型CNN架构可能会轻易消耗所有可用的GPU内存,导致