
2022年2月24日,俄罗斯宣战并入侵了和平的乌克兰。克里米亚吞并和唐巴斯地区的占领之后,普京政权决定摧毁乌克兰国籍。乌克兰人表现出激烈的抵抗,并向全世界展示了为国家独立而战的感觉。
乌克兰政府启动了一个网站,以帮助俄罗斯母亲,妻子和姐妹发现他们心爱的人在乌克兰被杀害或俘虏-https://200rf.com&https://t.me/rf200_now(Telegram Channel)。我们的目标是告知仍在俄罗斯和白俄罗斯的人们,因此他们拒绝袭击乌克兰。
帮助我们最大程度地接触到乌克兰,暴力和不人道的恐怖行为,“俄罗斯世界”带给乌克兰。这是关于如何帮助结束这场战争的全面Wiki:https://how-to-to-help-ukraine-now.super.site/
官方频道
荣耀乌克兰!
pytorch-toolbelt是一个Python图书馆,有一套铃铛和哨子,用于快速的研发原型和Kaggle养殖:
展示柜:催化剂,陈词滥调,pytorch工具带示例:语义分割 @ camvid
诚实的答案是“我需要一种方便的方法来重新利用我的Kaggle职业的代码”。在2018年,我获得了Kaggle Master徽章,这是一条漫长的道路。我经常发现自己一遍又一遍地重复使用大多数旧管道。在某个时候,它结晶到了此存储库中。
该液体并不是要取代催化剂 / IGNITE / fast.ai高级框架。相反,它旨在补充它们。
pip install pytorch_toolbelt
在代码片段下方创建用于二进制分割的Vanilla 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 ])与以前的示例类似,您可以使用contatenation将解码器更改为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)和第一卷积层即可更改。只要有可能,现有的卷积层的权重将被重新使用(如果新数量的通道数大于默认数量,则将使用随机定位的Weigth填充新的重量张量)。类方法返回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 ))
# Prints {'total': 34232561, 'trainable': 34232561, 'encoder': 25510896, 'decoder': 8721536, 'logits': 129}有多种方法可以结合多种损失,而高级DL框架(例如Catalyst)为实现这一目标提供了更灵活的方法,但是这里有100%的Pure Pytorch实施:
from pytorch_toolbelt import losses as L
# Creates a loss function that is a weighted sum of focal loss
# and lovasz loss with weigths 1.0 and 0.5 accordingly.
loss = L . JointLoss ( L . FocalLoss (), L . LovaszLoss (), 1.0 , 0.5 )测试时间Augmetnation(TTA)可用于训练和测试阶段。
from pytorch_toolbelt . inference import tta
model = UNet ()
# Truly functional TTA for image classification using horizontal flips:
logits = tta . fliplr_image2label ( model , input )
# Truly functional TTA for image segmentation using D4 augmentation:
logits = tta . d4_image2mask ( model , input )通常,需要对图像进行分割,以实现极大的图像(5000px等)。如此大的像素阵列有一些问题:
解决方案之一是将输入图像切成图块(可选地重叠),并通过模型将每个图像馈入并将结果串回。通过这种方式,您可以保证GPU RAM使用的上限,同时保持在GPU上处理任意尺寸的图像的能力。
import numpy as np
from torch . utils . data import DataLoader
import cv2
from pytorch_toolbelt . inference . tiles import ImageSlicer , CudaTileMerger
from pytorch_toolbelt . utils . torch_utils import tensor_from_rgb_image , to_numpy
image = cv2 . imread ( 'really_huge_image.jpg' )
model = get_model (...)
# Cut large image into overlapping tiles
tiler = ImageSlicer ( image . shape , tile_size = ( 512 , 512 ), tile_step = ( 256 , 256 ))
# HCW -> CHW. Optionally, do normalization here
tiles = [ tensor_from_rgb_image ( tile ) for tile in tiler . split ( image )]
# Allocate a CUDA buffer for holding entire mask
merger = CudaTileMerger ( tiler . target_shape , 1 , tiler . weight )
# Run predictions for tiles and accumulate them
for tiles_batch , coords_batch in DataLoader ( list ( zip ( tiles , tiler . crops )), batch_size = 8 , pin_memory = True ):
tiles_batch = tiles_batch . float (). cuda ()
pred_batch = model ( tiles_batch )
merger . integrate_batch ( pred_batch , coords_batch )
# Normalize accumulated mask and convert back to numpy
merged_mask = np . moveaxis ( to_numpy ( merger . merge ()), 0 , - 1 ). astype ( np . uint8 )
merged_mask = tiler . crop_to_orignal_size ( merged_mask ) @misc{Khvedchenya_Eugene_2019_PyTorch_Toolbelt,
author = {Khvedchenya, Eugene},
title = {PyTorch Toolbelt},
year = {2019},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {url{https://github.com/BloodAxe/pytorch-toolbelt}},
commit = {cc5e9973cdb0dcbf1c6b6e1401bf44b9c69e13f3}
}