从理论到代码 前面几篇文章讲了神经符号AI的理论、范式和挑战。现在是时候动手了。这篇文章带你从零实现一个神经符号推理系统——一个能解决简单数学推理问题的混合系统。
系统设计 我们的系统将解决以下问题:给定一段文字描述和一个数学问题,输出答案和推理过程。
示例输入:
"小明有5个苹果,小红给了小明3个苹果,然后小明吃了2个苹果。小明现在有多少个苹果?" 期望输出:
推理过程: 1. 小明最初有5个苹果 2. 小红给了小明3个苹果 → 5 + 3 = 8 3. 小明吃了2个苹果 → 8 - 2 = 6 答案:6个苹果 系统架构:
神经网络模块(GPT-2):理解自然语言,提取关键信息 符号推理模块:执行数学运算,保证计算正确性 桥接模块:将自然语言信息转化为符号化的数学表达式 代码实现 import torch import torch.nn as nn from transformers import GPT2LMHeadModel, GPT2Tokenizer import re class NeuroSymbolicReasoner: """神经符号推理系统""" def __init__(self): # 神经网络模块:用于自然语言理解 self.tokenizer = GPT2Tokenizer.from_pretrained('gpt2') self.lm = GPT2LMHeadModel.from_pretrained('gpt2') # 符号推理模块:用于数学运算 self.symbolic_engine = SymbolicMathEngine() # 桥接模块:将自然语言转化为符号表达式 self.bridge = NeuroSymbolicBridge() def reason(self, problem_text): # Step 1: 神经网络提取关键信息 entities = self.extract_entities(problem_text) actions = self.extract_actions(problem_text) # Step 2: 桥接模块将自然语言转化为符号表达式 symbolic_steps = self.bridge.convert_to_symbolic( entities, actions ) # Step 3: 符号推理引擎执行精确计算 result, reasoning_steps = self.symbolic_engine.execute( symbolic_steps ) return { 'answer': result, 'reasoning': reasoning_steps, 'confidence': self.estimate_confidence(entities, actions) } def extract_entities(self, text): """使用神经网络提取实体和数值""" # 简化版:使用正则表达式提取数值 # 实际应用中应使用NER模型 numbers = re.findall(r'\d+', text) names = re.findall(r'[小][明红]', text) return {'numbers': numbers, 'names': names} def extract_actions(self, text): """使用神经网络提取动作""" # 简化版:关键词匹配 actions = [] if '给了' in text or '给' in text: actions.append('add') if '吃了' in text or '用了' in text: actions.append('subtract') return actions class SymbolicMathEngine: """符号数学引擎:执行精确的数学运算""" def __init__(self): self.state = {} # 符号状态:存储变量的值 self.reasoning_steps = [] # 推理步骤记录 def execute(self, symbolic_steps): """执行符号化的推理步骤""" for step in symbolic_steps: operation = step['operation'] target = step['target'] value = step['value'] if operation == 'initialize': self.state[target] = value self.reasoning_steps.append( f"{target}最初有{value}" ) elif operation == 'add': old_value = self.state.get(target, 0) self.state[target] = old_value + value self.reasoning_steps.append( f"{target}增加了{value} → " f"{old_value} + {value} = {self.state[target]}" ) elif operation == 'subtract': old_value = self.state.get(target, 0) self.state[target] = old_value - value self.reasoning_steps.append( f"{target}减少了{value} → " f"{old_value} - {value} = {self.state[target]}" ) return self.state.get('result', 0), self.reasoning_steps class NeuroSymbolicBridge: """桥接模块:将自然语言理解结果转化为符号表达式""" def __init__(self): # 动作映射表 self.action_map = { '给了': {'operation': 'add', 'direction': 'receive'}, '吃了': {'operation': 'subtract', 'direction': 'self'}, '用了': {'operation': 'subtract', 'direction': 'self'}, } def convert_to_symbolic(self, entities, actions): """将自然语言理解结果转化为符号化的操作步骤""" steps = [] numbers = [int(n) for n in entities['numbers']] # 初始化 steps.append({ 'operation': 'initialize', 'target': 'result', 'value': numbers[0] }) # 执行操作 for i, action in enumerate(actions): if action == 'add': steps.append({ 'operation': 'add', 'target': 'result', 'value': numbers[i + 1] }) elif action == 'subtract': steps.append({ 'operation': 'subtract', 'target': 'result', 'value': numbers[i + 1] }) return steps # 使用示例 reasoner = NeuroSymbolicReasoner() problem = "小明有5个苹果,小红给了小明3个苹果,然后小明吃了2个苹果。小明现在有多少个苹果?" result = reasoner.reason(problem) print("推理过程:") for step in result['reasoning']: print(f" {step}") print(f"答案:{result['answer']}") 代码解析 为什么这个系统是神经符号的?
...