python神经网络Keras GhostNet模型的实现

目录
  • 什么是GhostNet模型
  • GhostNet模型的实现思路
    • 1、Ghost Module
    • 2、Ghost Bottlenecks
    • 3、Ghostnet的构建
  • GhostNet的代码构建
    • 1、模型代码的构建
    • 2、Yolov4上的应用

什么是GhostNet模型

GhostNet是华为诺亚方舟实验室提出来的一个非常有趣的网络,我们一起来学习一下。

2020年,华为新出了一个轻量级网络,命名为GhostNet。

在优秀CNN模型中,特征图存在冗余是非常重要的。如图所示,这个是对ResNet-50第一个残差块特征图进行可视化的结果,当我们给一个神经网络输入一张图片时,我们可以获得特别多的特征图。

利用小扳手连接起来的两幅特征图,它们的相似性就特别高,这个就是神经网络中存在的特征图冗杂的情况。

作者将相似的特征图认为是彼此的Ghost,所以这个网络就叫做GhostNet(误)。

在GhostNet这篇论文里面,作者认为可以使用一些计算量更低(Cheap Operations)的操作去生成这些冗余的特征图,这样就可以在保证良好检测效果的情况下,减少模型的参数量与提高模型的执行速度。

源码下载

GhostNet模型的实现思路

1、Ghost Module

通过上述的介绍,我们了解到了,GhostNet的核心思想就是使用一些计算量更低(Cheap Operations)的操作去生成这些冗余的特征图

在论文中,作者设计了一个名为Ghost Module的模块,他的功能是代替普通卷积

Ghost Module将普通卷积分为两部分,首先进行一个普通的1x1卷积,这是一个少量卷积,比如正常使用32通道的卷积,这里就用16通道的卷积,这个1x1卷积的作用类似于特征整合,生成输入特征层的特征浓缩

然后我们再进行深度可分离卷积,这个深度可分离卷积是逐层卷积,它也就是我们上面提到的Cheap Operations。它利用上一步获得的特征浓缩生成Ghost特征图

因此,如果我们从整体上去看这个Ghost Module,它其实就是两步简单思想的汇总:

1、利用1x1卷积获得输入特征的必要特征浓缩

2、利用深度可分离卷积获得特征浓缩的相似特征图(Ghost)。

Ghost Module的实现代码如下:

def _ghost_module(inputs, exp, kernel, dw_kernel, ratio, strides=1,
                    padding='same',use_bias=False, relu=True):
    output_channels = math.ceil(exp * 1.0 / ratio)

    x = Conv2D(output_channels, kernel, strides=strides, padding=padding, use_bias=use_bias)(inputs)
    x = BatchNormalization()(x)
    if relu:
        x = Activation('relu')(x)
    dw = DepthwiseConv2D(dw_kernel, strides, padding=padding, depth_multiplier=ratio-1, use_bias=use_bias)(x)
    dw = BatchNormalization()(dw)
    if relu:
        dw = Activation('relu')(dw)

    x = Concatenate(axis=-1)([x,dw])
    x = Lambda(slices, arguments={'n':exp})(x)

    return x

2、Ghost Bottlenecks

Ghost Bottlenecks是由Ghost Module组成的瓶颈结构,就像这样。

其实本质上就是用Ghost Module,来代替瓶颈结构里面的普通卷积。

Ghost Bottlenecks可以分为两个部分,分别是主干部分和残差边部分,包含Ghost Module的,我们称它为主干部分。

Ghost Bottlenecks有两个种类,如下图所示,当我们需要对特征层的宽高进行压缩的时候,我们会设置这个Ghost Bottlenecks的Stride=2,即步长为2

此时我们会Bottlenecks里面多添加一些卷积层,在主干部分里,我们会在两个Ghost Module中添加一个步长为2x2的深度可分离卷积进行特征层的宽高压缩。在残差边部分,我们也会添加上一个步长为2x2的深度可分离卷积和1x1的普通卷积。

Ghost Bottlenecks的实现代码如下:

def _ghost_bottleneck(inputs, output_channel, hidden_channel, kernel, ghost_kernel, strides, ratio, squeeze):

    input_shape = K.int_shape(inputs)       # 获取输入张量的尺寸

    x = _ghost_module(inputs, hidden_channel, [1,1], ghost_kernel, ratio)

    if strides > 1:
        x = DepthwiseConv2D(kernel, strides, padding='same', depth_multiplier=1, use_bias=False)(x)
        x = BatchNormalization()(x)

    if squeeze:
        x = _squeeze(x, hidden_channel, 4)

    x = _ghost_module(x, output_channel, [1,1], ghost_kernel, ratio, relu=False)

    if strides == 1 and input_shape[-1] == output_channel:
        res = inputs
    else:
        res = DepthwiseConv2D(kernel, strides=strides, padding='same', depth_multiplier=1, use_bias=False)(inputs)
        res = BatchNormalization()(res)
        res = Conv2D(output_channel, (1, 1), padding='same', strides=(1, 1), use_bias=False)(res)
        res = BatchNormalization()(res)
    x = Add()([res, x])

    return x

3、Ghostnet的构建

整个Ghostnet的构建方式如列表所示:

可以看到,整个Ghostnet都是由Ghost Bottlenecks进行组成的。

当一张图片输入到Ghostnet当中时,我们首先进行一个16通道的普通1x1卷积块(卷积+标准化+激活函数)

之后我们就开始Ghost Bottlenecks的堆叠了,利用Ghost Bottlenecks,我们最终获得了一个7x7x160的特征层(当输入是224x224x3的时候)

然后我们会利用一个1x1的卷积块进行通道数的调整,此时我们可以获得一个7x7x960的特征层。

之后我们进行一次全局平均池化,然后再利用一个1x1的卷积块进行通道数的调整,获得一个1x1x1280的特征层。

然后平铺后进行全连接就可以进行分类了。

GhostNet的代码构建

1、模型代码的构建

GhostNet的实现代码如下,该代码是Ghostnet在YoloV4上的应用,可以参考一下:

import math
import warnings

import numpy as np
import tensorflow as tf
from keras import backend as K
from keras.applications.imagenet_utils import decode_predictions
from keras.initializers import random_normal
from keras.layers import (Activation, Add, BatchNormalization, Concatenate,
                          Conv2D, DepthwiseConv2D, GlobalAveragePooling2D,
                          Lambda, Multiply, Reshape)

def slices(dw, n):
    return dw[:,:,:,:n]

def _make_divisible(v, divisor, min_value=None):
    if min_value is None:
        min_value = divisor
    new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)
    if new_v < 0.9 * v:
        new_v += divisor
    return new_v

def _squeeze(inputs, hidden_channel, ratio, block_id, sub_block_id):
    x = GlobalAveragePooling2D()(inputs)
    x = Reshape((1,1,-1))(x)

    x = Conv2D(_make_divisible(hidden_channel/ratio, 4), (1,1), strides=(1,1), padding='same', kernel_initializer=random_normal(stddev=0.02),
            name="blocks."+str(block_id)+"."+str(sub_block_id)+".se.conv_reduce")(x)
    x = Activation('relu')(x)

    x = Conv2D(hidden_channel, (1,1),strides=(1,1), padding='same', kernel_initializer=random_normal(stddev=0.02),
            name="blocks."+str(block_id)+"."+str(sub_block_id)+".se.conv_expand")(x)
    x = Activation('hard_sigmoid')(x)

    x = Multiply()([inputs, x])    # inputs和x逐元素相乘
    return x

def _ghost_module(inputs, exp, ratio, block_id, sub_block_id, part, kernel_size=1, dw_size=3, stride=1, relu=True):
    output_channels = math.ceil(exp * 1.0 / ratio)

    x = Conv2D(output_channels, kernel_size, strides=stride, padding="same", use_bias=False, kernel_initializer=random_normal(stddev=0.02),
            name="blocks."+str(block_id)+"."+str(sub_block_id)+".ghost"+str(part)+".primary_conv.0")(inputs)
    x = BatchNormalization(name="blocks."+str(block_id)+"."+str(sub_block_id)+".ghost"+str(part)+".primary_conv.1")(x)
    if relu:
        x = Activation('relu')(x)

    dw = DepthwiseConv2D(dw_size, 1, padding="same", depth_multiplier=ratio-1, use_bias=False, depthwise_initializer=random_normal(stddev=0.02),
            name="blocks."+str(block_id)+"."+str(sub_block_id)+".ghost"+str(part)+".cheap_operation.0")(x)
    dw = BatchNormalization(name="blocks."+str(block_id)+"."+str(sub_block_id)+".ghost"+str(part)+".cheap_operation.1")(dw)
    if relu:
        dw = Activation('relu')(dw)

    x = Concatenate(axis=-1)([x,dw])
    x = Lambda(slices, arguments={'n':exp})(x)
    return x

def _ghost_bottleneck(inputs, output_channel, hidden_channel, kernel, strides, ratio, squeeze, block_id, sub_block_id):
    input_shape = K.int_shape(inputs)

    x = _ghost_module(inputs, hidden_channel, ratio, block_id, sub_block_id, 1)

    if strides > 1:
        x = DepthwiseConv2D(kernel, strides, padding='same', depth_multiplier=1, use_bias=False, depthwise_initializer=random_normal(stddev=0.02),
                name="blocks."+str(block_id)+"."+str(sub_block_id)+".conv_dw")(x)
        x = BatchNormalization(name="blocks."+str(block_id)+"."+str(sub_block_id)+".bn_dw")(x)

    if squeeze:
        x = _squeeze(x, hidden_channel, 4, block_id, sub_block_id)

    x = _ghost_module(x, output_channel, ratio, block_id, sub_block_id, 2, relu=False)

    if strides == 1 and input_shape[-1] == output_channel:
        res = inputs
    else:
        res = DepthwiseConv2D(kernel, strides=strides, padding='same', depth_multiplier=1, use_bias=False, depthwise_initializer=random_normal(stddev=0.02),
                name="blocks."+str(block_id)+"."+str(sub_block_id)+".shortcut.0")(inputs)
        res = BatchNormalization(name="blocks."+str(block_id)+"."+str(sub_block_id)+".shortcut.1")(res)
        res = Conv2D(output_channel, (1, 1), padding='same', strides=(1, 1), use_bias=False, kernel_initializer=random_normal(stddev=0.02),
                name="blocks."+str(block_id)+"."+str(sub_block_id)+".shortcut.2")(res)
        res = BatchNormalization(name="blocks."+str(block_id)+"."+str(sub_block_id)+".shortcut.3")(res)
    x = Add()([res, x])

    return x

def Ghostnet(inputs):
    x = Conv2D(16, (3, 3), padding="same", strides=(2, 2), use_bias=False, kernel_initializer=random_normal(stddev=0.02), name="conv_stem")(inputs)
    x = BatchNormalization(name="bn1")(x)
    x = Activation('relu')(x)

    x = _ghost_bottleneck(x, 16, 16, (3, 3), strides=1, ratio=2, squeeze=False, block_id=0, sub_block_id=0)

    x = _ghost_bottleneck(x, 24, 48, (3, 3), strides=2, ratio=2, squeeze=False, block_id=1, sub_block_id=0)
    x = _ghost_bottleneck(x, 24, 72, (3, 3), strides=1, ratio=2, squeeze=False, block_id=2, sub_block_id=0)

    x = _ghost_bottleneck(x, 40, 72, (5, 5), strides=2, ratio=2, squeeze=True, block_id=3, sub_block_id=0)
    x = _ghost_bottleneck(x, 40, 120, (5, 5), strides=1, ratio=2, squeeze=True, block_id=4, sub_block_id=0)
    feat1 = x

    x = _ghost_bottleneck(x, 80, 240, (3, 3), strides=2, ratio=2, squeeze=False, block_id=5, sub_block_id=0)
    x = _ghost_bottleneck(x, 80, 200, (3, 3), strides=1, ratio=2, squeeze=False, block_id=6, sub_block_id=0)
    x = _ghost_bottleneck(x, 80, 184, (3, 3), strides=1, ratio=2, squeeze=False, block_id=6, sub_block_id=1)
    x = _ghost_bottleneck(x, 80, 184, (3, 3), strides=1, ratio=2, squeeze=False, block_id=6, sub_block_id=2)
    x = _ghost_bottleneck(x, 112, 480, (3, 3), strides=1, ratio=2, squeeze=True, block_id=6, sub_block_id=3)
    x = _ghost_bottleneck(x, 112, 672, (3, 3), strides=1, ratio=2, squeeze=True, block_id=6, sub_block_id=4)
    feat2 = x

    x = _ghost_bottleneck(x, 160, 672, (5, 5), strides=2, ratio=2, squeeze=True, block_id=7, sub_block_id=0)
    x = _ghost_bottleneck(x, 160, 960, (5, 5), strides=1, ratio=2, squeeze=False, block_id=8, sub_block_id=0)
    x = _ghost_bottleneck(x, 160, 960, (5, 5), strides=1, ratio=2, squeeze=True, block_id=8, sub_block_id=1)
    x = _ghost_bottleneck(x, 160, 960, (5, 5), strides=1, ratio=2, squeeze=False, block_id=8, sub_block_id=2)
    x = _ghost_bottleneck(x, 160, 960, (5, 5), strides=1, ratio=2, squeeze=True, block_id=8, sub_block_id=3)
    feat3 = x

    return feat1,feat2,feat3

2、Yolov4上的应用

作为一个轻量级网络,我把Ghostnet和Mobilenet放在一起,作为Yolov4的主干网络进行特征提取。

对于yolov4来讲,我们需要利用主干特征提取网络获得的三个有效特征进行加强特征金字塔的构建

我们通过上述代码可以取出三个有效特征层,我们可以利用这三个有效特征层替换原来yolov4主干网络CSPdarknet53的有效特征层。

为了进一步减少参数量,我们可以使用深度可分离卷积代替yoloV3中用到的普通卷积。

最终Ghostnet-Yolov4的构建代码如下:

from functools import wraps

from keras import backend as K
from keras.initializers import random_normal
from keras.layers import (Activation, BatchNormalization, Concatenate, Conv2D,
                          DepthwiseConv2D, Input, Lambda, MaxPooling2D,
                          UpSampling2D)
from keras.layers.normalization import BatchNormalization
from keras.models import Model
from keras.regularizers import l2
from utils.utils import compose

from nets.ghostnet import Ghostnet
from nets.mobilenet_v1 import MobileNetV1
from nets.mobilenet_v2 import MobileNetV2
from nets.mobilenet_v3 import MobileNetV3
from nets.yolo_training import yolo_loss

def relu6(x):
    return K.relu(x, max_value=6)

#------------------------------------------------------#
#   单次卷积DarknetConv2D
#   如果步长为2则自己设定padding方式。
#------------------------------------------------------#
@wraps(Conv2D)
def DarknetConv2D(*args, **kwargs):
    darknet_conv_kwargs = {'kernel_initializer' : random_normal(stddev=0.02), 'kernel_regularizer': l2(5e-4)}
    darknet_conv_kwargs['padding'] = 'valid' if kwargs.get('strides')==(2,2) else 'same'
    darknet_conv_kwargs.update(kwargs)
    return Conv2D(*args, **darknet_conv_kwargs)

#---------------------------------------------------#
#   卷积块 -> 卷积 + 标准化 + 激活函数
#   DarknetConv2D + BatchNormalization + Relu6
#---------------------------------------------------#
def DarknetConv2D_BN_Leaky(*args, **kwargs):
    no_bias_kwargs = {'use_bias': False}
    no_bias_kwargs.update(kwargs)
    return compose(
        DarknetConv2D(*args, **no_bias_kwargs),
        BatchNormalization(),
        Activation(relu6))

#---------------------------------------------------#
#   深度可分离卷积块
#   DepthwiseConv2D + BatchNormalization + Relu6
#---------------------------------------------------#
def _depthwise_conv_block(inputs, pointwise_conv_filters, alpha = 1,
                          depth_multiplier=1, strides=(1, 1)):

    pointwise_conv_filters = int(pointwise_conv_filters * alpha)

    x = DepthwiseConv2D((3, 3), depthwise_initializer=random_normal(stddev=0.02),
                        padding='same',
                        depth_multiplier=depth_multiplier,
                        strides=strides,
                        use_bias=False)(inputs)

    x = BatchNormalization()(x)
    x = Activation(relu6)(x)

    x = DarknetConv2D(pointwise_conv_filters, (1, 1),
                    padding='same',
                    use_bias=False,
                    strides=(1, 1))(x)
    x = BatchNormalization()(x)
    return Activation(relu6)(x)

#---------------------------------------------------#
#   进行五次卷积
#---------------------------------------------------#
def make_five_convs(x, num_filters):
    # 五次卷积
    x = DarknetConv2D_BN_Leaky(num_filters, (1,1))(x)
    x = _depthwise_conv_block(x, num_filters*2,alpha=1)
    x = DarknetConv2D_BN_Leaky(num_filters, (1,1))(x)
    x = _depthwise_conv_block(x, num_filters*2,alpha=1)
    x = DarknetConv2D_BN_Leaky(num_filters, (1,1))(x)
    return x

#---------------------------------------------------#
#   Panet网络的构建,并且获得预测结果
#---------------------------------------------------#
def yolo_body(input_shape, anchors_mask, num_classes, backbone="mobilenetv1", alpha=1):
    inputs = Input(input_shape)
    #---------------------------------------------------#
    #   生成mobilnet的主干模型,获得三个有效特征层。
    #---------------------------------------------------#
    if backbone=="mobilenetv1":
        #---------------------------------------------------#
        #   52,52,256;26,26,512;13,13,1024
        #---------------------------------------------------#
        feat1,feat2,feat3 = MobileNetV1(inputs, alpha=alpha)
    elif backbone=="mobilenetv2":
        #---------------------------------------------------#
        #   52,52,32;26,26,92;13,13,320
        #---------------------------------------------------#
        feat1,feat2,feat3 = MobileNetV2(inputs, alpha=alpha)
    elif backbone=="mobilenetv3":
        #---------------------------------------------------#
        #   52,52,40;26,26,112;13,13,160
        #---------------------------------------------------#
        feat1,feat2,feat3 = MobileNetV3(inputs, alpha=alpha)
    elif backbone=="ghostnet":
        #---------------------------------------------------#
        #   52,52,40;26,26,112;13,13,160
        #---------------------------------------------------#
        feat1,feat2,feat3 = Ghostnet(inputs)
    else:
        raise ValueError('Unsupported backbone - `{}`, Use mobilenetv1, mobilenetv2, mobilenetv3, ghostnet.'.format(backbone))

    P5 = DarknetConv2D_BN_Leaky(int(512* alpha), (1,1))(feat3)
    P5 = _depthwise_conv_block(P5, int(1024* alpha))
    P5 = DarknetConv2D_BN_Leaky(int(512* alpha), (1,1))(P5)
    maxpool1 = MaxPooling2D(pool_size=(13,13), strides=(1,1), padding='same')(P5)
    maxpool2 = MaxPooling2D(pool_size=(9,9), strides=(1,1), padding='same')(P5)
    maxpool3 = MaxPooling2D(pool_size=(5,5), strides=(1,1), padding='same')(P5)
    P5 = Concatenate()([maxpool1, maxpool2, maxpool3, P5])
    P5 = DarknetConv2D_BN_Leaky(int(512* alpha), (1,1))(P5)
    P5 = _depthwise_conv_block(P5, int(1024* alpha))
    P5 = DarknetConv2D_BN_Leaky(int(512* alpha), (1,1))(P5)

    P5_upsample = compose(DarknetConv2D_BN_Leaky(int(256* alpha), (1,1)), UpSampling2D(2))(P5)

    P4 = DarknetConv2D_BN_Leaky(int(256* alpha), (1,1))(feat2)
    P4 = Concatenate()([P4, P5_upsample])
    P4 = make_five_convs(P4,int(256* alpha))

    P4_upsample = compose(DarknetConv2D_BN_Leaky(int(128* alpha), (1,1)), UpSampling2D(2))(P4)

    P3 = DarknetConv2D_BN_Leaky(int(128* alpha), (1,1))(feat1)
    P3 = Concatenate()([P3, P4_upsample])
    P3 = make_five_convs(P3,int(128* alpha))

    #---------------------------------------------------#
    #   第三个特征层
    #   y3=(batch_size,52,52,3,85)
    #---------------------------------------------------#
    P3_output = _depthwise_conv_block(P3, int(256* alpha))
    P3_output = DarknetConv2D(len(anchors_mask[0])*(num_classes+5), (1,1))(P3_output)

    P3_downsample = _depthwise_conv_block(P3, int(256* alpha), strides=(2,2))
    P4 = Concatenate()([P3_downsample, P4])
    P4 = make_five_convs(P4,int(256* alpha))

    #---------------------------------------------------#
    #   第二个特征层
    #   y2=(batch_size,26,26,3,85)
    #---------------------------------------------------#
    P4_output = _depthwise_conv_block(P4, int(512* alpha))
    P4_output = DarknetConv2D(len(anchors_mask[1])*(num_classes+5), (1,1))(P4_output)

    P4_downsample = _depthwise_conv_block(P4, int(512* alpha), strides=(2,2))
    P5 = Concatenate()([P4_downsample, P5])
    P5 = make_five_convs(P5,int(512* alpha))

    #---------------------------------------------------#
    #   第一个特征层
    #   y1=(batch_size,13,13,3,85)
    #---------------------------------------------------#
    P5_output = _depthwise_conv_block(P5, int(1024* alpha))
    P5_output = DarknetConv2D(len(anchors_mask[2])*(num_classes+5), (1,1))(P5_output)

    return Model(inputs, [P5_output, P4_output, P3_output])

以上就是python神经网络Keras GhostNet模型的复现详解的详细内容,更多关于Keras GhostNet模型复现的资料请关注我们其它相关文章!

(0)

相关推荐

  • 浅谈keras使用预训练模型vgg16分类,损失和准确度不变

    问题keras使用预训练模型vgg16分类,损失和准确度不变. 细节:使用keras训练一个两类数据,正负比例1:3,在vgg16后添加了几个全链接并初始化了.并且对所有层都允许训练. 但是准确度一直是0.75. 数据预先处理已经检查过格式正确 再将模型中relu改成sigmoid就正常了. 数据处理程序 import os import pickle import numpy as np import DataFile import SelectiveSearch import Generat

  • keras自定义损失函数并且模型加载的写法介绍

    keras自定义函数时候,正常在模型里自己写好自定义的函数,然后在模型编译的那行代码里写上接口即可.如下所示,focal_loss和fbeta_score是我们自己定义的两个函数,在model.compile加入它们,metrics里'accuracy'是keras自带的度量函数. def focal_loss(): ... return xx def fbeta_score(): ... return yy model.compile(optimizer=Adam(lr=0.0001), lo

  • Keras神经网络efficientnet模型搭建yolov3目标检测平台

    目录 什么是EfficientNet模型 源码下载 EfficientNet模型的实现思路 1.EfficientNet模型的特点 2.EfficientNet网络的结构 EfficientNet的代码构建 1.模型代码的构建 2.Yolov3上的应用 什么是EfficientNet模型 2019年,谷歌新出EfficientNet,在其它网络的基础上,大幅度的缩小了参数的同时提高了预测准确度,简直太强了,我这样的强者也要跟着做下去 EfficientNet,网络如其名,这个网络非常的有效率,怎

  • Keras预训练的ImageNet模型实现分类操作

    本文主要介绍通过预训练的ImageNet模型实现图像分类,主要使用到的网络结构有:VGG16.InceptionV3.ResNet50.MobileNet. 代码: import keras import numpy as np from keras.applications import vgg16, inception_v3, resnet50, mobilenet # 加载模型 vgg_model = vgg16.VGG16(weights='imagenet') inception_mo

  • Keras 实现加载预训练模型并冻结网络的层

    在解决一个任务时,我会选择加载预训练模型并逐步fine-tune.比如,分类任务中,优异的深度学习网络有很多. ResNet, VGG, Xception等等... 并且这些模型参数已经在imagenet数据集中训练的很好了,可以直接拿过来用. 根据自己的任务,训练一下最后的分类层即可得到比较好的结果.此时,就需要"冻结"预训练模型的所有层,即这些层的权重永不会更新. 以Xception为例: 加载预训练模型: from tensorflow.python.keras.applicat

  • Keras保存模型并载入模型继续训练的实现

    我们以MNIST手写数字识别为例 import numpy as np from keras.datasets import mnist from keras.utils import np_utils from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD # 载入数据 (x_train,y_train),(x_test,y_test) = mnist

  • python神经网络Keras GhostNet模型的实现

    目录 什么是GhostNet模型 GhostNet模型的实现思路 1.Ghost Module 2.Ghost Bottlenecks 3.Ghostnet的构建 GhostNet的代码构建 1.模型代码的构建 2.Yolov4上的应用 什么是GhostNet模型 GhostNet是华为诺亚方舟实验室提出来的一个非常有趣的网络,我们一起来学习一下. 2020年,华为新出了一个轻量级网络,命名为GhostNet. 在优秀CNN模型中,特征图存在冗余是非常重要的.如图所示,这个是对ResNet-50

  • python神经网络AlexNet分类模型训练猫狗数据集

    目录 什么是AlexNet模型 训练前准备 1.数据集处理 2.创建Keras的AlexNet模型 开始训练 1.训练的主函数 2.Keras数据生成器 3.主训练函数全部代码 训练结果 最近在做实验室的工作,要用到分类模型,老板一星期催20次,我也是无语了,上有对策下有政策,在下先找个猫猫狗狗的数据集练练手,快乐极了 什么是AlexNet模型 AlexNet是2012年ImageNet竞赛冠军获得者Hinton和他的学生Alex Krizhevsky设计的.也是在那年之后,更多的更深的神经网络

  • python神经网络MobileNetV3 large模型的复现详解

    目录 神经网络学习小记录38——MobileNetV3(large)模型的复现详解 学习前言什么是MobileNetV3代码下载MobileNetV3(large)的网络结构1.MobileNetV3(large)的整体结构2.MobileNetV3特有的bneck结构 网络实现代码 学习前言 为了防止某位我的粉丝寒假没有办法正常工作,我赶紧看了看MobilenetV3. 什么是MobileNetV3 最新的MobileNetV3的被写在了论文<Searching for MobileNetV3

  • python神经网络Keras常用学习率衰减汇总

    目录 前言 为什么要调控学习率 下降方式汇总 2.指数型下降 3.余弦退火衰减 4.余弦退火衰减更新版 前言 增加了论文中的余弦退火下降方式.如图所示: 学习率是深度学习中非常重要的一环,好好学习吧! 为什么要调控学习率 在深度学习中,学习率的调整非常重要. 学习率大有如下优点: 1.加快学习速率. 2.帮助跳出局部最优值. 但存在如下缺点: 1.导致模型训练不收敛. 2.单单使用大学习率容易导致模型不精确. 学习率小有如下优点: 1.帮助模型收敛,有助于模型细化. 2.提高模型精度. 但存在如

  • python神经网络MobileNetV3 small模型的复现详解

    目录 什么是MobileNetV3 large与small的区别 MobileNetV3(small)的网络结构 1.MobileNetV3(small)的整体结构 2.MobileNetV3特有的bneck结构 网络实现代码 什么是MobileNetV3 不知道咋地,就是突然想把small也一起写了. 最新的MobileNetV3的被写在了论文<Searching for MobileNetV3>中. 它是mobilnet的最新版,据说效果还是很好的. 作为一种轻量级网络,它的参数量还是一如

  • python神经网络Keras搭建RFBnet目标检测平台

    目录 什么是RFBnet目标检测算法 RFBnet实现思路 一.预测部分 1.主干网络介绍 2.从特征获取预测结果 3.预测结果的解码 4.在原图上进行绘制 二.训练部分 1.真实框的处理 2.利用处理完的真实框与对应图片的预测结果计算loss 训练自己的RFB模型 一.数据集的准备 二.数据集的处理 三.开始网络训练 四.训练结果预测 什么是RFBnet目标检测算法 RFBnet是SSD的一种加强版,主要是利用了膨胀卷积这一方法增大了感受野,相比于普通的ssd,RFBnet也是一种加强吧 RF

  • python神经网络Inception ResnetV2模型复现详解

    目录 什么是Inception ResnetV2 Inception-ResNetV2的网络结构 1.Stem的结构: 2.Inception-resnet-A的结构: 3.Inception-resnet-B的结构: 4.Inception-resnet-C的结构: 全部代码 什么是Inception ResnetV2 Inception ResnetV2是Inception ResnetV1的一个加强版,两者的结构差距不大,如果大家想了解Inception ResnetV1可以看一下我的另一

  • Python搭建Keras CNN模型破解网站验证码的实现

    在本项目中,将会用Keras来搭建一个稍微复杂的CNN模型来破解以上的验证码.验证码如下: 利用Keras可以快速方便地搭建CNN模型,本项目搭建的CNN模型如下: 将数据集分为训练集和测试集,占比为8:2,该模型训练的代码如下: # -*- coding: utf-8 -*- import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from matplotlib im

  • python神经网络Keras构建CNN网络训练

    目录 Keras中构建CNN的重要函数 1.Conv2D 2.MaxPooling2D 3.Flatten 全部代码 利用Keras构建完普通BP神经网络后,还要会构建CNN Keras中构建CNN的重要函数 1.Conv2D Conv2D用于在CNN中构建卷积层,在使用它之前需要在库函数处import它. from keras.layers import Conv2D 在实际使用时,需要用到几个参数. Conv2D( nb_filter = 32, nb_row = 5, nb_col = 5

  • python神经网络Keras实现GRU及其参数量

    目录 什么是GRU 1.GRU单元的输入与输出 2.GRU的门结构 3.GRU的参数量计算 a.更新门 b.重置门 c.全部参数量 在Keras中实现GRU 实现代码 什么是GRU GRU是LSTM的一个变种. 传承了LSTM的门结构,但是将LSTM的三个门转化成两个门,分别是更新门和重置门. 1.GRU单元的输入与输出 下图是每个GRU单元的结构. 在n时刻,每个GRU单元的输入有两个: 当前时刻网络的输入值Xt: 上一时刻GRU的输出值ht-1: 输出有一个: 当前时刻GRU输出值ht: 2

随机推荐