TensorFlow深度学习实战(9)——构建VGG模型实现图像分类

TensorFlow深度学习实战(9)------构建VGG模型实现图像分类

    • [0. 前言](#0. 前言)
    • [1. VGG 模型](#1. VGG 模型)
      • [1.1 VGG16 与 VGG19](#1.1 VGG16 与 VGG19)
      • [1.2 ImageNet](#1.2 ImageNet)
    • [2. 构建 VGG16 模型实现图像分类](#2. 构建 VGG16 模型实现图像分类)
      • [2.1 模型构建](#2.1 模型构建)
      • [2.2 使用 VGG16 网络识别猫](#2.2 使用 VGG16 网络识别猫)
    • [3. 使用 tf.Keras 内置的 VGG16 网络模块](#3. 使用 tf.Keras 内置的 VGG16 网络模块)
    • [4. 利用预训练模型进行特征提取](#4. 利用预训练模型进行特征提取)
    • 小结
    • 系列链接

0. 前言

VGG 模型是一种经典的深度卷积神经网络 (Convolutional Neural Network, CNN) 架构,该模型以其简单而有效的设计而著名,在图像分类任务中取得了优异成绩。VGG 模型的核心特点是采用了深层的网络结构,其中大部分层由卷积层和池化层组成,且卷积操作使用了尺寸较小的 3 x 3 卷积核,这使得网络能够捕捉到丰富的图像特征。

1. VGG 模型

1.1 VGG16 与 VGG19

VGG 是于 2014 年提出的图像识别模型,通过将网络层深度增加到 16-19 个,显著提高了网络性能。模型在 ImageNet ILSVRC-2012 数据集上对模型进行训练,数据集包含 1000 个类别的图像,分为三组:训练集 (130 万张图像)、验证集 (5 万张图像)和测试集( 10 万张图像)。每个图像为 224 x 224 像素,具有 3 个通道。VGG16 模型在 ILSVRC-2012 验证集上的 top-5 错误率为 7.5%,在 ILSVRC-2012 测试集上的 top-5 错误率为 7.4%
VGG19VGG16 的改进版本,具有更多的卷积和池化操作,VGG19 模型的体系结构如下:

可以看到,上示的体系结构中具有更多的网络层以及更多的参数量。需要注意的是,VGG16VGG19 体系结构中的 1619 代表这些网络中的网络层数。

1.2 ImageNet

ImageNet 竞赛的目标是利用一个大型手工标注的 ImageNet 数据集( 1000 万标记图像,描述了 10000 多个类别)的子集进行训练,算法需要预测图像中存在的对象的标签,以便对照片内容进行检索和自动标注。

2. 构建 VGG16 模型实现图像分类

2.1 模型构建

使用 tf.keras 能够预加载已经训练完成的 VGG 模型权重到 tf.keras 模型中使用:

python 复制代码
import tensorflow as tf
from tensorflow.keras import layers, models
import cv2, numpy as np
import os

# define a VGG16 network
def VGG_16(weights_path=None):
    model = models.Sequential()
    model.add(layers.ZeroPadding2D((1,1),input_shape=(224,224, 3)))
    model.add(layers.Convolution2D(64, (3, 3), activation='relu'))
    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(64, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2,2), strides=(2,2)))

    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(128, (3, 3), activation='relu'))
    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(128, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2,2), strides=(2,2)))

    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(256, (3, 3), activation='relu'))
    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(256, (3, 3), activation='relu'))
    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(256, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2,2), strides=(2,2)))

    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(512, (3, 3), activation='relu'))
    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(512, (3, 3), activation='relu'))
    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(512, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2,2), strides=(2,2)))

    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(512, (3, 3), activation='relu'))
    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(512, (3, 3), activation='relu'))
    model.add(layers.ZeroPadding2D((1,1)))
    model.add(layers.Convolution2D(512, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2,2), strides=(2,2)))

    model.add(layers.Flatten())

    #top layer of the VGG net
    model.add(layers.Dense(4096, activation='relu'))
    model.add(layers.Dropout(0.5))
    model.add(layers.Dense(4096, activation='relu'))
    model.add(layers.Dropout(0.5))
    model.add(layers.Dense(1000, activation='softmax'))

    if weights_path:
        model.load_weights(weights_path)

    return model

虽然我们可以使用 tf.keras.applications.vgg16 来直接获取模型及其权重,但为了展示 VGG16 的内部工作原理,我们使用 tf.keras 实现了一个 VGG16 网络,接下来,将使用该模型实现图像分类。

2.2 使用 VGG16 网络识别猫

使用预训练权重测试模型性能:

python 复制代码
im = cv2.resize(cv2.imread('cat.jpg'), (224, 224)).astype(np.float32)
im = np.expand_dims(im, axis=0)

# Test pretrained model
path_file = os.path.join(os.path.expanduser("~"), '.keras/models/vgg16_weights_tf_dim_ordering_tf_kernels.h5')
model = VGG_16(path_file)
model.summary()
model.compile(optimizer='sgd', loss='categorical_crossentropy')
out = model.predict(im)
print(np.argmax(out))

模型返回类别 281,对应于 tabby, tabby cat

可以看到,我们所实现的 VGG16 网络能够成功识别猫的图像。

3. 使用 tf.Keras 内置的 VGG16 网络模块

tf.Keras.applications 包含预构建和预训练的深度学习模型。在实例化模型时,权重会自动下载并存储在 ~/.keras/models/ 中,使用模型预测小狗图像:

python 复制代码
import tensorflow as tf
from tensorflow.keras.applications.vgg16 import VGG16
import matplotlib.pyplot as plt
import numpy as np
import cv2

# prebuild model with pre-trained weights on imagenet
model = VGG16(weights='imagenet', include_top=True)
model.compile(optimizer='sgd', loss='categorical_crossentropy')

# resize into VGG16 trained images' format
im = cv2.resize(cv2.imread('dog.jpg'), (224, 224))
im = np.expand_dims(im, axis=0)
im.astype(np.float32)

# predict
out = model.predict(im)
index = np.argmax(out)
print(index)

plt.plot(out.ravel())
plt.show()

运行代码,模型返回结果 208,对应于 Labrador retriever,模型返回的其它类别置信度都非常小。

4. 利用预训练模型进行特征提取

当网络学习如何将图像分类到正确类别时,每一层都学会了识别执行最终分类所必需的特征。较低层识别低阶特征,如颜色和边缘,而较高层将这些低阶特征组合成形状或物体等高阶特征。因此,中间层具有提取图像重要特征的能力,这些特征能够用于模型执行分类任务。

可以使用深度卷积神经网络进行特征提取,本节中,我们以 VGG16 为例从特定层中提取图像特征。需要注意的是,由于顺序模型仅接受层进行构建,因此需要使用函数式 API

python 复制代码
import tensorflow as tf
from tensorflow.keras.applications.vgg16 import VGG16 
from tensorflow.keras import models
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.vgg16 import preprocess_input
import numpy as np
import cv2

# prebuild model with pre-trained weights on imagenet
base_model = VGG16(weights='imagenet', include_top=True)
print (base_model)
for i, layer in enumerate(base_model.layers):
    print (i, layer.name, layer.output_shape)

# extract features from block4_pool block
model = models.Model(inputs=base_model.input, 
    outputs=base_model.get_layer('block4_pool').output)

img_path = 'cat.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

# get the features from this block
features = model.predict(x)
print(features)

使用预训练模型进行特征提取具有以下优点:

  • 可以重用公开的大规模训练模型,并将学习的特征应用到新任务
  • 可以节省大量的训练时间
  • 即使在没有大量训练样本的情况下,也可以得到合理的解决方案
  • 可以使用一个适合当前任务的初始网络结构,而不必从零开始构建模型

小结

通过使用小尺寸的卷积核和深层网络设计,VGG 能够有效地提取图像的特征,并在各种视觉任务中取得优异的表现。在实际应用中,可以通过迁移学习等方式,充分利用 VGG 的预训练模型,加速训练过程并提高分类效果。

系列链接

TensorFlow深度学习实战(1)------神经网络与模型训练过程详解
TensorFlow深度学习实战(2)------使用TensorFlow构建神经网络
TensorFlow深度学习实战(3)------深度学习中常用激活函数详解
TensorFlow深度学习实战(4)------正则化技术详解
TensorFlow深度学习实战(5)------神经网络性能优化技术详解
TensorFlow深度学习实战(6)------回归分析详解
TensorFlow深度学习实战(7)------分类任务详解
TensorFlow深度学习实战(8)------卷积神经网络

相关推荐
赵钰老师35 分钟前
【Deepseek、ChatGPT】智能气候前沿:AI Agent结合机器学习与深度学习在全球气候变化驱动因素预测中的应用
人工智能·python·深度学习·机器学习·数据分析
Start_Present2 小时前
Pytorch 第十三回:神经网络编码器——自动编解码器
pytorch·python·深度学习·神经网络
Y1nhl4 小时前
搜广推校招面经六十四
人工智能·深度学习·leetcode·广告算法·推荐算法·搜索算法
Y1nhl5 小时前
Pyspark学习一:概述
数据库·人工智能·深度学习·学习·spark·pyspark·大数据技术
简简单单做算法7 小时前
基于mediapipe深度学习和限定半径最近邻分类树算法的人体摔倒检测系统python源码
人工智能·python·深度学习·算法·分类·mediapipe·限定半径最近邻分类树
就决定是你啦!8 小时前
机器学习 第一章 绪论
人工智能·深度学习·机器学习
liruiqiang0511 小时前
循环神经网络 - 简单循环网络
人工智能·rnn·深度学习·神经网络·机器学习
鸿蒙布道师12 小时前
OpenAI战略转向:开源推理模型背后的行业博弈与技术趋势
人工智能·深度学习·神经网络·opencv·自然语言处理·openai·deepseek
小白的高手之路13 小时前
torch.nn.Conv2d介绍——Pytorch中的二维卷积层
人工智能·pytorch·python·深度学习·神经网络·机器学习·cnn
船长@Quant13 小时前
PyTorch量化进阶教程:第五章 Transformer 在量化交易中的应用
pytorch·python·深度学习·transformer·量化交易·sklearn·ta-lab