有了 Deep Q-Network 的理论基础,根据文末的算法,就可以实现DQN。直接看所有代码
整个程序框架为:
1 | # 经验记忆库 |
主函数执行:
1 | rl = DQN( |
有了 Deep Q-Network 的理论基础,根据文末的算法,就可以实现DQN。直接看所有代码
整个程序框架为:
1 | # 经验记忆库 |
主函数执行:
1 | rl = DQN( |
Deep Q-Network (DQN) 算法在 Q-Learning 算法的基础上,利用 深度卷积神经网络来逼近值函数,将强化学习与深度学习相结合,估计出最优行为价值函数 (optimal action-value function) \[ Q^*(s,a) = \max_\pi \mathbb{E}[G_t|s_t=s, a_t=a, \pi] \] 然而通过深度学习的视角来进行强化学习面临着许多问题,一个是深度学习程序需要大量的人为标记的数据,但强化学习通常需要在大量稀疏的、延迟的、带有噪声的奖励数值中学习。另一个问题是大多数深度学习算法都需要假定数据样本之间是独立的,但强化学习的数据是一连串高度关联的序列。
为了解决这些问题,DQN 算法利用了 经验回放机制 和 设置目标网络与评估网络 。
有两篇论文提出了 DQN 算法,分别是:
- Mnih V, Kavukcuoglu K, Silver D, et al. Playing Atari with Deep Reinforcement Learning[J]. Computer Science, 2013.
- Mnih V, Kavukcuoglu K, Silver D, et al. Human-level control through deep reinforcement learning[J]. Nature, 2015, 518(7540):529.
后一篇论文比前一篇多了目标、评估网络的特性。
1 | sudo apt-get install python3-pip |
若出现 Command "[Python](https://link.jianshu.com/?t=http://lib.csdn.net/base/python) setup.py egg_info" failed with error code 1 in /tmp/pip-build-*
错误,则需要安装:
1 | sudo pip3 install setuptools |
新建shadowsocks配置文件shadowsocks.json :
1 | { |
PORT1
,PORT2
为服务器监听的端口号,后面是客户端连接当前端口的密码
开启服务器测试:
1 | ssserver -c shadowsocks.json |
如遇到 AttributeError: /usr/lib/x86_64-Linux-gnu/libcrypto.so.1.1: undefined symbol: EVP_CIPHER_CTX_cleanup
错误,则:
打开文件 /usr/local/lib/python3.6/dist-packages/shadowsocks/crypto/openssl.py
将 libcrypto.EVP_CIPHER_CTX_cleanup.argtypes = (c_void_p,)
改为 libcrypto.EVP_CIPHER_CTX_reset.argtypes = (c_void_p,)
将 libcrypto.EVP_CIPHER_CTX_cleanup(self._ctx)
改为 libcrypto.EVP_CIPHER_CTX_reset(self._ctx)
重新启动 shadowsocks 即可。
马尔可夫决策过程 (Markov decision process, MDP) 对完全可观测的环境进行了正式的描述,也就是说现有的状态完全决定了决策过程中的特征。
几乎所有强化学习的问题都可以转化为MDP,如:
针对连续MDP问题的最优决策
不完全观测问题也可以转化为MDP
一个状态\(S_t\)具有马尔可夫性的当且仅当 \[ \mathbb{P}[S_{t+1}|S_t] = \mathbb{P}[S_{t+1}|S_1, \dots , S_t] \] 一个状态保留了所有历史状态的信息,而一旦一个状态确定了,历史状态就不再重要,也就是说一个状态完全可以决定未来状态
状态转移概率:
\[ \mathcal{P}_{ss'}=\mathbb{P}[S_{t+1}=s'|S_t=s] \]
状态转移矩阵,每行之和为1 \[ \mathcal{P}= \begin{bmatrix} \mathcal{P}_{11} & \cdots & \mathcal{P}_{1n} \\ \vdots \\ \mathcal{P}_{n1} & \cdots & \mathcal{P}_{nn} \end{bmatrix} \]
在编写函数时, *args
和 **kwargs
可以使我们向函数传递任意数量的参数(Arbitrary Argument Lists)
*args
将函数的普通参数打包成元组的形式:
1 | >>> def foo(*args): |
**kwargs
将带有关键字的参数打包成字典的形式:
1 | >>> def bar(**kwargs): |
普通参数、*args
、 **kwargs
都可以混合使用
1 | def foo(kind, *args, **kwargs): |