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

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

关键词:

Keras深度学习实战——基于Inception v3实现性别分类

0. 前言

我们已经学习了基于 VGG16VGG19 体系结构实现性别分类,除此之外,还有许多其它设计更加巧妙的深度神经网络架构,例如 Inception 在保证模型质量的前提下,极大的减少模型参数个数。在本节中,我们将对 Inception 模型的核心思想进行介绍,然后使用基于预训练的 Inception 体系结构实现性别分类。

1. Inception 结构

为了更好理解 Inception 模型的核心思想,我们首先考虑以下场景:在数据集中,有一些图像中的对象占据了图像的大部分,但在另一些图像中对象可能仅仅占整个图像的一小部分。如果在两种情况下我们都使用相同大小的卷积核,则将使模型难以同时学习到识别图像中较小的对象和图像中较大的对象。
为了解决这个问题,我们可以在同一层中使用的多种不同尺寸的卷积核。在这种情况下,网络本质上是变宽了,而不是变深了,如下所示:


在上图中,我们在给定层中使用多种不同尺寸的卷积核进行卷积,Inception v1 模块具有九个线性堆叠的 Inception 模块,如下所示:

1.1 Inception v1 损失函数

Inception v1 体系架构图中,可以看到该架构既深又宽,这很可能会导致梯度消失。
为了解决梯度消失的问题,Inception v1 有两个辅助分类器,它们源于 Inception 模块,试图将基于 Inception 网络的总损失降到最低,如下所示:

total_loss = real_loss + 0.3 * aux_loss_1 + 0.3 * aux_loss_2

需要注意的是,辅助损失仅在训练期间使用,而在模型测试期间中会被忽略。

1.2 Inception v2 和 Inception v3

Inception v2Inception v3 是对 Inception v1 体系结构的改进,其中在 Inception v2 中,Inception 作者在卷积运算的基础上进行了优化,以更快地处理图像;在 Inception v3 中,Inception 作者在原有卷积核的基础上添加了 7 x 7 的卷积核,并将它们串联在一起。总而言之,Inception 的贡献如下:

  • 使用 Inception 模块捕获图像的多尺度细节
  • 使用 1 x 1 卷积作为瓶颈层
  • 使用平均池化层代替全连接层,降低模型参数量
  • 使用辅助分支来避免梯度消失

2. 使用预训练的 Inception v3 模型实现性别分类

《迁移学习》中,我们了解了利用迁移学习,只需要少量样本即可训练得到性能较好的模型;并基于迁移学习利用预训练的 VGG16 模型进行了性别分类的实战。在本节中,我们使用预训练的 Inception v3 构建模型识别图像中的人物性别。

2.1 模型实现

首先,加载所需要的库,并加载预训练的 Inception v3 模型:

from keras.applications import InceptionV3
from keras.applications.inception_v3 import preprocess_input
from glob import glob
from skimage import io
import cv2
import numpy as np

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

创建输入和输出数据集:

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

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

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

将输入和输出转换为 numpy 数组,并将数据集拆分为训练和测试集:

x_inception_v3 = np.array(x_inception_v3)
x_inception_v3 = x_inception_v3.reshape(x_inception_v3.shape[0], x_inception_v3.shape[2], x_inception_v3.shape[3], x_inception_v3.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_inception_v3, y, test_size=0.2)

在预训练模型得到的输出基础上构建微调模型:

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dropout, Dense
model_fine_tuning = Sequential()
model_fine_tuning.add(Conv2D(2048, 
                        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.5))
model_fine_tuning.add(Dense(1, activation='sigmoid'))
model_fine_tuning.summary()

前面的微调模型的简要信息输出,如下所示:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_94 (Conv2D)           (None, 4, 4, 2048)        37750784  
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 2, 2, 2048)        0         
_________________________________________________________________
flatten (Flatten)            (None, 8192)              0         
_________________________________________________________________
dense (Dense)                (None, 1024)              8389632   
_________________________________________________________________
dropout (Dropout)            (None, 1024)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 1025      
=================================================================
Total params: 46,141,441
Trainable params: 46,141,441
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))

在训练期间,模型在训练数据集和测试数据集上准确率和损失值的变化如下:


可以看到,基于与训练的 Inception V3 实现的性别分类模型准确率可以达到 95% 左右。

2.2 错误分类的图片示例

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

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_inception_v3 = []
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_inception_v3.append(img_feature)

x_test_inception_v3 = np.array(x_test_inception_v3)
x_test_inception_v3 = x_test_inception_v3.reshape(x_test_inception_v3.shape[0], x_test_inception_v3.shape[2], x_test_inception_v3.shape[3], x_test_inception_v3.shape[4])
y_pred = model_fine_tuning.predict(x_test_inception_v3)
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()

相关链接

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

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

Keras深度学习实战——基于VGG19模型实现性别分类0.前言1.VGG19架构简介2.使用预训练VGG19模型进行性别分类2.1构建输入与输出数据2.2模型构建与训练2.3模型错误分类示例相关链接0.前言在《迁移学习》中,我们了解了利用迁移学... 查看详情

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

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

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

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

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

Keras深度学习实战——基于ResNet模型实现性别分类0.前言1.ResNet架构简介2.基于预训练的ResNet50模型实现性别分类2.1训练性别分类模型2.2错误分类图像示例相关链接0.前言从VGG16到VGG19,最显著的变化在于网络层数的增加,通... 查看详情

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

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

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

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

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

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

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

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

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

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

keras深度学习实战(42)——强化学习基础(代码片段)

Keras深度学习实战(42)——强化学习基础0.前言1.强化学习基础1.1基本概念1.2马尔科夫决策过程1.3目标函数2.在具有非负奖励的模拟游戏中获取最佳动作2.1问题设定2.2模型分析2.3模型构建与训练3.在模拟游戏中获取最佳动... 查看详情

keras深度学习实战(26)——文档向量详解(代码片段)

Keras深度学习实战(26)——文档向量详解0.前言1.文档向量基本概念2.神经网络模型与数据集分析2.1模型分析2.2数据集介绍3.利用Keras构建神经网络模型生成文档向量小结系列链接0.前言在《从零开始构建单词向量》一节中,我们... 查看详情

keras深度学习实战(41)——语音识别(代码片段)

Keras深度学习实战(41)——语音识别0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.语音识别模型2.1数据加载与预处理2.2模型构建与训练小结系列链接0.前言语音识别(AutomaticSpeechRecognition,ASR,或称语音转录文本)... 查看详情

keras入门实战:手写数字识别

近些年由于理论知识的硬件的快速发展,使得深度学习达到了空前的火热。深度学习已经在很多方面都成功得到了应用,尤其是在图像识别和分类领域,机器识别图像的能力甚至超过了人类。本文用深度学习Python库Keras实现深度... 查看详情

keras深度学习实战(23)——dcgan详解与实现(代码片段)

Keras深度学习实战(23)——DCGAN详解与实现0.前言1.使用DCGAN生成手写数字图像2.使用DCGAN生成面部图像2.1模型分析2.2从零开始实现DCGAN生成面部图像小结系列链接0.前言在生成对抗网络(GenerativeAdversarialNetworks,GAN)一节中,我们使用... 查看详情

keras深度学习实战(20)——神经风格迁移详解(代码片段)

Keras深度学习实战(20)——神经风格迁移详解0.前言1.神经风格迁移原理2.模型分析3.使用Keras实现神经风格迁移小结系列链接0.前言在DeepDream图像生成算法的学习中,我们通过修改像素值试图使神经网络中卷积核的激... 查看详情

keras深度学习实战(37)——手写文字识别(代码片段)

Keras深度学习实战(37)——手写文字识别0.前言1.手写文字识别相关背景1.1Connectionisttemporalclassification(CTC)1.2解码CTC1.3计算CTC损失值2.模型与数据集分析2.1数据集分析2.2模型分析3.实现手写文字识别模型3.1数据集加载与预处... 查看详情

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

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

keras深度学习实战——新闻文本分类(代码片段)

Keras深度学习实战(9)——新闻文本分类0.前言1.新闻文本分类任务与神经网络模型分析1.1数据集1.2神经网络模型2.使用神经网络进行新闻文本分类小结系列链接0.前言在先前的应用实战中,我们分析了结构化的数据集&... 查看详情