- 1.EfficientNetV1论文一点总结
- 2.EfficientNetV1结构实现
- 3.重新搭建EfficientNetV1模型结构(便于训练)
- (1)关于数据集和训练的整个代码可以参考我这篇文章
- 4.训练结果
- 5.图像预测
- 6.使用TensorFlow中的efficientnet微调预测对比
- (1)efficientnetB0微调
- (1)微调的主要代码部分
https://mydreamambitious.blog.csdn.net/article/details/125036194
2.EfficientNetV1结构实现
https://mydreamambitious.blog.csdn.net/article/details/125091152
3.重新搭建EfficientNetV1模型结构(便于训练) (1)关于数据集和训练的整个代码可以参考我这篇文章
https://mydreamambitious.blog.csdn.net/article/details/123966676
注:只要将代码中的网络结构换成下面的这个ShuffleNetV2结构即可(如果采用的是面向对象的方式设计的网络结构的话,在训练数据的时候需要做一些调整)并且再将代码中的一些名称修改一下即可。
需要修改的名称如下:
#Swish激活函数的实现
#网络的深度缩放
#网络的宽度缩放
import math
import os
import keras
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.models import Model
def Swish(inputs):
return inputs*tf.sigmoid(inputs)
def MBConvxBlock(inputs,filter_inp,dropout_rate,kernel_size=(3,3),strides=(1,1)):
# 逐点卷积(1x1卷积)归一化
x=layers.Conv2D(6 * filter_inp, kernel_size=[1, 1], strides=[1, 1], padding='same')(inputs)
x= layers.BatchNormalization()(x)
x=Swish(x)
# 深度可分离卷积
x= layers.DepthwiseConv2D(kernel_size=kernel_size, strides=strides, padding='same')(x)
x= layers.BatchNormalization()(x)
x=Swish(x)
# SE操作
SE = keras.Sequential([
layers.AveragePooling2D(pool_size=[1, 1]),
layers.Conv2D(6 * filter_inp // 16, kernel_size=[1, 1], strides=[1, 1], padding='same'),
layers.Conv2D(6 * filter_inp, kernel_size=[1, 1], strides=[1, 1], padding='same')
])
x=SE(x)
x= layers.Conv2D(filter_inp, kernel_size=[1, 1], strides=[1, 1], padding='same')(x)
x= layers.BatchNormalization()(x)
# 连接失活
x= layers.Dropout(dropout_rate)(x)
# 如果步长为1的话,残差连接
if strides == 1:
shortcut = layers.Conv2D(filter_inp, kernel_size=[1, 1], strides=[1, 1], padding='same')(inputs)
shortcutBN = layers.BatchNormalization()(shortcut)
x_out=tf.add(x,shortcutBN)
return x_out
return x
def EfficientNetV1(width_coeff,depth_coeff,resolution,dropout=0.2):
divisor = 8
def MBConvx(inputs,filter_inp,layers,kernel_size,strides,dropout_rate,i):
x=MBConvxBlock(inputs,filter_inp, dropout_rate, kernel_size, strides)
for i in range(1,layers):
x=MBConvxBlock(x,filter_inp,dropout_rate,kernel_size)
return x
#计算缩放之后的宽度
def rounds_width(filters):
filters*=width_coeff
#计算之后的宽度
new_filters=max(divisor,int(filters+divisor/2)//divisor*divisor)
if new_filters<0.9*filters:
new_filters+=divisor
return int(new_filters)
#计算深度
def rounds_depth(layers):
return int(math.ceil((depth_coeff*layers)))
# 输入的第一个3x3卷积操作
input_shape=(resolution,resolution,3)
input=keras.Input(input_shape)
x= layers.Conv2D(32, kernel_size=[3, 3], strides=[2, 2], padding='same')(input)
x= layers.BatchNormalization()(x)
MBConvblock1= MBConvx(x,filter_inp=rounds_width(16), layers=rounds_depth(1), kernel_size=(3, 3),
strides=(1, 1), dropout_rate=0.2, i=1)
MBConvblock2 = MBConvx(MBConvblock1,filter_inp=rounds_width(24), layers=rounds_depth(2), kernel_size=(3, 3),
strides=(2, 2), dropout_rate=0.2, i=2)
MBConvblock3 = MBConvx(MBConvblock2,filter_inp=rounds_width(40), layers=rounds_depth(2), kernel_size=(5, 5),
strides=(2, 2), dropout_rate=0.2, i=3)
MBConvblock4 = MBConvx(MBConvblock3,filter_inp=rounds_width(80), layers=rounds_depth(3), kernel_size=(3, 3),
strides=(2, 2), dropout_rate=0.2, i=4)
MBConvblock5 = MBConvx(MBConvblock4,filter_inp=rounds_width(112), layers=rounds_depth(3), kernel_size=(5, 5),
strides=(1, 1), dropout_rate=0.2, i=5)
MBConvblock6 = MBConvx(MBConvblock5,filter_inp=rounds_width(192), layers=rounds_depth(4), kernel_size=(5, 5),
strides=(2, 2), dropout_rate=0.2, i=6)
MBConvblock7 = MBConvx(MBConvblock6,filter_inp=rounds_width(320), layers=rounds_depth(1), kernel_size=(3, 3),
strides=(1, 1), dropout_rate=0.2, i=7)
x= layers.Conv2D(1280, kernel_size=[1, 1], strides=[1, 1], padding='same')(MBConvblock7)
x= layers.BatchNormalization()(x)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(dropout)(x)
x= layers.Dense(2)(x)
x= layers.Activation('softmax')(x)
model=Model(inputs=input,outputs=x)
return model
if __name__ == '__main__':
print('Pycharm')
model=EfficientNetV1(width_coeff=1.0,depth_coeff=1.0,resolution=224,dropout=0.2)
model.summary()
4.训练结果
由于数据集不是很多,只有近1000张图片,并且之包含两个类别(猫-cat,狗-dot)所以训练的最后效果并不怎么样(中间还需要调参),读者可以根据自己的需要收集图片进行训练。
5.图像预测
只需要将flask中加载的权重文件换成自己训练的就可以了(flask这部分代码在从Github下载的文件中)。
https://github.com/KeepTryingTo/-.git
6.使用TensorFlow中的efficientnet微调预测对比 (1)efficientnetB0微调
预测结果:
(只需要将上面的网络结构换成以下微调部分即可)
#导入EfficientNetB0进行训练和预测,include_top为False表示不包含顶层(全连接层)
base_model=EfficientNetB0(weights='imagenet',include_top=False)
x=base_model.output
#自定义我们自己的全连接层
x=layers.GlobalAveragePooling2D()(x)
x=layers.Dropout(0.2)(x)
x=layers.Dense(2)(x)
output=layers.Activation('softmax')(x)
efficientnet=Model(inputs=base_model.input,outputs=output)
efficientnet.summary()
#冻结住所有的层,因为我们这里的数据集较少,所以使用他提供的
for layer in base_model.layers:
layer.trainable=False
注:efficientnetB7微调的话,本身的电脑有点支撑不住,所以读者可以使用显卡自己训练一遍。



