
Le 24 février 2022, la Russie a déclaré la guerre et a envahi Ukraine pacifique. Après l'annexion de la Crimée et l'occupation de la région du Donbas, le régime de Poutine a décidé de détruire la nationalité ukrainienne. Les Ukrainiens montrent une résistance féroce et démontrent au monde entier ce que c'est que de se battre pour l'indépendance du pays.
Le gouvernement de l'Ukraine a lancé un site Web pour aider les mères, les épouses et les sœurs russes à trouver leurs bien-aimés tuées ou capturées en Ukraine - https://200rf.com & https://t.me/rf200_now (Channel Telegram). Notre objectif est d'informer ceux qui sont toujours en Russie et en Bélarus, ils refusent donc d'agression Ukraine.
Aidez-nous à obtenir une exposition maximale à ce qui se passe en Ukraine, à la violence et aux actes de terreur inhumains que le «monde russe» a apporté en Ukraine. Ceci est un wiki complet sur la façon dont vous pouvez aider à mettre fin à cette guerre: https://how-to-help-ukraine-now.super.site/
Canaux officiels
Gloire à l'Ukraine!
Une pytorch-toolbelt est une bibliothèque Python avec un ensemble de cloches et de sifflets pour Pytorch pour le prototypage rapide de R&D et l'agriculture de Kaggle:
Showcase: Catalyst, Albumentations, Pytorch Toolbelt Exemple: Segmentation sémantique @ CAMVID
La réponse honnête est "J'avais besoin d'un moyen pratique de réutiliser le code pour ma carrière de Kaggle". En 2018, j'ai atteint un badge de maître Kaggle et c'était un long chemin. Très souvent, je me suis retrouvé à réutiliser la plupart des anciens pipelines encore et encore. À un moment donné, il s'est cristallisé dans ce référentiel.
Cette LIB n'est pas destinée à remplacer les cadres de catalyseur / ignite / jeûne.AI Frameworks de haut niveau. Au lieu de cela, il est conçu pour les compléter.
pip install pytorch_toolbelt
Sous un extrait de code qui crée un modèle de vanille U-Net pour la segmentation binaire. Par conception, l'encodeur et le décodeur produisent une liste de tenseurs, à partir de cartes de caractéristiques fines (haute résolution, indexées) à 0 (basse résolution). L'accès à toutes les cartes de fonctionnalités intermédiaires est bénéfique si vous souhaitez appliquer des pertes de supervision profondes sur eux ou encodeur de coder de la tâche de détection d'objet, où l'accès à des cartes de fonctionnalités intermédiaires est nécessaire.
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 ])De façon similaire à l'exemple précédent, vous pouvez modifier le décodeur en FPN avec la contatenation.
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 ]) Tous les encodeurs de pytorch_toolbelt prennent en charge la modification du nombre de canaux d'entrée. Appelez simplement encoder.change_input_channels(num_channels) et la première couche de convolution sera modifiée. Dans la mesure du possible, les poids existants de la couche convolutionnelle seront réutilisés (au cas où un nouveau nombre de canaux est supérieur à la défaillance, le nouveau tenseur de poids sera rembourré avec des weigths initialisés au hasard). La méthode de classe self , donc cet appel peut être enchaîné.
from pytorch_toolbelt . modules import encoders as E
encoder = E . SEResnet101Encoder ()
encoder = encoder . change_input_channels ( 6 ) Lors de la conception d'un modèle et de l'optimisation du nombre de fonctionnalités dans le réseau neuronal, j'ai trouvé qu'il était très utile d'imprimer le nombre de paramètres dans des blocs de haut niveau (comme encoder et decoder ). Voici comment le faire avec 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}Il existe plusieurs façons de combiner plusieurs pertes, et des cadres DL de haut niveau comme Catalyst offrent un moyen beaucoup plus flexible d'y parvenir, mais voici une mise en œuvre de la mienne à 100% 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 )L'augétnation de test (TTA) peut être utilisée dans les phases de formation et de test.
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 )Très souvent, il est nécessaire d'effectuer une segmentation d'image pour une image extrêmement grande (5000px et plus). Il y a quelques problèmes avec de si gros tableaux de pixels:
L'une des solutions consiste à trancher l'image d'entrée dans les carreaux (éventuellement se chevaucher) et à nourrir chacun par le modèle et à concaténer les résultats. De cette manière, vous pouvez garantir la limite supérieure de l'utilisation de la RAM GPU, tout en gardant la capacité de traiter les images de taille arbitraire sur 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}
}