使用Keras训练自动驾驶(使用Udacity自动驾驶模拟器)

1.完成项目所需要的资源

(1)模拟器下载

Linux
macOS
Windows

(2)Unity 下载

运行Udacity模拟器需要Unity,这是下载链接。
https://unity.cn/releases

(3)Behavioral Cloning Project

此存储库包含Behavioral Cloning Project的起始文件。
连接:https://github.com/udacity/CarND-Behavioral-Cloning-P3

2.获取训练数据

若正确安装unity和模拟器,则打开Udacity的模拟器,会出现如下画面
Udacity软件界面
点击TRAINING MODE
TRAINING MODE
点击右上角RECORD,选择保存模型路径。
按R开始记录训练数据,再按R停止记录数据。生成如下所示的数据
在这里插入图片描述
这就是训练用的照片和其对应的转向角了。

3.训练判断转向角的全连接模型

有了训练数据我们就可以搭建我们的训练模型了,我们使用csv库读取数据,利用Keras建立模型。

    import csv
    import cv2
    import numpy as np
    from keras.models import Sequential
    from keras.layers import Flatten, Dense
    
    
    # 初始化行的数组,将csv中的数据传入到数组中
    lines = []
    # 读取csv文件
    with open('.../data/driving_log.csv') as csvfile:
        reader = csv.reader(csvfile)
        for line in reader:
            lines.append(line)
    
    # 初始化图片矩阵和转向角
    images = []
    measurements = []
    for line in lines:
        source_path = line[0]
        filename = source_path.split("/")[-1]
        # 图片路径
        current_path = '.../data/IMG/' + filename
        # 将所有的图片数据存入images数组中
        image = cv2.imread(current_path)
        images.append(image)
        # 将相对应的转向角数据存入measurement数组中
        measurement = float(line[3])
        measurements.append(measurement)
    
    # 将images和measurements作为训练数据
    X_train = np.array(images)
    y_train = np.array(measurements)
    
    # 使用Keras建立模型
    model = Sequential()
    model.add(Flatten(input_shape=(160, 320, 3)))
    model.add(Dense(1))
    
    model.compile(loss='mse', optimizer='adam')
    model.fit(X_train, y_train, validation_split=0.2, shuffle=True, nb_epoch=10)
    
    model.save('model.h5')

这样就可以简单的利用Keras训练了一个控制转向角的网络,最后模型以model.h5的名称保存。在训练过程中,我将csv文件中的\全部替换成了/解决了模型输入不匹配的问题。

因为神经网络太过简单,导致这个模型的实际效果非常差,所以我们需要对模型进行改进。

3.模型改进

(1)数据预处理

对模型进行改进,需要预处理。使用数据归一化和均值中心化。
数据归一化:

    pixel_normalized = pixel / 255
    pixel_mean_centered = pixel_normalized - 0.5

均值归一化,使均值大约为0

    Lambda(lambda x: (x / 255.0) - 0.5)

使用Lambda图层
在Keras中,lambda图层可用于创建任意函数,这些函数在每个图像通过图层时对其进行操作。
在这个项目中,lambda层是并行化图像规范化的便捷方式。lambda图层还将确保模型在进行预测时将输入图像标准化drive.py。

该lambda图层可以获取图像中的每个像素并通过公式运行它:

model = Sequential()
model.add(Lambda(lambda x:x / 255.0 - 0.5))

(2)扩充训练数据

模型在训练初期容易出现一直向左拐的情况,我们可以将图片翻转作为新的训练数据。使用numpy库或者cv2库可以轻松实现将图片翻转。

这样不但扩充了训练数据,还使得整个模型有着更好的鲁棒性。

import cv2
image = cv2.imread('.../image.jpg')
# 实现图片的水平翻转
image1 = cv2.flip(image, 1)
# 垂直翻转
image2 = cv2.flip(image, 0)

(3)使用更复杂的模型

由于之前给的例子中只构建了一层全连接神经网络,导致训练出来的模型效果非常的差。我们可以使用LeNet-5模型来构建我们的神经网络。在这里插入图片描述

4.新的模型训练

经过模型改进之后,小车的自动驾驶有了更好的效果。其如下代码所示。

    import csv
    import cv2
    import numpy as np
    from keras.models import Sequential
    from keras.layers import Flatten, Dense, Convolution2D, MaxPooling2D, Lambda, Cropping2D
    
    
    # 初始化行的数组,将csv中的数据传入到数组中
    lines = []
    # 读取csv文件
    with open('.../data/driving_log.csv') as csvfile:
        reader = csv.reader(csvfile)
        for line in reader:
            lines.append(line)
    
    # 初始化图片矩阵和转向角
    images = []
    measurements = []
    for line in lines:
        source_path = line[0]
        filename = source_path.split("/")[-1]
        # 图片路径
        current_path = '.../data/IMG/' + filename
        # 将所有的图片数据存入images数组中
        image = cv2.imread(current_path)
        images.append(image)
        # 将相对应的转向角数据存入measurement数组中
        measurement = float(line[3])
        measurements.append(measurement)
    
    # 增加训练数据数量,将图像镜像
    augnented_images, augnented_measurements = [], []
    for image, measurement in zip(images, measurements):
        augnented_images.append(image)
        augnented_measurements.append(measurement)
        augnented_images.append(cv2.flip(image, 1))
        augnented_measurements.append(measurement*-1.0)
    
    # 将images和measurements作为训练数据
    X_train = np.array(augnented_images)
    y_train = np.array(augnented_measurements)
    
    # 使用Keras建立模型
    model = Sequential()
    
    # Cropping层用于裁剪图像,下面是距离图像顶部50像素,距离图像底部20像素,左侧右侧各0
    model.add(Cropping2D(cropping=((50,20), (0, 0)), input_shape=(160, 320, 3)))
    
    # 在Keras中Lambda层用于创建任意函数,这些函数在每个图像通过图层对其进行操作 。对输入图片进行预处理。
    model.add(Lambda(lambda x:x / 255.0 - 0.5))
    
    # 加入卷积层和池化层
    model.add(Convolution2D(6, 5, 5, activation='relu'))
    model.add(MaxPooling2D())
    model.add(Convolution2D(6, 5, 5, activation='relu'))
    model.add(MaxPooling2D())
    model.add(Flatten())
    model.add(Dense(120, activation='relu'))
    model.add(Dense(84, activation='relu'))
    model.add(Dense(1))
    
    # 模型训练
    model.compile(loss='mse', optimizer='adam')
    model.fit(X_train, y_train, validation_split=0.2, shuffle=True, nb_epoch=3)
    
    model.save('model_new.h5')

5.在模拟器上测试效果

在CarND-Behavioral-Cloning-P3-master目录下运行drive.py

python drive.py model_new.h5

打开模拟器
在这里插入图片描述
选择AUTONOMOUS MODE就可以查看效果。
在这里插入图片描述到此我们就实现了利用自己的训练神经网络来实现模拟器的自动驾驶。

环境:python3.6
IDE:pycharm2019.2

Logo

更多推荐