數據集介紹
關於交通標識的數據集
一共有43個類別
1從數字的每一個類別中隨機抽取一張圖片觀察
可以看到圖片中存在一些因素可能會對我們模型的准確度造成影響。
1圖片有亮有暗,這可能是時間早晚 或者天氣的影響
2凸顯有大有小,這應該是由於攝像頭距離標示牌的遠近不同
3角度視角不同 有的圖片是是傾斜的
4有些圖片很模糊不清晰
5可能會有遮擋
2查看每個類別的數據量分布
有的數據的量占比較少,我們可以考慮擴充數據量的方式來增加數據量
3我們對數據進行數據增強
image_datagen = ImageDataGenerator(rotation_range=15., zoom_range=0.2, width_shift_range=0.1, height_shift_range=0.1)
這里對每一張圖像 以15度 來進行旋轉 0.2的隨機縮放 0.1的水平或垂直平移。
查看一下 數據增強的結果。
原圖:
數據增強結果:
4數據預處理
1模型對交通牌的識別 主要是根據 交通牌的形狀經識別的。 我們 這里不考慮色彩。我們在YUV色彩空間上進行圖片的識別訓練。這里只考慮亮度。
2對圖像進行直方圖均值化處理
3均值化歸一化
def get_mean_std_img(X): X = np.array([np.expand_dims(cv2.cvtColor(rgb_img, cv2.COLOR_RGB2YUV)[:, :, 0], 2) for rgb_img in X]) X = np.array([np.expand_dims(cv2.equalizeHist((np.uint8(img))),2)for img in X]) X = np.float32(X) mean_img = np.mean(X, axis=0) std_img = (np.std(X, axis=0)) #+ np.finfo('floar32').eps #32wei fudianshu zuixiaozhi return mean_img, std_img def preprocess_features(X, mean_img, std_img): # convert from RGB to YUV #YUV 亮度 色度 濃度 X = np.array([np.expand_dims(cv2.cvtColor(rgb_img, cv2.COLOR_RGB2YUV)[:, :, 0], 2) for rgb_img in X]) #zhifangtujunyunhua X = np.array([np.expand_dims(cv2.equalizeHist((np.uint8(img))),2)for img in X]) X = np.float32(X) #standardize features X -= mean_img X /= std_img return X
5網絡模型
http://yann.lecun.com/exdb/publis/pdf/sermanet-ijcnn-11.pdf
這個網絡結構中有2個分支,其中一個分支比另一分支多進行一次卷積操作,之后把兩個特征圖合並。論文中指出這樣做的好處是網絡可以在兩個不同尺度的特征上進行學習。
這樣更利於模型提高准確度。
實現:
def get_model(dropout_rate = 0.0): input_shape = (32, 32, 1) input = Input(shape=input_shape) cv2d_1 = Conv2D(64, (3, 3), padding='same', activation='relu')(input) pool_1 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(cv2d_1) dropout_1 = Dropout(dropout_rate)(pool_1) flatten_1 = Flatten()(dropout_1) cv2d_2 = Conv2D(64, (3,3), padding='same', activation='relu')(dropout_1) pool_2 = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(cv2d_2) cv2d_3 = Conv2D(64, (3,3), padding='same', activation='relu')(pool_2) dropout_2 = Dropout(dropout_rate)(cv2d_3) flatten_2 = Flatten()(dropout_2) concat_1 = concatenate([flatten_1, flatten_2]) dense_1 = Dense(64, activation='relu')(concat_1) output = Dense(43, activation='softmax')(dense_1) model = Model(inputs=input, outputs=output) # compile model model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # summarize model model.summary() return model
6訓練和結果
history = model.fit_generator(image_datagen.flow(x_train, y_train, batch_size=128), steps_per_epoch=5000, validation_data=(x_validation, y_validation), epochs=8, callbacks=callbacks_list, verbose=1)