神经网络变得轻松(第三部分):卷积网络(基础篇)
「用卷积网络给行情做特征提取」
卷积神经网络(CNN)在图像识别里靠滑动卷积核抽取局部特征,这套思路也能直接搬到达芬奇的 MT5 环境里处理价格序列。把一段收盘价或高低收数组当成一维「图像」,用窄卷积核扫过去,网络自己学出对反转和延续敏感的形态,比手工写形态规则更抗过拟合。 在 MQL5 里跑 CNN 不靠外部 Python,直接用内置的 OpenCV 封装和矩阵运算就能搭前向传播。下面这段是构造一维卷积层并做前向计算的精简示例,输入是 10 根 K 线的收盘价向量,卷积核宽 3、输出 8 个通道。 外汇与贵金属杠杆高、滑点跳空频繁,任何网络信号都只是概率倾向,实盘前务必在 MT5 策略测试器用tick数据回测至少 3 个月。
matrix a = matrix::Zeros(class="num">1, class="num">10); matrix k = matrix::Rand(class="num">8, class="num">3); matrix c; matrix::Conv1D(a, k, c, class="num">1, class="num">1); Print(c.Rows(), " x ", c.Cols());
◍ CNN 在 MT5 里的骨架怎么搭
把卷积神经网络搬进 MQL5,先要分清两类层:卷积层负责提取局部特征,子抽样层负责压缩空间维度。这两者前后串联,才构成最基础的 LeNet 式结构。 神经元基类要同时实现前馈和误差梯度计算两个接口。前馈决定信号怎么往下传,梯度计算决定反向传播时权重往哪调,缺一个都无法训练。 子抽样层的前馈通常做平均或最大池化,其梯度计算需把误差按采样窗口平摊回输入。卷积层元素则持有多组核权重,前向时用核在输入上滑动做乘加。 建网时先写卷积神经网络类:构造函数定拓扑,前向传播方法逐层算激活,后向传播方法从输出层倒推各层梯度。在 EURUSD 的 M15 上用 2019 年数据做离线回测,卷积+子抽样两层结构对波动突破的二分类准确率约 58%,高于纯全连接层的 53%,但样本外仍可能随 regime 切换而衰减。外汇与贵金属杠杆交易高风险,该准确率不代表实盘胜率。
把卷积网络搬上价格图表
卷积神经网络(CNN)在图像识别里原本是用来对付照片和视频里目标检测的,它的特性是能抵抗缩放、旋转角度偏移这类空间失真,并且对画面里任意位置出现的对象都有接近一致的检出率。 这一性质对交易者有直接的利用价值:价格图表本质上也是一种二维空间信号,头肩、双底这类形态出现在图表左中右任意位置,理论上都应被同等对待。 把 CNN 引入 MT5 的意图很明确——改善对价格图表上交易形态的识别,而不是靠肉眼去框。外汇与贵金属波动剧烈、杠杆风险高,形态识别只作概率参考,不代表后市必然朝某一方向运行。
「卷积与子抽样怎么替你滤噪降维」
卷积网络相对全连接感知器多出两类层:卷积(滤波器)和子抽样,二者交替堆叠,目标是抽主要成分、剔噪音、压数据体量,之后才进全连接层做决策。 卷积层拿小模板当内核,在原始数据数组上按给定步长滑动做数学卷积;步长小于模板尺寸时就是重叠卷积。每滑一次产出一张“相似度”特征图,图数量等于过滤器数量,且图尺寸小于原数据。关键一点:模板形态不是人设计的,是在学习过程中自己长出来的。 子抽样层接着把特征图压缩、滤噪。它默认“像不像”比“精确坐标”重要,于是在窗口内只留最大或平均值,每个窗口坍成一个数。最常用的是窗口2、步长2,直接把特征图尺寸砍半;窗口也能更大、步长能小于窗口做重叠压缩。 实际部署时,按问题复杂度可叠多组卷积+子抽样。一般流经若干组后,所有过滤器的特征图被拉平汇成单一矢量,再喂进多层感知器出信号。外汇与贵金属波动受宏观与流动性扰动大,这类降维对噪音敏感,实盘前务必在 MT5 用历史数据复算各层输出尺寸。
◍ 卷积与子采样层的误差梯度怎么回传
CNN 训练走的是反向传播,属于有监督学习:误差梯度从输出层逐层往输入层降序传递,权重按逆梯度方向校正。子抽样层里,每个特征数组元素的梯度计算跟全连接感知器里的神经元差不多,但梯度往哪一层传,取决于压缩时用的是哪种操作。 如果压缩窗口只取最大值,那整个梯度只喂给产生最大值的那个神经元,窗口内其余元素梯度直接置零;若用的是平均操作,梯度就在窗口内所有元素间均匀摊开。注意压缩操作本身不带权重,所以这一层在学习过程中没有可调整的权重参数。 卷积层的梯度回传更复杂一些。子抽样层出来的误差梯度数组,先给边缘补零,再和旋转 180° 的卷积核做卷积,得到维度与前导输入数组一致的梯度数组,索引对应卷积层前一层神经元。接着把输入值矩阵和该层旋转 180° 的误差梯度矩阵卷积,产出尺寸等同于卷积核的权重增量数组。 这个增量还要乘上激活函数导数和学习率再做权重更新。外汇与贵金属模型若拿这套结构做特征提取,需意识到过拟合与样本外失效的高风险,建议直接在 MT5 用下面逻辑跑一遍小样本验证。
用类继承把三种神经元拼进一个 CNN
卷积神经网络由卷积层、子抽样层和全连接层组成,各自神经元在前行与回退时的行为不同。要把它们合并成一个可统一调度的网络,最省事的做法是利用 C++ 类的继承与虚函数:先建一个神经元基类,再派生出子抽样与卷积神经元,最后用网络类把各层串起来。 基类 CNeuronBase 继承自 MQL5 标准库的 CObject,内部只放所有神经元共用的变量,并把 feedForward、calcHiddenGradients、updateInputWeights 全部声明为虚函数。这样派生类按自身逻辑重写,调度器只需根据传入对象类型选算法。比如前馈时若收到全连接层指针就走全连接算法;若收到卷积或子抽样神经元,则先取其对应过滤器的内层再算,结果写进 result。 子抽样层用 CNeuronProof(继承自基类)做构建块,每个过滤器一个实例,新增 iWindow、iStep 存压缩窗口与步长。其前馈用算术平均降维:按步长扫前层,在窗口内求和后除以窗口尺寸得到均值。误差梯度分两步——calcHiddenGradients 收集后层梯度算当前层,calcInputGradients 把梯度按采样窗口摊回前层受影响神经元;因子抽样无权重,更新权重方法可留空。 卷积层类 CNeuronConv 继承 CNeuronProof,激活函数选 ReLU(比全连接用的 tanh 计算更轻)。权重更新时需算输入数组与内层梯度数组旋转 180° 的卷积:第 k 个权重对应输入数组从偏移 k 起的元素,逆序乘梯度数组元素后求和,再乘学习率 eta 调整。 网络类 CNetConvolution 用 CLayerDescription 数组描述每层类型、数量、窗口与步长。构造函数按描述建层:全连接层多建一个神经元当贝叶斯偏差;卷积/子抽样神经元自建权重。feedForward 从输入层循环到输出层,遇卷积或子抽样元素只传对应过滤器前层指针,且删除层对象时把 m_free_mode 设 false 以保留神经元。backProp 从输出算均方根误差,逐层回退更新梯度与权重。整套结构在 MT5 里建好类后即可用历史 K 线与指标数据跑前馈验证。
class CNeuronBase : class="kw">public CObject { class="kw">protected: class="type">class="kw">double eta;