强化学习Q-learning辅助flappy bird

flappy bird项目分析

标签:强化学习 实验 Q-learning

来源

来自一个github上的项目,使用Q-leraning训练flappy bird,效果很好,半小时能够到几十(比人厉害多了),使用小鸟到最近的柱子的x和y值作为状态

非常简单,但是效果比较一般,鸟很多此在第0次的时候撞在柱子上。

地址

因为用到了google托管css,所以应该是要梯子的。而且在本地打开会因为file协议,导致存储的csv因为google的CORS policy被拒绝访问,解决方案是使用服务器,比如nginx或者apache之类的进行本地代理,通过http协议进行访问(主要原因是因为它拿取文件的方式用的是jQuery的get方法)

分析flappy bird是怎么做的

首先看看原始代码是如何实现flappy bird这个游戏的。

很明显是使用了canvas。函数startingState()返回的是游戏的初始状态所需要的参数

function startingState() {
    return {
        mode: "ready",
        startFrame: 0,
        jumpFrame: 0,
        birdY: birdStartY,
        curFrame: 0,
        birdSprite: 0,
        round: 0,
        score: 0,
        totalScore: 0,
        maxScore: 0,
        deadFlash: 0,
        fps: 0,
        pipeList: [],
        landList: [],
    };
}

而后面有gameState = startingState(),所以后面所有拿到的游戏状态的类型与这个是一致的。

而resetState(gameState)函数则明显是重置游戏的函数

function resetState(gameState) {
    var round = gameState.round;
    var curFrame = gameState.curFrame;
    var totalScore = gameState.totalScore;
    var maxScore = gameState.maxScore;
    var score = gameState.score;

    var gameState = startingState();

    gameState.startFrame = curFrame;
    gameState.curFrame = curFrame;
    gameState.round = round + 1;
    gameState.totalScore = totalScore;
    gameState.maxScore = maxScore;

    return gameState;
}

从这两个函数可以看出游戏运行所必须的基本参数,以及核心状态gameState的各个属性。

判断状态函数分别有:

inPipeGap 判断鸟是否在Y轴与管子有接触
inPipe  判断鸟是否在X轴与管子有接触
collideGround 判断是否撞击地板
updateCollision 判断是否死亡

元素维持函数:

newPipe(curFrame,startX) 给定帧数和位置,创建新的管子
newLand(curFrame,startX) 给定帧数和位置,创建新的地板
updatePipes(gameState) 随着帧数更新管子的位置
updateLand  更新地板的位置
animation 调整Sprite Bird所用的动画
updateBird 调整鸟所在的位置(自由落体)
updateScore 更新分数
jump 开始游戏,或者重新开始游戏,或者设置跳跃帧jumpFrame,然后计算抛物线运动
drawSprite 在canvas的指定区域上绘制精灵
render 核心绘制函数

强化学习相关函数:

getQLState 拿到状态State(deltaX,deltaY),使用字符串加,进行传输
reward 奖励函数,返回Q
updateQL 强化学习的训练过程

强化学习核心算法分析

//拿到强化学习的状态
function getQLState(gameState) {
    var pipeList = gameState.pipeList;//获得当前有效地管子pipeList
    var birdY = gameState.birdY; //拿到当前bird的垂直坐标
    var pipeList = pipeList.filter(function (pipe) {
        return birdX < pipe.curX + pipeWidth;
    }).sort(function (a, b) {
        return a.curX - b.curX;
    });

    var firstPipe = first(pipeList);//拿到鸟前面的第一根管子
    var S = null;

    if (firstPipe) {//将管子与鸟之间的相对距离存储,以字符串形式传回 ,qlResolution = 15,其中鸟的宽度birdX = 69 
        S = [Math.floor(firstPipe.curX / qlResolution),
        Math.floor((firstPipe.gapTop - birdY) / qlResolution),
        ].join(',');
    }

    return S;
}

//奖励函数,非常经典的Q-learning更新过程
function reward(Q, S, S_, A, R) {
    if (S && S_ && A in [0, 1] && S in Q && S_ in Q)
        Q[S][A] = (1 - qlAlpha) * Q[S][A] + qlAlpha * (R + qlGamma * max(Q[S_]));
    return Q;
}

//强化学习训练过程
function updateQL(gameState) {
    if (!updateQL.enabled) return gameState;

    if (updateQL.skip) {
        updateQL.A = null;
        updateQL.S = null;
    }

    if (!updateQL.Q) {
        updateQL.Q = {};
        updateQL.S = null;
    }

    var Q = updateQL.Q;

    // 之前的状态
    var S = updateQL.S;
    // 之前的动作 
    var A = updateQL.A;
    // 当前的状态
    var S_ = getQLState(gameState);

//如果当前状态不在状态-动作函数Q中,进行初始化。A=0时不跳,A=1时跳
    if (S_ && !(S_ in Q)) Q[S_] = [0, 0];

    if (gameState.mode == "playing") {
        updateQL.Q = reward(Q, S, S_, A, qlAliveReward);
        updateQL.S = S_;

        // current action, 0 for stay, 1 for jump
        var A_ = 0;

        //episilon贪心法,有episilon的概率进行探索操作,不然进行贪心操作
        if (Math.random() < qlEpsilon) { // explore
            A_ = Math.random() < qlExploreJumpRate ? 1 : 0;
        } else if (S_ in Q) { // exploit 
            A_ = Q[S_][0] >= Q[S_][1] ? 0 : 1;
        }

        if (A_ === 1) gameState = jump(gameState);
        updateQL.A = A_;
    } else if (gameState.mode == "dead") {
        updateQL.Q = reward(Q, S, S_, A, qlDeadReward);
        updateQL.S = null;
        updateQL.A = null;

        // restart the game
        updateQL.skip = false;
        gameState = jump(gameState);
    }

    return gameState;
}


你可能感兴趣的:(深度学习)