Keras复现VGG16及实现花卉分类

VGG网络

VGG网络是2014年ILSVRC竞赛的第二名(第一名是GoogleNet,即后来的inception),由牛津大学的计算机视觉实验组提出。原始论文地址https://arxiv.org/abs/1409.1556

VGG的出现证明了网络深度的增加可以提升模型的效果,它由一系列的卷积、池化堆叠而成,在论文中作者搭建了不同深度的6种VGG模型,命名A-E,网络深度依次加深。通常VGG16和VGG19是指D、E两个版本。

下表是原始论文中的6个版本VGG结构,A-LRN是在A版本的基础上使用了AlexNet中的LRN层,用来对比。

在这里插入图片描述

VGG的另一个特点是使用的卷积只有11和33的卷积,2个33的卷积代替55卷积,3个33卷积代替77的卷积,尽管它们的感受野相同,但使用多个小卷积代替大卷积,在保证感受野不变的情况下可以使参数量减小,且提升了网络的深度。比如55的卷积需要的参数量是25个,而用2个小的33卷积代替只需要18个。

此外VGG中使用了1*1的卷积,作者认为1x1卷积可以增加决策函数的非线性能力,非线性是由激活函数决定的,1x1卷积是线性映射,在同样的维度上映射特征图。

VGG的输入是224*224尺寸的图像,且经过特殊处理后才输入网络,处理不仅包括归一化等常规操作,并且每个像素值还减去了在总的训练集的均值。

在Keras中内置了处理输入的函数。

from keras.applications.imagenet_utils import preprocess_input
img = preprocess_input(img) # img是要输入的图像
# 查看preprocess_input函数的部分源码如下
# 该函数针对TensorFlow、caffe、Torch的处理并不相同,对tf只需将图像像素值缩放到-1和1之间,caffe则将图片通道变为BGR,做中心化但不缩放像素值范围,Torch缩放像素值在0到1之间,然后标准化。

if mode == 'tf':
    x /= 127.5
    x -= 1.
    return x
if mode == 'torch':
    x /= 255.
    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]
else:
    if data_format == 'channels_first':
        # 'RGB'->'BGR'
        if backend.ndim(x) == 3:
            x = x[::-1, ...]
        else:
            x = x[:, ::-1, ...]
    else:
        # 'RGB'->'BGR'
        x = x[..., ::-1]
    mean = [103.939, 116.779, 123.68]
    std = None

Keras搭建VGG16并进行花卉分类

一个在线可视化vgg16结构的网站: https://dgschwend.github.io/netscope/#/preset/vgg-16

数据集来自谷歌的一个鲜花数据集,网址http://download.tensorflow.org/example_image/flower_photo.tgz

该数据集比较小,包含五类鲜花的照片,chamomile(甘菊)、 tulip(郁金香)、rose(玫瑰)、sunflower(向日葵)、dandelion(蒲公英),每一类图片有800张左右,且大小不一,但图像都比较小约为,400x300。

image.png

image.png

对数据集的处理,采用npy格式存储数据。OpenCV读取图像后,直接使用preprocess_input 函数处理,然后存入npy文件。标签采用to_categorical进行独热编码转换标签。

使用Keras搭建VGG16,比较方便,按照论文中的结构一层层累积即可。每层卷积使用relu激活函数,最后输出softmax分类,类别为5,优化器采用sgd(在网上一个博客看到说采用Adam优化效果更好,但我试了没有sgd效果好?),分类交叉熵损失categorical_crossentropy。

Keras的另一个好处是keras.applications模块内置了许多模型,包括VGG、ResNet、InceptionV3、DenseNet121等。因此我们可以使用内置的VGG16,只需修改最后的全连接层输出类别即可。

import numpy as np
from keras.models import Model, load_model
from keras.layers import Dropout, Flatten, Dense, Input
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.utils import plot_model,to_categorical
from keras import optimizers
import os
import cv2
from keras.applications import VGG16
from keras.applications.vgg16 import preprocess_input  
from keras.callbacks import TensorBoard

class vgg():
    def __init__(self, shape, num_classes, data_path, label_path, model_path):
        self.shape = shape
        self.num_classes = num_classes
        self.data_path = data_path
        self.label_path = label_path
        self.model_path = model_path
        self.log_path = "./logs"
        self.classes = self.classname()

    def classname(self, prepath="D://Datasets//flower_photos//flower_photos//"):
        # 数据集的类别序号和对应名称,注意的是序号是从1开始,而label中编码实际是从0开始
        classes = os.listdir(prepath)  # 类别序号和名称
        class_dict 
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值