keras交通信号识别(分类)

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/nima1994/article/details/83572824

自定义卷积网络完成分类。图像预处理(直方图均衡化增加对比度)。

使用数据:德国交通信号识别,其中train/test dataset的Images and annotations及test dataset的Extended annotations including class ids

实验结果

数据及代码组织结构:
在这里插入图片描述

训练过程与结果:
https://github.com/lsh1994/kerasDemo/blob/master/sec1/2.jpg

代码

"""
@file: tranfficSignRec.py
@time: 2018/10/26
"""
import pandas as pd
import numpy as np
from skimage import io, color, exposure, transform
import glob
import h5py
from keras.models import Sequential, model_from_json
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from keras.optimizers import SGD
from keras.callbacks import LearningRateScheduler, ModelCheckpoint
from matplotlib import pyplot as plt
import os
from pathlib import PurePath
import warnings

warnings.filterwarnings('ignore')  # 忽略警告

NUM_CLASSES = 43  # 43种交通标志
IMG_SIZE = 48  # 图像大小归一化为48

batch_size = 32 # 训练的参数
nb_epoch = 10
lr = 0.01


# 图像直方图均衡化(调整对比度)、取中心、resize
def preprocess_img(img):
    hsv = color.rgb2hsv(img)
    hsv[:, :, 2] = exposure.equalize_hist(hsv[:, :, 2])
    img = color.hsv2rgb(hsv)

    ms = min(img.shape[:2])
    xx = (img.shape[0] - ms) // 2
    yy = (img.shape[1] - ms) // 2
    img = img[xx:xx + ms, yy:yy + ms, :]

    img = transform.resize(img, (IMG_SIZE, IMG_SIZE))

    return img


# 根据路径(图片上层目录)得到标签
def get_class(img_path):
    return int(PurePath(img_path).parts[- 2])


def readfile():
    # 读取所有图片、标签(onehot),存放至h5py文件
    try:
        with h5py.File('X.h5') as hf:
            X, Y = hf['imgs'][:], hf['labels'][:]

        print("Loaded images from X.h5")

    except BaseException:
        print("Error in reading X.h5. Processing all images...")
        root_dir = r'../data/GTSRB/Final_Training/Images'
        imgs = []
        labels = []

        all_img_paths = glob.glob(os.path.join(root_dir,'*/*.ppm'))  # 提取所有ppm文件完整路径

        np.random.shuffle(all_img_paths)  # 打散
        for img_path in all_img_paths:
            try:
                img = preprocess_img(io.imread(img_path))
                label = get_class(img_path)
                imgs.append(img)
                labels.append(label)

                if len(imgs) % 1000 == 0:
                    print("Processed %d/%d" %(len(imgs), len(all_img_paths)))
            except BaseException:
                print('missed', img_path)
                pass
        X = np.array(imgs, dtype='float32')
        # labels数组转onehot
        Y = np.eye(len(labels), NUM_CLASSES, dtype=np.uint8)[labels]

        # 可以加速载入与处理
        with h5py.File('X.h5', 'w') as hf:
            hf.create_dataset('imgs', data=X)
            hf.create_dataset('labels', data=Y)
    return X, Y


def cnn_model():

    model = Sequential()

    model.add(Conv2D(32,(3,3),padding='same',activation='relu',input_shape=(IMG_SIZE,IMG_SIZE,3)))
    model.add(Conv2D(32, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.2))

    model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
    model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.2))

    model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
    model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.2))

    model.add(Flatten())
    model.add(Dense(512, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(NUM_CLASSES, activation='softmax'))

    sgd = SGD(lr=lr, decay=1e-6, momentum=0.9, nesterov=True)
    model.compile(
        loss='categorical_crossentropy',
        optimizer=sgd,
        metrics=['accuracy'])

    return model

# 每10个epoch学习率递减0.1倍
def lr_schedule(epoch):

    return lr * (0.1 ** int(epoch / 10))


def train():
    model = cnn_model()
    print(model.summary())
    X, Y = readfile()
    history = model.fit(X,Y,
        batch_size=batch_size,
        epochs=nb_epoch,
        validation_split=0.2,
        shuffle=True,
        verbose=2,
        callbacks=[
            LearningRateScheduler(lr_schedule),
            # ModelCheckpoint('model.h5',save_best_only=True)
        ])
    # 可视化训练曲线(train,val)
    plt.figure(figsize=(8, 4))
    plt.subplot(1, 2, 1)
    plot_train_history(history, 'loss', 'val_loss')
    plt.subplot(1, 2, 2)
    plot_train_history(history, 'acc', 'val_acc')
    plt.show()
    return model

def plot_train_history(history, train_metrics, val_metrics):
    plt.plot(history.history.get(train_metrics), '-o')
    plt.plot(history.history.get(val_metrics), '-o')
    plt.ylabel(train_metrics)
    plt.xlabel('Epochs')
    plt.legend(['train', 'validation'])


# 在测试集上测试
def test(model):
    test = pd.read_csv('../data/GTSRB/GT-final_test.csv',sep=';')
    X_test = []
    y_test = []
    for file_name, class_id in zip(list(test['Filename']), list(test['ClassId'])):
        img_path = os.path.join('../data/GTSRB/Final_Test/Images/', file_name)
        X_test.append(preprocess_img(io.imread(img_path)))
        y_test.append(class_id)
    X_test = np.array(X_test)
    y_test = np.array(y_test)

    print("X_test.shape: ", X_test.shape)
    print("y_test.shape: ", y_test.shape)

    y_pred = model.predict_classes(X_test) # 返回预测值
    acc = np.sum(y_pred == y_test) / np.size(y_pred)
    print("Test accuracy = {} ".format(acc))


if __name__ == '__main__':
    model=train()
    test(model)

参考:https://github.com/erhwenkuo/deep-learning-with-keras-notebooks

猜你喜欢

转载自blog.csdn.net/nima1994/article/details/83572824