量化交易中文教材

第 03 章 三种网络初探:感知机、Hamming 网络与 Hopfield 网络

对应原书第 3 章"一个说明性例子"。原书把它比作"预告片":用一个极度简化的水果分拣问题,演示三种结构完全不同的网络如何解决同一个问题。三种网络分别代表全书的三大类——前馈网络、竞争网络、循环联想记忆网络。读完本章不要求完全理解它们,但要记住每类网络"怎么想问题"。

学习目标

读完本章,你应当能够:

  1. 写出苹果/橙子问题的输入编码和原型向量,并说明为什么同一个问题可以用多种网络求解。
  2. 解释感知机的决策边界 \(\mathbf{W}\mathbf{p}+b=0\) 为什么与权值向量正交,偏置如何平移边界,以及"线性可分"的含义。
  3. 推导 Hamming 网络前馈层输出等于 \(2R-2\times\)(Hamming 距离),手算循环竞争层的迭代,并说明 \(\varepsilon<1/(S-1)\) 的理由。
  4. 手算 Hopfield 网络的迭代,解释原书给出的 \(\mathbf{W},\mathbf{b}\) 为什么能让网络收敛到原型。
  5. 说出三种网络的输出形式差异,以及本章留下的五个问题分别在哪一章回答。
  6. 用"内积前馈层 + 竞争层"的思想实现一个市场状态(regime)识别器。

读前导读

这一章在解决什么问题

结论先说:同一个二分类问题,可以用三种完全不同的"思考方式"解决——画一条线(感知机)、找最像的模板(Hamming 网络)、让系统自己滑向最近的稳定点(Hopfield 网络)。本章是全书的预告片,不讲训练,所有权值都是手工设计的。

用你熟悉的东西对照:感知机就是"线性打分 + 阈值",和用 Altman Z 值判断企业是否可能破产是同一个结构——各项财务比率乘权重加总,超过临界值归一类,低于归另一类。Hamming 网络是"最近模板":把当前市场特征和几个典型状态逐一比对,选最像的那个,类似分析师把一家公司和几个可比公司模板比对后归类。Hopfield 网络是一个会随时间演化的系统,像一个均值回复过程:无论从哪里出发,最终被拉回某个"均衡点",而均衡点被设计成了原型本身。

需要先想起来的数学

  • 内积(点积)。\(\mathbf{x}^T\mathbf{y}=\sum_i x_iy_i\)。例:\([1,-1,-1]\cdot[-1,-1,-1]=-1+1+1=1\)。长度固定时,内积越大说明两个向量方向越一致,可以把它当作"没有去均值、没有除以标准差的相关系数"。见 第 00 册第 06 章 线性代数速成。
  • 正交与超平面。两个向量内积为 0 叫正交(几何上垂直)。满足 \(\mathbf{w}^T\mathbf{p}=c\) 的所有点 \(\mathbf{p}\) 构成一个"超平面":二维时是直线,三维时是平面,更高维依此类推。
  • 欧氏距离。\(\|\mathbf{x}-\mathbf{y}\|=\sqrt{\sum_i(x_i-y_i)^2}\),就是"直线距离"。\(\|\cdot\|\) 读作"范数",表示向量的长度。
  • 迭代与不动点。\(a(t+1)=g(a(t))\) 反复计算,如果某个 \(a^*\) 满足 \(a^*=g(a^*)\),它叫不动点(迭代到这里就不再变化)。例:\(a(t+1)=0.5a(t)+1\) 的不动点是 \(a^*=2\),从任何初值出发都收敛到 2,和债券价格随到期日临近向面值收敛的感觉相似。见 第 00 册第 01 章 函数极限与连续。

怎么读这一章

3.2 节感知机是核心必读,"决策边界与权值向量正交"这个几何事实会在第 04 章反复用到。3.3 节 Hamming 网络要读懂 \(2R-2d\) 的推导和竞争层的一次手算,\(\varepsilon<1/(S-1)\) 的论证第一次可以只看结论。3.4 节 Hopfield 网络第一次读把逐分量分析看懂即可,最后一段特征值的回顾等读完第 05 章再回头看。3.6 节量化实战展示了二值编码会造成"平局",值得细读。


3.1 问题:分拣水果

一个农产品仓库要用机器把混在一起的水果按种类分开。传送带经过三个简陋的传感器:

  • 形状(shape):近似圆形输出 1,偏椭圆输出 −1;
  • 质地(texture):表面光滑输出 1,粗糙输出 −1;
  • 重量(weight):超过 1 磅输出 1,否则输出 −1。

每个水果被表示成一个三维向量

\[\mathbf{p}=\begin{bmatrix}\text{shape}\\ \text{texture}\\ \text{weight}\end{bmatrix}.\tag{3.1}\]

假设只有苹果和橙子两类,它们的原型(prototype)是

\[\text{橙子 }\ \mathbf{p}_1=\begin{bmatrix}1\\-1\\-1\end{bmatrix},\qquad \text{苹果 }\ \mathbf{p}_2=\begin{bmatrix}1\\1\\-1\end{bmatrix}.\tag{3.2–3.3}\]

两个原型只在第二个元素(质地)上不同。网络收到一个输入向量后,要判断它是橙子还是苹果。真实的水果不会恰好等于原型,例如一个椭圆形的橙子会产生 \(\mathbf{p}=[-1,-1,-1]^T\),我们希望网络依然把它判为橙子。


3.2 感知机:画一条分界线

3.2.1 两输入的情形

感知机是一个使用对称硬限幅的单层网络:\(\mathbf{a}=\mathrm{hardlims}(\mathbf{W}\mathbf{p}+\mathbf{b})\)。先看两个输入、一个神经元的情形,取 \(w_{1,1}=-1\),\(w_{1,2}=1\):

\[a=\mathrm{hardlims}(n)=\mathrm{hardlims}\big([-1\ \ 1]\mathbf{p}+b\big).\tag{3.4}\]

当权值向量与输入的内积 \(\ge -b\) 时输出 1,否则输出 −1。于是输入平面被一条直线分成两半。取 \(b=-1\),这条决策边界(decision boundary)是

\[n=[-1\ \ 1]\mathbf{p}-1=0.\tag{3.5}\]

两个几何事实贯穿全书:

  • 决策边界总与权值向量正交。边界上的点满足 \(\mathbf{w}^T\mathbf{p}=-b\),即它们在 \(\mathbf{w}\) 方向上的投影都相同,所以构成一条垂直于 \(\mathbf{w}\) 的直线(高维时是超平面)。权值向量指向输出为 1 的一侧。
  • 偏置平移边界。改变 \(b\) 只改变边界到原点的距离,不改变它的方向。

推导拆解:为什么边界与 \(\mathbf{w}\) 正交?在边界上任取两点 \(\mathbf{p}_A,\mathbf{p}_B\),它们都满足 \(\mathbf{w}^T\mathbf{p}+b=0\)。两式相减,\(b\) 抵消,得 \(\mathbf{w}^T(\mathbf{p}_A-\mathbf{p}_B)=0\)。\(\mathbf{p}_A-\mathbf{p}_B\) 是沿边界方向的任意向量,它与 \(\mathbf{w}\) 的内积为 0,即互相垂直。为什么 \(\mathbf{w}\) 指向输出为 1 的一侧?从边界上一点沿 \(\mathbf{w}\) 方向走一小步 \(\delta\mathbf{w}\)(\(\delta>0\)),净输入变为 \(0+\delta\mathbf{w}^T\mathbf{w}=\delta\|\mathbf{w}\|^2>0\),输出为 1。以式 (3.5) 为例:\(\mathbf{w}=[-1,1]^T\),边界是直线 \(p_2=p_1+1\);点 \((0,2)\) 处 \(n=-0+2-1=1>0\),在 \(\mathbf{w}\) 指向的左上方一侧。边界到原点的距离是 \(|b|/\|\mathbf{w}\|\),所以改 \(b\) 只平移、不转向。

一般地,边界由 \(\mathbf{W}\mathbf{p}+b=0\) 决定(3.6)。边界必须是线性的,所以单层感知机只能识别线性可分(linearly separable)的模式——能用一个超平面完全分开的两类点。若 \(\mathbf{W}\) 有多行,每一行对应一条边界(第 4 章)。

3.2.2 为苹果/橙子设计感知机

现在 \(R=3\):

\[a=\mathrm{hardlims}\big([w_{1,1}\ \ w_{1,2}\ \ w_{1,3}]\mathbf{p}+b\big).\tag{3.7}\]

希望苹果输出 1、橙子输出 −1。两个原型只在 \(p_2\) 上不同,所以把它们对称分开的线性边界就是 \(p_1\)–\(p_3\) 平面,即 \(p_2=0\)(3.8),写成

\[[0\ \ 1\ \ 0]\mathbf{p}+0=0 .\tag{3.9}\]

于是

\[\mathbf{W}=[0\ \ 1\ \ 0],\qquad b=0.\tag{3.10}\]

权值向量与边界正交,指向苹果一侧;边界过原点,所以 \(b=0\)。

验证:

\[\text{橙子:}\ a=\mathrm{hardlims}\big([0\ 1\ 0][1,-1,-1]^T\big)=\mathrm{hardlims}(-1)=-1,\qquad \text{苹果:}\ a=\mathrm{hardlims}(1)=1 .\]

椭圆形橙子 \(\mathbf{p}=[-1,-1,-1]^T\):\(a=\mathrm{hardlims}(-1)=-1\),仍判为橙子(3.13–3.14)。事实上,任何在欧氏距离上更靠近橙子原型的输入都会被判为橙子,反之亦然——因为这条边界正好是两个原型连线的垂直平分面。

推导拆解:为什么是垂直平分面?"离 \(\mathbf{p}_2\)(苹果)更近"等价于 \(\|\mathbf{p}-\mathbf{p}_2\|^2<\|\mathbf{p}-\mathbf{p}_1\|^2\)。两边展开 \(\|\mathbf{p}-\mathbf{p}_q\|^2=\mathbf{p}^T\mathbf{p}-2\mathbf{p}_q^T\mathbf{p}+\mathbf{p}_q^T\mathbf{p}_q\),\(\mathbf{p}^T\mathbf{p}\) 两边相同可消去;又因两个原型长度相同(都是 \(\sqrt3\)),\(\mathbf{p}_q^T\mathbf{p}_q\) 也消去,只剩 \((\mathbf{p}_2-\mathbf{p}_1)^T\mathbf{p}>0\)。这里 \(\mathbf{p}_2-\mathbf{p}_1=[0,2,0]^T\),与 \(\mathbf{W}=[0\ 1\ 0]\) 方向相同。所以"离谁更近"恰好就是一个线性判别,权值向量是两个原型之差、边界过两原型的中点。这也是 LDA(线性判别分析)在等协方差下给出线性边界的同一道理。

这里留下两个问题:

  1. 输入维数高时无法画图设计边界,需要学习算法(第 4、7、10、11 章);
  2. 类别不是线性可分时,需要多层感知机(第 11 章),它能解决任意复杂的分类问题。

3.3 Hamming 网络:找最近的原型

Hamming 网络(Lippmann 1987)专为二值模式识别设计——输入的每个元素只取两个值,这里是 ±1。它由一个前馈层和一个循环层组成,两层神经元数相同,每个原型对应一个神经元。目标是:判断哪个原型离输入最近。循环层收敛后只有一个神经元输出非零,它的位置就指示了最近的原型。

3.3.1 前馈层:计算相关

前馈层的权值矩阵各行就是原型:

\[\mathbf{W}^1=\begin{bmatrix}\mathbf{p}_1^T\\ \mathbf{p}_2^T\end{bmatrix}=\begin{bmatrix}1&-1&-1\\1&1&-1\end{bmatrix},\qquad \mathbf{b}^1=\begin{bmatrix}3\\3\end{bmatrix}.\tag{3.15–3.16}\]

传递函数为线性,偏置的每个元素等于输入维数 \(R=3\)。输出

\[\mathbf{a}^1=\mathbf{W}^1\mathbf{p}+\mathbf{b}^1=\begin{bmatrix}\mathbf{p}_1^T\mathbf{p}+3\\ \mathbf{p}_2^T\mathbf{p}+3\end{bmatrix}.\tag{3.17}\]

为什么用内积?长度相同的向量,方向越一致内积越大,方向相反时内积最小(第 05 章细讲)。加上 \(R\) 是为了保证前馈层输出非负,这是循环层正常工作所必需的。

为什么叫 Hamming 网络。两个 ±1 向量之间的 Hamming 距离 \(d\) 定义为不同元素的个数。每个相同元素对内积贡献 \(+1\),每个不同元素贡献 \(-1\),所以

\[\mathbf{p}_q^T\mathbf{p}=(R-d)-d=R-2d,\qquad a^1_q=\mathbf{p}_q^T\mathbf{p}+R=2R-2d .\]

前馈层输出最大的神经元,就对应 Hamming 距离最近的原型。

白话解释:\(R-2d\) 的来历可以用"数票"理解。\(R\) 个位置里,\(R-d\) 个位置两向量相同,每个贡献 \((+1)(+1)\) 或 \((-1)(-1)=+1\);\(d\) 个位置不同,每个贡献 \((+1)(-1)=-1\)。合计 \((R-d)-d=R-2d\)。内积取值在 \(-R\)(完全相反)到 \(R\)(完全相同)之间,加上偏置 \(R\) 后落在 \([0,2R]\),正好非负。这像一张有 \(R\) 项指标的检查表:每项符合加一分、不符合扣一分,再加一个底分让总分不为负。

3.3.2 循环层:竞争出胜者

循环层是一个竞争层(competitive layer)。它用前馈层的输出初始化,然后神经元之间相互竞争,最后只剩一个神经元非零:

\[\mathbf{a}^2(0)=\mathbf{a}^1,\qquad \mathbf{a}^2(t+1)=\mathrm{poslin}\big(\mathbf{W}^2\mathbf{a}^2(t)\big),\tag{3.18–3.19}\]
\[\mathbf{W}^2=\begin{bmatrix}1&-\varepsilon\\-\varepsilon&1\end{bmatrix},\qquad \varepsilon<\frac{1}{S-1}.\tag{3.20}\]

(上标 2 是层号,不是平方。)展开一次迭代:

\[\mathbf{a}^2(t+1)=\mathrm{poslin}\begin{bmatrix}a^2_1(t)-\varepsilon a^2_2(t)\\ a^2_2(t)-\varepsilon a^2_1(t)\end{bmatrix}.\tag{3.21}\]

每个神经元都被减去"对手"的一个比例。大的减得少,小的减得多,差距越拉越大,小的最终被 poslin 截成 0。这就是生物学里侧抑制(lateral inhibition)的思想。

推导拆解:为什么"差距越拉越大"?看两神经元的差 \(\Delta(t)=a_1(t)-a_2(t)\)。在两者都为正、poslin 不起作用时,由式 (3.21),\(\Delta(t+1)=(a_1-\varepsilon a_2)-(a_2-\varepsilon a_1)=(1+\varepsilon)\Delta(t)\)。差距每一步放大 \((1+\varepsilon)\) 倍;而两者之和 \(a_1+a_2\) 每一步乘以 \((1-\varepsilon)\),在缩小。总量缩小、差距放大,较小者迟早跌到 0 以下,被 poslin 截为 0。之后胜者的更新是 \(a_1-\varepsilon\cdot0=a_1\),保持不变,网络停止。式 (3.20) 中 \(\varepsilon<1/(S-1)\) 的论证见下一段。

为什么要求 \(\varepsilon<1/(S-1)\)(原书留作思考)。一般 \(S\) 个神经元时,\(\mathbf{W}^2\) 对角为 1、其余为 \(-\varepsilon\),第 \(i\) 个神经元的更新是 \(a_i-\varepsilon\sum_{j\ne i}a_j\)。最危险的情形是所有神经元一样大,都等于 \(a\):更新后都变成 \(a(1-(S-1)\varepsilon)\)。若 \(\varepsilon\ge1/(S-1)\),所有神经元会同时被压到 0 或以下,胜者也随之消失,网络无法给出答案。条件 \(\varepsilon<1/(S-1)\) 保证最大的神经元始终保持正值。

例 椭圆形橙子 \(\mathbf{p}=[-1,-1,-1]^T\)。前馈层输出

\[\mathbf{a}^1=\begin{bmatrix}(1+1+1)+3\\(-1+1+1)+3\end{bmatrix}=\begin{bmatrix}4\\2\end{bmatrix}.\tag{3.23}\]

取 \(\varepsilon=1/2\):

\[\mathbf{a}^2(1)=\mathrm{poslin}\left(\begin{bmatrix}1&-0.5\\-0.5&1\end{bmatrix}\begin{bmatrix}4\\2\end{bmatrix}\right)=\mathrm{poslin}\begin{bmatrix}3\\0\end{bmatrix}=\begin{bmatrix}3\\0\end{bmatrix},\qquad \mathbf{a}^2(2)=\mathrm{poslin}\begin{bmatrix}3\\-1.5\end{bmatrix}=\begin{bmatrix}3\\0\end{bmatrix}.\]

连续两次相同,已收敛;第 1 个神经元(橙子)获胜。这是对的:输入到橙子原型的 Hamming 距离为 1,到苹果为 2(\(a^1=2R-2d\) 给出 \(6-2=4\) 和 \(6-4=2\),吻合)。

"内积前馈层 + 竞争动态层"是许多网络共用的原理。第 15、16、18、19 章的自组织竞争网络会更进一步:原型不必事先给定,网络能根据输入自己调整原型向量,也就是学会聚类。


3.4 Hopfield 网络:让原型成为吸引点

Hopfield 网络是一个循环网络,结构类似 Hamming 网络的循环层,但一层就能完成 Hamming 网络两层的工作。原书用的是标准 Hopfield 网络的一个简化变体:

\[\mathbf{a}(0)=\mathbf{p},\qquad \mathbf{a}(t+1)=\mathrm{satlins}\big(\mathbf{W}\mathbf{a}(t)+\mathbf{b}\big).\tag{3.26–3.27}\]

神经元用输入向量初始化,然后迭代直到输出收敛。正常工作时,收敛后的输出就是某个原型向量本身。satlins 在 \([-1,1]\) 内是线性的,超出则饱和于 ±1。

权值的系统设计比较复杂(本册第 19 章,原书第 21 章)。原书给出一组可行参数:

\[\mathbf{W}=\begin{bmatrix}0.2&0&0\\0&1.2&0\\0&0&0.2\end{bmatrix},\qquad \mathbf{b}=\begin{bmatrix}0.9\\0\\-0.9\end{bmatrix}.\tag{3.28}\]

为什么可行。橙子和苹果的第一个元素都是 1、第三个元素都是 −1,只在第二个元素上不同。所以我们希望:不管输入是什么,第一个元素收敛到 1,第三个元素收敛到 −1,第二个元素收敛到与输入第二元素同号的 ±1。逐分量写出:

\[a_1(t+1)=\mathrm{satlins}(0.2a_1(t)+0.9),\quad a_2(t+1)=\mathrm{satlins}(1.2a_2(t)),\quad a_3(t+1)=\mathrm{satlins}(0.2a_3(t)-0.9).\tag{3.29}\]
  • 第一个分量:\(a_1\in[-1,1]\) 时 \(0.2a_1+0.9\ge0.7\),且不动点 \(a=0.2a+0.9\) 的解 \(a=1.125>1\),所以 \(a_1\) 不断增大直到饱和于 1。
  • 第三个分量对称,饱和于 −1。
  • 第二个分量每次乘以 \(1.2>1\):初值为正则不断放大到 1,为负则放大到 −1(初值恰为 0 时停在 0,这是一个不稳定的平衡点)。

推导拆解:第一个分量的逻辑是"不动点在饱和区外"。若没有 satlins,\(a_1(t+1)=0.2a_1(t)+0.9\) 是一个收缩映射(斜率 \(0.2<1\)),从任何初值出发都收敛到不动点 \(a^*=0.9/(1-0.2)=1.125\),与 \(a(t)-a^*\) 每步乘 0.2 衰减。但 satlins 把输出截在 1,所以 \(a_1\) 在向 1.125 前进的途中先撞上 1,就停在 1:\(\mathrm{satlins}(0.2\times1+0.9)=\mathrm{satlins}(1.1)=1\)。第二个分量的系数 1.2 大于 1,是"发散映射",0 是唯一的不动点但不稳定,任何偏离都被放大——这正是想要的:把输入在质地上的微弱倾向放大成明确的 ±1。可以对照 AR(1):系数小于 1 均值回复,大于 1 爆炸。

这组 \((\mathbf{W},\mathbf{b})\) 不是唯一的选择。

例 椭圆形橙子:

\[\mathbf{a}(0)=\begin{bmatrix}-1\\-1\\-1\end{bmatrix},\ \mathbf{a}(1)=\begin{bmatrix}0.7\\-1\\-1\end{bmatrix},\ \mathbf{a}(2)=\begin{bmatrix}1\\-1\\-1\end{bmatrix},\ \mathbf{a}(3)=\begin{bmatrix}1\\-1\\-1\end{bmatrix}.\tag{3.30}\]

收敛到橙子原型。

从第 05 章的角度回看这个例子:\(\mathbf{W}\) 是对角阵,三个坐标轴就是它的特征向量,特征值 0.2 小于 1 的方向被"压缩"(由偏置决定去向),特征值 1.2 大于 1 的方向被"放大"(由初值符号决定去向)。循环网络的行为由权值矩阵的特征值决定,这正是原书第 6 章要建立的工具。


3.5 三种网络对比与留下的问题

感知机 Hamming 网络 Hopfield 网络
类别 前馈网络 竞争网络 循环联想记忆
机制 一次前向计算,线性边界 内积度量相似度 + 竞争选胜者 动力系统收敛到吸引点
输出形式 单个 ±1(橙/苹果) 唯一非零神经元的位置 原型模式本身
本册后续 第 04、07、10–12、13a、13b、17 章 第 15、18、19 章 第 19 章(原书第 20、21 章)
典型用途 模式识别、函数逼近 聚类、向量量化 联想记忆、优化问题

原书在结语中列出五个将在后文回答的问题:

  1. 输入很多、无法作图时,感知机的权值怎么定?——第 4、10 章。
  2. 类别不是线性可分时,怎样扩展感知机?——第 11、12、13a、13b 章。
  3. 不知道原型时,能否学出 Hamming 网络的权值?——第 16、18、19 章。
  4. 怎样系统地设计 Hopfield 网络的权值?——第 19 章(原书第 21 章)。
  5. Hopfield 网络一定收敛吗?会不会振荡甚至混沌?——第 19 章(原书第 20、21 章)。

3.6 量化实战:用 Hamming 网络识别市场状态

3.6.1 三类网络对应的三种量化任务

  • 前馈网络(感知机及其多层推广)对应"打分–分类"任务:用因子预测涨跌方向、把多个信号合成一个分数。本章提醒我们:一个线性打分模型加阈值,决策边界就是一个超平面。因子之间的交互作用、"中间有效两端失效"这类非线性,它都表达不了。
  • 竞争网络对应状态识别:把当前市场特征与若干典型状态(牛市、熊市、震荡市)的原型比较,取最近者。这就是最近邻/最近原型分类;当原型由数据自动学出时,就是第 15 章(原书第 16 章)的竞争学习,本质上与 k-means 聚类一致。
  • Hopfield 型联想记忆对应"从带噪观测恢复典型模式",在量化中较少直接使用,了解即可。

3.6.2 代码

下面先用 numpy 复现原书三种网络对椭圆形橙子的计算,然后把 Hamming 网络用于一个模拟的市场状态识别问题。每天把 5 个市场指标离散成 ±1:指数 20 日收益是否为正、波动率是否低于中位数、上涨家数占比是否过半、信用利差是否收窄、成交额是否放大。三个状态原型由研究员事先设定(例子中的设定只是示意)。模拟 250 个交易日,每个指标有 15% 的概率被噪声翻转。

import numpy as np

hardlims = lambda n: np.where(n >= 0, 1.0, -1.0)
poslin   = lambda n: np.maximum(n, 0.0)
satlins  = lambda n: np.clip(n, -1.0, 1.0)

# ---------- 原书第 3 章:苹果/橙子,三种网络 ----------
p_orange = np.array([1., -1., -1.]); p_apple = np.array([1., 1., -1.])
p_test   = np.array([-1., -1., -1.])                 # 椭圆形橙子

# 1) 感知机 W=[0 1 0], b=0
W = np.array([0., 1., 0.])
print("perceptron:", hardlims(W @ p_test))

# 2) Hamming 网络
def hamming(p, protos, eps=None, max_iter=100):
    S, R = protos.shape
    eps = eps if eps is not None else 1.0 / S          # 须满足 eps < 1/(S-1)
    a = protos @ p + R                                  # 前馈层:2R - 2*Hamming距离
    W2 = (1 + eps) * np.eye(S) - eps * np.ones((S, S))
    hist = [a.copy()]
    for _ in range(max_iter):
        a_new = poslin(W2 @ a)
        hist.append(a_new.copy())
        if np.allclose(a_new, a): break
        a = a_new
    return hist
for a in hamming(p_test, np.vstack([p_orange, p_apple]), eps=0.5):
    print("hamming a2:", a)

# 3) Hopfield 网络
Wh = np.diag([0.2, 1.2, 0.2]); bh = np.array([0.9, 0., -0.9])
a = p_test.copy()
for t in range(4):
    print("hopfield a(%d):" % t, np.round(a, 3))
    a = satlins(Wh @ a + bh)

# ---------- 量化:用 Hamming 网络做市场状态识别 ----------
# 每天把 5 个市场指标离散成 ±1:
# [指数20日收益>0, 波动率低于中位数, 上涨家数占比>50%, 信用利差收窄, 成交额放大]
regimes = {"牛市":   [ 1,  1,  1,  1,  1],
           "熊市":   [-1, -1, -1, -1,  1],
           "震荡市": [ 1,  1, -1,  1, -1]}
names  = list(regimes)
protos = np.array([regimes[k] for k in names], dtype=float)
rng = np.random.default_rng(7)
true_state = rng.integers(0, 3, size=250)                     # 模拟 250 个交易日
obs = protos[true_state].copy()
flip = rng.random(obs.shape) < 0.15                           # 每个指标 15% 概率被噪声翻转
obs[flip] *= -1
pred = []
for x in obs:
    a = hamming(x, protos)[-1]
    winners = np.flatnonzero(a > 0)
    pred.append(winners[0] if len(winners) == 1 else -1)      # -1 表示平局未决
pred = np.array(pred)
print("decided days: %d / 250, accuracy on decided: %.3f, ties: %d"
      % ((pred >= 0).sum(), (pred[pred >= 0] == true_state[pred >= 0]).mean(), (pred < 0).sum()))
# 前馈层输出 = 2R - 2d,可直接换算成"与每个原型的 Hamming 距离"
x = obs[0]; R = len(x)
d = (2 * R - (protos @ x + R)) / 2
print("day0 obs:", x.astype(int), "distances:", {k: int(v) for k, v in zip(names, d)})

运行输出:

perceptron: -1.0
hamming a2: [4. 2.]
hamming a2: [3. 0.]
hamming a2: [3. 0.]
hopfield a(0): [-1. -1. -1.]
hopfield a(1): [ 0.7 -1.  -1. ]
hopfield a(2): [ 1. -1. -1.]
hopfield a(3): [ 1. -1. -1.]
decided days: 188 / 250, accuracy on decided: 0.952, ties: 62
day0 obs: [ 1  1 -1  1 -1] distances: {'牛市': 2, '熊市': 4, '震荡市': 0}

解读:

  • 前 8 行与原书式(3.23)–(3.25)、(3.30)完全一致。
  • 在给出判断的 188 天中,识别准确率约 95%。但有 62 天出现平局:观测到两个原型的 Hamming 距离相同,竞争层的两个最大神经元同步衰减、谁也赢不了。这不是代码缺陷,而是二值编码丢失了信息——把连续指标硬切成 ±1,就无法区分"略高于中位数"和"远高于中位数"。实践中有三种改法:保留连续指标、用欧氏距离或马氏距离代替 Hamming 距离(此时就是标准的最近原型分类器);给不同指标不同权重;或者干脆用概率模型(如第 06 册第 12b 章的 Markov 转换模型)给出各状态的后验概率。

金融直觉:平局为什么这么多?看原型之间的距离:牛市与熊市差 4 位,牛市与震荡市差 2 位(第 3、5 位),熊市与震荡市差 4 位(第 1、2、4、5 位)。牛市与震荡市只差 2 位,噪声只要翻转其中一位,观测就落在两者正中间(到两者距离都是 1),必然平局。这和信用评级里相邻两档难以区分是一个道理:模板越接近,越容易出现"两边都像"的情况。练习 8 讨论的"最小 Hamming 距离"就是衡量这一点的指标。

  • 最后一行展示了前馈层的可解释性:\(a^1_q=2R-2d_q\) 可以直接换算成观测与每个原型的距离,研究员能看到"今天离震荡市 0 步、离牛市 2 步",而不仅是一个标签。
  • 原型应该由谁定?本例由研究员凭经验设定。若改为从历史数据中自动学出原型,就是第 15 章(原书第 16 章)的竞争学习/聚类问题。要注意聚类得到的"状态"必须事后检验是否有经济含义、是否在样本外稳定,否则很容易把噪声当成结构。

本章小结

同一个分类问题可以用三种思路求解。感知机画一条线性决策边界 \(\mathbf{W}\mathbf{p}+b=0\),边界与权值向量正交、偏置负责平移,只能处理线性可分问题。Hamming 网络先用内积计算输入与每个原型的相似度(输出 \(2R-2d\)),再用侧抑制的循环竞争层选出最近的原型,要求 \(\varepsilon<1/(S-1)\) 以免胜者也被压没。Hopfield 网络把原型设计成动力系统的稳定吸引点,从输入出发迭代,输出就是原型本身。这三种网络分别是全书前馈、竞争、循环联想记忆三大类的代表。

概念 公式 / 要点
感知机 \(\mathbf{a}=\mathrm{hardlims}(\mathbf{W}\mathbf{p}+\mathbf{b})\);边界 \(\mathbf{W}\mathbf{p}+b=0\),与权值向量正交
苹果/橙子感知机 \(\mathbf{W}=[0\ 1\ 0]\),\(b=0\)
Hamming 前馈层 \(\mathbf{W}^1\) 各行为原型,\(\mathbf{b}^1=R\mathbf{1}\),\(a^1_q=2R-2d_q\)
Hamming 循环层 \(\mathbf{a}^2(t+1)=\mathrm{poslin}(\mathbf{W}^2\mathbf{a}^2(t))\),\(\mathbf{W}^2\) 对角 1、非对角 \(-\varepsilon\),\(\varepsilon<1/(S-1)\)
Hopfield 网络 \(\mathbf{a}(0)=\mathbf{p}\),\(\mathbf{a}(t+1)=\mathrm{satlins}(\mathbf{W}\mathbf{a}(t)+\mathbf{b})\)
苹果/橙子 Hopfield \(\mathbf{W}=\mathrm{diag}(0.2,1.2,0.2)\),\(\mathbf{b}=[0.9,0,-0.9]^T\)
线性可分 两类点能被一个超平面完全分开

练习

基础

  1. 为区分香蕉 \([-1,1,-1]^T\) 与菠萝 \([-1,-1,1]^T\),分别设计感知机、Hamming 网络和 Hopfield 网络,并用若干输入测试。(原书 E3.1) 提示:两者在第 2、3 个元素上都不同。感知机可取 \(\mathbf{W}=[0\ 1\ -1]\)、\(b=0\)(香蕉输出 1);Hamming 网络 \(\mathbf{W}^1\) 的两行就是两个原型、\(\mathbf{b}^1=[3,3]^T\);Hopfield 网络可让第一个分量饱和到 −1,第 2、3 个分量需要"同时取相反符号",对角 \(\mathbf{W}\) 做不到,要引入非对角元素,例如让 \(a_2\) 与 \(a_3\) 互相抑制。
  2. 证明:对 ±1 向量,\(\mathbf{p}_q^T\mathbf{p}=R-2d(\mathbf{p}_q,\mathbf{p})\)。由此说明 Hamming 网络前馈层的偏置为什么取 \(R\)。
  3. 两神经元 hardlims 感知机,\(\mathbf{W}=\begin{bmatrix}1&1\\-1&1\end{bmatrix}\),\(\mathbf{b}=[-2,0]^T\)。它最多能分几类?画出各类区域,并计算输入 \([1,-1]^T\) 的输出。(原书 E3.4) 答案要点:两条边界最多分 \(2^2=4\) 类;\(n=[1+(-1)-2,\ -1+(-1)]^T=[-2,-2]^T\),输出 \([-1,-1]^T\)。
  4. Hopfield 网络 \(\mathbf{W}=\begin{bmatrix}1&-1\\-1&1\end{bmatrix}\),\(\mathbf{b}=\mathbf{0}\),输入 \([0.9,\ 1]^T\)。逐次迭代到收敛。(原书 E3.3) 答案要点:\(\mathbf{a}(1)=\mathrm{satlins}([-0.1,0.1]^T)=[-0.1,0.1]^T\),\(\mathbf{a}(2)=[-0.2,0.2]^T\),\(\mathbf{a}(3)=[-0.4,0.4]^T\),\(\mathbf{a}(4)=[-0.8,0.8]^T\),\(\mathbf{a}(5)=[-1,1]^T\) 并保持。\(\mathbf{W}\) 的特征值为 0(方向 \([1,1]^T\))和 2(方向 \([1,-1]^T\)),初值在 \([1,1]^T\) 方向的分量一步就被消掉,在 \([1,-1]^T\) 方向的分量每步翻倍直到饱和。

进阶

  1. 若 Hamming 网络循环层取 \(\varepsilon\ge1/(S-1)\),构造一个 \(S=3\) 的输入,使循环层所有神经元都变为 0。 提示:取 \(\varepsilon=0.5\),前馈层输出 \([4,4,4]^T\)。
  2. 设计感知机使两个给定点输出 1、另两个点输出 −1,并讨论解的非唯一性:什么样的边界"最好"?(原书 E3.5 的思路) 提示:与所有训练点距离都尽量远的边界最稳健——这是最大间隔(支持向量机)思想的萌芽,第 04 章会在收敛定理里再次看到"间隔"。
  3. Hamming 网络是为二值输入设计的。对连续输入 \(\mathbf{p}=[0.5,-0.5]^T\) 与两个原型 \([1,1]^T\)、\([2,-2]^T\),比较"内积最大"与"欧氏距离最近"两种判据的结论是否一致,说明原因。(与原书 E3.2、E3.6 同一考点) 提示:内积判据受原型长度影响,只有原型长度相同时,内积最大才等价于欧氏距离最近(因为 \(\|\mathbf{p}-\mathbf{p}_q\|^2=\|\mathbf{p}\|^2-2\mathbf{p}_q^T\mathbf{p}+\|\mathbf{p}_q\|^2\))。
  4. 量化思考:在 3.6 节的状态识别代码中,把噪声翻转概率从 15% 提高到 30%,平局天数和准确率会怎样变化?再把"熊市"原型的最后一维改为 −1,原型之间的最小 Hamming 距离变了吗?这对识别有什么影响? 提示:原型之间的最小距离越大,抗噪声能力越强,这与纠错码的思想相同。

原书推荐习题:E3.1(完整走一遍三种网络设计)、E3.2(感知机与 Hamming 网络在非二值输入下的差异)、E3.3(Hopfield 吸引域)、E3.5(边界非唯一与"最优边界")。


原书对照

本章内容 原书章节 PDF 页码
3.1 问题陈述 3.1 Problem Statement p.62–63
3.2 感知机 3.2 Perceptron(两输入情形、模式识别例) p.63–68
3.3 Hamming 网络 3.3 Hamming Network p.68–72
3.4 Hopfield 网络 3.4 Hopfield Network p.72–74
3.5 对比与问题 Epilogue p.75
练习 Exercises E3.1–E3.7 p.76–79

原书配套演示:nnd3pc(感知机分类)、nnd3hamc(Hamming 分类)、nnd3hopc(Hopfield 分类)。