当前位置: 首页 > news >正文

自制efficientnet网络

用到的技术cnn,残差连接,全局池化注意力机制,点卷积切换通道,深度卷积提取空间特征

import os
os.environ["KERAS_BACKEND"] = "tensorflow"  # @param ["tensorflow", "jax", "torch"]
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import matplotlib.pyplot as plt
import numpy as np
import keras
import tensorflow as tf
from keras import layers

# MobileNetV2 的一个关键特性是使用了“扩张-压缩”模式,即首先通过 1x1 卷积(点卷积)增加通道数(扩张),
# 然后通过深度可分离卷积处理特征,最后再通过 1x1 卷积减少通道数(压缩),越往下,扩张和压缩通道越大
# 并且在特征图到60x60以下逐渐加大提取特征力度,用残差网络
# MobileNetV2 中的瓶颈块会根据网络的深度重复不同的次数。您的代码中为不同的瓶颈块设置了不同的重复次数(
# 如 2 次、3 次),这通常是正确的
def activation_block(x): # 大多预训练模型都是先批次标准化,再激活函数
    # 如果把激活函数放前面,在模型摘要里会先显示激活函数,但是这不是大多数模型的摘要信息
    # 说明是先批次标准化,之后激活函数
    x = layers.BatchNormalization()(x)
    return layers.Activation(keras.activations.hard_swish)(x)

def relu_activation_block(x): # 大多预训练模型都是先批次标准化,再激活函数
    # 如果把激活函数放前面,在模型摘要里会先显示激活函数,但是这不是大多数模型的摘要信息
    # 说明是先批次标准化,之后激活函数
    # relu6:如果输入 x 是正数,则输出 x,但不超过6;如果 x 是负数,则输出0;如果 x 大于6,
    # 则输出6.而relu无限制
    x = layers.BatchNormalization()(x)
    return layers.Activation('relu6')(x)

def se(inputs,in_c,out_c):
    multiply=inputs
    # (n,c) 全局平均池化,获取样本的全局分类信息
    x=layers.GlobalAveragePooling2D()(multiply)
    # 变形
    x=layers.Reshape([1,1,-1])(x)
    # 这里用了截距,这里减少通道数是为了紧凑特征,同时可以减少模型过拟合
    x=layers.Conv2D(in_c,1,padding='same')(x)
    # 之后放大到原通道数,这里卷积核大小是1,是点卷积
    x=layers.Conv2D(out_c,1,padding='same')(x)
    x=layers.Multiply()([x,multiply])
    return x

def depthwiseConv_block(inputs,filters,kernel_size=3,strides=1):
    x=inputs
    x=layers.Conv2D(filters,1,padding='same',use_bias=False)(x)
    x=relu_activation_block(x)
    x=layers.DepthwiseConv2D(kernel_size,strides=strides,padding='same',use_bias=False)(x)
    x=relu_activation_block(x)
    return x

def conv1_block(inputs,filters,dropout=None):
    x=inputs
    x=layers.Conv2D(filters,1,padding='same',use_bias=False)(x)
    x = layers.BatchNormalization()(x)
    if dropout:
        x=layers.Dropout(dropout)(x)
    return x

# 收缩点卷积:16--24--40--80--112--192
# 扩张点卷积:96--144--240--480--672--1152
# global注意力模块:4--6--10--20--28--48
def get_efficientnetb0_model(input_shape,num_classes):
    inputs=keras.Input(shape=input_shape)
    x=layers.Rescaling(1.0/255)(inputs)
    x=layers.Normalization()(x)
    x=layers.Rescaling(scale=[2.0896918976428642, 2.1128856368212916, 2.1081851067789197], offset=0.0)(x)
    x=layers.Conv2D(32,3,strides=2,padding='same',use_bias=False)(x) # (112,112)
    x=relu_activation_block(x)
    x=layers.DepthwiseConv2D(3,padding='same',use_bias=False)(x)
    x=relu_activation_block(x)
    x=se(x,8,32) # 有利于通道信息的重修订,减少过拟合,只关注重要的特征
    x=conv1_block(x,16)
    # 深度卷积模块,用来提取空间信息
    x=depthwiseConv_block(x,96,strides=2)  # (56,56)
    x=se(x,4,96)
    x=conv1_block(x,24)
    x0=x
    x=depthwiseConv_block(x0,144)
    x=se(x,6,144)
    x=conv1_block(x,24,0.025)
    x=layers.add([x,x0])
    # 注意:kernel_size=5,核大,视野就大
    x=depthwiseConv_block(x,144,kernel_size=5,strides=2) # (28,28)
    x=se(x,6,144)
    x=conv1_block(x,40)
    x0=x
    x=depthwiseConv_block(x0,240,kernel_size=5)
    x=se(x,10,240)
    x=conv1_block(x,40,0.025)
    x=layers.add([x,x0])
    # 这个位置用的kernel_size=3
    x=depthwiseConv_block(x,240,strides=2) # (14,14)
    x=se(x,10,240)
    x=conv1_block(x,80)
    for i in range(2):
        x0=x
        x=depthwiseConv_block(x0,480)
        x=se(x,20,480)
        x=conv1_block(x,80,0.025)
        x=layers.add([x,x0])
    x=depthwiseConv_block(x,480,kernel_size=5)
    x=se(x,20,480)
    x=conv1_block(x,112)
    for i in range(2):
        x0=x
        x=depthwiseConv_block(x0,672,kernel_size=5)
        x=se(x,28,672)
        x=conv1_block(x,112,0.025)
        x=layers.add([x,x0])
    x=depthwiseConv_block(x,672,kernel_size=5,strides=2) # (7,7)
    x=se(x,28,672)
    x=conv1_block(x,192)
    for i in range(3):
        x0=x
        x=depthwiseConv_block(x0,1152,kernel_size=5)
        x=se(x,48,1152)
        x=conv1_block(x,192,0.025)
        x=layers.add([x,x0])
    x=depthwiseConv_block(x,1152,kernel_size=3)
    x=se(x,48,1152)
    x=conv1_block(x,320)
    x=layers.Conv2D(1280,1,padding='same',use_bias=False)(x)
    x=activation_block(x)
    return keras.Model(inputs,x)

# 64--128--256--512--1024
# 没有残差,点卷积用来切换通道,便于深度卷积提取信息
def get_mobilenet_model(input_shape,num_classes):
    inputs=keras.Input(shape=input_shape)
    x=layers.Rescaling(1.0/255)(inputs)
    x=layers.Conv2D(32,3,strides=2,padding='same',use_bias=False)(x)  # (80,80,32)
    x=relu_activation_block(x)
    x=layers.DepthwiseConv2D(3,padding='same',use_bias=False)(x)
    x=relu_activation_block(x)
    x=layers.Conv2D(64,1,padding='same',use_bias=False)(x)
    x=relu_activation_block(x)
    x=layers.DepthwiseConv2D(3,strides=2,padding='same',use_bias=False)(x) # (40,40,64)
    x=relu_activation_block(x)
    for i in range(2): # 在40x40的特征图上深度卷积两次
        x=layers.Conv2D(128,1,padding='same',use_bias=False)(x)
        x=relu_activation_block(x)
        if i==0:
            x=layers.DepthwiseConv2D(3,padding='same',use_bias=False)(x)
        else:
           x=layers.DepthwiseConv2D(3,strides=2,padding='same',use_bias=False)(x) # (20,20,128)
        x=relu_activation_block(x)
    for i in range(2): # 在20x20的特征图上深度卷积两次
        x=layers.Conv2D(256,1,padding='same',use_bias=False)(x)
        x=relu_activation_block(x)
        if i ==0:
            x=layers.DepthwiseConv2D(3,padding='same',use_bias=False)(x)
        else:
            x=layers.DepthwiseConv2D(3,strides=2,padding='same',use_bias=False)(x) # (10,10,256)
        x=relu_activation_block(x)
    for i in range(6): # 在10x10的特征图上狠提特征
        x=layers.Conv2D(512,1,padding='same',use_bias=False)(x)
        x=relu_activation_block(x)
        if i !=5:
            x=layers.DepthwiseConv2D(3,padding='same',use_bias=False)(x)
        else:
            x=layers.DepthwiseConv2D(3,strides=2,padding='same',use_bias=False)(x)  # (5,5,512)
        x=relu_activation_block(x)
    x=layers.Conv2D(1024,1,padding='same',use_bias=False)(x)
    x=relu_activation_block(x)
    x=layers.DepthwiseConv2D(3,padding='same',use_bias=False)(x)
    x=relu_activation_block(x)
    x=layers.Conv2D(1024,1,padding='same',use_bias=False)(x)
    x=relu_activation_block(x)
    return keras.Model(inputs,x)


http://www.mrgr.cn/news/18133.html

相关文章:

  • 新一代网络研发利器——开物™,让用户每一行代码都贡献在核心创新
  • wlanapi.dll丢失怎么办?有没有什么靠谱的修复wlanapi.dll方法
  • U-Mail垃圾邮件过滤网关‍是如何过滤垃圾邮件的?
  • sql学习 inner join,left join,right join
  • netty编程之基于websocket实现聊天功能
  • 数据结构---五大排序---哈希表---二分查找法
  • 个人的 minimal-mistakes 配置记录
  • .gitignore 修改问题
  • ClimODE——使用神经网络ODE 进行天气预报
  • 零售商商品规划新纪元:全面策略融合与智能计划系统引领未来
  • OceanBase block_file与log过大 的问题
  • tiny_qemu模拟qemu虚拟化原理
  • 基于五种机器学习的某游戏数据分析与胜负预测系统设计与实现,采用Django+MySQL+HTML+CSS实现
  • 大屏自适应解决方案(手写js)
  • [LitCTF 2023]Http pro max plus
  • 使用docker容器部署考试系统
  • 公司注册资本金验资出具验资报告的看法
  • x264 编码器 AArch64汇编系列:quant 量化相关汇编函数
  • 汽车功能安全--TC3xx SMU之看门狗alarm处理
  • 2024“时光Classic演唱会”宜春站启动,李健杨宗纬吴克群唱响秋日浪漫