efficientNet的原理及实现

  Model Scaling(模型扩展)一直以来都是提高卷积神经网络效果的重要方法。比如说ResNet可以增加层数从ResNet18扩展到ResNet200,GPipe通过对基线网络的四倍扩展在ImageNet上可以达到84.3%的准确率。本节要介绍的最新网络结构——EfficientNet,就是一种标准化模型扩展的结果。通过下面这张图,我们可以直观的感受一下EfficientNet B0-B7在ImageNet上的效果:对于ImageNet历史上各种网络,EfficientNet可以算是在效果上实现了碾压。

     因为效果太好,kaggle上的一众视觉比赛都开始在用。

什么是EfficientNet?

     一般我们可以通过调整输入图像大小、网络深度和宽度(即卷积通道数)来实现对卷积网络的扩展。在EfficientNet之前,很多的研究工作都只是针对这三个维度中某一个维度进行调整尝试,限于计算资源和人工调参等因素,很少有研究对这三个维度进行综合调整的。

     所以EfficientNet的设想就是能否设计一个标准化的卷积网络扩展方法,既可以实现较高的准确率,也可以充分节省算力资源。因而问题可以描述成如何平衡分辨率、深度和宽度这三个维度,实现卷积网络在准确率和效率上的优化。

     EfficientNet给出的解决方案是提出一种模型复合缩放方法(compound scaling method),如下图所示:

     图a是一个基线网络,图b、c和d这三个网络分别对该基线网络的宽度、深度和输入分辨率进行扩展,而图d网络就是EfficientNet的主要思想,综合宽度、深度和分辨率对网络进行复合扩展。

     一个卷积网络可以定义为如下式子:

     其中Fi表述对第i层的卷积运算,Li表述层Fi在第i个阶段被重复了Li次。<Hi,Wi,Ci>表示第i层输入的shape。EfficientNet的设想是一个卷积网络所有的卷积层必须通过相同的比例常数进行统一扩展,所以,一个模型扩展问题可以用数学语言描述为:

     其中d、w和r分别表示网络深度、宽度和分辨率。该式表示为在给定计算内存和效率的约束下,如何优化参数d、w和r来实现最好的模型准确率。

     EfficientNet的规范化复合调参方法使用了一个复合系数Φ对三个参数进行复合调整:

     其中α,β,γ作为常数可以由小型的网格搜索来确定,Φ为复合系数,用来控制模型的扩增。以上就是EfficientNet的复合扩展方式,但这仅仅是一种模型扩展方法,EfficientNet到底是什么样的一种Net我们还没有说到。换句话说,要实现state of the art的模型效果,光有扩展方式肯定不行,我们必须给这种方式提供一个比较好的基线网络。

     EfficientNet使用了MobileNet V2中的MBConv作为模型的主干网络,同时也使用了SENet中的squeeze and excitation方法对网络结构进行了优化。MBConv的主要结构如下图右所示,相较于MobileNet V1,MBConv的设计使得MobileNet V2能够更好利用残差连接带来的效果提升。具体细节可参考MobileNet V2论文。

     SENet的squeeze and excitation操作如下图所示,具体可参考SENet论文,这里不做详述。

     所以综合MBConv和squeeze and excitation方法的EfficientNet-B0的网络结构如下表所示:

     那么对于EfficientNet-B0这样一个baseline基线网络,如何使用复合扩展法对该网络进行扩展呢?这里主要分两步走。首先是将复合系数Φ固定为1,先假设有两倍以上的计算资源可用,然后对α,β,γ进行网络搜索。对于EfficientNet-B0网络,在约束条件为

时,α,β,γ分别取1.2、1.1和1.15时效果最佳。第二步则是固定α,β,γ,通过复合调整公式调整Φ对基线网络进行扩展得到B1至B7网络。于是就有了本文开头那张图,EfficientNet在ImageNet上的效果碾压过往各种经典网络。EfficientNet-B7在top1准确率上达到了84.4%,在top5准确率上达到了97.1%,同时模型规模要比此前的GPipe小了8.4倍:

 EfficientNet有8个系列,分别从b0-b7,,其中b0是baseline,b1-b7都是在b0基础上对深度、宽度和分辨率进行调整。从官方源码上,可以得到以下参数。其中,参数分别是宽度的相关系数,深度的相关系数,输入图片的分辨率和dropout的比例。这些参数如何得到的呢,就是通过刚刚介绍的AutoML进行搜索出来的。

基于EfficientNet的迁移学习

     普通人来训练和扩展EfficientNet实在太昂贵,一个值得尝试的方法就是迁移学习。下面使用EfficientNet-B0进行猫狗分类的迁移学习训练。

     先下载基于keras的EfficientNet迁移学习库:

!git clone https://github.com/Tony607/efficientnet_keras_transfer_learning%cd efficientnet_keras_transfer_learning/

     导入相关模块:

from efficientnet import EfficientNetB0 as Netfrom efficientnet import center_crop_and_resize, preprocess_input# loading pretrained conv base modelconv_base = Net(weights='imagenet', include_top=False, input_shape=input_shape)

     搭建基于EfficientNet-B0的迁移学习网络:

from tensorflow.keras import modelsfrom tensorflow.keras import layersdropout_rate = 0.2model = models.Sequential()model.add(conv_base)model.add(layers.GlobalMaxPooling2D(name='gap'))# model.add(layers.Flatten(name='flatten'))if dropout_rate > 0: model.add(layers.Dropout(dropout_rate, name='dropout_out'))# model.add(layers.Dense(256, activation='relu', name='fc1'))model.add(layers.Dense(2, activation='softmax', name='fc_out'))

     冻结卷积层不参与训练:

conv_base.trainable = False

     下载猫狗数据:

!wget https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_3367a.zip!unzip -qq kagglecatsanddogs_3367a.zip -d dog_vs_cat

     使用keras的ImageDataGenerator模块加载数据并训练:

from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(    rescale=1.0 / 255,    rotation_range=40,    width_shift_range=0.2,    height_shift_range=0.2,    shear_range=0.2,    zoom_range=0.2,    horizontal_flip=True,    fill_mode='nearest',)
# Note that the validation data should not be augmented!test_datagen = ImageDataGenerator(rescale=1.0 / 255)train_generator = train_datagen.flow_from_directory(    # This is the target directory    train_dir,    # All images will be resized to target height and width.    target_size=(height, width),    batch_size=batch_size,    # Since we use categorical_crossentropy loss, we need categorical labels    class_mode='categorical',)
validation_generator = test_datagen.flow_from_directory(    validation_dir,    target_size=(height, width),    batch_size=batch_size,    class_mode='categorical',)
model.compile(    loss='categorical_crossentropy',    optimizer=optimizers.RMSprop(lr=2e-5),    metrics=['acc'],)
history = model.fit_generator(    train_generator,    steps_per_epoch=NUM_TRAIN // batch_size,    epochs=epochs,    validation_data=validation_generator,    validation_steps=NUM_TEST // batch_size,    verbose=1,    use_multiprocessing=True,    workers=4,)

     20个epoch之后验证集准确率达到0.82。训练集和验证集损失以及准确率:

     有学术和技术问题的同学可以加我微信进入机器学习实验室读者交流群。加微信后说明来意,最好做个简单的自我介绍,让我有个印象。

 

参考资料:

Tan M, Le Q V. EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks[J]. arXiv preprint arXiv:1905.11946, 2019.

Sandler M, Howard A, Zhu M, et al. Mobilenetv2: Inverted residuals and linear bottlenecks[C]//Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2018: 4510-4520.

Hu J, Shen L, Sun G. Squeeze-and-excitation networks[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2018: 7132-7141.

https://github.com/Tony607/efficientnet_keras_transfer_learning

github paper

链接:https://www.lijl888.com/archives/720

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EfficientNet是一种高效且有效的神经网络模型,在处理图像分类等计算机视觉任务中表现出色。它通过使用复合系数来平衡多个维度的模型扩展,以在有限的计算资源下实现更好的性能。EfficientNet在PyTorch中的实现非常方便。 在PyTorch中实现EfficientNet的首要步骤是安装所需的软件包和库。你需要安装torchvision、PIL和timm等库来对EfficientNet进行实现和训练。这些库可以通过pip等方式进行安装。 接下来,你需要从timm库中导入EfficientNet模型。可以使用如下代码段导入模型: ```python import timm model = timm.create_model('efficientnet_b0', pretrained=True) ``` 在这里,我们选择使用EfficientNet-B0模型,并加载预训练权重。timm库支持从EfficientNet-B0到EfficientNet-B7不同的模型规模。 然后,你可以将图像数据加载到模型中进行推理或训练,如下所示: ```python import torch from torchvision import transforms from PIL import Image # 加载和预处理图像 image = Image.open('image.jpg') preprocess = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) input_data = preprocess(image) input_batch = input_data.unsqueeze(0) # 添加batch维度 # 将图像数据输入模型进行推理 with torch.no_grad(): output = model(input_batch) # 获取预测结果 probabilities = torch.nn.functional.softmax(output[0], dim=0) ``` 在以上代码中,我们加载并预处理了一张图像,将其输入模型进行推理,并得到了预测结果。你可以根据自己的需求对预测结果进行解读和处理。 总之,通过使用PyTorch和timm库,你可以方便地实现和使用EfficientNet模型进行图像分类任务,从而获得高性能和高效率的计算机视觉应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值