本文记录了我最近在机器学习课上做的一个有趣小项目:用一个叫 Fermi-Bose Machine(FBM)的结构来训练神经网络。它不用传统反向传播,而是用了物理里的“费米子”和“玻色子”思想,通过构造“样本对”来进行训练。虽然听起来有点玄学,但跑下来还挺有意思!
🔍 什么是 FBM(Fermi-Bose Machine)?
Fermi-Bose Machine(简称 FBM)是一个借用物理概念构建的神经网络训练方式。它主要有两个灵感来源:
-
玻色子(Boson):可以堆在一起 → 类似的样本应该靠近;
-
费米子(Fermion):彼此排斥 → 不同的样本应该远离;
我们用这套思想训练神经网络的“中间层表示”,也就是让模型在看图像时,能自动把同类图片聚在一起,不同类的图片拉开距离。核心思想是“对比学习 + 局部更新”。
🎯 我们用 MNIST 数据集来干什么?
这个项目用到的是大家熟悉的 MNIST 手写数字集,一共是 28×28 像素的灰度图。我们用它做了三件事:
-
构造“样本对”来训练隐藏层 —— 用的是“相同数字靠近、不同数字远离”的思路;
-
用原始标签来训练分类器 —— 把学好的中间表示喂给最后一层;
-
评估准确率 + 鲁棒性 —— 看模型是不是不仅准,而且不容易被小扰动误导。
🧠 网络结构长什么样?
我们分两步训练模型:
-
第一步训练隐藏层(不反向传播)
-
第二步训练读出层(正常分类器训练)
🌟 模型结构如下:
class R_FBMP3_Net(nn.Module): def __init__(self, in_features, hidden_features, out_features): super().__init__() self.fc_W1 = nn.Parameter(torch.randn(in_features, hidden_features)) self.fc_W2 = nn.Parameter(torch.randn(hidden_features, out_features)) self.fc_W2.requires_grad = False # 不训练 W2(只训练 W1) self.activator = nn.Tanh() def forward(self, x): x = x.view(-1, 2, in_features) # 每次输入一对样本 x = torch.matmul(x, self.fc_W1) return 0.5 * (1 + self.activator(x)) # 输出两个嵌入向量
训练思路非常简单粗暴,直接用距离计算 loss:
criterion = nn.PairwiseDistance(p=2) distance = criterion(left, right)**2 loss = (1 - label) * distance + label * F.relu(fermi_d - distance)
🧪 实验流程
简单说,就是先学“怎么看图”,再学“怎么分类”!
步骤如下:
-
构造正负样本对
-
用 FBM 网络训练隐藏层
-
保存隐藏层参数
-
用 MLP 网络加载隐藏层,训练输出层
-
在测试集上评估准确率
💡 训练代码片段示意
# 训练 FBM 隐藏层
for epoch in range(100): for inputs, labels in train_loader: pairs, pair_labels = batch_pair(inputs, labels) outputs = fbm_net(pairs) left, right = outputs[:, 0], outputs[:, 1] loss = compute_fbm_loss(left, right, pair_labels) optimizer.zero_grad() loss.backward() optimizer.step()
# 再训练分类器
for epoch in range(100): for inputs, labels in train_loader: outputs = classifier(inputs) loss = F.cross_entropy(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step()
📊 实验结果
我只用了 300 张训练图像 + 2000 张测试图像,模型最终在测试集上达到了约 89% 的准确率,虽然不如CNN那种高大上的结构,但考虑到我们“没用反向传播训练隐藏层”,这效果还算说得过去了!
🤔 一点小体会
这次项目让我感受到几点:
-
模型不一定都靠反向传播,对比学习、几何结构也能学到东西;
-
数据的组织方式,比如成对样本,也是一种“模型设计”;
-
MNIST 虽然简单,但依然是验证新思路的好平台;
-
写一个自己的小框架,远比调库跑准确率来得充实!
🧩 后续计划
未来我想尝试的方向有:
-
用 Fashion-MNIST 替代 MNIST,更接近真实图像分类
-
引入动态阈值,自动调节“远近距离”标准
-
结合一些轻量卷积模块,看能否让表征更强
🏁 写在最后
如果你也对这类“轻理论 + 重结构”的训练方法感兴趣,不妨试着自己写一个小框架。别总调库调模型,自己造轮子真的很爽!有问题评论区见 👇👇👇