(一)选题背景:
秋冬季本就是流感的高发期,叠加近年来势汹汹的肺炎病毒疫情。个人防护工作显得更加重要。流感多数以人体唾沫传播。此时口罩就起到了非常重要的作用,可以在源头进行阻隔病毒的传统。是最有效也是最直接的防疫手段。人们在疫情期间,带上口罩,无论是对自己还是他人,都是负责任的态度。但是部分市民不适应口罩,仍然我行我素。本程序基于以上现象,可以通过图像的采集即可判别是否穿戴口罩,从而提出预警,起到威慑提醒作用,那么可以非常有效地引导,督促市民正常穿戴口罩出门。从而为共同防疫做贡献。
(二)机器学习设计案例设计方案:
从数据网站中下载相关的数据集,对数据集进行整理,在python的环境中,统计数据集中的文件个数,对数据进行预处理,利用keras,构建网络,训练模型,导入图片测试模型
参考来源:kaggle关于标签学习的讨论区
数据集来源:kaggle,网址:https://www.kaggle.com/
(三)机器学习的实现步骤:
1.下载数据集,并保存于本地目标路径
2、显示数据集个数,
#检查一下每个文件夹(训练文件夹 / 测试文件夹/ 验证文件夹)中分别有多少张图像 import os train_path="D:/Zero/FaceMaskDataset/Train/" #戴口罩 print('Train-WithMask-images:', len(os.listdir(train_path+"WithMask"))) #不戴口罩 print('Train-WithoutMask-images:', len(os.listdir(train_path+"WithoutMask"))) valid_path="D:/Zero/FaceMaskDataset/Validation/" print('Validation-WithMask-images:', len(os.listdir(valid_path+"WithMask"))) print('Validation-WithoutMask-images:', len(os.listdir(valid_path+"WithoutMask"))) valid_path="D:/Zero/FaceMaskDataset/Test/" print('Test-WithMask-images:', len(os.listdir(valid_path+"WithMask"))) print('Test-WithoutMask-images:', len(os.listdir(valid_path+"WithoutMask")))
3.搭建卷积神经网络模型
#搭建网络 from keras import layers from keras import models model = models.Sequential() #第一个卷积层作为输入层,32个3*3卷积核,输入形状input_shape = (300,300,3) model.add(layers.Conv2D(32,(3,3),activation = 'relu',input_shape = (300,300,3))) model.add(layers.MaxPooling2D((2,2))) model.add(layers.Conv2D(64,(3,3),activation = 'relu')) model.add(layers.MaxPooling2D((2,2))) # 输出图片尺寸 model.add(layers.Conv2D(128,(3,3),activation = 'relu')) model.add(layers.MaxPooling2D((2,2))) model.add(layers.Conv2D(128,(3,3),activation = 'relu')) model.add(layers.MaxPooling2D((2,2))) model.add(layers.Flatten()) model.add(layers.Dense(512,activation = 'relu')) model.add(layers.Dense(1,activation = 'sigmoid')) #sigmoid分类,输出是、否两类别
4.对图像进行预处理
#搭建网络 from keras import layers from keras import models model = models.Sequential() #第一个卷积层作为输入层,32个3*3卷积核,输入形状input_shape = (300,300,3) model.add(layers.Conv2D(32,(3,3),activation = 'relu',input_shape = (300,300,3))) model.add(layers.MaxPooling2D((2,2))) model.add(layers.Conv2D(64,(3,3),activation = 'relu')) model.add(layers.MaxPooling2D((2,2))) # 输出图片尺寸 model.add(layers.Conv2D(128,(3,3),activation = 'relu')) model.add(layers.MaxPooling2D((2,2))) model.add(layers.Conv2D(128,(3,3),activation = 'relu')) model.add(layers.MaxPooling2D((2,2))) model.add(layers.Flatten()) model.add(layers.Dense(512,activation = 'relu')) model.add(layers.Dense(1,activation = 'sigmoid')) #sigmoid分类,输出是两类别 # 编译模型 # RMSprop 优化器。因为网络最后一层是单一sigmoid单元, # 所以使用二元交叉熵作为损失函数 from keras import optimizers model.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(learning_rate=1e-4), metrics=['acc']) #图像在输入神经网络之前进行数据处理,建立训练和验证数据 from keras.preprocessing.image import ImageDataGenerator #归一化 train_datagen = ImageDataGenerator(rescale = 1./255) test_datagen = ImageDataGenerator(rescale = 1./255) train_dir = 'D:/Zero/FaceMaskDataset/Train/' #指向训练集图片目录路径 train_generator = train_datagen.flow_from_directory( train_dir, target_size = (300,300),# 输入训练图像尺寸 batch_size = 20, class_mode = 'binary') # validation_dir = 'D:/Zero/FaceMaskDataset/Validation/' #指向验证集图片目录路径 validation_generator = test_datagen.flow_from_directory( validation_dir, target_size = (300,300), batch_size = 20, class_mode = 'binary')
5.对模型进行训练
#训练模型20轮次 history = model.fit( train_generator, steps_per_epoch = 500, epochs = 20 , #训练轮次 validation_data = validation_generator, validation_steps=40)
6.数据保存为h5文件
#将训练过程产生的数据保存为h5文件 from keras.models import load_model model.save('WithMask_20epoch.h5')
7.绘制损失曲线和精度曲线图
# 分别绘制训练过程中模型在训练数据和验证数据上的损失和精度 import matplotlib.pyplot as plt loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(1, len(loss) + 1) plt.plot(epochs, loss, 'bo', label = 'Training loss') plt.plot(epochs, val_loss, 'b', label = 'Validation loss') plt.title('Training And Validation Loss') plt.xlabel('Epochs') plt.ylabel('Loss') plt.legend() plt.show() plt.clf() acc = history.history['acc'] val_acc = history.history['val_acc'] plt.plot(epochs, acc, 'bo', label = 'Training acc') plt.plot(epochs, val_acc, 'b', label = 'Validation acc') plt.title('Training And Validation Accuracy') plt.xlabel('Epochs') plt.ylabel('Accuracy') plt.legend() plt.show()
8.从测试集中读取一条样本并显示
#从测试集中读取一条样本 img_path = "D:/Zero/FaceMaskDataset/Test/WithMask/46.png" from keras.utils import image_utils import numpy as np img = image_utils.load_img(img_path, target_size=(300,300)) img_tensor = image_utils.img_to_array(img) img_tensor = np.expand_dims(img_tensor, axis=0) img_tensor /= 255. print(img_tensor.shape) #显示样本 import matplotlib.pyplot as plt plt.imshow(img_tensor[0]) plt.show()
9.建立模型,输入为原图像,输出为原模型的前8层的激活输出的特征图
#建立模型,输入为原图像,输出为原模型的前8层的激活输出的特征图 from keras import models layer_outputs = [layer.output for layer in model.layers[:8]] activation_model = models.Model(inputs=model.input, outputs=layer_outputs) #获得改样本的特征图 activations = activation_model.predict(img_tensor)
10.显示前4层激活输出的全部特征图
#存储层的名称 layer_names = [] for layer in model.layers[:4]: layer_names.append(layer.name) # 每行显示16个特征图 images_pre_row = 16 #每行显示的特征图数 # 循环8次显示8层的全部特征图 for layer_name, layer_activation in zip(layer_names, activations): n_features = layer_activation.shape[-1] #保存当前层的特征图个数 size = layer_activation.shape[1] #保存当前层特征图的宽高 n_col = n_features // images_pre_row #计算当前层显示多少行 #生成显示图像的矩阵 display_grid = np.zeros((size*n_col, images_pre_row*size)) #遍历将每个特张图的数据写入到显示图像的矩阵中 for col in range(n_col): for row in range(images_pre_row): #保存该张特征图的矩阵(size,size,1) channel_image = layer_activation[0,:,:,col*images_pre_row+row] #为使图像显示更鲜明,作一些特征处理 channel_image -= channel_image.mean() channel_image /= channel_image.std() channel_image *= 64 channel_image += 128 #把该特征图矩阵中不在0-255的元素值修改至0-255 channel_image = np.clip(channel_image, 0, 255).astype("uint8") #该特征图矩阵填充至显示图像的矩阵中 display_grid[col*size:(col+1)*size, row*size:(row+1)*size] = channel_image scale = 1./size #设置该层显示图像的宽高 plt.figure(figsize=(scale*display_grid.shape[1],scale*display_grid.shape[0])) plt.title(layer_name) plt.grid(False) #显示图像 plt.imshow(display_grid, aspect="auto", cmap="viridis")
11.导入图片进行判断是否佩戴口罩
#读取用户自定义图像文件,改尺寸后保存 import matplotlib.pyplot as plt from PIL import Image import os.path def convertjpg(jpgfile,outdir,width=300,height=300):#将图片缩小到(300,300)的大小 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) jpgfile = 'D:/Zero/FaceMaskDataset/Test/WithMask/46.png'#读取原图像 convertjpg(jpgfile,"D:/Zero/FaceMaskDataset/Test/")#图像大小改变到(300,300) img_scale = plt.imread('D:/Zero/FaceMaskDataset/Test/46.png') plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(300,300)大小 from keras.models import load_model model = load_model('WithMask_20epoch.h5') img_scale = img_scale.reshape(1,300,300,3).astype('float32') img_scale = img_scale/255 #归一化到0-1之间 result = model.predict(img_scale) #取图片信息 # print(result) if result>0.5: print('该图片是没戴口罩的概率为:',result) else: print('该图片是带口罩的概率为:',1-result)
#读取用户自定义图像文件,改尺寸后保存 import matplotlib.pyplot as plt from PIL import Image import os.path def convertjpg(jpgfile,outdir,width=300,height=300):#将图片缩小到(300,300)的大小 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) jpgfile = 'D:/Zero/FaceMaskDataset/Test/WithoutMask/84.png'#读取原图像(有机) convertjpg(jpgfile,"D:/Zero/FaceMaskDataset/Test/")#图像大小改变到(300,300) img_scale = plt.imread('D:/Zero/FaceMaskDataset/Test/84.png') plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(300,300)大小 from keras.models import load_model model = load_model('WithMask_20epoch.h5') img_scale = img_scale.reshape(1,300,300,3).astype('float32') img_scale = img_scale/255 #归一化到0-1之间 result = model.predict(img_scale) #取图片信息 # print(result) if result>0.5: print('该图片是没戴口罩的概率为:',result) else: print('该图片是带口罩的概率为:',1-result)
12.使用测试集数据对模型进行验证
# 用测试集对模型进行测试 test_datagen = ImageDataGenerator(rescale = 1./255) test_dir='D:/Zero/FaceMaskDataset/Test/' test_generator = test_datagen.flow_from_directory( test_dir, target_size=(300, 300), batch_size=20, class_mode='binary') test_loss, test_acc = model.evaluate_generator(test_generator, steps=test_generator.samples // 20) print('test acc:', test_acc)
13.尝试其他训练次数,验证获得结果的正确性
#训练模型50轮次 history = model.fit( train_generator, steps_per_epoch = 500, epochs = 50 , #训练轮次 validation_data = validation_generator, validation_steps=40)
14.将验证过程产生的数据保存为h5文件
#将验证过程产生的数据保存为h5文件 from keras.models import load_model model.save('WithMask_50epoch.h5')
15.绘制验测试过程中的损失曲线和精度曲线图
# 分别绘制验证过程中模型在训练数据和验证数据上的损失和精度 import matplotlib.pyplot as plt loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(1, len(loss) + 1) plt.plot(epochs, loss, 'bo', label = 'Training loss') plt.plot(epochs, val_loss, 'b', label = 'Validation loss') plt.title('Training And Validation Loss') plt.xlabel('Epochs') plt.ylabel('Loss') plt.legend() plt.show() plt.clf() acc = history.history['acc'] val_acc = history.history['val_acc'] plt.plot(epochs, acc, 'bo', label = 'Training acc') plt.plot(epochs, val_acc, 'b', label = 'Validation acc') plt.title('Training And Validation Accuracy') plt.xlabel('Epochs') plt.ylabel('Accuracy') plt.legend() plt.show()
16.导入图片进行判断是否佩戴口罩,验证之前所得结果的正确性
#读取用户自定义图像文件,改尺寸后保存 import matplotlib.pyplot as plt from PIL import Image import os.path def convertjpg(jpgfile,outdir,width=300,height=300):#将图片缩小到(300,300)的大小 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) jpgfile = 'D:/Zero/FaceMaskDataset/Test/WithMask/46.png'#读取原图像 convertjpg(jpgfile,"D:/Zero/FaceMaskDataset/Test/")#图像大小改变到(300,300) img_scale = plt.imread('D:/Zero/FaceMaskDataset/Test/46.png') plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(300,300)大小 from keras.models import load_model model = load_model('WithMask_20epoch.h5') img_scale = img_scale.reshape(1,300,300,3).astype('float32') img_scale = img_scale/255 #归一化到0-1之间 result = model.predict(img_scale) #取图片信息 # print(result) if result>0.5: print('该图片是没戴口罩的概率为:',result) else: print('该图片是带口罩的概率为:',1-result)
#读取用户自定义图像文件,改尺寸后保存 import matplotlib.pyplot as plt from PIL import Image import os.path def convertjpg(jpgfile,outdir,width=300,height=300):#将图片缩小到(300,300)的大小 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) jpgfile = 'D:/Zero/FaceMaskDataset/Test/WithoutMask/84.png'#读取原图像(有机) convertjpg(jpgfile,"D:/Zero/FaceMaskDataset/Test/")#图像大小改变到(300,300) img_scale = plt.imread('D:/Zero/FaceMaskDataset/Test/84.png') plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(300,300)大小 from keras.models import load_model model = load_model('WithMask_20epoch.h5') img_scale = img_scale.reshape(1,300,300,3).astype('float32') img_scale = img_scale/255 #归一化到0-1之间 result = model.predict(img_scale) #取图片信息 # print(result) if result>0.5: print('该图片是没戴口罩的概率为:',result) else: print('该图片是带口罩的概率为:',1-result)
17.用测试集对模型进行测试,验证模型精度
# 用测试集对模型进行测试 test_datagen = ImageDataGenerator(rescale = 1./255) test_dir='D:/Zero/FaceMaskDataset/Test/' test_generator = test_datagen.flow_from_directory( test_dir, target_size=(300, 300), batch_size=20, class_mode='binary') test_loss, test_acc = model.evaluate_generator(test_generator, steps=test_generator.samples // 20) print('test acc:', test_acc)
完整代码:
1 #检查一下每个文件夹(训练文件夹 / 测试文件夹/ 验证文件夹)中分别有多少张图像
2
3
4 import os
5 train_path="D:/Zero/FaceMaskDataset/Train/"
6 #戴口罩
7 print('Train-WithMask-images:', len(os.listdir(train_path+"WithMask")))
8 #不戴口罩
9 print('Train-WithoutMask-images:', len(os.listdir(train_path+"WithoutMask")))
10 valid_path="D:/Zero/FaceMaskDataset/Validation/"
11 print('Validation-WithMask-images:', len(os.listdir(valid_path+"WithMask")))
12 print('Validation-WithoutMask-images:', len(os.listdir(valid_path+"WithoutMask")))
13 valid_path="D:/Zero/FaceMaskDataset/Test/"
14 print('Test-WithMask-images:', len(os.listdir(valid_path+"WithMask")))
15 print('Test-WithoutMask-images:', len(os.listdir(valid_path+"WithoutMask")))
16
17 #搭建网络
18 from keras import layers
19 from keras import models
20 model = models.Sequential()
21 #第一个卷积层作为输入层,32个3*3卷积核,输入形状input_shape = (300,300,3)
22 model.add(layers.Conv2D(32,(3,3),activation = 'relu',input_shape = (300,300,3)))
23 model.add(layers.MaxPooling2D((2,2)))
24 model.add(layers.Conv2D(64,(3,3),activation = 'relu'))
25 model.add(layers.MaxPooling2D((2,2)))
26 # 输出图片尺寸
27 model.add(layers.Conv2D(128,(3,3),activation = 'relu'))
28 model.add(layers.MaxPooling2D((2,2)))
29 model.add(layers.Conv2D(128,(3,3),activation = 'relu'))
30 model.add(layers.MaxPooling2D((2,2)))
31 model.add(layers.Flatten())
32
33 model.add(layers.Dense(512,activation = 'relu'))
34 model.add(layers.Dense(1,activation = 'sigmoid'))
35 #sigmoid分类,输出是、否两类别
36
37 #看一下特征图的维度如何随着每层变化
38 model.summary()
39
40
41 # 编译模型
42 # RMSprop 优化器。因为网络最后一层是单一sigmoid单元,
43 # 所以使用二元交叉熵作为损失函数
44 from keras import optimizers
45 model.compile(loss='binary_crossentropy',
46
47 optimizer=optimizers.RMSprop(learning_rate=1e-4),
48 metrics=['acc'])
49
50 #图像在输入神经网络之前进行数据处理,建立训练和验证数据
51 from keras.preprocessing.image import ImageDataGenerator
52 #归一化
53 train_datagen = ImageDataGenerator(rescale = 1./255)
54 test_datagen = ImageDataGenerator(rescale = 1./255)
55 train_dir = 'D:/Zero/FaceMaskDataset/Train/' #指向训练集图片目录路径
56 train_generator = train_datagen.flow_from_directory(
57 train_dir,
58 target_size = (300,300),# 输入训练图像尺寸
59 batch_size = 20,
60 class_mode = 'binary') #
61 validation_dir = 'D:/Zero/FaceMaskDataset/Validation/' #指向验证集图片目录路径
62 validation_generator = test_datagen.flow_from_directory(
63 validation_dir,
64 target_size = (300,300),
65 batch_size = 20,
66 class_mode = 'binary')
67
68
69 #训练模型20轮次
70 history = model.fit(
71 train_generator,
72 steps_per_epoch = 500,
73 epochs = 20 , #训练轮次
74 validation_data = validation_generator,
75 validation_steps=40)
76 #将训练过程产生的数据保存为h5文件
77
78 from keras.models import load_model
79 model.save('WithMask_20epoch.h5')
80
81 # 分别绘制训练过程中模型在训练数据和验证数据上的损失和精度
82 import matplotlib.pyplot as plt
83 loss = history.history['loss']
84 val_loss = history.history['val_loss']
85 epochs = range(1, len(loss) + 1)
86 plt.plot(epochs, loss, 'bo', label = 'Training loss')
87 plt.plot(epochs, val_loss, 'b', label = 'Validation loss')
88 plt.title('Training And Validation Loss')
89 plt.xlabel('Epochs')
90 plt.ylabel('Loss')
91 plt.legend()
92 plt.show()
93
94 plt.clf()
95
96 acc = history.history['acc']
97 val_acc = history.history['val_acc']
98
99 plt.plot(epochs, acc, 'bo', label = 'Training acc')
100 plt.plot(epochs, val_acc, 'b', label = 'Validation acc')
101 plt.title('Training And Validation Accuracy')
102 plt.xlabel('Epochs')
103 plt.ylabel('Accuracy')
104 plt.legend()
105 plt.show()
106
107 #从测试集中读取一条样本
108 img_path = "D:/Zero/FaceMaskDataset/Test/WithMask/46.png"
109 from keras.utils import image_utils
110 import numpy as np
111 img = image_utils.load_img(img_path, target_size=(300,300))
112 img_tensor = image_utils.img_to_array(img)
113 img_tensor = np.expand_dims(img_tensor, axis=0)
114 img_tensor /= 255.
115 print(img_tensor.shape)
116
117 #显示样本
118 import matplotlib.pyplot as plt
119 plt.imshow(img_tensor[0])
120 plt.show()
121
122 #建立模型,输入为原图像,输出为原模型的前8层的激活输出的特征图
123 from keras import models
124
125 layer_outputs = [layer.output for layer in model.layers[:8]]
126 activation_model = models.Model(inputs=model.input, outputs=layer_outputs)
127 #获得改样本的特征图
128 activations = activation_model.predict(img_tensor)
129
130
131
132 #显示前4层激活输出的全部特征图
133 #存储层的名称
134 layer_names = []
135 for layer in model.layers[:4]:
136 layer_names.append(layer.name)
137 # 每行显示16个特征图
138 images_pre_row = 16 #每行显示的特征图数
139 # 循环8次显示8层的全部特征图
140 for layer_name, layer_activation in zip(layer_names, activations):
141 n_features = layer_activation.shape[-1] #保存当前层的特征图个数
142 size = layer_activation.shape[1] #保存当前层特征图的宽高
143 n_col = n_features // images_pre_row #计算当前层显示多少行
144 #生成显示图像的矩阵
145 display_grid = np.zeros((size*n_col, images_pre_row*size))
146 #遍历将每个特张图的数据写入到显示图像的矩阵中
147 for col in range(n_col):
148 for row in range(images_pre_row):
149 #保存该张特征图的矩阵(size,size,1)
150 channel_image = layer_activation[0,:,:,col*images_pre_row+row]
151 #为使图像显示更鲜明,作一些特征处理
152 channel_image -= channel_image.mean()
153 channel_image /= channel_image.std()
154 channel_image *= 64
155 channel_image += 128
156 #把该特征图矩阵中不在0-255的元素值修改至0-255
157 channel_image = np.clip(channel_image, 0, 255).astype("uint8")
158 #该特征图矩阵填充至显示图像的矩阵中
159 display_grid[col*size:(col+1)*size, row*size:(row+1)*size] = channel_image
160
161
162 scale = 1./size
163 #设置该层显示图像的宽高
164 plt.figure(figsize=(scale*display_grid.shape[1],scale*display_grid.shape[0]))
165 plt.title(layer_name)
166 plt.grid(False)
167 #显示图像
168 plt.imshow(display_grid, aspect="auto", cmap="viridis")
169
170 #导入图片进行判断是否佩戴口罩
171 #读取用户自定义图像文件,改尺寸后保存
172 import matplotlib.pyplot as plt
173 from PIL import Image
174 import os.path
175 def convertjpg(jpgfile,outdir,width=300,height=300):#将图片缩小到(300,300)的大小
176 img=Image.open(jpgfile)
177 try:
178 new_img=img.resize((width,height),Image.BILINEAR)
179 new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
180 except Exception as e:
181 print(e)
182 jpgfile = 'D:/Zero/FaceMaskDataset/Test/WithMask/46.png'#读取原图像
183 convertjpg(jpgfile,"D:/Zero/FaceMaskDataset/Test/")#图像大小改变到(300,300)
184 img_scale = plt.imread('D:/Zero/FaceMaskDataset/Test/46.png')
185 plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(300,300)大小
186 from keras.models import load_model
187 model = load_model('WithMask_20epoch.h5')
188 img_scale = img_scale.reshape(1,300,300,3).astype('float32')
189 img_scale = img_scale/255 #归一化到0-1之间
190 result = model.predict(img_scale) #取图片信息
191 # print(result)
192 if result>0.5:
193 print('该图片是没戴口罩的概率为:',result)
194 else:
195 print('该图片是带口罩的概率为:',1-result)
196
197
198 #读取用户自定义图像文件,改尺寸后保存
199 import matplotlib.pyplot as plt
200 from PIL import Image
201 import os.path
202 def convertjpg(jpgfile,outdir,width=300,height=300):#将图片缩小到(300,300)的大小
203 img=Image.open(jpgfile)
204 try:
205 new_img=img.resize((width,height),Image.BILINEAR)
206 new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
207 except Exception as e:
208 print(e)
209 jpgfile = 'D:/Zero/FaceMaskDataset/Test/WithoutMask/84.png'#读取原图像
210 convertjpg(jpgfile,"D:/Zero/FaceMaskDataset/Test/")#图像大小改变到(300,300)
211 img_scale = plt.imread('D:/Zero/FaceMaskDataset/Test/84.png')
212 plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(300,300)大小
213 from keras.models import load_model
214 model = load_model('WithMask_20epoch.h5')
215 img_scale = img_scale.reshape(1,300,300,3).astype('float32')
216 img_scale = img_scale/255 #归一化到0-1之间
217 result = model.predict(img_scale) #取图片信息
218 # print(result)
219 if result>0.5:
220 print('该图片是没戴口罩的概率为:',result)
221 else:
222
223 print('该图片是带口罩的概率为:',1-result)
224
225
226 #使用测试集数据对模型进行验证
227 # 用测试集对模型进行测试
228 test_datagen = ImageDataGenerator(rescale = 1./255)
229 test_dir='D:/Zero/FaceMaskDataset/Test/'
230 test_generator = test_datagen.flow_from_directory(
231 test_dir,
232 target_size=(300, 300),
233 batch_size=20,
234 class_mode='binary')
235
236 test_loss, test_acc = model.evaluate_generator(test_generator, steps=test_generator.samples // 20)
237 print('test acc:', test_acc)
238
239
240 #尝试其他训练次数,验证获得结果的正确性
241 #训练模型50轮次
242 history = model.fit(
243 train_generator,
244 steps_per_epoch = 500,
245 epochs = 50 , #训练轮次
246 validation_data = validation_generator,
247 validation_steps=40)
248
249
250 #将验证过程产生的数据保存为h5文件
251
252 from keras.models import load_model
253 model.save('WithMask_50epoch.h5')
254
255 #绘制验测试过程中的损失曲线和精度曲线图
256 # 分别绘制验证过程中模型在训练数据和验证数据上的损失和精度
257
258
259 import matplotlib.pyplot as plt
260 loss = history.history['loss']
261 val_loss = history.history['val_loss']
262 epochs = range(1, len(loss) + 1)
263 plt.plot(epochs, loss, 'bo', label = 'Training loss')
264 plt.plot(epochs, val_loss, 'b', label = 'Validation loss')
265 plt.title('Training And Validation Loss')
266 plt.xlabel('Epochs')
267 plt.ylabel('Loss')
268 plt.legend()
269 plt.show()
270
271 plt.clf()
272
273 acc = history.history['acc']
274 val_acc = history.history['val_acc']
275
276 plt.plot(epochs, acc, 'bo', label = 'Training acc')
277 plt.plot(epochs, val_acc, 'b', label = 'Validation acc')
278 plt.title('Training And Validation Accuracy')
279 plt.xlabel('Epochs')
280 plt.ylabel('Accuracy')
281 plt.legend()
282 plt.show()
283
284 #导入图片进行判断是否佩戴口罩,验证之前所得结果的正确性
285 #以下是验证图1
286 #读取用户自定义图像文件,改尺寸后保存
287 import matplotlib.pyplot as plt
288 from PIL import Image
289 import os.path
290 def convertjpg(jpgfile,outdir,width=300,height=300):#将图片缩小到(300,300)的大小
291 img=Image.open(jpgfile)
292 try:
293 new_img=img.resize((width,height),Image.BILINEAR)
294 new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
295 except Exception as e:
296 print(e)
297 jpgfile = 'D:/Zero/FaceMaskDataset/Test/WithMask/46.png'#读取原图像
298 convertjpg(jpgfile,"D:/Zero/FaceMaskDataset/Test/")#图像大小改变到(300,300)
299 img_scale = plt.imread('D:/Zero/FaceMaskDataset/Test/46.png')
300 plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(300,300)大小
301 from keras.models import load_model
302 model = load_model('WithMask_20epoch.h5')
303 img_scale = img_scale.reshape(1,300,300,3).astype('float32')
304 img_scale = img_scale/255 #归一化到0-1之间
305 result = model.predict(img_scale) #取图片信息
306 # print(result)
307 if result>0.5:
308 print('该图片是没戴口罩的概率为:',result)
309 else:
310 print('该图片是带口罩的概率为:',1-result)
311
312 #以下是验证图2
313 #读取用户自定义图像文件,改尺寸后保存
314 import matplotlib.pyplot as plt
315 from PIL import Image
316 import os.path
317 def convertjpg(jpgfile,outdir,width=300,height=300):#将图片缩小到(300,300)的大小
318 img=Image.open(jpgfile)
319 try:
320 new_img=img.resize((width,height),Image.BILINEAR)
321 new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
322 except Exception as e:
323 print(e)
324 jpgfile = 'D:/Zero/FaceMaskDataset/Test/WithoutMask/84.png'#读取原图像
325 convertjpg(jpgfile,"D:/Zero/FaceMaskDataset/Test/")#图像大小改变到(300,300)
326 img_scale = plt.imread('D:/Zero/FaceMaskDataset/Test/84.png')
327 plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(300,300)大小
328 from keras.models import load_model
329 model = load_model('WithMask_20epoch.h5')
330 img_scale = img_scale.reshape(1,300,300,3).astype('float32')
331 img_scale = img_scale/255 #归一化到0-1之间
332 result = model.predict(img_scale) #取图片信息
333 # print(result)
334 if result>0.5:
335 print('该图片是没戴口罩的概率为:',result)
336 else:
337 print('该图片是带口罩的概率为:',1-result)
338
339
340 #用测试集对模型进行测试,验证模型精度
341 # 用测试集对模型进行测试
342 test_datagen = ImageDataGenerator(rescale = 1./255)
343 test_dir='D:/Zero/FaceMaskDataset/Test/'
344 test_generator = test_datagen.flow_from_directory(
345 test_dir,
346 target_size=(300, 300),
347 batch_size=20,
348 class_mode='binary')
349
350 test_loss, test_acc = model.evaluate_generator(test_generator, steps=test_generator.samples // 20)
351 print('test acc:', test_acc)
结论:本课设基于新冠疫情的出发点设计,目的是判断人员(图片)是否佩戴口罩。该程序通过机器学习,能够较准确的实现是否佩戴口罩的识别。在本实验中,通过验证“其他训练次数",也进一步验证了本程序的可靠性。在实验中,我发现训练次数为20次的识别准确率,要高于训练次数为50次的验证训练。说明依旧存在过拟合的情况。从这个现象中,我得出结论:随着训练轮次增加,训练数据上的损失和精度能达到最高值,随后随着训练次数的再次增加,训练数据上的损失和精度能逐步回落。
收获:在这次课程设计的实现过程中,发现了自己的很多不足,从而更加明白知识扎实的重要性,理解实践能力的重要性。通过本次期末课设,很好的增强我对python的实际应用能力,也促进了我发现问题和解决问题的能力。通过本次课设实现,我对python的应用场景有了更加深入的理解。也很大程度上提升了我对python的学习兴趣。
标签:口罩,plt,img,--,佩戴,300,scale,import,model From: https://www.cnblogs.com/lmyr/p/16992271.html