pytorch进阶训练技巧
1:自定义损失函数。
diceloss, huberloss, sobolevloss
def my_loss(output,target):
loss=torch.mean((outoput-target)**2)
return loss
分割领域常见损失:dice loss
Class Dicloss(nn.Module):
def __init__(self,weigh=None, size_average=True):
super(Diceloss,self).__init__()
def forward(self,inputs,targets,smooth=1):
input= F.sigmoid(inputs)
inputs-inputs.view(-1)
targets=targets.view(-1)
intersection=(inputs*targets).sum()
dice=(2*intersection+smooth)/(inputs.sum()+targets.sum()+smooth)
return 1-dice
criterion=DiceLoss()
loss=criterion(input,targets)
IOU loss:
class IoUloss(nn.Module):
def __init__(self,weigth=None,size_average=True):
super(IOULoss,self).__init__()
def forward(self,inputs,targets,smooth=1_:
inputs=F.sigmoid(inputs)
inputs=inputs.view(-1)
targets=targets.view(-1)
intersection=(inputs*targets).sum()
total=(inputs+targets).sum()
union=total-intersection
IoI=(intersection+smooth)/(union+smooth)
return 1-IoU
2:动态调整学习率。
pytorch学习率再lr。scheduler中进行调整
有LambdaLR,MultiplicativeLR,StepLR,MultistepLR,ExponentialLR 等等
def adjust_learning_rate(optimizer,epoch):
lr=args.lr*(0.1**(epoch//30))
for param_graoup in optimizer.param_groups:
param_group['lr']=lr
由此则可以每三十轮变为原来的十分之1,
3:torchvision模型微调。
模型微调流程:
首先预训练神经网络模型
再创建新的目标模型。
再为目标模型添加一个输出大小为目标数据集类别个数的输出层。并随机化该模型参数。
再在目标数据集上训练目标模型,从头训练输出层,而其余层的参数都是基于原模型参数微调得到的。
使用已有模型
import torchvision.models as models
resnet18=models.resnet18()
alexnet=models.alexnet()
vgg16=models.vgg16()
传递pretrained参数
resnet18=models.resnet18(pretrained=True)
训练一个单独层的梯度:
import torchvision.models as models
feature_extract=True
model=model.resnet18(pretrained=True)
set_parameter_requires_grad(model,feature_extract)
num_ftrs=models.fc.in_features
model.fc=nn.Linear(in_features=num_ftrs,out_featurs=4,bias=True)
4:模型微调
使用timm
pip install timm
import timm
import torch
model.timm.create_model(‘resnet34’,pretrainted=True)
x=torch.randn(1,3,224,224)
output=model(x)
output.shape
查看第一层模型参数
model=timm.create_model('resnet34',pretrained=True)
list(dict(model.named_children())['conv1'].parameters())
将1000类改为10类输出
model=timm.create_model('resnet34',num_classes=10,pretrained=True)
x=torch.randn(1,3,224,224)
output=model(x)
output.shape
可以通过in_chans=1 来改变输入通道
模型保存
torch.save(model.state_dict())
model.load_state_dict(torch.load)
4:半精度训练
半精度设置
from torch.cuda.amp import autocast
用autocast装束forward函数
@autocast
def forward(self,x):
return x
训练中只需写上autocast
for x in train_loader:
x=x.cuda()
with autocast():
output=model(x)
半精度训练适用于数据size大。
5:数据增强:imgaug
pip install imgaug
import imageio
import imgaug as ia
img=imageio.imread('./lenna.jpg')
ia.imshow(img)
用augmenter进行数据增强此处用affine
from imgaug import augmenters as iaa
ia.seed(4)
rotate=iaa.Affine(rotate=(-4,45))
img_aug=rotate(image=img)
ia.imshow(img_aug)
实际中多种数据增强同时采用,使用imgaug.augmenters.sequential进行统一述说。
iaa.sequential(children=None,
random_order=false
name=None,
dterministic=False,
random_state=None)
对数据进行批次处理
images=[img,img,img,img]
images_aug=rotate(images=images)
ia.imshow(np.hstack(image_aug))
可以用
imgaug.augmenters.sometimes 对数据进行一部分处理a,一部分处理b
iaa.sometimes(p=0.5,then_list+none,else_list=None)
使用imgaug后,在pytorch中记得使用totensor
6:用argparse进行调参
创建argumentparser对象
调用add_argument 方法添加参数
使用parse_args()解析参数。
待补充代码
import argparse