一、选题的背景
随着城市化建设不断发展,我国对交通建设的需求也不断增长,成为了世界上在交通领域基础设施建设最快的国家之一,但车辆管控问题、道路交通问题、车辆违章问题等层出不穷,很难做到全面、有效的管理。马路上的摄像头每天拍摄下的许多汽车辆照片,怎么在大量的图片中筛选出是汽车或者摩托车的图片,这时车辆识别就显得尤为重要,我们可以使用Keras搭建部署一个简单易用的深度学习图像网页应用, 可以通过网页导入一张汽车或者摩托车的图片预测是汽车或者摩托车的概率。这样一来,车辆识别就能有效地简化一些交通管理问题,减小交通规划所需的成本,提升管理效率。除此之外,也有利于道路车辆信息实时地采集,通过对采集到的这些数据进行统计分析,有利于以后对不同道路交通的规划建设。
二、机器学习设计案例设计方案
从网站中下载相关的数据集,对数据集进行整理,在python的环境中,给数据集中的文件打上标签,对数据进行预处理,利用keras,构建网络,训练模型,导入图片测试模型。
数据源:本次课程设计的数据集来源于数据科学创新与实践平台。
附上网址:https://www.datacastle.cn/
参考来源:猫狗大战
三、数据分析步骤 1.下载数据集![](/i/l/?n=23&i=blog/3049844/202212/3049844-20221223235658877-1129732752.png)
2.检查一下每个分组(训练 / 测试)中分别包含多少张图像
1 #检查一下每个分组(训练 / 测试)中分别包含多少张图像 2 import os 3 4 train_path="E:/CarvsBike/train/" 5 print('Bikes images:', len(os.listdir(train_path+"Bikes"))) 6 print('Cars images:', len(os.listdir(train_path+"Cars"))) 7 8 valid_path="E:/CarvsBike/validation/" 9 print('Bikes images:', len(os.listdir(valid_path+"Bikes"))) 10 print('Cars images:', len(os.listdir(valid_path+"Cars"))) 11 12 test_path="E:/CarvsBike/test/" 13 print('test images:', len(os.listdir(test_path)))
3.搭建卷积神经网络模型,输出特征图的维度
1 from keras import layers 2 from keras import models 3 4 # 搭建网络 5 model = models.Sequential() 6 # 第一个卷积层作为输入层,32个3*3卷积核,输入形状input_shape = (150,150,3) 7 8 # 输出图片尺寸:150-3+1=148*148,参数数量:32*3*3*3+32=896 9 model.add(layers.Conv2D(32,(3,3),activation = 'relu',input_shape = (150,150,3))) 10 model.add(layers.MaxPooling2D((2,2))) # 输出图片尺寸:148/2=74*74 11 12 # 输出图片尺寸:74-3+1=72*72,参数数量:64*3*3*32+64=18496 13 model.add(layers.Conv2D(64,(3,3),activation = 'relu')) 14 model.add(layers.MaxPooling2D((2,2))) # 输出图片尺寸:72/2=36*36 15 16 # 输出图片尺寸:36-3+1=34*34,参数数量:128*3*3*64+128=73856 17 model.add(layers.Conv2D(128,(3,3),activation = 'relu')) 18 model.add(layers.MaxPooling2D((2,2))) # 输出图片尺寸:34/2=17*17 19 20 21 model.add(layers.Conv2D(128,(3,3),activation = 'relu')) 22 model.add(layers.MaxPooling2D((2,2))) 23 24 model.add(layers.Flatten()) 25 model.add(layers.Dense(512,activation = 'relu')) 26 model.add(layers.Dense(1,activation = 'sigmoid')) # sigmoid分类,输出是两类别 27 28 # 看一下特征图的维度如何随着每层变化 29 model.summary()
4.遍历数据集中的文件,将路径数据和标签数据生成DataFrame
1 from pathlib import Path 2 import pandas as pd 3 4 dir = Path('E:/CarvsBike/train/') 5 6 # 用glob遍历在dir路径中所有jpg格式的文件,并将所有的文件名添加到filepaths列表中 7 filepaths = list(dir.glob(r'**/*.jpg')) 8 9 # 将文件中的分好的小文件名(种类名)分离并添加到labels的列表中 10 labels = list(map(lambda l: os.path.split(os.path.split(l)[0])[1], filepaths)) 11 12 # 将filepaths通过pandas转换为Series数据类型 13 filepaths = pd.Series(filepaths, name='FilePaths').astype(str) 14 15 # 将labels通过pandas转换为Series数据类型 16 labels = pd.Series(labels, name='Labels').astype(str) 17 18 # 将filepaths和Series两个Series的数据类型合成DataFrame数据类型 19 df = pd.merge(filepaths, labels, right_index=True, left_index=True) 20 df = df[df['Labels'].apply(lambda l: l[-2:] != 'GT')] 21 df = df.sample(frac=1).reset_index(drop=True) 22 #查看形成的DataFrame的数据 23 df
5.查看图像以及对应的标签
1 #查看图像以及对应的标签 2 fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7)) 3 4 for i, a in enumerate(ax.flat): 5 a.imshow(plt.imread(df.FilePaths[i])) 6 a.set_title(df.Labels[i]) 7 8 plt.tight_layout() 9 plt.show() 10 11 #查看各个标签的图片张数 12 df['Labels'].value_counts(ascending=True)
6.对图像进行预处理
1 # 归一化 2 # 图像在输入神经网络之前进行数据处理,建立训练和验证数据 3 from keras.preprocessing.image import ImageDataGenerator 4 train_datagen = ImageDataGenerator(rescale = 1./255) 5 test_datagen = ImageDataGenerator(rescale = 1./255) 6 7 train_dir = 'E:/CarvsBike/train/' # 指向训练集图片目录路径 8 9 10 train_generator = train_datagen.flow_from_directory( 11 train_dir, 12 target_size = (150,150), # 输入训练图像尺寸 13 batch_size = 20, 14 class_mode = 'binary') # 15 16 validation_dir = 'E:/CarvsBike/validation/' # 指向验证集图片目录路径 17 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 24 25 for data_batch,labels_batch in train_generator: 26 print('data batch shape:',data_batch.shape) 27 print('data batch shape:',labels_batch.shape) 28 break # 生成器不会停止,会循环生成这些批量,所以我们就循环生成一次批量
7.编译和训练模型
1 # 编译模型 2 # RMSprop 优化器。因为网络最后一层是单一sigmoid单元, 3 # 所以使用二元交叉熵作为损失函数 4 from keras import optimizers 5 6 7 model.compile(loss='binary_crossentropy', 8 optimizer=optimizers.RMSprop(lr=1e-4), 9 metrics=['acc']) 10 # 训练模型20轮次 11 history = model.fit( 12 train_generator, 13 steps_per_epoch = 100, 14 epochs = 20, 15 validation_data = validation_generator, 16 validation_steps = 50)
8.将训练过程产生的数据保存为h5文件
1 from keras.models import load_model 2 model.save('E:/CarvsBike/2103840260.h5')
9.绘制模型在训练数据和验证数据上的损失曲线图和精度曲线图
1 import matplotlib.pyplot as plt 2 loss = history.history['loss'] 3 val_loss = history.history['val_loss'] 4 epochs = range(1, len(loss) + 1) 5 plt.plot(epochs, loss, 'bo', label = 'Training loss') 6 plt.plot(epochs, val_loss, 'b', label = 'Validation loss') 7 plt.title('Training And Validation Loss') 8 plt.xlabel('Epochs') 9 plt.ylabel('Loss') 10 plt.legend() 11 plt.show() 12 13 plt.clf() 14 15 acc = history.history['acc'] 16 val_acc = history.history['val_acc'] 17 18 plt.plot(epochs, acc, 'bo', label = 'Training acc') 19 plt.plot(epochs, val_acc, 'b', label = 'Validation acc') 20 plt.title('Training And Validation Accuracy') 21 plt.xlabel('Epochs') 22 plt.ylabel('Accuracy') 23 plt.legend() 24 plt.show()
10.从测试集中读取一条样本并显示样本
1 img_path = "E:/CarvsBike/test/Bike (53).jpg" 2 3 from keras.preprocessing import image 4 import numpy as np 5 from keras.utils import image_utils 6 7 img = image_utils.load_img(img_path, target_size=(150,150)) 8 img_tensor = image_utils.img_to_array(img) 9 img_tensor = np.expand_dims(img_tensor, axis=0) 10 img_tensor /= 255. 11 print(img_tensor.shape) 12 13 import matplotlib.pyplot as plt 14 plt.imshow(img_tensor[0]) 15 plt.show()
11.建立模型,输入为原图像,输出为原模型的前8层的激活输出的特征图
1 from keras import models 2 3 layer_outputs = [layer.output for layer in model.layers[:8]] 4 activation_model = models.Model(inputs=model.input, outputs=layer_outputs) 5 #获得改样本的特征图 6 activations = activation_model.predict(img_tensor) 7 8 #显示第一层激活输出特的第一个滤波器的特征图 9 import matplotlib.pyplot as plt 10 first_layer_activation = activations[0] 11 plt.matshow(first_layer_activation[0,:,:,1], cmap="viridis")
12.显示前4层激活输出的全部特征图
1 #存储层的名称 2 layer_names = [] 3 for layer in model.layers[:4]: 4 layer_names.append(layer.name) 5 # 每行显示16个特征图 6 images_pre_row = 16 #每行显示的特征图数 7 # 循环8次显示8层的全部特征图 8 for layer_name, layer_activation in zip(layer_names, activations): 9 n_features = layer_activation.shape[-1] #保存当前层的特征图个数 10 size = layer_activation.shape[1] #保存当前层特征图的宽高 11 n_col = n_features // images_pre_row #计算当前层显示多少行 12 #生成显示图像的矩阵 13 display_grid = np.zeros((size*n_col, images_pre_row*size)) 14 #遍历将每个特张图的数据写入到显示图像的矩阵中 15 for col in range(n_col): 16 for row in range(images_pre_row): 17 #保存该张特征图的矩阵(size,size,1) 18 channel_image = layer_activation[0,:,:,col*images_pre_row+row] 19 #为使图像显示更鲜明,作一些特征处理 20 channel_image -= channel_image.mean() 21 channel_image /= channel_image.std() 22 channel_image *= 64 23 channel_image += 128 24 #把该特征图矩阵中不在0-255的元素值修改至0-255 25 channel_image = np.clip(channel_image, 0, 255).astype("uint8") 26 #该特征图矩阵填充至显示图像的矩阵中 27 display_grid[col*size:(col+1)*size, row*size:(row+1)*size] = channel_image 28 29 scale = 1./size 30 #设置该层显示图像的宽高 31 plt.figure(figsize=(scale*display_grid.shape[1],scale*display_grid.shape[0])) 32 plt.title(layer_name) 33 plt.grid(False) 34 #显示图像 35 plt.imshow(display_grid, aspect="auto", cmap="viridis")
13.取图像样本,改变其尺寸,并进行图片测试
1 import matplotlib.pyplot as plt 2 from PIL import Image 3 import os.path 4 5 def convertjpg(jpgfile,outdir,width=150,height=150): #将图片缩小到(150,150)的大小 6 img=Image.open(jpgfile) 7 try: 8 new_img=img.resize((width,height),Image.BILINEAR) 9 new_img.save(os.path.join(outdir,os.path.basename(new_file))) 10 except Exception as e: 11 print(e) 12 13 jpgfile= "E:/CarvsBike/test/Bike (53).jpg" 14 new_file= "E:/CarvsBike/test/new_Bike (53).jpg" 15 #图像大小改变到(150,150),文件名保存 16 convertjpg(jpgfile,r"E:/CarvsBike") 17 img_scale = plt.imread('E:/CarvsBike/new_Bike (53).jpg') 18 19 plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(150,150)大小 20 21 # 导入h5模型 22 from keras.models import load_model 23 model = load_model('E:/CarvsBike/2103840260.h5') 24 25 img_scale = img_scale.reshape(1,150,150,3).astype('float32') 26 img_scale = img_scale/255 # 归一化到0-1之间 27 28 result = model.predict(img_scale) # 取图片信息 29 # print(result) 30 if result>0.5: 31 print('是汽车的概率为:',result) 32 else: 33 print('是摩托车的概率为:',1-result)
1 import matplotlib.pyplot as plt 2 from PIL import Image 3 import os.path 4 5 def convertjpg(jpgfile,outdir,width=150,height=150): #将图片缩小到(150,150)的大小 6 img=Image.open(jpgfile) 7 try: 8 new_img=img.resize((width,height),Image.BILINEAR) 9 new_img.save(os.path.join(outdir,os.path.basename(new_file))) 10 except Exception as e: 11 print(e) 12 13 jpgfile= "E:/CarvsBike/test/Car (32).jpg" 14 new_file= "E:/CarvsBike/test/new_Car (32).jpg" 15 #图像大小改变到(150,150),文件名保存 16 convertjpg(jpgfile,r"E:/CarvsBike") 17 img_scale = plt.imread('E:/CarvsBike/new_Car (32).jpg') 18 19 plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(150,150)大小 20 21 # 导入h5模型 22 from keras.models import load_model 23 model = load_model('E:/CarvsBike/2103840260_cb.h5') 24 25 img_scale = img_scale.reshape(1,150,150,3).astype('float32') 26 img_scale = img_scale/255 # 归一化到0-1之间 27 28 result = model.predict(img_scale) # 取图片信息 29 # print(result) 30 if result>0.5: 31 print('是汽车的概率为:',result) 32 else: 33 print('是摩托车的概率为:',1-result)
14.附完整程序源代码
1 #检查一下每个分组(训练 / 测试)中分别包含多少张图像 2 import os 3 4 train_path="E:/CarvsBike/train/" 5 print('Bikes images:', len(os.listdir(train_path+"Bikes"))) 6 print('Cars images:', len(os.listdir(train_path+"Cars"))) 7 8 valid_path="E:/CarvsBike/validation/" 9 print('Bikes images:', len(os.listdir(valid_path+"Bikes"))) 10 print('Cars images:', len(os.listdir(valid_path+"Cars"))) 11 12 test_path="E:/CarvsBike/test/" 13 print('test images:', len(os.listdir(test_path))) 14 15 from keras import layers 16 from keras import models 17 18 # 搭建网络 19 model = models.Sequential() 20 # 第一个卷积层作为输入层,32个3*3卷积核,输入形状input_shape = (150,150,3) 21 22 # 输出图片尺寸:150-3+1=148*148,参数数量:32*3*3*3+32=896 23 model.add(layers.Conv2D(32,(3,3),activation = 'relu',input_shape = (150,150,3))) 24 model.add(layers.MaxPooling2D((2,2))) # 输出图片尺寸:148/2=74*74 25 26 # 输出图片尺寸:74-3+1=72*72,参数数量:64*3*3*32+64=18496 27 model.add(layers.Conv2D(64,(3,3),activation = 'relu')) 28 model.add(layers.MaxPooling2D((2,2))) # 输出图片尺寸:72/2=36*36 29 30 # 输出图片尺寸:36-3+1=34*34,参数数量:128*3*3*64+128=73856 31 model.add(layers.Conv2D(128,(3,3),activation = 'relu')) 32 model.add(layers.MaxPooling2D((2,2))) # 输出图片尺寸:34/2=17*17 33 34 35 model.add(layers.Conv2D(128,(3,3),activation = 'relu')) 36 model.add(layers.MaxPooling2D((2,2))) 37 38 model.add(layers.Flatten()) 39 model.add(layers.Dense(512,activation = 'relu')) 40 model.add(layers.Dense(1,activation = 'sigmoid')) # sigmoid分类,输出是两类别 41 42 # 看一下特征图的维度如何随着每层变化 43 model.summary() 44 45 from pathlib import Path 46 import pandas as pd 47 48 dir = Path('E:/CarvsBike/train/') 49 50 # 用glob遍历在dir路径中所有jpg格式的文件,并将所有的文件名添加到filepaths列表中 51 filepaths = list(dir.glob(r'**/*.jpg')) 52 53 # 将文件中的分好的小文件名(种类名)分离并添加到labels的列表中 54 labels = list(map(lambda l: os.path.split(os.path.split(l)[0])[1], filepaths)) 55 56 # 将filepaths通过pandas转换为Series数据类型 57 filepaths = pd.Series(filepaths, name='FilePaths').astype(str) 58 59 # 将labels通过pandas转换为Series数据类型 60 labels = pd.Series(labels, name='Labels').astype(str) 61 62 # 将filepaths和Series两个Series的数据类型合成DataFrame数据类型 63 df = pd.merge(filepaths, labels, right_index=True, left_index=True) 64 df = df[df['Labels'].apply(lambda l: l[-2:] != 'GT')] 65 df = df.sample(frac=1).reset_index(drop=True) 66 #查看形成的DataFrame的数据 67 df 68 69 #查看图像以及对应的标签 70 fit, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 7)) 71 72 for i, a in enumerate(ax.flat): 73 a.imshow(plt.imread(df.FilePaths[i])) 74 a.set_title(df.Labels[i]) 75 76 plt.tight_layout() 77 plt.show() 78 79 #查看各个标签的图片张数 80 df['Labels'].value_counts(ascending=True) 81 82 83 # 归一化 84 # 图像在输入神经网络之前进行数据处理,建立训练和验证数据 85 from keras.preprocessing.image import ImageDataGenerator 86 train_datagen = ImageDataGenerator(rescale = 1./255) 87 test_datagen = ImageDataGenerator(rescale = 1./255) 88 89 train_dir = 'E:/CarvsBike/train/' # 指向训练集图片目录路径 90 91 92 train_generator = train_datagen.flow_from_directory( 93 train_dir, 94 target_size = (150,150), # 输入训练图像尺寸 95 batch_size = 20, 96 class_mode = 'binary') # 97 98 validation_dir = 'E:/CarvsBike/validation/' # 指向验证集图片目录路径 99 100 validation_generator = test_datagen.flow_from_directory( 101 validation_dir, 102 target_size = (150,150), 103 batch_size = 20, 104 class_mode = 'binary') 105 106 107 for data_batch,labels_batch in train_generator: 108 print('data batch shape:',data_batch.shape) 109 print('data batch shape:',labels_batch.shape) 110 break # 生成器不会停止,会循环生成这些批量,所以我们就循环生成一次批量 111 112 113 # 编译模型 114 # RMSprop 优化器。因为网络最后一层是单一sigmoid单元, 115 # 所以使用二元交叉熵作为损失函数 116 from keras import optimizers 117 118 119 model.compile(loss='binary_crossentropy', 120 optimizer=optimizers.RMSprop(lr=1e-4), 121 metrics=['acc']) 122 # 训练模型20轮次 123 history = model.fit( 124 train_generator, 125 steps_per_epoch = 100, 126 epochs = 20, 127 validation_data = validation_generator, 128 validation_steps = 50) 129 130 #将训练过程产生的数据保存为h5文件 131 from keras.models import load_model 132 model.save('E:/CarvsBike/2103840260.h5') 133 134 # 分别绘制训练过程中模型在训练数据和验证数据上的损失和精度 135 import matplotlib.pyplot as plt 136 loss = history.history['loss'] 137 val_loss = history.history['val_loss'] 138 epochs = range(1, len(loss) + 1) 139 plt.plot(epochs, loss, 'bo', label = 'Training loss') 140 plt.plot(epochs, val_loss, 'b', label = 'Validation loss') 141 plt.title('Training And Validation Loss') 142 plt.xlabel('Epochs') 143 plt.ylabel('Loss') 144 plt.legend() 145 plt.show() 146 147 plt.clf() 148 149 acc = history.history['acc'] 150 val_acc = history.history['val_acc'] 151 152 plt.plot(epochs, acc, 'bo', label = 'Training acc') 153 plt.plot(epochs, val_acc, 'b', label = 'Validation acc') 154 plt.title('Training And Validation Accuracy') 155 plt.xlabel('Epochs') 156 plt.ylabel('Accuracy') 157 plt.legend() 158 plt.show() 159 160 #从测试集中读取一条样本 161 img_path = "E:/CarvsBike/test/Bike (53).jpg" 162 163 from keras.preprocessing import image 164 import numpy as np 165 from keras.utils import image_utils 166 167 img = image_utils.load_img(img_path, target_size=(150,150)) 168 img_tensor = image_utils.img_to_array(img) 169 img_tensor = np.expand_dims(img_tensor, axis=0) 170 img_tensor /= 255. 171 print(img_tensor.shape) 172 173 # 显示样本 174 import matplotlib.pyplot as plt 175 plt.imshow(img_tensor[0]) 176 plt.show() 177 178 #建立模型,输入为原图像,输出为原模型的前8层的激活输出的特征图 179 from keras import models 180 181 layer_outputs = [layer.output for layer in model.layers[:8]] 182 activation_model = models.Model(inputs=model.input, outputs=layer_outputs) 183 #获得改样本的特征图 184 activations = activation_model.predict(img_tensor) 185 186 #显示第一层激活输出特的第一个滤波器的特征图 187 import matplotlib.pyplot as plt 188 first_layer_activation = activations[0] 189 plt.matshow(first_layer_activation[0,:,:,1], cmap="viridis") 190 191 192 #存储层的名称 193 layer_names = [] 194 for layer in model.layers[:4]: 195 layer_names.append(layer.name) 196 # 每行显示16个特征图 197 images_pre_row = 16 #每行显示的特征图数 198 # 循环8次显示8层的全部特征图 199 for layer_name, layer_activation in zip(layer_names, activations): 200 n_features = layer_activation.shape[-1] #保存当前层的特征图个数 201 size = layer_activation.shape[1] #保存当前层特征图的宽高 202 n_col = n_features // images_pre_row #计算当前层显示多少行 203 #生成显示图像的矩阵 204 display_grid = np.zeros((size*n_col, images_pre_row*size)) 205 #遍历将每个特张图的数据写入到显示图像的矩阵中 206 for col in range(n_col): 207 for row in range(images_pre_row): 208 #保存该张特征图的矩阵(size,size,1) 209 channel_image = layer_activation[0,:,:,col*images_pre_row+row] 210 #为使图像显示更鲜明,作一些特征处理 211 channel_image -= channel_image.mean() 212 channel_image /= channel_image.std() 213 channel_image *= 64 214 channel_image += 128 215 #把该特征图矩阵中不在0-255的元素值修改至0-255 216 channel_image = np.clip(channel_image, 0, 255).astype("uint8") 217 #该特征图矩阵填充至显示图像的矩阵中 218 display_grid[col*size:(col+1)*size, row*size:(row+1)*size] = channel_image 219 220 scale = 1./size 221 #设置该层显示图像的宽高 222 plt.figure(figsize=(scale*display_grid.shape[1],scale*display_grid.shape[0])) 223 plt.title(layer_name) 224 plt.grid(False) 225 #显示图像 226 plt.imshow(display_grid, aspect="auto", cmap="viridis") 227 228 229 import matplotlib.pyplot as plt 230 from PIL import Image 231 import os.path 232 233 def convertjpg(jpgfile,outdir,width=150,height=150): #将图片缩小到(150,150)的大小 234 img=Image.open(jpgfile) 235 try: 236 new_img=img.resize((width,height),Image.BILINEAR) 237 new_img.save(os.path.join(outdir,os.path.basename(new_file))) 238 except Exception as e: 239 print(e) 240 241 jpgfile= "E:/CarvsBike/test/Bike (53).jpg" 242 new_file= "E:/CarvsBike/test/new_Bike (53).jpg" 243 #图像大小改变到(150,150),文件名保存 244 convertjpg(jpgfile,r"E:/CarvsBike") 245 img_scale = plt.imread('E:/CarvsBike/new_Bike (53).jpg') 246 247 plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(150,150)大小 248 249 # 导入h5模型 250 from keras.models import load_model 251 model = load_model('E:/CarvsBike/2103840260.h5') 252 253 img_scale = img_scale.reshape(1,150,150,3).astype('float32') 254 img_scale = img_scale/255 # 归一化到0-1之间 255 256 result = model.predict(img_scale) # 取图片信息 257 # print(result) 258 if result>0.5: 259 print('是汽车的概率为:',result) 260 else: 261 print('是摩托车的概率为:',1-result) 262 263 # 导入h5模型 264 from keras.models import load_model 265 model = load_model('E:/CarvsBike/2103840260.h5') 266 267 img_scale = img_scale.reshape(1,150,150,3).astype('float32') 268 img_scale = img_scale/255 # 归一化到0-1之间 269 270 result = model.predict(img_scale) # 取图片信息 271 # print(result) 272 if result>0.5: 273 print('是汽车的概率为:',result) 274 else: 275 print('是摩托车的概率为:',1-result) 276 277 # 训练模型20轮次 278 history = model.fit( 279 train_generator, 280 steps_per_epoch = 100, 281 epochs = 20, 282 validation_data = validation_generator, 283 validation_steps = 50) 284 285 #将训练过程产生的数据保存为h5文件 286 from keras.models import load_model 287 model.save('E:/CarvsBike/2103840260_cb.h5') 288 289 #为了尽可能的消除过拟合,我打算进行数据增强 290 #定义ImageDataGenerator参数 291 train_datagen = ImageDataGenerator(rescale=1./255, 292 rotation_range=40, #将图像随机旋转40度 293 width_shift_range=0.2, #在水平方向上平移比例为0.2 294 height_shift_range=0.2, #在垂直方向上平移比例为0.2 295 shear_range=0.2, #随机错切变换的角度为0.2 296 zoom_range=0.2, #图片随机缩放的范围为0.2 297 horizontal_flip=True, #随机将一半图像水平翻转 298 fill_mode='nearest') #填充创建像素 299 300 test_datagen = ImageDataGenerator(rescale=1./255) 301 302 train_generator = train_datagen.flow_from_directory( 303 train_dir, 304 target_size=(150,150), 305 batch_size=32, 306 class_mode='binary' 307 ) 308 309 validation_generator = test_datagen.flow_from_directory( 310 validation_dir, 311 target_size=(150,150), 312 batch_size=32, 313 class_mode='binary') 314 315 #将训练过程产生的数据保存为h5文件 316 from keras.models import load_model 317 model.save('E:/CarvsBike/2103840260.h5') 318 319 #将训练过程产生的数据保存为h5文件 320 from keras.models import load_model 321 model.save('E:/CarvsBike/2103840260_cb.h5') 322 323 import matplotlib.pyplot as plt 324 from PIL import Image 325 import os.path 326 327 def convertjpg(jpgfile,outdir,width=150,height=150): #将图片缩小到(150,150)的大小 328 img=Image.open(jpgfile) 329 try: 330 new_img=img.resize((width,height),Image.BILINEAR) 331 new_img.save(os.path.join(outdir,os.path.basename(new_file))) 332 except Exception as e: 333 print(e) 334 335 jpgfile= "E:/CarvsBike/test/Car (32).jpg" 336 new_file= "E:/CarvsBike/test/new_Car (32).jpg" 337 #图像大小改变到(150,150),文件名保存 338 convertjpg(jpgfile,r"E:/CarvsBike") 339 img_scale = plt.imread('E:/CarvsBike/new_Car (32).jpg') 340 341 plt.imshow(img_scale) #显示改变图像大小后的图片确实变到了(150,150)大小 342 343 # 导入h5模型 344 from keras.models import load_model 345 model = load_model('E:/CarvsBike/2103840260_cb.h5') 346 347 img_scale = img_scale.reshape(1,150,150,3).astype('float32') 348 img_scale = img_scale/255 # 归一化到0-1之间 349 350 result = model.predict(img_scale) # 取图片信息 351 # print(result) 352 if result>0.5: 353 print('是汽车的概率为:',result) 354 else: 355 print('是摩托车的概率为:',1-result)
四、总结 这次的课程设计让我收获颇丰,在完成此设计过程中,我们将所学的知识综合运用起来,巩固了之前学习的知识。课程设计使用的卷积神经网络是深度学习技术中极具代表的网络结构之一, 在图像处理领域取得了很大的成功,也让我对机器学习有了更深层次的理解。但我认为给我留下最为重要的启示,就是做设计的时候遇到困难应及时交流与沟通,在与同学和老师的交流中不断进步。
标签:150,plt,机器,img,CarvsBike,机动车,import,model,识别 From: https://www.cnblogs.com/c-s-t/p/17001920.html