精华内容
下载资源
问答
  • 强化学习进行路径规划,各种强化学习的算法,适合从一开始进行学习,加实践代码哦
  • 在Q-learning算法中加入引力势场作为初始环境先验信息,在其基础上对环境进行陷阱区域逐层搜索,剔除凹形陷阱区域[Q]值迭代,加快了路径规划的收敛速度。同时取消对障碍物的试错学习,使算法在初始状态就能有效避开...
  • 运用强化学习算法在网格环境中进行了路径规划
  • 路径规划 强化学习 目标 (Goal) The reason for this article is to suggest a solution to Fortify Path Manipulation issues. 本文的目的是为Fortify Path Manipulation问题提供解决方案。 背景 (Background) ...

    路径规划 强化学习

    目标 (Goal)

    The reason for this article is to suggest a solution to Fortify Path Manipulation issues.

    本文的目的是为Fortify Path Manipulation问题提供解决方案。

    背景 (Background)

    Many companies, like my own, use a tool called Fortify to analyze their code. Fortify is an HP application that finds memory leaks and security threats. It is likely the most popular and well known tool for these purposes. Companies use it to improve the quality of their code and to prepare for third party audits. There are some Fortify links at the end of the article for your reference.

    与我自己的公司一样,许多公司都使用名为Fortify的工具来分析其代码。 Fortify是一个HP应用程序,可以发现内存泄漏和安全威胁。 为此,它可能是最流行和最著名的工具。 公司使用它来提高代码质量并为第三方审核做准备。 本文结尾处有一些Fortify链接供您参考。

    One of the common issues reported by Fortify is the Path Manipulation issue. The issue is that if you take data from an external source, then an attacker can use that source to manipulate your path. Thus enabling the attacker do delete files or otherwise compromise your system.

    Fortify报告的常见问题之一是路径操纵问题。 问题是,如果您从外部来源获取数据,则攻击者可以使用该来源来操纵您的路径。 因此,使攻击者能够删除文件或以其他方式破坏您的系统。

    Like many other people I found this issue in my code and did a search on the internet for a resolution. The most common proposal was to use the Java class FileSystems in the nio package to process the path. The intention is to obfuscate the fact that the path is coming from an external source. While this sometimes works, it does nothing to address the real issue. 

    像许多其他人一样,我在代码中发现了此问题,并在互联网上进行了搜索以寻求解决方案。 最常见的建议是使用nio包中的Java类FileSystems处理路径。 目的是混淆路径来自外部来源的事实。 尽管有时这是可行的,但却无法解决实际问题。

    The Fortify suggested remedy to this problem is to use a white-list of trusted directories as valid inputs and reject everything else. This solution is not always viable in a production environment because you can't always control where the client will be deploying your application. In my company's situation, we can't control where the client keeps their source data. So, we need to support the flexibility of specifying a directory path during execution. In this situation, and list of valid paths will not work.

    Fortify建议的解决此问题的方法是使用受信任目录的白名单作为有效输入,并拒绝其他所有内容。 该解决方案在生产环境中并不总是可行的,因为您无法始终控制客户端将在何处部署应用程序。 在我公司的情况下,我们无法控制客户将源数据保存在何处。 因此,我们需要支持在执行过程中指定目录路径的灵活性。 在这种情况下,有效路径列表将不起作用。

    解决方案 (The Solution)

    I am putting forward an alternative remedy. 

    我正在提出另一种补救办法。

    Allow the user to enter the path and parse the input for a white-list of acceptable characters. Reject from the input, any character you don't want in the path. It could be either removed or replaced. This approach gives you control over what the user can input while still allowing them the flexibility they need to specify their data and configuration.

    允许用户输入路径并解析输入以获取可接受字符的白名单。 从输入中拒绝路径中不需要的任何字符。 它可以被删除或替换。 这种方法使您可以控制用户可以输入的内容,同时仍然可以让他们灵活地指定数据和配置。

    Below is an example. This does pass the Fortify review. It is important to remember here to return the literal and not the char being checked. Fortify keeps track of the parts that came from the original input. If you use any of the original input, you may still get the error.

    下面是一个例子。 这确实通过了Fortify审查。 重要的是要记住在这里返回文字而不是要检查的字符。 Fortify会跟踪来自原始输入的零件。 如果您使用任何原始输入,您仍然可能会收到错误消息。

    Related Links:

    相关链接:

    Fortify: https://en.wikipedia.org/wiki/Fortify_Software

    Fortify: https//en.wikipedia.org/wiki/Fortify_Software

    HP: https://en.wikipedia.org/wiki/Hewlett-Packard

    惠普: https//en.wikipedia.org/wiki/惠普

    Path Manipulation: https://stackoverflow.com/questions/12690652/how-to-fix-path-manipulation-vulnerability-in-some-java-code

    路径操作: https : //stackoverflow.com/questions/12690652/how-to-fix-path-manipulation-vulnerability-in-some-java-code

    public class CleanPath {
    
    
        public static String cleanString(String aString) {
            if (aString == null) return null;
            String cleanString = "";
            for (int i = 0; i < aString.length(); ++i) {
                cleanString += cleanChar(aString.charAt(i));
            }
            return cleanString;
        }
    
    
        private static char cleanChar(char aChar) {
           
           // 0 - 9
           for (int i = 48; i < 58; ++i) {
                  if (aChar == i) return (char) i;
           }
           
           // 'A' - 'Z'
           for (int i = 65; i < 91; ++i) {
                  if (aChar == i) return (char) i;
           }
           
           // 'a' - 'z'
           for (int i = 97; i < 123; ++i) {
                  if (aChar == i) return (char) i;
           }
           
           // other valid characters
            switch (aChar) {
                case '/':
                    return '/';
                case '.':
                    return '.';
                case '-':
                    return '-';
                case '_':
                    return '_';
                case ' ':
                    return ' ';
            }
            return '%';
        }
    } 
    

    翻译自: https://www.experts-exchange.com/articles/30499/Fortify-Path-Manipulation-Issues.html

    路径规划 强化学习

    展开全文
  • 此方法同源借鉴于ICIA一篇强化学习paper 源码github地址:https://github.com/a7b23/Autonomous-MazePathFinder-using-DQN 该程序将由几个封锁(由块颜色表示)组成的图像作为输入,起始点由蓝色表示,目的地由绿色...

    感谢知乎搬砖的旺财博主;此方法同源借鉴于ICIA一篇强化学习paper
    源码github地址:https://github.com/a7b23/Autonomous-MazePathFinder-using-DQN

    该程序将由几个封锁(由块颜色表示)组成的图像作为输入,起始点由蓝色表示,目的地由绿色表示。 它输出一个由输入到输出的可能路径之一组成的图像。 下面显示的是程序的输入和输出。

    在这里插入图片描述

    在这里插入图片描述
    输入图像被馈送到由2个conv和2个fc层组成的模型,其输出对应于底部和右侧动作的Q值。 代理根据哪个Q值更大而向右或向下移动,并且使用代理的新位置生成的相应新图像再次被馈送到模型。获得输出状态并反馈新图像的过程保持重复 直到代理到达到达目的地的终端阶段。

    总体思路:

    • 获取image(map)
    • Agent处理image
    • Mobile Robot得到向前还是向右的指令
    • 实现了对无人车end-to-end的路径规划。

    在这里插入图片描述

    Data Generation

    代码DataGeneration.py为任务生成必需的数据。 它在25X25大小的图像中随机分配1X1像素大小的块。同时生成对应于每个不同起始位置的所有625个图像并将其存储在文件夹中。具有变化的阻塞位置的200个不同的这样的游戏的图像是 生成,因此总训练图像达250 * 625。 还生成与每个不同状态(图像)相关联的分数并将其存储在txt文件中,其中起始点与阻塞碰撞的状态获得-100的分数,当起始点与目的地碰撞时,其获得分数 100和所有剩余的状态得分为0。
    在这里插入图片描述

    Training

    InitialisingTarget.py生成与每个训练图像相关联的初始Q值,并将它们存储在txt文件-Targets200_New.txt中。生成的Q值只不过是随机初始化模型的输出。 training2.py开始训练模型。从trainig数据中选择随机批量大小的图像集并将其馈送到模型。根据损失更新模型权重,该损失是输出Q值和预期Q值之间的平方差异。预期的Q(s,a)= r(s,a)+ gamma * max(Q1(s1,a)),其中max取2个动作。这里Q1对应于存储在’Targets200_New.txt’文件中的q值。奖励r也是下一个州和当前州之间得分的差异。几个训练Q1值的时期再次更新并存储在相同的txt文件中,输出来自训练模型。新的Q1值再次用于训练模型。生成目标Q值和训练模型的步骤重复几个步骤,直到模型学习所需特征。
    在这里插入图片描述

    Testing

    就像DataGeneration.py一样,TestDataCollection.py也以相同的格式生成图像,除了它不是200个游戏,而是在单独的文件夹中生成仅对应20个游戏的图像。 对于20个游戏中的每个游戏,testing.py获取对应于代理位于0,0位置的图像,并将单个最终路径的图像输出到单独的文件夹中的目的地。 对于由于与阻塞冲突而无法找到路径的游戏,不会生成图像。

    initialisingtarget.py生成每个训练图像对应的初始Q值,保存在TXT文件targets200_new中,产生的Q值只是随机初始化模型的输出。

    一、定义函数

    定义一个函数,用于初始化所有的权值W

    def weight_variable(shape):
        initial = tf.truncated_normal(shape, stddev=0.05)
        return tf.Variable(initial)
    

    定义一个函数,用于初始化所有的偏置项b

    def bias_variable(shape):
        initial = tf.constant(0.05, shape=shape)
        return tf.Variable(initial)
    

    定义一个函数,用于构建卷积层

    def conv2d(x, W):
        return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
    

    x为input,[batch, in_height, in_width, in_channels] ,[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数];
    W为卷积核,它要求是一个Tensor,[filter_height, filter_width, in_channels, out_channels],[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input 相同,有一个地方需要注意,第三维 in_channels,就是参数input的第四维;
    strides,卷积时在图像每一维的步长;
    padding:string 类型的量,只能是"SAME" , “VALID” 其中之一,这个值决定了不同的卷积方式。

    二、网络

    2.1 input layer

    x = tf.placeholder(tf.float32, shape=[None, imageSize[0], imageSize[1], imageSize[2]])
    

    shape=[None, imageSize[0], imageSize[1], imageSize[2]]
    shape转换成了4D tensor,第二与第三维度对应的是照片的宽度与高度,最后一个维度是颜色通道数
    2. tf.placeholder(dtype, shape=None, name=None)

    dtype:数据类型。常用的是tf.float32 , tf.float64 等数值类型;
    shape:数据形状。默认是None,就是一维值,也可以是多维,比如[2,3] , [None, 3] 表示列是3,行不定;
    name:名称。

    2.2 卷积层

    2.2.1 卷积神经网络之训练算法

    同一般机器学习算法,先定义Loss function,衡量和实际结果之间差距
    找到最小化损失函数的w和b,CNN中用的算法是SGD(随机梯度下降)
    卷积运算是为了提取输入的不同特征,第一层可能只能提取到一些简单的特征,例如边缘,层数越高提取的特征越复杂。

    卷积层有两个关键操作:

    局部关联。每个神经元看做一个滤波器(filter)
    窗口(receptive field)滑动,filter对局部数据计算

    由于卷积层的神经元也是三维的,所以也具有深度
    卷积层的参数包含一系列过滤器,每个过滤器训练一个深度,有几个过滤器输出单元就具有多少深度
    对于输出单元不同深度的同一位置,与输入图片连接的区域是相同的,但是参数(过滤器)不同

    2.2.2 卷积神经网络之优缺点

    优点
    共享卷积核,对高维数据处理无压力
    无需手动选取特征,训练好权重,即得特征分类效果好
    2. 缺点
    需要调参,需要大样本量,训练最好要GPU
    物理含义不明确(也就说,我们并不知道每个卷积层到底提取到的是什么特征,而且神经网络本身就是一种难以解释的“黑箱模型”)

    2.2.3 第1个卷积层

    如下图所示,展示了一个3×3的卷积核在5×5的图像上做卷积的过程。每个卷积都是一种特征提取方式,就像一个筛子,将图像中符合条件(激活值越大越符合条件)的部分筛选出来。
    在这里插入图片描述

    # network weights
    # 第1、2个参数是窗口的大小,第3个参数是channel的数量,第4个参数定义了我们想使用多少个特征
    W_conv1 = weight_variable([2, 2, 3, 10])
    b_conv1 = bias_variable([10]) 
    
    # hidden layers
    h_conv1 = tf.nn.relu(conv2d(x, W_conv1) + b_conv1)
    

    分析程序的第一个卷积层,可以发现输入照片大小为25 * 25,窗口为2 * 2,会产生第一层隐藏层中25 * 25排列的神经元,这是因为我们需要从上到下移动窗口25次,从左到右移动窗口25 次来覆盖整个输入图片。在这里是假设窗口每次只移动一个像素,所以新窗口与上次的窗口会有重叠。

    padding=‘SAME’
    输入矩阵W×W,W = 25;
    filter矩阵F×F,卷积核,F = 2;
    stride值S,步长,S = 1;
    1.计算:

    new_height = new_width = W / S = 25 / 1 = 25 #结果向上取整
    

    含义:new_height为输出矩阵的高度
    说明:对W/S的结果向上取整得到W"包含"多少个S
    2. pad_needed_height = (new_height – 1) × S + F - W = (25-1)X 1 + 2 - 25 = 1

    含义:pad_needed_height为输入矩阵需要补充的高度
    说明:因为new_height是向上取整的结果,所以先-1得到W可以完全包裹住S的块数,之后乘以S得到这些块数的像素点总和,再加上filer的F并减去W,即得到在高度上需要对W补充多少个像素点才能满足new_height的需求
    3. pad_top = pad_needed_height / 2 = 1 / 2 = 0 #结果取整

    含义:pad_top为输入矩阵上方需要添加的高度
    说明:将上一步得到的pad_needed_height除以2 作为矩阵上方需要扩充0的像素点数
    4. pad_bottom = pad_needed_height - pad_top = 1 - 0 =1

    含义:pad_bottom为输入矩阵下方需要添加的高度
    说明:pad_needed_height减去pad_top的剩余部分补充到矩阵下方
    同理:

    pad_needed_width = (new_width – 1) × S + F - W = (25-1)X 1 + 2 - 25 = 1
    pad_left = pad_needed_width / 2 = 0
    pad_right = pad_needed_width – pad_left = 1

    在这里插入图片描述
    基于我们研究的样例,我们需要1个bias b与1个2*2的矩阵W来连接输入层与隐藏层的神经元。

    CNN的一个关键特性是这个权重矩阵W与bias b是隐藏层中所有神经元间共享的。

    本程序中是24 * 24 (576) 个神经元。你将会发现与全连接的神经网络相比,这会大大减少权重参数的数量。具体来说,由于共享了权重矩阵W,参数数量会从2304(2 * 2 * 24 * 24) 降到4(2 * 2)。

    这个共享的矩阵W与bias b在CNN中经常被叫作kernel或filter。这些filters与图像处理程序中润色图片的那些是类似的,此处是用来找出有鉴别性的feature。

    一个矩阵与bias定义了一个kernel。一个kernel仅仅只检测图像中一个特定相关的feature,所以建议使用多个kernels,每个想检测的特征一个kernel。这就意味着CNN中一个完整的卷积层包含了很多kernels。描述这些kernels的一个常用方法如下:
    在这里插入图片描述
    隐藏层的第一层包含了多个kernels。此处,我使用了10 个kernels,每一个定义了2*2的权重矩阵W和bias b,这两个参数也是隐藏层间共享的。

    ReLU(Rectified Linear unit)激活函数最近变成了神经网络中隐藏层的默认激活函数。这个简单的函数包含了返回max(0,x),所以对于负值,它会返回0,其它返回x。

    代码中首先对输入图像x(image) 计算卷积,计算得到的结果保存在2D tensor W_conv1中,然后与bias求和,接下来应用ReLU激活函数。

    2.2.4 第2个卷积层

    # network weights
    W_conv2 = weight_variable([2, 2, 10, 20])
    b_conv2 = bias_variable([20])
    
    # hidden layers
    h_conv2 = tf.nn.relu(conv2d(h_conv1, W_conv2) + b_conv2)
    

    分析程序的第二个卷积层,窗口为2 * 2,20个filters,此时我们会需传递10个channels,因为这是前一层的输出结果。

    2.2.5 卷积神经网络的时间复杂度分析

    在这里插入图片描述
    2.2.5.1 单个卷积层的时间复杂度
    在这里插入图片描述
    M:每个卷积核输出特征图的边长
    K:每个卷积核的边长
    C_{in} :每个卷积核的通道数,也即输入通道数,也即上一层的输出通道数
    C_{out} :本卷积层具有的卷积核个数,也即输出通道数
    注:严格来讲每层应该还包含1个Bias参数,这里为了简洁就省略了。
    在这里插入图片描述
    在这里插入图片描述
    2.2.5.2 卷积神经网络整体的时间复杂度

    在这里插入图片描述
    D :神经网络所具有的卷积层数,也即网络的深度。
    l :神经网络第 l 个卷积层。
    C_l :神经网络第 l 个卷积层的输出通道数 C_{out} ,也即该层的卷积核个数。对于第 l 个卷积层而言,其输入通道数 C_{in} 就是第 l-1 个卷积层的输出通道数。

    在这里插入图片描述
    2.2.5.3 时间复杂度对模型的影响
    时间复杂度决定了模型的训练/预测时间。如果复杂度过高,则会导致模型训练和预测耗费大量时间,既无法快速的验证想法和改善模型,也无法做到快速的预测。

    2.2.6 卷积神经网络的空间复杂度分析

    空间复杂度包括模型的参数数量(模型本身的体积)和每层输出的特征图大小(会影响模型运行时的内存占用情况)。

    2.2.6.1 空间复杂度
    在这里插入图片描述
    可见,网络的参数量只与卷积核的尺寸K、通道数C、网络的深度D相关。而与输入数据的大小无关。当我们需要裁剪模型时,由于卷积核的尺寸通常已经很小,而网络的深度又与模型的能力紧密相关,不宜过多削减,因此模型裁剪通常最先下手的地方就是通道数。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    2.2.6.2 空间复杂度对模型的影响
    空间复杂度决定了模型的参数数量。由于维度诅咒的限制,模型的参数越多,训练模型所需的数据量就越大,而现实生活中的数据集通常不会太大,这会导致模型的训练更容易过拟合。

    2.2.7 神经元的运算

    在这里插入图片描述
    以conv1为例:
    在这里插入图片描述
    卷积核实际上有2X2个神经元,每个神经元的厚度为3,所以1个卷积核有2X2X3个w参数,由于共有10个卷积核,所以共有2X2X3X10个w参数和10个b参数。连接数量为((2X2+1)X10)X25X25=31250。

    卷积核输出组成一个25×25的矩阵,称为特征图。

    第一个神经元连接到图像的第一个2×2的局部,第二个神经元则连接到第二个局部。(注意,有重叠!就跟你的目光扫视时也是连续扫视一样)如果应用参数共享的话,实际上每一层计算的操作就是输入层和权重的卷积。

    下面展示2(输出层的厚度)个3X3X3(卷积核的厚度)的卷积核在7X7X3(输入层的深度)的输入层上做卷积的过程,求出对应输出层的第一个元素(注意有厚度):
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    注释: \bullet 代表矩阵做内积。

    2.2.8 卷积神经网络的参数共享

    给一张输入图片,用一个filter去扫这张图,filter里面的数就叫权重,这张图每个位置是被同样的filter扫的,所以权重是一样的,也就是共享。

    对于一张输入图片,大小为WH,如果使用全连接网络,生成一张XY的feature map,需要WHX*Y个参数,如果原图长宽是 10^2 级别的,而且XY大小和WH差不多的话,那么这样一层网络需要的参数个数是 10^8 ~ 10^{12} 级别。

    这么多参数肯定是不行的,对于输出层feature map上的每一个像素,他与原图片的每一个像素都有连接,每一个连接都需要一个参数。但注意到图像一般都是局部相关的,那么如果输出层的每一个像素只和输入层图片的一个局部相连,那么需要参数的个数就会大大减少。

    假设输出层每个像素只与输入图片上FF的一个小方块有连接,也就是说输出层的这个像素值,只是通过原图的这个FF的小方形中的像素值计算而来,那么对于输出层的每个像素,需要的参数个数就从原来的WH减小到了FF。

    如果对于原图片的每一个FF的方框都需要计算这样一个输出值,那么需要的参数只是WHFF,如果原图长宽是 10^2 级别,而F在10以内的话,那么需要的参数的个数只有10^5 ~ 10{6}级别,相比于原来的108 ~ 10^{12}小了很多很多。这还不够。

    图片还有另外一个特性:图片的底层特征是与特征在图片中的位置无关的。比如说边缘,无论是在图片中间的边缘特征,还是在图片边角处的边缘特征,都可以用过类似于微分的特称提取器提取。那么对于主要用于提取底层特称的前几层网络,把上述局部全连接层中每一个FF方形对应的权值共享,就可以进一步减少网络中参数的个数。也就是说,输出层的每一个像素,是由输入层对应位置的FF的局部图片,与相同的一组FF的参数(或称权值)做内积,再经过非线性单元计算而来的。这样的话无论图片原大小如何,只用FF个参数就够了,也就是几个几十个的样子。当然一组F*F的参数只能得到一张feature map,一般会有多组参数,分别经过卷积后就可以有好几层feature map。

    高级特征一般是与位置有关的,比如一张人脸图片,眼睛和嘴位置不同,那么处理到高层,不同位置就需要用不同的神经网络权重,这时候卷积层就不能胜任了,就需要用局部全连接层和全连接层。
    在这里插入图片描述
    网上找的一张图,示意了局部连接,每一个W只与输入的一部分连接,如果W1和W2是相同的,那么就是卷积层,这时参数W1和W2相同,因此说共享。

    2.3 全连接层

    全连接层的每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来。在前向计算过程,也就是一个线性的加权求和的过程,全连接层的每一个输出都可以看成前一层的每一个结点乘以一个权重系数W,最后加上一个偏置值b得到。

    2.3.1 第1个全连接层

    我们使用包含100个神经元的一层来处理整个图片。权重与bias的tensor如下:
    network weights
    W_fc1 = weight_variable([25 * 25 * 20, 100])
    b_fc1 = bias_variable([100])
    tensor的第一维度表示第二层卷积层的输出,大小为25*25带有20个filters,第二个参数是层中的神经元数量,我们可自由设置。

    那么,全连接层fc1,输入有252520=12500个神经元结点,输出有100个结点,则一共需要252520*100=1250000个权值参数W和100个偏置参数b。
    在这里插入图片描述
    在这里插入图片描述
    接下来,我们将tensor打平到vector中。通过打平后的vector乘以权重矩阵W_fc1,再加上bias b_fc1,最后应用ReLU激活函数后就能实现

    # hidden layers
    h_conv2_flat = tf.reshape(h_conv2, [-1, 25 * 25 * 20])
    h_fc1 = tf.nn.relu(tf.matmul(h_conv2_flat, W_fc1) + b_fc1)
    # tf.matmul(a, b) 将矩阵a乘于矩阵b
    

    2.3.2 第2 个全连接层

    我们使用包含2个神经元的一层来处理整个图片。权重与bias的tensor如下:

    # network weights
    W_fc2 = weight_variable([100, 2])
    b_fc2 = bias_variable([2])
    
    # Q Value layer
    y_out = tf.matmul(h_fc1, W_fc2) + b_fc2
    

    2.4 网络结构

    在这里插入图片描述

    三、读取图像

    inputs = np.zeros([totalImages, imageSize[0], imageSize[1], imageSize[2]])
    print('reading inputs')
    for i in range(totalImages):
        temp = imageSize[0] * imageSize[1]
        inputs[i] = cv2.imread('trainImages/image_' + str(int(i / temp)) + '_' + str(i % temp) + '.png')
    print('inputs read')
    

    四、获取Q值

    4.1 iterations

    imageSize = [25, 25, 3]
    batchSize = 100
    games = 200
    totalImages = games * imageSize[0] * imageSize[1]
    
    iterations = int(totalImages / batchSize)
    

    images一共是25 * 25 * 200 = 125000,然后125000 / 100 = 1250,输出:

    number of iterations is 1250
    

    4.2 getBatchInput

    每次读取一个batchSize的inputs:

    batchInput, start = getBatchInput(inputs, start, batchSize) 
    
    def getBatchInput(inputs, start, batchSize):
        first = start
        start = start + batchSize
        end = start
        return inputs[first:end], start
    

    4.3 batchOutput

    batchOutput = sess.run(y_out, feed_dict={x: batchInput})
    

    其中feed_dict也即把batchInput一个一个赋给x,

    然后把x feed给我们搭好的网络。

    最后把batchOutput赋值给initialTarget:

    for j in range(batchSize):
        initialTarget.append(batchOutput[j])
    

    五、指数衰减

    首先使用较大学习率(目的:为快速得到一个比较优的解);
    然后通过迭代逐步减小学习率(目的:为使模型在训练后期更加稳定)。

    learningRate = 0.001  # 事先设定的初始学习率;
    lr_decay_rate = 0.9  # 衰减系数
    lr_decay_step = 2000  # 衰减速度
    

    生成学习率:

    lr = tf.train.exponential_decay(learningRate,
      global_step,
      lr_decay_step,
      lr_decay_rate,
      staircase=True)
    

    每隔lr_decay_step步,learningRate要乘以lr_decay_rate;
    staircase = True,每decay_steps次计算学习速率变化,更新原始学习速率。

    六、损失函数

    loss = tf.reduce_mean(tf.square(y_out), 1)  # tf.reduce_mean(x, 1)指定第二个参数为1,则第二维的元素取平均值,即每一行求平均值
    
    avg_loss = tf.reduce_mean(loss)  # tf.reduce_mean(x)如果不指定第二个参数,那么就在所有的元素中取平均值 
    

    七、训练模型

    我们已经定义好模型和训练用的损失函数,那么用TensorFlow进行训练就很简单了。因为TensorFlow知道整个计算图,它可以使用自动微分法找到对于各个变量的损失的梯度值。TensorFlow有大量内置的优化算法。我们用Adam优化算法让avg_loss下降,步长为lr。

    train_step = tf.train.AdamOptimizer(lr).minimize(avg_loss)
    

    这一行代码实际上是用来往计算图上添加一个新操作,其中包括计算梯度,计算每个参数的步长变化,并且计算出新的参数值。

    返回的train_step操作对象,在运行时会使用梯度下降来更新参数。因此,整个模型的训练可以通过反复地运行train_step来完成。

    八、运行TensorFlow的InteractiveSession

    sess = tf.InteractiveSession()
    

    Tensorflow依赖于一个高效的C++后端来进行计算。与后端的这个连接叫做session。一般而言,使用TensorFlow程序的流程是先创建一个图,然后在session中启动它。

    这里,我们使用更加方便的InteractiveSession类。通过它,你可以更加灵活地构建你的代码。它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的。这对于工作在交互式环境中的人们来说非常便利,比如使用IPython。如果你没有使用InteractiveSession,那么你需要在启动session之前构建整个计算图,然后启动该计算图。

    九、记录信息

    运行整个程序,在程序中定义的summary node就会将要记录的信息全部保存在指定的logdir 路径中了,训练的记录会存一份文件,测试的记录会存一份文件。

    checkpointFile = 'NewCheckpoints/Checkpoint3.ckpt'
    
    saver = tf.train.Saver()  # 生成saver
    sess.run(tf.initialize_all_variables())  # 先对模型初始化
    

    训练完以后,使用saver.save来保存

    sess.run(tf.initialize_all_variables())
    
    展开全文
  • 桔妹导读:滴滴的路线引擎每天要处理超过400亿次的路线规划请求,路径规划是滴滴地图输出的核心服务之一。不同于传统的路径规划算法,本文主要介绍的是一次深度强化学习路径规划业务场景下的探索...

    桔妹导读:滴滴的路线引擎每天要处理超过400亿次的路线规划请求,路径规划是滴滴地图输出的核心服务之一。不同于传统的路径规划算法,本文主要介绍的是一次深度强化学习在路径规划业务场景下的探索,目标是为用户规划出最符合司乘双方习惯的路线,降低偏航率。

    当我们打开滴滴使用网约车服务时,出发前我们往往会关注要走哪条路,这条路要花多长时间,要花多少钱,有多少个红绿灯,路况是否拥堵......这些都与路径规划密切相关。路径规划对滴滴来说十分重要,它是网约车服务的重要一环,与用户体验直接相关,一次糟糕的“绕路”可能会引起一次投诉进线,甚至影响用户留存;而良好的路径规划不仅可以显著提升司乘双方的使用体验,还能让司机少堵在路上,进一步提升整体出行效率。

    1. 

    滴滴路径规划的背景

    以及业务逻辑的复杂性

    类似于语言任务中的token,物理世界的道路会被建模成一段一段的link,这些link都具有唯一的id以及对应的道路属性,比如长度,方向,道路等级等。对于路口来说,进入路口的link和出路口的link往往都有多个。拿北京举例,北京的路网包含大约200W个link,网约车订单可能会包含数十甚至上百个路口,在如此庞大且复杂的路网中和较为苛刻的时间限制下,规划出高质量的路线绝非易事。

    图中每一个带箭头的红色线段表示一个link,可以看出不同link之间的长度差别是比较大的。

    此外,我们知道物理世界的道路是会发生改变的,这种改变可能是永久的,比如修路,也可能是临时的,比如交通管制。所以路网数据也是动态的,实际上目前我们地图的路网数据是天级更新的,这也加大了路径规划任务的复杂度。

    从实际业务来看,和自驾推荐走更快,更通畅的路线不同,由于网约车会基于里程、时长计费,我们需要同时考虑时间、距离、价格、安全因素,推荐相对快又相对便宜的路线。考虑用户的偏好,让用户在安全、快速到达目的地的同时,让行驶距离尽量短,总花费尽量少,是我们路径规划的核心原则。但很多时候“快”和“近”很难同时满足。距离更短的路往往是次干路或者支路,红绿灯多,堵车可能性更大;而绕远的高速路或者环路,通行能力更强,只要不极拥堵,车速通常更快,反倒用时更短。

    有乘客希望更快,也有乘客希望不绕远。为了尽量平衡,从去年3月起,我们率先在网约车上线了“选择路线”功能,充分考虑乘客的出行偏好,提供最多三条路线供乘客选择(拼车、一口价订单司机需按照平台指定路线行驶);并联动司机服务部鼓励司机主动询问乘客是否有常走路线。今年8月,我们还进一步在北京、杭州、深圳、南京、西安、厦门等28个城市试行“行前多路线选择”功能。乘客实时呼叫网约车,发单前可以根据路线标签、预估里程、行驶时长等信息选择最合适的路线,系统自动同步至司机端导航。

    综上,想要做好让司乘双方都满意的路径规划是一件极具挑战的事情,但是这也为我们进一步提高出行服务质量提供了机遇。

    2. 

    路径规划算法和AI技术的融合 

    路径规划是指给定起终点的情况下,规划出一条或多条由起点到终点的路线。传统的路径规划是一个图论问题,当路网中的权值都是静态的时候,使用dijkstra等算法就可以求出权值之和最小的路线,比如求出两点之间距离最短的路线是容易的。然而在很多场景需要动态权值,调整权值大小也需要大量经验,目前线上采用的方式是先使用基于图论的算法生成一批低权值的路线,然后再经过基于机器学习算法的排序模型的筛选,这个过程涉及到粗排,精排,rerank,最后将排名靠前的路线透出给用户选择。这个路线规划系统涉及的链路还是比较长的,不同于基于图论算法生成高权值的路线,我们尝试探索一种基于AI算法的路线生成方式。

    得益于滴滴海量的出行数据尤其是高质量的轨迹数据,我们可以利用深度学习技术去挖掘和学习司机的驾驶行为以及用户对路线的偏好,借助训练出的深度模型在短时间内为用户规划出满意的路线,降低线上的偏航率。

    我们这里可以把寻路的过程和AlphaGo下围棋的场景进行类比,司机在路网中行驶犹如棋手在棋盘上落子,初级棋手往往通过记忆棋谱来获取暂时的领先,而最终赢棋往往要求棋手有“大局观”,每一步的落子考虑到之后棋局的演变,关键在于最终赢棋,而不在于一时的得失。寻路过程也是需要往后多看几步的,因为在某个路口的选择眼前可能看是最优的,放在全局看则不一定是最好的选择。我们探索路线生成的过程是和AlphaGo“进化”过程是相似的[1],是一个从监督学习到强化学习的过程。

    3. 

    规划最符合司乘习惯的路线:

    从监督学习到强化学习 

    3.1 “克隆”高质量的历史轨迹

    我们最先想到的是使用行为克隆(behavior clone)的方式解决寻路问题,这里可以将寻路看作一个连续决策的过程,把用户的历史真实轨迹当做专家轨迹,在每个路口(对应一个状态)用户作出的选择看作是一个近似最优的动作(action),接下来我们就可以在每个决策点做分类,专家行为作为正样本,非专家行为作为负样本,让分类模型去判断某个决策是否符合用户习惯,分类器会对一个状态和动作对输出一个概率值,这个概率越大代表用户越有可能在该状态采取对应的动作。这点与AlphaGo中的走子网络是类似的:通过专业棋手的棋谱数据来训练模型,让它学习专业棋手的下棋行为。

    在实际处理中,因为路线是被建模成连续的link序列,所以我们在网络结构中引入了在序列预测上表现强大的lstm,用lstm可以更好地建模用户从起点到当前位置的状态信息,在经过百万量级条轨迹训练后,我们的模型在每个路口的决策准确率达到了98%+,我们将这个能够在每个路口输出决策概率的模型称作寻路agent,它已经基本可以模拟用户的真实选择。

    如果在每一次决策都选择概率最大的那一个link(即贪心搜索)往往只能找到局部最优解,比如一条路前半段看起来更优,但是后半段可能不是最佳的。为了尽可能找到最符合用户习惯(即整条路线的概率最大),我们使用了beam search搜索策略,其主要思想就是在寻路过程中维护若干个(即beam size)最优的候选集,这种方式相比穷举法大大缩减了需要探索的空间,相比于贪心搜索考虑的情况更多,往往能够找到得分更高的路线,在自然语言处理领域,比如机器翻译任务中被大量使用。可以通过下面简单的例子理解beam search的过程。

    图中移动的小车展示了beam search在路径规划中的应用,在小车前进的过程中,我们可以给不同的路线打分,维护得分最高的topK路线,直到小车抵达终点。红色的路线表示最终得分最高的路线,也是最符合用户习惯的路线。

    3.2 行为克隆的问题

    行为克隆实际上属于监督学习的范畴,在AlphaGo中如果让agent纯粹的去学习棋谱中的走法,它很难打败更加专业的棋手,所以AlphaGo引入了强化学习并搭配MCTS这一搜索策略,从而大大提升了对弈的胜率。同样的,纯粹的拟合专家轨迹是存在问题的:当寻路agent在某个路口判断错误,那么就会进入到没有遇到过的状态,在这种状态下agent的判断容易出错,而错误的累积会容易导致寻路过程演变成“一步错步步错”的结果。虽然我们的模型具有一定的泛化能力,寻路agent也可以找到终点,但由于我们没有显式的引入偏航后的监督信号,寻路agent往往需要更多不必要的“绕路”才能回到理想的路线上来。图中蓝色轨迹是小车偏航后所致,小车既有可能回到demo轨迹(红色路线)上来,也有可能越来越远,偏离demo轨迹,因为模型并没有学习到发生偏航后该如何快速纠正。

    3.3 强化学习的应用

    强化学习是近年来解决行为克隆带来的问题的热门方向。在文本生成领域,seqGAN通过判别器(简称D)来指导生成器(简称G)的训练,在G生成下一个单词时,使用MCTS和D来评估这个单词的好坏,通过reward作为反馈,使用Policy Gradient来更新G的参数,从而增加reward大的单词的生成概率。与此方法类似的还有在游戏系列数据集上表现优秀的GAIL,AIRL,这些方法的主要思想是另外训练一个能够指导生成网络更新的评估网络,缺点在于略显复杂,训练难度和计算量较大。

    AlphaGoZero通过“自己与自己对弈”的过程大大增强了棋力,类似的,我们想要通过生成学习的方式来增强路线引擎的能力。这里我们采用Q-learning的方式来学习一个寻路策略,为了加速模型收敛的速度,我们这里先使用前文提到的行为克隆的方式训练一个能够容易走到目的地的基础模型,然后使用该基础模型在路网上寻路,生成大量的采样轨迹,如果在某个状态,模型采取的动作与用户一致,则给该状态-动作对以+1的reward,相反如果在该状态模型采取的动作与用户不一致,则给该状态-动作对的reawrd为0。这种人为设定reward的方式既没有引入对抗学习的过程,也不要额外学一个reward函数,计算量大幅度减小,同时它可以有效克服行为克隆带来的状态分布偏移的问题。

    图中大致展示了我们的训练流程,通过老模型的self-play获取新的轨迹数据,将采样得到的新轨迹和真实轨迹融合训练,更新我们的策略模型,该过程是可以不断迭代的。经过多轮迭代后,路线生成模型的分类准确率虽然没有明显提升,但是生成轨迹质量更高:与真实轨轨迹的重合率明显提高,偏航后返回到demo轨迹的速度更快。这是让人惊喜的结果。

    4. 

    总结

    滴滴的路线引擎每天需要处理超过400亿次的路线规划请求,我们致力于为平台用户提供安全,快捷的路线服务。本文介绍的路线生成方式是深度强化学习在路径规划业务上落地的一次探索,主要用来降低偏航率。考虑到路径规划业务的复杂性,我们会从更多的方向(比如躲避拥堵)来打磨我们的路线引擎,让它变得更加智能。

    当然目前路线引擎还有它不完善的地方,还需要持续的迭代和优化,也欢迎大家给我们提供宝贵的意见。我们团队将会持续优化路线引擎系统的性能,迭代路线规划的算法,为司机和乘客创造更大的用户价值。

    引用

    1. Mastering the game of Go with deep neural networks and tree search[J]. Nature, 2016, 529(7587):484-489.

    本文作者

    团队招聘

    滴滴地图与公交事业群定位团队负责为滴滴平台上的司乘双方提供精准的定位服务,构建出行基础设施,发挥平台的大数据优势,应用概率统计、机器学习、深度学习等技术,在GPS质量优化、网络定位、惯导推算、融合定位等细分方向上持续深耕,以技术驱动用户体验的提升。

    团队长期招聘算法工程师,包括机器学习、惯导推算等方向,欢迎有兴趣的小伙伴加入,可投递简历至 diditech@didiglobal.com,邮件请邮件主题请命名为「姓名-应聘部门-应聘方向」。

    扫描了解更多

    延伸阅读


    
    内容编辑 | Charlotte联系我们 | DiDiTech@didiglobal.com
    
    
    展开全文
  • README This is a project about deep reinforcement learning autonomous obstacle avoidance algorithm for UAV. The whole project includes obstacle avoidance in static environment and obstacle avoidance

    地址:https://github.com/ZYunfeii/UAV_Obstacle_Avoiding_DRL

    README

    This is a project about deep reinforcement learning autonomous obstacle avoidance algorithm for UAV. The whole project includes obstacle avoidance in static environment and obstacle avoidance in dynamic environment. In the static environment, Multi-Agent Reinforcement Learning and artificial potential field algorithm are combined. In the dynamic environment, the project adopts the combination of disturbed flow field algorithm and single agent reinforcement learning algorithm.

    Static environment

    There are four methods to solve:

    1. MADDPG
    2. Fully Centralized DDPG
    3. Fully Decentralized DDPG
    4. Fully Centralized TD3

    The third and the fourth methods perform better than others.

    Dynamic environment

    There are four methods to solve:

    1. PPO+GAE(with multi-processing )
    2. TD3
    3. DDPG
    4. SAC

    The first three methods perform just the same. PPO convergence needs less episodes. TD3 and DDPG converge fast. Though Soft Actor-Critic is an outstanding algorithm in DRL, it has no obvious effect in my environment.

    Traditional methods for UAV path planning

    Three traditional methods are written with MATLAB:

    1. A * search algorithm*
    2. RRT algorithm
    3. Ant colony algorithm

    C++:

    1. D star algorithm

    The experiments show that A* search algorithm is much better than others but it is less effective than reinforcement learning path planning.

    Artificial potential field algorithm

    This project provides the MATLAB and Python realization of artificial potential field algorithm.

    Python realization: ./APF/APFPy2.py ./APF/APFPy3.py ./APF/ApfAlgorithm.py (two-dimensional and three-dimensional)

    Matlab realization: ./APF/APF_matlab (two-dimensional)

    IFDS and IIFDS algorithm

    This is an obstacle avoidance planning algorithm based on flow field. I realize it with matlab. The code is in folder IIFDS_and_IFDS.

    How to begin trainning

    For example, you want to train the agent in dynamic environment with TD3, what you need to do is just running the main.py, then test.py, finally open matlab and run the test.m to draw.

    If you want to test the model in the environment with 4 obstacles, you just need to run Multi_obstacle_environment_test.py.

    Requirements

    numpy

    torch

    matplotlib

    seaborn==0.11.1

    Files to illustrate

    calGs.m: calculate the index Gs which shows the performance of the route.

    calLs.m: calculate the index Ls which shows the performance of the route.

    draw.py: this file includes the Painter class which can draw the reward curve of various methods.

    config.py: this file give the setting of the parameters in trainning process of the algorithm such as the MAX_EPISODE, batch_size and so on.

    Method.py: this file concludes many important methods such as how to calculate the reward of the agents.

    static_obstacle_environment.py: there are many static obstacle environments’ parameters in this file.

    dynamic_obstacle_environment.py: there are many dynamic obstacle environments’ parameters in this file.

    Multi_obstacle_environment_test.py: this file test the dynamic model in the environment in dynamic_obstacle_environment.py.

    data_csv: this file save some data such as the trace of UAV and the reward in trainning.

    AntColonybenchmark.m: ACO algorithm realized by MATLAB.

    Astarbenchmark.m: A* algorithm realized by MATLAB.

    RRTbenchmark.m: RRT algorithm realized by MATLAB.

    A simple simulation example

    • 见github

    all rights reserved.

    展开全文
  • 多点路径规划指标机器人强化学习 增强学习已成为研究和研究的热门话题,该领域的许多领域都未曾动过。 这些领域之一是在物理机器人上实施强化学习算法。 我探索了在物理定制3D打印机器人Benny和Bunny上实现RL算法的...

空空如也

空空如也

1 2 3 4 5 6
收藏数 106
精华内容 42
关键字:

强化学习路径规划