人工智能笔记11 --强化学习

基本设置

例子:瓜农种西瓜

• 多步决策过程
• 过程中包含状态、动作、反馈 (奖赏) 等
• 需多次种瓜,在过程中不断摸索,才能总结出较好的种瓜策略
在这里插入图片描述

监督学习对比强化学习

预测:最小化预测误差,预测结果不会对环境产生影响

比如,是否为肿瘤,天气预测是否影响天气

决策:决策动作会对环境产生影响

比如:肿瘤去除,股票投资会影响股市

强化学习的关键要素
< A , X , R , P > <A,X,R,P> <A,X,R,P>
动作空间 A
状态空间 X
奖赏函数 R: X × A × X → R X\times A\times X\rightarrow \mathcal{R} X×A×XR
状态转移概率P: X × A × X → R X\times A\times X\rightarrow \mathcal{R} X×A×XR

目标:通过在种瓜过程中不断摸索,总结出较好的种瓜策略,种出好瓜(获得的累积奖赏最大)
在这里插入图片描述
强化学习的目标
器通过在环境中不断尝试,从而学到一个“策略”(policy) π \pi π,使得
长期执行该策略后得到的累积奖赏最大

策略表示:
确定性策略和随机性策略

策略的评估:累计奖赏
状态值函数:从x输出用策略 π \pi π带来的累计奖赏

状态值函数,从状态x出发,策略 π \pi π的累计奖赏
{ V T π ( x ) = E π [ 1 T ∑ t = 1 T r t ∣ x 0 = x ] T 步 累 计 奖 赏 V γ π ( x ) = E π [ ∑ t = 0 + ∞ γ t r t + 1 ∣ x 0 = x ] γ 折 扣 累 计 奖 赏 \left\{\begin{array}{l} V^\pi_T(x)=\mathbb{E}_\pi[\frac{1}{T}\sum^T_{t=1}r_t|x_0=x]&T步累计奖赏\\ V^\pi_\gamma(x)=\mathbb{E}_\pi[\sum^{+\infty}_{t=0}\gamma^t r_{t+1}|x_0=x]&\gamma折扣累计奖赏 \end{array}\right. {VTπ(x)=Eπ[T1t=1Trtx0=x]Vγπ(x)=Eπ[t=0+γtrt+1x0=x]Tγ
状态-动作值函数,从状态x出发,执行动作a再用策略 π \pi π的累计奖赏
{ Q T π ( x ) = E π [ 1 T ∑ t = 1 T r t ∣ x 0 = x , a 0 = a ] T 步 累 计 奖 赏 Q γ π ( x ) = E π [ ∑ t = 0 + ∞ γ t r t + 1 ∣ x 0 = x , a 0 = a ] γ 折 扣 累 计 奖 赏 \left\{\begin{array}{l} Q^\pi_T(x)=\mathbb{E}_\pi[\frac{1}{T}\sum^T_{t=1}r_t|x_0=x,a_0=a]&T步累计奖赏\\ Q^\pi_\gamma(x)=\mathbb{E}_\pi[\sum^{+\infty}_{t=0}\gamma^t r_{t+1}|x_0=x,a_0=a]&\gamma折扣累计奖赏 \end{array}\right. {QTπ(x)=Eπ[T1t=1Trtx0=x,a0=a]Qγπ(x)=Eπ[t=0+γtrt+1x0=x,a0=a]Tγ

强化学习方法分类

  1. 马尔科夫决策过程中,A、 X、 P、R已知:动态规划
  2. 模型意指马尔可夫决策过程:P和R往往未知
  3. 基于模型(model-based)的RL:先学习/还原环境模型,即P和R再求解最优策略
  4. 免模型(model-free)的RL:不学习/原环境模型,直接逼近最优策略

Q-learning算法

基本思想
• 学习状态-动作值函数 Q ( s , a ) Q(s,a) Q(s,a),再从学到的 Q Q Q函数里求出最优策略 π π π(即带来的累积奖赏最大)
• 免模型方法:无需先学习状态转移概率P和奖赏函数R

• 从与环境交互的轨迹数据中学习
一条轨迹数据: s 1 , a 1 , r 2 , s 2 , a 2 . . . s_1,a_1,r_2,s_2,a_2... s1,a1,r2,s2,a2...

【当动作和下一时刻状态都已经(通过采样)确定时】

Q γ π ( x ) = E π [ ∑ t = 0 + ∞ γ t r t + 1 ∣ x 0 = x , a 0 = a ] Q^\pi_\gamma(x)=\mathbb{E}_\pi[\sum^{+\infty}_{t=0}\gamma^t r_{t+1}|x_0=x,a_0=a] Qγπ(x)=Eπ[t=0+γtrt+1x0=x,a0=a]
转换为
Q ( s t , a t ) = R ( s t , a t ) + γ ⋅ Q ( s t + 1 , a t + 1 ) Q(s_t,a_t)=R(s_t,a_t)+\gamma\cdot Q(s_{t+1},a_{t+1}) Q(st,at)=R(st,at)+γQ(st+1,at+1)

基本思想:维护两个策略
目标策略: π ( a ∣ s ) \pi(a|s) π(as)用状态-动作值函数 Q ( s , a ) Q(s,a) Q(s,a)评估
执行/行为策略(用于收集数据和做探索): μ ( a ∣ s ) \mu(a|s) μ(as)用于收集轨迹数据
{ s 1 , a 1 , r 2 , s 2 , a 2 … … s T } ∼ μ \{s_1,a_1,r_2,s_2,a_2……s_T\}\sim \mu {s1,a1,r2,s2,a2sT}μ

μ ( a ∣ s ) \mu(a|s) μ(as)实现,可以使用 ϵ − g r e e d y \epsilon-greedy ϵgreedy的环境探索法【平衡探索与利用】
π ϵ ( s ) = { π ( s ) = a r g m a x a Q ( s , a ) 以 概 率 1 − ϵ A 中 以 均 匀 概 率 选 取 动 作 概 率 ϵ \pi^\epsilon(s)=\left\{\begin{array}{l} \pi (s) = argmax_aQ(s,a) & 以概率1-\epsilon \\ A中以均匀概率选取动作 & 概率\epsilon\end{array}\right. πϵ(s)={π(s)=argmaxaQ(s,a)A1ϵϵ
在这里插入图片描述
状态-动作值函数更新:
在这里插入图片描述
在这里插入图片描述
绵羊走迷宫
假设一个迷宫有5个房间,房间之间通过门相连,将这五个房间按照从0至4进行编号,且5号房间里面是草地。因绵羊要吃草,设定5号房间为绵羊的目标房间。求绵羊从任意一个房间走到目标房间(5号房间)的最优路径。
在这里插入图片描述

基于图表示的房间结构
• 节点:房间
• 边:如果两个房间有门相连,那么两个节点之间存在一条边。边的权重即为奖赏值(直接连接到5号房间的奖赏值为100,其他门的奖赏值为0)。没有门直接相连,奖赏值为-1
在这里插入图片描述
绵羊从任意一个房间走到目标房间的最优路径
→ \rightarrow 从任意状态到达目标状态的最大累积奖赏

令学习参数γ=0.8,初始状态为1号房间
在这里插入图片描述

• 根据奖赏矩阵R,状态1的下一步动作有两种选择:转向状态3或者状态5。

  • 根据行为策略,假设我们转向状态5。

• 绵羊位于状态5以后,有三种可能的动作选择
:转向状态1或4或5。

  • 根据目标策略,选择Q值最大的动作,并更新值函数:

Q ( 1 , 5 ) = R ( 1 , 5 ) + γ × m a x { Q ( 5 , 1 ) , Q ( 5 , 4 ) , Q ( 5 , 5 } = 100 Q(1,5)=R(1,5)+\gamma\times max\{Q(5,1),Q(5,4),Q(5,5\}=100 Q(1,5)=R(1,5)+γ×max{Q(5,1),Q(5,4),Q(5,5}=100
在这里插入图片描述

当前状态为5号房间(达到目标状态)
完成了一次episode,矩阵Q也相应地更新了

接着,假设选取3为初始状态
• 根据奖赏矩阵R,状态3有三种可能的动作选
择:转向状态1或2或4。

  • 根据行为策略,假设我们转向状态1。

绵羊位于状态1以后,有两种可能的动作选择
:转向状态3或5。

  • 根据目标策略,选择Q值最大的动作,并更
    新值函数:
    Q ( 3 , 1 ) = R ( 3 , 1 ) + γ × m a x { Q ( 1 , 3 ) , Q ( 1 , 5 ) } = 80 Q(3,1)=R(3,1)+\gamma\times max\{Q(1,3),Q(1,5)\}=80 Q(3,1)=R(3,1)+γ×max{Q(1,3),Q(1,5)}=80
    在这里插入图片描述

当前状态为1号房间(不是目标状态
第二次episode还没有结束

• 根据奖赏矩阵R,状态1有两种可能的动作选
择:转向状态3或5。

  • 根据行为策略,假设我们转向状态5。

由前面的分析,我们有:Q(1,5)=100。更新新矩阵Q,但是Q没有发生变化。第二次episode结束

继续执行更多的episode,最终Q将收敛成如下一个矩阵
在这里插入图片描述
如果以3号房间为初始状态,根据Q表,累积的奖赏最大的路径是3-﹥1-﹥5或者3-﹥4-﹥5,总的reward都为100。
在这里插入图片描述

强化学习拓展

RL需要对环境进行探索

智能体在探索中加深对环境的理解,使得长期累积奖赏最大

比如婴儿走路

智能体在探索中加深对环境的理解,使得长期累积奖赏最大

具体阐述:
K臂老虎机(K-armed Bandit):
一个状态,k个动作,每个摇臂奖励服从某个期望位置的分布,执行有限次动作,最大化累计奖赏
在这里插入图片描述

简化RL(无状态转移,因为只有一个状态),把探索抽象出来单独研究

若只探索:平均分配尝试次数(浪费大量尝试)

只利用:每个摇一次,根据反馈结果只选择期望最高的摇臂(误差大)

主要难题之一:平衡探索与利用
摇臂次数有限,如何分配资源做探索和利用,使得长期累积奖赏尽可能的大?

  1. 环境探索方法
    ϵ 贪 心 \epsilon贪心 ϵ
    ϵ \epsilon ϵ的概率探索:均匀随机选择一个摇臂
    1 − ϵ 1-\epsilon 1ϵ概率利用,选择当前期望最高的摇臂

  2. Softmax:基于当前已知摇臂期望对探索和利用这种
    if 摇臂当前平均奖赏大,选择概率高
    概率用Boltzmann分布
    P ( k ) = e Q ( k r ∑ i = 1 K e Q ( i ) r P(k)=\frac{e^{\frac{Q(k}{r}}}{\sum^K_{i=1} e^{ \frac{Q(i)}{r}}} P(k)=i=1KerQ(i)erQ(k
    Q ( i ) Q(i) Q(i)是记录当前摇臂的平均奖赏

两种算法都有折中参数 ( ϵ , r ) (\epsilon,r) (ϵ,r)

深度强化学习:深度模型+强化学习
深度强化学习
使用(深度)神经网络表示策略或值函数
迷宫:有限状态、动作,小规模

深度强化学习
大规模/连续动作、状态,复杂策略表示,可考虑深度强化学习

应用

例如,DQN(深度Q网络)玩游戏,可以超过人类水平
AlphaGo:树搜索+深度强化学习(深度网络+强化学习
除了各种棋类、还应用于机器人控制、推荐系统、军事博弈、股票预测
等各种决策任务

小结

有监督学习无监督学习强化学习
学习依据基于监督信息基于对数据结构的假设基于评估
数据来源一次给定一次给定在时序交互中产生
决策过程单步决策(如分类和识别)序贯决策(如棋类博弈)
学习目标样本到语义标签的映射数据的分布模式选择能够获取最大受益的状态到动作的映射

强化学习:多步决策过程,解决how的问题,决策会影响环境
• 强化学习拓展:探索-利用难题、深度强化学习、应用及问题
• Q-Learning 算法

迷宫寻宝

在这里插入图片描述
在这里插入图片描述
当然,你不需要写出程序所有代码,你只需要补全以下函数并提交即可。

函数部分定义如下(部分变量的说明已经在提示中详尽给出):

void Qlearning()
{
    int nx = 1 + rand() % n, ny = 1 + rand() % m;
    int cnt = 0;
    while (!isEnd(nx,ny) && cnt < n*m) {
        auto &s0 = Qstate[(nx-1)*m+ny];
        int siz = s0.size();
        int _next = -1,idx = 0;
        if (!siz) return;
        if (siz == 1) _next = s0[0].first;
        else {
            sort(s0.begin(),s0.end(),cmp);
            double p = rand() / double(RAND_MAX);
            if (p < 1 - greedy_factor) {
                _next = s0[0].first;
            }
            else {
                 idx = 1 + rand() % (siz - 1);
                _next = s0[idx].first;
            }
        }
        auto &s1 = Qstate[_next];
        sort(s1.begin(),s1.end(),cmp);
        double _nextMax = (int)s1.size() ? s1[0].second : 0.0;

        nx = (_next - 1) / m + 1;ny = (_next - (nx-1) * m) % (m+1);
        /********/
        // TODO
        // HINTS: 使用s0[idx].second、alpha、gama、_nextMax、Reward[nx][ny]变量,
        // 完成Qlearning的状态更新公式





        /********/
        cnt++;
    }
}

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
const int maxn = 21;
const int epics = 50000;
const int target_success = 5000;
const double inf = 1e8;

bool cmp(pair<int,double> X, pair<int,double> Y) 
{
    if(X.second == Y.second) return X.first < Y.first;
    return X.second > Y.second;
}


// 迷宫尺寸 n*m
// x,y坐标从1开始 起点(1,1) 终点(n,m)
// 对于每个位置(i,j),可以向U,L,R,D四个方向移动,不可走出迷宫边界,不可走到障碍物上
int n,m;

// maze[maxn+5][maxn+5]存储迷宫 0代表可走通 1代表陷阱 (maze[i][j], 1<=i<=n,1<=j<=m)
// 答案保证有解 即 maze[1][1] = 0, maze[n][m] = 0, 起点与终点之间保证至少存在一条路径
int maze[maxn+5][maxn+5];

// 奖励函数R 设置普通格子奖励为-(abs(i-n)+abs(j-m)) 陷阱奖励为-10000 终点奖励为100000 衰减因子alpha = 0.9 , gama = 0.9
const double alpha = 0.9;
const double gama = 0.9;
double Reward[maxn+5][maxn+5];

// 状态函数Q 下一步的选取采用1-ϵ贪心
// 关于Qstate[pos]中的pos索引到二维坐标(px,py)的转换:
//  px = (pos - 1) / m + 1
//  py = (pos - (px-1) * m) % (m+1);
const double greedy_factor = 0.1;
vector< pair<int,double> > Qstate[(maxn+5)*(maxn+5)];

// 存储答案
vector< pair<int,int> > ans;

// 初始化奖励函数R和状态函数Q
void init_RQ(int i,int j) 
{
    // 陷阱不设置奖励函数(可理解成均为-inf)
    if (maze[i][j] == 1) return;
    // Up
    if (Reward[i-1][j]) {
        Qstate[(i-1)*m+j].push_back({(i-2)*m+j,-1});
    }
    // Left
    if (Reward[i][j-1]) {
        Qstate[(i-1)*m+j].push_back({(i-1)*m+j-1,-1});
    }
    // Right
    if (Reward[i][j+1]) {
        Qstate[(i-1)*m+j].push_back({(i-1)*m+j+1,-1});
    }
    // Down
    if (Reward[i+1][j]) {
        Qstate[(i-1)*m+j].push_back({i*m+j,-1});
    }
}


int success_time = 0;
bool isEnd(int i,int j) 
{
    if (i == n && j == m) {
        ++success_time;
        return true;
    }
    if (maze[i][j] == 1) {
        return true;
    }
    return false;
}


void Qlearning()
{
    int nx = 1 + rand() % n, ny = 1 + rand() % m;
    int cnt = 0;
    while (!isEnd(nx,ny) && cnt < n*m) {
        auto &s0 = Qstate[(nx-1)*m+ny];
        int siz = s0.size();
        int _next = -1,idx = 0;
        if (!siz) return;
        if (siz == 1) _next = s0[0].first;
        else {
            sort(s0.begin(),s0.end(),cmp);
            double p = rand() / double(RAND_MAX);
            if (p < 1 - greedy_factor) {
                _next = s0[0].first;
            }
            else {
                 idx = 1 + rand() % (siz - 1);
                _next = s0[idx].first;
            }
        }
        auto &s1 = Qstate[_next];
        sort(s1.begin(),s1.end(),cmp);
        double _nextMax = (int)s1.size() ? s1[0].second : 0.0;

        nx = (_next - 1) / m + 1;ny = (_next - (nx-1) * m) % (m+1);
        /********/
        // TODO
        // HINTS: 使用s0[idx].second、alpha、gama、_nextMax、Reward[nx][ny]变量,
        // 完成Qlearning的状态更新公式
                // 你的代码将被嵌在此处





        /********/
        cnt++;
    }
}


int main()
{
    ios::sync_with_stdio(false);
    srand(2022);
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++) {
            int t;
            cin >> t;
            maze[i][j] = t;
            Reward[i][j] = (t == 0 ? -(abs(i-n)+abs(j-m)) : -10000.0);
        }
    }
    Reward[n][m] = 100000.0;

    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            init_RQ(i,j);
        }
    }


    int cnt = 0;
    while (cnt < epics && success_time != target_success) {
        Qlearning();
        ++cnt;
    }
    cnt = 0;
    int x = 1, y = 1;
    while ((x!=n || y!=m) && cnt < n*m) {
        auto &s = Qstate[(x-1)*m+y];
        if (!(int)s.size()) {
            // 无解情况,可忽略
            cout << "Something Wrong!" << endl;
            return 0;
        }
        ans.push_back({x,y});
        sort(s.begin(),s.end(),cmp);
        int _next = s[0].first;
        x = (_next - 1) / m + 1; y = (_next - (x-1) * m) % (m+1);
        ++cnt;
    }
    ans.push_back({n,m});
    cout << (int)ans.size() << endl;
    for(auto& u : ans) {
        cout << u.first << ' ' << u.second << endl;
    }

    return 0;
}

思路

搞清楚每个部分干啥套公式即可

代码

double former = (1 - alpha) * s0[idx].second;
double later = alpha * (Reward[nx][ny] + gama * _nextMax);
s0[idx].second = former + later;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值