来自一个编程都不懂的小白深度学习逆袭之路,关于Keras图像分类,轻量级MobileNetv1网络结构,训练预测和测试

本文记录了一位编程新手利用Keras进行深度学习逆袭的历程,重点介绍了轻量级MobileNetv1网络结构,包括深度可分离卷积的工作原理和网络结构,以及训练和预测的实现。
摘要由CSDN通过智能技术生成

来自一个编程都不懂的小白深度学习逆袭之路,关于Keras图像分类,轻量级MobileNetv1网络结构,训练预测和测试

当自己的电脑配置不这么好时,想快速实现代码,想试试调每个超参对网络带来怎么样的loss,acc改变可以采用MobileNet网络。优势在于快,轻便。同样的数据集训练,Mobilenet比VGG16快4倍左右!精度只比VGG差了0.2%(本人的测试,论文中比VGG16差了1%)

对于MobileNetv1的理解:

该网络最具代表性的就是深度可分离卷积模块(depthwise separable convolutions)
先来讲讲深度可分离卷积和普通卷积的计算
普通的卷积
在这里插入图片描述
输入特征图尺寸为H * W * C,被尺寸为h * w * k卷积,得到输出特征图为尺寸H’ * H’ * k’。(这里就不解释拉,自觉baidu卷积哈)
普通卷积的计算量为:H * W * C * K 3 3(这里拿33卷积)
深度卷积(depthwise):在这里插入图片描述
把input feature分为 g组,每组尺寸为H * W (C/g),假设可整除,下同
把kernel也分为g组,每组尺寸为h * w * (k/g)
按顺序,每组input feature和kernel分别做普通卷积,输出 g组H’ * W’ * (k/g)特征,
即一共H’ * W’ * k
Depthwise的计算量为H * W * C 3 * 3
(个人的看图见解)
可以想象成输入为6
6 * 3的RGB图像,我此时需要拿一个同样是RGB的卷积核对他进行卷积,
这里我用4 * 4 * 3(RGB)卷积核对他进行卷积。然后将输入的图像和卷积核的RGB3层图像分离(看下左图)
然后一个对应着一个(R
R)(B
B)(GG)卷积。
卷积后你会发现你卷积核的通道数(可以理解成上面的RGB的3)取决于你输入图像的通道数,
当你输入进来的图像是灰度图(只有一个通道)那我的卷积核也只能是一个通道数,
这样就不能对图像进行一个比较好的特征提取。
伟大的发明家就想到可以采用一个1 * 1的卷积核对图像进行一个通道数的调整,增加目标的特征(下右图)
在MobileNet中这个1
1卷积操作名字叫做(Pointwise)命个名可能更加高大上把!
Pointwise计算量为:H * W * C *k
在这里插入图片描述
在这里插入图片描述

通过Depthwise+Pointwise的拆分,相当于将普通卷积的计算量压缩为:
在这里插入图片描述
可以看出,深度可分离卷积比普通卷积的参数量减少了9倍多
举个例子,大家会好理解一点!
当输入为6 X 6 X 3,要求输出为4 X 4 X 256,有两种方法:
第一:直接拿一个33256的卷积核,参数量为6 X 6 X 3 X 3 X 3 X 256=248832(6 X 6 X 3为图像大小,3 X 3 X 256为卷积核大小)
第二:使用深度可分离卷积,为为两步,先用3 * 3卷积然后1 * 1卷积
参数量为6 X 6 X 3 X 3 X 3 + 6 X 6 X 3 X 1 X 1 X 256 = 972+28620=29592

深度可分离卷积结构

在这里插入图片描述
左边是普通的卷积结果,一层3*3的卷积然后跟着Batch Normalization(归一化的作用:防止过拟合)和激活函数(Relu)

右边是深度可分离卷积结构:先是深度卷积对图像进行目标的提取,这里的目标提取不能改变通道数!(输入和输出的通道数一样)后面一样跟着Batch Normalization(归一化的作用:防止过拟合)和激活函数(Relu),拿1*1的卷积核对图像调整通道数!后来还是BN和激活

(这里不明白没用关系,看代码就好了)

注意:如果是需要下采样,则在第一个深度卷积上取步长为2.

MobileNet网络结构在这里插入图片描述

超参数one:Mobilenet v1已经非常小了,但是还可以对所有卷积层统一乘以缩小因子 (其中 )以压缩网络。这样Depthwise+Pointwise总计算量可以进一降低(个人认为作用不太,代码depth_multiplier取值为1就好)
超参数tow:分辨率因子ρρ \rhoρ(resolution multiplier ).用于控制输入和内部层表示。即用分辨率因子控制输入的分辨率。(不太理解,希望大神评论区讲解。)

代码部分

'''
利于了深度可分离卷积,
  正常的卷积核:输入的通道数是16 输出图像需要32,卷积核大小3*3*32  3*3*16*32=4608
  深度可分离卷积核:输入的通道数是16 输出图像需要32,卷积核大小3*3*16和1*1*32
先用3*3*16对输入卷积,由于卷积后的通道数不足,在加上一个1*1*32的卷积增加通道数,3*3*16+16*32*1*1=656
depthwise conv最大的优势!
'''

import warnings
import numpy as np
import os
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1'
from keras.preprocessing import image  #数据增强
from keras.models import Model
from keras.layers import DepthwiseConv2D, Input, Activation, Dropout, Reshape, BatchNormalization, \
     GlobalAveragePooling2D, GlobalMaxPooling2D, Conv2D,Dense,Flatten
from keras.applications.imagenet_utils import decode_predictions
from keras import backend as K


# _depthwise_conv_block   深度可分离卷积块

def MobileNet(input_shape=[224, 224, 3],  # 导入图片的大小
              depth_multiplier=1, #有时你需要更小的模型时就需要将输入和输出的计算量都减少,一般会取值1,0.75,0.5,0.25。缩小你的卷积大小和通道
              dropout=1e-3,     #dropout 带多少神经元进行训练
              classes=1000): #分类1000,这个后面可以改的
    img_input = Input(shape=input_shape)  #转换为张量的形式,在tf和keras输入的值都是应该张量的形式
# 一阶的张量[1,2,3]的shape是(3,);一个二阶的张量[[1,2,3],[4,5,6]]的shape是(2,3);一个三阶的张量[[[1],[2],[3]],[[4],[5],[6]]]的shape是(2,3,1)。

    # 224,224,3 -> 112,112,32
    x = _conv_block(img_input, 32, strides=(2, 2))  # 输入 通道数  步数
    # 112,112,32 -> 112,112,64
    x = _depthwise_conv_block(x, 64, depth_multiplier, block_id=1)  # 输入 通道数 depth_multiplier不进行缩小卷积核(计算量), block_id=1

    # 112,112,64 -> 56,56,128
    x = _depthwise_conv_block(x, 128, depth_multiplier,
                              strides=(2, 2), block_id=2)
    # 56,56,128 -> 56,56,128
    x = _depthwise_conv_block(x, 128, depth_multiplier, block_id=3)

    # 56,56,128 -> 28,28,256
    x = _depthwise_conv_block(x, 256, depth_multiplier,
                              strides=(2, 2), block_id=4)
    # 28,28,256 -> 28,28,256
    x = _depthwise_conv_block(x, 256, depth_multiplier, block_id=5)

    # 28,28,256 -> 14,14,512
    x = _depthwise_conv_block(x, 512, depth_multiplier,
                              strides=(2, 2), block_id=6)
    # 14,14,512 -> 14,14,512
    x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=7)
    x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=8)
    x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=9)
    x = _depthwise_conv_block(x, 512, depth_multiplier, block_id=10)
    x 
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值