1. 主动学习概述

1.1 定义:智能选择实验点

主动学习(Active Learning)是机器学习的一个分支,核心思想是让模型”主动”选择最有价值的样本进行标注,从而用最少的训练数据获得最好的模型性能。

在材料科学语境下:

  • 样本:候选材料配方、合成条件、处理工艺
  • 标注:实验测量或计算得到的材料性质
  • 选择策略:基于模型的不确定性或预期收益

1.2 核心思想:不确定性驱动

主动学习的核心假设是:模型对某些样本的不确定性高时,这些样本最有信息量

# 主动学习的基本思想
def active_learning_loop():
    # 初始化:少量随机数据
    X_pool = load_candidate_materials()
    X_train = X_pool.sample(n=10)
    y_train = measure_properties(X_train)
    X_pool = X_pool.drop(X_train.index)
    
    model = train_model(X_train, y_train)
    
    while budget_remaining:
        # 1. 预测所有候选材料
        predictions = model.predict(X_pool)
        
        # 2. 估计不确定性
        uncertainties = model.estimate_uncertainty(X_pool)
        
        # 3. 选择最有价值的样本
        selected_idx = select_best_candidates(uncertainties)
        
        # 4. 实验验证
        X_new = X_pool.iloc[selected_idx]
        y_new = measure_properties(X_new)
        
        # 5. 更新模型
        X_train = pd.concat([X_train, X_new])
        y_train = pd.concat([y_train, y_new])
        model = train_model(X_train, y_train)
        
        X_pool = X_pool.drop(X_new.index)

1.3 与传统方法的对比

方面传统高通量筛选主动学习
数据采集固定网格/随机自适应选择
样本效率低(均匀采样)高(选择性采样)
目标性质已知目标可逐步探索
计算成本高(需处理所有样本)中等(仅预测候选)
适用场景大规模粗筛精细优化

2. 主动学习循环

主动学习在材料科学中形成完整的闭环流程:

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   ┌─────────┐    ┌─────────┐    ┌─────────────┐    ┌─────────┐  │
│   │ 数据集 │───▶│ 模型训练│───▶│ 不确定性估计│───▶│ 实验选择│  │
│   └─────────┘    └─────────┘    └─────────────┘    └────┬────┘  │
│         ▲                                               │       │
│         │         ┌─────────────────────┐               │       │
│         └─────────│       新数据       │◀──────────────┘       │
│                   │ (实验/计算测量)     │                       │
│                   └─────────────────────┘                       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

2.1 各阶段详解

阶段1:数据集

初始数据集来源:

  • 已有文献数据
  • 历史实验记录
  • 计算模拟结果

阶段2:模型训练

常用模型:

  • 高斯过程回归(GPR):不确定性量化精确
  • 随机森林:鲁棒性好
  • 神经网络集成:可扩展性强

阶段3:不确定性估计

这是主动学习的关键环节,见下一节。

阶段4:实验选择

根据采集函数选择下一个实验点。


3. 关键组件

3.1 不确定性量化

不确定性量化(Uncertainty Quantification, UQ)是主动学习的核心。

贝叶斯方法

贝叶斯方法天然地通过后验分布量化不确定性:

# 贝叶斯线性回归
class BayesianLinearRegression:
    def __init__(self, alpha=1.0, beta=1.0):
        self.alpha = alpha  # 精度先验
        self.beta = beta    # 噪声精度
    
    def fit(self, X, y):
        # 共轭先验下的闭式解
        self.mean = inv(X.T @ X + self.alpha * I) @ X.T @ y
        self.cov = inv(X.T @ X + self.alpha * I) / self.beta
        return self
    
    def predict(self, X_new):
        # 预测均值
        mean_pred = X_new @ self.mean
        # 预测方差
        var_pred = np.diag(X_new @ self.cov @ X_new.T) + 1/self.beta
        return mean_pred, var_pred
    
    def get_uncertainty(self, X_new):
        _, var_pred = self.predict(X_new)
        return np.sqrt(var_pred)  # 标准差作为不确定性

深度集成

通过训练多个模型并集成,量化认知不确定性:

class DeepEnsemble:
    def __init__(self, n_models=5):
        self.models = [MLP() for _ in range(n_models)]
    
    def predict(self, X):
        predictions = [model(X) for model in self.models]
        # 均值作为预测
        mean = np.mean(predictions, axis=0)
        # 方差作为不确定性
        variance = np.var(predictions, axis=0)
        return mean, variance
    
    def train(self, X_train, y_train):
        for i, model in enumerate(self.models):
            # 添加不同的噪声增强
            model.fit(X_train + np.random.randn(*X_train.shape) * 0.1, y_train)

MC Dropout

Monte Carlo Dropout通过在推理时保持dropout开启,多次采样估计不确定性:

class MCDropoutModel(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim, dropout_rate=0.1):
        super().__init__()
        self.layers = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.Dropout(dropout_rate),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.Dropout(dropout_rate),
            nn.ReLU(),
            nn.Linear(hidden_dim, output_dim)
        )
    
    def forward(self, x):
        return self.layers(x)
    
    def predict_with_uncertainty(self, x, n_samples=50):
        """MC Dropout不确定性估计"""
        self.train()  # 保持dropout开启
        
        with torch.no_grad():
            predictions = [self(x).numpy() for _ in range(n_samples)]
        
        predictions = np.array(predictions)
        mean = np.mean(predictions, axis=0)
        variance = np.var(predictions, axis=0)
        
        return mean, variance

3.2 采集函数

采集函数(Acquisition Function)决定如何选择下一个实验点。

期望改进(Expected Improvement, EI)

EI是最经典的采集函数,选择能带来最大预期改进的点:

其中 是当前最佳观察值。

def expected_improvement(X_train, y_train, X_candidates, model, xi=0.01):
    """
    计算期望改进
    
    Args:
        X_train: 已训练数据
        y_train: 已观测值
        X_candidates: 候选点
        model: 训练好的模型
        xi: 探索参数(越大越探索)
    """
    # 预测
    mean, var = model.predict(X_candidates)
    std = np.sqrt(var) + 1e-8
    
    # 当前最佳
    f_best = np.max(y_train)
    
    # 标准化
    z = (mean - f_best - xi) / std
    
    # EI公式(假设正态分布)
    ei = (mean - f_best - xi) * norm.cdf(z) + std * norm.pdf(z)
    
    return ei

上置信界(Upper Confidence Bound, UCB)

UCB平衡探索与利用:

def upper_confidence_bound(mean, std, kappa=2.0):
    """UCB采集函数"""
    return mean + kappa * std

熵搜索选择能最大程度减少目标函数分布熵的点:

def entropy_search(model, X_candidates, X_train, n_samples=100):
    """
    熵搜索采集函数
    
    近似计算信息增益
    """
    information_gain = []
    
    for x in X_candidates:
        # 当前预测分布
        p_y_current = model.get_predictive_distribution(x)
        
        # 考虑新数据后的分布(需要积分)
        # 这里用简化的近似方法
        p_y_updated = approximate_posterior(model, x, X_train)
        
        # KL散度作为信息增益
        ig = kl_divergence(p_y_current, p_y_updated)
        information_gain.append(ig)
    
    return np.array(information_gain)

3.3 实验设计

高通量实验

主动学习与高通量实验平台结合:

平台领域通量
传热材料热电材料筛选100+样品/天
Robot Scientist化学合成50+反应/天
高通量XRD晶体结构1000+扫描/天

自动化实验平台

典型闭环系统:

┌──────────────┐      ┌──────────────┐      ┌──────────────┐
│  AI决策系统  │ ────▶│  机械臂/自动化│ ────▶│  测量仪器    │
│              │      │  实验平台     │      │              │
└──────┬───────┘      └──────────────┘      └──────┬───────┘
       │                                             │
       └───────────── 数据反馈 ◀────────────────────┘

4. 在材料科学中的应用

4.1 锂离子电池材料

挑战:寻找更高能量密度、更安全的电极材料

应用

  • 正极材料:Li-Ni-Mn-Co-Oxide体系
  • 固态电解质:硫化物、氧化物
  • 负极材料:硅基、锂金属
# 电池材料优化的典型参数空间
search_space = {
    "composition": "Li_x(Ni_yMn_zCo_w)O2",  # 成分比例
    "synthesis_temp": (600, 1000),          # 烧结温度 (°C)
    "heating_rate": (1, 10),                 # 升温速率 (°C/min)
    "holding_time": (1, 24),                 # 保温时间 (h)
}

4.2 钙钛矿太阳能电池

挑战:提高效率和稳定性

主动学习应用

  • 成分工程:A位、B位阳离子调控
  • 添加剂筛选
  • 退火工艺优化

4.3 热电材料

挑战:寻找高热电优值(ZT)的材料

热电优值定义:

其中 为Seebeck系数, 为电导率, 为热导率。

4.4 高温超导材料

挑战:在更高温度下实现超导

主动学习用于:

  • 铜氧化物超导体的成分优化
  • 铁基超导体的探索
  • 氢化物高压超导的预测

5. 代表性工作

5.1 Gated Active Learning

Gated Active Learning是一种整合专家知识的主动学习方法。

核心思想

┌─────────────────────────────────────────┐
│                                         │
│   专家知识 ──▶┌────────┐                │
│               │ Gate   │──▶ 修正采集函数│
│   模型预测 ──▶└────────┘                │
│                                         │
└─────────────────────────────────────────┘

动态门控机制

class GatedActiveLearning:
    def __init__(self, model, gate_model):
        self.model = model
        self.gate_model = gate_model  # 学习专家偏好的门控模型
    
    def select_next(self, X_candidates, expert_constraints):
        """
        结合专家约束的选择策略
        """
        # 基础采集函数值
        base_scores = self.model.acquisition(X_candidates)
        
        # 门控调整
        gate_factors = self.gate_model.predict(X_candidates)
        
        # 专家硬约束过滤
        valid_mask = apply_constraints(X_candidates, expert_constraints)
        
        # 综合得分
        adjusted_scores = base_scores * gate_factors
        adjusted_scores *= valid_mask  # 过滤无效点
        
        return np.argmax(adjusted_scores)

5.2 多目标贝叶斯优化

实际材料设计需要同时优化多个目标。

Pareto前沿优化

class MultiObjectiveBayesianOptimization:
    def __init__(self, objectives, weights=None):
        self.objectives = objectives  # 多个目标函数
        self.weights = weights or [1.0] * len(objectives)
    
    def expected_hypervolume_improvement(self, X_candidates):
        """
        超体积改进(EHVI)
        
        用于多目标优化的采集函数
        """
        # 预测所有目标的均值和方差
        predictions = [model.predict(X_candidates) for model in self.models]
        
        # 估计Pareto前沿
        pareto_front = self.get_current_pareto_front()
        
        # 计算EHVI
        ehvi = compute_ehvi(predictions, pareto_front, self.reference_point)
        
        return ehvi
    
    def get_current_pareto_front(self):
        """获取当前Pareto前沿"""
        y_combined = np.column_stack([model.y_train for model in self.models])
        return find_pareto_front(y_combined)

Pareto前沿可视化

    目标1: 导电性 (↑)
     │
     │    ● ●
     │   ●  ● ●
     │  ●     ● ● ●
     │●          ○ ← 新发现Pareto最优
     │ ●             (被主导)
     │  ● ● ●
     └─────────────────── 目标2: 热稳定性 (↑)

5.3 自动化实验闭环

Robot Scientist系统

Robot Scientist是自动化实验闭环的典型代表:

系统机构应用
AdamCardiff University酵母基因功能
EveU. of Manchester药物筛选
Berkeley自动驾驶实验室UC Berkeley钙钛矿合成

AlphaFold式闭环

借鉴AlphaFold在蛋白质结构预测中的成功,材料科学也在探索类似的闭环:

实验设计 ──▶ 材料合成 ──▶ 性质测量 ──▶ 数据分析
     ▲                                          │
     │                                          ▼
     └──────────── 模型更新 ◀──────────────────┘

6. 挑战与展望

6.1 高成本实验的限制

问题:每次实验成本高昂,不能无限循环

应对策略

  • 批量选择:每次选择多个候选点
  • 代价敏感学习:考虑不同实验的成本差异
  • 早停策略:设置合理的终止条件

6.2 不确定性估计的可靠性

问题:模型的不确定性估计可能不准确

常见问题

  • 过度自信:神经网络往往低估不确定性
  • 分布偏移:新数据与训练数据差异大时估计失准
  • 相关误差:同时犯错的样本可能被低估不确定性

改进方法

  • 校准(Calibration)技术
  • 不确定性传播
  • 集成多模型

6.3 多模态数据融合

材料科学中存在多种类型的数据:

数据类型示例特点
成分数据化学式离散、稀疏
结构数据晶体结构图结构
工艺数据合成条件连续、相关
图像数据SEM/TEM图像高维、视觉

挑战:如何有效融合这些异构数据


7. 工具与平台

7.1 BoTorch

BoTorch是基于PyTorch的贝叶斯优化库:

import botorch
from botorch.models import SingleTaskGP
from botorch.acquisition import ExpectedImprovement
from botorch.optim import optimize_acqf
 
# 定义模型
model = SingleTaskGP(train_X, train_Y)
 
# 定义采集函数
EI = ExpectedImprovement(model, best_f=train_Y.max())
 
# 优化采集函数
candidate, _ = optimize_acqf(
    acq_function=EI,
    bounds=bounds,
    q=1,  # 选择一个点
    num_restarts=10,
    raw_samples=512,
)
 
# 获取新观测值
new_y = evaluate(candidate)

7.2 SMAC

SMAC(Sequential Model-based Algorithm Configuration)是另一个常用的贝叶斯优化库:

from smac import HyperparameterOptimizationFacade, Scenario
 
# 定义参数空间
parameters = [
    {"name": "temperature", "type": "float", "range": [600, 1000]},
    {"name": "time", "type": "int", "range": [1, 24]},
]
 
# 定义目标函数
def target_function(config):
    material = synthesize(config)
    performance = measure(material)
    return performance  # 最大化
 
# 运行优化
scenario = Scenario(configspace=parameters, deterministic=True)
smbo = HyperparameterOptimizationFacade(scenario, target_function)
smbo.optimize()

7.3 RDKit + ML集成

将RDKit的分子操作与机器学习结合:

from rdkit import Chem
from rdkit.Chem import Descriptors
from rdkit.Chem import AllChem
import numpy as np
 
def extract_molecular_features(smiles):
    """从SMILES提取分子特征"""
    mol = Chem.MolFromSmiles(smiles)
    
    features = [
        Descriptors.MolWt(mol),          # 分子量
        Descriptors.MolLogP(mol),       # LogP
        Descriptors.TPSA(mol),          # 极性表面积
        Descriptors.NumHDonors(mol),   # 氢键供体数
        Descriptors.NumHAcceptors(mol),# 氢键受体数
        Descriptors.NumRotatableBonds(mol),  # 可旋转键数
    ]
    
    # Morgan指纹
    fp = AllChem.GetMorganFingerprintAsBitVect(mol, 2, nBits=1024)
    fp_array = np.array(fp)
    
    return np.concatenate([features, fp_array])
 
# 在主动学习循环中使用
class MolecularActiveLearning:
    def __init__(self):
        self.model = ...
        self.train_features = []
        self.train_targets = []
    
    def add_data(self, smiles, target_property):
        features = extract_molecular_features(smiles)
        self.train_features.append(features)
        self.train_targets.append(target_property)
        self.model.fit(self.train_features, self.train_targets)
    
    def select_next(self, candidate_smiles):
        candidates = [extract_molecular_features(s) for s in candidate_smiles]
        uncertainties = self.model.predict_uncertainty(candidates)
        return candidate_smiles[np.argmax(uncertainties)]

8. 总结

主动学习为材料科学提供了一个强大的工具,能够:

  1. 提高实验效率:用更少的实验获得更好的材料
  2. 发现新材料:探索未被充分研究的成分空间
  3. 优化工艺:精细调控合成和加工条件
  4. 闭环自动化:实现材料发现的自动化

随着实验自动化程度的提高和机器学习模型的发展,主动学习将在材料发现中发挥越来越重要的作用。


参考资料