Files
2026_DesignAI/officefile/md/supplements/01-foundations/01.4-feedback-and-learning.md
T
pengxiao a90f7adfa1 refactor(officefile): 按 md/latex/word 三层结构重组文档目录
将 Markdown 源文件移入 md/,LaTeX 工作目录保留在 latex/,
Word 导出移入 word/;删除临时脚本、调试截图和空 stub。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 14:25:21 +08:00

719 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 01.4 反馈与学习
## 核心问题
> 系统如何从经验中改进?
> 强化学习的基本直觉是什么?
> 如何设计一个好的奖励函数?
---
## 概念讲解
### 反馈循环
**反馈**是系统学习的基础机制:
```
┌─────────────────────────────────────────────────┐
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐│
│ │ Action │ ───→ │ Effect │ ───→ │Reward ││
│ └─────────┘ └─────────┘ └─────────┘│
│ │ │ │
│ │ ┌────────────┐ │ │
│ └───────────→│ Update │←──────┘ │
│ ↑ │
│ │ │
│ ┌──────┴──────┐ │
│ │ Policy │ │
│ │ Improvement│ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────┘
```
**反馈的类型**
| 类型 | 说明 | 例子 |
|-----|------|------|
| **正反馈** | 强化正确行为 | 生态廊道有效,增加类似策略 |
| **负反馈** | 抑制错误行为 | 阻力面不合理,调整权重 |
| **延迟反馈** | 效果滞后 | 生态工程几年后才见效 |
| **隐式反馈** | 未明确标注 | 用户不使用某功能 = 不好用 |
### 强化学习的直觉
强化学习(RL)是关于"如何通过试错学习":
```
强化学习核心概念
智能体 ──→ 动作 ──→ 环境 ──→ 奖励
↑ │
│ │
└─────────────── 观察状态 ←──────────────┘
更新策略
```
**关键要素**
1. **状态 (State)**:智能体看到的当前情况
2. **动作 (Action)**:智能体能做的事情
3. **奖励 (Reward)**:动作好坏的即时反馈
4. **策略 (Policy)**:状态到动作的映射规则
5. **价值函数 (Value)**:对长期收益的估计
```python
# RL的数学直觉
# 策略:在状态s采取动作a的概率
π(a|s) = P(action=a | state=s)
# 价值函数:从状态s开始的期望累积奖励
V(s) = E[Σ γ^t * r_t | s_0 = s]
# γ是折扣因子,平衡即时和长期奖励
# 动作价值函数:在状态s采取动作a后的期望累积奖励
Q(s,a) = E[Σ γ^t * r_t | s_0 = s, a_0 = a]
# 目标:找到最优策略,最大化累积奖励
π* = argmax_π V^π(s)
```
### 探索与利用的权衡
RL中经典的困境:
```
探索 (Explore) vs 利用 (Exploit)
利用 探索
↓ ↓
选择已知最好的动作 尝试新动作
获得稳定奖励 可能发现更好动作
可能错过最优 可能浪费资源
```
**策略**
| 策略 | 方法 | 适用场景 |
|-----|------|---------|
| **ε-greedy** | 以ε概率随机探索 | 通用,简单 |
| **Boltzmann** | 按价值概率选择 | 需要细粒度控制 |
| **UCB** | 上置信界选择 | 需要理论保证 |
| **Thompson Sampling** | 采样后验概率 | 贝叶斯框架 |
```python
def epsilon_greedy_action(q_values, epsilon, n_actions):
"""
ε-greedy策略
Args:
q_values: 各动作的估计价值
epsilon: 探索概率
n_actions: 动作数量
Returns:
选择的动作
"""
if np.random.random() < epsilon:
# 探索:随机选择
return np.random.randint(n_actions)
else:
# 利用:选择价值最高的
return np.argmax(q_values)
# ε的衰减策略
def epsilon_schedule(initial_epsilon, final_epsilon, total_steps, current_step):
"""线性衰减ε"""
decay = (initial_epsilon - final_epsilon) / total_steps
return max(final_epsilon, initial_epsilon - decay * current_step)
```
---
## 设计原理
### 奖励函数设计
奖励函数定义了"什么是好的行为":
```python
"""
奖励函数设计原则
"""
# 原则1: 清晰明确
# 好的奖励
def good_reward(ecological_quality):
"""生态质量越高,奖励越高"""
return ecological_quality
# 不好的奖励(有歧义)
def bad_reward(ecological_quality, cost):
"""混合多个目标,可能冲突"""
return ecological_quality - cost * 0.001
# 原则2: 适度塑形 (Reward Shaping)
# 不要过度引导,让智能体自己探索
def shaped_reward(base_reward, intermediate_metric):
"""
基础奖励 + 形状奖励
基础奖励:定义最终目标
形状奖励:引导到达目标(权重较小)
"""
return base_reward + 0.1 * intermediate_metric
# 原则3: 避免奖励黑客 (Reward Hacking)
# 防止智能体找到"作弊"方法
def safe_reward_with_constraints(action_result):
"""
带约束的奖励
"""
base_reward = action_result['quality']
# 如果违反约束,给予惩罚
if action_result['violates_constraint']:
base_reward -= 100 # 大惩罚
# 如果使用"作弊"方法,给予惩罚
if action_result['uses_exploit']:
base_reward -= 50
return base_reward
# 原则4: 多目标平衡
def multi_objective_reward(ecological, economic, social, weights):
"""
多目标加权
Args:
ecological: 生态效益
economic: 经济效益
social: 社会效益
weights: 各目标权重
Returns:
综合奖励
"""
# 归一化到[0,1]
normalized = {
'eco': min(ecological / 100, 1.0),
'eco': min(economic / 1000, 1.0),
'soc': min(social / 100, 1.0)
}
total = (weights['eco'] * normalized['eco'] +
weights['eco'] * normalized['eco'] +
weights['soc'] * normalized['soc'])
return total
```
### 在空间分析中的应用
```python
class SpatialOptimizerRL:
"""
用强化学习优化空间布局
场景:给定区域内选择最优生态廊道路线
"""
def __init__(self, landscape, constraints):
self.landscape = landscape
self.constraints = constraints
# 状态空间:当前的廊道路线
# 动作空间:下一步走向哪个像元
# 奖励:连通性、距离、穿越地类的综合
def state_representation(self):
"""将当前空间格局转换为状态表示"""
return {
'current_position': self.current_position,
'visited_cells': self.visited_cells,
'local_context': self._get_local_context()
}
def available_actions(self):
"""获取可用的动作"""
# 可以向8个方向移动
directions = [
(0, 1), (1, 0), (0, -1), (-1, 0), # 上下左右
(1, 1), (1, -1), (-1, 1), (-1, -1) # 对角
]
actions = []
for dx, dy in directions:
new_x = self.current_position[0] + dx
new_y = self.current_position[1] + dy
if self._is_valid_move(new_x, new_y):
actions.append((new_x, new_y))
return actions
def reward_function(self, action, new_state):
"""
定义奖励函数
考虑:
1. 穿越的土地类型(林地奖励,城市惩罚)
2. 距离目标的远近(越近越好)
3. 是否到达目标(大奖励)
"""
x, y = new_state['position']
# 1. 土地类型奖励/惩罚
land_type = self.landscape[y, x]
land_rewards = {
'forest': 10,
'grassland': 5,
'wetland': 8,
'agriculture': 0,
'urban': -50,
'water': -20
}
land_reward = land_rewards.get(land_type, -10)
# 2. 距离奖励(离目标越近越好)
dist_to_goal = self._distance_to_goal(new_state['position'])
distance_reward = -dist_to_goal * 0.1
# 3. 目标到达奖励
goal_reward = 0
if new_state['position'] == self.goal_position:
goal_reward = 1000
# 4. 约束惩罚
constraint_penalty = 0
if self._violates_constraint(new_state):
constraint_penalty = -100
# 总奖励
total_reward = (land_reward + distance_reward +
goal_reward + constraint_penalty)
return total_reward
def train(self, n_episodes=1000):
"""
训练智能体
使用Q-learning
"""
q_table = {} # Q值表
for episode in range(n_episodes):
state = self._reset()
epsilon = self._epsilon_schedule(episode)
done = False
while not done:
# ε-greedy选择动作
if np.random.random() < epsilon:
action = np.random.choice(self.available_actions())
else:
# 选择Q值最高的动作
q_values = [q_table.get((state, a), 0)
for a in self.available_actions()]
action = self.available_actions()[np.argmax(q_values)]
# 执行动作
new_state, reward, done = self._step(action)
# 更新Q值
old_q = q_table.get((state, action), 0)
max_next_q = max([q_table.get((new_state, a), 0)
for a in self.available_actions()] + [0])
# Q-learning更新公式
q_table[(state, action)] = old_q + 0.1 * (
reward + 0.99 * max_next_q - old_q
)
state = new_state
return q_table
```
---
## 代码示例
### 简化的生态网络优化RL
```python
"""
简化版:用Q-learning优化生态源地选择
"""
import numpy as np
from typing import List, Dict, Tuple
import random
class EcologicalNetworkOptimizer:
"""
生态网络优化器(RL简化版)
问题:从候选源地中选择最优组合
- 最大化总生态价值
- 满足连通性要求
- 预算约束
"""
def __init__(self, candidate_sites: List[Dict], budget: float):
self.candidate_sites = candidate_sites
self.budget = budget
# 动作:选择或不选择某个源地
self.n_actions = len(candidate_sites)
# 状态:已选源地列表
# 简化:用位掩码表示状态
self.n_states = 2 ** self.n_actions
# Q表
self.q_table = np.zeros((self.n_states, self.n_actions))
def state_to_mask(self, state: int) -> List[bool]:
"""状态索引转位掩码"""
return [(state >> i) & 1 for i in range(self.n_actions)]
def mask_to_state(self, mask: List[bool]) -> int:
"""位掩码转状态索引"""
state = 0
for i, bit in enumerate(mask):
if bit:
state |= (1 << i)
return state
def available_actions(self, state_mask: List[bool]) -> List[int]:
"""获取可用动作(未选的源地)"""
return [i for i, selected in enumerate(state_mask) if not selected]
def reward_function(self, state_mask: List[bool]) -> float:
"""
计算当前选择的奖励
考虑:
1. 总生态价值
2. 连通性
3. 预算约束
"""
# 选中源地
selected_sites = [self.candidate_sites[i]
for i, selected in enumerate(state_mask) if selected]
if not selected_sites:
return 0
# 1. 总生态价值
total_value = sum(site['value'] for site in selected_sites)
# 2. 连通性(简化:已选源地之间的平均距离)
if len(selected_sites) > 1:
positions = [(site['x'], site['y']) for site in selected_sites]
distances = []
for i in range(len(positions)):
for j in range(i + 1, len(positions)):
dist = np.sqrt((positions[i][0] - positions[j][0])**2 +
(positions[i][1] - positions[j][1])**2)
distances.append(dist)
avg_distance = np.mean(distances)
connectivity_reward = -0.1 * avg_distance # 距离越近越好
else:
connectivity_reward = 0
# 3. 预算惩罚
total_cost = sum(site['cost'] for site in selected_sites)
budget_penalty = 0
if total_cost > self.budget:
budget_penalty = -100 * (total_cost - self.budget) / self.budget
# 总奖励
total_reward = total_value + connectivity_reward + budget_penalty
return total_reward
def step(self, state: int, action: int) -> Tuple[int, float, bool]:
"""
执行一步
Returns:
next_state: 下一个状态
reward: 奖励
done: 是否结束
"""
state_mask = self.state_to_mask(state)
# 执行动作(选择一个源地)
if state_mask[action]: # 已经选过了
return state, -100, True # 惩罚并结束
new_mask = state_mask.copy()
new_mask[action] = True
# 计算奖励
reward = self.reward_function(new_mask)
# 检查是否结束(预算用完或所有源地都选了)
total_cost = sum(self.candidate_sites[i]['cost']
for i, selected in enumerate(new_mask) if selected)
done = (total_cost >= self.budget) or (sum(new_mask) == len(new_mask))
next_state = self.mask_to_state(new_mask)
return next_state, reward, done
def train(self, n_episodes=1000, alpha=0.1, gamma=0.99,
epsilon_start=1.0, epsilon_end=0.01):
"""
Q-learning训练
Args:
n_episodes: 训练回合数
alpha: 学习率
gamma: 折扣因子
epsilon_start: 初始探索率
epsilon_end: 最终探索率
"""
for episode in range(n_episodes):
# 线性衰减ε
epsilon = epsilon_start - (epsilon_start - epsilon_end) * episode / n_episodes
state = 0 # 初始状态(空)
done = False
while not done:
state_mask = self.state_to_mask(state)
available = self.available_actions(state_mask)
if not available:
break
# ε-greedy
if np.random.random() < epsilon:
action = random.choice(available)
else:
q_values = [self.q_table[state, a] for a in available]
action = available[np.argmax(q_values)]
# 执行动作
next_state, reward, done = self.step(state, action)
# Q-learning更新
old_q = self.q_table[state, action]
next_max = np.max(self.q_table[next_state])
self.q_table[state, action] = old_q + alpha * (
reward + gamma * next_max - old_q
)
state = next_state
# 定期报告
if episode % 100 == 0:
current_epsilon = epsilon_start - (epsilon_start - epsilon_end) * episode / n_episodes
print(f"Episode {episode}, ε={current_epsilon:.3f}, "
f"Best Q: {np.max(self.q_table[0]):.2f}")
return self.q_table
def get_solution(self) -> List[Dict]:
"""获取学习到的最优解"""
state = 0
state_mask = self.state_to_mask(state)
solution = []
while True:
available = self.available_actions(state_mask)
if not available:
break
# 选择Q值最高的动作
q_values = [self.q_table[state, a] for a in available]
action = available[np.argmax(q_values)]
solution.append(self.candidate_sites[action])
state, _, done = self.step(state, action)
if done:
break
return solution
# 示例使用
def example_usage():
"""示例使用"""
print("=== 生态网络优化:Q-learning ===\n")
# 创建候选源地
np.random.seed(42)
n_candidates = 10
candidates = []
for i in range(n_candidates):
candidates.append({
'id': i,
'x': np.random.randint(0, 100),
'y': np.random.randint(0, 100),
'value': np.random.randint(50, 150),
'cost': np.random.randint(20, 80)
})
budget = 200
print(f"候选源地数: {n_candidates}")
print(f"预算: {budget}\n")
# 创建优化器并训练
optimizer = EcologicalNetworkOptimizer(candidates, budget)
optimizer.train(n_episodes=500)
# 获取解
solution = optimizer.get_solution()
print("\n=== 最优解 ===")
print(f"选择源地数: {len(solution)}")
total_value = sum(s['value'] for s in solution)
total_cost = sum(s['cost'] for s in solution)
print(f"总价值: {total_value}")
print(f"总成本: {total_cost}")
print("\n选择的源地:")
for s in solution:
print(f" 源地 {s['id']}: 价值={s['value']}, 成本={s['cost']}")
if __name__ == "__main__":
example_usage()
```
---
## 案例分析
### ENAgent中的反馈机制
```python
class ENAgentFeedback:
"""
ENAgent的反馈机制
场景:生态网络迭代的改进
"""
def __init__(self):
self.iteration_history = []
self.performance_metrics = []
def collect_feedback(self, iteration, result, human_feedback):
"""
收集每轮的反馈
Args:
iteration: 迭代次数
result: 本轮结果
human_feedback: 人类专家的反馈
"""
feedback_record = {
'iteration': iteration,
'result': result,
'human_feedback': human_feedback,
'timestamp': time.time()
}
self.iteration_history.append(feedback_record)
def analyze_feedback(self) -> Dict:
"""
分析反馈,提取改进建议
Returns:
改进建议
"""
if not self.iteration_history:
return {}
# 分析模式
suggestions = {}
# 1. 常见问题
problem_counts = {}
for record in self.iteration_history:
for problem in record['human_feedback'].get('problems', []):
problem_counts[problem] = problem_counts.get(problem, 0) + 1
if problem_counts:
common_problems = sorted(problem_counts.items(),
key=lambda x: x[1], reverse=True)
suggestions['common_problems'] = common_problems
# 2. 趋势分析
if len(self.iteration_history) > 1:
recent_quality = self.iteration_history[-1]['result']['quality']
previous_quality = self.iteration_history[-2]['result']['quality']
if recent_quality > previous_quality:
suggestions['trend'] = 'improving'
else:
suggestions['trend'] = 'stagnant_or_degrading'
# 3. 参数调整建议
suggestions['parameter_adjustments'] = self._suggest_adjustments()
return suggestions
def _suggest_adjustments(self) -> Dict:
"""建议参数调整"""
# 基于反馈历史,建议如何调整参数
# 这是一个简化示例
return {
'resistance_weights': 'consider adjusting urban weight',
'source_threshold': 'might be too high/low'
}
```
---
## 反思与延伸
### 思考问题
1. **延迟奖励**:生态工程的效果多年后才显现,如何设计奖励函数?
2. **稀疏奖励**:当大多数步骤没有明确反馈时,如何学习?
3. **多目标冲突**:生态目标和经济目标冲突时,奖励函数如何平衡?
4. **人类反馈**:如何整合人类专家的定性反馈?
### 实践练习
1. **奖励设计**:为一个你熟悉的任务设计奖励函数
2. **调试RL**:观察Q表的变化,理解学习过程
3. **探索策略**:比较不同ε衰减策略的效果
### 延伸阅读
- **"Reinforcement Learning: An Introduction"** (Sutton & Barto) - RL圣经
- **"Algorithms for Decision Making"** (Mykel Kochenderfer) - 决策与RL
- **"Reward Shaping"**论文 - 奖励塑形理论
---
## 关键要点
1. **反馈是学习的基础机制**,正反馈强化正确行为,负反馈纠正错误
2. **强化学习核心**:状态、动作、奖励、策略、价值函数
3. **探索vs利用**:经典困境,需要平衡策略
4. **奖励函数设计**是RL的关键,定义了"什么是好的行为"
5. **在空间分析中**:RL可用于优化布局、路径选择、参数调整