基于Unity的自动驾驶

  • Post author:
  • Post category:其他




1.流程

  1. 软件下载安装
  2. 数据采集
  3. 自定义dataset
  4. 模型搭建
  5. 模型训练
  6. 测试
  7. 总结
  8. 后续



本项目下载地址

GitHub



1.软件下载及安装

1.

下载地址

:https://github.com/udacity/self-driving-car-sim

2.进入链接后可在选择自己的平台下载。


3.下载的是个压缩包,直接解压即可使用

在这里插入图片描述



2.数据采集

  1. 软件打开后首先会有如图所示的界面,即选择分辨率,画质,显示器。如若你的计算资源有限建议选择如图所示的参数即可。不然在计算资源达不到的情况下会产生比较大地延时,这里不建议。

    在这里插入图片描述

  2. 进入后会让你选择模式,Training mode和autonomous mode两种模式,即训练模式和自动驾驶模式,在数据采集阶段肯定选择training mode,实际上就是进行数据采集。

    在这里插入图片描述

  3. 进入训练模式后点击如图所示按钮选择数据存放路径,然后再次点击即可进行数据采集

    在这里插入图片描述

  4. 采集完成后会在你选择的文件夹下生成这两个文件,IMG是小车前面三个摄像头所拍摄的画面,driving.csv是每张图片所具有的参数

    在这里插入图片描述

  5. csv文件如图所示,分别是中间摄像,左侧摄像,右侧摄像所拍摄画面,后面依次是转向角度,油门大小,刹车大小,当前速度。

    在这里插入图片描述



3.数据增强

  1. 为什么做这一步?如果你做一次转向数据直方图即可看到,想左转的数据明显大于向右转的数据,并且不转动的数据远大于转向数据,并且人工采集图像数据有限。

    在这里插入图片描述
  2. 需要做的便是对图像进行水平镜像翻转,剔除部分转向为0的值。以及HSV色彩空间的值随机变换。



4.模型搭建

  1. 模型如图所示,很简单的模型,但是对于这个项目而言参数足够了。

    在这里插入图片描述
class CustomerNet(nn.Module):
    def __init__(self):
        super(CustomerNet,self).__init__()
        self.conv2d0=nn.Conv2d(in_channels=3,out_channels=32,kernel_size=5,stride=1,padding=2,bias=True)
        self.conv2d1=nn.Conv2d(in_channels=32,out_channels=32,kernel_size=5,stride=1,padding=2,bias=True)
        self.conv2d2=nn.Conv2d(in_channels=32,out_channels=64,kernel_size=5,stride=1,padding=2,bias=True)
        self.maxpool0=nn.MaxPool2d(kernel_size=2,stride=2,padding=0)
        self.conv2d3=nn.Conv2d(in_channels=64,out_channels=32,kernel_size=5,stride=1,padding=2,bias=True)
        self.conv2d4=nn.Conv2d(in_channels=32,out_channels=3,kernel_size=5,stride=1,padding=0,bias=True)
        self.flatten1=nn.Flatten()
        self.relu=nn.ReLU()
        self.liner1=nn.Linear(in_features=2160,out_features=320)
        self.liner2=nn.Linear(in_features=320,out_features=80)
        self.liner3=nn.Linear(in_features=80,out_features=20)
        self.liner4=nn.Linear(in_features=20,out_features=1)

        self.liner11=nn.Linear(in_features=4096,out_features=1024)
        self.liner22=nn.Linear(in_features=1024,out_features=128)
        self.liner33=nn.Linear(in_features=128,out_features=1)


    def forward(self,x):
        x=self.relu(self.conv2d0(x))
        x=self.maxpool0(x)
        x=self.relu(self.conv2d1(x))
        x=self.maxpool0(x)
        x=self.relu(self.conv2d2(x))
        x=self.maxpool0(x)
        x=self.relu(self.flatten1(x))
        # print(x.shape)
        x=F.relu(self.liner11(x))
        x=self.relu(self.liner22(x))
        x=self.liner33(x)
        return x



5.模型训练

  1. 这一步按照一般流程走即可,因为模型很小,所以用cpu训练也会很快。同时训练会在logs目录下产生训练过程中的日志等
def main():
    model=CustomerNet()
    #加载损失函数
    # loss=nn.CrossEntropyLoss()
    loss=nn.MSELoss()
    #加载优化器
    optmizer=opt.SGD(model.parameters(),lr=0.003,momentum=0.8)
    # trans=transforms.Compose([transforms.ToTensor()])
    train_data,val_data,test_data=load_train_val(1)
    sumwriter=SummaryWriter(log_dir='../logs')
    #训练论数
    epochs=80
    step=1
    for epoch in range(epochs):
        print(f'-------------第{epoch+1}轮训练-----------')
        runing_loss = 0
        ind=0
        train_data, val_data, test_data = load_train_val(0.8)
        random.shuffle(train_data)
        for data in tqdm(train_data):
            try:imgpath,lables=data
            except:continue
            lables=torch.from_numpy(np.array([float(lables)],dtype=np.float32))
            #图像预处理
            img=trans_data(imgpath)
            optmizer.zero_grad()
            netout=model(img)
            # print(lables)
            lossnow=loss(netout,lables)
            lossnow.backward()
            optmizer.step()
            runing_loss+=lossnow.item()
            ind += 1
            if ind%1000==0:
                print('<<<<--------第%3d轮,图片:%10d张---------->>>> loss:%3f' %(epoch+1,ind,runing_loss/1000))
                # sumwriter.add_image('img',img,dataformats='CWH')
                sumwriter.add_scalar(tag='Loss',scalar_value=runing_loss/1000,global_step=step)
                step+=1
                if runing_loss/1000==0:
                    save(model,epoch)
                    return
                runing_loss = 0
        save(model,epoch)



6.测试

这个就多说了,直接看效果吧。


B站地址

:https://www.bilibili.com/video/BV1Kf4y1K7z2/

基于Unity的自动驾驶模型测试



7.总结

这里说一下我从这个实验里学到的东西吧,都是本人自己亲身一遍一遍的试过所总结的。

  1. 数据增强非常有必要,在训练之前一定要看观察整体数据在进行后续处理。有效的数据处理能起到事半功倍的效果
  2. 不加ReLu激活函数会产生过拟合的情况。
  3. 学习率太大会产生损失会产生剧烈的震荡
  4. 学习率太小会产生梯度消失
  5. 说一个小插曲,这个项目用了我三天半的时间,代码写完也就两个多小时,后面时间全是参数调试,所以才有了上面的总结,主要是在图像裁剪的部分,我原定的事向下裁剪60像素,训练几次都没觉得这里没有什么,最后实在找不到能改的地方了,就在这里改了下,把60改成65,后训练效果出奇的好。所以数据处理真的非常重要。



8.后续

  1. 目前在复现YOLOv1的代码,已经接近尾声,后续代码也会上传至GitHub。敬请关注,一起进步。



版权声明:本文为qq_38038123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。