基于C#的机器学习--惩罚与奖励-强化学习
强化学习概况
正如在前面所提到的,强化学习是指一种计算机以“试错”的方式进行学习,通过与环境进行交互获得的奖赏指导行为,目标是使程序获得最大的奖赏,强化学习不同于连督学习,区别主要表现在强化信号上,强化学习中由环境提供的强化信号是对产生动作的好坏作一种评价(通常为标量信号),而不是告诉强化学习系统如何去产生正确的动作。唯一的目的是最大化效率和/或性能。算法对正确的决策给予奖励,对错误的决策给予惩罚,如下图所示:
持续的训练是为了不断提高效率。这里的重点是性能,这意味着我们需要,在看不见的数据和算法已经学过的东西,之间找到一种平衡。该算法将一个操作应用到它的环境中,根据它所做的行为接受奖励或惩罚,不断的重复这个过程,等等。
接下来让我们看一个程序,概念是相似的,尽管它的规模和复杂性很低。想象一下,是什么让自动驾驶的车辆从一个地点移动到了另一个点。
让我们看看我们的应用程序:
在这里,可以看到我们有一个非常基本的地图,一个没有障碍,但有外部限制的墙。黑色块(start)是我们的对象,红色块(stop)是我们的目标。在这个应用程序中,我们的目标是让我们的对象在墙壁以内到达目标位置。如果我们的下一步把我们的对象放在一个白色的方块上,我们的算法将得到奖励。如果我们的下一步行动超出墙壁的围地范围,我们将受到惩罚。在这个例子中,它的路径上绝对没有障碍,所以我们的对象应该能够到达它的目的地。问题是:它能多快学会?
下面是另一个比较复杂的地图示例:
学习类型
在应用程序的右边是我们的设置,如下面的屏幕截图所示。我们首先看到的是学习算法。在这个应用中,我们将处理两种不同的学习算法,Q-learning和state-action-reward-state-action (SARSA)。让我们简要讨论一下这两种算法。
Q-learning
Q-learning可以在没有完全定义的环境模型的情况下,识别给定状态下的最优行为(在每个状态中值最高的行为)。它还擅长处理随机转换和奖励的问题,而不需要调整或适应。
以下是Q-learning的数学表达式:
如果我们提供一个非常高级的抽象示例,可能更容易理解。
程序从状态开始。然后它执行动作并获得奖励。接下来,它四处寻找状态中某个行为的最大可能奖励是多少;然后使用它来更新动作的值等等。
SARSA
SARSA的工作原理是这样的:
1. 程序从状态开始。
2. 然后它执行动作并获得奖励。
3. 接下来,它进入状态,执行动作,并获得奖励。
4. 然后,程序返回并更新动作的值。
这Q-learning算法的不同之处在于找到未来奖励的方式。
Q-learning使用状态中奖励最高的动作的值,而SARSA使用实际动作的值。
这是SARSA的数学表达式:
运行我们的应用程序
现在,让我们开始使用带有默认参数的应用程序。只需点击开始按钮,学习就开始了。完成后,您将能够单击Show Solution按钮,学习路径将从头到尾播放。
点击Start开始学习阶段,一直到黑色物体达到目标:
对于每个迭代,将评估不同的对象位置,以及它们的操作和奖励。一旦学习完成,我们可以单击Show Solution按钮来重播最终的解决方案。完成后,黑色对象将位于红色对象之上:
现在让我们看看应用程序中的代码。有两种我们之前强调过的学习方法。
Q-learning是这样的:
/// <summary>
/// Q-Learning 线程
/// </summary>
private void QLearningThread()
{
//迭代次数
int iteration = ;
TabuSearchExploration tabuPolicy = (TabuSearchExploration)qLearning.ExplorationPolicy;
EpsilonGreedyExploration explorationPolicy = (EpsilonGreedyExploration)tabuPolicy.BasePolicy;
while ((!needToStop)&&(iteration<learningIterations))
{
explorationPolicy.Epsilon = explorationRate - ((double)iteration / learningIterations) * explorationRate;
qLearning.LearningRate = learningRate - ((double)iteration / learningIterations) * learningRate;
tabuPolicy.ResetTabuList(); var agentCurrentX = agentStartX;
var agentCurrentY = agentStartY; int steps = ;
while ((!needToStop)&& ((agentCurrentX != agentStopX) || (agentCurrentY != agentStopY)))
{
steps++;
int currentState= GetStateNumber(agentCurrentX, agentCurrentY);
int action = qLearning.GetAction(currentState);
double reward = UpdateAgentPosition(ref agentCurrentX, ref agentCurrentY, action);
int nextState = GetStateNumber(agentCurrentX, agentCurrentY);
// 更新对象的qLearning以设置禁忌行为
qLearning.UpdateState(currentState, action, reward, nextState);
tabuPolicy.SetTabuAction((action + ) % , );
}
System.Diagnostics.Debug.WriteLine(steps);
iteration++; SetText(iterationBox, iteration.ToString());
}
EnableControls(true);
}
SARSA学习有何不同?让我们来看看SARSA学习的while循环,并理解它:
/// <summary>
/// Sarsa 学习线程
/// </summary>
private void SarsaThread()
{
int iteration = ;
TabuSearchExploration tabuPolicy = (TabuSearchExploration)sarsa.ExplorationPolicy;
EpsilonGreedyExploration explorationPolicy = (EpsilonGreedyExploration)tabuPolicy.BasePolicy;
while ((!needToStop) && (iteration < learningIterations))
{
explorationPolicy.Epsilon = explorationRate - ((double)iteration / learningIterations) * explorationRate;
sarsa.LearningRate = learningRate - ((double)iteration / learningIterations) * learningRate;
tabuPolicy.ResetTabuList(); var agentCurrentX = agentStartX;
var agentCurrentY = agentStartY;
int steps = ;
int previousState = GetStateNumber(agentCurrentX, agentCurrentY);
int previousAction = sarsa.GetAction(previousState);
double reward = UpdateAgentPosition(ref agentCurrentX, ref agentCurrentY, previousAction); while ((!needToStop) && ((agentCurrentX != agentStopX) || (agentCurrentY != agentStopY)))
{
steps++; tabuPolicy.SetTabuAction((previousAction + ) % , );
int nextState = GetStateNumber(agentCurrentX, agentCurrentY);
int nextAction = sarsa.GetAction(nextState);
sarsa.UpdateState(previousState, previousAction, reward, nextState, nextAction);
reward = UpdateAgentPosition(ref agentCurrentX, ref agentCurrentY, nextAction);
previousState = nextState;
previousAction = nextAction;
} if (!needToStop)
{
sarsa.UpdateState(previousState, previousAction, reward);
} System.Diagnostics.Debug.WriteLine(steps); iteration++; SetText(iterationBox, iteration.ToString());
}
// 启用设置控件
EnableControls(true);
}
最后一步,看看如何使解决方案具有动画效果。我们需要这样才能看到我们的算法是否实现了它的目标。
代码如下:
TabuSearchExploration tabuPolicy;
if (qLearning != null)
tabuPolicy = (TabuSearchExploration)qLearning.ExplorationPolicy;
else if (sarsa != null)
tabuPolicy = (TabuSearchExploration)sarsa.ExplorationPolicy;
else
throw new Exception();
var explorationPolicy = (EpsilonGreedyExploration)tabuPolicy?.BasePolicy;
explorationPolicy.Epsilon = ;
tabuPolicy?.ResetTabuList();
int agentCurrentX = agentStartX, agentCurrentY = agentStartY;
Array.Copy(map, mapToDisplay, mapWidth * mapHeight);
mapToDisplay[agentStartY, agentStartX] = ;
mapToDisplay[agentStopY, agentStopX] = ;
这是我们的while循环,所有神奇的事情都发生在这里!
while (!needToStop)
{
cellWorld.Map = mapToDisplay;
Thread.Sleep(); if ((agentCurrentX == agentStopX) && (agentCurrentY == agentStopY))
{
mapToDisplay[agentStartY, agentStartX] = ;
mapToDisplay[agentStopY, agentStopX] = ;
agentCurrentX = agentStartX;
agentCurrentY = agentStartY;
cellWorld.Map = mapToDisplay;
Thread.Sleep();
} mapToDisplay[agentCurrentY, agentCurrentX] = ;
int currentState = GetStateNumber(agentCurrentX, agentCurrentY);
int action = qLearning?.GetAction(currentState) ?? sarsa.GetAction(currentState);
UpdateAgentPosition(ref agentCurrentX, ref agentCurrentY, action);
mapToDisplay[agentCurrentY, agentCurrentX] = ;
}
让我们把它分成更容易消化的部分。我们要做的第一件事就是建立禁忌政策。如果您不熟悉tabu搜索,请注意,它的目的是通过放松其规则来提高本地搜索的性能。在每一步中,如果没有其他选择(有回报的行动),有时恶化行动是可以接受的。
此外,还设置了prohibition (tabu),以确保算法不会返回到以前访问的解决方案。
TabuSearchExploration tabuPolicy;
if (qLearning != null)
tabuPolicy = (TabuSearchExploration)qLearning.ExplorationPolicy;
else if (sarsa != null)
tabuPolicy = (TabuSearchExploration)sarsa.ExplorationPolicy;
else
throw new Exception(); var explorationPolicy = (EpsilonGreedyExploration)tabuPolicy?.BasePolicy;
explorationPolicy.Epsilon = ;
tabuPolicy?.ResetTabuList();
接下来,我们要定位我们的对象并准备地图。
int agentCurrentX = agentStartX, agentCurrentY = agentStartY;
Array.Copy(map, mapToDisplay, mapWidth * mapHeight);
mapToDisplay[agentStartY, agentStartX] = ;
mapToDisplay[agentStopY, agentStopX] = ;
下面是我们的主执行循环,它将以动画的方式显示解决方案:
while (!needToStop)
{
cellWorld.Map = mapToDisplay;
Thread.Sleep(); if ((agentCurrentX == agentStopX) && (agentCurrentY == agentStopY))
{
mapToDisplay[agentStartY, agentStartX] = ;
mapToDisplay[agentStopY, agentStopX] = ;
agentCurrentX = agentStartX;
agentCurrentY = agentStartY;
cellWorld.Map = mapToDisplay;
Thread.Sleep();
} mapToDisplay[agentCurrentY, agentCurrentX] = ;
int currentState = GetStateNumber(agentCurrentX, agentCurrentY);
int action = qLearning?.GetAction(currentState) ?? sarsa.GetAction(currentState);
UpdateAgentPosition(ref agentCurrentX, ref agentCurrentY, action);
mapToDisplay[agentCurrentY, agentCurrentX] = ;
}
汉诺塔游戏
河内塔由三根杆子和最左边的几个按顺序大小排列的圆盘组成。目标是用最少的移动次数将所有磁盘从最左边的棒子移动到最右边的棒子。
你必须遵守的两条重要规则是,一次只能移动一个磁盘,不能把大磁盘放在小磁盘上;也就是说,在任何棒中,磁盘的顺序必须始终是从底部最大的磁盘到顶部最小的磁盘,如下所示:
假设我们使用三个磁盘,如图所示。在这种情况下,有33种可能的状态,如下图所示:
河内塔谜题中所有可能状态的总数是的磁盘数次幂。
其中||S||是集合状态中的元素个数,n是磁盘的个数。
在我们的例子中,我们有3×3×3 = 27个圆盘在这三根棒上分布的唯一可能状态,包括空棒;但是两个空棒可以处于最大状态。
定义了状态总数之后,下面是我们的算法从一种状态移动到另一种状态的所有可能操作:
这个谜题的最小可能步数是:
磁盘的数量是n。
Q-learning算法的正式定义如下:
在这个Q-learning算法中,我们使用了以下变量:
- Q矩阵:一个二维数组,首先对所有元素填充一个固定值(通常为0),用于保存所有状态下的计算策略;也就是说,对于每一个状态,它持有对各自可能的行动的奖励。
- 折扣因子:决定了对象如何处理奖励的政策。当贴现率接近时,只考虑当前的报酬会使对象变得贪婪,而当贴现率接近时,会使对象变得更具策略性和前瞻性,从而在长期内获得更好的报酬。
- R矩阵:包含初始奖励的二维数组,允许程序确定特定状态的可能操作列表。
我们应该简要介绍一下Q-learning Class的一些方法:
Init:生成所有可能的状态以及开始学习过程。
Learn:在学习过程中有顺序的步骤
InitRMatrix: 这个初始化奖励矩阵的值如下:
1. 0:在这种状态下,我们没有奖励。
2. 100:这是我们在最终状态下的最大奖励,我们想去的地方。
3. X:在这种情况下是不可能采取这种行动的。
TrainQMatrix: 包含Q矩阵的实际迭代值更新规则。完成后,我们希望得到一个训练有素的对象。
NormalizeQMatrix: 使Q矩阵的值标准化,使它们成为百分数。
Test: 提供来自用户的文本输入,并显示解决此难题的最佳最短路径。
让我们更深入地研究我们的TrainQMatrix的代码:
/// <summary>
/// 训练Q矩阵
/// </summary>
/// <param name="_StatesMaxCount">所有可能移动的个数</param>
private void TrainQMatrix(int _StatesMaxCount)
{
pickedActions = new Dictionary<int, int>(); // 可用操作列表(基于R矩阵,其中包含从某个状态开始的允许的下一个操作,在数组中为0)
List<int> nextActions = new List<int>(); int counter = ;
int rIndex = ;
// 3乘以所有可能移动的个数就有足够的集来训练Q矩阵
while (counter < * _StatesMaxCount)
{
var init = Utility.GetRandomNumber(, _StatesMaxCount); do
{
// 获得可用的动作
nextActions = GetNextActions(_StatesMaxCount, init); // 从可用动作中随机选择一个动作
if (nextActions != null)
{
var nextStep = Utility.GetRandomNumber(, nextActions.Count);
nextStep = nextActions[nextStep]; // 获得可用的动作
nextActions = GetNextActions(_StatesMaxCount, nextStep); // 设置从该状态采取的动作的索引
for (int i = ; i < ; i++)
{
if (R != null && R[init, i, ] == nextStep)
rIndex = i;
} // 这是值迭代更新规则-折现系数是0.8
Q[init, nextStep] = R[init, rIndex, ] + 0.8 * Utility.GetMax(Q, nextStep, nextActions); // 将下一步设置为当前步骤
init = nextStep;
}
}
while (init != FinalStateIndex); counter++;
}
}
使用三个磁盘运行应用程序:
使用四个磁盘运行应用程序:
这里有7个磁盘。最佳移动步数是,所以你可以看到解决方案可以多快地乘以可能的组合:
总结
这种形式的强化学习更正式地称为马尔可夫决策过程(Markov Decision Process, MDP)。MDP是一个离散时间随机控制的过程,这意味着在每个时间步,在状态x下,决策者可以选择任何可用的行动状态,这个过程将在下一步反应,随机移动到一个新的状态,给决策者一个奖励。进程进入新状态的概率由所选动作决定。因此,下一个状态取决于当前状态和决策者的行为。给定状态和操作,下一步完全独立于之前的所有状态和操作。
基于C#的机器学习--惩罚与奖励-强化学习的更多相关文章
- 基于C#的机器学习--目录
转载请注明出处:https://www.cnblogs.com/wangzhenyao1994/p/10223666.html 文章发表的另一个地址:https://blog.csdn.net/wyz ...
- Reinforcement Learning 的那点事——强化学习(一)
引言 最近实验室的项目需要用到强化学习的有关内容,就开始学习起强化学习了,这里准备将学习的一些内容记录下来,作为笔记,方便日后忘记了好再方便熟悉,也可供大家参考.该篇为强化学习开篇文章,主要概括一些有 ...
- 深度学习-强化学习(RL)概述笔记
强化学习(Reinforcement Learning)简介 强化学习是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利益.其灵感来源于心理学中的行为主义理论,即有机体如何在环境给予 ...
- 强化学习(十四) Actor-Critic
在强化学习(十三) 策略梯度(Policy Gradient)中,我们讲到了基于策略(Policy Based)的强化学习方法的基本思路,并讨论了蒙特卡罗策略梯度reinforce算法.但是由于该算法 ...
- [Reinforcement Learning] 强化学习介绍
随着AlphaGo和AlphaZero的出现,强化学习相关算法在这几年引起了学术界和工业界的重视.最近也翻了很多强化学习的资料,有时间了还是得自己动脑筋整理一下. 强化学习定义 先借用维基百科上对强化 ...
- 机器学习算法总结(三)——集成学习(Adaboost、RandomForest)
1.集成学习概述 集成学习算法可以说是现在最火爆的机器学习算法,参加过Kaggle比赛的同学应该都领略过集成算法的强大.集成算法本身不是一个单独的机器学习算法,而是通过将基于其他的机器学习算法构建多个 ...
- Ubuntu下常用强化学习实验环境搭建(MuJoCo, OpenAI Gym, rllab, DeepMind Lab, TORCS, PySC2)
http://lib.csdn.net/article/aimachinelearning/68113 原文地址:http://blog.csdn.net/jinzhuojun/article/det ...
- 强化学习一:Introduction Of Reinforcement Learning
引言: 最近和实验室的老师做项目要用到强化学习的有关内容,就开始学习强化学习的相关内容了.也不想让自己学习的内容荒废掉,所以想在博客里面记载下来,方便后面复习,也方便和大家交流. 一.强化学习是什么? ...
- 强化学习 3—— 使用蒙特卡洛采样法(MC)解决无模型预测与控制问题
一.问题引入 回顾上篇强化学习 2 -- 用动态规划求解 MDP我们使用策略迭代和价值迭代来求解MDP问题 1.策略迭代过程: 1.评估价值 (Evaluate) \[v_{i}(s) = \sum_ ...
随机推荐
- VC++中关于控件重绘函数/消息 OnPaint,OnDraw,OnDrawItem,DrawItem的区别
而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息. OnDraw()是CVIEW的成员函数,并且没有响应消息的功能.这就是为什么你用VC成的程序代码时,在视图类只有OnDraw ...
- 初识Qt窗口界面
1.新建一个新的Qt Gui应用,项目名称随意,例如MyMainWindow,基类选择QMainWindow,类名为MainWindow. 2.项目建立后,双击mainwindow.ui文件,在界面的 ...
- $2018/8/19 = Day5$学习笔记 + 杂题整理
\(\mathcal{Morning}\) \(Task \ \ 1\) 容斥原理 大概这玩意儿就是来用交集大小求并集大小或者用并集大小求交集大小的\(2333\)? 那窝萌思考已知\(A_1,A_2 ...
- 学习笔记·斜率优化 [HNOI2008]玩具装箱
\(qwq\)今天\(rqy\)给窝萌这些蒟蒻讲了斜率优化--大概是他掉打窝萌掉打累了吧顺便偷了\(rqy\)讲课用的图 \(Step \ \ 1\) 一点小转化 事实上斜率优化是专门用来处理这样一类 ...
- 单链表(c语言实现)贼详细
直接上代码吧 #include<stdio.h> #include<malloc.h> /* 单链表特点: 它是一种动态的储存结构,链表中每个节点占用的储存空间不是预先分配的, ...
- .NET 操作 EventLog(Windows事件日志监控)(转载)
操作Windows日志:EventLog 如果要在.NET Core控制台项目中使用EventLog(Windows事件日志监控),首先需要下载Nuget包: System.Diagnostics.E ...
- java中跳出循环的方式
continue:跳出本次循环,继续下一次循环,也就是不执行本次循环continue下面的语句. 例如:"will you"不会被打印 for(int i = 0; i< 8 ...
- 人生苦短,我用python
星空不问赶路人,时光不负有心人,你可以脱变. 1.计算机的初步认识 2.解释器的安装 python2.7(2020年官方不在维护) python3.6 (官方推荐) 1.下载安装包 https://w ...
- 20155239 2017-11-19 实现mypwd(选做,加分)
20155239 2017-11-19 实现mypwd(选做,加分) 题目和要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试mypwd ...
- 【转载】COM 组件设计与应用(十七)——持续性
原文:http://vckbase.com/index.php/wv/1264.html 一.前言 我们写程序,经常需要实现这样的需求: 例一.程序运行产生一个窗口,用户关闭的时候需要记录窗口的位置, ...