精华内容
下载资源
问答
  • 使用Dataset制作好数据集之后,可以用Dataloader进行读取,然后用resnet34进行训练。...2 数据的读取batch_size为每一次处理数据的数量,以60张图片为一组# 读取数据 trainset = ImageFloder(root='D:/Anaco...

    使用Dataset制作好数据集之后,可以用Dataloader进行读取,然后用resnet34进行训练。

    具体代码及注释如下

    1 模块导入

    其中data_read是利用Dataset制作数据集时写的文件

    # 从data_read文件中读取函数
    

    2 数据的读取

    batch_size为每一次处理数据的数量,以60张图片为一组

    # 读取数据
    trainset = ImageFloder(root='D:/Anaconda3/data/tiny-imagenet-200', subdir='train', transform=train_transform)
    traindataloader = DataLoader(trainset, batch_size=60, shuffle=True, num_workers=0)
    valset = ImageFloder(root='D:/Anaconda3/data/tiny-imagenet-200', subdir='val', transform=test_transform)
    valdataloader = DataLoader(valset, batch_size=60, num_workers=0)

    3 网络构建

    # 因为batch_size的存在,因此输入的x的size实际为([60,1,224,224])
    # 网络开始搭建,自定义类均要继承 nn.Module 类
    # 只需要定义 __init__ 和 forward 即可
    # class_number表明最后分类的数量,200意味着一共有200个类型的图片,编号为0到199
    class Net(nn.Module):
        def __init__(self, class_number=200):
            super(Net, self).__init__()
            self.net = resnet34(pretrained=True)
            # 修改 resnet34 的全连接层,定义第一次Linear的输出通道数
            self.cov2fc = 1024
            self.net.fc = nn.Sequential(
                nn.Linear(512*1*1, self.cov2fc),
                nn.ReLU(True),
                nn.Dropout(),
                nn.Linear(self.cov2fc, self.cov2fc),
                nn.ReLU(True),
                nn.Dropout(),
                nn.Linear(self.cov2fc, class_number)
            )
        # 建立前向传播
        def forward(self, x):
            x = self.net(x)
            return x

    4 网络训练的前期准备

    # e_epoch为迭代次数,8代表迭代8次,但实际e_epoch是从0到7
    # lr为初始学习率
    # step用于学习率的更新
    # checkpoint是指输出loss时的节点
    e_epoch = 8
    lr = 0.01
    step = 20
    checkpoint = 100
    
    # device用于判断是不是满足cuda运行的条件,如果不满足则使用cpu
    # 需要注意的是,用了device定义之后,往后的代码中,涉及到网络内容、参数、及数据集的情况都要加上to(device)
    # 用net = Net().to(device)来调用上面创建的网络
    # nn.CrossEntropyLoss()用来计算损失loss
    # optim.SGD用来更新参数
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    net = Net().to(device)
    criterion = nn.CrossEntropyLoss().to(device)
    optimizer = optim.SGD(net.parameters(), lr=lr, momentum=0.9)
    
    # 制定学习率更新的条件
    def re_learningrate(epoch):
        re_lr = lr *(0.1 ** (epoch // step))
        return re_lr

    5 定义训练网络

    我的理解中,每一个epoch中,要完成整个所有图片数据的训练,因此设置了batch_size=60,数据集的大小为100000,因此需要循环的次数为100000//60+1次(//表示取商,向下取整,在此处表示1666),因此i的范围是(0,100000//60+1-1),当检查点checkpoint设置为100时,即当i=99、199、299、399…时,已经处理的数据量大小应该为6000、12000、18000…

    def train(epoch):
        net.train()
        # 更新梯度下降中的学习率
        for p in optimizer.param_groups:
            p['lr'] = re_learningrate(epoch)
        total_loss = 0.0
        # enumerate可以将数据集排序,因此i提取到每一个数据集的序号
        # 每一个数据集中有60张图片,意味着每一个i运行结束后有60张图片进行了训练
        # 调用的data_read函数中已经将图片读取到内存中
        # 因此traindataloader中,imgs可以直接读取到图片,labels则是对应的标签,是用0-199的数值代表的标签
        for i, (imgs, labels) in enumerate(traindataloader):
            imgs, labels = imgs.to(device), labels.to(device)
            # 运行前需要清除原有的grad
            optimizer.zero_grad()
            output = net(imgs)
            # 计算损失,这个loss代表的是一个batch_size大小的数据计算出的损失,不是指每一张图片的损失
            loss = criterion(output, labels)
            # 反向传播
            loss.backward()
            # 梯度下降方法更新参数
            optimizer.step()
            # 计算累加的损失
            total_loss += loss.item()
            # 以checkpoint为检查点,计算平均的损失loss
            # 其中imgs.size()应该为([60,1,224,224])
            # 因为batch_size=60,所以一个epoch中,当i=99时,代表已经循环了训练了100次
            # 因此已经训练的图片量为(i+1)*imgs.size()[0]
            # 总共要训练的图片量为len(traindataloader.dataset)
            # 因为已经训练了100次(checkpoint设置的数量),因此平均的loss为total_loss/float(checkpoint)
            if (i+1) % checkpoint == 0:
                print('Epoch: {} [{}/{}] loss: {}'.format(epoch+1, (i+1)*imgs.size()[0], len(traindataloader.dataset),
                                                          total_loss/float(checkpoint)))
                # 最后需要将总的loss归0,防止循环叠加出现误判
                total_loss = 0.0

    6 定义验证网络

    def val(epoch):
        net.eval()
        correct = 0.0
        # 仅对网络训练结果进行验证,不需要反向传播,也不需要计算梯度,所以要使用with torch.no_grad()
        with torch.no_grad():
            # 此处的循环次数与train函数中的一样
            # 因为不用每个循环都输出correct,只需要最后整个测试集的correct,因此不用enumerate进行编号
            for imgs, labels in valdataloader:
                imgs, labels = imgs.to(device), labels.to(device)
                output = net(imgs)
                # 以下注释没有考虑总数据集的大小,是将总的图片看为了60张,其实60只是一个batch_size的大小
                # output中其实为60行200列的数组,size大小为([60,200])
                # 假如一个epoch中的60张图片分别属于第1类、第2类、第3类...第200类
                # 逻辑判断的结果,1则代表判断结果是属于这一类
                # 则里面的内容为([[1,0,0,...,0],[0,1,0,...,0],...,[0,0,0,...,1]])
                # dim=1代表在列方向进行处理
                # argmax(dim=1)可以提取出列方向上最大值所在的序号值
                # 结果为([0,1,2,...,199])
                # predict.shape输入预测结果的维数,结果为([60])
                # labels.view()可以将标签文件中的数据按照predict.shape()的维度重组
                # 然后用predict.eq()判断两者是不是相等,相等则为1,不相等为0
                # 然后对判断结果进行累加,累加之后需要用item()将其转换为纯数字
                predict = output.argmax(dim=1)
                correct += predict.eq(labels.view(predict.shape)).sum().item()
            #然后计算出识别的正确率,此处为计算每一个epoch的正确率,因此要跳出循环
            print('Epoch: {} Accuracy: {}'.format(epoch+1, correct/float(len(valdataloader.dataset))*100))

    7 网络保存及运行

    # 每次完成一个epoch保存一次
    def save(epoch):
        root = 'D:/file/deep learning/pytorch practice/resnet34'
        stats = {
            'epoch': epoch,
            'model': net.state_dict()
        }
        if not os.path.exists(root):
            os.makedirs(root)
        savepath = join(root, 'model_{}.pth'.format(epoch+1))
        torch.save(stats, savepath)
        print('saving checkpoint in {}'.format(savepath))
    
    if __name__ == '__main__':
        for epoch in range(e_epoch):
            train(epoch)
            val(epoch)
            save(epoch)
    展开全文
  • ImageNet介绍

    千次阅读 2021-01-29 20:34:25
    ImageNet介绍 time: 2021.01.29     author: Blue         e-mail: 2458682080@qq.com 一. 引言        此文为阅读《ImageNet: A Large-...

    ImageNet介绍

    time: 2021.01.29     author: Blue         e-mail: 2458682080@qq.com

    一. 引言

           此文为阅读《ImageNet: A Large-Scale Hierarchical Image Database》论文的总结,本文按照原论文的结构进行归纳总结,当然文章也会夹杂个人观点,有误之处请指正!

    二. 简介

           论文主体共有七大部分组成: 摘要、介绍、ImageNet的特性、ImageNet和相关数据集、构造ImageNet、ImageNet应用、未来工作,分别介绍了ImageNet出现的背景、ImageNet的现状、ImageNet的优势、相关数据集、ImageNet的构建、ImageNet应用以及展望。

    三. 论文介绍

    1. 摘要:

           互联网上图像数据的爆炸式增长有可能训练出更复杂、更健壮的模型和算法,用于索引、检索、组织图像和多媒体数据并与之交互(背景)。文章介绍了ImageNet的现状:12个子树,5247个语法集,共320万幅图像(现状)。论文结果表明 ImageNet 具有更大的规模和多样性,比现有的图像数据集更精确(优势)。通过ImageNet在目标识别、图像分类和自动目标聚类中的三个简单应用,说明了ImageNet的实用性(应用)

    2. 介绍

    • 背景: 互联网上有很多数据,可以利用这些数据训练处一个复杂而稳定的算法或模型。但是怎么应用是个问题,因此提出了ImageNet。
    • 结构: 使用了WordNet层次结构
    • 现状: 报告ImageNet的当前版本,包括12个“子树”:哺乳动物、鸟类、鱼类、爬行动物、两栖动物、交通工具、家具、乐器、地质构造、工具、花卉、水果。这些子树包含5247个语法集,共320万幅图像。

    3. 特性(数据集描述)

    • 规模(Scale):目前的12个子树由320万张清晰标注的图像组成,这些图像分布在5247个类别中。平均每个语义集中超过了600张图片。这已经是视觉研究界可用的最大的干净图像数据集,就图像总数、每个类别的图像数以及类别数而言(规模优势)
    • 层级(Hierarchy):ImageNet将不同类别的图像组织在一个密集的语义层次结构中。与WordNet类似,ImageNet中图像的语法集通过几种类型的关系相互关联,“IS-A”关系是最全面、最有用的关系。(提出优势)尽管可以使用WordNet将任何带有类别标签的数据集映射到语义层次结构中,但是ImageNet的密度是其他数据集无法比拟的(层级优势)
    • 准确度(Accuracy):在不同树深度随机采样的80个synset上的标记精度,平均达到99.7%的精度(精度优势)
    • 多样性(Diversity):ImageNet的构建目标是图像中的对象应该具有不同的外观、位置、视点、姿势以及背景杂波和遮挡。为了解决图像多样性量化的难题,我们计算了每个synset的平均图像,并测量了反映图像中信息量的无损JPG文件大小。(希望看到一个更小的jpg文件大小的平均图像更多样化的语法集)

    4. ImageNet和相关数据集(数据集比较)

    • 小型图像数据集:随着计算机视觉研究的发展,下一代算法需要更大更具挑战性的数据集。当前的ImageNet提供了20倍于这些数据集的类别数,以及100倍于这些数据集的总图像数。
    • TinyImage:TinyImage是一个拥有8000万32×32低分辨率图像的数据集,数据集中的每个synset平均包含1000个图像,其中10-25%可能是干净的图像。高噪声和低分辨率的图像使得它不太适合于通用算法的开发、训练和评估。与TinyImage数据集相比,ImageNet包含高质量的synset(∼99%精度)和全分辨率图像,平均大小约为400×350。
    • ESP dataset:ESP dataset中数以百万计的图像通过游戏被标记,但它的快速性也构成了一个主要的缺点,即人们倾向于在一个易于接近的语义层次上标记视觉对象,称为“基本层次”(如鸟),而不是更具体的层次(“次坐标层次”,如麻雀),或更一般的层次(“超坐标层次”,如脊椎动物)。然而,ImageNet展示了图像在语义层次结构中更为均衡的分布(优势1: 语义层次更加均衡)。ESP和ImageNet的另一个关键区别是语义消歧。当人类玩家输入“银行”这个词时,不清楚它的意思是“河岸”还是“金融机构”。在如此大规模的情况下,消除歧义就成了一项非常重要的任务,但是ImageNet不存在这个问题(优势2: 不存在语义歧义问题)。最后,大部分ESP数据集都不公开,只能访问60K个图像及其标签(优势3: 公开)
    • LabelMe and Lotus Hill datasets:LabelMe和Lotus Hill数据集分别提供了30k和50k标记图像和分割图像。两者都只有大约200个类别,但提供了对象的轮廓和位置(劣势: 没有提供对象轮廓和位置)。ImageNet目前的形式并没有提供详细的对象轮廓,但是类别的数量和每个类别的图像数量已经远远超过了这两个数据集(数量优势)。此外,这两个数据集中的图像大部分是由数据集的用户或研究人员上传或提供的,而ImageNet包含从整个互联网上抓取的图像。Lotus Hill数据集只能通过购买获得。

    5. 构造ImageNet

    • 收集候选图像:ImageNet构建的第一阶段是为每个synset收集候选图像。互联网上的图像搜索结果平均准确率在10%左右。因此,收集了大量的候选图像。经过内部同步集重复删除后,每个语义集平均有超过10K个图像。

    • 清理候选图像:为了收集一个高度精确的数据集,工作人员依靠人工来验证在前一步中为给定的语法集收集的每个候选图像。这是通过使用Amazon Mechanical Turk(AMT)的服务实现的,AMT是一个在线平台,用户可以在这个平台上完成任务并获得报酬。(其中中间有很多筛选和算法过程,我就不详细介绍了)

    6. ImageNet应用

    1. 非参数物体识别

      • NN-voting + noisy ImageNet:为了模拟TinyImage数据集(即从搜索引擎中收集的图像,无需人工清理),使用每个synset的原始候选图像,并将它们降采样到32×32。给定一个查询图像,从哺乳动物子树中提取100个最近邻图像,然后通过聚集目标类别树内的投票(最近邻数)来进行分类。
      • NN-voting + clean ImageNet: 在干净的ImageNet数据集上运行上述相同的NN投票实验。这一结果表明,拥有更准确的数据可以提高分类性能。
      • NBNN:实现了朴素贝叶斯网络中提出的最近邻(NBNN)方法强调全分辨率图像的有用性。NBNN使用一个特征包来表示图像。结果表明,NBNN提供了更好的性能,证明了在全分辨率图像中使用更复杂的特征表示的优势。
      • NBNN-100:运行相同的NBNN实验,但将每个类别的图像数限制为100。结果发现,性能可以通过扩大数据集。值得注意的是,NBNN-100在访问整个数据集方面优于NN投票,再次展示了使用全分辨率图像获得详细特征级别信息的好处。
    2. 基于树的图像分类

      这个实验使用了一个简单的对象分类方法,我们称之为“tree-max classifier”,来说明ImageNet层次结构的有用性。结果表明,利用ImageNet层次结构的简单方法已经可以在不需要额外训练或模型学习的情况下为图像分类任务提供实质性的改进。

    3. 自动目标定位

      ImageNet可以扩展以提供有关每个图像的附加信息,其中一个信息是每个图像中对象的空间范围。想到两个应用领域:首先,为了训练一个鲁棒的目标检测算法,通常需要在不同的姿态和不同的视点下对目标进行定位;其次,在杂乱的场景中定位对象,使用户可以使用ImageNet作为对象定位算法的基准数据集。

    7. 未来方向

    • 完成ImageNet
    • 利用ImageNet
    展开全文
  • 在本教程中,我们将深入探讨如何对 torchvision 模型进行微调和特征提取,所有这些模型都已经预先在1000类的Imagenet数据集上训练完成。本教程将深入介绍如何使用几个现代的CNN架构,并将直观展示如何微调任意的...

    微调 Torchvision 模型

    在本教程中,我们将深入探讨如何对 torchvision 模型进行微调和特征提取,所有这些模型都已经预先在1000类的Imagenet数据集上训练完成。本教程将深入介绍如何使用几个现代的CNN架构,并将直观展示如何微调任意的PyTorch模型。由于每个模型架构是有差异的,因此没有可以在所有场景中使用的微调代码样板。然而,研究人员必须查看现有架构并对每个模型进行自定义调整。

    在本文档中,我们将执行两种类型的转移学习:微调和特征提取。在微调中,我们从预训练模型开始,更新我们新任务的所有模型参数,实质上是重新训练整个模型。在特征提取中,我们从预训练模型开始,仅更新从中导出预测的最终图层权重。它被称为特征提取,因为我们使用预训练的CNN作为固定的特征提取器,并且仅改变输出层。有关迁移学习的更多技术信息,请参阅此处和这里。

    通常,这两种迁移学习方法都遵循以下几个步骤:

    • 初始化预训练模型

    • 重组最后一层,使其具有与新数据集类别数相同的输出数

    • 为优化算法定义我们想要在训练期间更新的参数

    • 运行训练步骤

    1.导入相关包并打印版本号

    from __future__ import print_function
    from __future__ import division
    import torch
    import torch.nn as nn
    import torch.optim as optim
    import numpy as np
    import torchvision
    from torchvision import datasets, models, transforms
    import matplotlib.pyplot as plt
    import time
    import os
    import copy
    print("PyTorch Version: ",torch.__version__)
    print("Torchvision Version: ",torchvision.__version__)
    

    输出结果:

    PyTorch Version:  1.1.0
    Torchvision Version:  0.3.0
    

    2.输入

    以下为运行时需要更改的所有参数。我们将使用的数据集 hymenoptera_data 可在此处下载。该数据集包含两类:蜜蜂蚂蚁,其结构使得我们可以使用 ImageFolder 数据集,不需要编写我们自己的自定义数据集。下载数据并设置data_dir为数据集的根目录。model_name是您要使用的模型名称,必须从此列表中选择:

    [resnet, alexnet, vgg, squeezenet, densenet, inception]
    

    其他输入如下:num_classes为数据集的类别数,batch_size是训练的 batch 大小,可以根据您机器的计算能力进行调整,num_epochsis是我们想要运行的训练 epoch 数,feature_extractis是定义我们选择微调还是特征提取的布尔值。如果feature_extract = False,将微调模型,并更新所有模型参数。如果feature_extract = True,则仅更新最后一层的参数,其他参数保持不变。

    # 顶级数据目录。 这里我们假设目录的格式符合ImageFolder结构
    data_dir = "./data/hymenoptera_data"
    
    # 从[resnet, alexnet, vgg, squeezenet, densenet, inception]中选择模型
    model_name = "squeezenet"
    
    # 数据集中类别数量
    num_classes = 2
    
    # 训练的批量大小(根据您的内存量而变化)
    batch_size = 8
    
    # 你要训练的epoch数
    num_epochs = 15
    
    # 用于特征提取的标志。 当为False时,我们微调整个模型,
    # 当True时我们只更新重新形成的图层参数
    feature_extract = True
    

    3.辅助函数

    在编写调整模型的代码之前,我们先定义一些辅助函数。

    3.1 模型训练和验证代码

    train_model函数处理给定模型的训练和验证。作为输入,它需要PyTorch模型、数据加载器字典、损失函数、优化器、用于训练和验 证epoch数,以及当模型是初始模型时的布尔标志。is_inception标志用于容纳 Inception v3 模型,因为该体系结构使用辅助输出, 并且整体模型损失涉及辅助输出和最终输出,如此处所述。 这个函数训练指定数量的epoch,并且在每个epoch之后运行完整的验证步骤。它还跟踪最佳性能的模型(从验证准确率方面),并在训练 结束时返回性能最好的模型。在每个epoch之后,打印训练和验证正确率。

    def train_model(model, dataloaders, criterion, optimizer, num_epochs=25, is_inception=False):
        since = time.time()
    
        val_acc_history = []
    
        best_model_wts = copy.deepcopy(model.state_dict())
        best_acc = 0.0
    
        for epoch in range(num_epochs):
            print('Epoch {}/{}'.format(epoch, num_epochs - 1))
            print('-' * 10)
    
            # 每个epoch都有一个训练和验证阶段
            for phase in ['train', 'val']:
                if phase == 'train':
                    model.train()  # Set model to training mode
                else:
                    model.eval()   # Set model to evaluate mode
    
                running_loss = 0.0
                running_corrects = 0
    
                # 迭代数据
                for inputs, labels in dataloaders[phase]:
                    inputs = inputs.to(device)
                    labels = labels.to(device)
    
                    # 零参数梯度
                    optimizer.zero_grad()
    
                    # 前向
                    # 如果只在训练时则跟踪轨迹
                    with torch.set_grad_enabled(phase == 'train'):
                        # 获取模型输出并计算损失
                        # 开始的特殊情况,因为在训练中它有一个辅助输出。
                        # 在训练模式下,我们通过将最终输出和辅助输出相加来计算损耗
                        # 但在测试中我们只考虑最终输出。
                        if is_inception and phase == 'train':
                            # From https://discuss.pytorch.org/t/how-to-optimize-inception-model-with-auxiliary-classifiers/7958
                            outputs, aux_outputs = model(inputs)
                            loss1 = criterion(outputs, labels)
                            loss2 = criterion(aux_outputs, labels)
                            loss = loss1 + 0.4*loss2
                        else:
                            outputs = model(inputs)
                            loss = criterion(outputs, labels)
    
                        _, preds = torch.max(outputs, 1)
    
                        # backward + optimize only if in training phase
                        if phase == 'train':
                            loss.backward()
                            optimizer.step()
    
                    # 统计
                    running_loss += loss.item() * inputs.size(0)
                    running_corrects += torch.sum(preds == labels.data)
    
                epoch_loss = running_loss / len(dataloaders[phase].dataset)
                epoch_acc = running_corrects.double() / len(dataloaders[phase].dataset)
    
                print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))
    
                # deep copy the model
                if phase == 'val' and epoch_acc > best_acc:
                    best_acc = epoch_acc
                    best_model_wts = copy.deepcopy(model.state_dict())
                if phase == 'val':
                    val_acc_history.append(epoch_acc)
    
            print()
    
        time_elapsed = time.time() - since
        print('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))
        print('Best val Acc: {:4f}'.format(best_acc))
    
        # load best model weights
        model.load_state_dict(best_model_wts)
        return model, val_acc_history
    

    3.2 设置模型参数的`.requires_grad`属性

    当我们进行特征提取时,此辅助函数将模型中参数的 .requires_grad 属性设置为False。默认情况下,当我们加载一个预训练模型时,所有参数都是 .requires_grad = True,如果我们从头开始训练或微调,这种设置就没问题。但是,如果我们要运行特征提取并且只想为新初始化的层计算梯度,那么我们希望所有其他参数不需要梯度变化。这将在稍后更能理解。

    def set_parameter_requires_grad(model, feature_extracting):
        if feature_extracting:
            for param in model.parameters():
                param.requires_grad = False
    

    4.初始化和重塑网络

    现在来到最有趣的部分。在这里我们对每个网络进行重塑。请注意,这不是一个自动过程,并且对每个模型都是唯一的。回想一下,CNN模型的最后一层(通常是FC层)与数据集中的输出类的数量具有相同的节点数。由于所有模型都已在 Imagenet 上预先训练,因此它们都具有大小为1000的输出层,每个类一个节点。这里的目标是将最后一层重塑为与之前具有相同数量的输入,并且具有与数据集中的类别数相同的输出数。在以下部分中,我们将讨论如何更改每个模型的体系结构。但首先,有一个关于微调和特征提取之间差异的重要细节。

    当进行特征提取时,我们只想更新最后一层的参数,换句话说,我们只想更新我们正在重塑层的参数。因此,我们不需要计算不需要改变的参数的梯度,因此为了提高效率,我们将其它层的.requires_grad属性设置为False。这很重要,因为默认情况下,此属性设置为True。然后,当我们初始化新层时,默认情况下新参数.requires_grad = True,因此只更新新层的参数。当我们进行微调时,我们可以将所有.required_grad设置为默认值True。

    最后,请注意inception_v3的输入大小为(299,299),而所有其他模型都输入为(224,224)。

    4.1 Resnet

    论文Deep Residual Learning for Image Recognition介绍了Resnet模型。有几种不同尺寸的变体,包括Resnet18、Resnet34、Resnet50、Resnet101和Resnet152,所有这些模型都可以从 torchvision 模型中获得。因为我们的数据集很小,只有两个类,所以我们使用Resnet18。当我们打印这个模型时,我们看到最后一层是全连接层,如下所示:

    (fc): Linear(in_features=512, out_features=1000, bias=True)
    

    因此,我们必须将model.fc重新初始化为具有512个输入特征和2个输出特征的线性层:

    model.fc = nn.Linear(512, num_classes)
    

    4.2 Alexnet

    Alexnet在论文ImageNet Classification with Deep Convolutional Neural Networks中被介绍,是ImageNet数据集上第一个非常成功的CNN。当我们打印模型架构时,我们看到模型输出为分类器的第6层:

    (classifier): Sequential(
        ...
        (6): Linear(in_features=4096, out_features=1000, bias=True)
     )
    

    要在我们的数据集中使用这个模型,我们将此图层重新初始化为:

    model.classifier[6] = nn.Linear(4096,num_classes)
    

    4.3 VGG

    VGG在论文Very Deep Convolutional Networks for Large-Scale Image Recognition中被引入。Torchvision 提供了8种不同长度的VGG版本,其中一些版本具有批标准化层。这里我们使用VGG-11进行批标准化。输出层与Alexnet类似,即

    (classifier): Sequential(
        ...
        (6): Linear(in_features=4096, out_features=1000, bias=True)
     )
    

    因此,我们使用相同的方法来修改输出层

    model.classifier[6] = nn.Linear(4096,num_classes)
    

    4.4 Squeezenet

    论文SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size描述了 Squeeznet 架构,使用了与此处显示的任何其他模型不同的输出结构。Torchvision 的 Squeezenet 有两个版本,我们使用1.0版本。输出来自1x1卷积层,它是分类器的第一层:

    (classifier): Sequential(
        (0): Dropout(p=0.5)
        (1): Conv2d(512, 1000, kernel_size=(1, 1), stride=(1, 1))
        (2): ReLU(inplace)
        (3): AvgPool2d(kernel_size=13, stride=1, padding=0)
     )
    

    为了修改网络,我们重新初始化Conv2d层,使输出特征图深度为2

    model.classifier[1] = nn.Conv2d(512, num_classes, kernel_size=(1,1), stride=(1,1))
    

    4.5 Densenet

    论文Densely Connected Convolutional Networks引入了Densenet模型。Torchvision 有四种Densenet 变型,但在这里我们只使用 Densenet-121。输出层是一个具有1024个输入特征的线性层:

    (classifier): Linear(in_features=1024, out_features=1000, bias=True)
    

    为了重塑这个网络,我们将分类器的线性层重新初始化为

    model.classifier = nn.Linear(1024, num_classes)
    

    4.6 Inception v3

    Inception v3首先在论文Rethinking the Inception Architecture for Computer Vision中描述。该网络的独特之处在于它在训练时有两个输出层。第二个输出称为辅助输出,包含在网络的 AuxLogits 部分中。主输出是网络末端的线性层。注意,测试时我们只考虑主输出。加载模型的辅助输出和主输出打印为:

    (AuxLogits): InceptionAux(
        ...
        (fc): Linear(in_features=768, out_features=1000, bias=True)
     )
     ...
    (fc): Linear(in_features=2048, out_features=1000, bias=True)
    

    要微调这个模型,我们必须重塑这两个层。可以通过以下方式完成

    model.AuxLogits.fc = nn.Linear(768, num_classes)
    model.fc = nn.Linear(2048, num_classes)
    

    请注意,许多模型具有相似的输出结构,但每个模型的处理方式略有不同。另外,请查看重塑网络的模型体系结构,并确保输出特征数与数据集中的类别数相同。

    4.7 重塑代码

    def initialize_model(model_name, num_classes, feature_extract, use_pretrained=True):
        # 初始化将在此if语句中设置的这些变量。 
        # 每个变量都是模型特定的。
        model_ft = None
        input_size = 0
    
        if model_name == "resnet":
            """ Resnet18
     """
            model_ft = models.resnet18(pretrained=use_pretrained)
            set_parameter_requires_grad(model_ft, feature_extract)
            num_ftrs = model_ft.fc.in_features
            model_ft.fc = nn.Linear(num_ftrs, num_classes)
            input_size = 224
    
        elif model_name == "alexnet":
            """ Alexnet
     """
            model_ft = models.alexnet(pretrained=use_pretrained)
            set_parameter_requires_grad(model_ft, feature_extract)
            num_ftrs = model_ft.classifier[6].in_features
            model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes)
            input_size = 224
    
        elif model_name == "vgg":
            """ VGG11_bn
     """
            model_ft = models.vgg11_bn(pretrained=use_pretrained)
            set_parameter_requires_grad(model_ft, feature_extract)
            num_ftrs = model_ft.classifier[6].in_features
            model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes)
            input_size = 224
    
        elif model_name == "squeezenet":
            """ Squeezenet
     """
            model_ft = models.squeezenet1_0(pretrained=use_pretrained)
            set_parameter_requires_grad(model_ft, feature_extract)
            model_ft.classifier[1] = nn.Conv2d(512, num_classes, kernel_size=(1,1), stride=(1,1))
            model_ft.num_classes = num_classes
            input_size = 224
    
        elif model_name == "densenet":
            """ Densenet
     """
            model_ft = models.densenet121(pretrained=use_pretrained)
            set_parameter_requires_grad(model_ft, feature_extract)
            num_ftrs = model_ft.classifier.in_features
            model_ft.classifier = nn.Linear(num_ftrs, num_classes)
            input_size = 224
    
        elif model_name == "inception":
            """ Inception v3
     Be careful, expects (299,299) sized images and has auxiliary output
     """
            model_ft = models.inception_v3(pretrained=use_pretrained)
            set_parameter_requires_grad(model_ft, feature_extract)
            # 处理辅助网络
            num_ftrs = model_ft.AuxLogits.fc.in_features
            model_ft.AuxLogits.fc = nn.Linear(num_ftrs, num_classes)
            # 处理主要网络
            num_ftrs = model_ft.fc.in_features
            model_ft.fc = nn.Linear(num_ftrs,num_classes)
            input_size = 299
    
        else:
            print("Invalid model name, exiting...")
            exit()
    
        return model_ft, input_size
    
    # 在这步中初始化模型
    model_ft, input_size = initialize_model(model_name, num_classes, feature_extract, use_pretrained=True)
    
    # 打印我们刚刚实例化的模型
    print(model_ft)
    
    • 输出结果

    SqueezeNet(
      (features): Sequential(
        (0): Conv2d(3, 96, kernel_size=(7, 7), stride=(2, 2))
        (1): ReLU(inplace)
        (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)
        (3): Fire(
          (squeeze): Conv2d(96, 16, kernel_size=(1, 1), stride=(1, 1))
          (squeeze_activation): ReLU(inplace)
          (expand1x1): Conv2d(16, 64, kernel_size=(1, 1), stride=(1, 1))
          (expand1x1_activation): ReLU(inplace)
          (expand3x3): Conv2d(16, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (expand3x3_activation): ReLU(inplace)
        )
        (4): Fire(
          (squeeze): Conv2d(128, 16, kernel_size=(1, 1), stride=(1, 1))
          (squeeze_activation): ReLU(inplace)
          (expand1x1): Conv2d(16, 64, kernel_size=(1, 1), stride=(1, 1))
          (expand1x1_activation): ReLU(inplace)
          (expand3x3): Conv2d(16, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (expand3x3_activation): ReLU(inplace)
        )
        (5): Fire(
          (squeeze): Conv2d(128, 32, kernel_size=(1, 1), stride=(1, 1))
          (squeeze_activation): ReLU(inplace)
          (expand1x1): Conv2d(32, 128, kernel_size=(1, 1), stride=(1, 1))
          (expand1x1_activation): ReLU(inplace)
          (expand3x3): Conv2d(32, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (expand3x3_activation): ReLU(inplace)
        )
        (6): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)
        (7): Fire(
          (squeeze): Conv2d(256, 32, kernel_size=(1, 1), stride=(1, 1))
          (squeeze_activation): ReLU(inplace)
          (expand1x1): Conv2d(32, 128, kernel_size=(1, 1), stride=(1, 1))
          (expand1x1_activation): ReLU(inplace)
          (expand3x3): Conv2d(32, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (expand3x3_activation): ReLU(inplace)
        )
        (8): Fire(
          (squeeze): Conv2d(256, 48, kernel_size=(1, 1), stride=(1, 1))
          (squeeze_activation): ReLU(inplace)
          (expand1x1): Conv2d(48, 192, kernel_size=(1, 1), stride=(1, 1))
          (expand1x1_activation): ReLU(inplace)
          (expand3x3): Conv2d(48, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (expand3x3_activation): ReLU(inplace)
        )
        (9): Fire(
          (squeeze): Conv2d(384, 48, kernel_size=(1, 1), stride=(1, 1))
          (squeeze_activation): ReLU(inplace)
          (expand1x1): Conv2d(48, 192, kernel_size=(1, 1), stride=(1, 1))
          (expand1x1_activation): ReLU(inplace)
          (expand3x3): Conv2d(48, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (expand3x3_activation): ReLU(inplace)
        )
        (10): Fire(
          (squeeze): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1))
          (squeeze_activation): ReLU(inplace)
          (expand1x1): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1))
          (expand1x1_activation): ReLU(inplace)
          (expand3x3): Conv2d(64, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (expand3x3_activation): ReLU(inplace)
        )
        (11): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)
        (12): Fire(
          (squeeze): Conv2d(512, 64, kernel_size=(1, 1), stride=(1, 1))
          (squeeze_activation): ReLU(inplace)
          (expand1x1): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1))
          (expand1x1_activation): ReLU(inplace)
          (expand3x3): Conv2d(64, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (expand3x3_activation): ReLU(inplace)
        )
      )
      (classifier): Sequential(
        (0): Dropout(p=0.5)
        (1): Conv2d(512, 2, kernel_size=(1, 1), stride=(1, 1))
        (2): ReLU(inplace)
        (3): AdaptiveAvgPool2d(output_size=(1, 1))
      )
    )
    

    5.加载数据

    现在我们知道输入尺寸大小必须是什么,我们可以初始化数据转换,图像数据集和数据加载器。请注意,模型是使用硬编码标准化值进行预先训练的,如这里所述。

    # 数据扩充和训练规范化
    # 只需验证标准化
    data_transforms = {
        'train': transforms.Compose([
            transforms.RandomResizedCrop(input_size),
            transforms.RandomHorizontalFlip(),
            transforms.ToTensor(),
            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ]),
        'val': transforms.Compose([
            transforms.Resize(input_size),
            transforms.CenterCrop(input_size),
            transforms.ToTensor(),
            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ]),
    }
    
    print("Initializing Datasets and Dataloaders...")
    
    # 创建训练和验证数据集
    image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']}
    # 创建训练和验证数据加载器
    dataloaders_dict = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True, num_workers=4) for x in ['train', 'val']}
    
    # 检测我们是否有可用的GPU
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    
    • 输出结果

    Initializing Datasets and Dataloaders...
    

    6.创建优化器

    现在模型结构是正确的,微调和特征提取的最后一步是创建一个只更新所需参数的优化器。回想一下,在加载预训练模型之后,但在重塑之前,如果feature_extract = True,我们手动将所有参数的.requires_grad属性设置为False。然后重新初始化默认为.requires_grad = True的网络层参数。所以现在我们知道应该优化所有具有.requires_grad = True的参数。接下来,我们列出这些参数并将此列表输入到 SGD 算法构造器。

    要验证这一点,可以查看要学习的参数。微调时,此列表应该很长并包含所有模型参数。但是,当进行特征提取时,此列表应该很短并且仅包括重塑层的权重和偏差。

    # 将模型发送到GPU
    model_ft = model_ft.to(device)
    
    # 在此运行中收集要优化/更新的参数。 
    # 如果我们正在进行微调,我们将更新所有参数。 
    # 但如果我们正在进行特征提取方法,我们只会更新刚刚初始化的参数,即`requires_grad`的参数为True。
    params_to_update = model_ft.parameters()
    print("Params to learn:")
    if feature_extract:
        params_to_update = []
        for name,param in model_ft.named_parameters():
            if param.requires_grad == True:
                params_to_update.append(param)
                print("\t",name)
    else:
        for name,param in model_ft.named_parameters():
            if param.requires_grad == True:
                print("\t",name)
    
    # 观察所有参数都在优化
    optimizer_ft = optim.SGD(params_to_update, lr=0.001, momentum=0.9)
    

    *输出结果

    Params to learn:
             classifier.1.weight
             classifier.1.bias
    

    7.运行训练和验证

    最后一步是为模型设置损失,然后对设定的epoch数运行训练和验证函数。请注意,取决于epoch的数量,此步骤在CPU上可能需要执行一段时间。此外,默认的学习率对所有模型都不是最佳的,因此为了获得最大精度,有必要分别调整每个模型。

    # 设置损失函数
    criterion = nn.CrossEntropyLoss()
    
    # Train and evaluate
    model_ft, hist = train_model(model_ft, dataloaders_dict, criterion, optimizer_ft, num_epochs=num_epochs, is_inception=(model_name=="inception"))
    
    • 输出结果

    Epoch 0/14
    ----------
    train Loss: 0.5066 Acc: 0.7336
    val Loss: 0.3781 Acc: 0.8693
    
    Epoch 1/14
    ----------
    train Loss: 0.3227 Acc: 0.8893
    val Loss: 0.3254 Acc: 0.8889
    
    Epoch 2/14
    ----------
    train Loss: 0.2080 Acc: 0.9057
    val Loss: 0.3137 Acc: 0.9216
    
    Epoch 3/14
    ----------
    train Loss: 0.2211 Acc: 0.9262
    val Loss: 0.3126 Acc: 0.9020
    
    Epoch 4/14
    ----------
    train Loss: 0.1523 Acc: 0.9426
    val Loss: 0.3000 Acc: 0.9085
    
    Epoch 5/14
    ----------
    train Loss: 0.1480 Acc: 0.9262
    val Loss: 0.3167 Acc: 0.9150
    
    Epoch 6/14
    ----------
    train Loss: 0.1943 Acc: 0.9221
    val Loss: 0.3129 Acc: 0.9216
    
    Epoch 7/14
    ----------
    train Loss: 0.1247 Acc: 0.9549
    val Loss: 0.3139 Acc: 0.9150
    
    Epoch 8/14
    ----------
    train Loss: 0.1825 Acc: 0.9098
    val Loss: 0.3336 Acc: 0.9150
    
    Epoch 9/14
    ----------
    train Loss: 0.1436 Acc: 0.9303
    val Loss: 0.3295 Acc: 0.9281
    
    Epoch 10/14
    ----------
    train Loss: 0.1419 Acc: 0.9303
    val Loss: 0.3548 Acc: 0.8889
    
    Epoch 11/14
    ----------
    train Loss: 0.1407 Acc: 0.9549
    val Loss: 0.2953 Acc: 0.9216
    
    Epoch 12/14
    ----------
    train Loss: 0.0900 Acc: 0.9713
    val Loss: 0.3457 Acc: 0.9216
    
    Epoch 13/14
    ----------
    train Loss: 0.1283 Acc: 0.9467
    val Loss: 0.3451 Acc: 0.9281
    
    Epoch 14/14
    ----------
    train Loss: 0.0975 Acc: 0.9508
    val Loss: 0.3381 Acc: 0.9281
    
    Training complete in 0m 20s
    Best val Acc: 0.928105
    

    8.对比从头开始模型

    这部分内容出于好奇心理,看看如果我们不使用迁移学习,模型将如何学习。微调与特征提取的性能在很大程度上取决于数据集,但一般而言,两种迁移学习方法相对于从头开始训练模型,在训练时间和总体准确性方面产生了良好的结果。

    # 初始化用于此运行的模型的非预训练版本
    scratch_model,_ = initialize_model(model_name, num_classes, feature_extract=False, use_pretrained=False)
    scratch_model = scratch_model.to(device)
    scratch_optimizer = optim.SGD(scratch_model.parameters(), lr=0.001, momentum=0.9)
    scratch_criterion = nn.CrossEntropyLoss()
    _,scratch_hist = train_model(scratch_model, dataloaders_dict, scratch_criterion, scratch_optimizer, num_epochs=num_epochs, is_inception=(model_name=="inception"))
    
    # 绘制验证精度的训练曲线与转移学习方法
    # 和从头开始训练的模型的训练epochs的数量
    ohist = []
    shist = []
    
    ohist = [h.cpu().numpy() for h in hist]
    shist = [h.cpu().numpy() for h in scratch_hist]
    
    plt.title("Validation Accuracy vs. Number of Training Epochs")
    plt.xlabel("Training Epochs")
    plt.ylabel("Validation Accuracy")
    plt.plot(range(1,num_epochs+1),ohist,label="Pretrained")
    plt.plot(range(1,num_epochs+1),shist,label="Scratch")
    plt.ylim((0,1.))
    plt.xticks(np.arange(1, num_epochs+1, 1.0))
    plt.legend()
    plt.show()
    
    • 输出结果

      640?wx_fmt=png

    Epoch 0/14
    ----------
    train Loss: 0.7131 Acc: 0.4959
    val Loss: 0.6931 Acc: 0.4575
    
    Epoch 1/14
    ----------
    train Loss: 0.6930 Acc: 0.5041
    val Loss: 0.6931 Acc: 0.4575
    
    Epoch 2/14
    ----------
    train Loss: 0.6932 Acc: 0.5041
    val Loss: 0.6931 Acc: 0.4575
    
    Epoch 3/14
    ----------
    train Loss: 0.6932 Acc: 0.5041
    val Loss: 0.6931 Acc: 0.4575
    
    Epoch 4/14
    ----------
    train Loss: 0.6931 Acc: 0.5041
    val Loss: 0.6931 Acc: 0.4575
    
    Epoch 5/14
    ----------
    train Loss: 0.6929 Acc: 0.5041
    val Loss: 0.6931 Acc: 0.4575
    
    Epoch 6/14
    ----------
    train Loss: 0.6931 Acc: 0.5041
    val Loss: 0.6931 Acc: 0.4575
    
    Epoch 7/14
    ----------
    train Loss: 0.6918 Acc: 0.5041
    val Loss: 0.6934 Acc: 0.4575
    
    Epoch 8/14
    ----------
    train Loss: 0.6907 Acc: 0.5041
    val Loss: 0.6932 Acc: 0.4575
    
    Epoch 9/14
    ----------
    train Loss: 0.6914 Acc: 0.5041
    val Loss: 0.6927 Acc: 0.4575
    
    Epoch 10/14
    ----------
    train Loss: 0.6851 Acc: 0.5041
    val Loss: 0.6946 Acc: 0.4575
    
    Epoch 11/14
    ----------
    train Loss: 0.6841 Acc: 0.5041
    val Loss: 0.6942 Acc: 0.4575
    
    Epoch 12/14
    ----------
    train Loss: 0.6778 Acc: 0.5041
    val Loss: 0.7228 Acc: 0.4575
    
    Epoch 13/14
    ----------
    train Loss: 0.6874 Acc: 0.5041
    val Loss: 0.6931 Acc: 0.4575
    
    Epoch 14/14
    ----------
    train Loss: 0.6931 Acc: 0.5041
    val Loss: 0.6931 Acc: 0.4575
    
    Training complete in 0m 30s
    Best val Acc: 0.457516
    

    9.总结展望

    尝试运行其他模型,看看可以得到多好的正确率。另外,请注意特征提取花费的时间较少,因为在后向传播中我们不需要计算大部分的梯度。还有很多地方可以尝试。例如:

    • 在更难的数据集上运行此代码,查看迁移学习的更多好处。

    • 在新的领域(比如NLP,音频等)中,使用此处描述的方法,使用迁移学习更新不同的模型。

    • 一旦您对一个模型感到满意,可以将其导出为 ONNX 模型,或使用混合前端跟踪它以获得更快的速度和优化的机会。

     

    PyTorch 入门视频教程,欢迎B站观看,收藏,点赞:

    https://www.bilibili.com/video/av66421076

     

    欢迎关注磐创博客资源汇总站:
    http://docs.panchuang.net/

    欢迎关注PyTorch官方中文教程站:
    http://pytorch.panchuang.net/

    展开全文
  • ImageNet数据集应用

    万次阅读 2018-09-14 19:43:07
    图片数量最多,分辨率最高,含有的类别更多,有上千个图像类别。 每年ImageNet的项目组织都会举办一场ImageNet大规模视觉识别竞赛,从而会诞生许多图像识别模型。 下面介绍历代ImageNet图像识别模型: 2012年,...

    ImageNet数据集是为了促进计算机图像识别技术的发展而设立的一个大型图像数据集。

    其图片数量最多,分辨率最高,含有的类别更多,有上千个图像类别。

    每年ImageNet的项目组织都会举办一场ImageNet大规模视觉识别竞赛,从而会诞生许多图像识别模型。

    下面介绍历代ImageNet图像识别模型:

    2012年,多伦多大学的教授及其学生Alex参赛,使用深度学习处理图像识别问题,AlexNet网络模型将错误率从原来的25%降到了16%。下图是其网络结构

    输入图像会经过5层卷积层(11*11卷积,5*5卷积,3个3*3卷积),有些卷积层后面还使用了池化层。

    AlexNet的成果主要得益于以下几个方面:

    1)训练了较深层的卷积神经网络

    2)ImageNet提供了大量的训练样本,此外还使用了数据增强技术,因此神经网络的过拟合现象不严重

    3)使用了dropout等技术,进一步降低了过拟合

     

    2014年,ILSVRC竞赛上又出现了两个引人关注的模型:VGGNet和GoogleNet。相比AlexNet 16%的错误率,VGGNet把错误率降到了7%,GoogleNet则是6%。

    VGGNet的网络结构示意图如下:

    conv-3-512表示使用了3*3的卷积,卷积之后的通道数为512,从图中可以清晰的看出VGGNet的网络结构

    2015年又新提出了一种名为深度残差网络(ResNet),深度残差网络比之前的任何模型都要深,它可以训练100层,甚至1000层,把错误率从6%降到了3.57%,也是ImageNet数据集上,机器表现首次优于人类。

    展开全文
  • Imagenet数据集

    万次阅读 2017-06-17 22:53:18
    MNIST将初学者领进了深度学习领域,而Imagenet数据集对深度学习的浪潮起了巨大的推动作用。深度学习领域大牛Hinton在2012年发表的论文《ImageNet Classification with Deep Convolutional Neural Networks》在计算机...
  • Dataset之ImageNetImageNet数据集简介、下载、使用方法之详细攻略 目录 lmageNet 数据集简介 1、ImageNet数据集的意义 2、ImageNet的数据结构——层次结构及其1000个类别 3、ImageNet数据集与ILSVRC...
  •     译者 | 刘畅 林椿眄 整理 | Jane 出品 | AI科技大本营 ...Google 最新的研究成果 BERT 的热度还没褪去,大家都还在讨论是否 ImageNet 带来的预训练模型之风真的要进入 NLP 领域了。如今,Facebook AI...
  • ImageNet调查报告

    千次阅读 2019-05-05 15:48:19
    ImageNet大规模视觉识别挑战赛即“ILSVRC”(ImageNet Large Scale Visual Recognition Challenge),它是基于ImageNet图像数据库的国际计算机视觉识别竞赛。ILSVRC从2010年开始举办,并逐渐发展为国际计算机视觉领域...
  • ImageNet冠军模型解析

    千次阅读 2017-07-01 14:32:24
    导语ImageNet是斯坦福大学李飞飞教授主持设立的关于计算机视觉的数据库,里面含有大量的图片,这些图片分为上万个类别,是深度学习领域一个非常火热的竞赛。近年来由于硬件水平的提高,以及大数据量的爆发式增长,给...
  • 使用ImageNet、CIFAR、MNIST 或 IMDB 这些数据集时,你是不是会潜意识中假设,这些数据集中的类标签都是正确的? 然而,你可能不知道:ImageNet数据集中至少有十万个标签是存在问题的。 尽管大量的研究都在使用...
  • 作者训练了一个面向数量为 1.2 百万的高分辨率的图像数据集 ImageNet, 图像的种类为 1000 种的深度卷积神经网络。 下载链接:NIPS-2012-imagenet-classification-with-deep-convolutional-neural-networks-Paper....
  • 这篇文章是何恺明组做的一个偏实验的工作,主要是探究ImageNet预训练的模型,在迁移到其他任务比如目标检测,分割等会不会比从头训练模型的要更好。可以总结一下就是 在数据集充分的条件下,各个任务里,从头训练的...
  • 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 ...训练ImageNet数据集三、测试多张图片总结 环境 Ubuntu16.04 Python3.6 Cuda10 一、代码下载 代码下载址:https://github.com/AlexeyAB/da
  • (由于博客系统问题,部分公式、图片和格式有可能存在显示问题,请参阅原书了解详情) 1.1ImageNet简述 2012年,深度学习领域的大牛Hinton发表的论文《ImageNet Classification with Deep Convolutional Neu...
  • ImageNet Classification with Deep Convolutional Neural Networks Alex Krizhevsky, Ilya Sutskever, Geoffrey E. Hinton University of Toronto University of Toronto,U of T, UToronto or Toronto:多伦多大学...
  • ImageNet 数据集的下载及处理

    千次阅读 2021-01-19 17:36:02
    imagenet数据集下载并且导入 一、首先将数据集从官网下载下来 这里给出官网下载的链接:http://www.image-net.org/download-images 如果想要下载原始图片,需要注册一个账号,注册邮箱需要带有 edu,即学校邮箱。...
  • 可打印版本附pdf下载链接 近日,谷歌大脑团队公布了Vision Transformer(ViT)进阶版ViT-G/14,参数高达20亿的CV模型,经过30亿张图片的训练,刷新了ImageNet上最高准确率记录——90.45%,此前的ViT取得的最高准确率...
  • #将单通道图像转化为3通道图像 file = r'D:\image' floder = [cla for cla in os.listdir(file)] total = 0 flodernumber =...for cla in floder: ...共处理图片数量: ',total)
  • 一个计算机视觉系统识别项目, 是目前世界上图像识别最大的数据库,具有超过22,000个分类的标签化的高分辨率的图片,总计达1千5百多万张。 2. CNN 深度学习算法在图像处理领域的一个应用,由神经网络模型发展而来,...
  • 何恺明,RBG,Piotr Dollár。 三位从Mask R-CNN就开始合作的大神搭档,刚刚再次联手,一文“终结”了ImageNet预训练时代。...这篇重新思考ImageNet预训练(Rethinking ImageNet Pre-training)就给出...
  • ImageNet数据集中共有~1000类的图片集,涵盖了动物、植物、物品等图片。这里,VGG16的模型是事先用Keras训练好的。我们要做的事情,就是在该模型的基础上,用新任务中的花卉图片重新训练网络的一小部分,从而迁移到...
  • 运用CNN对ImageNet进行图像分类

    万次阅读 多人点赞 2016-12-08 10:18:01
    运用CNN对ImageNet进行图像分类 译者注:本篇翻译自Alex Krizhevsky, Ilya Sutskever以及Geoffrey E.Hinton的论文 ImageNet Classification with Deep Convolutional Neural Networks. 该论文在智能单元专栏文章《CS...
  • 文章作者:Tyan 博客:noahsnail.com &amp;nbsp;|&amp;nbsp; CSDN &amp;nbsp;|&amp;nbsp; 简书 翻译论文汇总:...ImageNet Classification with Deep Convolutional Neural Networks...
  • ImageNet历届冠军作品 keras了解 一.ImageNet历届冠军作品 在多届冠军作品中,我挑选了四个最有特点的网络进行了学习。其中包 括:AlexNet、GoogleNet、ResNet和一个亚军作品VGG。 下面依次介绍以上网络各自的...
  • miniImageNet包含100类共60000张彩色图片,其中每类有600个样本,每张图片的大小被resize到了84×84。这里,这个数据集的训练集和测试集的类别划分为:5:1。相比于CIFAR10数据集,miniImageNet数据集更加复杂,但更...
  • ImageNet Classification with Deep Convolutional Neural Networks 译文
  • 目的:使用自己的数据集,使用caffe自带的ImageNet网络结构,训练测试 参考官网链接:...我们的数据集图片分10个类,每个类有100个train图片(train文件夹下,一共1000),

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,867
精华内容 4,746
关键字:

imagenet图片数量