神经网络学习小记录26——Keras 利用efficientnet系列模型搭建efficientnet-yolov3目标检测平台

  • 学习前言
  • 什么是EfficientNet模型
  • 源码下载
  • EfficientNet模型的实现思路
    • 1、EfficientNet模型的特点
    • 2、EfficientNet网络的结构
  • EfficientNet的代码构建
    • 1、模型代码的构建
    • 2、Yolov3上的应用

学习前言

2019年,谷歌新出EfficientNet,在其它网络的基础上,大幅度的缩小了参数的同时提高了预测准确度,简直太强了,我这样的强者也要跟着做下去!

什么是EfficientNet模型

2019年,谷歌新出EfficientNet,网络如其名,这个网络非常的有效率,怎么理解有效率这个词呢,我们从卷积神经网络的发展来看:
从最初的VGG16发展到如今的Xception,人们慢慢发现,提高神经网络的性能不仅仅在于堆叠层数,更重要的几点是:

1、网络要可以训练,可以收敛。
2、参数量要比较小,方便训练,提高速度。
3、创新神经网络的结构,学到更重要的东西。

而EfficientNet很好的做到了这一点,它利用更少的参数量(关系到训练、速度)得到最好的识别度(学到更重要的特点)

源码下载

https://github.com/bubbliiiing/efficientnet-yolo3-keras

EfficientNet模型的实现思路

1、EfficientNet模型的特点

EfficientNet模型具有很独特的特点,这个特点是参考其它优秀神经网络设计出来的。经典的神经网络特点如下:
1、利用残差神经网络增大神经网络的深度,通过更深的神经网络实现特征提取。
2、改变每一层提取的特征层数,实现更多层的特征提取,得到更多的特征,提升宽度。
3、通过增大输入图片的分辨率也可以使得网络可以学习与表达的东西更加丰富,有利于提高精确度

EfficientNet就是将这三个特点结合起来,通过一起缩放baseline模型MobileNet中就通过缩放α实现缩放模型,不同的α有不同的模型精度,α=1时为baseline模型;ResNet其实也是有一个baseline模型,在baseline的基础上通过改变图片的深度实现不同的模型实现),同时调整深度宽度输入图片的分辨率完成一个优秀的网络设计。

EfficientNet的效果如下:

在EfficientNet模型中,其使用一组固定的缩放系数统一缩放网络深度、宽度和分辨率。
假设想使用 2N倍的计算资源,我们可以简单的对网络深度扩大αN倍、宽度扩大βN 、图像尺寸扩大γN倍,这里的α,β,γ都是由原来的小模型上做微小的网格搜索决定的常量系数。
如图为EfficientNet的设计思路,从三个方面同时拓充网络的特性。

2、EfficientNet网络的结构

EfficientNet一共由一个Stem + 16个Blocks + Con2D + GlobalAveragePooling2D + Dense组成,其核心内容是16个Blocks,其它的结构与常规的卷积神经网络差距不大。

下图展示的是EfficientNet-B0也就是EfficientNet的设计基线的结构:

第一部分是Stem,用于进行初步的特征提取,实际内容是一个卷积+标准化+激活函数。
第二部分是16个Blocks,是efficientnet特有的特征提取结构,在Blocks堆叠的过程中完成高效的特征提取。
第三部分是Con2D + GlobalAveragePooling2D + Dense,是efficientnet的分类头,在构建efficientnet-yolov3的时候没有使用到。

整个efficientnet由7个部分的Block组成,对应上图的Block1-Block7,其中每个部分的Block的的参数如下:

DEFAULT_BLOCKS_ARGS = [{'kernel_size': 3, 'repeats': 1, 'filters_in': 32, 'filters_out': 16,'expand_ratio': 1, 'id_skip': True, 'strides': 1, 'se_ratio': 0.25},{'kernel_size': 3, 'repeats': 2, 'filters_in': 16, 'filters_out': 24,'expand_ratio': 6, 'id_skip': True, 'strides': 2, 'se_ratio': 0.25},{'kernel_size': 5, 'repeats': 2, 'filters_in': 24, 'filters_out': 40,'expand_ratio': 6, 'id_skip': True, 'strides': 2, 'se_ratio': 0.25},{'kernel_size': 3, 'repeats': 3, 'filters_in': 40, 'filters_out': 80,'expand_ratio': 6, 'id_skip': True, 'strides': 2, 'se_ratio': 0.25},{'kernel_size': 5, 'repeats': 3, 'filters_in': 80, 'filters_out': 112,'expand_ratio': 6, 'id_skip': True, 'strides': 1, 'se_ratio': 0.25},{'kernel_size': 5, 'repeats': 4, 'filters_in': 112, 'filters_out': 192,'expand_ratio': 6, 'id_skip': True, 'strides': 2, 'se_ratio': 0.25},{'kernel_size': 3, 'repeats': 1, 'filters_in': 192, 'filters_out': 320,'expand_ratio': 6, 'id_skip': True, 'strides': 1, 'se_ratio': 0.25}
]

Block的通用结构如下,其总体的设计思路是一个结合深度可分离卷积注意力机制逆残差结构,每个Block可分为两部分:

  • 左边为主干部分,首先利用1x1卷积升维,再使用3x3或者5x5的逐层卷积进行跨特征点的特征提取。完成特征提取后添加一个通道注意力机制,最后利用1x1卷积降维
  • 右边为残差边,不进行处理。


Block实现代码如下

#-------------------------------------------------#
#   efficient_block
#-------------------------------------------------#
def block(inputs, activation_fn=tf.nn.swish, drop_rate=0., name='',filters_in=32, filters_out=16, kernel_size=3, strides=1,expand_ratio=1, se_ratio=0., id_skip=True):filters = filters_in * expand_ratio#-------------------------------------------------##   利用Inverted residuals#   part1 利用1x1卷积进行通道数上升#-------------------------------------------------#if expand_ratio != 1:x = layers.Conv2D(filters, 1,padding='same',use_bias=False,kernel_initializer=CONV_KERNEL_INITIALIZER,name=name + 'expand_conv')(inputs)x = layers.BatchNormalization(axis=3, name=name + 'expand_bn')(x)x = layers.Activation(activation_fn, name=name + 'expand_activation')(x)else:x = inputs#------------------------------------------------------##   如果步长为2x2的话,利用深度可分离卷积进行高宽压缩#   part2 利用3x3卷积对每一个channel进行卷积#------------------------------------------------------#if strides == 2:x = layers.ZeroPadding2D(padding=correct_pad(x, kernel_size),name=name + 'dwconv_pad')(x)conv_pad = 'valid'else:conv_pad = 'same'x = layers.DepthwiseConv2D(kernel_size,strides=strides,padding=conv_pad,use_bias=False,depthwise_initializer=CONV_KERNEL_INITIALIZER,name=name + 'dwconv')(x)x = layers.BatchNormalization(axis=3, name=name + 'bn')(x)x = layers.Activation(activation_fn, name=name + 'activation')(x)#------------------------------------------------------##   完成深度可分离卷积后#   对深度可分离卷积的结果施加注意力机制#------------------------------------------------------#if 0 < se_ratio <= 1:filters_se = max(1, int(filters_in * se_ratio))se = layers.GlobalAveragePooling2D(name=name + 'se_squeeze')(x)se = layers.Reshape((1, 1, filters), name=name + 'se_reshape')(se)#------------------------------------------------------##   通道先压缩后上升,最后利用sigmoid将值固定到0-1之间#------------------------------------------------------#se = layers.Conv2D(filters_se, 1,padding='same',activation=activation_fn,kernel_initializer=CONV_KERNEL_INITIALIZER,name=name + 'se_reduce')(se)se = layers.Conv2D(filters, 1,padding='same',activation='sigmoid',kernel_initializer=CONV_KERNEL_INITIALIZER,name=name + 'se_expand')(se)x = layers.multiply([x, se], name=name + 'se_excite')#------------------------------------------------------##   part3 利用1x1卷积进行通道下降#------------------------------------------------------#x = layers.Conv2D(filters_out, 1,padding='same',use_bias=False,kernel_initializer=CONV_KERNEL_INITIALIZER,name=name + 'project_conv')(x)x = layers.BatchNormalization(axis=3, name=name + 'project_bn')(x)#------------------------------------------------------##   part4 如果满足残差条件,那么就增加残差边#------------------------------------------------------#if (id_skip is True and strides == 1 and filters_in == filters_out):if drop_rate > 0:x = layers.Dropout(drop_rate,noise_shape=(None, 1, 1, 1),name=name + 'drop')(x)x = layers.add([x, inputs], name=name + 'add')return x

EfficientNet的代码构建

1、模型代码的构建

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

import math
from copy import deepcopyimport tensorflow as tf
from keras import backend, layers#-------------------------------------------------#
#   一共七个大结构块,每个大结构块都有特定的参数
#-------------------------------------------------#
DEFAULT_BLOCKS_ARGS = [{'kernel_size': 3, 'repeats': 1, 'filters_in': 32, 'filters_out': 16,'expand_ratio': 1, 'id_skip': True, 'strides': 1, 'se_ratio': 0.25},{'kernel_size': 3, 'repeats': 2, 'filters_in': 16, 'filters_out': 24,'expand_ratio': 6, 'id_skip': True, 'strides': 2, 'se_ratio': 0.25},{'kernel_size': 5, 'repeats': 2, 'filters_in': 24, 'filters_out': 40,'expand_ratio': 6, 'id_skip': True, 'strides': 2, 'se_ratio': 0.25},{'kernel_size': 3, 'repeats': 3, 'filters_in': 40, 'filters_out': 80,'expand_ratio': 6, 'id_skip': True, 'strides': 2, 'se_ratio': 0.25},{'kernel_size': 5, 'repeats': 3, 'filters_in': 80, 'filters_out': 112,'expand_ratio': 6, 'id_skip': True, 'strides': 1, 'se_ratio': 0.25},{'kernel_size': 5, 'repeats': 4, 'filters_in': 112, 'filters_out': 192,'expand_ratio': 6, 'id_skip': True, 'strides': 2, 'se_ratio': 0.25},{'kernel_size': 3, 'repeats': 1, 'filters_in': 192, 'filters_out': 320,'expand_ratio': 6, 'id_skip': True, 'strides': 1, 'se_ratio': 0.25}
]#-------------------------------------------------#
#   Kernel的初始化器
#-------------------------------------------------#
CONV_KERNEL_INITIALIZER = {'class_name': 'VarianceScaling','config': {'scale': 2.0,'mode': 'fan_out','distribution': 'normal'}
}#-------------------------------------------------#
#   用于计算卷积层的padding的大小
#-------------------------------------------------#
def correct_pad(inputs, kernel_size):img_dim = 1input_size = backend.int_shape(inputs)[img_dim:(img_dim + 2)]if isinstance(kernel_size, int):kernel_size = (kernel_size, kernel_size)if input_size[0] is None:adjust = (1, 1)else:adjust = (1 - input_size[0] % 2, 1 - input_size[1] % 2)correct = (kernel_size[0] // 2, kernel_size[1] // 2)return ((correct[0] - adjust[0], correct[0]),(correct[1] - adjust[1], correct[1]))#-------------------------------------------------#
#   该函数的目的是保证filter的大小可以被8整除
#-------------------------------------------------#
def round_filters(filters, divisor, width_coefficient):filters *= width_coefficientnew_filters = max(divisor, int(filters + divisor / 2) // divisor * divisor)if new_filters < 0.9 * filters:new_filters += divisorreturn int(new_filters)#-------------------------------------------------#
#   计算模块的重复次数
#-------------------------------------------------#
def round_repeats(repeats, depth_coefficient):return int(math.ceil(depth_coefficient * repeats))#-------------------------------------------------#
#   efficient_block
#-------------------------------------------------#
def block(inputs, activation_fn=tf.nn.swish, drop_rate=0., name='',filters_in=32, filters_out=16, kernel_size=3, strides=1,expand_ratio=1, se_ratio=0., id_skip=True):filters = filters_in * expand_ratio#-------------------------------------------------##   利用Inverted residuals#   part1 利用1x1卷积进行通道数上升#-------------------------------------------------#if expand_ratio != 1:x = layers.Conv2D(filters, 1,padding='same',use_bias=False,kernel_initializer=CONV_KERNEL_INITIALIZER,name=name + 'expand_conv')(inputs)x = layers.BatchNormalization(axis=3, name=name + 'expand_bn')(x)x = layers.Activation(activation_fn, name=name + 'expand_activation')(x)else:x = inputs#------------------------------------------------------##   如果步长为2x2的话,利用深度可分离卷积进行高宽压缩#   part2 利用3x3卷积对每一个channel进行卷积#------------------------------------------------------#if strides == 2:x = layers.ZeroPadding2D(padding=correct_pad(x, kernel_size),name=name + 'dwconv_pad')(x)conv_pad = 'valid'else:conv_pad = 'same'x = layers.DepthwiseConv2D(kernel_size,strides=strides,padding=conv_pad,use_bias=False,depthwise_initializer=CONV_KERNEL_INITIALIZER,name=name + 'dwconv')(x)x = layers.BatchNormalization(axis=3, name=name + 'bn')(x)x = layers.Activation(activation_fn, name=name + 'activation')(x)#------------------------------------------------------##   完成深度可分离卷积后#   对深度可分离卷积的结果施加注意力机制#------------------------------------------------------#if 0 < se_ratio <= 1:filters_se = max(1, int(filters_in * se_ratio))se = layers.GlobalAveragePooling2D(name=name + 'se_squeeze')(x)se = layers.Reshape((1, 1, filters), name=name + 'se_reshape')(se)#------------------------------------------------------##   通道先压缩后上升,最后利用sigmoid将值固定到0-1之间#------------------------------------------------------#se = layers.Conv2D(filters_se, 1,padding='same',activation=activation_fn,kernel_initializer=CONV_KERNEL_INITIALIZER,name=name + 'se_reduce')(se)se = layers.Conv2D(filters, 1,padding='same',activation='sigmoid',kernel_initializer=CONV_KERNEL_INITIALIZER,name=name + 'se_expand')(se)x = layers.multiply([x, se], name=name + 'se_excite')#------------------------------------------------------##   part3 利用1x1卷积进行通道下降#------------------------------------------------------#x = layers.Conv2D(filters_out, 1,padding='same',use_bias=False,kernel_initializer=CONV_KERNEL_INITIALIZER,name=name + 'project_conv')(x)x = layers.BatchNormalization(axis=3, name=name + 'project_bn')(x)#------------------------------------------------------##   part4 如果满足残差条件,那么就增加残差边#------------------------------------------------------#if (id_skip is True and strides == 1 and filters_in == filters_out):if drop_rate > 0:x = layers.Dropout(drop_rate,noise_shape=(None, 1, 1, 1),name=name + 'drop')(x)x = layers.add([x, inputs], name=name + 'add')return xdef EfficientNet(width_coefficient,depth_coefficient,drop_connect_rate=0.2,depth_divisor=8,activation_fn=tf.nn.swish,blocks_args=DEFAULT_BLOCKS_ARGS,inputs=None,**kwargs):img_input = inputs#-------------------------------------------------##   创建stem部分#   416,416,3 -> 208,208,32#-------------------------------------------------#x = img_inputx = layers.ZeroPadding2D(padding=correct_pad(x, 3),name='stem_conv_pad')(x)x = layers.Conv2D(round_filters(32, depth_divisor, width_coefficient), 3,strides=2,padding='valid',use_bias=False,kernel_initializer=CONV_KERNEL_INITIALIZER,name='stem_conv')(x)x = layers.BatchNormalization(axis=3, name='stem_bn')(x)x = layers.Activation(activation_fn, name='stem_activation')(x)#-------------------------------------------------##   进行一个深度的copy#-------------------------------------------------#blocks_args = deepcopy(blocks_args)#-------------------------------------------------##   计算总的efficient_block的数量#-------------------------------------------------#b = 0blocks = float(sum(args['repeats'] for args in blocks_args))feats = []filters_outs = []#------------------------------------------------------------------------------##   对结构块参数进行循环、一共进行7个大的结构块。#   每个大结构块下会重复小的efficient_block、每个大结构块的shape变化为:#   208,208,32 -> 208,208,16 -> 104,104,24 -> 52,52,40 #   -> 26,26,80 -> 26,26,112 -> 13,13,192 -> 13,13,320#   输入为208,208,32,最终获得三个shape的有效特征层#   104,104,24、26,26,112、13,13,320#------------------------------------------------------------------------------#for (i, args) in enumerate(blocks_args):assert args['repeats'] > 0args['filters_in'] = round_filters(args['filters_in'], depth_divisor, width_coefficient)args['filters_out'] = round_filters(args['filters_out'], depth_divisor, width_coefficient)for j in range(round_repeats(args.pop('repeats'), depth_coefficient)):if j > 0:args['strides'] = 1args['filters_in'] = args['filters_out']x = block(x, activation_fn, drop_connect_rate * b / blocks,name='block{}{}_'.format(i + 1, chr(j + 97)), **args)b += 1feats.append(x)if i == 2 or i == 4 or i == 6:filters_outs.append(args['filters_out'])return feats, filters_outsdef EfficientNetB0(inputs=None, **kwargs):return EfficientNet(1.0, 1.0, inputs=inputs, **kwargs)def EfficientNetB1(inputs=None, **kwargs):return EfficientNet(1.0, 1.1, inputs=inputs, **kwargs)def EfficientNetB2(inputs=None, **kwargs):return EfficientNet(1.1, 1.2, inputs=inputs, **kwargs)def EfficientNetB3(inputs=None, **kwargs):return EfficientNet(1.2, 1.4, inputs=inputs, **kwargs)def EfficientNetB4(inputs=None, **kwargs):return EfficientNet(1.4, 1.8, inputs=inputs, **kwargs)def EfficientNetB5(inputs=None, **kwargs):return EfficientNet(1.6, 2.2, inputs=inputs, **kwargs)def EfficientNetB6(inputs=None, **kwargs):return EfficientNet(1.8, 2.6, inputs=inputs, **kwargs)def EfficientNetB7(inputs=None, **kwargs):return EfficientNet(2.0, 3.1, inputs=inputs, **kwargs)

2、Yolov3上的应用


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

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

为了进一步减少参数量,我们减少了yolov3中用到的普通卷积的通道数。

最终EfficientNet-YoloV3的构建代码如下:

from functools import wrapsfrom keras.initializers import random_normal
from keras.layers import (BatchNormalization, Concatenate, Conv2D, Input,Lambda, LeakyReLU, UpSampling2D)
from keras.models import Model
from keras.regularizers import l2
from utils.utils import composefrom nets.efficientnet import (EfficientNetB0, EfficientNetB1, EfficientNetB2,EfficientNetB3, EfficientNetB4, EfficientNetB5,EfficientNetB6, EfficientNetB7)
from nets.yolo_training import yolo_lossEfficient = [EfficientNetB0,EfficientNetB1,EfficientNetB2,EfficientNetB3,EfficientNetB4,EfficientNetB5,EfficientNetB6,EfficientNetB7]#------------------------------------------------------#
#   单次卷积DarknetConv2D
#   如果步长为2则自己设定padding方式。
#   测试中发现没有l2正则化效果更好,所以去掉了l2正则化
#------------------------------------------------------#
@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 + LeakyReLU
#---------------------------------------------------#
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(),LeakyReLU(alpha=0.1))#---------------------------------------------------#
#   特征层->最后的输出
#---------------------------------------------------#
def make_five_conv(x, num_filters):x = DarknetConv2D_BN_Leaky(num_filters, (1,1))(x)x = DarknetConv2D_BN_Leaky(num_filters*2, (3,3))(x)x = DarknetConv2D_BN_Leaky(num_filters, (1,1))(x)x = DarknetConv2D_BN_Leaky(num_filters*2, (3,3))(x)x = DarknetConv2D_BN_Leaky(num_filters, (1,1))(x)return xdef make_yolo_head(x, num_filters, out_filters):y = DarknetConv2D_BN_Leaky(num_filters*2, (3,3))(x)y = DarknetConv2D(out_filters, (1,1))(y)return y#---------------------------------------------------#
#   FPN网络的构建,并且获得预测结果
#---------------------------------------------------#
def yolo_body(input_shape, anchors_mask, num_classes, phi = 0):inputs      = Input(input_shape)#---------------------------------------------------#   #   生成darknet53的主干模型#   获得三个有效特征层,他们的shape分别是:#   C3 为 52,52,256#   C4 为 26,26,512#   C5 为 13,13,1024#---------------------------------------------------#feats, filters_outs = Efficient[phi](inputs = inputs)feat1 = feats[2]feat2 = feats[4]feat3 = feats[6]#---------------------------------------------------##   第一个特征层#   y1=(batch_size,13,13,3,85)#---------------------------------------------------## 13,13,1024 -> 13,13,512 -> 13,13,1024 -> 13,13,512 -> 13,13,1024 -> 13,13,512x   = make_five_conv(feat3, int(filters_outs[2]))P5  = make_yolo_head(x, int(filters_outs[2]), len(anchors_mask[0]) * (num_classes+5))# 13,13,512 -> 13,13,256 -> 26,26,256x   = compose(DarknetConv2D_BN_Leaky(int(filters_outs[1]), (1,1)), UpSampling2D(2))(x)# 26,26,256 + 26,26,512 -> 26,26,768x   = Concatenate()([x, feat2])#---------------------------------------------------##   第二个特征层#   y2=(batch_size,26,26,3,85)#---------------------------------------------------## 26,26,768 -> 26,26,256 -> 26,26,512 -> 26,26,256 -> 26,26,512 -> 26,26,256x   = make_five_conv(x, int(filters_outs[1]))P4  = make_yolo_head(x, int(filters_outs[1]), len(anchors_mask[1]) * (num_classes+5))# 26,26,256 -> 26,26,128 -> 52,52,128x   = compose(DarknetConv2D_BN_Leaky(int(filters_outs[0]), (1,1)), UpSampling2D(2))(x)# 52,52,128 + 52,52,256 -> 52,52,384x   = Concatenate()([x, feat1])#---------------------------------------------------##   第三个特征层#   y3=(batch_size,52,52,3,85)#---------------------------------------------------## 52,52,384 -> 52,52,128 -> 52,52,256 -> 52,52,128 -> 52,52,256 -> 52,52,128x   = make_five_conv(x, int(filters_outs[0]))P3  = make_yolo_head(x, int(filters_outs[0]), len(anchors_mask[2]) * (num_classes+5))return Model(inputs, [P5, P4, P3])

神经网络学习小记录26——Keras 利用efficientnet系列模型搭建yolov3目标检测平台相关推荐

  1. 神经网络学习小记录50——Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台

    神经网络学习小记录50--Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台 学习前言 什么是EfficientNet模型 源码下载 EfficientNet模型的实现思 ...

  2. 神经网络学习小记录58——Keras GhostNet模型的复现详解

    神经网络学习小记录58--Keras GhostNet模型的复现详解 学习前言 什么是GhostNet模型 源码下载 GhostNet模型的实现思路 1.Ghost Module 2.Ghost Bo ...

  3. 神经网络学习小记录45——Keras常用学习率下降方式汇总

    神经网络学习小记录45--Keras常用学习率下降方式汇总 2020年5月19日更新 前言 为什么要调控学习率 下降方式汇总 1.阶层性下降 2.指数型下降 3.余弦退火衰减 4.余弦退火衰减更新版 ...

  4. 神经网络学习小记录37——Keras实现GRU与GRU参数量详解

    神经网络学习小记录37--Keras实现GRU与GRU参数量详解 学习前言 什么是GRU 1.GRU单元的输入与输出 2.GRU的门结构 3.GRU的参数量计算 a.更新门 b.重置门 c.全部参数量 ...

  5. 神经网络学习小记录39——MobileNetV3(small)模型的复现详解

    神经网络学习小记录39--MobileNetV3(small)模型的复现详解 学习前言 什么是MobileNetV3 代码下载 large与small的区别 MobileNetV3(small)的网络 ...

  6. 神经网络学习小记录14——slim常用函数与如何训练、保存模型

    神经网络学习小记录14--slim训练与保存模型 学习前言 slim是什么 slim常用函数 1.slim = tf.contrib.slim 2.slim.create_global_step 3. ...

  7. 神经网络学习小记录2——利用tensorflow构建循环神经网络(RNN)

    神经网络学习小记录2--利用tensorflow构建循环神经网络(RNN) 学习前言 RNN简介 tensorflow中RNN的相关函数 tf.nn.rnn_cell.BasicLSTMCell tf ...

  8. 神经网络学习小记录19——微调VGG分类模型训练自己的数据(猫狗数据集)

    神经网络学习小记录19--微调VGG分类模型训练自己的数据(猫狗数据集) 注意事项 学习前言 什么是VGG16模型 VGG模型的复杂程度 训练前准备 1.数据集处理 2.创建Keras的VGG模型 3 ...

  9. 神经网络学习小记录-番外篇——常见问题汇总

    神经网络学习小记录-番外篇--常见问题汇总 前言 问题汇总 1.下载问题 a.代码下载 b. 权值下载 c. 数据集下载 2.环境配置问题 a.20系列所用的环境 b.30系列显卡环境配置 c.CPU ...

最新文章

  1. ALV标准范例Demo汇总
  2. Java中this的简单应用
  3. Fiori elements:when smart template is entered for first time, no data filled
  4. 供应商寄售库存管理_【论文解读】物流联合外包下库存管理模式对供应链运作的影响...
  5. Spring Boot Actuator监控关闭
  6. Tensorflow代码转pytorch代码 函数的转换
  7. 记忆化搜索=搜索的形式+动态规划的思想(来自百度百科)
  8. Python判断字符串是否为数字(数字、小数、负数、负小数、0)
  9. python读取txt文件数据并存到list中
  10. 金士顿DT100G3(16G) U盘修复
  11. 图像/视频无损放大,用一个工具就够了
  12. 知乎被爆裁员20%锤子60%,BAT裁员缩招为啥急于否认?
  13. php自定义建站系统,PbootCMS(开源免费PHP建站系统) V2.0.9 官方版
  14. 小白初上手HTML+CSS 仿写小米官网logo动画
  15. 交替性注意力_注意力不足的小朋友通常都是持续性专注力
  16. 查看mysql数据库的版本
  17. 让Qt程序适配高分辨率屏幕,解决软件界面错乱异常
  18. 人工智能为什么要做全栈工程师
  19. MATLAB下批量修改图片名称
  20. 58同城和赶集网要合并了!

热门文章

  1. cass生成曲线要素_使用CASS6_0获取道路平曲线测设元素的解决方案
  2. 阿里巴巴的名字是怎么来的?只因为马云发现很多外国人都能读出来
  3. kubectl命令管理kubernetes对象的三种方式
  4. 简单总结文件上传漏洞
  5. Android仿IOS封装通用的弹出框Dialog和底部弹出列表选择框 仿美团顶部条件筛选框 附自定义ViewGroup
  6. 表实体字段忽略非数据库字段的注解
  7. 以简书为例,简介尼尔森十大可用性原则
  8. 自己动手做个25键热插拔机械键盘 带幻彩ARGB!!!! stm32主控+蓝牙HID模块 typec接口
  9. Excel如何取消显示分页虚线
  10. 手机太卡是关机再开机好,还是重启更好?