【自动驾驶专题】|小白都会玩的自动驾驶算法

时间:2022-07-22
本文章向大家介绍【自动驾驶专题】|小白都会玩的自动驾驶算法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

今天,我们介绍一个可实现自动驾驶的简单算法。本算法是在Udacity的Self-Driving Car Simulator模拟器环境下开发,将摄像头的图像输入到深度学习模型中,可以让汽车学会如何自动运行。

在模拟器中,我们从三个不同的视角创建了1551个画面,同时记录了车辆在517个不同状态下的转角、速度、油门和刹车等数据。

本算法是在keras环境下开发的。首先,将数据划分为训练集和验证集。

def load_data():
    data_df = pd.read_csv(os.path.join(os.getcwd(),data_dir, 'driving_log.csv'), names=['center', 'left', 'right', 'steering', 'throttle', 'reverse', 'speed'])
    X = data_df[['center', 'left', 'right']].values
    y = data_df['steering'].values
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
    return X_train, X_test, y_train, y_test

然后,我们进行模型的创建。模型包含5个卷积层、1个Dropout层和4个压缩层(Dense layer)。

def build_model():
    model = Sequential()
    model.add(Lambda(lambda x: x/127.5-1.0, input_shape=INPUT_SHAPE))
    model.add(Conv2D(24, kernel_size=(5, 5),strides=(2,2) ,activation='elu'))
    model.add(Conv2D(36, kernel_size=(5, 5),strides=(2,2) ,activation='elu'))
    model.add(Conv2D(48, kernel_size=(5, 5),strides=(2,2),activation='elu'))
    model.add(Conv2D(64, kernel_size=(3, 3), activation='elu'))
    model.add(Conv2D(64, kernel_size=(3, 3), activation='elu'))
    model.add(Dropout(0.5))
    model.add(Flatten())
    model.add(Dense(100, activation='elu'))
    model.add(Dense(50, activation='elu'))
    model.add(Dense(10, activation='elu'))
    model.add(Dense(1))
    #model.summary()
    return model

整个模型只输出一个值:车辆转角(steering angle)。将训练图像输入模型前,我们需要先做些预处理。

首先,为了增加训练样本数,我们需要进行数据增强处理:对已有图像进行翻转、平移、增加随机阴影或改变亮度等。

image, steering_angle = choose_image(data_dir, center, left, right, steering_angle)
image, steering_angle = random_flip(image, steering_angle)
image, steering_angle = random_translate(image, steering_angle, range_x, range_y)
image = random_shadow(image)
image = random_brightness(image)

然后,我们对图像进行剪裁和重设大小(resize),以便输入图像能适合训练模型。

def preprocess(image):
    image = crop(image)
    image = resize(image)
    image = rgb2yuv(image)
    return image

接下来,进行训练:

def train_model(model, X_train, X_valid, y_train, y_valid):
    model.compile(loss='mean_squared_error', optimizer=Adam(lr=0.001))

    #Fits the model on data generated batch-by-batch by a Python generator.
    model.fit_generator(batch_generator(data_dir, X_train, y_train, batch_size, True),
                        steps_per_epoch,
                        num_epochs,
                        verbose=1,
                        validation_data=batch_generator(data_dir, X_valid, y_valid, batch_size, False),
                        validation_steps=40
                        )

现在,我们获得了训练好的模型。然后,利用一个简单的服务器(socketio server)将模型预测的转角实时的传输给模拟器。

steering_angle = float(data["steering_angle"])
throttle = float(data["throttle"])
speed = float(data["speed"])
image = Image.open(BytesIO(base64.b64decode(data["image"])))
image = np.asarray(image)
image = preprocess_data.preprocess(image)
image = np.array([image])

steering_angle = float(model.predict(image, batch_size=1))
throttle = 1.0 - steering_angle ** 2 - (speed / speed_limit) ** 2

#send prediction to the simulator
send_control(steering_angle, throttle) 

车辆的运行情况如下:

可以看到,本算法实现了基本的自动驾驶功能,非常适合于初学者进行尝试。