最近,MIT博士Tom Silver发表了一篇博客,他认为有很多AI论文都缺少了「问题设定」(Problem Setting)部分,或者是字数不够导致定义不够清晰,让读者在阅读论文后很难用代码复现出具体方法。
博客中介绍了自己关于如何写好问题设定部分的心得,并给出了一些他认为写的比较好的论文样例以供参考学习。
Tom Silver是麻省理工学院计算机科学专业五年级博士生,本科毕业于哈佛大学计算机科学与数学专业,主要研究方向是智能机器人,如自动规划、程序合成等。
问题设定里应该有什么?
除纯理论研究、实验现象的实证、提出新基准数据等类型的研究外,大部分AI领域的论文中基本都包括三要素:提出了一种新的方法(new method),在某类问题(a certain class of problems)上性能表现良好(perform well);
也就是说,在设置论文问题时,应该能回答三个问题:
1. 这篇论文考虑的是哪一类问题?
这个问题对于潜在读者来说很重要,他们更想了解手里的问题是否与论文中的问题类别契合。
2. 方法的形式是什么?
这个问题对于寻求替代方法的潜在开发者来说很重要,他们需要知道应该做出怎样的设计选择。
3. 如何测试方法的性能?
这个问题不仅对审稿人来说有价值,对于想要采纳论文中研究方案的普通读者来说也有用。
需要注意的是,研究背景与问题设定不同,可以为其他领域的读者提供通用背景知识,但不一定能回答这三个问题。
问题设定应该写在方法章节前,并且应该给予读者足够的信息,在读完这部分后就可以自己思考如何设计方法来解决该问题。
把文字写成代码
通过一个简单的测试,就可以检查出自己论文中的问题设置部分是否清晰,且足够完整。
在读者阅读完问题设定部分后,你就需要问问自己,目标受众是否能够实现Problem抽象类、Method抽象类以及run函数(输入为Problem和Method,输出为性能指标)。
抽象 Problem 类表示论文中定义的问题类别,即使对于相对简单和熟悉的问题,如图像分类,也需要描述地非常精确。
图像是灰度、RGB、RGB-D还是任意N维矩阵?尺寸可以不同吗?可能的类别是否固定和已知?数据集中是否存在训练/验证/测试集分割?
如果在问题设定部分中已经明确回答了这些问题,读者应该能将文本转换成如下代码:
import abcimport timefrom dataclasses import dataclassfrom typing import List, Set, Tupleimport numpy as npfrom numpy.typing import NDArrayGrayImage = NDArray[np.uint8] # two-dimensionalLabel = str # e.g., "cat"class Problem(abc.ABC): """An image classification dataset.""" @abc.abstractmethod def get_training_data(self) -> List[Tuple[GrayImage, Label]]: """Labeled data for training.""" @abc.abstractmethod def get_evaluation_data(self) -> List[Tuple[GrayImage, Label]]: """Held-out labeled data for evaluation.""" @abc.abstractmethod def get_image_dims(self) -> Tuple[int, int]: """Images assumed the same size, e.g., (32, 32).""" @abc.abstractmethod def get_all_labels(self) -> Set[Label]: """Output classes assumed fixed, e.g., {"cat", "no-cat"}."""
Method 抽象类描述了论文中提出方法的基本形式。
Method类可从Problem中获得哪些信息?Method需要对这些信息做什么?
同样,即使对于熟悉的问题设定,也需要在写作时保持足够精确,以便在实现时不会有歧义:
class Method(abc.ABC): """A method for image classification.""" @abc.abstractmethod def init(self, image_dims: Tuple[int, int], labels: Set[Label]) -> None: """Initialize the method before training starts.""" @abc.abstractmethod def train(self, training_data: List[Tuple[GrayImage, Label]]) -> None: """Train the method given training data.""" @abc.abstractmethod def predict(self, image: GrayImage) -> Label: """Predict the class label for an image."""
run 函数描述了问题和方法之间的接口,并确定最终报告的性能指标。
对于图像分类任务来说,实现是直接的,但仍需要选择与问题相关的评估指标,选择的过程也需要在文中清晰地描述出来。
@dataclassclass Metrics: """Metrics of interest for image classification.""" training_time: float evaluation_accuracy: floatdef run(problem: Problem, method: Method) -> Metrics: """Train and evaluate a method on a problem.""" # Initialization. image_dims = problem.get_image_dims() labels = problem.get_all_labels() method.init(image_dims, labels) # Training. training_data = problem.get_training_data() start_time = time.perf_counter() method.train(training_data) training_time = time.perf_counter() - start_time # Evaluation. evaluation_data = problem.get_evaluation_data() num_correct = 0 num_total = 0 for img, ground_truth_label in evaluation_data: num_total += 1 predicted_label = method.predict(img) if ground_truth_label == predicted_label: num_correct += 1 accuracy = num_correct / num_total return Metrics(training_time, accuracy)
在实验中,文中需要考虑不同的子类 Method (新提出的方法、基线和消融实验)和不同的子类 Problem (具有训练/测试分割的不同数据集,不同的强化学习环境等)。
如果问题设定一致,应该可以直接运行,然后在Result章节中报告性能。
metrics = {}for problem in problems: for method in methods: metrics[(problem, method)] = run(problem, method)
这部分的重点并不是让读者实际实现任何可运行的代码,但如果读者能够实现这两个抽象类和run函数,并给出足够的motivation说明,那么问题设定部分就算写的比较成功了。
代码之外的语义
虽然上面提出的测试可以被视为问题设定部分的必要条件,但却不是充分条件,即并不是问题设定的所有特性都可以在代码中被捕获。
一些额外的语义信息应该表达出超出测试中检查的句法(syntactic)信息,包括:
1. 上面运行示例中的灰度图像可能并不是随机阵列,而是真实存在或生成的图像,以结构化或非结构化的方式存储;也可能是来自互联网的随机图像子集,或者是精选的卡通长颈鹿集合。
2. 分类标签可能有部分错误的情况:标签可以由人类(专家或非专家)进行标注,也可以是用脚本进行自动化标注。
3. 训练可能意味着在大型计算机集群上运行一次,持续很长一段时间,或者在嵌入式设备上运行数千次,每次持续很短的时间;预测也有类似的自由度。
语义信息在问题设定部分中很难检查,但它的重要性并不亚于问题本身,为了确保意图是清晰明确的,用一个或多个具体的例子来说明你的环境中的问题和方法是很有用的;将文中的问题设定与之前相关工作中的问题进行比较和对比也很有用。
优秀样例
有一些论文在问题设定部分写的非常好。
图片
论文链接:https://arxiv.org/pdf/2011.10024.pdf
这篇论文在阐述问题类别时写的特别好,将其基本设定描述为MDP的分布。
但作者并没有就此止步,还直观地、形式化地描述了文中提出方法可以运行的一个分布,还清晰地建立了问题设定和其他常见问题之间的关系。
图片
论文链接:https://openreview.net/pdf?id=bERaNdoegnO
这篇论文的问题设定部分对问题目标有一个出色的、简洁的描述,作者选择了一个相对狭窄的框架来解决问题。
图片
论文链接:https://arxiv.org/pdf/2301.06054.pdf
这篇论文中有一个非常简洁的问题定义,包含了所有的基本信息,对在线训练和评估期间发生的所有事情都进行了描述,方法的形式也是非常清晰的。
图片
论文链接:https://arxiv.org/pdf/2303.04912.pdf
这篇论文在描述非常复杂的问题设定方面做得非常好,使用了图表辅助。
图片
论文链接:https://arxiv.org/pdf/2306.06236.pdf
这篇文章的作者找到了一个明确的方法,从一个抽象描述开始,然后用符号让问题变得清晰;问题设定中有很多符号,但在这种情况下,符号是非常有必要的,对阅读来说也很有帮助。
参考资料: