对,而且我觉得 StructNN 最适合画成“结构逐步生长 + 候选竞争 + 学习反馈”的思路图,而不是传统 NLP 那种“输入 → 编码 → 分类 → 输出”。
可以先画成下面这个总图:
┌──────────────────┐
│ 输入句子 │
│ 小王说小红喜欢红苹果 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Token化 │
└────────┬─────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
小 王 喜 欢 红 苹 果
│ │ │
└─────────┬─────────┴─────────┬─────────┘
│ │
▼ ▼
┌────────────┐ ┌────────────┐
│组合候选生成器│ │组合候选生成器│
└──────┬─────┘ └──────┬─────┘
│ │
▼ ▼
小+王 → 小王 苹+果 → 苹果
│ │
└────────┬──────────┘
│
▼
┌──────────────┐
│ 形成新结构 │
│ Phrase Node │
└──────┬───────┘
│
▼
┌──────────────────────┐
│ 新一轮组合搜索 │
│ Phrase + Token/Phrase│
└──────────┬───────────┘
│
▼
红 + 苹果
│
▼
红苹果
│
▼
喜欢 + 红苹果
│
▼
EventMention(喜欢)
│
▼
┌──────────────────────┐
│ Form Tree稳定? │
└───────┬───────┬──────┘
│否 │是
│ ▼
│ ┌─────────┐
└───▶│ Freeze │
└────┬────┘
│
▼
┌──────────────────┐
│ Semantic Phase B │
└────────┬─────────┘
│
┌───────────────────┼──────────────────┐
▼ ▼ ▼
Entity Event Concept
│ │ │
└───────────────────┼──────────────────┘
│
▼
┌─────────────────┐
│ Semantic Graph │
│ 小红→喜欢→红苹果 │
└─────────────────┘
但这个还只是传统的结构构建流程。
你现在想让 StructNN 真正往“Structure Neural Network”走,我认为最关键的是把中间部分改成:
┌─────────────────┐
│ 当前已有结构集合 │
└────────┬────────┘
│
▼
┌───────────────────┐
│ Candidate Generator│
│ 生成组合候选 │
└─────────┬─────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
A + B B + C C + D
│ │ │
▼ ▼ ▼
候选① 候选② 候选③
│ │ │
└────────────┼────────────┘
▼
┌───────────────────┐
│ Feature Extraction│
│ 结构特征提取 │
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ Combination Score │
│ 组合评分 │
└─────────┬─────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
0.92 0.71 0.38
│ │ │
└────────────┼────────────┘
▼
┌────────────────┐
│ 选择组合动作 │
└───────┬────────┘
│
▼
COMBINE
│
▼
产生新的 Node
│
▼
加入结构记忆
│
▼
再次生成候选组合
│
└───────────────┐
│
▼
直到结构稳定 / 停止
这里有一个非常重要的变化
不是“Pattern 决定组合”。
而是:
Pattern
↓
提出“可能可以组合”
↓
候选
Scorer
↓
判断“组合的可能性有多大”
↓
Score
Decision
↓
决定是否真的组合
这就非常接近你以后想加入的“神经网络学习”。
再往后,可以形成一个闭环
我觉得最终的思路图应该是这个:
┌───────────────┐
│ 输入文本 │
└───────┬───────┘
↓
┌───────────────┐
│ Tokenize │
└───────┬───────┘
↓
┌────────────────────────────┐
│ 当前结构状态 S │
└─────────────┬──────────────┘
↓
┌────────────────────┐
│ 产生组合候选 C │
└─────────┬──────────┘
↓
┌────────────────────┐
│ 提取组合特征 F(S,C) │
└─────────┬──────────┘
↓
┌────────────────────┐
│ 组合评分器 │
│ │
│ 规则 → 统计 → 学习 │
└─────────┬──────────┘
↓
Score(C)
│
┌────────────┼────────────┐
↓ ↓ ↓
候选A 候选B 候选C
0.91 0.63 0.21
│
▼
选择 A
│
▼
COMBINE
│
▼
新结构 S'
│
▼
┌─────────────────────────┐
│ 结构是否已经稳定? │
└──────────┬──────────────┘
│
┌────┴────┐
│ │
否 是
│ │
│ ▼
│ FREEZE
│ │
│ ▼
│ Semantic Graph
│
└─────────┐
│
▼
下一轮组合
最关键的是“反馈”这一条线
以后学习机制不要只放在“评分器”里面。
应该形成:
结构组合
│
▼
Form Tree
│
▼
Semantic Graph
│
▼
评价 / 反馈
│
┌────────────┴────────────┐
▼ ▼
组合正确 组合错误
│ │
▼ ▼
Positive Negative
Feedback Feedback
│ │
└────────────┬────────────┘
▼
Structure Memory
│
▼
更新组合评分
│
▼
下一次遇到类似结构
│
▼
更好的候选排序
这时候 StructNN 就开始有一个非常有意思的性质:
它不是学习“这个句子应该输出什么答案”,而是在学习“下一步应该怎样组织结构”。
这个区别我认为非常重要。
甚至可以把它抽象成一个“结构生长算法”
最终可以用一句非常简单的数学描述:
S₀ = Token集合
Cₜ = Candidate(Sₜ)
Fₜ = Feature(Sₜ, Cₜ)
c* = argmax Score(Fₜ)
Sₜ₊₁ = COMBINE(Sₜ, c*)
直到:
Sₜ₊₁ ≈ Sₜ
然后学习机制就是:
Score = fθ(Features)
最开始:
fθ = 人工规则
以后:
fθ = 规则 + 统计学习
再以后:
fθ = Learned Model
甚至最终可以:
fθ = Neural Structure Scorer
但无论评分器怎么变,外面的结构生长框架不变。
所以我会把 StructNN 的核心架构概括成一句话
Token 是种子,COMBINE 是生长,Candidate 是可能性,Score 是选择,Structure Memory 是经验,Feedback 是学习,Form Tree 是阶段性成果,Semantic Graph 是对成熟结构的解释。
这样一来,你现在的 PatternMatcher 就不再是整个“大脑”,而更像是候选生成器和知识提供者。
而真正越来越像“神经网络”的部分,是中间那个:
候选 → 特征 → 评分 → 选择 → 反馈 → 更新。
这条线其实就是以后 StructNN 最值得继续发展的主线。