Term-1-p2-traffic-sign-classifier

简介

  Term-1第二节课是进行交通标志分类,数据集主要来自于German Traffic Sign,包含了42种交通标志,通过深度学习网络进行分类。

环境准备

  • python 2.7
  • numpy
  • scikit-learn
  • tensorflow
  • keras

处理流程

  处理流程如下图所示



数据读取

  我们拿到的数据集是一系列交通标志图像,每个类别的交通标志放在了同一个文件夹下,并且有一个csv文件用于描述每个交通标志图片的ROI区域和该标志所属类别。下载图像的时候网站提供了一份用于数据处理的python程序(Python code for GTSRB文件夹下),在这里可以用到。
  这里按csv描述的图像信息进行ROI部分的提取,并使用pickle保存为.p文件方便后续模型训练使用。代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import numpy as np
import pickle
import os
import cv2
import csv

//处理训练数据
def process_train_data(path):
file = os.listdir(path)
classes = len(file)
train_data = []
train_labels = []
for i in range(0,classes):
dir_name = file[i]
if dir_name=='.DS_Store':
continue
full_dir_path = path + dir_name
csv_file_path = full_dir_path + '/' + 'GT-{0}.csv'.format(dir_name)
with open(csv_file_path) as f:
csv_reader = csv.reader(f,delimiter=';')
# pass header
csv_reader.next()
for (filename,width,height,x1,y1,x2,y2,classid) in csv_reader:
train_labels.append(classid)
image_file_path = full_dir_path+'/'+filename
resized_image = resize_image(image_file_path,(x1,y1,x2,y2))
train_data.append(resized_image)
f.close()
print 'train data process done'
return train_data,train_labels

//提取roi区域,并调整大小,统一为32*32像素
def resize_image(path,index):
image = cv2.imread(path)
image = image[int(index[0]):int(index[2]),int(index[1]):int(index[3])]
res = cv2.resize(image,(32,32),interpolation = cv2.INTER_CUBIC)
return res

//处理测试数据
def process_test_data(path):
test_data = []
test_labels = []
csv_file_path = path + '/' + 'GT-final_test.csv'
with open(csv_file_path) as f:
csv_reader = csv.reader(f,delimiter=';')
csv_reader.next()
for (filename,width,height,x1,y1,x2,y2,classid) in csv_reader:
test_labels.append(classid)
image_file_path = path+'/'+filename
resized_image = resize_image(image_file_path,(x1,y1,x2,y2))
test_data.append(resized_image)
print 'test data process done'
return test_data,test_labels

def main():
train_data_path = '../data/GTSRB/Final_Training/Images/'
test_data_path = '../data/GTSRB2/Final_Test/Images'
train_data,train_labels = process_train_data(train_data_path)
test_data,test_labels = process_test_data(test_data_path)
with open('./train.p','wb') as f:
pickle.dump({"data":np.array(train_data),"labels":np.array(train_labels)},f)
with open('./test.p','wb') as f:
pickle.dump({"data":np.array(test_data),"labels":np.array(test_labels)},f)

if __name__=="__main__":
main()

  放几张效果图



数据处理

  目前已经得到了训练集和测试集,需要对数据进行shuffle以及对label进行one-hot编码。

1
2
3
4
5
6
7
8
9
def shuffle_data(X_train,Y_train,X_test,Y_test):
X_train,Y_train = shuffle(X_train,Y_train,random_state = 0)
X_test,Y_test = shuffle(X_test,Y_test,random_state=0)
return X_train,Y_train,X_test,Y_test

def encode_label(Y_train,Y_test):
Y_train_encoded = to_categorical(Y_train,num_classes = 43)
Y_test_encode = to_categorical(Y_test,num_classes = 43)
return Y_train_encoded,Y_test_encode

模型构建

  下面使用keras构建卷积神经网络,keras的使用方法具体参见Keras中文文档

  模型构建部分代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def build_model():
//使用sequential模型
model = Sequential()
//创建卷积层,输入为32*32*3的图像数据,卷积核大小为3*3
model.add(Conv2D(32,(3,3),input_shape = (32,32,3),activation = 'relu'))
//添加最大池化层
model.add(MaxPooling2D(pool_size=(2,2)))
//dropout修正过拟合
model.add(Dropout(0.5))
//将输出展平
model.add(Flatten())
//普通全连接层
model.add(Dense(512,activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(128,activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(43,activation='softmax'))
//定义损失函数,优化器、评估标准
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
return model

模型训练

  模型定义完成后开始进行模型训练

1
2
//指定训练集、测试机,迭代次数等
model.fit(X_train,Y_train,validation_data=(x_dev,y_dev),epochs=40,batch_size=200,verbose =1)

效果评估

  经过40轮迭代,模型准确率基本能达到99%左右,为了验证模型效果,特意挑选了10张图像进行比对。
  最终结果如下图所示




  其中第6张图类别应该是“Priority road”,其他分类全部正确。

总结

  这节课主要是使用深度学习模型进行图像分类,在没有进行深入调优的情况下,在测试集上获得了90%的正确率,如果想进一步提高分类准确率可以采用效果更好的模型进行轮数更多的训练。这部分的代码详见Term-1-p2-traffic-sign-classifier

-------------本文结束感谢您的阅读-------------

本文标题:Term-1-p2-traffic-sign-classifier

文章作者:小建儿

发布时间:2018年03月22日 - 10:03

最后更新:2018年11月17日 - 18:11

原始链接:http://yajian.github.io/Term-1-p2-traffic-sign-classifier/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。