深度学习之基于卷积神经网络(VGG16)实现性别判别

无意间在kaggle上发现的一个数据集,旨在提高网络模型判别男女的准确率,博主利用迁移学习试验了多个卷积神经网络,最终的模型准确率在95%左右。并划分了训练集、测试集、验证集三类,最终在验证集上的准确率为93.63%.

1.导入库

import tensorflow as tf
import matplotlib.pyplot as plt
import os,PIL,pathlib
import pandas as pd
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers,models
from tensorflow.keras import layers, models, Input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2D, Dense, Flatten, Dropout,BatchNormalization,Activation
from tensorflow.keras.layers import MaxPooling2D, AveragePooling2D, Concatenate, Lambda,GlobalAveragePooling2D
from tensorflow.keras import backend as K

# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

2.导入数据

kaggle上下载的原数据一共有20000+张,由于硬件原因,博主选取了4286张作为训练集和测试集,剩下的作为验证集。

data_dir = "E:/tmp/.keras/datasets/Man_Women/faces_test"
data_dir = pathlib.Path(data_dir)
img_count = len(list(data_dir.glob('*/*')))
print(img_count)

all_images_paths = list(data_dir.glob('*'))
all_images_paths = [str(path) for path in all_images_paths]
all_label_names = [path.split("\\")[6].split(".")[0] for path in all_images_paths]
print(all_label_names)
4286
['man', 'woman']
Found 4286 images belonging to 2 classes.

参数设置:

height = 224
width = 224
epochs = 15
batch_size = 32

3.训练集与测试集

按照8:2的比例划分训练集和测试集

train_data_gen = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1./255,#归一化
    validation_split=0.2,
    horizontal_flip=True#进行水平翻转,作为数据增强
)

train_ds = train_data_gen.flow_from_directory(
    directory=data_dir,
    target_size=(height,width),
    batch_size=batch_size,
    shuffle=True,
    class_mode='categorical',
    subset='training'
)
test_ds = train_data_gen.flow_from_directory(
    directory=data_dir,
    target_size=(height,width),
    batch_size=batch_size,
    shuffle=True,
    class_mode='categorical',
    subset='validation'
)
Found 3430 images belonging to 2 classes.
Found 856 images belonging to 2 classes.

图片展示:

plt.figure(figsize=(15, 10))  # 图形的宽为15高为10

for images, labels in train_ds:
    for i in range(30):
        ax = plt.subplot(5, 6, i + 1)
        plt.imshow(images[i])
        plt.title(all_label_names[np.argmax(labels[i])])
        plt.axis("off")
    break
plt.show()

在这里插入图片描述

3.迁移学习VGG16网络

base_model = tf.keras.applications.VGG16(include_top=False, weights="imagenet",input_shape=(height,width,3),pooling = 'max')
x = base_model.output
x = tf.keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
x = tf.keras.layers.Dense(256, activation='relu')(x)
x = tf.keras.layers.Dropout(rate=.45, seed=123)(x)
output = tf.keras.layers.Dense(2, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)

设置优化器

# #设置优化器
# #起始学习率
init_learning_rate = 1e-4
lr_sch = tf.keras.optimizers.schedules.ExponentialDecay(
    initial_learning_rate=init_learning_rate,
    decay_steps=50,
    decay_rate=0.96,
    staircase=True
)
gen_optimizer = tf.keras.optimizers.Adam(learning_rate=lr_sch)

网络编译&&训练

model.compile(
    optimizer=gen_optimizer,
    loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
    metrics=['accuracy']
)

history = model.fit(
    train_ds,
    epochs=epochs,
    validation_data=test_ds
)

训练结果如下所示:
在这里插入图片描述
最终的模型准确率为95%左右,在博主试验的这些网络模型中,VGG16的模型准确率是最高的。

4.混淆矩阵的绘制

网络保存:

model.save("E:/Users/yqx/PycharmProjects/Man_Women_Rec/model_.h5")

网络加载:

model = tf.keras.models.load_model("E:/Users/yqx/PycharmProjects/Man_Women_Rec/model.h5")

利用模型对验证集的数据进行测试:

plt.figure(figsize=(50,50))

    for images,labels in validation_ds:
        num = 0
        total = 0
        for i in range(64):
            total += 1
            ax = plt.subplot(8,8,i+1)
            plt.imshow(images[i])
            img_array = tf.expand_dims(images[i],0)

            pre = model.predict(img_array)
            if np.argmax(pre) == np.argmax(labels[i]):
                num += 1
            plt.title(all_label_names[np.argmax(pre)])
            plt.axis("off")

        print(total)
        print(num)
        break
    plt.suptitle("The acc rating of validation is:{}".format((num / total)))
    plt.show()

在这里插入图片描述
绘制混淆矩阵:

from sklearn.metrics import confusion_matrix
import seaborn as sns
import pandas as pd
    # 绘制混淆矩阵
def plot_cm(labels, pre):
    conf_numpy = confusion_matrix(labels, pre)  # 根据实际值和预测值绘制混淆矩阵
    conf_df = pd.DataFrame(conf_numpy, index=all_label_names,
                               columns=all_label_names)  # 将data和all_label_names制成DataFrame
    plt.figure(figsize=(8, 7))

    sns.heatmap(conf_df, annot=True, fmt="d", cmap="BuPu")  # 将data绘制为混淆矩阵
    plt.title('混淆矩阵', fontsize=15)
    plt.ylabel('真实值', fontsize=14)
    plt.xlabel('预测值', fontsize=14)
    plt.show()


test_pre = []
test_label = []
for images, labels in validation_ds:
    for image, label in zip(images, labels):
        img_array = tf.expand_dims(image, 0)  # 增加一个维度
        pre = model.predict(img_array)  # 预测结果
        test_pre.append(all_label_names[np.argmax(pre)])  # 将预测结果传入列表
        test_label.append(all_label_names[np.argmax(label)])  # 将真实结果传入列表
    break  # 由于硬件问题。这里我只用了一个batch,一共128张图片。
plot_cm(test_label, test_pre)  # 绘制混淆矩阵

在这里插入图片描述

5.测试验证集

model = tf.keras.models.load_model("E:/Users/yqx/PycharmProjects/Man_Women_Rec/model.h5")
model.evaluate(validation_ds)

最终结果如下所示:

716/716 [==============================] - 418s 584ms/step - loss: 0.5345 - accuracy: 0.9363
[0.5345107175451417, 0.936279]#loss值与acc率

模型准确率比较高。在kaggle上,看到有模型准确率在99%左右,路过的大佬可以试验一下。

努力加油a啊

  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值