
เมื่อวันที่ 24 กุมภาพันธ์ 2565 รัสเซียประกาศสงครามและบุกยูเครนอย่างสงบสุข หลังจากการผนวกไครเมียและการยึดครองของภูมิภาคดอนบาสระบอบการปกครองของปูตินตัดสินใจที่จะทำลายสัญชาติยูเครน Ukrainians แสดงการต่อต้านที่รุนแรงและแสดงให้เห็นถึงโลกทั้งโลกว่าการต่อสู้เพื่ออิสรภาพของประเทศเป็นอย่างไร
รัฐบาลของยูเครนเปิดตัวเว็บไซต์เพื่อช่วยเหลือคุณแม่ชาวรัสเซียภรรยาและน้องสาวพบว่าคนที่รักถูกฆ่าหรือถูกจับในยูเครน - https://200rf.com & https://t.me/rf200_now (ช่องโทรเลข) เป้าหมายของเราคือการแจ้งให้ผู้ที่ยังคงอยู่ในรัสเซียและเบลารุสดังนั้นพวกเขาจึงปฏิเสธที่จะโจมตียูเครน
ช่วยให้เราได้รับการเปิดเผยสูงสุดในสิ่งที่เกิดขึ้นในยูเครนความรุนแรงและการกระทำที่น่ากลัวอย่างไร้มนุษยธรรมว่า "โลกรัสเซีย" ได้นำมาสู่ยูเครน นี่คือวิกิที่ครอบคลุมเกี่ยวกับวิธีที่คุณสามารถช่วยยุติสงครามนี้ได้: https://how-to-help-ukraine-now.super.site/
ช่องทางการ
Glory to Ukraine!
pytorch-toolbelt เป็นห้องสมุด Python ที่มีชุดระฆังและนกหวีดสำหรับ Pytorch สำหรับการสร้างต้นแบบ R&D ที่รวดเร็วและการทำฟาร์ม Kaggle:
Showcase: Catalyst, albumentations, pytorch toolbelt ตัวอย่าง: การแบ่งส่วนความหมาย @ camvid
คำตอบที่ซื่อสัตย์คือ "ฉันต้องการวิธีที่สะดวกในการใช้รหัสใหม่สำหรับอาชีพ Kaggle ของฉัน" ในช่วงปี 2561 ฉันประสบความสำเร็จในการเป็นนาย Kaggle Master Badge และนี่เป็นเส้นทางที่ยาวนาน บ่อยครั้งที่ฉันพบว่าตัวเองใช้ท่อเก่าส่วนใหญ่ซ้ำแล้วซ้ำอีก ในบางจุดมันตกผลึกในที่เก็บนี้
lib นี้ไม่ได้หมายถึงการแทนที่ตัวเร่งปฏิกิริยา / Ignite / fast.ai กรอบระดับสูง แต่มันถูกออกแบบมาเพื่อเติมเต็มพวกเขา
pip install pytorch_toolbelt
ด้านล่างของโค้ดตัวอย่างที่สร้างโมเดลวานิลลา 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 ด้วย 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 ]) ตัวเข้ารหัสทั้งหมดจาก pytorch_toolbelt รองรับการเปลี่ยนจำนวนช่องสัญญาณอินพุต เพียงแค่เรียก call encoder.change_input_channels(num_channels) และเลเยอร์ convolution ครั้งแรกจะมีการเปลี่ยนแปลง เมื่อใดก็ตามที่เป็นไปได้น้ำหนักของเลเยอร์ convolutional ที่มีอยู่จะถูกนำกลับมาใช้ใหม่ (ในกรณีที่จำนวนช่องทางใหม่มากกว่าค่าเริ่มต้นเทนเซอร์น้ำหนักใหม่จะได้รับการเบาะด้วย weigths แบบสุ่ม) วิธีการเรียนกลับมา 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 เสนอวิธีที่ยืดหยุ่นมากขึ้นในการบรรลุเป้าหมายนี้ แต่นี่คือการใช้งาน Pytorch 100%ของฉัน:
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}
}