今天,我们介绍一个可实现自动驾驶的简单算法。本算法是在Udacity的Self-Driving Car Simulator模拟器环境下开发,将摄像头的图像输入到深度学习模型中,可以让汽车学会如何自动运行。
在模拟器中,我们从三个不同的视角创建了1551个画面,同时记录了车辆在517个不同状态下的转角、速度、油门和刹车等数据。
本算法是在keras环境下开发的。首先,将数据划分为训练集和验证集。
代码语言:javascript复制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)。
代码语言:javascript复制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)。将训练图像输入模型前,我们需要先做些预处理。
首先,为了增加训练样本数,我们需要进行数据增强处理:对已有图像进行翻转、平移、增加随机阴影或改变亮度等。
代码语言:javascript复制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),以便输入图像能适合训练模型。
代码语言:javascript复制def preprocess(image):
image = crop(image)
image = resize(image)
image = rgb2yuv(image)
return image
接下来,进行训练:
代码语言:javascript复制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)将模型预测的转角实时的传输给模拟器。
代码语言:javascript复制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)
车辆的运行情况如下:
可以看到,本算法实现了基本的自动驾驶功能,非常适合于初学者进行尝试。