机器学习——人脸识别判断表情

一、选题背景

随着机器学习和深度神经网络两个领域的迅速发展以及智能设备的普及,人脸识别技术正在经历前所未有的发展,关于人脸识别技术讨论从未停歇。目前,人脸识别精度已经超过人眼,同时大规模普及的软硬件基础条件也已具备,应用市场和领域需求很大,基于这项技术的市场发展和具体应用正呈现蓬勃发展态势。

人脸表情识别作为人脸识别技术中的一个重要组成部分,近年来在人机交互、安全、机器人制造、自动化、医疗、通信和驾驶领域得到了广泛的关注,成为学术界和工业界的研究热点。

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

数据来源:

本案例中涉及的数据集来源于 INC 网站 ,案例用keras框架对人脸面部图像进行的笑脸识别。

数据集包括4000张不同大小的像素的面部图像,通过人脸识别68个特征点检测数据库(shape_predictor_68_face_landmarks.dat)进一步确定人脸大小,将具有笑脸特征的图像转化为150×150像素保存在一个文件夹内。

使用用keras,搭建模型,训练模型,输出模型训练次数的精度变化, 导入图片测试模型。

三、机器学习的实现步骤

1.下载数据集

 

 2.导入需要用到的库

复制代码
 1 import dlib  # 人脸识别的库dlib
 2 import numpy as np  # 数据处理的库numpy
 3 import cv2  # 图像处理的库OpenCv
 4 import os
 5 from keras import layers
 6 from keras import models
 7 from keras import optimizers
 8 from keras.preprocessing.image import ImageDataGenerator
 9 import matplotlib.pyplot as plt
10 from keras.utils import image_utils
复制代码

3.对图片进行人脸识别,并截取人脸部分输出150*150像素图像。

复制代码
 1 import dlib  # 人脸识别的库dlib
 2 import numpy as np  # 数据处理的库numpy
 3 import cv2  # 图像处理的库OpenCv
 4 import os
 5 
 6 # dlib预测器
 7 detector = dlib.get_frontal_face_detector()
 8 predictor = dlib.shape_predictor('E:\\smiletest\\shape_predictor_68_face_landmarks.dat')
 9 
10 # 读取图像的路径
11 path_read = "E:\\smiletest\\files"
12 num = 0
13 for file_name in os.listdir(path_read):
14     # aa是图片的全路径
15     aa = (path_read + "/" + file_name)
16     # 读入的图片的路径中含非英文
17     img = cv2.imdecode(np.fromfile(aa, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
18     # 获取图片的宽高
19     img_shape = img.shape
20     img_height = img_shape[0]
21     img_width = img_shape[1]
22 
23     # 用来存储生成的单张人脸的路径
24     path_save = "E:\\smiletest\\files1"
25     # dlib检测
26     dets = detector(img, 1)
27     print("人脸数:", len(dets))
28     for k, d in enumerate(dets):
29         if len(dets) > 1:
30             continue
31         num = num + 1
32         # 计算矩形大小
33         # (x,y), (宽度width, 高度height)
34         pos_start = tuple([d.left(), d.top()])
35         pos_end = tuple([d.right(), d.bottom()])
36 
37         # 计算矩形框大小
38         height = d.bottom() - d.top()
39         width = d.right() - d.left()
40 
41         # 根据人脸大小生成空的图像
42         img_blank = np.zeros((height, width, 3), np.uint8)
43         for i in range(height):
44             if d.top() + i >= img_height:  # 防止越界
45                 continue
46             for j in range(width):
47                 if d.left() + j >= img_width:  # 防止越界
48                     continue
49                 img_blank[i][j] = img[d.top() + i][d.left() + j]
50         img_blank = cv2.resize(img_blank, (200, 200), interpolation=cv2.INTER_CUBIC)
51 
52         cv2.imencode('.jpg', img_blank)[1].tofile(path_save + "\\" + "file" + str(num) + ".jpg")  
复制代码

 

 

 

4.导入数据集路径,对数据集进行分类。

复制代码
 1 import os, shutil
 2 
 3 # 原始数据集路径
 4 original_dataset_dir = 'E:\\smiletest\\files1'
 5 
 6 # 新的数据集
 7 base_dir = 'E:\\smiletest\\files2'\
 8 # 创建文件夹
 9 os.mkdir(base_dir)
10 
11 # 训练图像、验证图像、测试图像的目录
12 train_dir = os.path.join(base_dir, 'train')
13 os.mkdir(train_dir)
14 validation_dir = os.path.join(base_dir, 'validation')
15 os.mkdir(validation_dir)
16 test_dir = os.path.join(base_dir, 'test')
17 os.mkdir(test_dir)
18 
19 train_smiles_dir = os.path.join(train_dir, 'smile')
20 os.mkdir(train_smiles_dir)
21 
22 train_unsmiles_dir = os.path.join(train_dir, 'unsmile')
23 os.mkdir(train_unsmiles_dir)
24 
25 validation_smiles_dir = os.path.join(validation_dir, 'smile')
26 os.mkdir(validation_smiles_dir)
27 
28 validation_unsmiles_dir = os.path.join(validation_dir, 'unsmile')
29 os.mkdir(validation_unsmiles_dir)
30 
31 test_smiles_dir = os.path.join(test_dir, 'smile')
32 os.mkdir(test_smiles_dir)
33 
34 test_unsmiles_dir = os.path.join(test_dir, 'unsmile')
35 os.mkdir(test_unsmiles_dir)
36 
37 # 复制900张笑脸图片到train_smiles_dir
38 fnames = ['file{}.jpg'.format(i) for i in range(1, 900)]
39 for fname in fnames:
40     src = os.path.join(original_dataset_dir, fname)
41     dst = os.path.join(train_smiles_dir, fname)
42     shutil.copyfile(src, dst)
43 # 复制450张笑脸图片到validation_smiles_dir
44 fnames = ['file{}.jpg'.format(i) for i in range(900, 1350)]
45 for fname in fnames:
46     src = os.path.join(original_dataset_dir, fname)
47     dst = os.path.join(validation_smiles_dir, fname)
48     shutil.copyfile(src, dst)
49 
50 # 复制450张笑脸图片到test_smiles_dir
51 fnames = ['file{}.jpg'.format(i) for i in range(1350, 1800)]
52 for fname in fnames:
53     src = os.path.join(original_dataset_dir, fname)
54     dst = os.path.join(test_smiles_dir, fname)
55     shutil.copyfile(src, dst)
56 
57 # 复制873张笑脸图片到train_unsmiles_dir
58 fnames = ['file{}.jpg'.format(i) for i in range(2127, 3000)]
59 for fname in fnames:
60     src = os.path.join(original_dataset_dir, fname)
61     dst = os.path.join(train_unsmiles_dir, fname)
62     shutil.copyfile(src, dst)
63 
64 # 复制878张笑脸图片到validation_unsmiles_dir
65 fnames = ['file{}.jpg'.format(i) for i in range(3000, 3878)]
66 for fname in fnames:
67     src = os.path.join(original_dataset_dir, fname)
68     dst = os.path.join(validation_unsmiles_dir, fname)
69     shutil.copyfile(src, dst)
复制代码

 

 

5.输出分类后的数据集图片数量

1 print('total training smile images:', len(os.listdir(train_smiles_dir)))
2 print('total training unsmile images:', len(os.listdir(train_unsmiles_dir)))
3 print('total testing smile images:', len(os.listdir(test_smiles_dir)))
4 print('total testing unsmile images:', len(os.listdir(test_unsmiles_dir)))
5 print('total validation smile images:', len(os.listdir(validation_smiles_dir)))
6 print('total validation unsmile images:', len(os.listdir(validation_unsmiles_dir)))

 

 

 

 

 6.数据集分类完成后,搭建卷积网络。

复制代码
 1 from keras import layers
 2 from keras import models
 3 #创建模型
 4 model = models.Sequential()
 5 #第一个卷积层作为输入层,32个3*3卷积核
 6 #输出尺寸:150-3+1=148*148,参数数量:32*3*3*3+32=896
 7 model.add(layers.Conv2D(32, (3, 3), activation='relu',input_shape=(150, 150, 3)))
 8 model.add(layers.MaxPooling2D((2, 2)))
 9 #输出尺寸:74-3+1=72*72,对应数量:64*3*3*32+64=18496
10 model.add(layers.Conv2D(64, (3, 3), activation='relu'))
11 model.add(layers.MaxPooling2D((2, 2)))
12 #输出尺寸:36-3+1=34*34,对应数量:128*3*3*64+128=73856
13 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
14 model.add(layers.MaxPooling2D((2, 2)))
15 #输出尺寸:17-3+1=15*15,对应数量:128*3*3*128+128=147584
16 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
17 model.add(layers.MaxPooling2D((2, 2)))
18 model.add(layers.Flatten())
19 model.add(layers.Dense(512, activation='relu'))
20 model.add(layers.Dense(1, activation='sigmoid'))
21 model.summary()#查看标量信息
复制代码

 

 

 

 

 7.将所有图片统一化

复制代码
 1 from keras import layers
 2 from keras import models
 3 from keras import optimizers
 4 #统一化
 5 model.compile(loss='binary_crossentropy',
 6               optimizer=optimizers.RMSprop(lr=1e-4),
 7               metrics=['acc'])
 8 train_datagen = ImageDataGenerator(rescale=1./255)
 9 validation_datagen=ImageDataGenerator(rescale=1./255)
10 test_datagen = ImageDataGenerator(rescale=1./255)
11 train_generator = train_datagen.flow_from_directory(
12         # 目标文件目录
13         train_dir,
14         #所有图片的size必须是150x150
15         target_size=(150, 150),
16         batch_size=20,
17         class_mode='binary')
18 validation_generator = test_datagen.flow_from_directory(
19         validation_dir,
20         target_size=(150, 150),
21         batch_size=20,
22         class_mode='binary')
23 test_generator = test_datagen.flow_from_directory(test_dir,
24                                                    target_size=(150, 150),
25                                                    batch_size=20,
26                                                    class_mode='binary')
27 for data_batch, labels_batch in train_generator:
28     print('data batch shape:', data_batch.shape)
29     print('labels batch shape:', labels_batch)
30     break
复制代码

 

 

 

 

 ‘微笑’:0,‘非微笑’:1

8.对图像进行预处理(数据增强)

复制代码
 1 from keras import layers
 2 from keras import models
 3 from keras import optimizers
 4 from keras.preprocessing.image import ImageDataGenerator
 5 import os, shutil
 6 #数据增强
 7 datagen = ImageDataGenerator(
 8       rotation_range=40,
 9       width_shift_range=0.2,
10       height_shift_range=0.2,
11       shear_range=0.2,
12       zoom_range=0.2,
13       horizontal_flip=True,
14       fill_mode='nearest')
15 #数据增强后图片变化
16 import matplotlib.pyplot as plt
17 # from keras.preprocessing import image
18 from keras.utils import image_utils
19 train_smile_dir='E:\\smiletest\\files2\\train\\smile'
20 fnames = [os.path.join(train_smile_dir, fname) for fname in os.listdir(train_smile_dir)]
21 img_path = fnames[3]
22 img = image_utils.load_img(img_path, target_size=(150, 150))
23 x = image_utils.img_to_array(img)
24 x = x.reshape((1,) + x.shape)
25 i = 0
26 for batch in datagen.flow(x, batch_size=1):
27     plt.figure(i)
28     imgplot = plt.imshow(image_utils.array_to_img(batch[0]))
29     i += 1
30     if i % 4 == 0:
31         break
32 plt.show()
复制代码

 

 

 

 

 9.训练卷积神经网络

复制代码
 1 from keras import layers
 2 from keras import models
 3 from keras import optimizers
 4 import matplotlib.pyplot as plt
 5 #创建网络
 6 from keras.preprocessing.image import ImageDataGenerator
 7 
 8 model = models.Sequential()
 9 model.add(layers.Conv2D(32, (3, 3), activation='relu',input_shape=(150, 150, 3)))
10 model.add(layers.MaxPooling2D((2, 2)))
11 model.add(layers.Conv2D(64, (3, 3), activation='relu'))
12 model.add(layers.MaxPooling2D((2, 2)))
13 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
14 model.add(layers.MaxPooling2D((2, 2)))
15 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
16 model.add(layers.MaxPooling2D((2, 2)))
17 model.add(layers.Flatten())
18 model.add(layers.Dropout(0.5))
19 model.add(layers.Dense(512, activation='relu'))
20 model.add(layers.Dense(1, activation='sigmoid'))
21 model.compile(loss='binary_crossentropy',
22               optimizer=optimizers.RMSprop(lr=1e-4),
23               metrics=['acc'])
24 
25 #统一化处理
26 train_datagen = ImageDataGenerator(
27     rescale=1./255,
28     rotation_range=40,
29     width_shift_range=0.2,
30     height_shift_range=0.2,
31     shear_range=0.2,
32     zoom_range=0.2,
33     horizontal_flip=True,)
34 
35 test_datagen = ImageDataGenerator(rescale=1./255)
36 train_dir = 'E:\\smiletest\\files2\\train'
37 validation_dir='E:\\smiletest\\files2\\validation'
38 train_generator = train_datagen.flow_from_directory(
39         # This is the target directory
40         train_dir,
41         # All images will be resized to 150x150
42         target_size=(150, 150),
43         batch_size=32,
44         # Since we use binary_crossentropy loss, we need binary labels
45         class_mode='binary')
46 
47 validation_generator = test_datagen.flow_from_directory(
48         validation_dir,
49         target_size=(150, 150),
50         batch_size=32,
51         class_mode='binary')
52 
53 history = model.fit_generator(
54       train_generator,
55       steps_per_epoch=55,
56       epochs=60,
57       validation_data=validation_generator,
58       validation_steps=27)
复制代码

 

 

 

 

 10.保存训练模型

 1 model.save('E:\\smiletest\\smileAndunsmile1.h5') 

 

 

 11.输出精度与损失曲线图和散点图

复制代码
 1 import matplotlib.pyplot as plt
 2 #数据增强过后的训练集与验证集的精确度与损失度的图形
 3 acc = history.history['acc']
 4 val_acc = history.history['val_acc']
 5 loss = history.history['loss']
 6 val_loss = history.history['val_loss']
 7 
 8 epochs = range(len(acc))
 9 # 输出精度度曲线图与散点图
10 plt.plot(epochs, acc, 'bo', label='Training acc')
11 plt.plot(epochs, val_acc, 'b', label='Validation acc')
12 plt.title('Training and validation accuracy')
13 plt.legend()
14 plt.figure()
15 # 输出损失曲线图与散点图
16 plt.plot(epochs, loss, 'bo', label='Training loss')
17 plt.plot(epochs, val_loss, 'b', label='Validation loss')
18 plt.title('Training and validation loss')
19 plt.legend()
20 plt.show()
复制代码

 

 

 

12.使用训练模型对单张图片进行判断是否微笑。

复制代码
 1 # import cv2
 2 # from keras.preprocessing import image
 3 from keras.utils import image_utils
 4 from keras.models import load_model
 5 import numpy as np
 6 # 单张图片进行判断是笑脸还是非笑脸
 7 # 加载模型
 8 model = load_model('E:\\smiletest\\smileAndunsmile1.h5')
 9 # 本地图片路径
10 img_path = 'E:\\smiletest\\testimg\\2.jpeg'
11 img = image_utils.load_img(img_path, target_size=(150, 150))
12 
13 img_tensor = image_utils.img_to_array(img) / 255.0
14 img_tensor = np.expand_dims(img_tensor, axis=0)
15 prediction = model.predict(img_tensor)
16 prediction1=str((1-prediction)*100).strip('[]')
17 # (1-prediction1)*100
18 print('笑脸的概率:',prediction1,'%')
19 if prediction[0][0] > 0.5:
20     result = '非笑脸'
21 else:
22     result = '笑脸'
23 print('测试结果:',result)
复制代码

 

笑脸

 

 

 

非笑脸

 

 四、总结

       在现代化社会工作学习给年轻人带来了诸多压力与困扰,笑容逐渐从脸上丢失,这是社会进步不得已的现如今人人都为学历、金钱、权利而奋斗,在内卷的过程中不知自己脸上那份可爱的笑容在不知不觉的消失了。此次项目识别人脸是否微笑是对社会幸福度的某一角度的贡献,可以通过人们时常微笑进而得出城市幸福度。

       通过学习人脸微笑识别的制作,大致了解了机器学习相关概念,整个过程让我感觉到机器学习的学习困难与逻辑思维上相比其他语言有着许多的不同,经过自己滚打摸爬解决了许多问题,遇到问题少有代码文档给予我理解与渗透。

      最后感谢老师的悉心栽培。

 

 

附完整代码

复制代码
  1 import dlib  # 人脸识别的库dlib
  2 import numpy as np  # 数据处理的库numpy
  3 import cv2  # 图像处理的库OpenCv
  4 import os
  5 
  6 # dlib预测器
  7 detector = dlib.get_frontal_face_detector()
  8 predictor = dlib.shape_predictor('E:\\smiletest\\shape_predictor_68_face_landmarks.dat')
  9 
 10 # 读取图像的路径
 11 path_read = "E:\\smiletest\\files"
 12 num = 0
 13 for file_name in os.listdir(path_read):
 14     # aa是图片的全路径
 15     aa = (path_read + "/" + file_name)
 16     # 读入的图片的路径中含非英文
 17     img = cv2.imdecode(np.fromfile(aa, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
 18     # 获取图片的宽高
 19     img_shape = img.shape
 20     img_height = img_shape[0]
 21     img_width = img_shape[1]
 22 
 23     # 用来存储生成的单张人脸的路径
 24     path_save = "E:\\smiletest\\files1"
 25     # dlib检测
 26     dets = detector(img, 1)
 27     print("人脸数:", len(dets))
 28     for k, d in enumerate(dets):
 29         if len(dets) > 1:
 30             continue
 31         num = num + 1
 32         # 计算矩形大小
 33         # (x,y), (宽度width, 高度height)
 34         pos_start = tuple([d.left(), d.top()])
 35         pos_end = tuple([d.right(), d.bottom()])
 36 
 37         # 计算矩形框大小
 38         height = d.bottom() - d.top()
 39         width = d.right() - d.left()
 40 
 41         # 根据人脸大小生成空的图像
 42         img_blank = np.zeros((height, width, 3), np.uint8)
 43         for i in range(height):
 44             if d.top() + i >= img_height:  # 防止越界
 45                 continue
 46             for j in range(width):
 47                 if d.left() + j >= img_width:  # 防止越界
 48                     continue
 49                 img_blank[i][j] = img[d.top() + i][d.left() + j]
 50         img_blank = cv2.resize(img_blank, (200, 200), interpolation=cv2.INTER_CUBIC)
 51 
 52         cv2.imencode('.jpg', img_blank)[1].tofile(path_save + "\\" + "file" + str(num) + ".jpg")  
 53 
 54 from keras import layers
 55 from keras import models
 56 from keras import optimizers
 57 from keras.preprocessing.image import ImageDataGenerator
 58 import os, shutil
 59 
 60 # 原始数据集路径
 61 original_dataset_dir = 'E:\\smiletest\\files1'
 62 
 63 # 新的数据集
 64 base_dir = 'E:\\smiletest\\files2'\
 65 # 创建文件夹
 66 os.mkdir(base_dir)
 67 
 68 # 训练图像、验证图像、测试图像的目录
 69 train_dir = os.path.join(base_dir, 'train')
 70 os.mkdir(train_dir)
 71 validation_dir = os.path.join(base_dir, 'validation')
 72 os.mkdir(validation_dir)
 73 test_dir = os.path.join(base_dir, 'test')
 74 os.mkdir(test_dir)
 75 
 76 train_smiles_dir = os.path.join(train_dir, 'smile')
 77 os.mkdir(train_smiles_dir)
 78 
 79 train_unsmiles_dir = os.path.join(train_dir, 'unsmile')
 80 os.mkdir(train_unsmiles_dir)
 81 
 82 validation_smiles_dir = os.path.join(validation_dir, 'smile')
 83 os.mkdir(validation_smiles_dir)
 84 
 85 validation_unsmiles_dir = os.path.join(validation_dir, 'unsmile')
 86 os.mkdir(validation_unsmiles_dir)
 87 
 88 test_smiles_dir = os.path.join(test_dir, 'smile')
 89 os.mkdir(test_smiles_dir)
 90 
 91 test_unsmiles_dir = os.path.join(test_dir, 'unsmile')
 92 os.mkdir(test_unsmiles_dir)
 93 
 94 # 复制900张笑脸图片到train_smiles_dir
 95 fnames = ['file{}.jpg'.format(i) for i in range(1, 900)]
 96 for fname in fnames:
 97     src = os.path.join(original_dataset_dir, fname)
 98     dst = os.path.join(train_smiles_dir, fname)
 99     shutil.copyfile(src, dst)
100 # 复制450张笑脸图片到validation_smiles_dir
101 fnames = ['file{}.jpg'.format(i) for i in range(900, 1350)]
102 for fname in fnames:
103     src = os.path.join(original_dataset_dir, fname)
104     dst = os.path.join(validation_smiles_dir, fname)
105     shutil.copyfile(src, dst)
106 
107 # 复制450张笑脸图片到test_smiles_dir
108 fnames = ['file{}.jpg'.format(i) for i in range(1350, 1800)]
109 for fname in fnames:
110     src = os.path.join(original_dataset_dir, fname)
111     dst = os.path.join(test_smiles_dir, fname)
112     shutil.copyfile(src, dst)
113 
114 # 复制873张笑脸图片到train_unsmiles_dir
115 fnames = ['file{}.jpg'.format(i) for i in range(2127, 3000)]
116 for fname in fnames:
117     src = os.path.join(original_dataset_dir, fname)
118     dst = os.path.join(train_unsmiles_dir, fname)
119     shutil.copyfile(src, dst)
120 
121 # 复制878张笑脸图片到validation_unsmiles_dir
122 fnames = ['file{}.jpg'.format(i) for i in range(3000, 3878)]
123 for fname in fnames:
124     src = os.path.join(original_dataset_dir, fname)
125     dst = os.path.join(validation_unsmiles_dir, fname)
126     shutil.copyfile(src, dst)
127 
128 # 复制878张笑脸图片到test_unsmiles_dir
129 fnames = ['file{}.jpg'.format(i) for i in range(3000, 3878)]
130 for fname in fnames:
131     src = os.path.join(original_dataset_dir, fname)
132     dst = os.path.join(test_unsmiles_dir, fname)
133     shutil.copyfile(src, dst)
134 
135 print('total training smile images:', len(os.listdir(train_smiles_dir)))
136 print('total training unsmile images:', len(os.listdir(train_unsmiles_dir)))
137 print('total testing smile images:', len(os.listdir(test_smiles_dir)))
138 print('total testing unsmile images:', len(os.listdir(test_unsmiles_dir)))
139 print('total validation smile images:', len(os.listdir(validation_smiles_dir)))
140 print('total validation unsmile images:', len(os.listdir(validation_unsmiles_dir)))
141 
142 
143 #创建模型
144 model = models.Sequential()
145 #第一个卷积层作为输入层,32个3*3卷积核
146 #输出尺寸:150-3+1=148*148,参数数量:32*3*3*3+32=896
147 model.add(layers.Conv2D(32, (3, 3), activation='relu',input_shape=(150, 150, 3)))
148 model.add(layers.MaxPooling2D((2, 2)))
149 #输出尺寸:74-3+1=72*72,对应数量:64*3*3*32+64=18496
150 model.add(layers.Conv2D(64, (3, 3), activation='relu'))
151 model.add(layers.MaxPooling2D((2, 2)))
152 #输出尺寸:36-3+1=34*34,对应数量:128*3*3*64+128=73856
153 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
154 model.add(layers.MaxPooling2D((2, 2)))
155 #输出尺寸:17-3+1=15*15,对应数量:128*3*3*128+128=147584
156 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
157 model.add(layers.MaxPooling2D((2, 2)))
158 model.add(layers.Flatten())
159 model.add(layers.Dense(512, activation='relu'))
160 model.add(layers.Dense(1, activation='sigmoid'))
161 model.summary()#查看标量信息
162 
163 
164 #统一
165 model.compile(loss='binary_crossentropy',
166               optimizer=optimizers.RMSprop(lr=1e-4),
167               metrics=['acc'])
168 train_datagen = ImageDataGenerator(rescale=1./255)
169 validation_datagen=ImageDataGenerator(rescale=1./255)
170 test_datagen = ImageDataGenerator(rescale=1./255)
171 train_generator = train_datagen.flow_from_directory(
172         # 目标文件目录
173         train_dir,
174         #所有图片的size必须是150x150
175         target_size=(150, 150),
176         batch_size=20,
177         class_mode='binary')
178 validation_generator = test_datagen.flow_from_directory(
179         validation_dir,
180         target_size=(150, 150),
181         batch_size=20,
182         class_mode='binary')
183 test_generator = test_datagen.flow_from_directory(test_dir,
184                                                    target_size=(150, 150),
185                                                    batch_size=20,
186                                                    class_mode='binary')
187 for data_batch, labels_batch in train_generator:
188     print('data batch shape:', data_batch.shape)
189     print('labels batch shape:', labels_batch)
190     break
191 # '微笑': 0, '非微笑': 1
192 
193 #数据增强
194 datagen = ImageDataGenerator(
195       rotation_range=40,
196       width_shift_range=0.2,
197       height_shift_range=0.2,
198       shear_range=0.2,
199       zoom_range=0.2,
200       horizontal_flip=True,
201       fill_mode='nearest')
202 #数据增强后图片变化
203 import matplotlib.pyplot as plt
204 # from keras.preprocessing import image
205 from keras.utils import image_utils
206 train_smile_dir='E:\\smiletest\\files2\\train\\smile'
207 fnames = [os.path.join(train_smile_dir, fname) for fname in os.listdir(train_smile_dir)]
208 img_path = fnames[22]
209 img = image_utils.load_img(img_path, target_size=(150, 150))
210 x = image_utils.img_to_array(img)
211 x = x.reshape((1,) + x.shape)
212 i = 0
213 for batch in datagen.flow(x, batch_size=1):
214     plt.figure(i)
215     imgplot = plt.imshow(image_utils.array_to_img(batch[0]))
216     i += 1
217     if i % 4 == 0:
218         break
219 plt.show()
220 
221 
222 #创建模型
223 from keras import layers
224 from keras import models
225 from keras import optimizers
226 import matplotlib.pyplot as plt
227 #创建网络
228 from keras.preprocessing.image import ImageDataGenerator
229 
230 model = models.Sequential()
231 model.add(layers.Conv2D(32, (3, 3), activation='relu',input_shape=(150, 150, 3)))
232 model.add(layers.MaxPooling2D((2, 2)))
233 model.add(layers.Conv2D(64, (3, 3), activation='relu'))
234 model.add(layers.MaxPooling2D((2, 2)))
235 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
236 model.add(layers.MaxPooling2D((2, 2)))
237 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
238 model.add(layers.MaxPooling2D((2, 2)))
239 model.add(layers.Flatten())
240 model.add(layers.Dropout(0.5))
241 model.add(layers.Dense(512, activation='relu'))
242 model.add(layers.Dense(1, activation='sigmoid'))
243 model.compile(loss='binary_crossentropy',
244               optimizer=optimizers.RMSprop(lr=1e-4),
245               metrics=['acc'])
246 
247 #统一化处理
248 train_datagen = ImageDataGenerator(
249     rescale=1./255,
250     rotation_range=40,
251     width_shift_range=0.2,
252     height_shift_range=0.2,
253     shear_range=0.2,
254     zoom_range=0.2,
255     horizontal_flip=True,)
256 
257 test_datagen = ImageDataGenerator(rescale=1./255)
258 train_dir = 'E:\\smiletest\\files2\\train'
259 validation_dir='E:\\smiletest\\files2\\validation'
260 train_generator = train_datagen.flow_from_directory(
261         
262         train_dir,
263         #转化为150*150像素
264         target_size=(150, 150),
265         batch_size=32,
266         #二进制标签
267         class_mode='binary')
268 
269 validation_generator = test_datagen.flow_from_directory(
270         validation_dir,
271         target_size=(150, 150),
272         batch_size=32,
273         class_mode='binary')
274 
275 history = model.fit_generator(
276       train_generator,
277       steps_per_epoch=55,
278       epochs=60,
279       validation_data=validation_generator,
280       validation_steps=27)
281 model.save('E:\\smiletest\\smileAndunsmile1.h5')
282 
283 #数据增强过后的训练集与验证集的精确度与损失度的图形
284 acc = history.history['acc']
285 val_acc = history.history['val_acc']
286 loss = history.history['loss']
287 val_loss = history.history['val_loss']
288 
289 epochs = range(len(acc))
290 # 输出准确度折线图与散点图
291 plt.plot(epochs, acc, 'bo', label='Training acc')
292 plt.plot(epochs, val_acc, 'b', label='Validation acc')
293 plt.title('Training and validation accuracy')
294 plt.legend()
295 plt.figure()
296 # 输出损失度折线图与散点图
297 plt.plot(epochs, loss, 'bo', label='Training loss')
298 plt.plot(epochs, val_loss, 'b', label='Validation loss')
299 plt.title('Training and validation loss')
300 plt.legend()
301 plt.show()
302 
303 
304 
305 # 单张图片进行判断是笑脸还是非笑脸
306 # from keras.preprocessing import image
307 from keras.utils import image_utils
308 from keras.models import load_model
309 import numpy as np
310 # 加载模型
311 model = load_model('E:\\smiletest\\smileAndunsmile1.h5')
312 # 本地图片路径
313 img_path = 'E:\\smiletest\\testimg\\5.jpeg'
314 img = image_utils.load_img(img_path, target_size=(150, 150))
315 
316 img_tensor = image_utils.img_to_array(img) / 255.0
317 img_tensor = np.expand_dims(img_tensor, axis=0)
318 prediction = model.predict(img_tensor)
319 prediction1=str((1-prediction)*100).strip('[]')
320 # (1-prediction1)*100
321 print('笑脸的概率:',prediction1,'%')
322 if prediction[0][0] > 0.5:
323     result = '非笑脸'
324 else:
325     result = '笑脸'
326 print('测试结果:',result)
复制代码

 

posted @   starbao  阅读(784)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示