pytorch框架(计算机视觉)if __name__ == ‘__main__‘:

之所以常看见这样的写法,是因为该程序可能有“单独执行”(例如执行一些单元测试)与“被引用”两种情况,鉴于这两种情况中__name__的值是不同的:当一个模块被直接执行时,其__name__必然等于__main__;当一个模块被引用时,其__name__必然等于文件名(不含.py)。所以利用判断__name__== 'main’的真假就可以将这两种情况区分出来。

if __name__ == '__main__':

    image_size = 64 ##图像统一缩放大小
    crop_size = 48 ##图像裁剪大小,即训练输入大小
    nclass = 4 ##分类类别数
    model = simpleconv3(nclass) ##创建模型
   
    
    ## 模型缓存接口
    if not os.path.exists('models'):
        os.mkdir('models')

    ## 检查GPU是否可用,如果是使用GPU,否使用CPU
    use_gpu = torch.cuda.is_available()
    if use_gpu:
        model = model.cuda()
    print(model)

    ## 创建数据预处理函数,训练预处理包括随机裁剪缩放、随机翻转、归一化,验证预处理包括中心裁剪,归一化
    data_transforms = {
        'train': transforms.Compose([
            transforms.RandomSizedCrop(48),
            transforms.RandomHorizontalFlip(),
            transforms.ToTensor(),
            transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])
        ]),
        'val': transforms.Compose([
            transforms.Scale(image_size),
            transforms.CenterCrop(crop_size),
            transforms.ToTensor(),
            transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])
        ]),
    }

    ## 使用torchvision的dataset ImageFolder接口读取数据
     data_dir = './data' ##数据目录
    image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
                                              data_transforms[x]) for x in ['train', 'val']}
#data_transforms  在前面已经定义 是一个字典

    ## 创建数据指针,设置batch大小,shuffle,多进程数量
    dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x],
                                                 batch_size=64,
                                                 shuffle=True,
                                                 num_workers=4) for x in ['train', 'val']}
    ## 获得数据集大小
    dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}

    ## 优化目标使用交叉熵,优化方法使用带动量项的SGD,学习率迭代策略为step,每隔100个epoch,变为原来的0.1倍
    criterion = nn.CrossEntropyLoss()
    optimizer_ft = optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
    step_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=100, gamma=0.1)

    model = train_model(model=model,
                           criterion=criterion,
                           optimizer=optimizer_ft,
                           scheduler=step_lr_scheduler,
                           num_epochs=10)

    torch.save(model.state_dict(),'models/model.pt')

为了保证可以复现,随机种子相同

在硬件设备(CPU、GPU)不同时,完全的可复现性无法保证,即使随机种子相同。但是,在同一个设备上,应该保证可复现性。具体做法是,在程序开始的时候固定torch的随机种子,同时也把numpy的随机种子固定。

np.random.seed(0)
torch.manual_seed(0)
torch.cuda.manual_seed_all(0)
#保证每次生成随即数组相同

torch.backends.cudnn.benchmark = False

将上面的值设置为True,Pytorch就会针对模型的卷积层进行预先的优化,即针对每一层卷积都寻找最快的实现算法,进而提升整体效率。如此,便可在模型启动的时候额外增加一点预处理时间,而大幅度减少整体训练时间。
影响卷积运算速度的因素有

卷积层本身的参数,如卷积核尺寸,步长,填充,输出通道个数。 输入的参数,如输入的通道数,宽,高等

因此如果上面影响卷积速度的参数频繁的变化,
则将torch.backends.cudnn.benchmark设置为True就不是明智的选择。因为在每次变化之后,算法都会重新预处理,预处理如果做太多次,也是很浪费时间的。
大部分的卷积神经网络的模型卷积层参数和输入参数都是固定的,因此可以利用上述方式提高效率。

torch.backends.cudnn.deterministic = True

torch.backends.cudnn.deterministic顾名思义,将这个 flag 置为True的话,每次返回的卷积算法将是确定的,即默认算法。如果配合上设置 Torch
的随机种子为固定值的话,应该可以保证每次运行网络的时候相同输入的输出是固定的

dataset=torchvision.datasets.ImageFolder

本文链接:https://blog.csdn.net/taylorman/article/details/118631209

dataset=torchvision.datasets.ImageFolder(
                       root, transform=None, 
                       target_transform=None, 
                       loader=<function default_loader>, 
                       is_valid_file=None)

参数详解:

  • root:图片存储的根目录,即各类别文件夹所在目录的上一级目录。

  • transform:对图片进行预处理的操作(函数),原始图片作为输入,返回一个转换后的图片。

  • target_transform:对图片类别进行预处理的操作,输入为 target,输出对其的转换。如果不传该参数,即对 target 不做任何转换,返回的顺序索引 0,1, 2…

  • loader:表示数据集加载方式,通常默认加载方式即可。

  • is_valid_file:获取图像文件的路径并检查该文件是否为有效文件的函数(用于检查损坏文件)
    返回的dataset都有以下三种属性:

  • self.classes:用一个 list 保存类别名称

  • self.class_to_idx:类别对应的索引,与不做任何转换返回的 target 对应

  • self.imgs:保存(img-path, class) tuple的 list

dos.path.join()函数合并目录的操作

会从第一个以”/”开头的参数开始拼接,之前的参数全部丢弃。

os.path.join("aa","/bb","ccc.txt")

结果:

'/bb/ccc.txt'

torch.utils.data.DataLoader

  • 作用:torch.utils.data.DataLoader 主要是对数据进行 batch 的划分。
    数据加载器,结合了数据集和取样器,并且可以提供多个线程处理数据集。在训练模型时使用到此函数,用来 把训练数据分成多个小组 ,此函数 每次抛出一组数据 。直至把所有的数据都抛出。就是做一个数据的初始化。

  • 好处:
    使用DataLoader的好处是,可以快速的迭代数据。用于生成迭代数据非常方便。

  • 注意:
    除此之外,特别要注意的是输入进函数的数据一定得是可迭代的。如果是自定的数据集的话可以在定义类中用def__len__、def__getitem__定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值