<jupyter_start><jupyter_text>知识参考：[1] [从马尔科夫决策过程到强化学习（From Markov Decision Process to Reinforcement Learning）](https://blog.csdn.net/qq_32690999/article/details/83745759)[2] [强化学习之二：Q-Learning原理及表与神经网络的实现（Q-Learning with Tables and Neural Networks）](https://blog.csdn.net/qq_32690999/article/details/78996381) 一、Q-LearningQ(s,a)指的是对于“在状态s下，采取行动a”的一个回报/价值估计，我们根据Q值来决策agent的下一步行动，并在不断行动的过程中，利用贝尔曼方程来学习/更新Q值，以学习如何更好地表现/达到更好的效果。- 贝尔曼方程$$Q(s,a)=Reward+\gamma*(max_{a'} Q(s',a'))$$意义：某一个状态与行动对应的Q值，等于当前回报+折现率*（采取下一行动a'后，到达状态s'的最大可能值）- 由贝尔曼方程衍生出的Q值更新公式借由贝尔曼方程得到的估计Q值的方法，我们采取“采样”（sample）的思想：**sample的本质就是在未知的情况下，去尝试获得碎片信息，然后一点点把碎片拼起来，就获得了完整的信息**。意即每当我们完成一次行动，就相当于做了一次sample：$$sample=Q(s,a)=Reward+\gamma*(max_{a'} Q(s',a'))$$然后，我们把根据此次sample获得的新的信息更新到旧的Q值之中（更新的幅度由学习率控制）：$$Q(s,a) = Q(s,a) + lr*(r + y*max_a Q(s1,a) - Q(s,a))$$意义：新的Q值等于 旧的Q值+学习率lr*（回报+折现率*当前状态s1下能获得的最大Q值-旧的Q值。然后我们不断重复【行动-采样-更新】这个过程，直到agent的表现令人满意！ 二、Table-Based Q-Learning当s和a都是有限集合的时候，(s,a)这样一个状态+行动的组合是有限的，因此我们可以将所有的Q值都“记住”，比如用一个列为行动，行为状态的表存起来，然后每次更新时，直接更新表中对应的Q值即可。|Q(s,a)|action-1|action-2|...||--|--|--|--||state-1|Q(state-1,action-1)|Q(state-1,action-2)|...||state-2|Q(state-2,action-1)|Q(state-2,action-2)|...||...|...|...|...|最开始的时候，我们初始化所有Q值为0。 超参数- 学习率：$\gamma$- 折现率：lr<jupyter_code>import gym
env = gym.make('CartPole-v0')
for i_episode in range(20):
    observation = env.reset()
    for t in range(100):
        env.render()
#         print(observation)
        action = env.action_space.sample()
        observation, reward, done, info = env.step(action)
        if done:
#             print("Episode finished after {} timesteps".format(t+1))
            break
exit()<jupyter_output><empty_output><jupyter_text>测试环境：[FrozenLake-v0](https://gym.openai.com/envs/FrozenLake-v0/)冰湖是这样的一个用字符表示的4*4的网格：```SFFF       (S: 起始点，安全)FHFH       (F: 冰冻的表面，安全)FFFH       (H: 洞，掉进去就挂了)HFFG       (G: 目标方格)```一局游戏会在**到达目标**或**掉进洞里**时结束。到达目标的话，会获得+1分的回报，掉进洞里则得0分。<jupyter_code># 实现基于表的Q-Learning
# 代码来自：https://medium.com/emergent-future/simple-reinforcement-learning-with-tensorflow-part-0-q-learning-with-tables-and-neural-networks-d195264329d0

import gym
import numpy as np

# 加载冰湖环境
env = gym.make('FrozenLake-v0')

# 实现Q表学习算法，初始化Q表为全0值，数组的行代表状态（所在的方格），列代表行动上下左右
Q = np.zeros([env.observation_space.n,env.action_space.n])

# 设置学习参数
lr = .8 #学习率
y = .95 #折现率

# 训练的episodes（周期/游戏局数）
num_episodes = 2000

# 创建列表以包含每个episode的总回报与总步数
jList = []
rList = []

for i in range(num_episodes):
    # 初始化环境，并获得初始状态
    s = env.reset()
    # 回报初始化为0
    rAll = 0
    # 表示当局游戏是否结束的boolean值
    d = False
    # agent行动的步数统计
    j = 0

    # Table-based Q-Learning算法核心部分
    while j < 99:
        # 步数自增1
        j+=1
        
        # 基于Q表贪婪地选择一个最优行动（有噪音干扰，以增强获得的Q表结果的稳定性）
        a = np.argmax(Q[s,:] + np.random.randn(1,env.action_space.n)*(1./(i+1)))

        # 从环境中获得当前新的状态、回报值、当局游戏是否已结束的信息
        s1,r,d,_ = env.step(a)
        
        # *用新的知识更新Q表
        Q[s,a] = Q[s,a] + lr*(r + y*np.max(Q[s1,:]) - Q[s,a])
        
        # 统计加总回报
        rAll += r
        
        # 当前状态更新
        s = s1
        
        # 判断游戏是否已经结束
        if d == True:
            break
    jList.append(j)
    rList.append(rAll)

print("Score over time: " +  str(sum(rList)/num_episodes))

print("Final Q-Table Values")
print(Q)

print('-------------------------------------------------')

def testAgent(QTable=None,test_episodes=30):
    jList = []
    rList = []
    
    trained=True
    # random agent
    if QTable is None:
        trained=False
        
    for i in range(test_episodes):
        s = env.reset()
        rAll = 0
        d = False
        j = 0
        
        while j<99:

            j+=1
            
            if trained:
                # 基于Q表贪婪地选择一个最优行动（这里去掉了之前训练过程中加入的噪音干扰）
                a = np.argmax(Q[s,:])
            else:
                a=env.action_space.sample()
            
            s,r,d,_=env.step(a)
            
            rAll+=r;
            
            # 判断游戏是否已经结束
            if d == True:
                break
        
        jList.append(j)
        rList.append(rAll)
    return jList,rList
print('基于学习到的Q值表，测试agent的性能：')
print()

print('随机行动/未经训练的agent得分率：')
randomAgentResult=testAgent()
print(sum(randomAgentResult[1])/len(randomAgentResult[1]))


print('Q-Learning agent得分率：')
QLearningAgentResult=testAgent(Q)
print(sum(QLearningAgentResult[1])/len(QLearningAgentResult[1]))


    


from gym import envs
print(envs.registry.all())


# change token of jupyter notebook
from notebook.auth import passwd
passwd()<jupyter_output>dict_values([EnvSpec(Copy-v0), EnvSpec(RepeatCopy-v0), EnvSpec(ReversedAddition-v0), EnvSpec(ReversedAddition3-v0), EnvSpec(DuplicatedInput-v0), EnvSpec(Reverse-v0), EnvSpec(CartPole-v0), EnvSpec(CartPole-v1), EnvSpec(MountainCar-v0), EnvSpec(MountainCarContinuous-v0), EnvSpec(Pendulum-v0), EnvSpec(Acrobot-v1), EnvSpec(LunarLander-v2), EnvSpec(LunarLanderContinuous-v2), EnvSpec(BipedalWalker-v2), EnvSpec(BipedalWalkerHardcore-v2), EnvSpec(CarRacing-v0), EnvSpec(Blackjack-v0), EnvSpec(KellyCoinflip-v0), EnvSpec(KellyCoinflipGeneralized-v0), EnvSpec(FrozenLake-v0), EnvSpec(FrozenLake8x8-v0), EnvSpec(CliffWalking-v0), EnvSpec(NChain-v0), EnvSpec(Roulette-v0), EnvSpec(Taxi-v2), EnvSpec(GuessingGame-v0), EnvSpec(HotterColder-v0), EnvSpec(Reacher-v1), EnvSpec(Pusher-v0), EnvSpec(Thrower-v0), EnvSpec(Striker-v0), EnvSpec(InvertedPendulum-v1), EnvSpec(InvertedDoublePendulum-v1), EnvSpec(HalfCheetah-v1), EnvSpec(Hopper-v1), EnvSpec(Swimmer-v1), EnvSpec(Walker2d-v1), EnvSpec(Ant-v1), EnvSpec(Hum[...]
{'fraction_non_alphanumeric': 0.16645581059099945, 'fraction_numerical': 0.02692933309235496, 'mean_word_length': 3.4557165861513686, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 8, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '184176', 'license': 'MIT', 'n_tokens_mistral': 2875, 'n_tokens_neox': 2981, 'n_words': 261, 'path': 'Q-Learning/TableBasedQLearning.ipynb', 'repo_name': 'bluemapleman/Maple-Reinforcement-Learning', 'size': '5533'}