一、自定义损失函数
1、函数方式2、类方式 二、动态调整学习率
1、流程2、使用已有模型结构 三、模型微调四、半精度训练
1、原因2、半精度3、半精度训练的设置
一、自定义损失函数 1、函数方式如MSE的定义如下:
def my_loss(output, target):
loss = torch.mean((output - target)**2)
return loss
2、类方式
以类方式定义更常用,方便观察LOSS函数的继承关系。以Dice Loss是一种在分割领域常见的损失函数,定义如下:
D
S
C
=
2
∣
X
∩
Y
∣
∣
X
∣
+
∣
Y
∣
DSC = frac{2|X∩Y|}{|X|+|Y|}
DSC=∣X∣+∣Y∣2∣X∩Y∣
实现代码如下:见ipynb文件
注: 使用PyTorch提供的张量计算接口,可自动求导且直接调用cuda。
step1. 在源数据集(如ImageNet数据集)上预训练一个神经网络模型,即源模型。
step2. 创建目标模型。该目标模型复制了源模型上除了输出层外的所有模型设计及其参数。我们假设这些模型参数包含了源数据集上学习到的知识,且这些知识同样适用于目标数据集。我们还假设源模型的输出层跟源数据集的标签紧密相关,因此在目标模型中不予采用。
step3. 为目标模型添加一个输出⼤小为⽬标数据集类别个数的输出层,并随机初始化该层的模型参数。
step4. 在目标数据集上训练目标模型。我们将从头训练输出层,而其余层的参数都是基于源模型的参数微调得到的。
以torchvision中的常见模型为例,以下为在图像分类任务中使用PyTorch提供的常见模型结构和参数:
实例化网络
import torchvision.models as models resnet18 = models.resnet18() # resnet18 = models.resnet18(pretrained=False) 等价于与上面的表达式 alexnet = models.alexnet() vgg16 = models.vgg16() squeezenet = models.squeezenet1_0() densenet = models.densenet161() inception = models.inception_v3() googlenet = models.googlenet() shufflenet = models.shufflenet_v2_x1_0() mobilenet_v2 = models.mobilenet_v2() mobilenet_v3_large = models.mobilenet_v3_large() mobilenet_v3_small = models.mobilenet_v3_small() resnext50_32x4d = models.resnext50_32x4d() wide_resnet50_2 = models.wide_resnet50_2() mnasnet = models.mnasnet1_0()
传递pretrained参数
import torchvision.models as models resnet18 = models.resnet18(pretrained=True) alexnet = models.alexnet(pretrained=True) squeezenet = models.squeezenet1_0(pretrained=True) vgg16 = models.vgg16(pretrained=True) densenet = models.densenet161(pretrained=True) inception = models.inception_v3(pretrained=True) googlenet = models.googlenet(pretrained=True) shufflenet = models.shufflenet_v2_x1_0(pretrained=True) mobilenet_v2 = models.mobilenet_v2(pretrained=True) mobilenet_v3_large = models.mobilenet_v3_large(pretrained=True) mobilenet_v3_small = models.mobilenet_v3_small(pretrained=True) resnext50_32x4d = models.resnext50_32x4d(pretrained=True) wide_resnet50_2 = models.wide_resnet50_2(pretrained=True) mnasnet = models.mnasnet1_0(pretrained=True)三、模型微调
见ipynp文件
四、半精度训练 1、原因GPU的性能主要分为两部分:算力和显存,前者决定了显卡计算的速度,后者则决定了显卡可以同时放入多少数据用于计算。如何合理使用显存在训练中十分重要。
2、半精度定义:PyTorch默认的浮点数存储方式用的是torch.float32,小数点后位数更多固然能保证数据的精确性,但绝大多数场景其实并不需要这么精确,只保留一半的信息也不会影响结果,也就是使用torch.float16格式。由于数位减了一半,因此被称为“半精度”。
作用:半精度能够减少显存占用,使得显卡可以同时加载更多数据进行计算
import autocast
from torch.cuda.amp import autocast
模型设置
在模型定义中,使用python的装饰器方法,用autocast装饰模型中的forward函数。关于装饰器的使用,可以参考这里:
@autocast()
def forward(self, x):
...
return x
训练过程
在训练过程中,只需在将数据输入模型及其之后的部分放入“with autocast():“即可:
for x in train_loader:
x = x.cuda()
with autocast():
output = model(x)
...



