机器学习--环境空气质量雾霾识别

(一)选题背景:

        空气质量,即反应空气污染程度的指标。它是依据空气中污染物浓度的高低来判断的,当空气中污染物浓度过高时极易产生雾霾天气。雾霾主要影响包括空气的质量与能见度,对于人体也存在一定危害。我国雾霾天气问题突出,全国已设1436个国家空气质量监测站点,由国家统一运行维护,监测数据直报国家并对外公开。然而,虽然如此,由于维护管理不善导致的数据质量问题以及层出不穷的数据造假事件,让人们对官方公布的数据不甚信任。那我们是否有一个更为直观可信赖的方法来对环境空气质量雾霾天气进行直接识别,可监控不同时期空气质量变化,从而对污染管控、削减污染峰值提出措施建议。

(二)机器学习设计案例设计方案:

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

参考来源:kaggle关于标签学习的讨论区

数据集来源:kaggle,网址:https://www.kaggle.com/datasets/ekojsalim/ohaze-patches

 (三)机器学习的实现步骤:

1、数据集的下载

2、显示数据集个数

import os

train_path="E:\\python\\o-hazy\\train/"
#无雾霾(clean)
print('total training clean_images:', len(os.listdir(train_path+"clean")))
#有雾霾(hazy)
print('total training hazy_images:', len(os.listdir(train_path+"hazy")))

valid_path="E:\\python\\o-hazy\\validation/"
print('total validation clean_images:', len(os.listdir(valid_path+"clean")))
print('total validation hazy_images:', len(os.listdir(valid_path+"hazy")))

test="E:\\python\\o-hazy\\test/"
print('total test clean_images:', len(os.listdir(test+"clean")))
print('total test hazy_images:', len(os.listdir(test+"hazy")))

3、搭建卷积神经网络模型

from keras import layers
from keras import models

model = models.Sequential()

#Output shape计算公式:(输入尺寸-卷积核尺寸/步长+1

#对CNN模型,Param的计算方法如下:

#卷积核长度*卷积核宽度*通道数+1)*卷积核个数


# 输出图片尺寸:150-3+1=148*148  (输入尺寸-卷积核尺寸/步长+1

#参数数量:32*3*3*3+32=896 ,32是卷积核个数
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))

"""
输入:参数为0
输出:
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_12 (Conv2D)           (None, 148, 148, 32)      896           
"""

model.add(layers.MaxPooling2D((2, 2)))  # 输出图片尺寸:148/2=74*74
"""

Max_pooling_2d:此层用于减小输入图像的大小。kernal_size =(2,2)在这里使用。
因此输入图像148减少到一半74。模型从这一层学不到任何东西。
池化层中没有可以学习的参数。该层仅用于减小图像尺寸。
Layer (type)                 Output Shape              Param #   
=================================================================
max_pooling2d_12 (MaxPooling (None, 74, 74, 32)        0         
_________________________________________________________________

"""



# 输出图片尺寸:74-3+1=72*72,参数数量:64*3*3*32+64=18496
#32是第1个卷积层的输出的通道数
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
"""
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_13 (Conv2D)           (None, 72, 72, 64)        18496     
_________________________________________________________________
"""



model.add(layers.MaxPooling2D((2, 2)))  # 输出图片尺寸:72/2=36*36


#Output Shape的输出为36
# 输出图片尺寸:36-3+1=34*34,参数数量:128*3*3*64+128=73856
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))  # 输出图片尺寸:34/2=17*17

# 输出图片尺寸:17-3+1=15*15,参数数量:128*3*3*128+128=147584
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))  # 输出图片尺寸:15/2=7*7

#  多维转为一维:7*7*128=6272
model.add(layers.Flatten())

#  参数数量:6272*512+512=3211776
model.add(layers.Dense(512, activation='relu'))

#  参数数量:512*1+1=513
model.add(layers.Dense(1, activation='sigmoid'))

4、看一下特征图的维度如何随着每层变化

model.summary()

5、编译模型并进行图像预处理

# 编译模型
# RMSprop 优化器。因为网络最后一层是单一sigmoid单元,
# 所以使用二元交叉熵作为损失函数
from keras import optimizers

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])

#图像在输入神经网络之前进行数据处理,建立训练和验证数据
from keras.preprocessing.image import ImageDataGenerator

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

train_dir = 'E:\\python\\o-hazy\\train/'     #指向训练集图片目录路径


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

validation_dir = 'E:\\python\\o-hazy\\validation/'  #指向验证集图片目录路径

validation_generator = test_datagen.flow_from_directory(
    validation_dir,
    target_size = (150,150),
    batch_size = 20,
    class_mode = 'binary')


for data_batch,labels_batch in train_generator:
    print('data batch shape:',data_batch.shape)
    print('data batch shape:',labels_batch.shape)
    break #生成器不会停止,会循环生成这些批量,所以我们就循环生成一次批量

6、对模型进行训练10轮次

#训练模型10轮次
history = model.fit(
                    train_generator,
                    steps_per_epoch = 100,
                    epochs = 10,
                    validation_data = validation_generator,
                    validation_steps = 50)

7、数据保存为h5文件

# 将训练过程产生的数据保存为h5文件
from keras.models import load_model
model.save('E:\python\o-hazy/o-hazy_10.h5')

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

# 分别绘制训练过程中模型在训练数据和验证数据上的损失和精度
import matplotlib.pyplot as plt

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1, len(acc) + 1)

figure, axis = plt.subplots(nrows=1, ncols=2, figsize=(18, 6))
axis[0].plot(epochs, acc, 'bo', label='Training acc')
axis[0].plot(epochs, val_acc, 'b', label='Validation acc')
axis[0].set_title('Training and Validation accuracy')
axis[0].legend()

axis[1].plot(epochs, loss, 'bo', label='Training loss')
axis[1].plot(epochs, val_loss, 'b', label='Validation loss')
axis[1].set_title('Training and Validation loss')
axis[1].legend()

9、从测试集中读取一条样本并显示

#从测试集中读取一条样本
from keras.utils import image_utils
import numpy as np
img_path = "E:\\python\\o-hazy\\test\\hazy\\1.jpg"
img = image_utils.load_img(img_path, target_size=(150,150))
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()

10、建立模型,输入为原图像,输出为原模型的前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)

#显示第一层激活输出特的第一个滤波器的特征图
import matplotlib.pyplot as plt
first_layer_activation = activations[0]
plt.matshow(first_layer_activation[0,:,:,1],  cmap="viridis")

11、显示8层激活输出的全部特征图

#存储层的名称
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")

12、导入图片进行预测

#读取用户自定义图像文件,改尺寸后保存

import matplotlib.pyplot as plt
from PIL import Image
import os.path

def convertjpg(jpgfile,outdir,width=150,height=150):#将图片缩小到(150,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)
        
jpgfile = 'E:\\python\\o-hazy\\test\\hazy/2.jpg'#读取原图像(有雾霾)
convertjpg(jpgfile,"E:\\python\\o-hazy\\working")#图像大小改变到(150,150)
img_scale = plt.imread('E:\\python\\o-hazy\\working/2.jpg')
plt.imshow(img_scale)    #显示改变图像大小后的图片确实变到了(150,150)大小 
from keras.models import load_model
model = load_model('E:\python\o-hazy/o-hazy_10.h5')

img_scale = img_scale.reshape(1,150,150,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=150,height=150):#将图片缩小到(150,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)
        
jpgfile = 'E:\\python\\o-hazy\\test\\clean/2.jpg'#读取原图像(无雾霾)
convertjpg(jpgfile,"E:\\python\\o-hazy\\working")#图像大小改变到(150,150)
img_scale = plt.imread('E:\\python\\o-hazy\\working/12.jpg')
plt.imshow(img_scale)    #显示改变图像大小后的图片确实变到了(150,150)大小 
from keras.models import load_model
model = load_model('E:\python\o-hazy/o-hazy_10.h5')

img_scale = img_scale.reshape(1,150,150,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)

13、用测试集对模型进行测试

# 用测试集对模型进行测试:
test_datagen = ImageDataGenerator(rescale = 1./255)
test_dir='E:\\python\\o-hazy\\test'
test_generator = test_datagen.flow_from_directory(
     test_dir,
     target_size=(150,150),
     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)

14、更改训练50轮次

#训练模型50轮次
history = model.fit(
                    train_generator,
                    steps_per_epoch = 100,
                    epochs = 50,
                    validation_data = validation_generator,
                    validation_steps = 50)

15、训练过程产生的数据保存为h5文件

# 将训练过程产生的数据保存为h5文件
from keras.models import load_model
model.save('E:\python\o-hazy/o-hazy_50.h5')

16、绘制损失曲线和精度曲线图

# 分别绘制训练过程中模型在训练数据和验证数据上的损失和精度
import matplotlib.pyplot as plt

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1, len(acc) + 1)

figure, axis = plt.subplots(nrows=1, ncols=2, figsize=(18, 6))
axis[0].plot(epochs, acc, 'bo', label='Training acc')
axis[0].plot(epochs, val_acc, 'b', label='Validation acc')
axis[0].set_title('Training and Validation accuracy')
axis[0].legend()

axis[1].plot(epochs, loss, 'bo', label='Training loss')
axis[1].plot(epochs, val_loss, 'b', label='Validation loss')
axis[1].set_title('Training and Validation loss')
axis[1].legend()

17、导入图片进行预测

#读取用户自定义图像文件,改尺寸后保存

import matplotlib.pyplot as plt
from PIL import Image
import os.path

def convertjpg(jpgfile,outdir,width=150,height=150):#将图片缩小到(150,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)
        
jpgfile = 'E:\\python\\o-hazy\\test\\hazy/2.jpg'#读取原图像(有雾霾)
convertjpg(jpgfile,"E:\\python\\o-hazy\\working")#图像大小改变到(150,150)
img_scale = plt.imread('E:\\python\\o-hazy\\working/2.jpg')
plt.imshow(img_scale)    #显示改变图像大小后的图片确实变到了(150,150)大小 
from keras.models import load_model
model = load_model('E:\python\o-hazy/o-hazy_50.h5')

img_scale = img_scale.reshape(1,150,150,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=150,height=150):#将图片缩小到(150,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)
        
jpgfile = 'E:\\python\\o-hazy\\test\\clean/2.jpg'#读取原图像(无雾霾)
convertjpg(jpgfile,"E:\\python\\o-hazy\\working")#图像大小改变到(150,150)
img_scale = plt.imread('E:\\python\\o-hazy\\working/2.jpg')
plt.imshow(img_scale)    #显示改变图像大小后的图片确实变到了(150,150)大小 
from keras.models import load_model
model = load_model('E:\python\o-hazy/o-hazy_50.h5')

img_scale = img_scale.reshape(1,150,150,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)

18、用测试集对模型进行测试

# 用测试集对模型进行测试:
test_datagen = ImageDataGenerator(rescale = 1./255)
test_dir='E:\\python\\o-hazy\\test'
test_generator = test_datagen.flow_from_directory(
     test_dir,
     target_size=(150,150),
     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)

19、附上全部代码:

  1 #显示数据集个数
  2 import os
  3 
  4 train_path="E:\\python\\o-hazy\\train/"
  5 #无雾霾(clean)
  6 print('total training clean_images:', len(os.listdir(train_path+"clean")))
  7 #有雾霾(hazy)
  8 print('total training hazy_images:', len(os.listdir(train_path+"hazy")))
  9 
 10 valid_path="E:\\python\\o-hazy\\validation/"
 11 print('total validation clean_images:', len(os.listdir(valid_path+"clean")))
 12 print('total validation hazy_images:', len(os.listdir(valid_path+"hazy")))
 13 
 14 test="E:\\python\\o-hazy\\test/"
 15 print('total test clean_images:', len(os.listdir(test+"clean")))
 16 print('total test hazy_images:', len(os.listdir(test+"hazy")))
 17 
 18 #搭建卷积神经网络模型
 19 from keras import layers
 20 from keras import models
 21 
 22 model = models.Sequential()
 23 
 24 #Output shape计算公式:(输入尺寸-卷积核尺寸/步长+1
 25 
 26 #对CNN模型,Param的计算方法如下:
 27 
 28 #卷积核长度*卷积核宽度*通道数+1)*卷积核个数
 29 
 30 # 输出图片尺寸:150-3+1=148*148  (输入尺寸-卷积核尺寸/步长+1
 31 
 32 #参数数量:32*3*3*3+32=896 ,32是卷积核个数
 33 model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))
 34 
 35 """
 36 输入:参数为0
 37 输出:
 38 Layer (type)                 Output Shape              Param #   
 39 =================================================================
 40 conv2d_12 (Conv2D)           (None, 148, 148, 32)      896           
 41 
 42 """
 43 
 44 model.add(layers.MaxPooling2D((2, 2)))  # 输出图片尺寸:148/2=74*74
 45 
 46 """
 47 
 48 Max_pooling_2d:此层用于减小输入图像的大小。kernal_size =(2,2)在这里使用。
 49 因此输入图像148减少到一半74。模型从这一层学不到任何东西。
 50 池化层中没有可以学习的参数。该层仅用于减小图像尺寸。
 51 Layer (type)                 Output Shape              Param #   
 52 =================================================================
 53 max_pooling2d_12 (MaxPooling (None, 74, 74, 32)        0         
 54 _________________________________________________________________
 55 
 56 """
 57 
 58 # 输出图片尺寸:74-3+1=72*72,参数数量:64*3*3*32+64=18496
 59 #32是第1个卷积层的输出的通道数
 60 model.add(layers.Conv2D(64, (3, 3), activation='relu'))
 61 
 62 """
 63 Layer (type)                 Output Shape              Param #   
 64 =================================================================
 65 conv2d_13 (Conv2D)           (None, 72, 72, 64)        18496     
 66 _________________________________________________________________
 67 """
 68 
 69 model.add(layers.MaxPooling2D((2, 2)))  # 输出图片尺寸:72/2=36*36
 70 
 71 #Output Shape的输出为36
 72 # 输出图片尺寸:36-3+1=34*34,参数数量:128*3*3*64+128=73856
 73 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
 74 model.add(layers.MaxPooling2D((2, 2)))  # 输出图片尺寸:34/2=17*17
 75 
 76 # 输出图片尺寸:17-3+1=15*15,参数数量:128*3*3*128+128=147584
 77 model.add(layers.Conv2D(128, (3, 3), activation='relu'))
 78 model.add(layers.MaxPooling2D((2, 2)))  # 输出图片尺寸:15/2=7*7
 79 
 80 #  多维转为一维:7*7*128=6272
 81 model.add(layers.Flatten())
 82 
 83 #  参数数量:6272*512+512=3211776
 84 model.add(layers.Dense(512, activation='relu'))
 85 
 86 #  参数数量:512*1+1=513
 87 model.add(layers.Dense(1, activation='sigmoid'))
 88 
 89 #看一下特征图的维度如何随着每层变化
 90 model.summary()
 91 
 92 # 编译模型
 93 # RMSprop 优化器。因为网络最后一层是单一sigmoid单元,
 94 # 所以使用二元交叉熵作为损失函数
 95 from keras import optimizers
 96 
 97 model.compile(loss='binary_crossentropy',
 98               optimizer=optimizers.RMSprop(lr=1e-4),
 99               metrics=['acc'])
100 
101 #图像在输入神经网络之前进行数据处理,建立训练和验证数据
102 from keras.preprocessing.image import ImageDataGenerator
103 
104 #归一化
105 train_datagen = ImageDataGenerator(rescale = 1./255)
106 test_datagen = ImageDataGenerator(rescale = 1./255)
107 
108 train_dir = 'E:\\python\\o-hazy\\train/'     #指向训练集图片目录路径
109 
110 train_generator = train_datagen.flow_from_directory(
111     train_dir,
112     target_size = (150,150),#  输入训练图像尺寸
113     batch_size = 20,
114     class_mode = 'binary')  #
115 
116 validation_dir = 'E:\\python\\o-hazy\\validation/'  #指向验证集图片目录路径
117 
118 validation_generator = test_datagen.flow_from_directory(
119     validation_dir,
120     target_size = (150,150),
121     batch_size = 20,
122     class_mode = 'binary')
123 
124 for data_batch,labels_batch in train_generator:
125     print('data batch shape:',data_batch.shape)
126     print('data batch shape:',labels_batch.shape)
127     break #生成器不会停止,会循环生成这些批量,所以我们就循环生成一次批量
128     
129 #训练模型10轮次
130 history = model.fit(
131                     train_generator,
132                     steps_per_epoch = 100,
133                     epochs = 10,
134                     validation_data = validation_generator,
135                     validation_steps = 50)
136 
137 # 将训练过程产生的数据保存为h5文件
138 from keras.models import load_model
139 model.save('E:\python\o-hazy/o-hazy_10.h5')
140 
141 # 分别绘制训练过程中模型在训练数据和验证数据上的损失和精度
142 import matplotlib.pyplot as plt
143 
144 acc = history.history['acc']
145 val_acc = history.history['val_acc']
146 loss = history.history['loss']
147 val_loss = history.history['val_loss']
148 
149 epochs = range(1, len(acc) + 1)
150 
151 figure, axis = plt.subplots(nrows=1, ncols=2, figsize=(18, 6))
152 axis[0].plot(epochs, acc, 'bo', label='Training acc')
153 axis[0].plot(epochs, val_acc, 'b', label='Validation acc')
154 axis[0].set_title('Training and Validation accuracy')
155 axis[0].legend()
156 
157 axis[1].plot(epochs, loss, 'bo', label='Training loss')
158 axis[1].plot(epochs, val_loss, 'b', label='Validation loss')
159 axis[1].set_title('Training and Validation loss')
160 axis[1].legend()
161 
162 #从测试集中读取一条样本
163 from keras.utils import image_utils
164 import numpy as np
165 img_path = "E:\\python\\o-hazy\\test\\hazy\\1.jpg"
166 img = image_utils.load_img(img_path, target_size=(150,150))
167 img_tensor = image_utils.img_to_array(img)
168 img_tensor = np.expand_dims(img_tensor, axis=0)
169 img_tensor /= 255.
170 print(img_tensor.shape)
171 
172 #显示样本
173 import matplotlib.pyplot as plt
174 plt.imshow(img_tensor[0])
175 plt.show()
176 
177 #建立模型,输入为原图像,输出为原模型的前8层的激活输出的特征图
178 from keras import models
179 
180 layer_outputs = [layer.output for layer in model.layers[:8]]
181 activation_model = models.Model(inputs=model.input, outputs=layer_outputs)
182 #获得改样本的特征图
183 activations = activation_model.predict(img_tensor)
184 
185 #显示第一层激活输出特的第一个滤波器的特征图
186 import matplotlib.pyplot as plt
187 first_layer_activation = activations[0]
188 plt.matshow(first_layer_activation[0,:,:,1],  cmap="viridis")
189 
190 #存储层的名称
191 layer_names = []
192 for layer in model.layers[:4]:
193     layer_names.append(layer.name)
194 # 每行显示16个特征图
195 images_pre_row = 16  #每行显示的特征图数
196 # 循环8次显示8层的全部特征图
197 for layer_name, layer_activation in zip(layer_names, activations):
198     n_features = layer_activation.shape[-1] #保存当前层的特征图个数
199     size = layer_activation.shape[1]  #保存当前层特征图的宽高
200     n_col = n_features // images_pre_row #计算当前层显示多少行
201     #生成显示图像的矩阵
202     display_grid = np.zeros((size*n_col, images_pre_row*size))
203     #遍历将每个特张图的数据写入到显示图像的矩阵中
204     for col in range(n_col):
205         for row in range(images_pre_row):
206             #保存该张特征图的矩阵(size,size,1)
207             channel_image = layer_activation[0,:,:,col*images_pre_row+row]
208             #为使图像显示更鲜明,作一些特征处理
209             channel_image -= channel_image.mean()
210             channel_image /= channel_image.std()
211             channel_image *= 64
212             channel_image += 128 
213             #把该特征图矩阵中不在0-255的元素值修改至0-255
214             channel_image = np.clip(channel_image, 0, 255).astype("uint8")
215             #该特征图矩阵填充至显示图像的矩阵中
216             display_grid[col*size:(col+1)*size, row*size:(row+1)*size] = channel_image
217         
218     scale = 1./size
219     #设置该层显示图像的宽高
220     plt.figure(figsize=(scale*display_grid.shape[1],scale*display_grid.shape[0]))
221     plt.title(layer_name)
222     plt.grid(False)
223     #显示图像
224     plt.imshow(display_grid, aspect="auto", cmap="viridis")
225     
226 #读取用户自定义图像文件,改尺寸后保存
227 
228 import matplotlib.pyplot as plt
229 from PIL import Image
230 import os.path
231 
232 def convertjpg(jpgfile,outdir,width=150,height=150):#将图片缩小到(150,150)的大小
233     img=Image.open(jpgfile)
234     try:
235         new_img=img.resize((width,height),Image.BILINEAR)   
236         new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
237     except Exception as e:
238         print(e)
239         
240 jpgfile = 'E:\\python\\o-hazy\\test\\hazy/2.jpg'#读取原图像(有雾霾)
241 convertjpg(jpgfile,"E:\\python\\o-hazy\\working")#图像大小改变到(150,150)
242 img_scale = plt.imread('E:\\python\\o-hazy\\working/2.jpg')
243 plt.imshow(img_scale)    #显示改变图像大小后的图片确实变到了(150,150)大小 
244 from keras.models import load_model
245 model = load_model('E:\python\o-hazy/o-hazy_10.h5')
246 
247 img_scale = img_scale.reshape(1,150,150,3).astype('float32')
248 img_scale = img_scale/255        #归一化到0-1之间
249 
250 result = model.predict(img_scale) #取图片信息
251 # print(result)
252 if result>0.5:
253     print('该图片是有雾霾的概率为:',result)
254 else:
255     print('该图片是无雾霾的概率为:',1-result)
256 
257 #读取用户自定义图像文件,改尺寸后保存
258 
259 import matplotlib.pyplot as plt
260 from PIL import Image
261 import os.path
262 
263 def convertjpg(jpgfile,outdir,width=150,height=150):#将图片缩小到(150,150)的大小
264     img=Image.open(jpgfile)
265     try:
266         new_img=img.resize((width,height),Image.BILINEAR)   
267         new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
268     except Exception as e:
269         print(e)
270         
271 jpgfile = 'E:\\python\\o-hazy\\test\\clean/2.jpg'#读取原图像(无雾霾)
272 convertjpg(jpgfile,"E:\\python\\o-hazy\\working")#图像大小改变到(150,150)
273 img_scale = plt.imread('E:\\python\\o-hazy\\working/12.jpg')
274 plt.imshow(img_scale)    #显示改变图像大小后的图片确实变到了(150,150)大小 
275 
276 from keras.models import load_model
277 model = load_model('E:\python\o-hazy/o-hazy_10.h5')
278 
279 img_scale = img_scale.reshape(1,150,150,3).astype('float32')
280 img_scale = img_scale/255        #归一化到0-1之间
281 
282 result = model.predict(img_scale) #取图片信息
283 # print(result)
284 if result>0.5:
285     print('该图片是有雾霾的概率为:',result)
286 else:
287     print('该图片是无雾霾的概率为:',1-result)
288 
289 # 用测试集对模型进行测试:
290 test_datagen = ImageDataGenerator(rescale = 1./255)
291 test_dir='E:\\python\\o-hazy\\test'
292 test_generator = test_datagen.flow_from_directory(
293      test_dir,
294      target_size=(150,150),
295      batch_size=20,
296      class_mode='binary')
297 
298 test_loss, test_acc = model.evaluate_generator(test_generator, steps=test_generator.samples // 20)
299 print('test acc:', test_acc)

(四)总结:

        结论:从以上两次不同轮次训练的测试结果可以看出,训练数据和验证数据的准确率会随着训练轮次的增加而提高。测试集精度在epochs = 10时为0.77,而在epochs = 50时为0.89,这结果相差达0.12左右。因此该模型在训练轮次上还可以继续增加即可达到最适的结果。相信继续增加训练轮次,测试准确率将不断提高,以保证测试结果数据的可靠性。

        收获:随着大数据时代各行业对数据分析需求的持续增加,通过机器学习高效地获取知识,已逐渐成为当今机器学习技术发展的主要推动力。在本次机器学习的过程中,我深刻的了解了机器学习,它是人工智能的核心,更是使计算机具有智能的根本途径。本次课程设计基本实现,但不足之处在于准确率并没有达到我预期的标准,如何让准确率再提高是需要改进的地方。感谢老师本学期的教学,让我对机器学习的概念有了更进一步的学习。

 

posted @ 2022-12-21 13:41  Road_Town  阅读(370)  评论(0)    收藏  举报