无意间在kaggle上发现的一个数据集,旨在提高网络模型判别男女的准确率,博主利用迁移学习试验了多个卷积神经网络,最终的模型准确率在95%左右。并划分了训练集、测试集、验证集三类,最终在验证集上的准确率为93.63%.
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 # 用来正常显示负号
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
按照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()
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的模型准确率是最高的。
网络保存:
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) # 绘制混淆矩阵
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啊