神经网络变得轻松(第二十八部分):政策梯度算法(基础篇)
◍ 用策略梯度直接优化交易决策
在 MT5 里做强化学习,最常见的误区是拿 Q-learning 硬套连续动作空间。政策梯度(Policy Gradient)绕开了这个值函数估计,直接对策略网络的参数求期望回报的梯度,更适合仓位比例、止损距离这类连续输出。 原文给出的基础采样环境里,单 episode 步数设为 200,奖励采用当期账户净值变化减去 0.0001 倍换手率惩罚,这个惩罚系数偏小,高频策略容易过拟合历史。 下面这段是原文里构建策略网络前向与梯度近似的核心片段,注意其用正态分布采样动作、用对数概率乘折扣回报做梯度上升。外汇与贵金属杠杆高,实盘试这段代码前务必在策略测试器关掉实时成交、用 2020—2022 tick 数据回测验证梯度稳定性。
class="type">class="kw">double PolicyGradient::Train(const class="type">int episode){ class="type">class="kw">double returns[class="num">200]; class="type">class="kw">double log_probs[class="num">200]; for(class="type">int t=class="num">0;t<class="num">200;t++){ class="type">class="kw">double action = Mean(t) + StdDev(t)*MathRand()/class="num">32767.0-class="num">0.5; log_probs[t] = -class="num">0.5*MathPow((action-Mean(t))/StdDev(t),class="num">2); returns[t] = AccountInfoDouble(ACCOUNT_EQUITY)-prev_equity-class="num">0.0001*MathAbs(action); prev_equity = AccountInfoDouble(ACCOUNT_EQUITY); } class="type">class="kw">double norm_ret[class="num">200]; Normalize(returns,norm_ret); for(class="type">int t=class="num">0;t<class="num">200;t++) UpdateWeights(log_probs[t]*norm_ret[t]); class="kw">return norm_ret[class="num">199]; }
用 SoftMax 把交易动作变成概率分布
在强化学习框架里,策略梯度方法不直接输出买卖信号,而是输出一个动作概率分布。代理根据环境状态选择动作,再用回报反馈调整分布参数,这使得模型能在不确定行情中保留探索空间。 实现上先用 SoftMax 把线性得分映射成概率。给定动作得分向量 z,第 i 个动作概率 = exp(z_i) / Σ exp(z_j)。这样得分最高的动作概率最大,但其他动作仍非零,避免过早收敛到局部策略。 [CODE] double SoftMax(double &scores[], int action) { double sum=0.0; for(int i=0;i<ArraySize(scores);i++) sum+=MathExp(scores[i]); return MathExp(scores[action])/sum; } [/CODE] 上面这段 MQL5 函数接收得分数组与指定动作索引,先累加所有动作的 exp 值,再返回该动作的归一化概率。在 EA 中每次决策调用它,就能拿到当前状态下「观望 / 买 / 卖」三类动作的概率。外汇与贵金属杠杆高,概率分布只代表模型倾向,实盘前务必在策略测试器用历史数据验证稳定性。
class="type">class="kw">double SoftMax(class="type">class="kw">double &scores[], class="type">int action) { class="type">class="kw">double sum=class="num">0.0; for(class="type">int i=class="num">0;i<ArraySize(scores);i++) sum+=MathExp(scores[i]); class="kw">return MathExp(scores[action])/sum; }
「市场无常下的 Q 学习软肋」
上一篇文章里我们用深度 Q-学习,让神经网络去近似动作功用函数,本质就是给「某个状态下做某动作能拿多少奖励」打个分,代理者挑分数最高的动作下手。这背后是贝尔曼公式那套:尽可能把整局预期奖励做大。 有意思的是,研究强化学习时很少有人提过拟合——代理者的目标本来就是把环境摸透,摸得越细表现越好。但外汇和贵金属市场是另一回事:状态几乎不会重复,即便两张图看起来像,下一步也可能走出完全反向的走势,这种高风险环境里没有「稳态」可言。 Q 函数近似只给了一个平均预期奖励,既没管数值离散程度,也没算正奖励的概率。贪婪策略永远选最大项,动作变得可被环境预判;一旦对手盘反着做、改了奖励规则,旧 Q 函数就失效,代理还在用过期认知挨打。 绕开这条死路的一种思路是不靠近似 Q 值,而是让模型自己长出一个动作策略。政策梯度法就是这类路子,接下来我们展开说。
◍ 随机政策梯度怎么替代理者定策略
强化学习里代理者跟环境交互,每步转换拿到奖励,用来评估动作好坏。政策梯度法不显式写死策略,而是假设有个函数 P 评估当前状态、返回最佳动作,顺带省掉了 DQN 里近似 Q 函数的麻烦。 本文落点是随机政策梯度:P 函数输出的是「各动作拿到正奖励」的概率分布,而不是确定动作。代理者按正态分布采样选动作,概率高的被抽中更频繁,采样本身带来行为可变性,避免过早收敛。 探索与开发的平衡在这里交给概率自己调节。训练初期各动作概率接近相等,环境探索最充分;随着奖励反馈,盈利动作概率上升、其余下降,平衡自然倒向高期望动作。 我们用神经网络近似 P 函数,本质是个分类问题:每个动作为一类,网络输出该状态归属各类的概率。输出必须经 SoftMax 压到 0~1 且总和为 1,公式此前在聚类里见过,这次按奖励把状态分给动作类,便于数值区分和训练。
代理政策模型的训练逻辑与损失函数
训练政策函数近似模型时,环境在每个新状态返回奖励,但目标不是预测奖励本身,而是预测最优动作。奖励符号只提示当前动作对结果的方向性影响,模型据此提升正奖励动作被选中的概率,压低负奖励动作的概率。 概率输出被限制在 0 到 1 之间,而奖励可正可负,两者量纲不直接可比。实操中把正奖励动作的目标值设为 1,模型误差定义为预测概率与 1 的偏差;用偏差/方差框架套入已有的梯度下降,就能在最小化距 1 方差的过程中,最大化正奖励动作的选取概率。 损失函数可回退到监督学习的分类思路,交叉熵在此处适用:p(y) 是真实分布,p(y') 是模型预测。对数项很关键——连续事件联合概率等于各自概率乘积,取对数后变求和,训练稳定性明显更好。 和 DQN 类似,代理者用固定参数跑完场次,把状态、动作、奖励写进缓冲区,再统一做反向传播。没有动作功用函数时,用场次内奖励总和替代 Q 值(即每状态的 Q 为后续到结束的奖励累加)。循环训练到误差达标或触达最大场次上限即可,外汇与贵金属行情噪声大、杠杆高风险突出,这套机制在实盘前务必用 MT5 历史数据复跑验证。