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

一、选题背景

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

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

        从网站中下载相关的数据集,对数据集进行整理,在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_direlif i < 9000:to_path = woman_validation_direlse:to_path = woman_test_dircopy(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_direlif i < 9000:to_path = man_validation_direlse:to_path = man_test_dircopy(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.2height_shift_range=0.2,  # 在垂直方向上平移比例为0.2shear_range=0.2,  # 随机错切变换的角度为0.2zoom_range=0.2,  # 图片随机缩放的范围为0.2horizontal_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_direlif i < 9000:to_path = woman_validation_direlse:to_path = woman_test_dircopy(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_direlif i < 9000:to_path = man_validation_direlse:to_path = man_test_dircopy(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.2height_shift_range=0.2,  # 在垂直方向上平移比例为0.2shear_range=0.2,  # 随机错切变换的角度为0.2zoom_range=0.2,  # 图片随机缩放的范围为0.2horizontal_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.rhkb.cn/news/415728.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springnboot +uniapp汽车租赁系统

springnboot uniapp汽车租赁系统 手机移动端&#xff1a;主页&#xff0c;租赁汽车展示&#xff0c;汽车租赁&#xff0c;我的租赁记录&#xff0c;还车记录&#xff0c;注册登录&#xff0c;修改个人资料 PC端管理后台&#xff1a;公告管理&#xff0c;用户管理&#xff0c;…

【链表】环形链表

环形链表 环形链表I题目思路讲解代码书写拓展问题 环形链表II题目题目解析思路讲解代码书写 环形链表I 题目 题目链接: 环形链表 思路讲解 对于探究一个线性结构是否有环, 最经典的做法就是快慢指针法. 我们定义两个指针, 一个一次走两步, 一个一次走一步, 走完后判断两个是…

虚幻引擎VR游戏开发01 | VR设备和术语

四款Unreal Engine默认配套按键映射的VR设备 IMC按键映射 Oculus Touch (R) Grip Axis: 代表Oculus Rift或Quest设备的右手控制器的抓握轴输入。Valve Index (R) Grip Axis: 代表Valve Index设备的右手控制器的抓握轴输入。Vive (R) Grip: 代表HTC Vive设备的右手控制器的抓握…

chrome 插件开发入门

1. 介绍 Chrome 插件可用于在谷歌浏览器上控制当前页面的一些操作&#xff0c;可自主控制网页&#xff0c;提升效率。 平常我们可在谷歌应用商店中下载谷歌插件来增强浏览器功能&#xff0c;作为开发者&#xff0c;我们也可以自己开发一个浏览器插件来配合我们的日常学习工作…

Vite - 兼容旧版浏览器 plugin-legacy(2)

目录 1&#xff0c;问题2&#xff0c;解决3&#xff0c;String 其他新增 API 的版本 接上文 Vite - 兼容旧版浏览器 plugin-legacy&#xff08;1&#xff09; 1&#xff0c;问题 客户浏览器报错&#xff0c;不支持 replaceAll 方法。 该方法在 query-string 依赖内部使用了。…

嵌入式Linux:常见信号的默认行为

信号是一种软件中断&#xff0c;用于通知进程发生了某种异步事件。信号可以由用户、其他进程或操作系统内核产生。进程可以选择捕获并处理这些信号&#xff0c;或者忽略它们&#xff0c;让系统执行默认操作。 不可靠信号&#xff08;非实时信号&#xff09;&#xff1a;编号为 …

反爬虫策略收录集

前言 反爬虫&#xff0c;是指对扫描器中的网络爬虫环节进行反制&#xff0c;通过一些反制策略来阻碍或干扰爬虫的正常爬行&#xff0c;从而间接地起到防御目的。下面是一些常见的反爬虫策略的收录。 入门版 封IP 由于服务器有防火墙&#xff08;如果防火墙在TCP/UDP层或者它…

渲染100高性能云渲染,性价比超高

在这个3D渲染行业迅速发展的时代&#xff0c;对于渲染速度和稳定性的渴望日益强烈。需要更快的渲染时间来缩短项目周期&#xff0c;同时希望渲染过程更加稳定&#xff0c;避免问题导致的损失。 如今市场上虽然不乏各种云渲染服务&#xff0c;但要找到既经济又能满足高要求的选…

Java内存区域

文章目录 运行时数据区域1. 程序计数器2. 虚拟机栈局部变量表 3. 本地方法栈4. 堆5. 方法区运行时常量池直接内存 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途&#xff0c;以及创建和销毁的时间&…

sqli-labs靶场通关攻略(61-65)

Less-61 步骤一&#xff1a;查看数据库 ?id1)) and updatexml(1,concat(1,(select database())),1)-- 步骤二&#xff1a;查看表名 ?id1)) and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schemasecurity)),1)--…

uniapp写的一个年月日时分秒时间选择功能

代码: <template><view><picker mode"multiSelector" :value"multiIndex" :range"multiRange" change"onMultiChange"><view class"picker">当前选择&#xff1a;{{ formattedDateTime }}</vie…

中国各地级市的海拔标准差

海拔标准差是衡量地理测量准确性的重要指标&#xff0c;它通过计算特定地点的海拔测量值与平均海拔之间的偏差来评估数据的可靠性。较小的标准差意味着测量结果较为一致&#xff0c;而较大的标准差则可能指出数据的波动性或测量误差。 计算方法 海拔标准差的计算遵循以下公式…

C++学习/复习补充记录 --- 图论(深搜,广搜)

图的度 无向图&#xff1a; 连接某节点的边数&#xff0c;即为该节点的【度】。 &#xff08;无向图中&#xff0c;有5条边连接节点4&#xff0c;则节点4的度为5。&#xff09; 有向图&#xff1a; 出度&#xff1a;从该节点出发的边的个数。 入度&#xff1a;指向该节点边的个…

Idea_服务器自动化部署_傻瓜式教程

使用Alibaba Cloud Toolkit 在 IntelliJ IDEA 中一键部署项目到服务器 1. 安装 Alibaba Cloud Toolkit 插件 确保 IntelliJ IDEA 版本为 2018.3 或以上。打开 IntelliJ IDEA&#xff0c;进入 File -> Settings -> Plugins&#xff0c;搜索并安装 Alibaba Cloud Toolkit…

【Python基础】字典类型

本文收录于 《Python编程入门》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程基础知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、Python 字典类型2.1 访问字典里的值2.2 修改字典2.3 删除字典元素2.4 字典键值的特性2.5 遍历字典…

Vision Transformer (ViT) + 代码【详解】

文章目录 1、Vision Transformer (ViT) 介绍2、patch embedding3、代码3.1 class embedding Positional Embedding3.2 Transformer Encoder3.3 classifier3.4 ViT总代码 1、Vision Transformer (ViT) 介绍 VIT论文的摘要如下&#xff0c;谷歌翻译如下&#xff1a; 虽然 Transf…

《JavaEE进阶》----10.<SpringMVC应用分层:【三层架构】>

本篇博客我们主要讲解 1.应用的分层&#xff1a;三层架构 2.Spring MVC和三层架构的区别和联系 3.软件设计原则&#xff1a;高内聚低耦合 4.应用分层的好处 5.通过应用分层后的代码示例 一、三层架构简介 阿里开发手册中,关于工程结构部分,定义了常见工程的应用分层结构: 上图…

【Java 基础】:三大特征之多态

✨ 杏花疏影里&#xff0c;吹笛到天明 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;java学习 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&…

u盘格式化数据还能恢复吗?点击了解实用教程

U盘是电子数据存储设备&#xff0c;我们主要用它来转移数据、随身携带数据等。同时U盘在使用过程中常会遇到问题&#xff0c;比如U盘中毒&#xff0c;U盘中毒会导致里面保存的数据文件无法读取&#xff0c;我们需要进行U盘格式化。格式化之后的U盘才可以继续使用&#xff0c;那…

软件测试-Selenium+python自动化测试

目录 会用到谷歌浏览器Chrome测试,需要下载一个Chromedriver(Chrome for Testing availability)对应自己的浏览器版本号选择。 一、元素定位 对html网页中的元素进行定位,同时进行部分操作。 1.1一个简单的模板 from selenium import webdriver from selenium.webdrive…