Python机器学习——人脸性别识别

news2024/9/21 19:09:46

一、选题背景

        人脸识别技术是模式识别和计算机视觉领域最富挑战性的研究课题之一,也是近年来的研究热点,人脸性别识别作为人脸识别技术的重要组成部分也受到了广泛地关注。人脸性别识别就是向计算机输入人脸图像,经过某种方法或运算,得出其性别。这种识别对人眼来说很简单,但对计算机却并不是一件容易的事情。

二、机器学习案例设计方案

        从网站中下载相关的数据集,对数据集进行整理,在python的环境中,给数据集中的文件进行划分,对数据进行预处理,利用keras,构建神经网络,训练模型,导入图片测试模型。       

数据来源:kaggle,网址:https://www.kaggle.com/maciejgronczynski/biggest-genderface-recognition-dataset

数据集包含27167个jpg文件,其中17678个是男性面部照片,9489个是女性照片。

三、机器学习的实验步骤

1.下载数据集

2.导入需要用到的库

import os
import random
from shutil import copy
from matplotlib import pyplot as plt
from keras import optimizers
from keras import models
from keras import layers
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
from PIL import Image

3.数据集划分,由总的数据集生成分别生成训练集,测试集和验证集

# 女性图片训练集想保存到的根路径
woman_train_dir = r'sex\faces\train\woman'
# 女性图片验证集想保存到的根路径
woman_validation_dir = r'sex\faces\validation\woman'
# 女性图片测试集想保存到的根路径
woman_test_dir = r'sex\faces\test\woman'

# 男性图片训练集想保存到的根路径
man_train_dir = r'sex\faces\train\man'
# 男性图片验证集想保存到的根路径
man_validation_dir = r'sex\faces\validation\man'
# 男性图片测试集想保存到的根路径
man_test_dir = r'sex\faces\test\man'

# 创建列表,保存上方6个路径
dir_list = [woman_train_dir, woman_validation_dir, woman_test_dir,
            man_train_dir, man_validation_dir, man_test_dir]
# 如果目录不存在,则创建
for dir_child in dir_list:
    if not os.path.isdir(dir_child):
        os.makedirs(dir_child)

# 女性图片根路径
woman_path = r'sex\faces\woman'
# 获取 woman_path 下的文件夹列表
woman_path_list = os.listdir(woman_path)
# 遍历列表,取6000张图片加入训练集,3000张图片加入验证集,其余加入测试集
for i in range(len(woman_path_list)):
    child_path = os.path.join(woman_path, woman_path_list[i])
    if i < 6000:
        to_path = woman_train_dir
    elif i < 9000:
        to_path = woman_validation_dir
    else:
        to_path = woman_test_dir
    copy(child_path, to_path)

# 男性图片根路径
man_path = r'sex\faces\man'
# 获取 man_path 下的文件夹列表
man_path_list = os.listdir(man_path)
# 遍历列表,取6000张图片加入训练集,3000张图片加入验证集,其余加入测试集
for i in range(len(man_path_list)):
    child_path = os.path.join(man_path, man_path_list[i])
    if i < 6000:
        to_path = man_train_dir
    elif i < 9000:
        to_path = man_validation_dir
    else:
        to_path = man_test_dir
    copy(child_path, to_path)

# 输出各目录中的文件数目
train_path = "sex/faces/train/"
print('total training woman images:', len(os.listdir(train_path+"woman")))
print('total training man images:', len(os.listdir(train_path+"man")))

valid_path = "sex/faces/validation/"
print('total validation woman images:', len(os.listdir(valid_path+"woman")))
print('total validation man images:', len(os.listdir(valid_path+"man")))

test_path = "sex/faces/test/"
print('total test woman images:', len(os.listdir(test_path+"woman")))
print('total test man images:', len(os.listdir(test_path+"man")))

4.查看图像以及对应标签

# 查看图像以及对应的标签
fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7))
# 查看图像的根路径
test_view_path = r'sex\faces\test\man'
# 获取 test_view_path 下的文件夹列表
test_view_list = os.listdir(test_view_path)
for i, a in enumerate(ax.flat):
    view_path = os.path.join(test_view_path, test_view_list[i])
    # 读取源图
    a.imshow(plt.imread(view_path))
    # 添加图像名称
    a.set_title(man_path_list[i])
plt.tight_layout()  # 自动调整子图参数,使之填充整个图像区域
plt.show()

5.图片预处理

# 图片预处理
# 批量大小
BATCH_SIZE = 20
# 输入图片的大小
IMG_SIZE = (150, 150)

# 归一化处理
train_datagen = ImageDataGenerator(rescale=1./255)
validation_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_dir = 'sex/faces/train'     # 指向训练集图片目录路径

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=IMG_SIZE,  # 输入训练图像尺寸
    batch_size=BATCH_SIZE,
    color_mode='rgb',
    class_mode='binary')

validation_dir = 'sex/faces/validation'  # 指向验证集图片目录路径

validation_generator = validation_datagen.flow_from_directory(
    validation_dir,
    target_size=IMG_SIZE,
    batch_size=BATCH_SIZE,
    color_mode='rgb',
    class_mode='binary')

test_dir = 'sex/faces/test'  # 指向测试集图片目录路径

test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=IMG_SIZE,
    batch_size=BATCH_SIZE,
    color_mode='rgb',
    class_mode='binary')

6.查看经过处理的图片以及它的binary标签

# 查看经过处理的图片以及它的binary标签
fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7))

for i, a in enumerate(ax.flat):
    img, label = test_generator.next()
    a.imshow(img[0],)
    a.set_title(label[0])

plt.tight_layout()
plt.show()

7.构建神经网络并对模型进行训练

# 构建神经网络
model = models.Sequential()

# 1.Conv2D层,32个过滤器。输出图片尺寸:150-3+1=148*148,参数数量:32*3*3*3+32=896
model.add(layers.Conv2D(32, (3, 3),
                        activation='relu',
                        input_shape=(150, 150, 3)))  # 卷积层1
model.add(layers.MaxPooling2D((2, 2)))  # 最大值池化层1。输出图片尺寸:148/2=74*74

# 2.Conv2D层,64个过滤器。输出图片尺寸:74-3+1=72*72,参数数量:64*3*3*32+64=18496
model.add(layers.Conv2D(64, (3, 3),
                        activation='relu'))  # 卷积层2
model.add(layers.MaxPooling2D((2, 2)))  # 最大值池化层2。输出图片尺寸:72/2=36*36

# 3.Conv2D层,128个过滤器。输出图片尺寸:36-3+1=34*34,参数数量:128*3*3*64+128=73856
model.add(layers.Conv2D(128, (3, 3),
                        activation='relu'))  # 卷积层3
model.add(layers.MaxPooling2D((2, 2)))  # 最大值池化层3。输出图片尺寸:34/2=17*17

# 4.Conv2D层,128个过滤器。输出图片尺寸:17-3+1=15*15,参数数量:128*3*3*128+128=147584
model.add(layers.Conv2D(128, (3, 3),
                        activation='relu'))  # 卷积层4
model.add(layers.MaxPooling2D((2, 2)))  # 最大值池化层4。输出图片尺寸:15/2=7*7

# 将输入层的数据压缩成1维数据,全连接层只能处理一维数据
model.add(layers.Flatten())

# 全连接层
model.add(layers.Dense(512,
                       activation='relu'))  # 全连接层1
model.add(layers.Dense(1,
                       activation='sigmoid'))  # 全连接层2,作为输出层。sigmoid分类,输出是两类别

# 编译模型
# RMSprop 优化器。因为网络最后一层是单一sigmoid单元,
# 所以使用二元交叉熵作为损失函数
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])

# 看一下特征图的维度如何随着每层变化
model.summary()

# 训练模型50轮次
history_save = model.fit(
                    train_generator,
                    steps_per_epoch=100,
                    epochs=50,
                    validation_data=validation_generator,
                    validation_steps=50)
# 将训练过程产生的数据保存为h5文件
model.save('sex/faces/sex_model.h5')

8.绘制损失曲线和精度曲线图

# 绘制损失曲线和精度曲线图
accuracy = history_save.history['acc']  # 训练集精度
loss = history_save.history['loss']  # 训练集损失
val_loss = history_save.history['val_loss']  # 验证集精度
val_accuracy = history_save.history['val_acc']  # 验证集损失
plt.figure(figsize=(17, 7))

# 训练集精度和验证集精度曲线图图
plt.subplot(2, 2, 1)
plt.plot(range(50), accuracy, 'bo', label='Training Accuracy')
plt.plot(range(50), val_accuracy, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend(loc='center right')

# 训练集损失和验证集损失图
plt.subplot(2, 2, 2)
plt.plot(range(50), loss, 'bo', label='Training Loss')
plt.plot(range(50), val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend(loc='center right')

# 训练集精度和损失散点图
plt.subplot(2, 2, 3)
plt.scatter(range(50), accuracy, label="Training Accuracy", color='b', s=25, marker="o")
plt.scatter(range(50), loss, label="Training Loss", color='r', s=25, marker="o")
plt.title('Training : Accuracy and Loss')
plt.legend(loc='center right')

# 验证集精度和损失散点图
plt.subplot(2, 2, 4)
plt.scatter(range(50), val_accuracy, label="Validation Accuracy", color='b', s=25, marker="o")
plt.scatter(range(50), val_loss, label="Validation Loss", color='r', s=25, marker="o")
plt.title('Validation : Accuracy and Loss')
plt.legend(loc='center right')

plt.show()

9.用ImageDataGenerator数据增强

train_datagen = ImageDataGenerator(rescale=1./255,
                                   rotation_range=40,  # 将图像随机旋转40度
                                   width_shift_range=0.2,  # 在水平方向上平移比例为0.2
                                   height_shift_range=0.2,  # 在垂直方向上平移比例为0.2
                                   shear_range=0.2,  # 随机错切变换的角度为0.2
                                   zoom_range=0.2,  # 图片随机缩放的范围为0.2
                                   horizontal_flip=True,  # 随机将一半图像水平翻转
                                   fill_mode='nearest')  # 填充创建像素
validation_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=IMG_SIZE,  # 输入训练图像尺寸
    batch_size=BATCH_SIZE,
    class_mode='binary')

validation_generator = validation_datagen.flow_from_directory(
    validation_dir,
    target_size=IMG_SIZE,
    batch_size=BATCH_SIZE,
    class_mode='binary')

再次训练模型,并绘制绘制损失曲线和精度曲线图,得到结果图:

10.随机选取测试集的图片进行预测

# 将图片缩小到(150,150)的大小
def convertjpg(jpgfile, outdir, width=150, height=150):
    img = Image.open(jpgfile)
    try:
        new_img = img.resize((width, height), Image.BILINEAR)
        new_img.save(os.path.join(outdir, os.path.basename(jpgfile)))
    except Exception as e:
        print(e)

# 从测试集随机获取一张男性图片
man_test = r'sex\faces\test\man'
man_test_list = os.listdir(man_test)
key = random.randint(0, len(man_test_list))
img_key = man_test_list[key]
jpg_file = os.path.join(man_test, img_key)
convertjpg(jpg_file, "sex/faces/test")  # 图像大小改变到(150,150)
img_scale = plt.imread('sex/faces/test/' + img_key)
plt.imshow(img_scale)  # 显示改变图像大小后的图片确实变到了(150,150)大小

# 调用训练模型结果进行预测
model = load_model('sex/faces/sex_model.h5')
img_scale = img_scale.reshape(1, 150, 150, 3).astype('float32')
img_scale = img_scale/255  # 归一化到0-1之间
result = model.predict(img_scale)  # 取图片信息
if result > 0.5:
    print('该图片是女性的概率为:', result)
else:
    print('该图片是男性的概率为:', 1-result)
plt.show()  # 打印尺寸改变后的图像

# 从测试集随机获取一张女性图片
woman_test = r'sex\faces\test\woman'
woman_test_list = os.listdir(woman_test)
key = random.randint(0, len(woman_test_list))
img_key = woman_test_list[key]
jpg_file = os.path.join(woman_test, img_key)
convertjpg(jpg_file, "sex/faces/test")  # 图像大小改变到(150,150)
img_scale = plt.imread('sex/faces/test/' + img_key)
plt.imshow(img_scale)  # 显示改变图像大小后的图片确实变到了(150,150)大小

# 调用训练模型结果进行预测
model = load_model('sex/faces/sex_model.h5')
img_scale = img_scale.reshape(1, 150, 150, 3).astype('float32')
img_scale = img_scale/255  # 归一化到0-1之间
result = model.predict(img_scale)  # 取图片信息
if result > 0.5:
    print('该图片是女性的概率为:', result)
else:
    print('该图片是男性的概率为:', 1-result)
plt.show()  # 打印尺寸改变后的图像

11.自定义一张图片进行预测

# 自定义一张男性图片进行预测
diy_img = 'sex/faces/man.jpg'
convertjpg(diy_img, "sex")  # 图像大小改变到(150,150)
img_scale = plt.imread('sex/man.jpg')
plt.imshow(img_scale)  # 显示改变图像大小后的图片确实变到了(150,150)大小

# 调用数据增强后的训练模型结果进行预测
model = load_model('sex/faces/sex_model_idg.h5')
img_scale = img_scale.reshape(1, 150, 150, 3).astype('float32')
img_scale = img_scale/255  # 归一化到0-1之间
result = model.predict(img_scale)  # 取图片信息
if result > 0.5:
    print('该图片是女性的概率为:', result)
else:
    print('该图片是男性的概率为:', 1-result)
plt.show()  # 打印尺寸改变后的图像

# 自定义一张女性图片进行预测
diy_img = 'sex/faces/woman_2.jpg'
convertjpg(diy_img, "sex")  # 图像大小改变到(150,150)
img_scale = plt.imread('sex/woman_2.jpg')
plt.imshow(img_scale)  # 显示改变图像大小后的图片确实变到了(150,150)大小

# 调用数据增强后的训练模型结果进行预测
model = load_model('sex/faces/sex_model.h5')
img_scale = img_scale.reshape(1, 150, 150, 3).astype('float32')
img_scale = img_scale/255  # 归一化到0-1之间
result = model.predict(img_scale)  # 取图片信息
if result > 0.5:
    print('该图片是女性的概率为:', result)
else:
    print('该图片是男性的概率为:', 1-result)
plt.show()  # 打印尺寸改变后的图像

12.完整代码:

import os
import random
from shutil import copy
from matplotlib import pyplot as plt
from keras import optimizers
from keras import models
from keras import layers
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
from PIL import Image

# 女性图片训练集想保存到的根路径
woman_train_dir = r'sex\faces\train\woman'
# 女性图片验证集想保存到的根路径
woman_validation_dir = r'sex\faces\validation\woman'
# 女性图片测试集想保存到的根路径
woman_test_dir = r'sex\faces\test\woman'

# 男性图片训练集想保存到的根路径
man_train_dir = r'sex\faces\train\man'
# 男性图片验证集想保存到的根路径
man_validation_dir = r'sex\faces\validation\man'
# 男性图片测试集想保存到的根路径
man_test_dir = r'sex\faces\test\man'

# 创建列表,保存上方6个路径
dir_list = [woman_train_dir, woman_validation_dir, woman_test_dir,
            man_train_dir, man_validation_dir, man_test_dir]
# 如果目录不存在,则创建
for dir_child in dir_list:
    if not os.path.isdir(dir_child):
        os.makedirs(dir_child)

# 女性图片根路径
woman_path = r'sex\faces\woman'
# 获取 woman_path 下的文件夹列表
woman_path_list = os.listdir(woman_path)
# 遍历列表,取6000张图片加入训练集,3000张图片加入验证集,其余加入测试集
for i in range(len(woman_path_list)):
    child_path = os.path.join(woman_path, woman_path_list[i])
    if i < 6000:
        to_path = woman_train_dir
    elif i < 9000:
        to_path = woman_validation_dir
    else:
        to_path = woman_test_dir
    copy(child_path, to_path)

# 男性图片根路径
man_path = r'sex\faces\man'
# 获取 man_path 下的文件夹列表
man_path_list = os.listdir(man_path)
# 遍历列表,取6000张图片加入训练集,3000张图片加入验证集,其余加入测试集
for i in range(len(man_path_list)):
    child_path = os.path.join(man_path, man_path_list[i])
    if i < 6000:
        to_path = man_train_dir
    elif i < 9000:
        to_path = man_validation_dir
    else:
        to_path = man_test_dir
    copy(child_path, to_path)

# 输出各目录中的文件数目
train_path = "sex/faces/train/"
print('total training woman images:', len(os.listdir(train_path+"woman")))
print('total training man images:', len(os.listdir(train_path+"man")))

valid_path = "sex/faces/validation/"
print('total validation woman images:', len(os.listdir(valid_path+"woman")))
print('total validation man images:', len(os.listdir(valid_path+"man")))

test_path = "sex/faces/test/"
print('total test woman images:', len(os.listdir(test_path+"woman")))
print('total test man images:', len(os.listdir(test_path+"man")))

# 查看图像以及对应的标签
fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7))
# 查看图像的根路径
test_view_path = r'sex\faces\test\man'
# 获取 test_view_path 下的文件夹列表
test_view_list = os.listdir(test_view_path)
for i, a in enumerate(ax.flat):
    view_path = os.path.join(test_view_path, test_view_list[i])
    # 读取源图
    a.imshow(plt.imread(view_path))
    # 添加图像名称
    a.set_title(man_path_list[i])
plt.tight_layout()  # 自动调整子图参数,使之填充整个图像区域
plt.show()

# 图片预处理
# 批量大小
BATCH_SIZE = 20
# 输入图片的大小
IMG_SIZE = (150, 150)

# 归一化处理
train_datagen = ImageDataGenerator(rescale=1./255)
validation_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_dir = 'sex/faces/train'     # 指向训练集图片目录路径

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=IMG_SIZE,  # 输入训练图像尺寸
    batch_size=BATCH_SIZE,
    color_mode='rgb',
    class_mode='binary')

validation_dir = 'sex/faces/validation'  # 指向验证集图片目录路径

validation_generator = validation_datagen.flow_from_directory(
    validation_dir,
    target_size=IMG_SIZE,
    batch_size=BATCH_SIZE,
    color_mode='rgb',
    class_mode='binary')

test_dir = 'sex/faces/test'  # 指向测试集图片目录路径

test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=IMG_SIZE,
    batch_size=BATCH_SIZE,
    color_mode='rgb',
    class_mode='binary')

# 查看经过处理的图片以及它的binary标签
fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7))

for i, a in enumerate(ax.flat):
    img, label = test_generator.next()
    a.imshow(img[0],)
    a.set_title(label[0])

plt.tight_layout()
plt.show()

# 构建神经网络
model = models.Sequential()

# 1.Conv2D层,32个过滤器。输出图片尺寸:150-3+1=148*148,参数数量:32*3*3*3+32=896
model.add(layers.Conv2D(32, (3, 3),
                        activation='relu',
                        input_shape=(150, 150, 3)))  # 卷积层1
model.add(layers.MaxPooling2D((2, 2)))  # 最大值池化层1。输出图片尺寸:148/2=74*74

# 2.Conv2D层,64个过滤器。输出图片尺寸:74-3+1=72*72,参数数量:64*3*3*32+64=18496
model.add(layers.Conv2D(64, (3, 3),
                        activation='relu'))  # 卷积层2
model.add(layers.MaxPooling2D((2, 2)))  # 最大值池化层2。输出图片尺寸:72/2=36*36

# 3.Conv2D层,128个过滤器。输出图片尺寸:36-3+1=34*34,参数数量:128*3*3*64+128=73856
model.add(layers.Conv2D(128, (3, 3),
                        activation='relu'))  # 卷积层3
model.add(layers.MaxPooling2D((2, 2)))  # 最大值池化层3。输出图片尺寸:34/2=17*17

# 4.Conv2D层,128个过滤器。输出图片尺寸:17-3+1=15*15,参数数量:128*3*3*128+128=147584
model.add(layers.Conv2D(128, (3, 3),
                        activation='relu'))  # 卷积层4
model.add(layers.MaxPooling2D((2, 2)))  # 最大值池化层4。输出图片尺寸:15/2=7*7

# 将输入层的数据压缩成1维数据,全连接层只能处理一维数据
model.add(layers.Flatten())

# 全连接层
model.add(layers.Dense(512,
                       activation='relu'))  # 全连接层1
model.add(layers.Dense(1,
                       activation='sigmoid'))  # 全连接层2,作为输出层。sigmoid分类,输出是两类别

# 编译模型
# RMSprop 优化器。因为网络最后一层是单一sigmoid单元,
# 所以使用二元交叉熵作为损失函数
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])

# 看一下特征图的维度如何随着每层变化
model.summary()
#

train_datagen = ImageDataGenerator(rescale=1./255,
                                   rotation_range=40,  # 将图像随机旋转40度
                                   width_shift_range=0.2,  # 在水平方向上平移比例为0.2
                                   height_shift_range=0.2,  # 在垂直方向上平移比例为0.2
                                   shear_range=0.2,  # 随机错切变换的角度为0.2
                                   zoom_range=0.2,  # 图片随机缩放的范围为0.2
                                   horizontal_flip=True,  # 随机将一半图像水平翻转
                                   fill_mode='nearest')  # 填充创建像素
validation_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=IMG_SIZE,  # 输入训练图像尺寸
    batch_size=BATCH_SIZE,
    class_mode='binary')

validation_generator = validation_datagen.flow_from_directory(
    validation_dir,
    target_size=IMG_SIZE,
    batch_size=BATCH_SIZE,
    class_mode='binary')
#
# 训练模型50轮次
history_save = model.fit(
                    train_generator,
                    steps_per_epoch=100,
                    epochs=50,
                    validation_data=validation_generator,
                    validation_steps=50)

# 将训练过程产生的数据保存为h5文件
model.save('sex/faces/sex_model.h5')
# 保存数据增强后的训练模型
model.save('sex/faces/sex_model_idg.h5')

# 绘制损失曲线和精度曲线图
accuracy = history_save.history['acc']  # 训练集精度
loss = history_save.history['loss']  # 训练集损失
val_loss = history_save.history['val_loss']  # 验证集精度
val_accuracy = history_save.history['val_acc']  # 验证集损失
plt.figure(figsize=(17, 7))

# 训练集精度和验证集精度曲线图图
plt.subplot(2, 2, 1)
plt.plot(range(50), accuracy, 'bo', label='Training Accuracy')
plt.plot(range(50), val_accuracy, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend(loc='center right')

# 训练集损失和验证集损失图
plt.subplot(2, 2, 2)
plt.plot(range(50), loss, 'bo', label='Training Loss')
plt.plot(range(50), val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend(loc='center right')

# 训练集精度和损失散点图
plt.subplot(2, 2, 3)
plt.scatter(range(50), accuracy, label="Training Accuracy", color='b', s=25, marker="o")
plt.scatter(range(50), loss, label="Training Loss", color='r', s=25, marker="o")
plt.title('Training : Accuracy and Loss')
plt.legend(loc='center right')

# 验证集精度和损失散点图
plt.subplot(2, 2, 4)
plt.scatter(range(50), val_accuracy, label="Validation Accuracy", color='b', s=25, marker="o")
plt.scatter(range(50), val_loss, label="Validation Loss", color='r', s=25, marker="o")
plt.title('Validation : Accuracy and Loss')
plt.legend(loc='center right')

plt.show()

# 将图片缩小到(150,150)的大小
def convertjpg(jpgfile, outdir, width=150, height=150):
    img = Image.open(jpgfile)
    try:
        new_img = img.resize((width, height), Image.BILINEAR)
        new_img.save(os.path.join(outdir, os.path.basename(jpgfile)))
    except Exception as e:
        print(e)

# 从测试集随机获取一张男性图片
man_test = r'sex\faces\test\man'
man_test_list = os.listdir(man_test)
key = random.randint(0, len(man_test_list))
img_key = man_test_list[key]
jpg_file = os.path.join(man_test, img_key)
convertjpg(jpg_file, "sex/faces/test")  # 图像大小改变到(150,150)
img_scale = plt.imread('sex/faces/test/' + img_key)
plt.imshow(img_scale)  # 显示改变图像大小后的图片确实变到了(150,150)大小

# 调用训练模型结果进行预测
model = load_model('sex/faces/sex_model.h5')
img_scale = img_scale.reshape(1, 150, 150, 3).astype('float32')
img_scale = img_scale/255  # 归一化到0-1之间
result = model.predict(img_scale)  # 取图片信息
if result > 0.5:
    print('该图片是女性的概率为:', result)
else:
    print('该图片是男性的概率为:', 1-result)
plt.show()  # 打印尺寸改变后的图像

# 从测试集随机获取一张女性图片
woman_test = r'sex\faces\test\woman'
woman_test_list = os.listdir(woman_test)
key = random.randint(0, len(woman_test_list))
img_key = woman_test_list[key]
jpg_file = os.path.join(woman_test, img_key)
convertjpg(jpg_file, "sex/faces/test")  # 图像大小改变到(150,150)
img_scale = plt.imread('sex/faces/test/' + img_key)
plt.imshow(img_scale)  # 显示改变图像大小后的图片确实变到了(150,150)大小

# 调用训练模型结果进行预测
model = load_model('sex/faces/sex_model.h5')
img_scale = img_scale.reshape(1, 150, 150, 3).astype('float32')
img_scale = img_scale/255  # 归一化到0-1之间
result = model.predict(img_scale)  # 取图片信息
if result > 0.5:
    print('该图片是女性的概率为:', result)
else:
    print('该图片是男性的概率为:', 1-result)
plt.show()  # 打印尺寸改变后的图像

# 自定义一张男性图片进行预测
diy_img = 'sex/faces/man.jpg'
convertjpg(diy_img, "sex")  # 图像大小改变到(150,150)
img_scale = plt.imread('sex/man.jpg')
plt.imshow(img_scale)  # 显示改变图像大小后的图片确实变到了(150,150)大小

# 调用数据增强后的训练模型结果进行预测
model = load_model('sex/faces/sex_model_idg.h5')
img_scale = img_scale.reshape(1, 150, 150, 3).astype('float32')
img_scale = img_scale/255  # 归一化到0-1之间
result = model.predict(img_scale)  # 取图片信息
if result > 0.5:
    print('该图片是女性的概率为:', result)
else:
    print('该图片是男性的概率为:', 1-result)
plt.show()  # 打印尺寸改变后的图像

# 自定义一张女性图片进行预测
diy_img = 'sex/faces/woman_2.jpg'
convertjpg(diy_img, "sex")  # 图像大小改变到(150,150)
img_scale = plt.imread('sex/woman_2.jpg')
plt.imshow(img_scale)  # 显示改变图像大小后的图片确实变到了(150,150)大小

# 调用数据增强后的训练模型结果进行预测
model = load_model('sex/faces/sex_model.h5')
img_scale = img_scale.reshape(1, 150, 150, 3).astype('float32')
img_scale = img_scale/255  # 归一化到0-1之间
result = model.predict(img_scale)  # 取图片信息
if result > 0.5:
    print('该图片是女性的概率为:', result)
else:
    print('该图片是男性的概率为:', 1-result)
plt.show()  # 打印尺寸改变后的图像

 四、实验总结

        机器学习就是通过利用数据,训练模型,然后模型预测的一种方法。这次学习主要是对二分类进行实践。二分类:所用到的二分类函数即sigmoid。用ImageDataGenerator数据增强进行二次训练。绘制两次训练的损失精度曲线图。相比第一次训练模型,第二次训练模型精度较低。但对图像进行识别的精确率仍是较准确的。

        本次程序设计的不足:在数据增强上效果不是很明显,在设计过程中还遇到图像失真导致训练精度上升缓慢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2097593.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot图书商城

1.可注册可登录 2.首页-》可浏览热销图书&#xff0c;可查看用户发布的帖子&#xff0c;可查看热门资讯 3.图书商城-》图书详情&#xff0c;可购买&#xff0c;可加入购物车&#xff0c;可展示评价 4.图书贴吧-》可查看用户发布的帖子&#xff0c;可留言评论 5.平台资讯-》可查…

BugKu练习记录:小山丘的秘密

题目&#xff1a; hill能有什么秘密呢 bugku{PLGTGBQHM} 其中A1&#xff0c;flag全为小写hill解密&#xff0c;a1&#xff0c;所以z0&#xff0c;字母表为zabcdefghijklmnopqrstuvwxy&#xff0c;根据图片上的棋子数得到对应的字母&#xff0c;分别是abczadefz&#xff0c;用工…

无头结点单链表直接插入排序(王红梅分级抽象教学方法)

struct ListNode {int val;struct ListNode* next; };typedef struct ListNode ListNode; struct ListNode* insertionSortList(struct ListNode* head) {// 如果链表为空或者链表只有一个元素&#xff0c;那就根本不用排序if (head NULL || head->next NULL)return head…

C++入门基础知识45——【关于C++ 函数】定义函数、函数声明

成长路上不孤单&#x1f60a;【14后&#xff0c;C爱好者&#xff0c;持续分享所学&#xff0c;如有需要欢迎收藏转发&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#xff01;&#xff01;&#xff01;&#xff01;&#xff…

海外广告投放成功的关键点有哪些?

在全球化日益加深的今天&#xff0c;海外广告投放已成为众多企业拓展国际市场、提升品牌影响力的关键手段。然而&#xff0c;面对不同文化、语言、消费习惯以及市场环境的挑战&#xff0c;如何确保海外广告投放的成功&#xff0c;是每一个跨境营销者面对的重大课题。本文将从多…

曹启富主任医师:高血压的罪魁祸首找到啦!原来是他变硬了

上周公司一年一度的体检&#xff0c;如同一场无声的健康大考&#xff0c;本以为不过是例行公事&#xff0c;走走过场&#xff0c;没想到却意外揭开了许多同事健康背后的隐忧。平日里自诩年轻力壮、身体倍儿棒的他们&#xff0c;体检报告上却赫然出现了多个警示灯&#xff0c;让…

开放式耳机是什么意思?开放式耳机好不好用?

开放式耳机是一种在设计上不会完全封闭或堵塞耳道的耳机类型 。其发声原理通常是通过空气传导和骨传导的组合&#xff0c;将声音传递到内耳&#xff0c;并刺激听觉神经产生听觉感受 。 优点&#xff1a; 佩戴舒适&#xff1a;通常采用轻盈的设计&#xff0c;不会直接刺激耳膜&…

心脑血管科曹启富主任医师:低压高的2大原因!年轻人血压高一定要看

在现代社会&#xff0c;不仅仅是中老年人&#xff0c;越来越多的年轻人也开始面临血压低压&#xff08;舒张压&#xff09;偏高的问题。这一现象往往被忽视&#xff0c;但其潜在的健康风险却不容忽视。了解低压高的原因&#xff0c;对于年轻人维护心血管健康至关重要。本文将深…

海外社交媒体引流策略及云手机的应用

在外贸电商领域&#xff0c;海外社交媒体引流已成为一种极为有效的营销手段。通过精准锁定目标受众&#xff0c;企业能够以较低成本获取大量流量&#xff0c;从而提高转化率。在这个过程中&#xff0c;云手机的应用也越来越受到重视。 首先&#xff0c;我们需要选择适合的海外社…

工作录屏工具选择全攻略:哪种录屏工具更得你心?

在如今这个信息爆炸的时代&#xff0c;电脑录屏工具已经成为我们工作中不可或缺的利器。无论是制作教程、演示操作还是记录重要时刻&#xff0c;一款好的录屏工具都能让我们的工作事半功倍。接下来&#xff0c;为大家推荐几款工作中常用的电脑录屏工具&#xff0c;并分享使用感…

Neo4j在Ubuntu 20.04上安装

rootnode11:~# cat /etc/lsb-release DISTRIB_IDUbuntu DISTRIB_RELEASE20.04 DISTRIB_CODENAMEfocal DISTRIB_DESCRIPTION"Ubuntu 20.04.6 LTS" rootnode11:~# cat /etc/issue Ubuntu 20.04.6 LTS \n \l 1.安装jdk java 1.8.xx版本对应neo4j 3.xx版本 jdk 11版本对…

CpK vs PpK,过程能力指标的精彩对决

Cpk VS Ppk&#xff08;一&#xff09;描述 对于Cpk和Ppk这两个概念&#xff0c;大家可能会有无数个疑问&#xff01;这两个指标我该看哪个&#xff1f;计算有什么差别……那么我们首先来看一下Minitab中对它们俩是怎么描述的。 大多数能力评估都可以分组为以下两种类别中的一…

区块链未来发展展望:机遇与挑战并存

前言 随着全球数字化进程的不断推进&#xff0c;区块链技术作为一种去中心化、安全性高、透明度强的分布式账本技术&#xff0c;正逐步融入各个领域并产生深远影响。近年来&#xff0c;区块链已经从初期的加密货币应用扩展到金融、供应链管理、医疗健康、物联网、能源等多个行…

位图(布隆过滤器)

bitset/bitmap 给40亿个不重复的无符号整数&#xff0c;没排过序。给1个无符号整数,如何快速判断一个数是否在这40亿个数中。 ​ #pragma once#include <vector> #include <string> #include <time.h>template<size_t N> class bitset { public:bitse…

实战docker第一天——windows安装docker,测试,并解决被墙办法

Docker 是一个开源的容器化平台&#xff0c;它允许开发者将应用程序及其所有依赖项打包在一个名为“容器”的单独环境中&#xff0c;从而确保应用程序在任何环境下都能一致地运行。以下是 Docker 的一些核心概念及其意义&#xff1a; 容器化&#xff1a;Docker 通过将应用程序及…

外卖霸王餐系统的运作流程及注意事项

霸王餐系统概述 一、系统组成 商家端发布霸王餐活动信息&#xff0c;包括菜品、时间、人数等。管理活动报名者信息。查看活动效果和用户反馈。用户端浏览和报名感兴趣的霸王餐活动。提交评价和反馈。管理后台审核商家和用户信息。监控活动流程和数据。 二、运作流程 1.商家…

去中心化网络:Web3如何颠覆传统互联网

在互联网的演进过程中&#xff0c;从最初的静态网页到交互式的Web2.0&#xff0c;技术的进步不断推动着网络的变革。而如今&#xff0c;Web3作为互联网的下一代技术&#xff0c;正以其去中心化的特性&#xff0c;逐步颠覆传统的互联网架构。本文将深入探讨Web3如何通过去中心化…

CH9114 USB转四串口替换FT4232H系列芯片

之前针对CH9101系列芯片替换FT232系列芯片型号发布了一系列文章&#xff0c;想必有需要的同学或工程师已经体验过替换的便捷之处了。早前CH系列芯片只发现有单串口型号的替换&#xff0c;4串口芯片苦于迟迟找不到替换型号&#xff0c;所幸今年和他们工程师聊天中获悉&#xff0…

【C语言必学知识点六】自定义类型——结构体

结构体 导读一、自定义类型二、结构体2.1 什么是结构体2.2 结构的声明2.2.1 构体的声明格式2.2.2 结构体的特殊声明 2.3 关键字typedef2.3.1 typedef的作用2.3.2 typedef的使用2.3.2 typedef在结构体中的应用 2.4 结构体变量的创建和初始化2.4.1 结构体变量创建的区别2.4.2 重命…

系统一执行systemctl就报错`No space left on device`,全部拿下

前言 在现代计算机系统中&#xff0c;存储空间似乎总是无尽的&#xff0c;但当你突然看到“No space left on device”的错误消息时&#xff0c;那种突然的焦虑感可不是开玩笑的。这就像是你在一个精心设计的房间里忽然发现最后一块空地也被填满了——这时候你会发现&#xff…