• Eclipse Deeplearning4j GitChat课程:https://gitbook.cn/gitchat/column/5bfb6741ae0e5f436e35cd9fEclipse Deeplearning4j 系列博客:...

    Eclipse Deeplearning4j GitChat课程https://gitbook.cn/gitchat/column/5bfb6741ae0e5f436e35cd9f
    Eclipse Deeplearning4j 系列博客https://blog.csdn.net/wangongxi
    Eclipse Deeplearning4j Githubhttps://github.com/eclipse/deeplearning4j

    在之前的博客中,我用Deeplearning4j构建深度神经网络来解决监督、无监督的机器学习问题。但除了这两类问题外,强化学习也是机器学习中一个重要的分支,并且Deeplearning4j的子项目--Rl4j提供了对部分强化学习算法的支持。这里,就以强化学习中的经典任务--Cartpole问题作为学习Rl4j的入门例子,讲解从环境搭建、模型训练再到最后的效果评估的结果。

    Cartpole描述的问题可以认为是:在一辆小车上竖立一根杆子,然后给小车一个推或者拉的力,使得杆子尽量保持平衡不滑倒。更详细的描述可参见openai官网上关于Cartpole问题的解释:https://gym.openai.com/envs/CartPole-v0

    接着给出强化学习的一些概念:environment,action,reward

    environment:描述强化学习问题中的外部环境,比如:Cartpole问题中杆子的角度,小车的位置、速度等。

    action:在不同外部环境条件下采取的动作,比如:Cartpole问题中对于小车施加推或者拉的力。action可以是离散的集合,也可以是连续的。

    reward:对于agent/network作出的action后获取的回报/评价。比如:Cartpole问题中如果施加的力可以继续让杆子保持平衡,那reward就+1。

    在描述reward这个概念时,提到了agent这个概念,在实际应用中,agent可以用神经网络来实现。

    对于强化学习训练后的agent来说,学习到的是如何在变化中的environment和reward选择action的能力。通常有两种学习策略可以选择:Policy-Based和Value-Based。 Policy-Based直接学习action,通过Policy Gradient来更新模型参数,而相对的,Value-Based是最优化action所带来的reward(action-value function,Q-function)来间接选取action。一般认为如果action是离散的,那么Value-Based会优于Policy-Based,而连续的action则相反。在这里主要讨论Value-Based的学习策略,或者更具体的说Q-learning的问题。对于Policy-Based还有Model-Based不做讨论。

    Q-learning的概念早在20多年前就已经提出,再与近年来流行的深度神经网络结合产生了DQN的概念。Q-learning的目标是最大化Q值从而学习到选取action的策略。Q-leaning学习的策略公式:

    Q(st,at)←Q(st,at)+α[rt+1+λmaxaQ(st+1,a)−Q(st,at)]

    对于这里主要讨论的Catpole问题,我们也采用Q-learning来实现。

    可以看到,与监督学习相比,强化学习多了action,environment等概念。虽然可以将reward类比成监督学习中的label(或者反过来,label也可以认为是强化学习中最终的reward),但通过action与environment不断的交互甚至改变environment这一特点,是监督学习中所没有的。在构建应用的时候,监督学习的学习的目标:label,灌入的数据都是一个定值。比如,图像的分类的问题,在用CNN训练的时候,图片本身不发生变化,label也不会发生变化,唯一变化的是神经网络中的权重值。但强化学习在训练的时候,除了神经网络中的权重会发生变化(如果用NN建模的话),environment、reward等都会发生动态的变化。这样构建合适正确的训练数据会比较麻烦,容易出错,所以对于CartPole问题,我们可以采用openAI提供的强化学习开发环境gym来训练/测试agent。

    gym的官方地址:https://gym.openai.com/

    gym提供了棋类、视频游戏等强化学习问题的学习/测试/算法效果比较的环境。这里要处理的Cartpole问题,gym也提供了环境的支持。但是,除了python,gym对其他语言的支持不是很友好,所以为了可以获取gym中的数据,RL4j提供了对gym-http-api(https://github.com/openai/gym-http-api)调用的包装类。gym-http-api是为了方便除python外的其他语言也可以使用gym环境数据的一个REST接口。简单来说,对于像RL4j这样以Java实现的强化学习算法库可以通过gym-http-api获取gym提供的数据。

    gym的REST接口的安装可以参见之前给出的github地址,里面有详细的描述。下面先给出gym-http-api的安装和启动过程的截图:

    下面就结合上面说的内容,给出RL4j的Catpole实现逻辑

    1. 定义Q-learning的参数以及神经网络结构,两者共同决定DQN的属性

    2. 定义读取gym数据的包装类对象

    3. 训练DQN并保存模型

    4. 加载保存的模型并测试

    这里先贴下需要的Maven依赖以及代码版本

     

      <properties>
    	  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    	  <nd4j.version>0.8.0</nd4j.version>  
    	  <dl4j.version>0.8.0</dl4j.version>  
    	  <datavec.version>0.8.0</datavec.version>  
    	  <rl4j.version>0.8.0</rl4j.version>
    	  <scala.binary.version>2.10</scala.binary.version>  
      </properties>
      <dependencies>
    	<dependency>  
    		<groupId>org.nd4j</groupId>  
    		<artifactId>nd4j-native</artifactId>   
    		<version>${nd4j.version}</version>  
    	</dependency>  
            <dependency>  
    		<groupId>org.deeplearning4j</groupId>  
    		<artifactId>deeplearning4j-core</artifactId>  
    		<version>${dl4j.version}</version>  
    	</dependency>  
            <dependency>
                <groupId>org.deeplearning4j</groupId>
                <artifactId>rl4j-core</artifactId>
                <version>${rl4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.deeplearning4j</groupId>
                <artifactId>rl4j-gym</artifactId>
                <version>${rl4j.version}</version>
            </dependency>
    
      </dependencies>

     

     

     

     

     

    第一部分的代码如下:

     

        public static QLearning.QLConfiguration CARTPOLE_QL =
                new QLearning.QLConfiguration(
                        123,    //Random seed
                        200,    //Max step By epoch
                        150000, //Max step
                        150000, //Max size of experience replay
                        32,     //size of batches
                        500,    //target update (hard)
                        10,     //num step noop warmup
                        0.01,   //reward scaling
                        0.99,   //gamma
                        1.0,    //td-error clipping
                        0.1f,   //min epsilon
                        1000,   //num step for eps greedy anneal
                        true    //double DQN
                );
    
        public static DQNFactoryStdDense.Configuration CARTPOLE_NET = DQNFactoryStdDense.Configuration.builder()            												.l2(0.001)            																        .learningRate(0.0005)
           								.numHiddenNodes(16)
               							.numLayer(3)
                							.build();

     

    第一部分中定义Q-learning的参数,包括每一轮的训练的可采取的action的步数,最大步数以及存储过往action的最大步数等。除此以外,DQNFactoryStdDense用来定义基于MLP的DQN网络结构,包括网络深度等常见参数。这里的代码定义的是一个三层(只有一层隐藏层)的全连接神经网络。

    接下来,定义两个方法分别用于训练和测试。catpole方法用于训练DQN,而loadCartpole则用于测试。

    训练:

     

        public static void cartPole() {
    
            //record the training data in rl4j-data in a new folder (save)
            DataManager manager = new DataManager(true);
    
            //define the mdp from gym (name, render)
            GymEnv<Box, Integer, DiscreteSpace> mdp = null;
            try {
                mdp = new GymEnv<Box, Integer, DiscreteSpace>("CartPole-v0", false, false);
            } catch (RuntimeException e){
                System.out.print("To run this example, download and start the gym-http-api repo found at https://github.com/openai/gym-http-api.");
            }
            //define the training
            QLearningDiscreteDense<Box> dql = new QLearningDiscreteDense<Box>(mdp, CARTPOLE_NET, CARTPOLE_QL, manager);
    
            //train
            dql.train();
    
            //get the final policy
            DQNPolicy<Box> pol = dql.getPolicy();
    
            //serialize and save (serialization showcase, but not required)
            pol.save("/tmp/pol1");
    
            //close the mdp (close http)
            mdp.close();
    
        }


    测试:

     

     

        public static void loadCartpole(){
    
            //showcase serialization by using the trained agent on a new similar mdp (but render it this time)
    
            //define the mdp from gym (name, render)
            GymEnv<Box, Integer, DiscreteSpace> mdp2 = new GymEnv<Box, Integer, DiscreteSpace>("CartPole-v0", true, false);
    
            //load the previous agent
            DQNPolicy<Box> pol2 = DQNPolicy.load("/tmp/pol1");
    
            //evaluate the agent
            double rewards = 0;
            for (int i = 0; i < 1000; i++) {
                mdp2.reset();
                double reward = pol2.play(mdp2);
                rewards += reward;
                Logger.getAnonymousLogger().info("Reward: " + reward);
            }
    
            Logger.getAnonymousLogger().info("average: " + rewards/1000);
            
            mdp2.close();
    
        }

    在训练模型的方法中,包含了第二、三步的内容。首先需要定义gym数据读取对象,即代码中的GymEnv<Box, Integer, DiscreteSpace> mdp。它会通过gym-http-api的接口读取训练数据。接着,将第一步中定义的Q-learning的相关参数,神经网络结构作为参数传入DQN训练的包装类中。其中DataManager的作用是用来管理训练数据。

    测试部分的代码实现了之前说的第四步,即加载策略模型并进行测试的过程。在测试的过程中,将每次action的reward打上log,并最后求取平均的reward。

    训练的过程截图如下:

     

    最后我们其实最关心的还是这个模型的效果。纯粹通过平均reward的数值大小可能并不是非常的直观,因此这里给出一张gif的效果图:

    总结一下Cartpole问题的整个解决过程。首先我们明确,这是一个强化学习的问题,而不是传统的监督学习,因为涉及到与环境的交互等因素。然后,利用openAI提供的强化学习开发环境gym来构建训练平台,而RL4j则可以定义并训练DQN。最后的效果就是上面这张gif图片。需要注意的是,这张gif效果图并非是RL4j直接生成的,而是通过xvfb命令截取虚拟monitor的在每个action后的效果拼接起来的图。具体可先查阅xvfb的相关内容。

    展开全文
  • Q学习sarsa学习 java

    2020-04-24 23:31:37
    Q学习算法sarsa学习算法的Java示例。
  • 强化学习 强化学习和遗传算法优胜劣汰的思想类似,通过奖惩机制不断强化好的行为,弱化坏的行为。什么是好的行为,什么是坏的行为,这跟你要解决的具体问题有关,比如路径规划问题,走距离目标点较近的路线就是好的...

    一、强化学习

    强化学习和遗传算法优胜劣汰的思想类似,通过奖惩机制不断强化好的行为(action),弱化坏的行为。至于什么是好的行为,什么是坏的行为,跟你要解决的具体问题有关,比如路径规划问题,走距离目标点较近的路线就是好的行为,走距离目标点较远的路线就是坏的行为。

    强化学习包含四要素:agent、环境状态、动作和奖励,目标是获得最多的累计奖励。

    二、Q learning

    Q learning 融合了马尔科夫过程和动态规划,使用贝尔曼方程求解马尔科夫过程。今天我们不展开讲马尔科夫过程和贝尔曼方程,因为那样入门起来就不简单了,今天仅从算法过程的角度理解并入门,马尔科夫过程和贝尔曼方程是入门后再去深入研究的原理性部分。

    Q learning 最重要的数据结构为 Q 表,Q 是 quality 的缩写。算法最终就是要学习到一张好的 Q 表,这样我们就可以根据 Q 表对环境中的任何情况(状态)都能给出一个好的反应(动作)。具体的,就是每次都选择 Q 表中对应状态下具有最大 Q 值的动作。

    图1
    Q 表一般用二维数组表示,每一行表示一个状态,每一列表示一个动作。 例如上图所示的基于移动的二维游戏,每个状态(方块)有四个动作:左移、右移、上移、下移。

    q表
    0 代表不能向对应方向移动的地形边缘。

    算法流程图:
    算法流程
    伪码描述:

    初始化Q表
    while Q表未收敛:
    	初始化状态s,开始新一轮训练
    	while s != 目标状态
    		使用策略(E-greedy)获得动作a
    		执行动作转换到下一个状态s1,并获得奖励r(s,a)
    		Q[s,a] = (1-alpha)*Q[s,a]+alpha*(r(s,a)+gamma*max(Q[s1])) // update Q
    		s = s1
    

    后面我们会有一个和这个伪码描述完全一致的 java 实现,可以对比理解。

    看完伪码描述后,我们的脑海里可能会有两个迫切想要了解的点。

    关键点一:更新公式如何理解?

    更新公式
    奖励由两部分组成:

    1. 眼前的奖励;
    2. 未来的奖励,衰减因子 γ(0,1)\gamma\in(0,1) 表示对未来奖励的重视程度

    新的 Q 值是旧的 Q 值和奖励的凸组合,换句话说就是新的 Q 值一定介于旧的 Q 值和奖励之间。

    因为奖励中包含未来的奖励,所以如果未来收益很小,说明照此发展下去,未来不容乐观,Q 值就会变小,下次在状态 s 下选择动作 a 的可能性就会变小。

    相反的,如果未来收益很大,Q 值就会变大,下次在状态 s 下选择动作 a 的可能性就会变大。

    关键点二:使用策略(ϵ\epsilon-greedy)获得动作,使用什么策略?为什么?

    Q 表训练完成后,我们可以每次都选择 Q 表中对应状态下具有最大 Q 值的动作作为决策。但是在训练过程中,这样选择动作是否合理呢?

    答案是不合理,为什么,因为在初始阶段,Q 表中大部分的值还没更新,普遍比较小。一旦找到一个可以到达目标状态的策略(往往不是最优的),那么以后每次按照最大值决策,就都会使用那一个策略,因为其它 Q 值都比较小,没有机会被选择到。所以在训练过程中过于贪婪(greedy)的使用 Q 表选择动作,很容易陷入局部最优,并且跳不出来。

    一般在训练时,通过 epsilon(ϵ\epsilon)参数控制 agent 的贪婪程度,例如 epsilon = 0.9,表示 90% 的时间使用 Q 表做决策,10% 的时间随机选择动作来探索未知的环境。

    三、java 实现的小例子

    一个简单的不能再简单的小例子。

    问题:最短路径,寻找起始点A到目标点D的最短路径。
    图
    设计

    package main;
    import java.util.Arrays;
    public class Qlearning {
    	public static void main(String[] args) {
    		double[][] Q = new double[][] {
    			{-1,  0,  0, -1},
    			{-1, -1, -1,  0},
    			{-1, -1, -1,  0},
    			{-1, -1, -1, -1}
    		};
    		
    		int[][] graph = new int[][] {
    			{0, 3, 2, 0},
    			{0, 0, 0, 1},
    			{0, 0, 0, 4},
    			{0, 0, 0, 0}
    		};
    		
    		double epsilon = 0.8;
    		double alpha = 0.2;
    		double gamma = 0.8;
    		int MAX_EPISODES = 400; // 一般都通过设置最大迭代次数来控制训练轮数
    		for(int episode = 0; episode < MAX_EPISODES; ++episode) {
    			System.out.println("第"+episode+"轮训练...");
    			int index = 0;
    			while(index != 3) { // 到达目标状态,结束循环,进行下一轮训练
    				int next;
    				if(Math.random() < epsilon) next = max(Q[index]); // 通过 Q 表选择动作
    				else next = randomNext(Q[index]); // 随机选择可行动作
    				
    				int reward =5 - graph[index][next]; // 奖励
    				Q[index][next] = (1-alpha)*Q[index][next] + alpha*(reward+gamma*maxNextQ(Q[next]));
    				index = next; // 更新状态
    			}
    		}
    		System.out.println(Arrays.deepToString(Q));
    	}
    
    	private static int randomNext(double[] is) { // 蓄水池抽样,等概率选择流式数据
    		int next = 0, n = 1;
    		for(int i = 0; i < is.length; ++i) {
    			if(is[i] >= 0 && Math.random() < 1.0/n++) next = i;
    		}
    		return next;
    	}
    
    	private static int max(double[] is) {
    		int max = 0;
    		for(int i = 1; i < is.length; ++i) {
    			if(is[i] > is[max]) max = i;
    		}
    		return max;
    	}
    	
    	private static double maxNextQ(double[] is) {
    		double max = is[0];
    		for(int i = 1; i < is.length; ++i) {
    			if(is[i] > max) max = is[i];
    		}
    		return max;
    	}
    
    }
    

    Q 表的更新过程:
    更新过程
    第三个 Q 表其实已经收敛。

    Q(s,a)=(1α)Q(s,a)+α(R+γmaxQ(s))Q(s,a)=(1-\alpha)Q(s,a)+\alpha(R+\gamma\cdot \max Q(s^{'}))

    (1-0.2)*4.56 + 0.2*(2+0.8*3.2)=4.56
    (1-0.2)*3.16 + 0.2*(3+0.8*0.2)=3.16
    (1-0.2)*3.2 + 0.2*(4-0.8)=3.2
    (1-0.2)*0.2 + 0.2*(1-0.8)=0.2

    对照着公式,通过手工计算可以看到所有的 Q 值已经趋于稳定,继续迭代,Q 值也不会发生更新。

    对比 Q 表的更新过程可以发现,刚开始时,还会选择 A->C 这条路径,因为短期从 A->C 能够获得更多的奖励,但是当接受到未来奖励的反馈后,开始逐渐倾向于 A->B,并最终选择 A-> B 路径,因为从 B->D 会获得比从 C->D 大得多的奖励。这也体现了强化学习延迟反馈的特征。

    参数设置对模型的影响:

    • epsilon 过大,模型不容易收敛。
    • alpha 过小,模型不容易收敛。
    • gamma 改变最终的收敛结果也会改变。(强化学习的目的就是根据累计收益做决策,如果 gamma 过小,把眼前利益看的太重,不容易得到最优解)

    代码中用到了蓄水池抽样技术,可以等概率的选择流式数据,如果对蓄水池抽样感兴趣可以看看这篇文章

    展开全文
  • 选自DeepLearning4j机器之心编译参与:Nurhachu Null、李泽南从 AlphaGo 到自动驾驶汽车,我们能在很多最先进的人工智能应用中找到强化学习的身影。这种技术是如何从零开始慢慢学会完成任务,成长为「超越人类水平」...
    
      
        

    选自DeepLearning4j

    机器之心编译

    参与:Nurhachu Null、李泽南


    从 AlphaGo 到自动驾驶汽车,我们能在很多最先进的人工智能应用中找到强化学习的身影。这种技术是如何从零开始慢慢学会完成任务,成长为「超越人类水平」的专家的?本文将会进行一番简要介绍。


    神经网络造就了最近我们在计算机视觉、机器翻译和时间序列预测等领域上的突破—同时它也可以和强化学习算法结合来创建一些惊人的成果,例如 AlphaGo(参阅:无需人类知识,DeepMind 新一代围棋程序 AlphaGo Zero 再次登上 Nature)。


    强化学习指的是面向目标的算法,这种算法学习如何在一些具体的步骤中达到一个目标或者最大化;例如,最大化一个游戏中通过一些行动而获得的得分。它们可以从一个空白状态开始,然后在合适的条件下达到超越人类水平的性能。就像被糖果和体罚刺激的小孩子一样,当它们做出错误的预测时,这些算法会受到惩罚,当它们做出正确的预测时,它们会得到奖励—这便是强化的意义所在。


    结合深度学习的强化算法可以在围棋和 Atari 游戏中打败人类冠军。尽管这听起来还不具有足够的说服力,但是这已经远远优于它们之前的成就了,而且目前最先进的进步是很迅速的。


    两个强化学习的算法 Deep-Q learning 和 A3C 已经在 Deeplearning4j 库上实现了,现在,它已经可以玩《毁灭战士(Doom)》了。


    强化学习解决了对即刻行动和与之相关的延迟响应之间的关联的问题。就像人类一样,强化学习算法必须等待一会,看看它们决策的结果如何。它们运行在延迟响应的环境之中,在这种环境中理解哪些行动在多个步骤后导致哪些结果是很困难的。


    我们可以期望强化学习算法在更加模糊的现实环境中表现得更好,它可以在真实环境下从任意多个可能的行动中进行选择,而不是从有限个电子游戏动作选项中进行选择。也就是说,随着时间的推移,我们希望它们(强化学习算法)能够在现实世界中有着实现目标的价值。


    强化学习入门(https://docs.skymind.ai/docs?__hstc=3042607.e3fc0b81c1643174a38ec061d10e5084.1517447567935.1517447567935.1517447567935.1&__hssc=3042607.1.1517447567935&__hsfp=3282609078)


    强化学习定义


    我们可以通过了解智能体、环境、状态、行动以及奖励等概念来理解强化学习,我们会在一下的内容里解释这些概念。大写字母表示事物的集合,小写字母代表事物的实例;例如,A 是所有可能存在的行动的集合,而 a 是这个集合中包含的一个实例。


    • 智能体(Agent):可以采取行动的智能个体;例如,可以完成投递的无人机,或者在视频游戏中朝目标行动的超级马里奥。强化学习算法就是一个智能体。而在现实生活中,那个智能体就是你。

    • 行动(Action):A 是智能体可以采取的行动的集合。一个行动(action)几乎是一目了然的,但是应该注意的是智能体是在从可能的行动列表中进行选择。在电子游戏中,这个行动列表可能包括向右奔跑或者向左奔跑,向高出处跳或者向低处跳,下蹲或者站住不动。在股市中,这个行动列表可能包括买入,卖出或者持有任何有价证券或者它们的变体。在处理空中飞行的无人机时,行动选项包含三维空间中的很多速度和加速度。

    • 环境(Environment):指的就是智能体行走于其中的世界。这个环境将智能体当前的状态和行动作为输入,输出是智能体的奖励和下一步的状态。如果你是一个智能体,那么你所处的环境就是能够处理行动和决定你一系列行动的结果的物理规律和社会规则。

    • 状态(State,S):一个状态就是智能体所处的具体即时状态;也就是说,一个具体的地方和时刻,这是一个具体的即时配置,它能够将智能体和其他重要的失事物关联起来,例如工具、敌人和或者奖励。它是由环境返回的当前形势。你是否曾在错误的时间出现在错误的地点?那无疑就是一个状态了。

    • 奖励(Reward,R):奖励是我们衡量某个智能体的行动成败的反馈。例如,在视频游戏中,当马里奥碰到金币的时候,它就会赢得分数。面对任何既定的状态,智能体要以行动的形式向环境输出,然后环境会返回这个智能体的一个新状态(这个新状态会受到基于之前状态的行动的影响)和奖励(如果有任何奖励的话)。奖励可能是即时的,也可能是迟滞的。它们可以有效地评估该智能体的行动。

    • 策略(policy,π):policy 是智能体基于当前的状态做出下一步行动所用的策略。

    • 价值(value,V):期望的具有折扣的长期收益,而不是短期回报 R。我们定义 Vπ(s) 为当前状态为 s 时基于策略π的长期回报。

    • Q 价值或者行动价值(Q):Q 价值(Q-Value)和上述的价值类似,不同的是它还使用了另一个参数--当前的行动 a。Vπ(s) 指的是基于当前状态 s,行动 a 和策略π,得到的长期回报。


    所以,环境就是能够将当前状态下采取的动作转换成下一个状态和奖励的函数;智能体是将新的状态和奖励转换成下一个行动的函数。我们可以知悉智能体的函数,但是我们无法知悉环境的函数。环境是一个我们只能看到输入输出的黑盒子。强化学习相当于智能体在尝试逼近这个环境的函数,这样我们就能够向黑盒子环境发送最大化奖励的行动了。



    在上图的反馈回路中,每一个代表时间步骤的下标 t 和 t+1 都指的是一个不同的状态:在 t 时刻和 t+1 时刻的状态。与其他诸如监督学习和非监督学习形式不同—强化学习仅可以被认为是一系列先后发生的状态-行动(state-action)对。


    强化学习通过行动产生的结果来判断行动。它是面向目标的,它的目标是习得能够让智能体达到目标的一些行动序列。这里有一些例子:


    • 在电子游戏中,这个目标是以最高的分数完成游戏,所以游戏过程中每一次得到的额外分数都会影响智能体随后的行动;也就是说,智能体可能学会:为了最大化它的得分,他应该射击战舰,触碰硬币或者躲避流星。

    • 在现实世界中,一个机器人的目标可能是从 A 点移动到 B 点,机器人从 A 点向 B 点移动的每一英寸都算作得分。


    可以通过对输入的解释将强化学习与监督学习和非监督学习区分开来。我们可以通过描述它们学习的「东西」来说明它们的不同之处。


    • 无监督学习:那东西就是这个样子的。(无监督学习算法学到了没有名字的事物之间的相似性,通过进一步的扩展,它们可以通过识别不寻常或者不相似的实例来发现相反或者执行异常检测)

    • 监督学习:那个东西是一块「双层吉士汉堡」。(标签,联系名字和面孔……)这些监督学习算法学到了数据实体实例和它们的标签之间的关联;也就是说,监督学习算法需要有一个有标签的数据集。那些标签被用来「监督」和矫正算法,因为算法在预测标签的时候可能会做出错误的猜测。

    • 强化学习:吃了这个东西,因为它味道蛮不错,而且可以让你活得更久。(基于短期和回报和长期回报的奖励,就相当于你摄入的卡路里或者你生存的时间一样。)强化学习可以被看做是在一个具有稀疏反馈的环境中的监督学习。


    强化学习的域选择


    可以将一个自动强化学习的智能体想象为一个盲人,这个盲人智能依靠耳朵和手中的白手杖来尝试在这个世界中导航。智能体有一些允许它们感知所处环境的小窗,但是那些小窗甚至是最不适合它们感知周遭环境的最不适合的方式。


    事实上,决定你的智能体的输入和反馈类型是一个需要解决的复杂问题。这就是所谓的域选择问题。学习玩电子游戏的算法可以忽略这个问题,因为它们的环境是人为设定的,而且是受到严格限制的。因此,电子游戏提供了无菌的实验室环境,可以在里面测试强化学习的想法。域选择需要人为决定,通常是基于需要解决的问题的知识或理论来进行的;例如,在无人车的算法中输入域的选择可能包括雷达传感器、相机以及 GPS 数据的信息。



    状态-动作对(state-action pair)& 复杂的奖励概率分布


    强化学习算法的目标是习得针对任意给定状态的最佳行动,这意味着行动必须被排序,并逐个赋值。由于那些行动都是依赖于状态的,所以我们实际上测量的是状态-行动对(state-action pairs)的价值;也就是说,您在某个状态下采取的行动,也就是你在某地方所做的某件事情。这里有几个例子,可以描述一下一个行动的价值和意义取决于智能体在采取这个行动时所面对的状态。


    • 如果这里的行动指的是和某人结婚,那么您在 18 岁的时候和一位 35 岁的结婚可能会与您在 90 岁的时候与一位 35 岁的结婚大有不同,这两个结果可能会有着不同的动机,而且会进一步导致不同的结果。

    • 如果这里的行动时大喊一声「Fire」,那么在一个人群密集的影院和在一众持枪者旁边大喊这句话则有不同的意义。如果不了解具体的语境,我们就不能预测行动会导致的结果。


    我们用上述的 Q 函数将状态-行动对映射到我们希望它能够产生的价值上。Q 函数将智能体的状态和行动作为输入,将它们映射到可能的奖励上。


    强化学习是通过一系列状态-行动对来运行智能体的过程,观察状态-行动对所导致的结果,调整 Q 函数的预测,直到它能够准确地预测出智能体应该采取的最佳行动。这种预测被称作策略。


    强化学习是一种尝试,它对于大量的状态-行动对以及与之关联的奖励的复杂概率分布进行建模。这是强化学习与马尔科夫决策过程(https://deeplearning4j.org/markovchainmontecarlo)配合使用的一个原因,马尔科夫决策过程是一个从复杂的分布中进行采样,以推断它的属性的一种方法。这和启发 Stan Ulam 来发明蒙特卡罗方法的问题是很相似的;即在纸牌游戏中通过给定的手牌尝试推断获胜的机会。


    任何统计方法,其本质上都是无知的。有些现象(例如生物学、政治学或者与棋类游戏有关的现象)的巨大复杂性使得从最初原则去推断是不可能的。唯一的方法就是通过统计去研究它们,从表面去衡量事件,并尝试建立它们之间的关联,即便我们不懂得它们相关联的机制。就像深度神经网络一样,强化学习就是这样的方法,依靠采样来从数据中抽取信息。


    强化学习是迭代的。在大多数有趣的应用中,它起始的时候都并不明白当前的状态-行动对会产生怎样的奖励。强化学习算法通过在一次又一次的状态中运行以学到这些关联,就像运动员或者音乐家在一次又一次的状态迭代中提升他们的水平一样。


    机器学习与时间之间的关系


    也许你会认为强化学习算法与实践的关系与人类有所不同。我们可以在相同的状态下采取不同的行动运行算法,直至我们可以可以推断哪个行动是状态对应的最佳行动。事实上,我们给算法设定了它们自己的土拨鼠日(http://www.imdb.com/title/tt0107048/0),它们从一个蠢蛋开始,然后慢慢获得智慧。


    由于人类从来不会经历电影之外的那种土拨鼠日,所以强化学习有可能比人类学到更多、更好。你可能会说,与人类相比,这些强化学习算法的真正优势并不在于它们的固有本质,而在于它们能够并行地存在于很多芯片上的能力,然后夜以继日不知疲倦地进行训练,因此能够学到更多。一个在围棋游戏上训练的算法,例如 AlphaGo,它能够玩的游戏比任何人类有望在 100 个有生之年玩得还要多。


    深度神经网络和深度强化学习


    神经网络适合用在什么地方呢?神经网络是能够学会映射状态-行动对和奖励的智能体。就像所有的神经网络一样,它们使用参数来逼近与输入输出相关的函数,它们的学习通过沿着错误降低的方向迭代地调整参数或者权重构成。


    在强化学习中,卷积网络可以被用来识别智能体的状态;例如,马里奥所在的屏幕,或者无人机前面的地形。也就是说,它们起到了典型的图像识别的作用。


    但是卷积网络在强化学习中能够得到比在监督学习中更多的解释。在监督学习中,网络给一副图片赋予一个标签;也就是说,它将名称映射到像素上。


    事实上,卷积网络会根据概率对最适合图片的标签进行排序。给定一张驴子的图片时,卷积网络可能会以 80% 的可能性将其判断为驴子,以 50% 的概率将其判断为马,以 30% 的概率将其判断为狗。


    在强化学习中,给定代表一个状态的图片,卷积网络可以给出一个在这个状态下可以采取的行动的排序;例如,它可能预测运行向右跑的动作会得 5 分,跳跃的动作会得 7 分,向左跑会得 0 分。


    给期望的奖励赋予价值之后,Q 函数就会简单地选择具有最高的 Q 价值的状态-行动对。


    在强化学习的起始阶段,神经网络的参数可能会被随机初始化。利用从环境中获得的反馈,神经网络可以使用期望奖励和实际奖励之间的差距来调整网络参数,以提升状态-行动对的解释性。


    这种反馈回路与监督学习中的误差反向传播类似。然而,监督学习开始的时候就已经含有神经网络尝试预测的真实标签。它的目标就是去创建能够映射不同的图片与对应的名字的模型。


    强化学习依靠环境来为算法提供与每个新行动对应的标量数字。环境返回的奖励可以使变化的、延迟的或者受已知变量影响的,这会给反馈回路引入噪声。


    这会得到关于 Q 函数的更完整的表达,它不仅仅考虑由一个行动产生的即时奖励,而且还能够将奖励顺序地延迟到几个时间步长的深度。


    就像人类一样,Q 函数也是递归的。就像调用湿体函数 human() 一样,human() 函数自身又包含另一个 human() 函数,我们是里面的所有结果,给一个给定的状态-行动对调用 Q 函数,需要我们调用一个嵌套的 Q 函数来预测下一个状态的价值,它反过来又要依赖之后的状态的 Q 函数,以此类推。


    代码


    RL4J 的例子在这里可以获得(https://github.com/deeplearning4j/dl4j-examples/tree/master/rl4j-examples)。 


    package org.deeplearning4j.examples.rl4j;

    import java.io.IOException;
    import org.deeplearning4j.rl4j.learning.HistoryProcessor;
    import org.deeplearning4j.rl4j.learning.async.a3c.discrete.A3CDiscrete;
    import org.deeplearning4j.rl4j.learning.async.a3c.discrete.A3CDiscreteConv;
    import org.deeplearning4j.rl4j.mdp.ale.ALEMDP;
    import org.deeplearning4j.rl4j.network.ac.ActorCriticFactoryCompGraphStdConv;
    import org.deeplearning4j.rl4j.util.DataManager;

    /**
    * @author saudet
    *
    * Main example for A3C with The Arcade Learning Environment (ALE)
    *
    */
    public class A3CALE {

       public static HistoryProcessor.Configuration ALE_HP =
               new HistoryProcessor.Configuration(
                       4,       //History length
                       84,      //resize width
                       110,     //resize height
                       84,      //crop width
                       84,      //crop height
                       0,       //cropping x offset
                       0,       //cropping y offset
                       4        //skip mod (one frame is picked every x
               )
    ;

       public static A3CDiscrete.A3CConfiguration ALE_A3C =
               new A3CDiscrete.A3CConfiguration(
                       123,            //Random seed
                       10000,          //Max step By epoch
                       8000000,        //Max step
                       8,              //Number of threads
                       32,             //t_max
                       500,            //num step noop warmup
                       0.1,            //reward scaling
                       0.99,           //gamma
                       10.0            //td-error clipping
               )
    ;

       public static final ActorCriticFactoryCompGraphStdConv.Configuration ALE_NET_A3C =
               new ActorCriticFactoryCompGraphStdConv.Configuration(
                       0.00025, //learning rate
                       0.000,   //l2 regularization
                       null, null, false
               )
    ;

       public static void main(String[] args) throws IOException {

           //record the training data in rl4j-data in a new folder
           DataManager manager = new DataManager(true);

           //setup the emulation environment through ALE, you will need a ROM file
           ALEMDP mdp = null;
           try {
               mdp = new ALEMDP("pong.bin");
           } catch (UnsatisfiedLinkError e) {
               System.out.println("To run this example, uncomment the \"ale-platform\" dependency in the pom.xml file.");
           }

           //setup the training
           A3CDiscreteConv<ALEMDP.GameScreen> a3c = new A3CDiscreteConv(mdp, ALE_NET_A3C, ALE_HP, ALE_A3C, manager);

           //start the training
           a3c.train();

           //save the model at the end
           a3c.getPolicy().save("ale-a3c.model");

           //close the ALE env
           mdp.close();
       }
    }


    原文链接:https://deeplearning4j.org/deepreinforcementlearning



    Yoshua Bengio团队最新强化学习研究:智能体通过与环境交互,「分离」变化的独立可控因素


    原文来源:arXiv

    作者:Valentin Thomas、Emmanuel Bengio∗、William Fedus、Jules Pondard、Philippe Beaudoin、Hugo Larochelle、Joelle Pineau、Doina Precup、Yoshua Bengio


    「雷克世界」编译:嗯~阿童木呀


    人们普遍认为,一个良好的表征(representation)在于能够对变化的潜在可解释性因素进行分离。然而,对于什么样的训练框架可以实现这一目标,仍然是一个悬而未决的问题。


    尽管以往的大多数研究重点主要集中于静态设置(例如,使用图像),但我们假设,如果允许学习者与其环境进行交互的话,就可以从中发现一些因果因素。


    智能体可以尝试不同的操作并观察其所产生的效果。更具体地说,我们假设这些因素中的一些与环境的某些可独立控制的方面相对应,即对于环境中的每一个这样的方面来说,都存在一个策略和可学习的特征,从而使得该策略可以在该特征中产生相应的变化,同时对其他特征进行最小程度的更改,从而对所观察到数据中的统计变化进行解释。


    我们提出了一个特定的目标函数以找到这些因素,并通过实验验证,它确实可以在没有任何外部奖励信号的情况下,对环境的独立可控制方面进行分离。


    在解决强化学习问题时,想要将好的结果从随机策略中区分开来往往需要具有正确的特征表征即使使用函数近似(function approximation),相较于盲目地去尝试解决给定的问题,学习正确的特征将可能会带来更快的收敛性(Jaderberg 等人于2016年提出)。



     我们架构的计算模型。其中,st是第一个状态,由其编码ht和噪声分布z产生。φ是生成的,φ用于对在环境中运行的策略πφ进行计算。序列ht、ht’通过选择性损失和ht上的可选择性自编码器损失,用于对我们的模型进行更新。


    在监督学习研究(Bengio于2009年、Goodfellow等人于2016年提出)和强化学习研究(Dayan于1993年、Precup于2000年提出)领域中存在着这样一种观点,学习一个好的,而非新的表征对于解决大多数现实世界中的问题来说具有至关重要的作用。


    而另一种观点是,这些表征通常不需要被显式地进行学习,这种学习可以通过内部奖励机制来进行引导,而这种奖励机制通常称为“内在动机(intrinsic motivation)”(Barto等人、Oudeyer和Kaplan于2009年、Salge等人于2013年、Gregor等人于2017年提出)。


    在以前研究成果的基础上(Thomas等人于2017年提出),我们构建了一个表征学习机制,它与内在动机机制和因果关系密切相关。该机制显式地将智能体对其环境的控制与智能体所学习到的环境表征联系起来。更具体地说,这种机制的假设是,环境中变化的潜在因素大部分可以由另一个变化的智能体独立控制。



    (a)对随机可控因素φ进行采样时,对1000次变化h’—h及其核密度估计的采样。我们观察到我们的算法在4种主要模式下对这些表征进行分离,每种模式都对应于智能体所实际采取的行动


    (b)潜在空间中的分离结构。x轴和y轴是分离的,这样我们就可以通过查看其潜在的编码h = f(s)来恢复任何观测值中智能体的x和y位置。当智能体位于橙色块上时,这个网格上的缺失点其所不能到达的唯一位置。


    我们为这个机制提出了一个通用且容易计算的目标,可以用于任何一个使用函数近似学习潜在空间的强化学习算法中。


    我们的研究结果表明,我们的机制可以推动模型学习以一种有意义的方式对输入进行分离,并学习对要采取多种行动才能得以的改变的因素进行表征,此外,研究结果还表明,这些表征可以在已学习的潜在空间中执行基于模型的预测,而不是在低级输入空间(例如像素)中。


    学习分离表征


    Hinton和Salakhutdinov于2006年提出的,用于学习表征的规范的深度学习框架就是一个典型的自编码框架。然而,这并不一定意味着已学习的潜在空间会对变化的不同因素进行分离。出于这些问题的考虑,我们提出了本文中所阐述的方法。



    (a)智能体所实际完成的3步轨迹;


    (b)空间φ(h0, z), z ∼ N (0, 1)的PCA视图。每个箭头指向由不同的φ所形成的预测Tθ(h0,φ)的重构。


    (a)中的策略使用的是绿色箭头开始处的φ。需要注意的是它的预测是如何对实际的最终状态进行准确预测的。


    其他作者提出了一些用于分离变化的潜在因素的机制。诸如变分自编码器(Kingma和Welling于2014年提出)、生成对抗网络(Goodfellow等人于2014年提出)或非线性版本的ICA(Dinh等人于2014年、Hyvarinen和Morioka于2016年提出)等之类的许多深度生成式模型,试图通过假设它们的联合分布(对所观察到的s进行边缘化处理)是因式分解后的结果(即它们是边缘独立的),对变化的潜在因素进行分离。


    在本文中,我们沿着另一个方向进行探讨,试图利用学习智能体在环境中行动的能力,以便对表征施加进一步的约束。我们假设,交互是学习如何对智能体所面临的观察流的各种因果因素进行分离的关键所在,并且这种学习可以在一种无监督的方式下完成。


    可以这样说,到目前为止,将表征延展到模型的独立可控特征中取得了一些令人鼓舞的成功。 我们的特征的可视化清楚地展示了简单环境中的不同可控方面,但是,我们的学习算法也存在一定的缺陷,即它是不稳定的。甚至可以这样说,我们方法的优势似乎也可能是它的弱点所在,因为先前的独立迫使已学习表征中的关注点进行非常严格地分离,而这些应该是可以缓和的。


    与此同时,一些不稳定性的来源似乎也减缓了我们的进程:学习一个有关可控方面的条件分布,往往会产生少于预期的模式。学习随机策略,通常会非常乐观地收敛域一个单一的动作中,由于模型具有多个部分因此往往需要对许多超参数进行调整。尽管如此,对于我们目前所采取的方法和措施,我们仍然报以希望。分离会发生,但对我们的优化过程以及我们目前的目标函数进行详细的了解将是推动进一步发展的关键点所在。


    人工智能赛博物理操作系统

    AI-CPS OS

    人工智能赛博物理操作系统新一代技术+商业操作系统“AI-CPS OS:云计算+大数据+物联网+区块链+人工智能)分支用来的今天,企业领导者必须了解如何将“技术”全面渗入整个公司、产品等“商业”场景中,利用AI-CPS OS形成数字化+智能化力量,实现行业的重新布局、企业的重新构建和自我的焕然新生。


    AI-CPS OS的真正价值并不来自构成技术或功能,而是要以一种传递独特竞争优势的方式将自动化+信息化、智造+产品+服务数据+分析一体化,这种整合方式能够释放新的业务和运营模式。如果不能实现跨功能的更大规模融合,没有颠覆现状的意愿,这些将不可能实现。


    领导者无法依靠某种单一战略方法来应对多维度的数字化变革。面对新一代技术+商业操作系统AI-CPS OS颠覆性的数字化+智能化力量,领导者必须在行业、企业与个人这三个层面都保持领先地位:

    1. 重新行业布局:你的世界观要怎样改变才算足够?你必须对行业典范进行怎样的反思?

    2. 重新构建企业:你的企业需要做出什么样的变化?你准备如何重新定义你的公司?

    3. 重新打造自己:你需要成为怎样的人?要重塑自己并在数字化+智能化时代保有领先地位,你必须如何去做?

    AI-CPS OS是数字化智能化创新平台,设计思路是将大数据、物联网、区块链和人工智能等无缝整合在云端,可以帮助企业将创新成果融入自身业务体系,实现各个前沿技术在云端的优势协同。AI-CPS OS形成的字化+智能化力量与行业、企业及个人三个层面的交叉,形成了领导力模式,使数字化融入到领导者所在企业与领导方式的核心位置:

    1. 精细种力量能够使人在更加真实、细致的层面观察与感知现实世界和数字化世界正在发生的一切,进而理解和更加精细地进行产品个性化控制、微观业务场景事件和结果控制。

    2. 智能:模型随着时间(数据)的变化而变化,整个系统就具备了智能(自学习)的能力。

    3. 高效:企业需要建立实时或者准实时的数据采集传输、模型预测和响应决策能力,这样智能就从批量性、阶段性的行为变成一个可以实时触达的行为。

    4. 不确定性:数字化变更颠覆和改变了领导者曾经仰仗的思维方式、结构和实践经验,其结果就是形成了复合不确定性这种颠覆性力量。主要的不确定性蕴含于三个领域:技术、文化、制度。

    5. 边界模糊:数字世界与现实世界的不断融合成CPS不仅让人们所知行业的核心产品、经济学定理和可能性都产生了变化,还模糊了不同行业间的界限。这种效应正在向生态系统、企业、客户、产品快速蔓延。

    AI-CPS OS形成的数字化+智能化力量通过三个方式激发经济增长:

    1. 创造虚拟劳动力,承担需要适应性和敏捷性的复杂任务,即“智能自动化”,以区别于传统的自动化解决方案;

    2. 对现有劳动力和实物资产进行有利的补充和提升,提高资本效率

    3. 人工智能的普及,将推动多行业的相关创新,开辟崭新的经济增长空间


    给决策制定者和商业领袖的建议:

    1. 超越自动化,开启新创新模式:利用具有自主学习和自我控制能力的动态机器智能,为企业创造新商机;

    2. 迎接新一代信息技术,迎接人工智能:无缝整合人类智慧与机器智能,重新

      评估未来的知识和技能类型;

    3. 制定道德规范:切实为人工智能生态系统制定道德准则,并在智能机器的开

      发过程中确定更加明晰的标准和最佳实践;

    4. 重视再分配效应:对人工智能可能带来的冲击做好准备,制定战略帮助面临

      较高失业风险的人群;

    5. 开发数字化+智能化企业所需新能力:员工团队需要积极掌握判断、沟通及想象力和创造力等人类所特有的重要能力。对于中国企业来说,创造兼具包容性和多样性的文化也非常重要。


    子曰:“君子和而不同,小人同而不和。”  《论语·子路》云计算、大数据、物联网、区块链和 人工智能,像君子一般融合,一起体现科技就是生产力。


    如果说上一次哥伦布地理大发现,拓展的是人类的物理空间。那么这一次地理大发现,拓展的就是人们的数字空间。在数学空间,建立新的商业文明,从而发现新的创富模式,为人类社会带来新的财富空间。云计算,大数据、物联网和区块链,是进入这个数字空间的船,而人工智能就是那船上的帆,哥伦布之帆!


    新一代技术+商业的人工智能赛博物理操作系统AI-CPS OS作为新一轮产业变革的核心驱动力,将进一步释放历次科技革命和产业变革积蓄的巨大能量,并创造新的强大引擎。重构生产、分配、交换、消费等经济活动各环节,形成从宏观到微观各领域的智能化新需求,催生新技术、新产品、新产业、新业态、新模式。引发经济结构重大变革,深刻改变人类生产生活方式和思维模式,实现社会生产力的整体跃升。



    产业智能官  AI-CPS


    用“人工智能赛博物理操作系统新一代技术+商业操作系统“AI-CPS OS”:云计算+大数据+物联网+区块链+人工智能)在场景中构建状态感知-实时分析-自主决策-精准执行-学习提升的认知计算和机器智能;实现产业转型升级、DT驱动业务、价值创新创造的产业互联生态链


    长按上方二维码关注微信公众号: AI-CPS,更多信息回复:


    新技术“云计算”、“大数据”、“物联网”、“区块链”、“人工智能新产业:智能制造”、智能金融”、“智能零售”、“智能驾驶”、智能城市新模式:“财富空间“工业互联网”、“数据科学家”、“赛博物理系统CPS”、“供应链金融”


    官方网站:AI-CPS.NET


    本文系“产业智能官”(公众号ID:AI-CPS)收集整理,转载请注明出处!



    版权声明产业智能官(公众号ID:AI-CPS推荐的文章,除非确实无法确认,我们都会注明作者和来源。部分文章推送时未能与原作者取得联系。若涉及版权问题,烦请原作者联系我们,与您共同协商解决。联系、投稿邮箱:erp_vip@hotmail.com






    展开全文
  • 本文主要整理和参考了李宏毅的强化学习系列课程和莫烦python的强化学习教程 本系列主要分几个部分进行介绍 强化学习背景介绍 SARSA算法原理和Agent实现 Q-learning算法原理和Agent实现 DQN算法原理和Agent实现 ...

    本文主要整理和参考了李宏毅的强化学习系列课程和莫烦python的强化学习教程
    本系列主要分几个部分进行介绍

    1. 强化学习背景介绍
    2. SARSA算法原理和Agent实现
    3. Q-learning算法原理和Agent实现
    4. DQN算法原理和Agent实现(tensorflow)
    5. Double-DQN、Dueling DQN算法原理和Agent实现(tensorflow)
    6. Policy Gradients算法原理和Agent实现(tensorflow)
    7. Actor-Critic、A2C、A3C算法原理和Agent实现(tensorflow)

    一、什么是强化学习(Reinforcement Learning, RL)

    1.1强化学习背景

    强化学习(RL)由两个部分组成,一个是环境environment,一个是代理agent。其中环境就是学习者所处的环境,agent可以理解为处在环境中的学习方法。agent会观察当前的environment得到当前环境的state(observation),并进一步选择需要执行的动作action,由于执行action,environment会发生改变,并且给agent一个奖励reward。这就是environment和agent的交互作用。
    可以知道environment是实现就给定的,agent的作用是根据给定的environment即state(observation)选定要执行的动作。强化学习的主要功能就是让agent学习尽可能好的动作action,使其后续获得的奖励尽可能的大。(注意是后续一系列奖励,而不是执行动作后的局部奖励)
    在这里插入图片描述
    RL让agent学习尽可能好的ction就是寻找一个函数a=π(s)a=π(s)使的aa的总奖励最大:
    在这里插入图片描述

    2.1强化学习分类

    根据不同的分列方法可以将强化学习算法分成不同的种类:
    1.基于概率(policy-based)和基于价值(value-based)
    基于概率是强化学习中最直接的一种, 他能通过感官分析所处的环境, 直接输出下一步要采取的各种动作的概率, 然后根据概率采取行动, 所以每种动作都有可能被选中, 只是可能性不同. 而基于价值的方法输出则是所有动作的价值, 我们会根据最高价值来选着动作, 相比基于概率的方法, 基于价值的决策部分更为铁定, 毫不留情, 就选价值最高的, 而基于概率的, 即使某个动作的概率最高, 但是还是不一定会选到他.(来自莫烦python)
    policy-based是根据动作的概率π():S>Aπ():S->A选择动作
    value-based是根据动作的价值选择动作,其中状态s下,动作a的价值可表示为Q(s,a)Q(s,a)

    在这里插入图片描述
    其中policy-based中的典型算法有Policy Gradients,value-based的典型算法有Q-learning、SARSA、DQN,两者重合的典型模型有AC、A2C、A3C
    在这里插入图片描述
    2.在线学习(on-policy)和离线学习(off-policy)
    所谓在线学习(on-policy), 就是指我必须本人在场, 并且一定是本人边玩边学习, 学习者与环境必须产生实际的交互。而离线学习(off-policy)是你可以选择自己玩, 也可以选择看着别人玩, 通过看别人玩来学习别人的行为准则。
    on-policy的典型算法是SARSA, off-policy的典型算法是Q-learning、DQN。
    on-policy是的学习者必学进行完一系列实际动作后才能产生样本,这样效率往往较慢。off-policy可以从以往的经验或别人的动作开学习,效率往往比较高。
    在这里插入图片描述
    3.model-based和model-free
    可以将所有强化学习的方法分为理不理解所处环境,如果我们不尝试去理解环境, 环境给了我们什么就是什么. 我们就把这种方法叫做 model-free, 这里的 model 就是用模型来表示环境, 那理解了环境也就是学会了用一个模型来代表环境, 所以这种就是 model-based 方法.
    在这里插入图片描述

    展开全文
  • 这是从国外网站上找到的强化学习的源代码,和大家共同学习。
  • 最近工作是在太忙了,996不遑多让,无奈,也没空更新博客,职业上也从研发变成了产品,有小半年没写代码了,怕自己手生的不行,给自己两天时间,写了点东西,之前做搞机器学习,搞深度学习,但一直对依赖全场景数据...

            最近工作是在太忙了,无奈,也没空更新博客,职业上也从研发变成了产品,有小半年没写代码了,怕自己手生的不行,给自己两天时间,写了点东西,之前做搞机器学习,搞深度学习,但一直对依赖全场景数据喂模型的方向有点感冒,因为数据又贵又难搞全,企业靠这个发家有点难,且本身需要企业具有很大的体量,另收集数据-训练-部署三板斧就当做AI的自进化说法感觉有点勉强,不谈特定场景妄图一个AI模型解决通用问题的都是大忽悠,咱们还是等待学术界的大佬们能真正提出新的理论来造福业内吧。

            一直在想,有没有一种更好适应的算法方向可以不那么依赖数据的,或者说能依赖数据少一些,这样对于一个产品也许有更好的成本控制和生命力加成,因此想了想是不是强化学习有可能,顺势就了解了下,花了几天时间简单学习了下入门皮毛,对最简单的Q-Learning先进行了复现。

     

    设定环境为一个5x5的棋盘,墙壁四周无法通行,碰到炸弹直接死亡,找到宝石就算过关。

     

    关于理论知识和排版我下次总结补充哈,先把我前两天写的代码放在这,先上传个效果:

    训练刚开始随机探索,:

    训练几十轮之后,基本直奔终点:

    代码部分:

    环境Env(为啥不使用我之前写的pycharm加pyqt5.0进行环境开发,我表示,忘光了,赶时间,选个最简单tk来用~):

    import tkinter as tk
    from PIL import ImageTk
    from PIL import Image
    import time
    
    class Env:
        def __init__(self):
            self.grid_size = 100
            self.win = tk.Tk()
            self.pic_player, self.pic_diamond, self.pic_boom1, self.pic_boom2, self.pic_boom3, self.pic_boom4 = self.__load_img()
            self.__init_win()
            self.canvas = self.__init_rc()
            self.texts= self.__produce_text()
            self.canvas.pack()
            # self._init_test_case()
            # self.win.mainloop()
    
        def __init_win(self):
            self.win.title('Grid World')
            # self.win.geometry("500x300")
    
        def __init_rc(self):
            canvas = tk.Canvas(self.win, width=500, height=720, bg='white')
            for h in range(5):
                for v in range(5):
                    canvas.create_rectangle(self.grid_size * v, self.grid_size * h, self.grid_size * (v + 1), self.grid_size * (h + 1))
            trans_pixel = int(self.grid_size / 2)
            self.player = canvas.create_image(trans_pixel + self.grid_size * 0, trans_pixel + self.grid_size * 0, image = self.pic_player)
            self.diamond = canvas.create_image(trans_pixel + self.grid_size * 4, trans_pixel + self.grid_size * 4, image=self.pic_diamond)
            self.boom1 = canvas.create_image(trans_pixel + self.grid_size * 1, trans_pixel + self.grid_size * 1, image=self.pic_boom1)
            self.boom2 = canvas.create_image(trans_pixel + self.grid_size * 3, trans_pixel + self.grid_size * 1, image=self.pic_boom2)
            self.boom3 = canvas.create_image(trans_pixel + self.grid_size * 1, trans_pixel + self.grid_size * 3, image=self.pic_boom3)
            self.boom4 = canvas.create_image(trans_pixel + self.grid_size * 3, trans_pixel + self.grid_size * 3, image=self.pic_boom4)
    
            return canvas
    
        def __load_img(self):
            pic_resize = int (self.grid_size / 2)
            player = ImageTk.PhotoImage(Image.open("player.png").resize((pic_resize, pic_resize)))
            diamond = ImageTk.PhotoImage(Image.open("diamond.png").resize((pic_resize, pic_resize)))
            boom1 = ImageTk.PhotoImage(Image.open('boom.png').resize((pic_resize, pic_resize)))
            boom2 = ImageTk.PhotoImage(Image.open('boom.png').resize((pic_resize, pic_resize)))
            boom3 = ImageTk.PhotoImage(Image.open('boom.png').resize((pic_resize, pic_resize)))
            boom4 = ImageTk.PhotoImage(Image.open('boom.png').resize((pic_resize, pic_resize)))
            return player, diamond, boom1, boom2, boom3, boom4
    
        def __produce_text(self):
            texts = []
            x = self.grid_size / 2
            y = self.grid_size / 6
            for h in range(5):
                for v in range(5):
                    up = self.canvas.create_text(x + h * self.grid_size, y + v * self.grid_size,text=0)
                    down = self.canvas.create_text(x + h *self.grid_size, self.grid_size - y + v * self.grid_size, text = 0)
                    left = self.canvas.create_text(y + h*self.grid_size, x + v*self.grid_size,text = 0)
                    right = self.canvas.create_text(self.grid_size-y + h*self.grid_size, x + v*self.grid_size,text = 0)
                    texts.append({"up": up, "down": down, "left": left, "right": right})
            return texts
    
        def _win_d_update(self):
            self.win.update()
            time.sleep(0.1)
    
    
    class GridWorld(Env):
        def __init__(self):
            super().__init__()
            self._win_d_update()
    
        def player_move(self, x, y):
            # x横向移动向右,y纵向移动向下
            self.canvas.move(self.player, x * self.grid_size, y*self.grid_size)
            self._win_d_update()
    
        def reset(self):
            # 重置为起始位置
            x, y = self.canvas.coords(self.player)
            self.canvas.move(self.player, -x + self.grid_size/2, -y + self.grid_size/2)
            self._win_d_update()
            return self.get_state(self.player)
    
        def get_state(self, who):
            x, y = self.canvas.coords(who)
            state = [int(x/self.grid_size), int(y/self.grid_size)]
            return state
    
        def update_val(self, num, arrow, val):
            pos = num[0] * 5 + num[1]
            x, y = self.canvas.coords(self.texts[pos][arrow])
            self.canvas.delete(self.texts[pos][arrow])
            self.texts[pos][arrow] = self.canvas.create_text(x, y, text=val)
            # self._win_d_update()
    
        def exec_calc(self, action):
            # 执行一次决策
            feedback = 'alive'  # alive, stop, dead 分别对应通过,撞墙,炸死
            next_state = []
            next_h, next_v, reward = 0.0, 0.0, 0.0
            h, v = self.get_state(self.player)
            if action == 0:     # up
                next_h = h
                next_v = v - 1
                # self.player_move(0, -1)
            elif action == 1:   # down
                next_h = h
                next_v = v + 1
                # self.player_move(0, 1)
            elif action == 2:   # left
                next_h = h - 1
                next_v = v
                # self.player_move(-1, 0)
            elif action == 3:   # right
                next_h = h + 1
                next_v = v
                # self.player_move(1, 0)
            else:
                print('programmer bug ...')
            next_state = [next_h, next_v]
            boom1, boom2, boom3, boom4 = self.get_state(self.boom1), self.get_state(self.boom2), self.get_state(
                self.boom3), self.get_state(self.boom4)
            diamond = self.get_state(self.diamond)
            if next_h < 0 or next_v < 0 or next_h > 4 or next_v >4:  # 超过边界
                reward = -1
                feedback = 'stop'
            elif next_state == boom1 or next_state == boom2 or next_state == boom3 or next_state == boom4:    # 炸弹区域
                reward = -100
                feedback = 'dead'
            elif next_state == diamond:   # 获得的通关物品
                reward = 500
            else:
                reward = 0
            return feedback, next_state, reward
    
        def update_view(self, state, action, next_state, q_val):
            action_list = ['up', 'down', 'left', 'right']
            self.player_move(next_state[0]-state[0], next_state[1]-state[1])
            self.update_val(state, action_list[action], round(q_val, 2))
    
        def attach(self):
            # 到达终点,返回True , 未到达,返回False
            return str(self.get_state(self.player)) == str(self.get_state(self.diamond))

    智能体Agent代码:

    import numpy as np
    import env
    
    
    
    class Agent:
        def __init__(self):
            self.actions = [0, 1, 2, 3]  # up down left right
            self.q_table = dict()
            self.__init_q_table()
            self.epsilon = 0.1
            self.learning_rate = 0.1
            self.gamma = 0.8
            # print(self.q_table)
    
        def __init_q_table(self):
            for v in range(5):
                for h in range(5):
                    self.q_table[str([h, v])] = [0.0, 0.0, 0.0, 0.0]
    
        def get_action(self, state):
            # 根据状态选取下一个动作,但不对无法通过的区域进行选取
            action_list = self.q_table[str(state)]
            pass_action_index = []
            for index, val in enumerate(action_list):
                if val >= 0:
                    pass_action_index.append(index)
            # 使用epsilon greedy来进行动作选取
            if np.random.rand() <= self.epsilon:
                # 进行探索
                return np.random.choice(pass_action_index)
            else:
                # 直接选取q最大值
                max_val = action_list[pass_action_index[0]]
                max_list = []
                for i in pass_action_index:
                    # 最大值相同且不止一个则随机选个最大值
                    if max_val < action_list[i]:
                        max_list.clear()
                        max_val = action_list[i]
                        max_list.append(i)
                    elif max_val == action_list[i]:
                        max_list.append(i)
                return np.random.choice(max_list)
    
        def update_q_table(self, feedback, state, action, reward, next_state):
            # Q(s,a) = Q(s,a) + lr * { reward + gamma * max[Q(s`,a`)] - Q(s,a) }
            q_s_a = self.q_table[str(state)][action] # 取出对应当前状态动作的q值
            if feedback == 'stop':
                q_ns_a = 0  # 撞墙时不存在下一状态,属于原地不变
            else :
                q_ns_a = np.max(self.q_table[str(next_state)])
            # 贝尔曼方程更新
            # self.q_table[str(state)][action] = q_s_a + self.learning_rate * (
            #     reward + self.gamma * q_ns_a - q_s_a
            # )
            self.q_table[str(state)][action] = (1 - self.learning_rate) * q_s_a + self.learning_rate * (reward + self.gamma * q_ns_a)
            # print(self.q_table)
            return self.q_table[str(state)][action]
    
    if __name__ == '__main__':
        np.random.seed(0)
        env = env.GridWorld()
        agent = Agent()
        for ep in range(2000):
            if ep < 100 :
                agent.epsilon = 0.2
            else:
                agent.epsilon = 0.1
            state = env.reset()
            print('第{}轮训练开始 ... '.format(ep + 1))
            while not env.attach():
                action = agent.get_action(state)    # 产生动作
                # print(action)
                feedback, next_state, reward = env.exec_calc(action)     # 计算状态
                q_val = agent.update_q_table(feedback, state, action, reward, next_state)   # 更新Q表
                if feedback == 'stop':
                    env.update_view(state, action, state, q_val)
                    continue
                elif feedback == 'dead':
                    env.update_view(state, action, next_state, q_val)
                    break
                else:
                    env.update_view(state, action, next_state, q_val)
                state = next_state   # 状态改变
    

    代码里出现的细节点和博客要讲的理论知识,我后续有空补充哈!

    展开全文
  • 拜读了论文Target-driven Visual Navigation in Indoor Scenesusing Deep Reinforcement Learning之后,来实现GitHub上的代码:icra2017-visual-navigation。1.先配置好TensorFlow,可以去官网...
  • 强化学习 强化学习是代理面临的学习问题,它通过与动态环境反复交互试验从而学习到某种行为。它是机器学习的主要学习方法之一,智能体从环境到行为的学习,也就是如何在环境中采取一些列行为,才能使得回报信号函数...
  • 这篇文章会从以下四个方面对“强化学习开发黑白棋、五子棋游戏”进行分析 一、总述 二、黑白棋游戏思路 三、五子棋游戏思路 四、分布式训练 ----------------------------------------------------------------...
  • 强化学习 强化学习是代理面临的学习问题,它通过与动态环境反复交互试验从而学习到某种行为。它是机器学习的主要学习方法之一,智能体从环境到行为的学习,也就是如何在环境中采取一些列行为,才能使得回报信号函数...
  • Java调用Python强化学习的例子 1. 在java类中直接执行python语句 此方法需要引用 org.python包,需要下载Jpython。在这里先介绍一下Jpython。下面引入百科的解释: Jython是一种完整的语言,而不是一个Java翻译器或...
  • Java·代码的复用之美

    2018-01-24 17:49:11
    Java的三大特性:封装,继承和多态,相信学习过的Java的都能够说出来但是,这三个特性是为了什么而存在呢,我认为,归根到底就是为了使代码能够复用,即我们应该把更多的心思放在新的功能上,而不是反复的写一些陈旧...
  • amp;utm_medium=referral深度强化学习是最接近于通用人工智能(AGI)的范式之一。...在本文中,作者将为我们解释深度强化学习没有成功的原因,介绍成功的典型案例,并指出让深度强化学习奏效的方法和研究方向。本...
  • 2:编程语言采用的是Java,源代码如下: package top10; import java.util.*; import java.io.*; public class top { public static void top(String []one,String []two,String []three){ ...
  • 首先有三部分代码:第一部分是绘制地图代码,第二部分是Q-Learning的代码,第三部分是运行代码 地图如下: 黄色圆形 : 机器人 红色方形 : 炸弹 [reward = -1] 绿色方形 : 宝藏 [reward = +1] 其他方格 : 平地 ...
  • 写在前面:我是根据莫烦的视频学习的Reinforce learning,具体代码实现包括Q-learning,SARSA,DQN,Policy-Gradient,Actor-Critic以及A3C。(莫凡老师的网站:...
  • 有个非盈利的开源学习组织Datawhale开源了一个github仓库:“南瓜书(PumpkinBook)”,对《机器学习》(西瓜书)里比较难理解的公式加以解析,以及对部分...
  • 多巴胺是强化学习算法快速原型制作的研究框架。 https://github.com/google/dopamine 多巴胺是强化学习算法快速原型制作的研究框架。它旨在满足一个小的,易于理解的代码库的需求,用户可以自由地尝试疯狂的想法...
  • IT派 - {技术青年圈}持续关注互联网、区块链、人工智能领域摘要: 本文将介绍一些目前流行的、强大的基于Java的机器学习库。图片来源: Mindfire Soluti...
1 2 3 4 5 ... 20
收藏数 8,640
精华内容 3,456