keras深度学习实战——基于vgg19模型实现性别分类(代码片段)

盼小辉丶 盼小辉丶     2022-10-21     696

关键词:

Keras深度学习实战——基于VGG19模型实现性别分类

0. 前言

《迁移学习》中,我们了解了利用迁移学习,只需要少量样本即可训练得到性能较好的模型;并基于迁移学习利用预训练的 VGG16 模型进行了性别分类的实战,进一步加深对迁移学习工作原理的理解。

1. VGG19 架构简介

本文,我们将介绍另一种常用的网络模型架构——VGG19,并使用预训练的 VGG19 模型进行性别分类实战。VGG19VGG16 的改进版本,具有更多的卷积和池化操作,VGG19 模型的体系结构如下:

Model: "vgg19"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 256, 256, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 256, 256, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 256, 256, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 128, 128, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 128, 128, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 128, 128, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 64, 64, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 64, 64, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 64, 64, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 64, 64, 256)       590080    
_________________________________________________________________
block3_conv4 (Conv2D)        (None, 64, 64, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 32, 32, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 32, 32, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block4_conv4 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 16, 16, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 16, 16, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 16, 16, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 16, 16, 512)       2359808   
_________________________________________________________________
block5_conv4 (Conv2D)        (None, 16, 16, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 8, 8, 512)         0         
=================================================================
Total params: 20,024,384
Trainable params: 20,024,384
Non-trainable params: 0
_________________________________________________________________

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

将每个图像通过 VGG19 网络后,提取到 8 x 8 x 512 输出后,该输出将成为微调模型的输入。接下来,创建输入和输出数据集,然后构建、编译和拟合模型的过程与使用基于预训练的 VGG16 模型进行性别分类的过程相同。

2. 使用预训练 VGG19 模型进行性别分类

在本节中,我们基于迁移学习使用预训练的 VGG19 模型进行性别分类。

2.1 构建输入与输出数据

首先,准备输入和输出数据,我们重用在《卷积神经网络进行性别分类》中使用的数据集以及数据加载代码:

from keras.applications import VGG19
from keras.applications.vgg19 import preprocess_input
from glob import glob
from skimage import io
import cv2
import numpy as np

model = VGG19(include_top=False, weights='imagenet', input_shape=(256, 256, 3))

x = []
y = []
for i in glob('man_woman/a_resized/*.jpg')[:800]:
    try:
        image = io.imread(i)
        x.append(image)
        y.append(0)
    except:
        continue

for i in glob('man_woman/b_resized/*.jpg')[:800]:
    try:
        image = io.imread(i)
        x.append(image)
        y.append(1)
    except:
        continue

x_vgg19 = []
for i in range(len(x)):
    img = x[i]
    img = preprocess_input(img.reshape((1, 256, 256, 3)))
    img_feature = model.predict(img)
    x_vgg19.append(img_feature)

将输入和输出转换为其相应的数组,并创建训练和测试数据集:

x_vgg19 = np.array(x_vgg19)
x_vgg19 = x_vgg19.reshape(x_vgg19.shape[0], x_vgg19.shape[2], x_vgg19.shape[3], x_vgg19.shape[4])
y = np.array(y)

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x_vgg19, y, test_size=0.2)

2.2 模型构建与训练

构建微调模型:

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dropout, Dense
model_fine_tuning = Sequential()
model_fine_tuning.add(Conv2D(512, 
                        kernel_size=(3, 3),
                        activation='relu',
                        input_shape=(x_train.shape[1], x_train.shape[2], x_train.shape[3])))
model_fine_tuning.add(MaxPooling2D(pool_size=(2, 2)))
model_fine_tuning.add(Flatten())
model_fine_tuning.add(Dense(1024, activation='relu'))
model_fine_tuning.add(Dropout(0.6))
model_fine_tuning.add(Dense(1, activation='sigmoid'))
model_fine_tuning.summary()

该模型架构的简要信息输入如下:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 6, 6, 512)         2359808   
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 3, 3, 512)         0         
_________________________________________________________________
flatten (Flatten)            (None, 4608)              0         
_________________________________________________________________
dense (Dense)                (None, 1024)              4719616   
_________________________________________________________________
dropout (Dropout)            (None, 1024)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 1025      
=================================================================
Total params: 7,080,449
Trainable params: 7,080,449
Non-trainable params: 0
_________________________________________________________________

接下来,编译并拟合模型:

model_fine_tuning.compile(loss='binary_crossentropy',optimizer='adam',metrics=['acc'])

history = model_fine_tuning.fit(x_train, y_train,
                                    batch_size=32,
                                    epochs=20,
                                    verbose=1,
                                    validation_data = (x_test, y_test))

最后,我们绘制在训练期间,模型在训练和测试数据集的损失和准确率的变化。可以看到,当我们使用 VGG19 架构时,能够在测试数据集上达到约 95% 的准确率,结果与使用 VGG16 架构时的性能相似:

2.3 模型错误分类示例

一些错误分类的图像示例如下:

x = np.array(x)
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)

x_test_vgg19 = []
for i in range(len(x_test)):
    img = x_test[i]
    img = preprocess_input(img.reshape((1, 256, 256, 3)))
    img_feature = model.predict(img)
    x_test_vgg19.append(img_feature)

x_test_vgg19 = np.array(x_test_vgg19)
x_test_vgg19 = x_test_vgg19.reshape(x_test_vgg19.shape[0], x_test_vgg19.shape[2], x_test_vgg19.shape[3], x_test_vgg19.shape[4])
y_pred = model_fine_tuning.predict(x_test_vgg19)
wrong = np.argsort(np.abs(y_pred.flatten()-y_test))
print(wrong)

y_test_char = np.where(y_test==0,'M','F')
y_pred_char = np.where(y_pred>0.5,'F','M')

plt.subplot(221)
plt.imshow(x_test[wrong[-1]])
plt.title('Actual: '+str(y_test_char[wrong[-1]])+', '+'Predicted: '+str((y_pred_char[wrong[-1]][0])))
plt.subplot(222)
plt.imshow(x_test[wrong[-2]])
plt.title('Actual: '+str(y_test_char[wrong[-2]])+', '+'Predicted: '+str((y_pred_char[wrong[-2]][0])))
plt.subplot(223)
plt.imshow(x_test[wrong[-3]])
plt.title('Actual: '+str(y_test_char[wrong[-3]])+', '+'Predicted: '+str((y_pred_char[wrong[-3]][0])))
plt.subplot(224)
plt.imshow(x_test[wrong[-4]])
plt.title('Actual: '+str(y_test_char[wrong[-4]])+', '+'Predicted: '+str((y_pred_char[wrong[-4]][0])))
plt.show()

从图中,可以看出,VGG19 类似于 VGG16 除了由于人物在图像中占据的空间较小造成错误分类外,倾向于根据头发来判断人物究竟是男性还是女性。

相关链接

Keras深度学习实战(7)——卷积神经网络详解与实现
Keras深度学习实战(9)——卷积神经网络的局限性
Keras深度学习实战(10)——迁移学习
Keras深度学习实战——使用卷积神经网络实现性别分类

keras深度学习实战——基于inceptionv3实现性别分类(代码片段)

Keras深度学习实战——基于Inceptionv3实现性别分类0.前言1.Inception结构1.1Inceptionv1损失函数1.2Inceptionv2和Inceptionv32.使用预训练的Inceptionv3模型实现性别分类2.1模型实现2.2错误分类的图片示例相关链接0.前言我们已经学习了基于VGG16和VG... 查看详情

keras深度学习实战(10)——迁移学习(代码片段)

Keras深度学习实战(10)——迁移学习0.前言1.迁移学习1.1迁移学习原理1.2ImageNet数据集介绍2.利用预训练VGG16模型进行性别分类2.1VGG16架构2.2微调模型2.3错误分类的图片示例小结系列链接0.前言在《卷积神经网络的局限性》... 查看详情

keras深度学习实战(19)——使用对抗攻击生成可欺骗神经网络的图像(代码片段)

Keras深度学习实战(19)——使用对抗攻击生成可欺骗神经网络的图像0.前言1.对抗攻击简介2.对抗攻击模型分析2.1模型识别图像流程2.2对抗攻击流程3.使用Keras实现对抗攻击小结系列链接0.前言近年来,深度学习在图像... 查看详情

keras深度学习实战(33)——基于lstm的序列预测模型(代码片段)

Keras深度学习实战(33)——基于LSTM的序列预测模型0.前言1.序列学习任务1.1命名实体提取1.2文本摘要1.3机器翻译2.从输出网络返回输出序列2.1传统模型体系结构2.2返回每个时间戳的网络中间状态序列2.3使用双向LSTM网络小... 查看详情

keras深度学习实战(18)——语义分割详解(代码片段)

Keras深度学习实战(18)——语义分割详解0.前言1.语义分割基本概念2.模型与数据集分析2.1模型训练流程2.2模型输出3.实现语义分割模型3.1加载数据集3.2模型构建与训练小结系列链接0.前言在《使用U-Net架构进行图像分割》... 查看详情

keras深度学习实战——基于编码器-解码器的机器翻译模型(代码片段)

Keras深度学习实战——基于编码器-解码器的机器翻译模型0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.基于编码器-解码器结构的机器翻译模型2.1基于编码器-解码器体系结构2.2基于注意力机制的编码器-解码器体系结构小结... 查看详情

keras深度学习实战——使用glove模型构建单词向量(代码片段)

Keras深度学习实战——使用GloVe模型构建单词向量0.前言1.GloVe算法模型1.1模型目标1.2GloVe算法计算细节3.实现GloVe模型构建单词向量3.1数据集3.2模型实现相关链接0.前言在《使用fastText模型构建单词向量》一节中,我们学习了如何构... 查看详情

keras深度学习实战——使用glove模型构建单词向量(代码片段)

Keras深度学习实战——使用GloVe模型构建单词向量0.前言1.GloVe算法模型1.1模型目标1.2GloVe算法计算细节3.实现GloVe模型构建单词向量3.1数据集3.2模型实现相关链接0.前言在《使用fastText模型构建单词向量》一节中,我们学习了如... 查看详情

迁移学习案例:keras基于vgg对五种图片类别识别(代码片段)

迁移学习-实战案例案例:基于VGG对五种图片类别识别的迁移学习1.案例效果2.数据集以及迁移需求3.思路和步骤4.训练的时候读取本地图片以及类别5.VGG模型的修改添加全连接层-GlobalAveragePooling2D6.freezeVGG模型结构7.编译和训练8.... 查看详情

keras深度学习实战(39)——音乐音频分类

Keras深度学习实战(39)——音乐音频分类0.前言1.数据集与模型分析1.1数据集分析1.2模型分析2.歌曲流派分类模型2.1数据加载与预处理2.2模型构建与训练3.聚类分析小结系列链接0.前言音乐音频分类技术能够基于音乐内容为音乐添... 查看详情

keras深度学习实战(32)——基于lstm预测股价(代码片段)

Keras深度学习实战(32)——基于LSTM预测股价0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.基于长短时记忆网络LSTM预测股价2.1根据最近五天的股价预测股价2.2考虑最近五天的股价和新闻数据小结系列链接0.前言股价... 查看详情

keras深度学习实战——使用fasttext模型构建单词向量(代码片段)

Keras深度学习实战——使用fastText模型构建单词向量0.前言1.fastText算法模型2.模型与数据集分析2.1fastText模型分析2.2数据集分析3.使用Keras实现fastText生成单词向量相关链接0.前言fastText是另一种用于生成单词向量的神经网络模型,其... 查看详情

keras深度学习实战(20)——deepdream模型详解(代码片段)

Keras深度学习实战(20)——DeepDream模型详解0.前言1.DeepDream的技术原理2.DeepDream模型分析3.DeepDream算法实现3.1数据加载与预处理3.2DeepDream生成模型小结系列链接0.前言在《对抗样本生成》一节中,我们通过略微修改输入... 查看详情

keras深度学习实战(15)——从零开始实现yolo目标检测(代码片段)

Keras深度学习实战(15)——从零开始实现YOLO目标检测0.前言1.YOLO目标检测模型1.1锚框(anchorboxes)1.2YOLO目标检测模型原理2.从零开始实现YOLO目标检测2.1加载数据集2.2计算锚框尺寸2.3创建训练数据集2.4实现YOLO目标检测模型2.5... 查看详情

keras深度学习实战——使用fasttext模型构建单词向量(代码片段)

Keras深度学习实战——使用fastText模型构建单词向量0.前言1.fastText算法模型2.模型与数据集分析2.1fastText模型分析2.2数据集分析3.使用Keras实现fastText生成单词向量相关链接0.前言fastText是另一种用于生成单词向量的神经网络模型࿰... 查看详情

keras深度学习实战(39)——音乐音频分类(代码片段)

Keras深度学习实战(39)——音乐音频分类0.前言1.数据集与模型分析1.1数据集分析1.2模型分析2.歌曲流派分类模型2.1数据加载与预处理2.2模型构建与训练3.聚类分析小结系列链接0.前言音乐音频分类技术能够基于音乐内容为... 查看详情

keras深度学习实战(35)——构建机器翻译模型(代码片段)

Keras深度学习实战(35)——构建机器翻译模型0.前言1.模型与数据集分析1.1模型分析1.2数据集分析2.实现机器翻译模型2.1预处理数据2.2传统多对多架构2.3使用具有多个隐藏层的模型架构小结系列链接0.前言我们已经学习了... 查看详情

keras深度学习实战——使用循环神经网络构建情感分析模型(代码片段)

Keras深度学习实战——使用循环神经网络构建情感分析模型0.前言1.使用循环神经网络构建情感分析模型1.1数据集分析1.2构建RNN模型进行情感分析相关链接0.前言在《循环神经详解与实现》一节中,我们已经了解循环神经网络(Recurr... 查看详情