
Em 24 de fevereiro de 2022, a Rússia declarou guerra e invadiu a Ucrânia pacífica. Após a anexação da Crimeia e a ocupação da região de Donbas, o regime de Putin decidiu destruir a nacionalidade ucraniana. Os ucranianos mostram resistência feroz e demonstram ao mundo inteiro como é lutar pela independência do país.
O governo da Ucrânia lançou um site para ajudar as mães russas, esposas e irmãs a encontrarem seus amados mortos ou capturados na Ucrânia - https://200rf.com & https://t.me/rf200_now (canal de telegrama). Nosso objetivo é informar aqueles que ainda estão na Rússia e na Bielorrússia, então eles se recusam a atacar a Ucrânia.
Ajude -nos a obter a máxima exposição ao que está acontecendo na Ucrânia, violência e atos desumanos de terror que o "mundo russo" trouxe para a Ucrânia. Este é um wiki abrangente sobre como você pode ajudar a terminar esta guerra: https://how-to-help-ukraine-now.super.site/
Canais oficiais
Glória para a Ucrânia!
Um pytorch-toolbelt é uma biblioteca Python com um conjunto de sinos e assobios para Pytorch para prototipagem de P&D rápida e agricultura de kaggle:
Showcase: Catalyst, Albumentations, Pytorch Toolbelt Exemplo: Segmentação Semântica @ Camvid
A resposta honesta é "eu precisava de uma maneira conveniente de reutilizar o código para minha carreira de Kaggle". Durante 2018, consegui um crachá mestre de Kaggle e este foi um caminho longo. Muitas vezes me vi reutilizando a maioria dos oleodutos antigos repetidamente. Em algum momento, ele se cristalizou nesse repositório.
Este LIB não pretende substituir o Catalyst / Ignite / Fast.ai de estruturas de alto nível. Em vez disso, foi projetado para complementá -los.
pip install pytorch_toolbelt
Abaixo de um trecho de código que cria o modelo de rede U de baunilha para segmentação binária. Por design, o codificador e o decodificador produz uma lista de tensores, de finos (alta resolução, indexada 0 ) a mapas grossos (de baixa resolução). O acesso a todos os mapas de recursos intermediários é benéfico se você deseja aplicar perdas profundas de supervisão nelas ou no codificador-decodificador da tarefa de detecção de objetos, onde é necessário acesso a mapas de recursos intermediários.
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 ])Da mesma forma que o exemplo anterior, você pode alterar o decodificador para FPN com a contatenação.
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 ]) Todos os codificadores de pytorch_toolbelt suporta alterações no número de canais de entrada. Basta chamar encoder.change_input_channels(num_channels) e a primeira camada de convolução serão alterados. Sempre que possível, os pesos existentes da camada convolucional serão reutilizados (caso um novo número de canais seja maior que o padrão, o novo tensor de peso será acolchoado com weigths aleatoriamente iniciais). O método de classe retorna self , para que essa chamada possa ser acorrentada.
from pytorch_toolbelt . modules import encoders as E
encoder = E . SEResnet101Encoder ()
encoder = encoder . change_input_channels ( 6 ) Ao projetar um modelo e otimizar o número de recursos na rede neural, achei bastante útil imprimir o número de parâmetros em blocos de alto nível (como encoder e decoder ). Aqui está como fazer isso com 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}Existem várias maneiras de combinar várias perdas e estruturas DL de alto nível, como o Catalyst, oferece uma maneira muito mais flexível de conseguir isso, mas aqui está a implementação da minha 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 )Augustação no tempo de teste (TTA) pode ser usada nas fases de treinamento e teste.
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 )Muitas vezes, é necessário executar a segmentação de imagens para uma imagem enormemente grande (5000px e muito mais). Existem alguns problemas com uma grande matriz de pixels:
Uma das soluções é cortar a imagem de entrada em ladrilhos (opcionalmente sobrepostos) e alimentar cada um através do modelo e concatenar os resultados de volta. Dessa forma, você pode garantir o limite superior do uso da GPU RAM, mantendo a capacidade de processar imagens de tamanho arbitrário na 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}
}