这节采用德国交通标志数据集实现交通标志识别。本节步骤分为数据导入,探索和可视化数据集,数据预处理,交通标志识别模型搭建。
一、加载数据

# 加载数据
import pickle# 数据集所在的文件位置
training_file = "/content/drive/traffic-signs-data/train.p"
validation_file = "/content/drive/traffic-signs-data/valid.p"
testing_file = "/content/drive/traffic-signs-data/test.p"# 打开文件
with open(training_file,mode="rb") as f:train = pickle.load(f)
with open(validation_file,mode="rb") as f:valid = pickle.load(f)
with open(testing_file,mode="rb") as f:test = pickle.load(f)# 获取数据集的特征及标签数据
X_train,y_train = train["features"],train["labels"]
X_valid,y_valid = valid["features"],valid["labels"]
X_test,y_test = test["features"],test["labels"]
# 查看数据量
print("Number of training examples =",X_train.shape[0])
print("Number of validtion examples =",X_valid.shape[0])
print("Number of testing examples=",X_test.shape[0])# 查看数据格式
print("Image data shape =",X_train.shape[1:])
Number of training examples = 34799
Number of validtion examples = 4410
Number of testing examples= 12630
Image data shape = (32, 32, 3)
# 查看数据的标签的数量
import numpy as npsum = np.unique(y_train)
print("number of classes =",len(sum))
number of classes = 43
# 查看标签数据
import pandas as pdsign_names_file = "/content/drive/traffic-signs-data/signnames.csv"
sign_names = pd.read_csv(sign_names_file)
print(sign_names)
    ClassId                                           SignName
0         0                               Speed limit (20km/h)
1         1                               Speed limit (30km/h)
2         2                               Speed limit (50km/h)
3         3                               Speed limit (60km/h)
4         4                               Speed limit (70km/h)
5         5                               Speed limit (80km/h)
6         6                        End of speed limit (80km/h)
7         7                              Speed limit (100km/h)
8         8                              Speed limit (120km/h)
9         9                                         No passing
10       10       No passing for vehicles over 3.5 metric tons
11       11              Right-of-way at the next intersection
12       12                                      Priority road
13       13                                              Yield
14       14                                               Stop
15       15                                        No vehicles
16       16           Vehicles over 3.5 metric tons prohibited
17       17                                           No entry
18       18                                    General caution
19       19                        Dangerous curve to the left
20       20                       Dangerous curve to the right
21       21                                       Double curve
22       22                                         Bumpy road
23       23                                      Slippery road
24       24                          Road narrows on the right
25       25                                          Road work
26       26                                    Traffic signals
27       27                                        Pedestrians
28       28                                  Children crossing
29       29                                  Bicycles crossing
30       30                                 Beware of ice/snow
31       31                              Wild animals crossing
32       32                End of all speed and passing limits
33       33                                   Turn right ahead
34       34                                    Turn left ahead
35       35                                         Ahead only
36       36                               Go straight or right
37       37                                Go straight or left
38       38                                         Keep right
39       39                                          Keep left
40       40                               Roundabout mandatory
41       41                                  End of no passing
42       42  End of no passing by vehicles over 3.5 metric ...
# 定义将标签id转换成name的函数
sign_names = np.array(sign_names)
def id_to_name(id):return sign_names[id][1]
# 验证是否id_to_name函数
id_to_name(0)
'Speed limit (20km/h)'
# 绘制交通标志图
import matplotlib.pyplot as plt
%matplotlib inlinefig,axes = plt.subplots(2,5,figsize=(18,5))
ax_array = axes.ravel()
for ax in ax_array:index = np.random.randint(0,len(X_train))ax.imshow(X_train[index])ax.axis("off")ax.set_title(id_to_name(y_train[index]))
plt.show()

# 直方图来展示图像训练集的各个类别的分布情况
n_classes = len(sum)
def plot_y_train_hist():fig = plt.figure(figsize=(15,5))ax = fig.add_subplot(1,1,1)hist = ax.hist(y_train,bins = n_classes)ax.set_title("the frequency of each category sign")ax.set_xlabel("signs")ax.set_ylabel("frequency")plt.show()return histprint(X_train.shape)
print(y_train.shape)
hist = plot_y_train_hist()
(34799, 32, 32, 3)
(34799,)

# 数据重采样,使样本个数分配均匀
bin_edges = hist[1]
bin_centers = (bin_edges[1:] + bin_edges[0:len(bin_edges)-1])/2
for i in range(len(bin_centers)):if hist[0][i] < 1000:train_data = [X_train[j] for j in range(len(y_train)) if y_train[j] == i]need_resample_num = int(1000 - hist[0][i])new_data_x = [np.copy(train_data[np.random.randint(len(train_data))]) for k in range(need_resample_num)]new_data_y = [i for x in range(need_resample_num)]X_train = np.vstack((X_train, np.array(new_data_x)))y_train = np.hstack((y_train, np.array(new_data_y)))
print(X_train.shape)
print(y_train.shape)
plot_y_train_hist()
(51690, 32, 32, 3)
(51690,)

(array([1000., 1980., 2010., 1260., 1770., 1650., 1000., 1290., 1260.,1320., 1800., 1170., 1890., 1920., 1000., 1000., 1000., 1000.,1080., 1000., 1000., 1000., 1000., 1000., 1000., 1350., 1000.,1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1080.,1000., 1000., 1860., 1000., 1000., 1000., 1000.]),array([ 0.        ,  0.97674419,  1.95348837,  2.93023256,  3.90697674,4.88372093,  5.86046512,  6.8372093 ,  7.81395349,  8.79069767,9.76744186, 10.74418605, 11.72093023, 12.69767442, 13.6744186 ,14.65116279, 15.62790698, 16.60465116, 17.58139535, 18.55813953,19.53488372, 20.51162791, 21.48837209, 22.46511628, 23.44186047,24.41860465, 25.39534884, 26.37209302, 27.34883721, 28.3255814 ,29.30232558, 30.27906977, 31.25581395, 32.23255814, 33.20930233,34.18604651, 35.1627907 , 36.13953488, 37.11627907, 38.09302326,39.06976744, 40.04651163, 41.02325581, 42.        ]),<a list of 43 Patch objects>)

二、数据预处理

# 源图像
src = X_train[4000]
plt.imshow(src)
print(src.shape)
(32, 32, 3)

# 转为灰度图像
import cv2dst = cv2.cvtColor(src,cv2.COLOR_RGB2GRAY)
plt.imshow(dst)
print(dst.shape)
(32, 32)

# 灰度图的直方图
plt.hist(dst.ravel(),256,[0,256],color="r")
plt.show()

# 灰度图的直方图均衡化
dst2 = cv2.equalizeHist(dst)
plt.hist(dst2.ravel(),256,[0,256],color="r")
plt.show()

# 查看直方图均衡化的图片
plt.imshow(dst2)
<matplotlib.image.AxesImage at 0x7f97bb3a86a0>

# 增加维度
print(dst2.shape)
dst3 = np.expand_dims(dst2,2)
print(dst3.shape)
(32, 32)
(32, 32, 1)
# 归一化处理
dst4 = np.array(dst3,dtype=np.float32)
dst4 = (dst4-128)/128
# 查看一下归一化处理后的图像数据
dst4[0]
array([[-0.859375 ],[-0.9609375],[-0.9765625],[-0.9296875],[-0.859375 ],[-0.859375 ],[-0.625    ],[-0.484375 ],[-0.625    ],[-0.625    ],[-0.375    ],[-0.375    ],[-0.2890625],[ 0.171875 ],[ 0.6171875],[ 0.3359375],[-0.1171875],[ 0.171875 ],[ 0.3359375],[ 0.171875 ],[-0.0546875],[ 0.125    ],[ 0.125    ],[ 0.0078125],[ 0.0078125],[ 0.125    ],[-0.1171875],[-0.1875   ],[-0.1875   ],[ 0.0625   ],[ 0.125    ],[ 0.171875 ]], dtype=float32)
# 封装数据预处理的方法
import cv2def preprocess_features(X, equalize_hist=True):normalized_X = []for i in range(len(X)):# Convert from RGB to YUVyuv_img = cv2.cvtColor(X[i], cv2.COLOR_RGB2YUV)yuv_img_v = X[i][:, :, 0]# equalizeHistyuv_img_v = cv2.equalizeHist(yuv_img_v)# expand_disyuv_img_v = np.expand_dims(yuv_img_v, 2)normalized_X.append(yuv_img_v)# normalizenormalized_X = np.array(normalized_X, dtype=np.float32)normalized_X = (normalized_X-128)/128# normalized_X /= (np.std(normalized_X, axis=0) + np.finfo('float32').eps)return normalized_X
# 对数据集整体进行处理
X_train_normalized = preprocess_features(X_train)
X_valid_normalized = preprocess_features(X_valid)
X_test_normalized = preprocess_features(X_test)
# 将数据集打乱
from sklearn.utils import shuffle
X_train_normalized,y_train = shuffle(X_train_normalized,y_train)
# 数据增强
from keras.preprocessing.image import ImageDataGenerator# 图像数据生成器
image_datagen = ImageDataGenerator(rotation_range = 10.,zoom_range = 0.2,width_shift_range =  0.08,height_shift_range = 0.08)# 从训练集随意选取一张图片
index = np.random.randint(0, len(X_train_normalized))
img = X_train_normalized[index]# 展示原始图片
plt.figure(figsize=(1, 1))
plt.imshow(np.squeeze(img), cmap="gray")
plt.title('Example of GRAY image (name = {})'.format(id_to_name(y_train[index])))
plt.axis('off')
plt.show()# 展示数据增强生成的图片
fig, ax_array = plt.subplots(3, 10, figsize=(15, 5))
for ax in ax_array.ravel():images = np.expand_dims(img, 0)# np.expand_dims(img, 0) means add dimaugmented_img, _ = image_datagen.flow(np.expand_dims(img, 0), np.expand_dims(y_train[index], 0)).next()#augmented_img=preprocess_features(augmented_img)ax.imshow(augmented_img.squeeze(), cmap="gray")ax.axis('off')
plt.suptitle('Random examples of data augment (starting from the previous image)')
plt.show()
Using TensorFlow backend.

print("Number of training examples =",X_train.shape[0])
Number of training examples = 51690
# 对标签数据进行one-hot编码
from keras.utils  import np_utils
print("Shape before one-hot encoding:",y_train.shape)
Y_train = np_utils.to_categorical(y_train,n_classes)
Y_valid = np_utils.to_categorical(y_valid,n_classes)
Y_test = np_utils.to_categorical(y_test,n_classes)
print("Shape after one-hot encoding:",Y_train.shape)
Shape before one-hot encoding: (51690,)
Shape after one-hot encoding: (51690, 43)
print(y_train[0])
print(Y_train[0])
24
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

三、交通标志牌的识别模型搭建

1.2层Conv2D+1层MaxPooling2D+1层Drop(0.25)+1层Flatten+1层Dense+1层Dropout层(0.5)+1层Dense

from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2Dmodel = Sequential()
## Feature Extraction
# 第1层卷积,32个3x3的卷积核 ,激活函数使用 relu
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu',input_shape=X_train_normalized.shape[1:]))# 第2层卷积,64个3x3的卷积核,激活函数使用 relu
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))# 最大池化层,池化窗口 2x2
model.add(MaxPooling2D(pool_size=(2, 2)))# Dropout 25% 的输入神经元
model.add(Dropout(0.25))# 将 Pooled feature map 摊平后输入全连接网络
model.add(Flatten())## Classification
# 全联接层
model.add(Dense(128, activation='relu'))# Dropout 50% 的输入神经元
model.add(Dropout(0.5))# 使用 softmax 激活函数做多分类,输出各类别的概率
model.add(Dense(n_classes, activation='softmax'))
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.
Instructions for updating:
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.
# 查看模型的结构
model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_1 (Conv2D)            (None, 30, 30, 32)        320
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 28, 28, 64)        18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 14, 14, 64)        0
_________________________________________________________________
dropout_1 (Dropout)          (None, 14, 14, 64)        0
_________________________________________________________________
flatten_1 (Flatten)          (None, 12544)             0
_________________________________________________________________
dense_1 (Dense)              (None, 128)               1605760
_________________________________________________________________
dropout_2 (Dropout)          (None, 128)               0
_________________________________________________________________
dense_2 (Dense)              (None, 43)                5547
=================================================================
Total params: 1,630,123
Trainable params: 1,630,123
Non-trainable params: 0
_________________________________________________________________
# 编译模型
model.compile(loss="categorical_crossentropy",metrics=["accuracy"],optimizer="adam")
# 训练模型
history = model.fit(X_train_normalized,Y_train,batch_size=256,epochs=120,verbose=2,validation_data=(X_valid_normalized,Y_valid))
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
Train on 51690 samples, validate on 4410 samples
Epoch 1/120- 7s - loss: 1.2242 - acc: 0.6591 - val_loss: 0.3351 - val_acc: 0.8957
Epoch 2/120- 4s - loss: 0.2724 - acc: 0.9174 - val_loss: 0.2139 - val_acc: 0.9370
Epoch 3/120- 4s - loss: 0.1670 - acc: 0.9492 - val_loss: 0.1646 - val_acc: 0.9490
Epoch 4/120- 4s - loss: 0.1190 - acc: 0.9622 - val_loss: 0.1639 - val_acc: 0.9467
Epoch 5/120- 4s - loss: 0.0910 - acc: 0.9709 - val_loss: 0.1620 - val_acc: 0.9537
Epoch 6/120- 4s - loss: 0.0770 - acc: 0.9752 - val_loss: 0.1439 - val_acc: 0.9585
Epoch 7/120- 4s - loss: 0.0656 - acc: 0.9795 - val_loss: 0.1304 - val_acc: 0.9587
Epoch 8/120- 4s - loss: 0.0572 - acc: 0.9809 - val_loss: 0.1411 - val_acc: 0.9601
Epoch 9/120- 4s - loss: 0.0514 - acc: 0.9835 - val_loss: 0.1529 - val_acc: 0.9562
Epoch 10/120- 4s - loss: 0.0473 - acc: 0.9847 - val_loss: 0.1166 - val_acc: 0.9642
Epoch 11/120- 4s - loss: 0.0427 - acc: 0.9863 - val_loss: 0.1336 - val_acc: 0.9619
Epoch 12/120- 4s - loss: 0.0371 - acc: 0.9879 - val_loss: 0.1309 - val_acc: 0.9635
Epoch 13/120- 4s - loss: 0.0380 - acc: 0.9874 - val_loss: 0.1194 - val_acc: 0.9685
Epoch 14/120- 4s - loss: 0.0315 - acc: 0.9898 - val_loss: 0.1403 - val_acc: 0.9633
Epoch 15/120- 4s - loss: 0.0328 - acc: 0.9889 - val_loss: 0.1469 - val_acc: 0.9574
Epoch 16/120- 4s - loss: 0.0292 - acc: 0.9903 - val_loss: 0.1241 - val_acc: 0.9689
Epoch 17/120- 4s - loss: 0.0291 - acc: 0.9903 - val_loss: 0.1307 - val_acc: 0.9673
Epoch 18/120- 4s - loss: 0.0265 - acc: 0.9910 - val_loss: 0.1434 - val_acc: 0.9651
Epoch 19/120- 4s - loss: 0.0259 - acc: 0.9914 - val_loss: 0.1291 - val_acc: 0.9680
Epoch 20/120- 4s - loss: 0.0246 - acc: 0.9916 - val_loss: 0.1332 - val_acc: 0.9635
Epoch 21/120- 4s - loss: 0.0231 - acc: 0.9922 - val_loss: 0.1261 - val_acc: 0.9671
Epoch 22/120- 4s - loss: 0.0232 - acc: 0.9923 - val_loss: 0.1301 - val_acc: 0.9680
Epoch 23/120- 4s - loss: 0.0198 - acc: 0.9932 - val_loss: 0.1388 - val_acc: 0.9669
Epoch 24/120- 4s - loss: 0.0226 - acc: 0.9923 - val_loss: 0.1210 - val_acc: 0.9719
Epoch 25/120- 4s - loss: 0.0212 - acc: 0.9930 - val_loss: 0.1297 - val_acc: 0.9683
Epoch 26/120- 4s - loss: 0.0206 - acc: 0.9932 - val_loss: 0.1344 - val_acc: 0.9687
Epoch 27/120- 4s - loss: 0.0203 - acc: 0.9932 - val_loss: 0.1495 - val_acc: 0.9692
Epoch 28/120- 4s - loss: 0.0200 - acc: 0.9935 - val_loss: 0.1305 - val_acc: 0.9696
Epoch 29/120- 4s - loss: 0.0181 - acc: 0.9938 - val_loss: 0.1436 - val_acc: 0.9685
Epoch 30/120- 4s - loss: 0.0167 - acc: 0.9944 - val_loss: 0.1377 - val_acc: 0.9673- 7s - loss: 0.0072 - acc: 0.9977 - val_loss: 0.1146 - val_acc: 0.9823
Epoch 111/120- 7s - loss: 0.0059 - acc: 0.9981 - val_loss: 0.1531 - val_acc: 0.9741
Epoch 112/120- 7s - loss: 0.0065 - acc: 0.9977 - val_loss: 0.1157 - val_acc: 0.9805
Epoch 113/120- 7s - loss: 0.0061 - acc: 0.9980 - val_loss: 0.1638 - val_acc: 0.9717
Epoch 114/120- 7s - loss: 0.0055 - acc: 0.9983 - val_loss: 0.1301 - val_acc: 0.9794
Epoch 115/120- 7s - loss: 0.0041 - acc: 0.9985 - val_loss: 0.1501 - val_acc: 0.9773
Epoch 116/120- 5s - loss: 0.0066 - acc: 0.9976 - val_loss: 0.1437 - val_acc: 0.9757
Epoch 117/120- 4s - loss: 0.0064 - acc: 0.9979 - val_loss: 0.1508 - val_acc: 0.9780
Epoch 118/120- 4s - loss: 0.0066 - acc: 0.9978 - val_loss: 0.1489 - val_acc: 0.9769
Epoch 119/120- 4s - loss: 0.0065 - acc: 0.9980 - val_loss: 0.1378 - val_acc: 0.9766
Epoch 120/120- 4s - loss: 0.0059 - acc: 0.9982 - val_loss: 0.1255 - val_acc: 0.9789
# 可视化指标
fig = plt.figure()
plt.subplot(2,1,1)
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model Accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='lower right')plt.subplot(2,1,2)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model Loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper right')
plt.tight_layout()plt.show()

# 保存模型
import os
import tensorflow.gfile as gfilesave_dir = "/content/drive/model/v1/"if gfile.Exists(save_dir):gfile.DeleteRecursively(save_dir)
gfile.MakeDirs(save_dir)model_name = 'keras_traffic_1.h5'
model_path = os.path.join(save_dir, model_name)
model.save(model_path)
print('Saved trained model at %s ' % model_path)
Saved trained model at /content/drive/model/v1/keras_traffic_1.h5
# 加载模型
from keras.models import load_modeltraffic_model = load_model(model_path)
# 统计模型在测试集上的分类结果
loss_and_metrics = traffic_model.evaluate(X_test_normalized, Y_test, verbose=2,batch_size=256)print("Test Loss: {}".format(loss_and_metrics[0]))
print("Test Accuracy: {}%".format(loss_and_metrics[1]*100))predicted_classes = traffic_model.predict_classes(X_test_normalized)correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
print("Classified correctly count: {}".format(len(correct_indices)))
print("Classified incorrectly count: {}".format(len(incorrect_indices)))
Test Loss: 0.22923571624080058
Test Accuracy: 96.88836103380434%
Classified correctly count: 12237
Classified incorrectly count: 393

2.3层Con2D MaxPooling2D+1层Flatten层+2层Dense

from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPooling2Dmodel2 = Sequential()# layers1
model2.add(Conv2D(filters=32,kernel_size=(3,3),input_shape=X_train_normalized.shape[1:],activation="relu"))
model2.add(MaxPooling2D(pool_size=(2,2)))# layers2
model2.add(Conv2D(filters=64,kernel_size=(3,3),activation="relu"))
model2.add(MaxPooling2D(pool_size=(2,2)))# layers3
model2.add(Conv2D(filters=64,kernel_size=(3,3),activation="relu"))
model2.add(MaxPooling2D(pool_size=(2,2)))# flattern
model2.add(Flatten())# Dense
model2.add(Dense(512,activation="relu"))# Dense
model2.add(Dense(n_classes,activation="softmax"))
# 查看模型的结构
model2.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_3 (Conv2D)            (None, 30, 30, 32)        320
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 15, 15, 32)        0
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 13, 13, 64)        18496
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 6, 6, 64)          0
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 4, 4, 64)          36928
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 2, 2, 64)          0
_________________________________________________________________
flatten_2 (Flatten)          (None, 256)               0
_________________________________________________________________
dense_3 (Dense)              (None, 512)               131584
_________________________________________________________________
dense_4 (Dense)              (None, 43)                22059
=================================================================
Total params: 209,387
Trainable params: 209,387
Non-trainable params: 0
_________________________________________________________________
# 编译模型
model2.compile(loss="categorical_crossentropy",metrics=["accuracy"],optimizer="adam")
# 训练模型
history2 = model2.fit(X_train_normalized,Y_train,batch_size=256,epochs=120,verbose=2,validation_data=(X_valid_normalized,Y_valid))
Train on 51690 samples, validate on 4410 samples
Epoch 1/120- 2s - loss: 1.3340 - acc: 0.6319 - val_loss: 0.6667 - val_acc: 0.8041
Epoch 2/120- 2s - loss: 0.2375 - acc: 0.9308 - val_loss: 0.4388 - val_acc: 0.8762
Epoch 3/120- 2s - loss: 0.1122 - acc: 0.9669 - val_loss: 0.3823 - val_acc: 0.8964
Epoch 4/120- 2s - loss: 0.0769 - acc: 0.9775 - val_loss: 0.3509 - val_acc: 0.9036
Epoch 5/120- 2s - loss: 0.0508 - acc: 0.9857 - val_loss: 0.3434 - val_acc: 0.9088
Epoch 6/120- 2s - loss: 0.0420 - acc: 0.9874 - val_loss: 0.3413 - val_acc: 0.9204
Epoch 7/120- 2s - loss: 0.0297 - acc: 0.9912 - val_loss: 0.3266 - val_acc: 0.9243
Epoch 8/120- 2s - loss: 0.0198 - acc: 0.9943 - val_loss: 0.3150 - val_acc: 0.9256
Epoch 9/120- 2s - loss: 0.0205 - acc: 0.9940 - val_loss: 0.3463 - val_acc: 0.9200
Epoch 10/120- 2s - loss: 0.0174 - acc: 0.9947 - val_loss: 0.3045 - val_acc: 0.9236
Epoch 11/120- 2s - loss: 0.0194 - acc: 0.9943 - val_loss: 0.3561 - val_acc: 0.9184
Epoch 12/120- 2s - loss: 0.0109 - acc: 0.9968 - val_loss: 0.3475 - val_acc: 0.9259
Epoch 13/120- 2s - loss: 0.0116 - acc: 0.9964 - val_loss: 0.3646 - val_acc: 0.9270
Epoch 14/120- 2s - loss: 0.0127 - acc: 0.9958 - val_loss: 0.3486 - val_acc: 0.9295
Epoch 15/120- 2s - loss: 0.0090 - acc: 0.9975 - val_loss: 0.3234 - val_acc: 0.9297
Epoch 16/120- 2s - loss: 0.0118 - acc: 0.9962 - val_loss: 0.4056 - val_acc: 0.9236
Epoch 17/120- 2s - loss: 0.0082 - acc: 0.9976 - val_loss: 0.3282 - val_acc: 0.9345
Epoch 18/120- 2s - loss: 0.0066 - acc: 0.9982 - val_loss: 0.3327 - val_acc: 0.9381
Epoch 19/120- 2s - loss: 0.0089 - acc: 0.9971 - val_loss: 0.3708 - val_acc: 0.9338
Epoch 20/120- 2s - loss: 0.0109 - acc: 0.9967 - val_loss: 0.3011 - val_acc: 0.9397
Epoch 21/120- 2s - loss: 0.0030 - acc: 0.9993 - val_loss: 0.3431 - val_acc: 0.9406
Epoch 22/120- 2s - loss: 0.0121 - acc: 0.9965 - val_loss: 0.3113 - val_acc: 0.9413
Epoch 23/120- 2s - loss: 0.0068 - acc: 0.9981 - val_loss: 0.3195 - val_acc: 0.9431
Epoch 24/120- 2s - loss: 0.0021 - acc: 0.9995 - val_loss: 0.3079 - val_acc: 0.9447
Epoch 25/120- 2s - loss: 0.0080 - acc: 0.9973 - val_loss: 0.2953 - val_acc: 0.9408
Epoch 26/120- 2s - loss: 0.0086 - acc: 0.9971 - val_loss: 0.3595 - val_acc: 0.9315
Epoch 27/120- 2s - loss: 0.0105 - acc: 0.9967 - val_loss: 0.3286 - val_acc: 0.9342
Epoch 28/120- 2s - loss: 0.0039 - acc: 0.9990 - val_loss: 0.3357 - val_acc: 0.9363
Epoch 29/120- 2s - loss: 0.0038 - acc: 0.9992 - val_loss: 0.2930 - val_acc: 0.9440
Epoch 30/120- 2s - loss: 0.0053 - acc: 0.9985 - val_loss: 0.2465 - val_acc: 0.9537Epoch 110/120- 2s - loss: 6.2377e-04 - acc: 1.0000 - val_loss: 0.4051 - val_acc: 0.9519
Epoch 111/120- 2s - loss: 6.2377e-04 - acc: 1.0000 - val_loss: 0.4071 - val_acc: 0.9524
Epoch 112/120- 2s - loss: 6.2377e-04 - acc: 1.0000 - val_loss: 0.4111 - val_acc: 0.9524
Epoch 113/120- 2s - loss: 6.2377e-04 - acc: 1.0000 - val_loss: 0.4106 - val_acc: 0.9524
Epoch 114/120- 2s - loss: 6.2377e-04 - acc: 1.0000 - val_loss: 0.4115 - val_acc: 0.9522
Epoch 115/120- 2s - loss: 6.2377e-04 - acc: 1.0000 - val_loss: 0.4134 - val_acc: 0.9519
Epoch 116/120- 2s - loss: 6.2377e-04 - acc: 1.0000 - val_loss: 0.4157 - val_acc: 0.9510
Epoch 117/120- 2s - loss: 6.2377e-04 - acc: 1.0000 - val_loss: 0.4181 - val_acc: 0.9515
Epoch 118/120- 2s - loss: 6.2376e-04 - acc: 1.0000 - val_loss: 0.4188 - val_acc: 0.9517
Epoch 119/120- 2s - loss: 6.2376e-04 - acc: 1.0000 - val_loss: 0.4199 - val_acc: 0.9517
Epoch 120/120- 2s - loss: 6.2376e-04 - acc: 1.0000 - val_loss: 0.4196 - val_acc: 0.9510
# 可视化指标
fig = plt.figure()
plt.subplot(2,1,1)
plt.plot(history2.history['acc'])
plt.plot(history2.history['val_acc'])
plt.title('Model Accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='lower right')plt.subplot(2,1,2)
plt.plot(history2.history['loss'])
plt.plot(history2.history['val_loss'])
plt.title('Model Loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper right')
plt.tight_layout()plt.show()

# 保存模型
import os
import tensorflow.gfile as gfilesave_dir = "/content/drive/model/v2/"if gfile.Exists(save_dir):gfile.DeleteRecursively(save_dir)
gfile.MakeDirs(save_dir)model_name = 'keras_traffic_2.h5'
model_path = os.path.join(save_dir, model_name)model2.save(model_path)
print('Saved trained model at %s ' % model_path)
Saved trained model at /content/drive/model/v2/keras_traffic_2.h5
# 加载模型
from keras.models import load_modeltraffic_model = load_model(model_path)
# 统计模型在测试集上的分类结果
loss_and_metrics = traffic_model.evaluate(X_test_normalized, Y_test, verbose=2,batch_size=256)print("Test Loss: {}".format(loss_and_metrics[0]))
print("Test Accuracy: {}%".format(loss_and_metrics[1]*100))predicted_classes = traffic_model.predict_classes(X_test_normalized)correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
print("Classified correctly count: {}".format(len(correct_indices)))
print("Classified incorrectly count: {}".format(len(incorrect_indices)))
Test Loss: 0.6938359957692742
Test Accuracy: 93.08788600368152%
Classified correctly count: 11757
Classified incorrectly count: 873

3.对上述模型进行改进 增加2层Dropout层

from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPooling2Dmodel3 = Sequential()# layers1
model3.add(Conv2D(filters=32,kernel_size=(3,3),input_shape=X_train_normalized.shape[1:],activation="relu"))
model3.add(MaxPooling2D(pool_size=(2,2)))# layers2
model3.add(Conv2D(filters=64,kernel_size=(3,3),activation="relu"))
model3.add(MaxPooling2D(pool_size=(2,2)))# Dropout
model3.add(Dropout(0.25))# layers3
model3.add(Conv2D(filters=64,kernel_size=(3,3),activation="relu"))
model3.add(MaxPooling2D(pool_size=(2,2)))# flattern
model3.add(Flatten())# Dense
model3.add(Dense(512,activation="relu"))# Dropout
model3.add(Dropout(0.5))# Dense
model3.add(Dense(n_classes,activation="softmax"))
model3.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_6 (Conv2D)            (None, 30, 30, 32)        320
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 15, 15, 32)        0
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 13, 13, 64)        18496
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 6, 6, 64)          0
_________________________________________________________________
dropout_3 (Dropout)          (None, 6, 6, 64)          0
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 4, 4, 64)          36928
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 2, 2, 64)          0
_________________________________________________________________
flatten_3 (Flatten)          (None, 256)               0
_________________________________________________________________
dense_5 (Dense)              (None, 512)               131584
_________________________________________________________________
dropout_4 (Dropout)          (None, 512)               0
_________________________________________________________________
dense_6 (Dense)              (None, 43)                22059
=================================================================
Total params: 209,387
Trainable params: 209,387
Non-trainable params: 0
_________________________________________________________________
# 编译模型
model3.compile(loss="categorical_crossentropy",metrics=["accuracy"],optimizer="adam")
# 训练模型
history3 = model3.fit(X_train_normalized,Y_train,batch_size=256,epochs=120,verbose=2,validation_data=(X_valid_normalized,Y_valid))
Train on 51690 samples, validate on 4410 samples
Epoch 1/120- 2s - loss: 1.8536 - acc: 0.4729 - val_loss: 0.6255 - val_acc: 0.8197
Epoch 2/120- 2s - loss: 0.4513 - acc: 0.8609 - val_loss: 0.3030 - val_acc: 0.9082
Epoch 3/120- 2s - loss: 0.2391 - acc: 0.9261 - val_loss: 0.2413 - val_acc: 0.9272
Epoch 4/120- 2s - loss: 0.1676 - acc: 0.9480 - val_loss: 0.2010 - val_acc: 0.9401
Epoch 5/120- 2s - loss: 0.1248 - acc: 0.9610 - val_loss: 0.1635 - val_acc: 0.9519
Epoch 6/120- 2s - loss: 0.1006 - acc: 0.9692 - val_loss: 0.1346 - val_acc: 0.9619
Epoch 7/120- 2s - loss: 0.0848 - acc: 0.9736 - val_loss: 0.1464 - val_acc: 0.9553
Epoch 8/120- 2s - loss: 0.0731 - acc: 0.9765 - val_loss: 0.1513 - val_acc: 0.9526
Epoch 9/120- 2s - loss: 0.0664 - acc: 0.9785 - val_loss: 0.1365 - val_acc: 0.9580
Epoch 10/120- 2s - loss: 0.0590 - acc: 0.9810 - val_loss: 0.1404 - val_acc: 0.9553
Epoch 11/120- 2s - loss: 0.0493 - acc: 0.9838 - val_loss: 0.1258 - val_acc: 0.9646
Epoch 12/120- 2s - loss: 0.0446 - acc: 0.9859 - val_loss: 0.1265 - val_acc: 0.9642
Epoch 13/120- 2s - loss: 0.0389 - acc: 0.9874 - val_loss: 0.1258 - val_acc: 0.9678
Epoch 14/120- 2s - loss: 0.0385 - acc: 0.9872 - val_loss: 0.1220 - val_acc: 0.9669
Epoch 15/120- 2s - loss: 0.0348 - acc: 0.9889 - val_loss: 0.1200 - val_acc: 0.9662
Epoch 16/120- 2s - loss: 0.0354 - acc: 0.9883 - val_loss: 0.0980 - val_acc: 0.9728
Epoch 17/120- 2s - loss: 0.0316 - acc: 0.9897 - val_loss: 0.1222 - val_acc: 0.9680
Epoch 18/120- 2s - loss: 0.0280 - acc: 0.9909 - val_loss: 0.1069 - val_acc: 0.9703
Epoch 19/120- 2s - loss: 0.0285 - acc: 0.9911 - val_loss: 0.1080 - val_acc: 0.9703
Epoch 20/120- 2s - loss: 0.0240 - acc: 0.9915 - val_loss: 0.1049 - val_acc: 0.9714
Epoch 21/120- 2s - loss: 0.0248 - acc: 0.9921 - val_loss: 0.1137 - val_acc: 0.9703
Epoch 22/120- 2s - loss: 0.0248 - acc: 0.9922 - val_loss: 0.0974 - val_acc: 0.9728
Epoch 23/120- 2s - loss: 0.0213 - acc: 0.9930 - val_loss: 0.1277 - val_acc: 0.9633
Epoch 24/120- 2s - loss: 0.0232 - acc: 0.9924 - val_loss: 0.0980 - val_acc: 0.9751
Epoch 25/120- 2s - loss: 0.0208 - acc: 0.9932 - val_loss: 0.1124 - val_acc: 0.9739
Epoch 26/120- 2s - loss: 0.0183 - acc: 0.9939 - val_loss: 0.1076 - val_acc: 0.9726
Epoch 27/120- 2s - loss: 0.0205 - acc: 0.9928 - val_loss: 0.0998 - val_acc: 0.9735
Epoch 28/120- 2s - loss: 0.0167 - acc: 0.9944 - val_loss: 0.1231 - val_acc: 0.9701
Epoch 29/120- 2s - loss: 0.0188 - acc: 0.9940 - val_loss: 0.1025 - val_acc: 0.9737
Epoch 30/120- 2s - loss: 0.0164 - acc: 0.9947 - val_loss: 0.1189 - val_acc: 0.9701Epoch 110/120- 2s - loss: 0.0069 - acc: 0.9980 - val_loss: 0.0982 - val_acc: 0.9805
Epoch 111/120- 2s - loss: 0.0086 - acc: 0.9976 - val_loss: 0.0940 - val_acc: 0.9816
Epoch 112/120- 2s - loss: 0.0057 - acc: 0.9982 - val_loss: 0.0958 - val_acc: 0.9807
Epoch 113/120- 2s - loss: 0.0066 - acc: 0.9981 - val_loss: 0.1343 - val_acc: 0.9780
Epoch 114/120- 2s - loss: 0.0059 - acc: 0.9982 - val_loss: 0.1218 - val_acc: 0.9796
Epoch 115/120- 2s - loss: 0.0074 - acc: 0.9979 - val_loss: 0.1266 - val_acc: 0.9771
Epoch 116/120- 2s - loss: 0.0063 - acc: 0.9981 - val_loss: 0.1001 - val_acc: 0.9819
Epoch 117/120- 2s - loss: 0.0063 - acc: 0.9980 - val_loss: 0.0945 - val_acc: 0.9819
Epoch 118/120- 2s - loss: 0.0082 - acc: 0.9976 - val_loss: 0.1334 - val_acc: 0.9751
Epoch 119/120- 2s - loss: 0.0073 - acc: 0.9976 - val_loss: 0.1341 - val_acc: 0.9735
Epoch 120/120- 2s - loss: 0.0072 - acc: 0.9977 - val_loss: 0.1004 - val_acc: 0.9794
# 可视化指标
fig = plt.figure()
plt.subplot(2,1,1)
plt.plot(history3.history['acc'])
plt.plot(history3.history['val_acc'])
plt.title('Model Accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='lower right')plt.subplot(2,1,2)
plt.plot(history3.history['loss'])
plt.plot(history3.history['val_loss'])
plt.title('Model Loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper right')
plt.tight_layout()plt.show()

# 保存模型
import os
import tensorflow.gfile as gfilesave_dir = "/content/drive/model/v3/"if gfile.Exists(save_dir):gfile.DeleteRecursively(save_dir)
gfile.MakeDirs(save_dir)model_name = 'keras_traffic_3.h5'
model_path = os.path.join(save_dir, model_name)model3.save(model_path)
print('Saved trained model at %s ' % model_path)
Saved trained model at /content/drive/model/v3/keras_traffic_3.h5
# 加载模型
from keras.models import load_modeltraffic_model = load_model(model_path)
# 统计模型在测试集上的分类结果
loss_and_metrics = traffic_model.evaluate(X_test_normalized, Y_test, verbose=2,batch_size=256)print("Test Loss: {}".format(loss_and_metrics[0]))
print("Test Accuracy: {}%".format(loss_and_metrics[1]*100))predicted_classes = traffic_model.predict_classes(X_test_normalized)correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
print("Classified correctly count: {}".format(len(correct_indices)))
print("Classified incorrectly count: {}".format(len(incorrect_indices)))
Test Loss: 0.2989197100426409
Test Accuracy: 95.88281867056732%
Classified correctly count: 12110
Classified incorrectly count: 520

4.2层卷积池化层+1层展开层+3层全连接层

from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPooling2Dmodel4 = Sequential()# layers1
model4.add(Conv2D(filters=32,kernel_size=(3,3),input_shape=X_train_normalized.shape[1:],activation="relu"))
model4.add(MaxPooling2D(pool_size=(2,2)))# layers2
model4.add(Conv2D(filters=64,kernel_size=(3,3),activation="relu"))
model4.add(MaxPooling2D(pool_size=(2,2)))# flattern
model4.add(Flatten())# Dense
model4.add(Dense(512,activation="relu"))# Dense
model4.add(Dense(100,activation="relu"))# Dense
model4.add(Dense(n_classes,activation="softmax"))
# 查看模型的结构
model4.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_9 (Conv2D)            (None, 30, 30, 32)        320
_________________________________________________________________
max_pooling2d_8 (MaxPooling2 (None, 15, 15, 32)        0
_________________________________________________________________
conv2d_10 (Conv2D)           (None, 13, 13, 64)        18496
_________________________________________________________________
max_pooling2d_9 (MaxPooling2 (None, 6, 6, 64)          0
_________________________________________________________________
flatten_4 (Flatten)          (None, 2304)              0
_________________________________________________________________
dense_7 (Dense)              (None, 512)               1180160
_________________________________________________________________
dense_8 (Dense)              (None, 100)               51300
_________________________________________________________________
dense_9 (Dense)              (None, 43)                4343
=================================================================
Total params: 1,254,619
Trainable params: 1,254,619
Non-trainable params: 0
_________________________________________________________________
# 编译模型
model4.compile(loss="categorical_crossentropy",metrics=["accuracy"],optimizer="adam")
# 训练模型
history4 = model4.fit(X_train_normalized,Y_train,batch_size=256,epochs=120,verbose=2,validation_data=(X_valid_normalized,Y_valid))
Train on 51690 samples, validate on 4410 samples
Epoch 1/120- 3s - loss: 0.9466 - acc: 0.7433 - val_loss: 0.4214 - val_acc: 0.8746
Epoch 2/120- 2s - loss: 0.1339 - acc: 0.9632 - val_loss: 0.3042 - val_acc: 0.9152
Epoch 3/120- 2s - loss: 0.0681 - acc: 0.9809 - val_loss: 0.2988 - val_acc: 0.9170
Epoch 4/120- 2s - loss: 0.0414 - acc: 0.9885 - val_loss: 0.3027 - val_acc: 0.9125
Epoch 5/120- 2s - loss: 0.0244 - acc: 0.9934 - val_loss: 0.2754 - val_acc: 0.9308
Epoch 6/120- 2s - loss: 0.0198 - acc: 0.9944 - val_loss: 0.2664 - val_acc: 0.9299
Epoch 7/120- 2s - loss: 0.0139 - acc: 0.9963 - val_loss: 0.3340 - val_acc: 0.9197
Epoch 8/120- 2s - loss: 0.0150 - acc: 0.9958 - val_loss: 0.2918 - val_acc: 0.9336
Epoch 9/120- 2s - loss: 0.0166 - acc: 0.9948 - val_loss: 0.2496 - val_acc: 0.9399
Epoch 10/120- 2s - loss: 0.0070 - acc: 0.9979 - val_loss: 0.2661 - val_acc: 0.9365
Epoch 11/120- 2s - loss: 0.0060 - acc: 0.9984 - val_loss: 0.3019 - val_acc: 0.9290
Epoch 12/120- 2s - loss: 0.0063 - acc: 0.9984 - val_loss: 0.2890 - val_acc: 0.9347
Epoch 13/120- 2s - loss: 0.0076 - acc: 0.9979 - val_loss: 0.2583 - val_acc: 0.9363
Epoch 14/120- 2s - loss: 0.0124 - acc: 0.9962 - val_loss: 0.3169 - val_acc: 0.9240
Epoch 15/120- 2s - loss: 0.0097 - acc: 0.9970 - val_loss: 0.2796 - val_acc: 0.9429
Epoch 16/120- 2s - loss: 0.0088 - acc: 0.9975 - val_loss: 0.3084 - val_acc: 0.9320
Epoch 17/120- 2s - loss: 0.0093 - acc: 0.9972 - val_loss: 0.3469 - val_acc: 0.9281
Epoch 18/120- 2s - loss: 0.0029 - acc: 0.9991 - val_loss: 0.2834 - val_acc: 0.9388
Epoch 19/120- 2s - loss: 9.1336e-04 - acc: 0.9998 - val_loss: 0.2210 - val_acc: 0.9535
Epoch 20/120- 2s - loss: 3.3410e-04 - acc: 0.9999 - val_loss: 0.2416 - val_acc: 0.9546
Epoch 21/120- 2s - loss: 4.8947e-05 - acc: 1.0000 - val_loss: 0.2395 - val_acc: 0.9556
Epoch 22/120- 2s - loss: 2.7690e-05 - acc: 1.0000 - val_loss: 0.2449 - val_acc: 0.9556
Epoch 23/120- 2s - loss: 2.0403e-05 - acc: 1.0000 - val_loss: 0.2481 - val_acc: 0.9556
Epoch 24/120- 2s - loss: 1.6893e-05 - acc: 1.0000 - val_loss: 0.2507 - val_acc: 0.9553
Epoch 25/120- 2s - loss: 1.4042e-05 - acc: 1.0000 - val_loss: 0.2534 - val_acc: 0.9553
Epoch 26/120- 2s - loss: 1.2080e-05 - acc: 1.0000 - val_loss: 0.2556 - val_acc: 0.9556
Epoch 27/120- 2s - loss: 1.0456e-05 - acc: 1.0000 - val_loss: 0.2577 - val_acc: 0.9551
Epoch 28/120- 2s - loss: 9.1271e-06 - acc: 1.0000 - val_loss: 0.2589 - val_acc: 0.9560
Epoch 29/120- 2s - loss: 8.0037e-06 - acc: 1.0000 - val_loss: 0.2610 - val_acc: 0.9549
Epoch 30/120- 2s - loss: 7.1773e-06 - acc: 1.0000 - val_loss: 0.2630 - val_acc: 0.9560Epoch 110/120- 2s - loss: 1.2023e-07 - acc: 1.0000 - val_loss: 0.3727 - val_acc: 0.9533
Epoch 111/120- 2s - loss: 1.2010e-07 - acc: 1.0000 - val_loss: 0.3727 - val_acc: 0.9537
Epoch 112/120- 2s - loss: 1.1994e-07 - acc: 1.0000 - val_loss: 0.3716 - val_acc: 0.9535
Epoch 113/120- 2s - loss: 1.1984e-07 - acc: 1.0000 - val_loss: 0.3747 - val_acc: 0.9535
Epoch 114/120- 2s - loss: 1.1972e-07 - acc: 1.0000 - val_loss: 0.3758 - val_acc: 0.9535
Epoch 115/120- 2s - loss: 1.1968e-07 - acc: 1.0000 - val_loss: 0.3763 - val_acc: 0.9533
Epoch 116/120- 2s - loss: 1.1957e-07 - acc: 1.0000 - val_loss: 0.3789 - val_acc: 0.9528
Epoch 117/120- 2s - loss: 1.1953e-07 - acc: 1.0000 - val_loss: 0.3783 - val_acc: 0.9531
Epoch 118/120- 2s - loss: 1.1947e-07 - acc: 1.0000 - val_loss: 0.3796 - val_acc: 0.9528
Epoch 119/120- 2s - loss: 1.1943e-07 - acc: 1.0000 - val_loss: 0.3805 - val_acc: 0.9535
Epoch 120/120- 2s - loss: 1.1942e-07 - acc: 1.0000 - val_loss: 0.3811 - val_acc: 0.9533
# 可视化指标
fig = plt.figure()
plt.subplot(2,1,1)
plt.plot(history4.history['acc'])
plt.plot(history4.history['val_acc'])
plt.title('Model Accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='lower right')plt.subplot(2,1,2)
plt.plot(history4.history['loss'])
plt.plot(history4.history['val_loss'])
plt.title('Model Loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper right')
plt.tight_layout()plt.show()

# 保存模型
import os
import tensorflow.gfile as gfilesave_dir = "/content/drive/model/v4/"if gfile.Exists(save_dir):gfile.DeleteRecursively(save_dir)
gfile.MakeDirs(save_dir)model_name = 'keras_traffic_4.h5'
model_path = os.path.join(save_dir, model_name)model4.save(model_path)
print('Saved trained model at %s ' % model_path)
Saved trained model at /content/drive/model/v4/keras_traffic_4.h5
# 加载模型
from keras.models import load_modeltraffic_model = load_model(model_path)
# 统计模型在测试集上的分类结果
loss_and_metrics = traffic_model.evaluate(X_test_normalized, Y_test, verbose=2,batch_size=256)print("Test Loss: {}".format(loss_and_metrics[0]))
print("Test Accuracy: {}%".format(loss_and_metrics[1]*100))predicted_classes = traffic_model.predict_classes(X_test_normalized)correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
print("Classified correctly count: {}".format(len(correct_indices)))
print("Classified incorrectly count: {}".format(len(incorrect_indices)))
Test Loss: 0.61759698928016
Test Accuracy: 93.18289788016608%
Classified correctly count: 11769
Classified incorrectly count: 861

5.对上述模型进行改进增加3层Dropout层

# 改进模型
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPooling2Dmodel5 = Sequential()# layers1
model5.add(Conv2D(filters=32,kernel_size=(3,3),input_shape=X_train_normalized.shape[1:],activation="relu"))
model5.add(MaxPooling2D(pool_size=(2,2)))# layers2
model5.add(Conv2D(filters=64,kernel_size=(3,3),activation="relu"))
model5.add(MaxPooling2D(pool_size=(2,2)))# Dropout
model5.add(Dropout(0.5))# flattern
model5.add(Flatten())# Dense
model5.add(Dense(512,activation="relu"))# Dropout
model5.add(Dropout(0.5))# Dense
model5.add(Dense(100,activation="relu"))# Dropout
model5.add(Dropout(0.5))# Dense
model5.add(Dense(n_classes,activation="softmax"))
model5.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_11 (Conv2D)           (None, 30, 30, 32)        320
_________________________________________________________________
max_pooling2d_10 (MaxPooling (None, 15, 15, 32)        0
_________________________________________________________________
conv2d_12 (Conv2D)           (None, 13, 13, 64)        18496
_________________________________________________________________
max_pooling2d_11 (MaxPooling (None, 6, 6, 64)          0
_________________________________________________________________
dropout_5 (Dropout)          (None, 6, 6, 64)          0
_________________________________________________________________
flatten_5 (Flatten)          (None, 2304)              0
_________________________________________________________________
dense_10 (Dense)             (None, 512)               1180160
_________________________________________________________________
dropout_6 (Dropout)          (None, 512)               0
_________________________________________________________________
dense_11 (Dense)             (None, 100)               51300
_________________________________________________________________
dropout_7 (Dropout)          (None, 100)               0
_________________________________________________________________
dense_12 (Dense)             (None, 43)                4343
=================================================================
Total params: 1,254,619
Trainable params: 1,254,619
Non-trainable params: 0
_________________________________________________________________
# 编译模型
model5.compile(loss="categorical_crossentropy",metrics=["accuracy"],optimizer="adam")
# 训练模型
history5 = model5.fit(X_train_normalized,Y_train,batch_size=256,epochs=120,verbose=2,validation_data=(X_valid_normalized,Y_valid))                    
Train on 51690 samples, validate on 4410 samples
Epoch 1/120- 3s - loss: 2.0740 - acc: 0.4183 - val_loss: 0.5267 - val_acc: 0.8590
Epoch 2/120- 2s - loss: 0.5917 - acc: 0.8149 - val_loss: 0.2372 - val_acc: 0.9395
Epoch 3/120- 2s - loss: 0.3512 - acc: 0.8919 - val_loss: 0.1723 - val_acc: 0.9508
Epoch 4/120- 2s - loss: 0.2560 - acc: 0.9214 - val_loss: 0.1449 - val_acc: 0.9583
Epoch 5/120- 2s - loss: 0.2048 - acc: 0.9382 - val_loss: 0.1341 - val_acc: 0.9590
Epoch 6/120- 2s - loss: 0.1682 - acc: 0.9497 - val_loss: 0.1183 - val_acc: 0.9655
Epoch 7/120- 2s - loss: 0.1406 - acc: 0.9573 - val_loss: 0.1070 - val_acc: 0.9698
Epoch 8/120- 2s - loss: 0.1288 - acc: 0.9604 - val_loss: 0.1037 - val_acc: 0.9667
Epoch 9/120- 2s - loss: 0.1175 - acc: 0.9641 - val_loss: 0.1056 - val_acc: 0.9685
Epoch 10/120- 2s - loss: 0.1016 - acc: 0.9690 - val_loss: 0.0935 - val_acc: 0.9696
Epoch 11/120- 2s - loss: 0.0940 - acc: 0.9709 - val_loss: 0.0856 - val_acc: 0.9741
Epoch 12/120- 2s - loss: 0.0896 - acc: 0.9729 - val_loss: 0.0901 - val_acc: 0.9741
Epoch 13/120- 2s - loss: 0.0857 - acc: 0.9744 - val_loss: 0.0879 - val_acc: 0.9719
Epoch 14/120- 2s - loss: 0.0803 - acc: 0.9757 - val_loss: 0.0894 - val_acc: 0.9723
Epoch 15/120- 2s - loss: 0.0740 - acc: 0.9782 - val_loss: 0.1040 - val_acc: 0.9705
Epoch 16/120- 2s - loss: 0.0708 - acc: 0.9796 - val_loss: 0.1073 - val_acc: 0.9683
Epoch 17/120- 2s - loss: 0.0652 - acc: 0.9800 - val_loss: 0.0791 - val_acc: 0.9753
Epoch 18/120- 2s - loss: 0.0660 - acc: 0.9801 - val_loss: 0.0794 - val_acc: 0.9751
Epoch 19/120- 2s - loss: 0.0571 - acc: 0.9828 - val_loss: 0.0925 - val_acc: 0.9705
Epoch 20/120- 2s - loss: 0.0573 - acc: 0.9828 - val_loss: 0.0692 - val_acc: 0.9791
Epoch 21/120- 2s - loss: 0.0532 - acc: 0.9834 - val_loss: 0.0726 - val_acc: 0.9785
Epoch 22/120- 2s - loss: 0.0548 - acc: 0.9837 - val_loss: 0.0824 - val_acc: 0.9741
Epoch 23/120- 2s - loss: 0.0529 - acc: 0.9841 - val_loss: 0.0747 - val_acc: 0.9789
Epoch 24/120- 2s - loss: 0.0544 - acc: 0.9839 - val_loss: 0.0710 - val_acc: 0.9776
Epoch 25/120- 2s - loss: 0.0470 - acc: 0.9859 - val_loss: 0.0687 - val_acc: 0.9789
Epoch 26/120- 2s - loss: 0.0459 - acc: 0.9860 - val_loss: 0.0710 - val_acc: 0.9769
Epoch 27/120- 2s - loss: 0.0482 - acc: 0.9859 - val_loss: 0.0718 - val_acc: 0.9764
Epoch 28/120- 2s - loss: 0.0456 - acc: 0.9862 - val_loss: 0.0744 - val_acc: 0.9812
Epoch 29/120- 2s - loss: 0.0469 - acc: 0.9861 - val_loss: 0.0883 - val_acc: 0.9762
Epoch 30/120- 2s - loss: 0.0445 - acc: 0.9863 - val_loss: 0.0757 - val_acc: 0.9757Epoch 110/120- 2s - loss: 0.0217 - acc: 0.9941 - val_loss: 0.0600 - val_acc: 0.9832
Epoch 111/120- 2s - loss: 0.0243 - acc: 0.9936 - val_loss: 0.0716 - val_acc: 0.9800
Epoch 112/120- 2s - loss: 0.0204 - acc: 0.9941 - val_loss: 0.0740 - val_acc: 0.9794
Epoch 113/120- 2s - loss: 0.0178 - acc: 0.9948 - val_loss: 0.0669 - val_acc: 0.9828
Epoch 114/120- 2s - loss: 0.0184 - acc: 0.9949 - val_loss: 0.0569 - val_acc: 0.9850
Epoch 115/120- 2s - loss: 0.0224 - acc: 0.9943 - val_loss: 0.0703 - val_acc: 0.9791
Epoch 116/120- 2s - loss: 0.0203 - acc: 0.9944 - val_loss: 0.0762 - val_acc: 0.9789
Epoch 117/120- 2s - loss: 0.0182 - acc: 0.9945 - val_loss: 0.0705 - val_acc: 0.9798
Epoch 118/120- 2s - loss: 0.0204 - acc: 0.9944 - val_loss: 0.0603 - val_acc: 0.9819
Epoch 119/120- 2s - loss: 0.0188 - acc: 0.9950 - val_loss: 0.0544 - val_acc: 0.9848
Epoch 120/120- 2s - loss: 0.0198 - acc: 0.9947 - val_loss: 0.0593 - val_acc: 0.9857
# 可视化指标
fig = plt.figure()
plt.subplot(2,1,1)
plt.plot(history5.history['acc'])
plt.plot(history5.history['val_acc'])
plt.title('Model Accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='lower right')plt.subplot(2,1,2)
plt.plot(history5.history['loss'])
plt.plot(history5.history['val_loss'])
plt.title('Model Loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper right')
plt.tight_layout()plt.show()

# 保存模型
import os
import tensorflow.gfile as gfilesave_dir = "/content/drive/model/v5/"if gfile.Exists(save_dir):gfile.DeleteRecursively(save_dir)
gfile.MakeDirs(save_dir)model_name = 'keras_traffic_5.h5'
model_path = os.path.join(save_dir, model_name)model5.save(model_path)
print('Saved trained model at %s ' % model_path)
Saved trained model at /content/drive/model/v5/keras_traffic_5.h5
# 加载模型
from keras.models import load_modeltraffic_model = load_model(model_path)
# 统计模型在测试集上的分类结果
loss_and_metrics = traffic_model.evaluate(X_test_normalized, Y_test, verbose=2,batch_size=256)print("Test Loss: {}".format(loss_and_metrics[0]))
print("Test Accuracy: {}%".format(loss_and_metrics[1]*100))predicted_classes = traffic_model.predict_classes(X_test_normalized)correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
print("Classified correctly count: {}".format(len(correct_indices)))
print("Classified incorrectly count: {}".format(len(incorrect_indices)))
Test Loss: 0.15594110083032578
Test Accuracy: 96.76167853182493%
Classified correctly count: 12221
Classified incorrectly count: 409

补充单张图片预测

# 加载模型
from keras.models import load_modeltraffic_model = load_model(model_path)
# 加载预测图片import os
import cv2
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import numpy as npimage_path = "/content/drive/image/"
filenames = os.listdir(image_path)X_predict = []for filename in filenames:if filename.endswith(".jpg"):img = cv2.imread(image_path+filename)img = cv2.resize(img,(32,32),cv2.INTER_LINEAR)X_predict.append(img)plt.imshow(img)
# 封装数据预处理的方法
import cv2def preprocess_features(X, equalize_hist=True):normalized_X = []for i in range(len(X)):# Convert from RGB to YUVyuv_img = cv2.cvtColor(X[i], cv2.COLOR_RGB2YUV)yuv_img_v = X[i][:, :, 0]# equalizeHistyuv_img_v = cv2.equalizeHist(yuv_img_v)# expand_disyuv_img_v = np.expand_dims(yuv_img_v, 2)normalized_X.append(yuv_img_v)# normalizenormalized_X = np.array(normalized_X, dtype=np.float32)normalized_X = (normalized_X-128)/128# normalized_X /= (np.std(normalized_X, axis=0) + np.finfo('float32').eps)return normalized_X
# 对数据进行处理
X_predict_normalized = preprocess_features(X_predict)
# 数据维度及数据类型
print(X_predict_normalized.shape,type(X_predict_normalized))
# 模型预测
y_predict = traffic_model.predict_classes(X_predict_normalized)
print(id_to_name(y_predict[0]))

卷积神经网络交通标志识别相关推荐

  1. 【交通标志识别】BP神经网络交通标志识别【含GUI Matlab源码 718期】

    ⛄一.BP神经网络交通标志识别简介 道路交通标志用以禁止.警告.指示和限制道路使用者有秩序地使用道路, 保障出行安全.若能自动识别道路交通标志, 则将极大减少道路交通事故的发生.但是由于道路交通错综复 ...

  2. 【交通标志识别】基于matlab GUI BP神经网络交通标志识别系统(含语音报警)【含Matlab源码 2240期】

    ⛄一.BP神经网络交通标志识别简介 道路交通标志用以禁止.警告.指示和限制道路使用者有秩序地使用道路, 保障出行安全.若能自动识别道路交通标志, 则将极大减少道路交通事故的发生.但是由于道路交通错综复 ...

  3. 【交通标志识别】BP神经网络雾霾天气交通标志识别(带面板)【含GUI Matlab源码 1771期】

    ⛄一.BP神经网络交通标志识别简介 道路交通标志用以禁止.警告.指示和限制道路使用者有秩序地使用道路, 保障出行安全.若能自动识别道路交通标志, 则将极大减少道路交通事故的发生.但是由于道路交通错综复 ...

  4. Python交通标志识别基于卷积神经网络的保姆级教程(Tensorflow)

    项目介绍 TensorFlow2.X 搭建卷积神经网络(CNN),实现交通标志识别.搭建的卷积神经网络是类似VGG的结构(卷积层与池化层反复堆叠,然后经过全连接层,最后用softmax映射为每个类别的 ...

  5. 人工智能深度学习框架MXNet实战:深度神经网络的交通标志识别训练

    人工智能深度学习框架MXNet实战:深度神经网络的交通标志识别训练 MXNet 是一个轻量级.可移植.灵活的分布式深度学习框架,2017 年 1 月 23 日,该项目进入 Apache 基金会,成为 ...

  6. ​【交通标志识别】基于BP神经网络实现交通标志识别matlab代码

    1 简介 近年来,交通标志识别在车辆视觉导航系统中是一个热门研究课题.为了安全驾驶和高效运输,交通部门在公路道路上设置了各类重要的交通标志,以提醒司机和行人有关道路交通信息,如指示标志.警告标志.禁止 ...

  7. matlab交通标志神经网络识别,基于神经网络的交通标志识别方法

    Municipal & Traffic Construction SCIENCE & TECHNOLOGY FOR DEVELOPMENT 149 基于神经网络的交通标志识别方法 赵丹 ...

  8. 基于残差神经网络的交通标志识别算法研究与应用实现

    问题: 从图像中识别交通标志对于自动驾驶至关重要.要想实现自动驾驶,车辆必须了解并遵守所有交通规则.当前,特斯拉.谷歌.梅赛德斯-奔驰.丰田.福特.奥迪等许多大公司都在研究自动驾驶.因此,为了实现这项 ...

  9. 动手学无人驾驶(1):交通标志识别

    今天主要介绍无人驾驶当中深度学习技术的应用. 本文是根据博客专家AdamShan的文章整理而来,在此表示感谢. 关于深度学习的图像分类技术,网上已有很多关于深度学习的课程(如吴恩达老师的深度学习专项课 ...

  10. 基于深度学习的大规模交通标志识别(附6GB交通标志数据集)

    01 1.文章信息 <Deep Learning for Large-Scale Traffic-Sign Detection and Recognition>. 国外学者2020年发在I ...

最新文章

  1. STL 队列queue
  2. CVPR2020检测类论文最全汇总:136篇论文方向细分(附代码和论文打包下载)
  3. SQL 数据库 连接查询 变量、if else、while
  4. Linux 中挖矿病毒处理过程
  5. oracle中的cursor属性有哪些,Cursor语法及理解
  6. cocoa pods的安装与我遇到的问题
  7. sql加上唯一索引后批量插入_MySQL当批量插入遇上唯一索引
  8. 《架构探险》第三章 项目核心实现
  9. MVC之LayOut布局页
  10. Pspice for TI取消默认打开方式
  11. 深圳以招聘忽悠面试的培训机构
  12. 网页媒体播放利器 - JW Player的demo
  13. 番茄助手功能及快捷键
  14. 一个查英语缩写的网站
  15. 计算机网络广东海洋大学简答题,广东海洋大学计算机网络历年考题(直接阅读版6套可编辑)...
  16. 服务器柜机位置摆放电子图,柜式空调摆放位置有什么要注意的吗
  17. 赛马c语言编程,C/C++编程题之渊子赛马
  18. win11开机后输入法无法使用
  19. el-table拆分单元格
  20. 一个总是令人记不住的vectorvectorPoint

热门文章

  1. VR养狗,养的是寂寞还是潮流?
  2. gentoo Cataclysm - Dark Days Ahead
  3. 4个很 丝滑 的 Veu 路由过渡动效
  4. JAVA购物网站商城系统毕业设计 开题报告
  5. oracle里如何求及格率,统计出每个教师每门课的及格人数和及格率
  6. 元的符号在计算机怎么打出来,告诉你电脑上特殊符号怎么打出来?
  7. 在Word中的方框里打对勾都有哪些方法?☑☑☑
  8. vmware上用kali破解wifi
  9. windows11微软拼音输入法(自带输入法)修复
  10. UOS 下wine的记录