KindXiaoming / pykan

Kolmogorov Arnold Networks
MIT License
14.76k stars 1.35k forks source link

$$$ When we talk about KAN, what exactly are we talking about? 当我们谈论KAN时,我们到底在谈论什么? #86

Closed yuedajiong closed 2 months ago

yuedajiong commented 5 months ago

(on editing ...)

1.Since my native language is Chinese, I will first write quickly in Chinese to avoid language issues affecting the expression of technical content itself. Later, I will translate it into English. If non-Chinese friends see this post and interested, they can try using ChatGPT for translation. 因为我的母语是中文,我将先用中文快速的写,不至于英文语言问题影响我技术内容本身的表达,等最后我会翻译为英文。 如果非中文的朋友看到这个贴子且有兴趣,可以尝试用chatgpt翻译。

2.During the continuous thinking and writing process, the intermediate process may not be organized well here. Finally, I will organize it. 不断思考书写的过程,这中间过程,可能不是那么有条理的记录在这里,最后我会整理。

3.The author's level is very high, far above me. If there are some expressions that are not completely 'say-great' in later list, it is purely technical discussion, and it is very likely to be my misunderstanding. 作者水平很高,远在我之上,这中间如果出现一些非完全肯定的表述,是纯粹技术探讨,而且很大可能是我的理解错误。

1.关于“网络表示”和“符号提取”能力 我尝试整理了一下作者的代码,https://github.com/yuedajiong/minimum-kan 看从KA+Spline来做逼近的过程,特别在 https://github.com/yuedajiong/minimum-kan/blob/main/kan.py 我把最核心的逻辑,用了60多行整理出来,并用一行简写和论文公式做了对齐。 简明表示如下:
KAN_Y = sequential: sum { _mask [ $_Scale_base base_fun_silu(X) + $_Scale_spline $Coef spline(X, !grid, !k) ] } + $bias
prefix: $:Parameter:
:optional !:relative-fixed 这里,为了一眼看清,我对每项做了一个简单的处理约定:$大写表示待优化的参数;_表示这项是可选的;!表示一旦表示和学习完毕这里是相对固定的准常数看待;sequential是 pytorch层间顺序化调用复合,函数复合的依次逐层复合;对于非线性base激活单元作者用的silu我就固定跟在这里。 更简化一些看:
KA_Y = sequential: sum { _W1silu(X_i) + W2spline(X_i) + _Bias_j } 最简化的形式是:
KA_Y = sequential: sum { W2*spline(X_i) } 所以我们得到,最外层形式: KA_Y= f1(f2(fn(...))

思考一:网络表示&符号提取 sequential: 现代数学的数理逻辑基础中,关键的四论集合论,表示论,递归论,证明论。 递归论研究递归函数、可计算性和计算复杂性等问题。 或者更泛泛的数,现代数学学起来困难,纯个人的一个理解,一个是引入了无限这个东西,一个是抽象的思维。 言归正传,我这里想引入的第一个关键词是“递归”,“抽象”放到后面来说。(插播:我的一个进行中的研究工作之一,是Mathink(参见我主页),在我看来,真正的要实现mathinker,不是“类型类-to-Code"实现lean4做ATP自动定理证明就完事了的,从算法难度上,那是相对比较简单的一部分。一是要类似伽罗瓦这样/群/代数群,系统性的解决”抽象“这个问题,一个是要解决研究对象类似”无限‘的东西。当然退而求其次,类似拉马努金这样提出一大堆公式(很多是逼近相关的),也行啊。)假设我们要用KAN, KAN++或者将来的其他算法,来实现:e的提取,pi的提取,sin的提取(这是指无中生有的提取这种符号,不是KAN中设置这个符号)。 所以,我们知道,在实数空间,我们需要连分数这种递归着一层套一层的递归形式才能表示完实数,对于重复出现的有规律的形式我们甚至可以提取(发现/发明)出pi, e之外的一些有用的无理数,将带有递归嵌套的一些规律简化的表示出来(https://en.wikipedia.org/wiki/Approximations_of_%CF%80); 类似的,我们需要无穷级数的这种带有广义递归形式的来表示很多函数,比如简单且我们熟悉的的诸如sin,当然类似这样的可以无限写下去。SO:所以,直接嵌套+样条函数,如何在表示能力上,发现“无限递归”的这种“模式”并提取出来。 其实相当有难度。

思考二:网络表示 sum: 关于KA(https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Arnold_representation_theorem) ,为了方便交流,和快速思维,我们先用不严谨的表述基本形式: KA 就是:(单变量函数,二元加) 组合逼近 多变量函数。所以我们可以看到,在KAN的的第二层次中,KA的表示采用了sum。这里,我先插播一个例子,然后继续讨论。以前的工作中,比较深入的理解和处理过一类问题,时序预测和异常检测,并设计过一种网络TNN。一个实际的例子CPU使用率的关于时间的变化。 这个非常适合举例。 在深入分析后,其实可以表示为: Y = [Trend(t)] op(+x) Periods(t) op(+x) Noise。其中Trend部分可能是采样的时间窗口不够但本质上是更长周期的一部分(比如周期为年,但只观察到季度),也有可能是真实地一个趋势(比如一个新业务用户访问量是逐渐上升/下降。)这种尝试合适的滑动窗口做滑动平均可以处理。 而 Periods相对比较复杂,第一是具有不同地周期,比如年,月,周,5+2,天等,按照日历放假可以作为常数和项引入,周期的个数,频率,振幅,相位(cpu反应延后等)等。展开后可以表示为: Y = [Trend(t)] op(+x) Periods(t) {A(sin&cos(BX+C)+D} op(+x) Noise。 当在该"统一模式"下,处理不同的时序数据的时候,会有不少挑战: 二元操作类型,B的宽度,噪音的建模等等。 我仅仅列举与KAN这里的讨论相关的。 SO: a) 在不同的“部分”之间的op关系,可能是加性关系还是乘性的关系? 对应到KAN中,从外向内的第二层,受KA理论的约束被确定为sum,可能有很好的理论保证,但实际上在有限网络深度/宽度下,从本质上,限制了最终符号表示的空间/形式,或者需要更复杂的组合才能用加性完成乘性的性质。 或者更抽象的说,KAN的函数复合形式(不仅这里讨论的第二层),对整个最后的符号表示其实是一种比较强的限制(负面)。 要最终提取出上面TS的公式,其实很困难。 b)在符号提取的原子表示中,其实还有一类概率性质的函数,比如某类业务会概率性(有规律但不是确定性的)的影响cpu指标,比如此式所示例的:y = np.sin(3x) np.random.binomial(n=1, p=0.5, size=len(x));是否需要建模。 c)沿此思路下去,个人在AI4Science中,做过Bio/Drug, Phy/DFT/Density Functional Theory, 还有组合优化等问题,而数学家们眼里,对函数从不同角度去看有更广泛的类型,比如封闭曲线/多值函数,除了初等函数之外太多,等等等等,很多函数类型是很难用KAN/MLP/NN这种去表示后提取(无论整体,还是局部)。

思考三:网络表示 spline:选择了用spline作为基,局部上对不同函数的逼近能力/精度,逼近速度,和对应的spline的复杂度(我们可以假设k=3足够平滑后,grid的大小。 在issues中,我看到有人至少已经扩展到grid到几百了。这里我举例一个例子,来帮助说明我想表达的。 假设我们还没有sin函数,这里想提取出一个sin。而sin我们看当前的实现,基本都是基于泰勒展开,然后很多优化技巧来实现足够的精度。所以粗略,有一定道理但不一定严格正确的结论就是:sin的拟合用泰勒展开比用样条好一些? 以此类推。SO: 局部:局部逼近的不同方式的优劣。

思考四:符号提取 code: 我们在KAN的代码中,符号抽取部分,看到的是相对简单的逻辑:通过循环,“很局部的”在做suggest_symbolic,这是一种自底向上的策略。另外,我们看到有 prune等逻辑,但好像没有看到merge/equivalent等逻辑。意思是将一个相对紧密连接的“子网络”给合并抽象到一个更简洁的表示,或者将一个复杂的表示替换为等价的简洁的表示的化简过程,类似的可以展开思考;在提取代码中,我们看到,很多系数出现了1.000000000123, 3.1415...这种数值,是否可以有策略将其替换为1和pi等,然后将误差的“挤”到其他的系数/参数上,这要可能更能接近上帝公式。 SO:全局:更强大的符号提取的策略是什么?是否甚至需要更强大search的过程?(我不肯定其他的符号提取软件这些方向算法怎么做的。)

2.关于网络“局部”“激活函数”的选择 我们做一个小小的试验,然后再分析。 设置网络结构为[1,1],待拟合函数为:1torch.sin(33x+0)+0,这里尽力简化,只测试33所在的周期频率部分。再令数据集train_num和训练的steps足够大;所以余下主要的待调节参数为k和grid,k=3足够光滑,所以主要调节grid了。 通过试验,结论为: 当sin(Px)部分p很大的时候,通过grid的增加来拟合的足够小,其实grid的增长很费劲。 分析背后的原因,这个问题转换为: 在数值计算,类似sin这种周期函数,一般选择了泰勒展开的路线,而用样条来逼近,对于高频率的部分,还是很费劲。 我的大概理解是这样的,不一定对。 fit-sin-hifreq.py.txt

3.目前被各种爆改的KAN*,到底在改什么? https://github.com/Boris-73-TA/awesome-kan 看了awesome部分的各种实现,我主要关注了两类:一是原始KAN的工程优化,特别B-Spline部分; 二是算法层面的探索(不一定能优化),其实主要也集中在B-Spline部分的替换。 大概情况是: 工程优化: efficient-kan, deep-kan, large-kan ... 算法探索: ChebyKAN,fast-kan/RBF, RBF-KAN, FourierKAN, FusedFourierKAN 和 https://github.com/Boris-73-TA/OrthogPolyKANs 中若干

4.用什么理性明智的方式看待KAN 简单的挑战KAN,说本质上就是...,也不能如何如何,这个没有太多意义。 简单的夸大KAN,说就是MLP替代者,甚至AGI的希望之光就更过分,哪怕仅仅解决物理领域的问题都还超远,费曼数据集是相对比较简单的,很多PDE的问题要复杂很多,更别说更难的。 所以,我按照我的认知,尽力用大白话描述我的理解: $1. 有些工程问题,并且是可以优化,其实不是问题,谁需要的时候自己解决。不用来考察KAN。 $2. 有些工程问题,比如是否能够:a)很好的张量化/高维度化,b)对内存的使用量和分配方式,c)对数值精度敏感程度比如半精度或者bfloat之类是否难以处理;... 如果存在难以大规模化的,这个会限制KAN的发挥。 $3. 算法问题,从对普通NN的改变来说,KAN本身没有neural operator之类对建模影响大,甚至在某些问题上,直接对输入做一个变换到特定空间去处理比如FT,可能影响更大。 $4. 算法问题,其实我们从来没有真正的算过无理数特别超越数。在DL中,哪怕activation用个sin之类的本质最后都是泰勒展开,最后还是回到有限轮的加乘为主的算子上。 所以,假设一个很成功的网络,当我们在以加乘为主的算法粒度上去展开执行图的时候,其实核心还是这些基本算法的复合(这里算子的粒度不是pytroch中,特别是不包含sin/fft/ifft之类)。 所以,可以看到,KAN本质是整个大网络中,某些building block部分,采用的:“输入独立逼近后求和”。 这里有两个理解点:要求解的问题,在某层/那个表示空间,在输入到输出,这种“量/不仅物理量”,在局部使用加性,是否比乘性更合适于描述这一层的运动(加性更多的代表同类对象在数量上的累计,而乘性主要代表不同物理量之间的互作转化组合)? 如果在一个深层的网络中,如果不施加特殊的约束(包括网络/损失/训练),层可能更倾向于纯数值拟合,这是真正的黑盒,难以和人类理解的空间对齐。(如果对一个很抽象的空间,不在乎黑盒,很多很难以理解的变量,我个人更倾向于用MLP这种乘性building block去拟合(除非后来有人大量的分析和试验完全可以替代),反而是在浅层,或者偏输出的层,知道I/O之间的空间是有限次变换可以得到的,还想“逼”处和I相关的变化关系,那么可以用KAN;如果是于I直接关系不强,对MLP做各种正则化,更容易“发现”一些“组合/复合”的特征。) $5. 算法问题,我们是否需要在单层需要强/理论上无限精度的逼近保证? 个人认为者需要反思(当然个人的的答案是否定的)当我们在一个有相当深度(复合)的网络中,而所求问题是有限精度(现在one-bit量化其实是个例子),形如:https://github.com/yuedajiong/super-ai-universal-nonlinear AX/(abs(BX)+C)+D 这种挤压函数都足以解决很多问题到所需要的精度。 反而是类似费曼数据集这样的问题,最后的公式不长,需要的网络不深,需要在有限的网络中某个部分子网要附后提取对应到诸如exp/sin等本质上“需要逼近”的函数。 $6. 算法问题,对于高频/大数,KAN不擅长的,需要特定处理。比如对大数做对数化处理必要的时候在局部区间继续提升精度,对所求高频作为用周期的系数,其实对问题有一定背景,自己转化后,可以很完美解决,不用挑战原始KAN能不能。 $7. 算法问题,走向SuperAI的角度来看,真正深刻的见解在于:能否在广义函数拟合的,通过有限次的递归模式,发现诸如e, pi这种概念性的抽象,并表示为任意你喜欢的符号。这才是对这个离散的表象的世界简化而本质的理性认识。

5.各种变种维护在这里: https://github.com/KindXiaoming/pykan/issues/159

6.做过物理学,生化的问题,比如DFT密度泛函预测材料性质等。 但整体和KAN解决的各种问题差异很大。也就是说,我仅仅限于从各种初等函数和及其有限的复合,各种时序问题的拟合,等等比较直白的问题上,对KAN有了一些认识。 我目前得到的比较确认的收获: 1)其他我尝试不同的NN的Building Block。 2)KAN在关联输入x做解纠缠有用。 3)近似的精度下,可能参数会少,反过来可能影响很高精度的逼近。 4)在符号化等场景,甚至可以进一步尝试ChebyKAN等正交性质的。

这个帖子到此为止了。

ZiyaoLi commented 4 months ago

关于KAN的主要讨论可以分为以下几类:

  1. KAN可以拟合任意函数么?答案应该是正确的,且提出 KAN 的核心意义在于用 KAT bridging 一维和高维情况。而在1D情况下,无论你是用 Taylor、 fourier、 spline、还是 RBF 都没太大关系,怎么快、怎么准就怎么来。BTW, RBF最有意思的一点是它的基函数甚至和b-spline基本没差,所以实现上,特别是数值与优化上看,是最接近原版 KAN 的。你提出的所有工程化问题在RBF(fastkan)都基本不存在。
  2. KAN能抗过拟合么?这个问题是focus在机器学习的人最感兴趣的问题。当某个函数值的observation是含噪音的时候,KAN是否倾向于捕捉一个较为光滑的解来刻画其中单变量的变换?这个问题更empirical且很可能没有答案,因为泛化性这个问题本身就很难定义。我尝试过在信噪比较低的数据上用KAN,效果并不理想。
  3. 关于Grid的选取,看上去似乎和MLP的宽度非常一致。越高的num grid其实就是越高的单元素变换的dof,毕竟单层KAN的参数量为 d_in d_out (n_grid + order),越细的grid越能捕捉变换里面高频的部分,这在高非线性的函数拟合里可能很有用,但对于general 的 machine learning 任务则很可能带来过拟合。
  4. 关于深度和宽度的调整,这个会和MLP里的结论非常相似,不做展开。

关于“简单挑战KAN,说KAN本质上是xxx”,其实更多是在讨论KAN究竟有没有什么本质不同,以及要不要投入精力到后续的研究上。

yuedajiong commented 4 months ago

@ZiyaoLi 谢谢你的讨论。

第2, 4,还有最后一句4.5这句,我都没有什么特别的想法值得讨论的。

关于你的第1, 3句,我抛一个问题(我把关键点都双引号),你看是否不同的路线,差别如何: 假设我们拟合的就是简单的y=sin(999x),这里的核心是周期函数中有个“很大的系数”999需要拟合,当然也可以更大。 当直接使用sin作为周期函数的时候,无论是否是mlp或者自己定义的一个简单网络:Y=Asin(BX+C)+D,甚至对于超大的B还可以对数化处理。 当直接用sin作为算子,内部其实是泰勒级数展开来算,比如到20项,可能就很高精度了。 算子内部只有几个简单的记录周期偏移分段的固定的数值,可以认为参数为0. 也就是说频率B部分其实只有1个参数。 内部用有限的计算/时间来换了空间/参数/内存。 用样条的话会有不同。 (深度本质差不多,这里只讨论简化的单层。)

KindXiaoming commented 2 months ago

close for now, feel free to reopen if there's more update