From 2a589fc03928ee803cef58d7bfc8efbd30c13437 Mon Sep 17 00:00:00 2001 From: mehizelali Date: Sun, 28 Jun 2026 08:26:18 +0100 Subject: [PATCH] Add refined MatrixKAN with mean-based spline path and MNIST benchmark MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce refinedMatrixKAN.py: mean over (num+k) basis/coef axes, nn.Linear spline projection, and faster forward pass. Add MNIST compare experiment; refined matches original test accuracy (92.6% vs 92.1%) at ~1.5× speed. --- .gitignore | 38 +- .../mnist_compare/plots/mnist_comparison.png | Bin 0 -> 150210 bytes .../mnist_compare/plots/mnist_final_bar.png | Bin 0 -> 23721 bytes experiments/mnist_compare/results.json | 42 ++ experiments/mnist_compare/results.md | 170 +++++++ experiments/mnist_compare/run_experiment.py | 441 ++++++++++++++++++ refinedMatrixKAN.py | 331 +++++++++++++ 7 files changed, 1021 insertions(+), 1 deletion(-) create mode 100644 experiments/mnist_compare/plots/mnist_comparison.png create mode 100644 experiments/mnist_compare/plots/mnist_final_bar.png create mode 100644 experiments/mnist_compare/results.json create mode 100644 experiments/mnist_compare/results.md create mode 100644 experiments/mnist_compare/run_experiment.py create mode 100644 refinedMatrixKAN.py diff --git a/.gitignore b/.gitignore index d69ee67..0843e19 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,41 @@ +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +*.egg-info/ +.eggs/ +dist/ +build/ + + venv/ +.venv/ +env/ + + .idea/ +.vscode/ +*.swp +*.swo + + model/ figures/ -__pycache__/ \ No newline at end of file +*.pt +*.pth +*.ckpt + + +experiments/**/data/ + +experiments/**/*.log + + + +.DS_Store +Thumbs.db + + +*.prof +/tmp/ diff --git a/experiments/mnist_compare/plots/mnist_comparison.png b/experiments/mnist_compare/plots/mnist_comparison.png new file mode 100644 index 0000000000000000000000000000000000000000..0a54bdee23c77da4bb547ff77d88952e89e4e4bf GIT binary patch literal 150210 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 b?-!X8X$qOTpYTPJ#gI93@pRHj-Mjw>#94sD literal 0 HcmV?d00001 diff --git a/experiments/mnist_compare/plots/mnist_final_bar.png b/experiments/mnist_compare/plots/mnist_final_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..bf1da8af38b614e1c33650b052b640d5c4b91f2f GIT binary patch literal 23721 zcmeIaXH-?$)-AftWiCr8MFmj-MHD1wFru3vN)X8?NphAfm`g>$t>mPVvx4NPmLQTO zOIFEQvgFq%)H$c#yQh8a`*B~p-)-&CTD4Mywbz+Kp-?tb z&z_Q}P*!SFD9exjvKrqhI?tes{|VcizGS0du5V*^*-DQhd)daq#N5Wj@Cws4Ju7QN zb2A`~=4HPbU43z2?6KR}i~YIs;V&0f zCSG~VzD_w)e$_KpsiA#4gpWIJ{FP~oeEHDk;O0GjW=!{msGgI34kJy)emn-bJXzA7<)$1PAOZhS358jF9T`+pzRay_H9ozURFqf9VgGBq=Kv|D;X-KlF#b zrdB>bek));d*l;4EiBh%Cg%99)v9^dT{bBPWf>J68O-Qn6 ze7)8gP_>Fe@eE2eYj&&>SBg=5!aUHDqo$T-R`cQEc2gf)g^XzLrtfL3*A;AR-hBW5 z-70fi*w!H(O8$U5Wi`b@ZMr+uqdJVb)uVXbc8VfaxzfX=n^mXXbLIj19#z9sw(eZG|Zs?kxTfb>jZC8kE zf@}bPkB7wk`BSHEPfrdd7ChS3Y7rnYH}+J&EHK(-W`a#fNTuVGmqMCZv&~S>?;q5*+IbN7~ z{>2IMDEwwkQL)O2F;ZTK9DAc96_fR4sg)hYKI1jYT0Mn(T&pvzyA*Ss9X9SbdJH$7 z_buJeVI$8dW6t$}(+{>)++Mr&&Gk9Q4}bpIJzTh_F4RNZztdHL_U3BEzS1BOH5P%;vU^4!!K`Y|*>>{MKrV&-C*c1i4I)akV;+K2k|B^70e5jWKM= z&Um7G;>3xP;kLr6ro4TpANXz-|Ct}Bl3Y*{BGGzEQc~FC+xHI-n^T2!KmOXaeSF!9 z)xIp!-o7EO^Yz(dmC~%{E!mQ^o~DfCM#qJza@WANRK%@}ANPkijjY;|Ad$N4`RTq0 z=cy6>`XoJ-3E`%*`bI_l*R}FChfDkL?{S@dJ=GH#Qc@kQAnSEV$(>mNaib7>@yOQQ zyGtq(C0YMbeYQigkmdK= zTm_>u_MIhulC+|y2R!J-ozti0XNIt+j7v)VcuN1+vR|gBGQ706CYFR%htq0`+ZdDE zGD_3M-CCmT$_XaDb%{e0RjH%KL-a^x#cC8v)7^=o)=GM= zkv8P4v$5yZX>YC#G}zR6dOM7EVu_`(T7H?feVwn%t;@v@P*sz3?-zD#mY97NqntQc z+1b$%p4Q?ht*NQmkZBvcX^(h+QfYg;t`~=fYPsmBd!xNZ)-|PK?;|W!awLY~ z;o(CnNntH6lNuf=_D)XhOicN0NhR5v42xv24~P21CY!9+tzBzr$gY)}9dj}M5Vf}| z(u3^7B+-KhKMI+t&iGc;ouBR-s)!7BltKWWvz`i}JACOp?HP^s-7>?&!vnjlYu4`K z?x8s6a#R#enRn|c=|{rHcl082ggLptVcl=*JmvoI;b{8o*SEL)#a%K{bYhYX%6k!1 z+y#O@A>uBo(b3T(6J@ilRDRP2W@D|8s4#(@>64!<*;_+t|LpcKz4$0x`HX$~!Wibm3XGZrhJ9gFof{{r!7W`=82* zS9tC{8Tjqqfr1?x8CItep?(Pi{q@PTFdl=lZfq}s{uxAqy$Pp6gp7aR?K^jRu&sq% z=d+Us-rZSWre|pBTwyon6=vO4MwR!M%gpfm+sg~Lt+}tW$1GJe-le45_~6|5i&a>@McatN#4rW4P z&(*awSWJyG`^U}S4_{(pv)co_YId7yzl`#c^>N-O<=Bg*Z6lm{v)sk0HR00RsdcQ< z8pyv91v^mX3meaiFU(rAFf$)SY189)gjhaHtBq3$J))MH9&guKLN6O6Toazi+_ilW zXvGLw)-Q%H7HFYl(C*sDZe!n|p^AXDn>Jlsn4e?GxO*gH%6R6`-5CGrX+LYd0 zy&yLG<2^@83!;J+HrSkHTox$AVQmp8=5#Ss@=+z0f>spzatRv;>a+E<}E^t>DqqcHvfOGw~K=%3so$mQg%q8J&L|&zb5B5JnN&$!`*sq*wf@ zwN(o@u4rYIBy8Io1|VusKfx;NAGV1>_$pFc=ED38-HshmNIC3#_a4X2ukvD7W~Q2F z58o{uZ%j3fHLQv-#2u30C<~ED+reJs!ksNK;KSi$_k4KI6f-4zJ|WC0|@Q6uF05 zsTIsCl*6rBtW|H`NS=ApNip+UO2y054++p@6BN9JQd?OQt8Dx8$7PlS2iWC;MIEO) ze1hhzM~7EazDlMqM;$ehf2DnVZmdeqsN&@v=AIwl-Z!L~hpgLn@HqggX6yACQ*Sd) zX692sjkp0jhshP>4Iz0I{M#hBgn)b&xi~evc9M^K4vwgIaPYM-A zSyA!Xxj@0acr>w*kNc;A8tH!h^=s<6@!pyg%Qi{;Pa2{B09YCCltm+pK^L(IKpooX z_~8Lv)%1AZ`0QwT?4{RN9z1$f^O!-zrnj1nj#E>8VSX}?XV$*0@{>tGrq*-d{I&(;(krcf-_TQ*(X!pL~N zD(~@7eexMgOG`7C(3dZ5#(R~N;#F(fbnJDmT(Rl?yqE5f;#vInLvW%#*?^>Cx`XGB zUA}yIWO&#zI#Dynkwfl)RIInVpmnGFxe)Pqq%9z$Pg7xG60ryb+(-)0GoM-0CA?!{ zn{LkpWD2W}PizMd9@J>evg&w%Y8vi@6q7%gr z>h{JOWoSxH%;?X&a$UGi{uQ?bcz>tKdykOSDTA`W3xM7lj5UFDiI*i?Lj@YQ_jC@m zJ>1UOivogMy#P2TcGua}+pAE7y@iKD3A+QfL`nZS>SNdBXulCD#wC5#+C{FJ&rLWI z`6?#JmV6!7*@SO>-6!@mdY@ez-%1M8cd za(eCBwTN0JY}nbkIqOWs8hOZ5l(x6z^3R@yEd_{_xVX5G#&1?HQ1y_ryT^K}G7$?` zu3S+>{s`n)PkzsHy=D3BHMk<})X$r{MkXdM<~mO)X4)81L2T7GDX%0y^f8{?kgTki zkI(jR>nlIh)hPp}aTm1Pu#tauQ-AQkzKwso9JMY;5+r$nF#3k-G_7k~y#B1%RHx0d zw3k2Txr8)M_)o|lq*bw`XIOl@iP*LUOWn=TcJT`<`K+%)_t~|zHBdiN5T<-a)d$ZM zlJ8TPA}v;Jhy(k*XklUT*kkd%9y_p2&ZhR9HMXtY9Pruti}iGG!w(J~R$ z46AT=E+g7&`S#WtcA(PlTcBJ}n5Y$7wg_n~PojRvak9?5 zt&ZJfRu&`@2_|6-9>FmHEK&34{jDiRHHW-7wOZ;Kw{8vX?!GD;D0pEgZz0#6YY~Q> z9TD~Ugt(}ImcbzI{G~qCw2_|xjTn{W2$I8qbJaTyHxyorlnY6KV9{9b+Eo^$`ufTp z4vow(NG(D$1ZxwHQY=n16!wd8pWhf(y}A5;^{UmY^{3Mp*V^;< zh=guaR&)IJ+i$!e$t3SeEX*cLc^_t@#wf*lH=yJi)x;R0W(b2Q5d|X246!i|h8khK z3q(X7`SZ<{59_*2CGjHU0brC!2Fi67YUYy|E#Yy*N(U_@sHG(kjRfTMIBv^g@O{o? zODyDx-iMsIpCMJmfGU#R&Bv!ynbP=lF`{4Hh-7;E0k1NFNGnRQ7t6lB+k5ordAnAZ zG-kuP1P!ykiSCO18jXVBdw7Cs!cl*IKcA#a^68FRJRvCu!qboRCaw$dp{?U5PM)kvdDPzCzRPTX z{KT7W2hZonmlhVDp#>_Z?a&!(vMw*e-vE`88r~R&0wf#)9LU7(9ZYZA)YZhdcxhce z#K%E}2zMwDBy?C8^Wh?Q>`YQ6v+RaydCEmYCFXygq}lXTvJhDcD5&&-hGk;}C;)J67Uj|2o>*LM_`0GSpLO^ib1+k=4fmN@9=Q zSWXx!1QilrNLOcR?R^2Z+pmImMByWat=j(p9gV{tK(#&#oVFl+`8V=`l%C_16#^S~ z@_q)3tVz<7rdE>dPNTg9`?-oz3|v2|)gp-)Bs!T=wESsO{jo@glw!glQ?R+t&!TY1 z&(BURj9g2Y#O?HfnRtTI0y@0_92g&J)p~kBuB>uk@dJMtXm;}ZJ5&$b1daFAwZ3W% z7IR{zLOOk|sbIE!&z?kI-yNu;_JREuGx_sA-C4hV+wZ@3@*B9@3{X#zG^P~ujF9Ej zSuj6Z*p&|tdO-4GF1>yUO8F8}M6-qaF4IZLVj7KRGd*SqolfTZ_3PXP2Ze=Ij~_qI zv2|^0++ZIOyeL2W-pv%Y+pPV#S|ZNOzlwz^K(Q%HAX56{voZZO^dFeB(_f&-A^o(x zlKb}V4&KH$UY|8<*02i-eu;PK{`|u6`~3q1P*N*joV>?t@%0!11-OTto*e=WgO9vB zik_YU-M=>9SX?X(G$m!%ytoLu+m>yxD)~9w#;0Ghg9rf-`M{n6!;F>RZP+6&dM|cS zEobUGx&}W7rI2pRmKRWQA$VDTg205IjRWr^`Cdqaaq*HWciFW)br@Y|EybW#{i6hf zdUQYvjVxY-8cfAo@|g;un9AvWdRElKz4(i-?*6xM&%dp-ix>DCIQrWU9Zwa!KAWz2 zeM)bxZO_7a)RGh=u+wMG#3JAN^P8%k^Ep7xbR3U?s*}K_^Uo@uM-LeD_2M>$El;Xg z!lJ*o16*o)GH)Rs)Iy0i_UBeP`|O;q+?m0uTbsqZXD12YL`3%ymE`8C z^}Me0&LAj+knTLH?KaX?KEyBS*qhNpa`f7*tR#-X>FVBZmWabpY=a=jenke(-J7%NcMJ0OTb7cs>CE$fi> zK0KVBBT>FAS^MqsnrMYHauRcIpy_v+gmCHHWt9t#+qjGWpjNJP*~D0F+bffLZri?E zS>*(E%T$+m&2WSJqrws%Noj6o0%9; z0N1oF7n_Va`(z(UQS&pc3%#xjGa(3%m_kM;nVJ}-Dn$GuRzhdM|LEnLXp{8smcSCA z;E$&dXkDK=jjL2a>x+cycZii$Qm61Sp<1LMiw*y|mG-eh$_K-&Ao8$#3$CXVJV67=u9a4PeElu^%E_g`mDE4B! z)#{_I2(iq*Ct+Y=?6_Sq$Fa}Qz164jhR#FYc97h(WpM?2PEc;~lD%wZ3g!Q)%>aKm z;`q~!{Zy!Zt`I%PebN{h83%vMJu8o>Ztv=fM11OJ2AejfQfWxv?Wv`Z8~*~$+N+jr zs3e)R_8LkNwGzs7oLLqY-pmvro8%OEd3kP)awy|_sfSeGL^X2DnJ(Uk?ke&or|%mx zECLqC4liXzv~&77iex4G*r3fa8{%CO98;Wx@G@|@vG{9eN6LDZTNw9X7lawh@y2N7 zI+&3fjPe@`=rRqUhm^3f*`X_lVCH@M_JP?v z`{yN_ZrhgPDv@8a`ygms5Umna> z@%5F{9$V|h$Ey{3E5jc){+WqFP>HZcPXAUZu2Zl91>kdAszHhGi?3h5<|)eImk5m* zXwB0iO(`^D6caVY!XqM#2AeWCJU%V%cP4gw`a)|b^A+gzJz?%r+H8n`@?efebF9|* zUF!;>sk`NIWV_0o^Kmoz@xC{L!2F_k$Kex>$+z6E5FSjv{zZ-d4Ws;D`Sag?s9=S; zxjDVgGw8Hc;a`8(c7MVpiC98+lw6m|XP?_}J~$lhnWv}cd#|q-f8Dc(lL~RD{F@Z{ z0ZInlGWRt=Ha^URFd>Btsc*Dm*KtRil;|W>`5VhuS*0(g;A3VT0UEo6ul4(08)}J% z8i3}g6$!c7+1bkeJxKA`)rUAZ&VBp#Ee74!YhEz`1*CI{*CRyNP z<4Dpmx<#~9X>YLVckkY91070F7xdw5aJz-?fGR7YysTQYrnoU+{ins}3|85!?Kn9Y zkNm9(Bm$)GweI)BQP`$E&<=YmLhtdLe0h!yD>zdgD5OBz5J0chFHf((bN6m9RG(U8 zHXHB|W8nV!k<)e1_mD`Fav2sc|6|gCuZV~?xeN17t5&V*LEpB9#v(liI&^iYC5I3~ z>}_6$5nUf!P3Pg$)JnqVketxgQ$YSwf@qau+jr4rW+07UdNH^tAFVE~@Wnby(FnSR zkTkv^&^r)+hSA|vWlDzTZqU03ELseTR9OdY+wR?Q0xk9@X}rd@hXYuaI{msrvCCwz zJ?Vb??PYV89Xkg{nO;4%EHf2s!8&zrq?nUNB+2wgHMuTM4o*%YGmFndX*v{FwyX{5 zjI2IdhoBRW#(uot9IO5IW_4<5)v%;U~jA|4dKr$?UtSiO36FR6Zc3v=cMPCgtOytciHt5&WQY=l_L zQWQSm2$)D9F74^lj=lg>xz9^$@>4o4atD!X(aqboZCe;Wxwm=01b9q8(unkj#zT+`b2Jp+LziAX_dcxh z5-6o6d;v-+Gxf=nCll+I9{yE+?~${1&9*+^9QftKprKOu=T9LLc@zEhq130WRN5f= z-3G2uOE=PUpF$5o5tSKPPmT?8CR&Dd2uei&Qo#Ol{i3CJtx{%0Q9yzu$_QcI7ZcQ@ zA<1SQHm?l3FX_QJP)VAdrmeXe04X)-zzmvfUc0se-5;{e{uOF{a>pIVD$dlr);U9< z9f|4_CvJlJMgS7V0xOJ6T+3Pi3F(Mbb##_foTscleE7g7DyqI&Y|In=FtaT6#d~r) zY#`?LBn+)Y;~!t&(yK;d$)W5&4S%q7%Sj$Jq?19uj{U>b@_)7Sg*=Jd|BaTN|J*oP zf&UHfP9=5KQKyOi3evm;+>b>wptmtC5e??v*F#9D9Xlu`WeWOTkAI6AkWLdtyL=7sH$}x9u6GIG0Up@S4XTC|p8!8Q*=>zD+D|(2I`~e&r zjh4G%`^P7Q*!JYv4QWydmTxLpw|TQNd=trw+7l%|{vEO}@Fb0ykatuxc^MgZ>w3t! zd?@SauU!P;q=msWbe7gw!?}sroxZ)lr|15}$4A+}(G znCNCH^GXCn2`wAR(azE;@TM_>aDY*SA@|+g#L(Lx;_vSmf6yEn+RvXKceM4dSzKKU z_E(OpWKf@2s6?wmwp0o`y9J%x8q=oq*Jubv;oD^8TUuJyty@Q9Mz5!$&3-$lrsA<< zZqClmX6el+1WqP$eV_h9q5*N5%SbJt)&<+Q|Dv@UI$b>EHFk0F7NPAjK-er)1gYh& zK4kv~_wQRyEG=!i(xr{sFv>BZ@Gzi<1bvF57(%7Z>`%+7>1pA_XO`+OMqqQv7!Tnw zcr3kVDLT~d)KDT&a7jD=T(D>~ab^&@oX{*)4FUN>K|u`ULPCrn%H%hJQ3yN#e1*n; z9CT7C8mX(Wv7DvN!+q3n7+@P;OvMiLI_{+#cMIE`1yfeUOG3F+0^=bF7dHmI^D~$i z_>+dg0(6;JC}>0jS-xV061tc{f|e&}W1mlMHiQQ3m+--ITt?OUPjcmtLf__e%v#o_ zW$(EtP}=jGr|c2~(R~o#pWjP&l%|-VE)=hlED4{6BBV{yw$yP~O*M%I5zV^INvnQ! z`6S?m4Axv3rXHfrEnl_nD(p4W*xaT*i)|W;XGfg)s-nI7_MHIsyNI77tpLzmp%D9a zVu*R8SNuCxh9GSO+{k#TxBOpQLp?QOC!87UHf)fwTlo4_8wj|O{TFiU6sBF5^8V_` zeZ6+(A0_jDst=Uh@qen}f0p3iM?q&m^Da?1i!R1p+DnD_5RRJB`??j76+Ix%pIlA^NK`|gYlBTaugiV3u15of648Q)0kUW-5e_=9%_&Pc7fnaMho043-Fwu4P7tJeQsjnrF{<77v#ll1xu30}hb z8<+c{c3%COe}foSka4{A^H2|@Y2s7uThZ-MdieX1O3-2=E2Ef^f?Th(BnKb!{+LSX zOsUgUfaSQro&KqQ2yzN(RT8I1u>JS722PO2#vyh}(Q>CcclD(#)f3%t6TjP&#ET5q zD6eS)FI4=ndUKR?S{Uj|=8-;tXb{^#m&LoJn9 z85y&}R0Z{q*wjEInrs4~atwcA1ftl#xtj^^BqDl}&(EP-%p)pkt9@SS3kXzE~L+ z>H)c6n_cXvedu*wMBl*Fdx`TQyRJS;yy3tcw!k0`>f%=IXQ_1wmkd!ei9c~RE%G%= z*T0qsBoQgN53LTf0rHz@GZ0~b?ucr&gOW7#06Gv+((i*wOCHcBurC`u;xewK;4@>v z?}HCk>o}p6J>KD?)k|J1bjZK~QneN2#KOU@qtU2yL{D|w&Ydy%HnIM|&R7At(#W#$Wereu+_gd}Mn|4RtSg|G|qY1qd2(*fTjmfVM zExiDdZ0pRWKe^?J{FkcK5?%fGJ&C1Hdqu4G>r3iu)+gmvg7S{s- zsTviD%v@w1&O(!1_0826AOHr9(AatPK5Ziw8B!ZcX-k_TDX>P(lb99J*Wbt>tcZqN z9b`vdrwJ4EFw|k)Avz+YS@l}tZh!gmB~&ZhQa_$ENbpr~RKPe1>%$AQLF)gBhE;Nw zN8qUlaL&%runvaRBMN?C&=w!!Q-FvlMdQ%QjZ4g%S6#Mj8ObY)Jq9E272L~W-{;-! zwZwl>`VS8F3><9v^5sqMwo}p1tAa<8jY=$Rsfns7Qs}}F6K4=87<|KQJq@O^OIah0 zw%cKyJb-a+qE;el&>K~Mtj{$lXQax{O^-L%Mysa8;Hv*hytN@W+l$o9bHal}?1+8h zJPb>L1KT;&J((g>XH*UP%AjBd2P85`KS{Md> zGLMJ=xReEp_4O|av=*_i81uu>RX~Tuu`fPt3@F7hd*s6lv+_noi28{C zwT9~;=*r8}h`WgBb?@(PtU@=`;{7}t8uIuX`Z)1e5|OUk^>8l2%ea@?+nkm5w-BRr zLc*(cr{`&hlL3wKm~%nGW)hJ0Y*o6@3_Tw#>cC4n;;=|=*|LQQ{P=-zIB=Cs8{WKD z`3FKt7G7(P8)0UHO|3D_eDX^d+9@0hX7H6`_#liZrx3o00~{UUSj=+uqA`@F!m;=q zZgeP$P&k@x%Di8_I+~U`G09zdGmaK~ z5P0L_SG&83(}pG2N&dip*P6EYoBydh|3BBA(b68gy^rz#aCgkGZY%16-zDGFja_@` z?fsV?&%fCi{UCRh??V@n ztRU0+j)p}$9K=4t6u@AVz*GV`)-J9ulY&*pk+W!JT)6)mOLe-X4(YnXYz!B904(Jp zRpCnut9vOSYq>s9^K_TQ0-KIIwtU3r&*z~bT>wB18qAs0oP&j0NMoP2hRvx{q?LKz za;OD2gO54JUu3JC55J6h!H!4tJdz@IgVkgr0wgIGz98bAgv%l;kYlN#&UDgBiLw2&jOI9(Wi?{D4Q>3)41f6_lD(QJNCIN&OK}eYu!=#Z&oJg1u5MYReQp(tvW>Wt$+hH^!Lo`ifXHXz97mZ~*k4_4i zxj2|tSXT_(9vvLGVLdo-Yt(G8&|z{SAOBg#2HU~B4VvNE(bgG5VHFqGq@mZ;Zs`E2 z%@%eh*x-xn1lq!9rl(bf{-_T>_d$K!>MaeWo#Ds05|lwqn0`&g^@cpGIXts0TIOcj zvLC7)hv)`-Sdw#-y6xR!h+520ql(%_!orx*d28ieG$ec1t=8RMNT-_Zu`FM_EQ8{i zBRKT^nl~PmO+M@o<{r3d%!=K)(1m|S(qXgS(mR}G$vET|eKFpj*%0;0teEr$Z{J=? zIBM3C?}+kK8cRbSbKPr-b1;7uH zBzs@nW2}UDN@OxP$|NF-mulumPj$YviOe~e_9K2*LdRfqY^V?B)Dp*-h}U1H>ii>x z#XEGYGXIc}rcx`=>it{)2W`eE2$sHoi^&bzi(x>SKWA05`>$DM*E9dkspfpGU(pms z{p`h{R&A;!{1!*l)6b(Pm6G}>ZUQ4kS7A1$*BpYQk9bEw_zo+sVhZI@Pk#=1&X}wZ zI-=)%o`%Bxv6=iX*xjekj(H37S){(fR447#+yosU#p2tEAYt1>g+>&&K%4$AT;zu# zG}szSAUF}f*WQrU}v`-Xi$Q8Z(h3bBL~KVlz{cdN6RG)>@|Q~AbCsgaT&W%yL~m&$pVi( z#A4f1CNiXmmg*R$o7!!tLcM4;6C)I{_Cz=_=(vOBhhvXkf@}Qu*sRyE*KNf9Me9%Z zaSesZnlvDhD&_~$3>)`*h`uDVdZ47XsbnMrkbnRwCCvSjkvqmZm*EfF`Rspa!-v~y zs?w6}KvW6R+kJgeWM13Gr^&@ z7z*t3Qr4`%nCu$}`n%&-9V=*ZU6?amy}~sTL5#N)f9dtR4)tu~I*vy>xK6;f6izIo zLe`yE`@g(a#awK0Cb=Fl>5}CE8fGlSL_`>brWXh$)#lB!V!!57GSs1ilea!T*ent$ zoe@pETL72@XJO>UGnxxNf-s1;y?9OK-+L)xb8s?>JW)zKr$AFA85z{kfrOhwNK~@0wASN<6u`nky zb~j~VqR||-5@lk78X9t~ntSy4@iooP4D(iTpD|HxZh0S0ty&ZoMLf#sQ>U6N7EYcx z(KIjR@-=@M1C)A{CA3@eE+6R;nh@ZIrI0xq|i`T&m@8ab! z>P`l&ICFoVAQNucIYswx^p62x8pFR$n|BRnUlaz5JL*81h{FioB&C<9))Ffbx>ROu zrY+ejL>bc64I?gPgam0@fRPZ*gtV97?aEO9Jr`O#_O=wB-AV}4dNyZq^nekBA~HIe z6oiJlF)>#^e3tp?u17_c)&k3^e+$!e&Bwo@Z|@ce6{4`M4~hiUQNJqthY ziO-EGkPa5Hkp2)~_E8+$y%NidchaA&)cozS$RM#S1umQ$n)<>uNK{6&*)W$D1Ljhu z#>|sc`erwNAKgGQnF8~^W0fuXhGdMCSb1So4m_k7^>sK|%W-C|9+fvmzjS9B`5@@at*SjnTr9p94$|Kk24cSf-W(S_O3g1Wl8`aD>B$iTQ++fY+R6|c#c&w3`v zbfaig`l9WVIWB><>Vb+oJTY-iB@%R?6DD3W+w8fC#)8(?)_P7}-s(8jl-`J$Ib_0g zch@;N5EV>A1U%6NA^K*ypalnx&m6Hg2w_(Ufumqr^=Yv^7#crno@>vS*0U(1vScQz z!DEkv8F)!I|8+3@QtafW>AcyIVo6#(AXR4CMkeE*KY!Yb?!m{Km%&Qr&IMzvg^DJc zL8FMstVi4F=`lMFr>Y<5qR5OZ(q||10X|v@R$8N$4Qu^GH`uY4&1d4w9+&E~RzjS} zS4Hq&6%EWnP*h4r19d}=%vO**OOt!Ci6rTEYRD>L&iuU>$oThjMI3h%_rvzuz(Uv%o!DPJhr z={3Y+zQ2f^YS7cLh9XorJXK!h(Uv!a0qxOG?1{dZ$MESu_U0zz6UFwhjCCSC^C2Z# z_o%_sha(6|Y|MF%ETG!Rpgd{Rl6MZc$A{u&+ZXcenJyXnNNZ(*v(!3TEN8Bg8=9s^ z2;034^jBah{8o7}@*KnH*IS!+>Lko@e1y9N?Y(*HD$^Z0B?zlW%%cs)iQ%ylW?HZ( z(m~JA#hlRFF#ZaUl{5m_S5vT*Kd-uMrZ{2cC@Z1=DX%W!+BQOexBLV^h z5(z_2Ubw&YfDA@EaQpz=ECe5sBM7>-KLTnk4-ZDM_C*797ZuK1QF6h>OJEC2(x#A~ z)O(|#$R|IBVO4MjRx!s7b_tWn(*7uRxB-mjv2t@)PCcd3tlm>10C>yVKF27rlM@b@ z{aoiqLn6?rCsEsES;)|daJ9Ma8G?&x2~QZ_fB2BcVWgc4(!Y&bElzdVU$k=NN?%;r zA9X7LJ%?S?PB3mo1(L%h)y54PB^UhYrrS5cAnQ6|b7Y zjjo|24Q*D-^}!4`&fpcv0+<@&K#lwE?!4Gee8>t%X(a$oL36N88#DVstl0{eD>s=O z#bn7{=|K zIm;iNNtCPJ%E4c>VGf0-+d&4`HAGOeVXlBj(DB=y?d}+GjfM-r5bd2JL;ynl`m~|X zYhp(d9fY=h6mC!+GZ+wR0M4|cI^tgHoRx#4n?s}o1B7Sp%9Fh`M;f{BqVXYr;t zhEKT)eBoK3rxr9eHde>0)gkehVMMOTVN=$8@(;MRzg4DTqq6SX_wFa!))HCa1_6fA zNY+>`E)w+QQ_(XP036__k>fa;rm;kgQ(0jspb==}l#SMnch!$gNJ|5!J;HN08q@>% z?V{>K{l|NN_G3KKUevZh9TP5w*ntMvnX&*k^{+19BFAAY9``T+!RP}DU*Q|0n%)S$ zZxfP~Tk78)3A7xg$>2J&AbZJTi0lnJc|V@z2F0^X69mX`d&$B!7)uc1HGyz@R5m7c6|q&6cYqVWpG7sW{T{gz1gOY&^q&DF}UHL>C8y z<%5@4fL4MgnR(^{ytw#tY+^1B1dv=tUa1Psbx58=^C1E$yNpv3OK!t~9FS3{b(3Cf z!jK%y(YT%M9#DcWiiR~Hoewc(2f*N55uev4U5_(NJQkxCXR{z}VUP7!GH%~)04`^a zx~yKd9)6RuQ4_Si)oU$RG6E=#*`L-xmq!K=V6+wS#e;fY_Ph%R1YmVhLQR?d04CGp z7T`AUBOeA8H2{I)4_M`g4Cf0eYA2OwVCU?_c=SuKqSzEAI3Ffx0OLaZKq5Vxw1GBc zNniq%HG2y!-*M(+|1VcT5@bNNgD#IFBLwxKfL7nWecKoD?DKkhtVf60kDQwEW~eo< z71*>!#}pP2F3^mu9t0!<{H9mYIBTyR{Mn>Lwx&bnW%Tw)D2^e7>O0d9nFGCWxS+cTmIeIr{zjLTxg`3WR1P-$w9!+FMIN^89+4C3saN5xuVD>;C zjYRrhyZt0Y@!Z#p<<6bs2cGB0;_<>*m|_U?D=9knJv;=^gXG2z(nn-;g4snNcS1qn zCYdS%gDqxV>i3|5X9PvwkkGMO)xHjh#|L9YWcCGX+jnoz_0N;7u8BaJu|%S20|S7KR~Cu@z_b>5zZI(g-eSz|Yvld>Je%^OFzf zka{hq<6x#Khz~AdoRJU#s%4Hw)SDHf2O9zSn`SCtTq}bTYuPshFHL>2Kr@G1e=>&2 zG0dj|1Y3D>vsk;y~Im@+5JL> zF7v_#P1mxgVW868F#RfCy&6TFAD}CQzhQd+8FN>9PqYE*BrOcVmQ}Jw0po)?6Ai`! zg4_v&cR~m7=sI~1Xq?P!*p*d%h5r`f?s*z9!=zlTcvqi>88)N3gdo6K0J=UCbGY!s zjICYZOBZfrSBh!h-B*qgxIZ)Ke(tg;k*-WJRwi?t#8@@TqmE`S+|ugec^a;{XQ@=n z)O&aCM57Jpni2fthlOqT=i`W%i{QD{I1qxoMc|x=xcqxTL2-jT;2WdH)c9gS)NKVM zJ)UaLBLGW8;Vra&ji4Yj2`}U-;tz864b-Ru$Vg&vpOO)+>gUH-eJ3>(>4dJd8&8;s)E>;iG?(*#(*oldZ5|F{KnlHDj=vdM(0sHq|OHa8G8842Yo zcBT}S`h?85!8wHVf*HNacvo~1STq8dYQF&!5e>v8C*3Ll`Uqqjm% z=z{1@1|nH}j}}BB`Ws&B+`D=6reeG*AKLXF;g7`>r)t(UQ~y1;#cJ9FB^;-lVQSOx zXtTEp9er_9zpS+~Wv$(qI2;Fng zWtpdl(7O)!!}php*Gceapv6Cp;~K`v(PgAWz+4*&Ss)txmvLc-_m+x^3c}Li-z7sH z!~q7{i9|s}BjlnXD-LnYiZBZ;eD?7s#SQ@5oy#!z;d;75VFInrRpA4z3-f8P?8gxG zpfV+r1vUFDJl(V~U|eFhmPgsa3+hfv&=CPigUL%S!lawevw(g~h2{f2F z8h^s8X1gRBa-7ltj1y26qVeR@P&k8>*9!?29E8k}IkD{6 zgoU%OT;IBNa$O4da6=C2k!aDQ%T+;qc4YE5)27J5OB!BCUhq{S><~nZv8mpXJ6CX^ z2YIbzs+gc^6CDU6Wd}+ezDF|_e!=4?pdYW{9e&`CYv~nJpZBttwG#8BuuT-~elf^! z8Y0*F0Tg4aAwrRJFUZkrjlzIec1}09xv6=y?XCsz@;OkgF;pIMc@6XiOMo5Arvw%K&WF8xwP@`dY-hLc2;quuG#;g6$MQFp zf2eB&dqZssWmAZV!eDErO%DwzMBKa5y?9jW_72E}ksU}ATqwRGGU&nOG& z>!V6ZRbs0RrIsQa`bg&|-`vlV2YbEu;{ZlKu?bgbi$c^&K=vkYq4}HN1_t7>qx;A) zK17#?uI7t;lAqhSDwpGerpDP46D=BInW|e~iQLZ-f^C zN1%mfP6d`aNWxVUn1YDuWNa{L5L=a*iuZ22R?(e{@%_C3OLe+YWaq3S*0Tv`J#a2m z6tE9t`8|~)OEa%9=%%sQLOXf%-GOXeyCDFPQ3&P@2;%VY+E$rHe6Zx0AKf!bvK`LYi%^+C zaq6-Xd3I}miJW=fE>v{&%(4#!J2qm54Wyz5Q}YLUR4LC6$T7kbB{U;6zc8+_Q!r4} zfi}u+_5hQr>>GCR%Yd$30H_&<S8+Lr{7r6SFsT9^IIkE9)*XPESQLIi7#fKbUNQ}BDTO8Ku8!(ap zBu8d9$Xqx%pXm^?@?WzHJ)oz+ML|g>3mDU7p^}z7go)nSzAzo}?E&0Q{R?q`Ch)9) zZv-@XBdf~-BPf8ClUXtr78WwRPmU%lY<#y{N8L4cnOh(hMaULX7_m~Kh!dfb95V(L zXByKiWXAeHh%@*5He>?LUHm4W!K5P~*$Q*EU7KCNF$9J6Lyq_$FC_XF93BCko{Yc} zy&O!leME0x4&(KomxbJN2}r~aV%Cf(k2h@MLaPX13CzL(m;2Bc#g4^ zYEYRmZ%qY4BJvdRa8c`W&#Rk5_QmNT?M>^NP7v=cv3=o?xd(szL3A222PF0*e}!Y) zBZ0Br*hC}1HZm50v3*-8+zf&i$M9+LxJJ-k9C{%diuyyQBV%xkC6V+=9~}TpYLfpU z&P#kbiw(m@Xue3S$U|U9uw(_7zy%)C;Ud{T1o$H;m(eDR<_yNE^Z6o7Ld?X|^~Q z6to-1h?SVu!^iHD_KkMZ>4k`&=zZ^5@q3 zWFOZxok_|8B8i*U6g*~=gOOH$NL2wS<;AA;m>_b;c5nboFF`TYMPM0_y^(euC>O_Z zBF&krZZ$JkUv^796fYQ`)VFI0Z>bPg;w>^hvXnc4POMD+16X{_Mq78w_I4?8U4q(p#-ksF^-{uEF%O42w~ zDt|%CmydS~y+k_*^2K#>d?V6Y1d3&3#-6$?gf$-~WRc2apfLKy{|`xmoCa(~^o2 zGW5+DDmQ!D)N(Z-7=jG$NQnS7I6YbEbx2Dap(}?ZsDN8;G$5uX;vxYC^Cw5{f)d99 zxe-OI25sOClhVZy1>zxR7$c+%#Rm-0<|9Xi!H#0w;L!Z9_rvdaAU`78tC zO)NRmry-?J*7)5(X|b<_M##FR<-|!zTr0@Vz-?F0`P}Lw8Xh_N2|&v~dK`Iz49FNF zk7Z(NH91v~@==lu^RvqMK5r}Z=(2yFO%BjO8G~qCkvBh{h^7@KsfwI~gSAovvK;w& z?@k^$9heC6WNwu7SXIQu=QVwAZ$IWunnUD#Nc0PjzVC|&3%gn!bph@DUEkKbskOj} z#EdkCt~_g`bVY!9ZZsMI5ytYil%FE>fSMqRVW{{j^b0U>U4Tb+D)eY2&K^4EO$280 z8ZlL^Z{G|s5e*W&Q_S(rolg`dCvutx8Sn=b5EFm9KT91ah#~S3xq;;H2OV3=v2zE{ zKX((K?%q$DClHcKD_`Suvl!?VedvHFVyHOD#$;9u$GMnMVIHajA{ayc>_z*ksK;ut t@0-5&pBB^q>MXIp%|ibVHk2kUtgxz1F!oWg%Oej*J$>#}!U^r0{|{b*PSXGY literal 0 HcmV?d00001 diff --git a/experiments/mnist_compare/results.json b/experiments/mnist_compare/results.json new file mode 100644 index 0000000..6c11b92 --- /dev/null +++ b/experiments/mnist_compare/results.json @@ -0,0 +1,42 @@ +{ + "config": { + "hidden": 8, + "num": 3, + "k": 3, + "batch_size": 128, + "epochs": 50, + "max_train_batches": 80, + "lr": 0.001, + "seed": 42 + }, + "original": { + "summary": { + "epoch": 50, + "train_loss": 0.21944646630436182, + "train_acc": 0.9365234375, + "test_loss": 0.2677607791423798, + "test_acc": 0.9212, + "epoch_sec": 1.788625517001492, + "forward_ms": 8.535971966921352 + }, + "total_train_sec": 103.28054552200047, + "param_count": 50816 + }, + "refined": { + "summary": { + "epoch": 50, + "train_loss": 0.24699158957228065, + "train_acc": 0.92822265625, + "test_loss": 0.2701142538547516, + "test_acc": 0.9256, + "epoch_sec": 1.1814144699965254, + "forward_ms": 5.467074267168452 + }, + "total_train_sec": 69.20829865599808, + "param_count": 50816, + "edge_weight_shape": [ + 10, + 8 + ] + } +} \ No newline at end of file diff --git a/experiments/mnist_compare/results.md b/experiments/mnist_compare/results.md new file mode 100644 index 0000000..85df257 --- /dev/null +++ b/experiments/mnist_compare/results.md @@ -0,0 +1,170 @@ +# MNIST: original vs refined MatrixKAN + +We trained two small KAN classifiers on MNIST to compare the original layer +(`MatrixKANLayer.py`) with the refactored one (`refinedMatrixKAN.py`). +Same architecture, same seed — only the forward pass differs. + +## What we ran + +| | | +|---|---| +| Data | MNIST, pixels scaled to roughly [-1, 1] | +| Network | 784 → 8 → 10 (two KAN layers) | +| Spline grid | `num=3`, order `k=3` | +| Training | 50 epochs, 80 batches/epoch × 128 samples | +| Optimizer | Adam, lr=0.001 | +| Hardware | CPU, seed=42 | + +## How the refined layer differs + +The original builds a full `(batch, in, out)` tensor and scales it with broadcast +multiply before summing over inputs. The refined version: + +1. Means spline basis values along the `(num+k)` axis (same for coef edge weights). +2. Projects to outputs with `nn.Linear` (no bias). +3. Applies the residual `base_fun` **after** the input→output linear mix. + +Edge weights in the refined model use shape `(out, in)` — the same layout as +`nn.Linear.weight`. On layer 2 that is `[10, 8]`. + +## Bottom line (epoch 50) + +| | Original | Refined | +|---|----------|---------| +| Test accuracy | 92.1% | **92.6%** (+0.5 pp) | +| Train accuracy | 93.7% | 92.8% | +| Time per epoch | 1.8 s | 1.2 s (1.51× faster) | +| Forward pass | 8.5 ms | 5.5 ms (1.56× faster) | +| Parameters | 50,816 | 50,816 | + +The refined model is about **1.51× faster** per epoch on this setup and reaches +**slightly higher test accuracy** (92.6% vs 92.1%). The forward path is not +identical to the original einsum-based spline — we mean bases and coefs over +`(num+k)` separately instead of pairing them per basis index — but mean +aggregation keeps the spline scale stable and trains well at this learning rate. + +## Plots + +![Training curves](plots/mnist_comparison.png) + +![Final epoch comparison](plots/mnist_final_bar.png) + +## Epoch-by-epoch + +### Original + +| Epoch | Loss | Train acc | Test acc | Time | Forward | +|-------|------|-----------|----------|------|---------| +| 1 | 2.0566 | 26.4% | 37.8% | 2.0s | 8.6ms | +| 2 | 1.4391 | 48.7% | 60.2% | 1.8s | 8.6ms | +| 3 | 0.9866 | 68.5% | 75.6% | 1.8s | 8.4ms | +| 4 | 0.7323 | 78.4% | 81.4% | 1.8s | 8.7ms | +| 5 | 0.5950 | 82.6% | 84.6% | 1.8s | 8.5ms | +| 6 | 0.5098 | 85.0% | 85.5% | 1.8s | 8.4ms | +| 7 | 0.4813 | 86.2% | 86.6% | 1.8s | 8.6ms | +| 8 | 0.4593 | 86.8% | 87.5% | 1.8s | 8.5ms | +| 9 | 0.4285 | 88.1% | 87.8% | 1.8s | 8.5ms | +| 10 | 0.4105 | 88.5% | 88.1% | 1.8s | 8.6ms | +| 11 | 0.4019 | 88.7% | 88.3% | 1.8s | 8.5ms | +| 12 | 0.3835 | 89.0% | 89.0% | 1.8s | 8.6ms | +| 13 | 0.3752 | 89.4% | 89.4% | 1.8s | 8.6ms | +| 14 | 0.3671 | 89.3% | 89.6% | 1.8s | 8.6ms | +| 15 | 0.3609 | 90.0% | 89.4% | 1.8s | 8.6ms | +| 16 | 0.3290 | 90.6% | 90.1% | 1.8s | 8.6ms | +| 17 | 0.3338 | 90.7% | 90.6% | 1.8s | 8.7ms | +| 18 | 0.3191 | 91.0% | 90.0% | 1.8s | 8.6ms | +| 19 | 0.3388 | 90.5% | 90.4% | 1.8s | 8.5ms | +| 20 | 0.3290 | 90.9% | 90.7% | 1.8s | 8.4ms | +| 21 | 0.3117 | 91.0% | 91.1% | 1.8s | 8.5ms | +| 22 | 0.2887 | 91.5% | 90.9% | 1.8s | 8.3ms | +| 23 | 0.2837 | 91.5% | 90.8% | 1.8s | 8.4ms | +| 24 | 0.2924 | 91.6% | 91.3% | 1.8s | 8.4ms | +| 25 | 0.2860 | 92.0% | 91.1% | 1.8s | 8.4ms | +| 26 | 0.2817 | 92.1% | 91.2% | 1.8s | 8.5ms | +| 27 | 0.2587 | 92.7% | 91.6% | 1.8s | 8.5ms | +| 28 | 0.2916 | 91.9% | 91.6% | 1.8s | 8.5ms | +| 29 | 0.2715 | 92.1% | 91.5% | 1.8s | 8.6ms | +| 30 | 0.2841 | 92.1% | 91.5% | 1.8s | 8.5ms | +| 31 | 0.2710 | 92.4% | 91.6% | 1.8s | 8.3ms | +| 32 | 0.2517 | 93.0% | 91.5% | 1.8s | 8.4ms | +| 33 | 0.2566 | 93.1% | 91.5% | 1.8s | 8.5ms | +| 34 | 0.2595 | 92.6% | 91.8% | 1.8s | 8.4ms | +| 35 | 0.2541 | 93.2% | 91.8% | 1.7s | 8.3ms | +| 36 | 0.2553 | 93.0% | 91.9% | 1.8s | 8.5ms | +| 37 | 0.2509 | 92.9% | 91.8% | 1.8s | 8.5ms | +| 38 | 0.2358 | 93.0% | 91.3% | 1.7s | 8.4ms | +| 39 | 0.2462 | 93.0% | 92.1% | 1.7s | 8.4ms | +| 40 | 0.2282 | 93.5% | 92.0% | 1.7s | 8.4ms | +| 41 | 0.2535 | 93.2% | 92.2% | 1.8s | 8.5ms | +| 42 | 0.2483 | 93.2% | 91.9% | 1.8s | 8.4ms | +| 43 | 0.2331 | 93.1% | 92.0% | 1.8s | 8.5ms | +| 44 | 0.2181 | 93.7% | 92.5% | 1.8s | 8.4ms | +| 45 | 0.2265 | 93.5% | 92.0% | 1.8s | 8.5ms | +| 46 | 0.2279 | 93.5% | 92.3% | 1.8s | 8.5ms | +| 47 | 0.2260 | 93.6% | 92.2% | 1.8s | 8.4ms | +| 48 | 0.2244 | 93.6% | 91.6% | 1.8s | 8.5ms | +| 49 | 0.2130 | 94.1% | 92.6% | 1.8s | 8.5ms | +| 50 | 0.2194 | 93.7% | 92.1% | 1.8s | 8.5ms | + +### Refined + +| Epoch | Loss | Train acc | Test acc | Time | Forward | +|-------|------|-----------|----------|------|---------| +| 1 | 1.2505 | 61.7% | 78.4% | 1.2s | 5.6ms | +| 2 | 0.7140 | 79.0% | 80.6% | 1.2s | 5.4ms | +| 3 | 0.6141 | 81.5% | 82.2% | 1.2s | 5.5ms | +| 4 | 0.5733 | 82.6% | 83.8% | 1.2s | 5.5ms | +| 5 | 0.5410 | 84.1% | 85.5% | 1.2s | 5.5ms | +| 6 | 0.5100 | 85.8% | 86.2% | 1.2s | 5.5ms | +| 7 | 0.4851 | 86.8% | 87.3% | 1.2s | 5.4ms | +| 8 | 0.4738 | 87.7% | 88.6% | 1.2s | 5.5ms | +| 9 | 0.4569 | 88.3% | 88.4% | 1.2s | 5.6ms | +| 10 | 0.4169 | 89.3% | 88.2% | 1.2s | 5.5ms | +| 11 | 0.4226 | 89.0% | 88.9% | 1.2s | 5.5ms | +| 12 | 0.4150 | 89.4% | 89.9% | 1.2s | 5.5ms | +| 13 | 0.3735 | 90.6% | 90.4% | 1.2s | 5.7ms | +| 14 | 0.3570 | 90.6% | 91.0% | 1.2s | 5.5ms | +| 15 | 0.3599 | 91.1% | 90.9% | 1.2s | 5.5ms | +| 16 | 0.3474 | 91.2% | 91.7% | 1.2s | 5.4ms | +| 17 | 0.3388 | 91.0% | 91.0% | 1.2s | 5.4ms | +| 18 | 0.3370 | 91.0% | 91.0% | 1.2s | 5.5ms | +| 19 | 0.3147 | 91.7% | 91.6% | 1.2s | 5.5ms | +| 20 | 0.3138 | 91.6% | 91.7% | 1.2s | 5.6ms | +| 21 | 0.3018 | 92.0% | 91.9% | 1.3s | 5.7ms | +| 22 | 0.3093 | 91.8% | 91.6% | 1.2s | 5.7ms | +| 23 | 0.3062 | 91.5% | 91.8% | 1.2s | 5.6ms | +| 24 | 0.2897 | 92.1% | 91.8% | 1.3s | 5.6ms | +| 25 | 0.2931 | 91.9% | 91.1% | 1.2s | 5.5ms | +| 26 | 0.2804 | 92.4% | 91.3% | 1.2s | 5.4ms | +| 27 | 0.2908 | 92.0% | 91.8% | 1.2s | 5.5ms | +| 28 | 0.2998 | 91.5% | 91.8% | 1.2s | 5.6ms | +| 29 | 0.2956 | 91.7% | 92.1% | 1.2s | 5.5ms | +| 30 | 0.2729 | 92.3% | 91.9% | 1.2s | 5.5ms | +| 31 | 0.2719 | 92.4% | 91.8% | 1.2s | 5.4ms | +| 32 | 0.2695 | 92.3% | 92.0% | 1.2s | 5.5ms | +| 33 | 0.2796 | 92.3% | 92.4% | 1.2s | 5.5ms | +| 34 | 0.2605 | 92.7% | 92.0% | 1.2s | 6.0ms | +| 35 | 0.2730 | 92.5% | 92.4% | 1.3s | 5.5ms | +| 36 | 0.2716 | 92.3% | 91.9% | 1.2s | 5.7ms | +| 37 | 0.2780 | 92.0% | 92.1% | 1.3s | 5.6ms | +| 38 | 0.2550 | 92.9% | 92.3% | 1.2s | 5.8ms | +| 39 | 0.2884 | 92.0% | 91.5% | 1.2s | 5.5ms | +| 40 | 0.2663 | 92.5% | 92.4% | 1.2s | 5.5ms | +| 41 | 0.2648 | 92.6% | 92.2% | 1.2s | 5.5ms | +| 42 | 0.2732 | 92.4% | 91.3% | 1.2s | 5.5ms | +| 43 | 0.2449 | 93.0% | 92.3% | 1.2s | 5.5ms | +| 44 | 0.2545 | 92.6% | 91.9% | 1.2s | 5.5ms | +| 45 | 0.2698 | 92.4% | 92.5% | 1.2s | 5.4ms | +| 46 | 0.2724 | 92.1% | 91.9% | 1.2s | 5.5ms | +| 47 | 0.2603 | 92.7% | 92.0% | 1.2s | 5.5ms | +| 48 | 0.2532 | 92.7% | 92.1% | 1.2s | 5.5ms | +| 49 | 0.2599 | 92.8% | 92.4% | 1.2s | 5.5ms | +| 50 | 0.2470 | 92.8% | 92.6% | 1.2s | 5.5ms | + +## Notes + +- This is a 50-epoch run (80 batches/epoch, ~10k train samples per epoch). +- Refined uses **mean** (not sum) over the `(num+k)` spline basis axis for both + activations and edge weights. +- Refined wins on speed by skipping the `(batch, in, out)` multiply–sum pattern. +- For higher accuracy, try full MNIST, more epochs, or a wider hidden layer. diff --git a/experiments/mnist_compare/run_experiment.py b/experiments/mnist_compare/run_experiment.py new file mode 100644 index 0000000..68df5ed --- /dev/null +++ b/experiments/mnist_compare/run_experiment.py @@ -0,0 +1,441 @@ +""" +MNIST comparison: original MatrixKANLayer vs refinedMatrixKAN. +""" + +from __future__ import annotations + +import argparse +import importlib.util +import json +import sys +import time +import gzip +import urllib.request +import struct +from dataclasses import asdict, dataclass, field +from pathlib import Path + +import matplotlib.pyplot as plt +import torch +import torch.nn as nn +from torch.utils.data import DataLoader, TensorDataset + +ROOT = Path(__file__).resolve().parents[2] +EXP_DIR = Path(__file__).resolve().parent +PLOTS_DIR = EXP_DIR / "plots" +RESULTS_MD = EXP_DIR / "results.md" +RESULTS_JSON = EXP_DIR / "results.json" + + +def load_layer_module(name: str, filename: str): + spec = importlib.util.spec_from_file_location(name, ROOT / filename) + mod = importlib.util.module_from_spec(spec) + sys.modules[name] = mod + spec.loader.exec_module(mod) + return mod + + +ORIG = load_layer_module("orig_mkl", "MatrixKANLayer.py") +REF = load_layer_module("ref_mkl", "refinedMatrixKAN.py") + + +@dataclass +class EpochStats: + epoch: int + train_loss: float + train_acc: float + test_loss: float + test_acc: float + epoch_sec: float + forward_ms: float + + +@dataclass +class RunResult: + name: str + epochs: list[EpochStats] = field(default_factory=list) + total_train_sec: float = 0.0 + param_count: int = 0 + edge_weight_shape: list[int] = field(default_factory=list) + + +class KANMNIST(nn.Module): + """Two MatrixKAN layers: 784 -> hidden -> 10.""" + + def __init__(self, layer_cls, hidden: int, num: int, k: int, save_plot_data: bool = False): + super().__init__() + kw = dict(num=num, k=k, grid_range=[-1, 1], device="cpu") + import inspect + sig = inspect.signature(layer_cls.__init__) + if "save_plot_data" in sig.parameters: + kw["save_plot_data"] = save_plot_data + self.layer1 = layer_cls(in_dim=784, out_dim=hidden, **kw) + self.layer2 = layer_cls(in_dim=hidden, out_dim=10, **kw) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + if x.dim() > 2: + x = x.view(x.size(0), -1) + y, *_ = self.layer1(x) + y, *_ = self.layer2(y) + return y + + def count_params(self) -> int: + return sum(p.numel() for p in self.parameters() if p.requires_grad) + + +MNIST_URLS = { + "train_images": "https://storage.googleapis.com/cvdf-datasets/mnist/train-images-idx3-ubyte.gz", + "train_labels": "https://storage.googleapis.com/cvdf-datasets/mnist/train-labels-idx1-ubyte.gz", + "test_images": "https://storage.googleapis.com/cvdf-datasets/mnist/t10k-images-idx3-ubyte.gz", + "test_labels": "https://storage.googleapis.com/cvdf-datasets/mnist/t10k-labels-idx1-ubyte.gz", +} + + +def _download(url: str, dest: Path): + dest.parent.mkdir(parents=True, exist_ok=True) + if not dest.exists(): + print(f"Downloading {dest.name}...") + urllib.request.urlretrieve(url, dest) + + +def _read_idx_images(path: Path) -> torch.Tensor: + with gzip.open(path, "rb") as f: + _magic, n, rows, cols = struct.unpack(">IIII", f.read(16)) + data = torch.tensor(list(f.read()), dtype=torch.float32) + return data.view(n, rows * cols) + + +def _read_idx_labels(path: Path) -> torch.Tensor: + with gzip.open(path, "rb") as f: + _magic, n = struct.unpack(">II", f.read(8)) + data = torch.tensor(list(f.read()), dtype=torch.long) + return data + + +def mnist_loaders(batch_size: int): + data_dir = EXP_DIR / "data" / "raw" + files = {} + for key, url in MNIST_URLS.items(): + dest = data_dir / url.rsplit("/", 1)[-1] + _download(url, dest) + files[key] = dest + + def normalize(images): + images = images / 255.0 + images = (images - 0.1307) / 0.3081 + return images * 2.0 - 1.0 + + train_x = normalize(_read_idx_images(files["train_images"])) + train_y = _read_idx_labels(files["train_labels"]) + test_x = normalize(_read_idx_images(files["test_images"])) + test_y = _read_idx_labels(files["test_labels"]) + + return ( + DataLoader(TensorDataset(train_x, train_y), batch_size=batch_size, shuffle=True), + DataLoader(TensorDataset(test_x, test_y), batch_size=batch_size, shuffle=False), + ) + + +@torch.no_grad() +def evaluate(model, loader, criterion, device): + model.eval() + total_loss, correct, total = 0.0, 0, 0 + for x, y in loader: + x, y = x.to(device), y.to(device) + logits = model(x) + loss = criterion(logits, y) + total_loss += loss.item() * x.size(0) + correct += (logits.argmax(1) == y).sum().item() + total += x.size(0) + return total_loss / total, correct / total + + +def bench_forward_ms(model, device, batch_size=256, repeats=30): + model.eval() + x = torch.randn(batch_size, 784, device=device) + with torch.no_grad(): + for _ in range(5): + model(x) + times = [] + for _ in range(repeats): + t0 = time.perf_counter() + model(x) + times.append((time.perf_counter() - t0) * 1000) + return sum(times) / len(times) + + +def align_layer_dtypes(model: nn.Module): + """Use float32 everywhere (basis_matrix defaults to float64).""" + for m in model.modules(): + if hasattr(m, "basis_matrix"): + m.basis_matrix.data = m.basis_matrix.data.float() + if hasattr(m, "grid_range"): + m.grid_range.data = m.grid_range.data.float() + if hasattr(m, "grid_intervals"): + m.grid_intervals.data = m.grid_intervals.data.float() + + +def train_one(name: str, layer_cls, cfg: dict) -> RunResult: + torch.manual_seed(cfg["seed"]) + device = torch.device("cpu") + + train_loader, test_loader = mnist_loaders(cfg["batch_size"]) + model = KANMNIST( + layer_cls, + hidden=cfg["hidden"], + num=cfg["num"], + k=cfg["k"], + save_plot_data=False, + ).to(device) + align_layer_dtypes(model) + + criterion = nn.CrossEntropyLoss() + optimizer = torch.optim.Adam(model.parameters(), lr=cfg["lr"]) + + result = RunResult(name=name, param_count=model.count_params()) + + layer2 = model.layer2 + if hasattr(layer2, "edge_weight"): + result.edge_weight_shape = list(layer2.edge_weight.shape) + else: + ew = layer2.coef.mean(dim=-1) * layer2.mask + result.edge_weight_shape = list(ew.shape) + + t_total = time.perf_counter() + for epoch in range(1, cfg["epochs"] + 1): + model.train() + t0 = time.perf_counter() + run_loss, correct, total = 0.0, 0, 0 + + for batch_idx, (x, y) in enumerate(train_loader): + x, y = x.to(device), y.to(device) + optimizer.zero_grad() + logits = model(x) + loss = criterion(logits, y) + loss.backward() + optimizer.step() + run_loss += loss.item() * x.size(0) + correct += (logits.argmax(1) == y).sum().item() + total += x.size(0) + if cfg.get("max_train_batches") and (batch_idx + 1) >= cfg["max_train_batches"]: + break + + train_loss = run_loss / total + train_acc = correct / total + test_loss, test_acc = evaluate(model, test_loader, criterion, device) + epoch_sec = time.perf_counter() - t0 + fwd_ms = bench_forward_ms(model, device, batch_size=cfg["batch_size"]) + + result.epochs.append( + EpochStats(epoch, train_loss, train_acc, test_loss, test_acc, epoch_sec, fwd_ms) + ) + print( + f"[{name}] epoch {epoch}/{cfg['epochs']} " + f"loss={train_loss:.4f} acc={train_acc:.3f} " + f"test_acc={test_acc:.3f} time={epoch_sec:.1f}s fwd={fwd_ms:.2f}ms", + flush=True, + ) + + result.total_train_sec = time.perf_counter() - t_total + return result + + +def plot_results(orig: RunResult, ref: RunResult): + PLOTS_DIR.mkdir(parents=True, exist_ok=True) + epochs = [e.epoch for e in orig.epochs] + + fig, axes = plt.subplots(2, 2, figsize=(11, 8)) + fig.suptitle("MNIST: original MatrixKANLayer vs refinedMatrixKAN", fontsize=13) + + for res, label, color in [(orig, "original", "#2563eb"), (ref, "refined", "#dc2626")]: + axes[0, 0].plot(epochs, [e.train_loss for e in res.epochs], "-o", label=label, color=color) + axes[0, 1].plot(epochs, [e.test_acc for e in res.epochs], "-o", label=label, color=color) + axes[1, 0].plot(epochs, [e.epoch_sec for e in res.epochs], "-o", label=label, color=color) + axes[1, 1].plot(epochs, [e.forward_ms for e in res.epochs], "-o", label=label, color=color) + + axes[0, 0].set_title("Train loss"); axes[0, 0].set_xlabel("epoch"); axes[0, 0].legend() + axes[0, 1].set_title("Test accuracy"); axes[0, 1].set_xlabel("epoch"); axes[0, 1].legend() + axes[1, 0].set_title("Epoch wall time (s)"); axes[1, 0].set_xlabel("epoch"); axes[1, 0].legend() + axes[1, 1].set_title("Forward pass (ms)"); axes[1, 1].set_xlabel("epoch"); axes[1, 1].legend() + + plt.tight_layout() + out = PLOTS_DIR / "mnist_comparison.png" + fig.savefig(out, dpi=140) + plt.close(fig) + + # bar summary (final epoch) + fig2, ax = plt.subplots(figsize=(8, 4)) + labels = ["epoch time (s)", "forward (ms)", "test acc (%)"] + o_last, r_last = orig.epochs[-1], ref.epochs[-1] + o_vals = [o_last.epoch_sec, o_last.forward_ms, o_last.test_acc * 100] + r_vals = [r_last.epoch_sec, r_last.forward_ms, r_last.test_acc * 100] + x_pos = torch.arange(len(labels)) + w = 0.35 + ax.bar(x_pos - w / 2, o_vals, w, label="original", color="#2563eb") + ax.bar(x_pos + w / 2, r_vals, w, label="refined", color="#dc2626") + ax.set_xticks(x_pos.tolist()) + ax.set_xticklabels(labels) + ax.set_title("Final epoch comparison") + ax.legend() + plt.tight_layout() + out2 = PLOTS_DIR / "mnist_final_bar.png" + fig2.savefig(out2, dpi=140) + plt.close(fig2) + + return out, out2 + + +def write_markdown(orig: RunResult, ref: RunResult, cfg: dict, plot_paths): + o_last, r_last = orig.epochs[-1], ref.epochs[-1] + speed_epoch = o_last.epoch_sec / r_last.epoch_sec + speed_fwd = o_last.forward_ms / r_last.forward_ms + + acc_delta_pct = (r_last.test_acc - o_last.test_acc) * 100 + if r_last.test_acc >= o_last.test_acc: + test_acc_row = ( + f"| Test accuracy | {o_last.test_acc:.1%} | **{r_last.test_acc:.1%}** ({acc_delta_pct:+.1f} pp) |" + ) + acc_summary = ( + f"The refined model is about **{speed_epoch:.2f}× faster** per epoch on this setup and reaches " + f"**slightly higher test accuracy** ({r_last.test_acc:.1%} vs {o_last.test_acc:.1%}). " + f"The forward path is not identical to the original einsum-based spline — we mean bases and coefs over " + f"`(num+k)` separately instead of pairing them per basis index — but mean aggregation keeps the " + f"spline scale stable and trains well at this learning rate." + ) + else: + test_acc_row = ( + f"| Test accuracy | **{o_last.test_acc:.1%}** | {r_last.test_acc:.1%} ({acc_delta_pct:+.1f} pp) |" + ) + acc_summary = ( + f"The refined model is about **{speed_epoch:.2f}× faster** per epoch on this setup. " + f"Test accuracy is lower ({r_last.test_acc:.1%} vs {o_last.test_acc:.1%}) — the forward path " + f"is not identical to the original einsum-based spline (we mean bases and coefs over `(num+k)` " + f"separately instead of pairing them per basis index)." + ) + + md = f"""# MNIST: original vs refined MatrixKAN + +We trained two small KAN classifiers on MNIST to compare the original layer +(`MatrixKANLayer.py`) with the refactored one (`refinedMatrixKAN.py`). +Same architecture, same seed — only the forward pass differs. + +## What we ran + +| | | +|---|---| +| Data | MNIST, pixels scaled to roughly [-1, 1] | +| Network | 784 → {cfg['hidden']} → 10 (two KAN layers) | +| Spline grid | `num={cfg['num']}`, order `k={cfg['k']}` | +| Training | {cfg['epochs']} epochs, {cfg.get('max_train_batches') or 'full dataset'} batches/epoch × {cfg['batch_size']} samples | +| Optimizer | Adam, lr={cfg['lr']} | +| Hardware | CPU, seed={cfg['seed']} | + +## How the refined layer differs + +The original builds a full `(batch, in, out)` tensor and scales it with broadcast +multiply before summing over inputs. The refined version: + +1. Means spline basis values along the `(num+k)` axis (same for coef edge weights). +2. Projects to outputs with `nn.Linear` (no bias). +3. Applies the residual `base_fun` **after** the input→output linear mix. + +Edge weights in the refined model use shape `(out, in)` — the same layout as +`nn.Linear.weight`. On layer 2 that is `{ref.edge_weight_shape}`. + +## Bottom line (epoch {cfg['epochs']}) + +| | Original | Refined | +|---|----------|---------| +{test_acc_row} +| Train accuracy | {o_last.train_acc:.1%} | {r_last.train_acc:.1%} | +| Time per epoch | {o_last.epoch_sec:.1f} s | {r_last.epoch_sec:.1f} s ({speed_epoch:.2f}× faster) | +| Forward pass | {o_last.forward_ms:.1f} ms | {r_last.forward_ms:.1f} ms ({speed_fwd:.2f}× faster) | +| Parameters | {orig.param_count:,} | {ref.param_count:,} | + +{acc_summary} + +## Plots + +![Training curves](plots/{plot_paths[0].name}) + +![Final epoch comparison](plots/{plot_paths[1].name}) + +## Epoch-by-epoch + +### Original + +| Epoch | Loss | Train acc | Test acc | Time | Forward | +|-------|------|-----------|----------|------|---------| +""" + for e in orig.epochs: + md += f"| {e.epoch} | {e.train_loss:.4f} | {e.train_acc:.1%} | {e.test_acc:.1%} | {e.epoch_sec:.1f}s | {e.forward_ms:.1f}ms |\n" + + md += """ +### Refined + +| Epoch | Loss | Train acc | Test acc | Time | Forward | +|-------|------|-----------|----------|------|---------| +""" + for e in ref.epochs: + md += f"| {e.epoch} | {e.train_loss:.4f} | {e.train_acc:.1%} | {e.test_acc:.1%} | {e.epoch_sec:.1f}s | {e.forward_ms:.1f}ms |\n" + + md += f""" +## Notes + +- This is a {cfg['epochs']}-epoch run{' (full MNIST)' if not cfg.get('max_train_batches') else f' ({cfg["max_train_batches"]} batches/epoch, ~{cfg["max_train_batches"] * cfg["batch_size"]:,} train samples/epoch)'}. +- Refined uses **mean** (not sum) over the `(num+k)` spline basis axis for both + activations and edge weights. +- Refined wins on speed by skipping the `(batch, in, out)` multiply–sum pattern. +- For higher accuracy, try full MNIST, more epochs, or a wider hidden layer. +""" + RESULTS_MD.write_text(md) + RESULTS_JSON.write_text(json.dumps({ + "config": cfg, + "original": {"summary": asdict(orig.epochs[-1]), "total_train_sec": orig.total_train_sec, + "param_count": orig.param_count}, + "refined": {"summary": asdict(ref.epochs[-1]), "total_train_sec": ref.total_train_sec, + "param_count": ref.param_count, "edge_weight_shape": ref.edge_weight_shape}, + }, indent=2)) + + +def main(): + parser = argparse.ArgumentParser(description="Compare original vs refined MatrixKAN on MNIST") + parser.add_argument("--epochs", type=int, default=3) + parser.add_argument("--hidden", type=int, default=8) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--max-train-batches", type=int, default=None, + help="Cap batches per epoch (default: full training set)") + parser.add_argument("--lr", type=float, default=1e-3) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + + cfg = { + "hidden": args.hidden, + "num": 3, + "k": 3, + "batch_size": args.batch_size, + "epochs": args.epochs, + "max_train_batches": args.max_train_batches, + "lr": args.lr, + "seed": args.seed, + } + PLOTS_DIR.mkdir(parents=True, exist_ok=True) + + print("=" * 60) + print("MNIST compare — original MatrixKANLayer") + print("=" * 60) + orig = train_one("original", ORIG.MatrixKANLayer, cfg) + + print("\n" + "=" * 60) + print("MNIST compare — refinedMatrixKAN") + print("=" * 60) + ref = train_one("refined", REF.MatrixKANLayer, cfg) + + plots = plot_results(orig, ref) + write_markdown(orig, ref, cfg, plots) + print(f"\nSaved: {RESULTS_MD}") + print(f"Plots: {plots[0]}, {plots[1]}") + + +if __name__ == "__main__": + main() diff --git a/refinedMatrixKAN.py b/refinedMatrixKAN.py new file mode 100644 index 0000000..3eadd86 --- /dev/null +++ b/refinedMatrixKAN.py @@ -0,0 +1,331 @@ +""" +MatrixKANLayer — matrix-form B-spline KAN layer for PyTorch. +""" + +from __future__ import annotations + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +import kan +from kan.spline import coef2curve, curve2coef, extend_grid +from kan.utils import sparse_mask + + +class MatrixKANLayer(kan.KANLayer, nn.Module): + """ + KAN layer with B-splines evaluated via a precomputed basis matrix. + + Forward path (refined): + spline basis → mean over (num+k) → nn.Linear → output + residual branch → nn.Linear → base_fun → output + """ + + def __init__( + self, + in_dim: int = 3, + out_dim: int = 2, + num: int = 5, + k: int = 3, + noise_scale: float = 0.5, + scale_base_mu: float = 0.0, + scale_base_sigma: float = 1.0, + scale_sp: float = 1.0, + base_fun: nn.Module | None = None, + grid_eps: float = 0.02, + grid_range: list | None = None, + sp_trainable: bool = True, + sb_trainable: bool = True, + save_plot_data: bool = True, + device: str = "cpu", + sparse_init: bool = False, + ): + nn.Module.__init__(self) + + if base_fun is None: + base_fun = nn.SiLU() + if grid_range is None: + grid_range = [-1, 1] + + self.in_dim = in_dim + self.out_dim = out_dim + self.num = num + self.k = k + self.base_fun = base_fun + self.grid_eps = grid_eps + self.device = device + self.save_plot_data = save_plot_data + + self._init_grid(grid_range, device) + self._init_coef(noise_scale) + self._init_linears( + scale_base_mu, scale_base_sigma, scale_sp, + in_dim, out_dim, sparse_init, sp_trainable, sb_trainable, + ) + + basis = self._compute_basis_matrix() + self.register_buffer("basis_matrix", basis, persistent=True) + + self.to(device) + + # ------------------------------------------------------------------ + # Init + # ------------------------------------------------------------------ + + def _init_grid(self, grid_range: list, device: str) -> None: + grid = torch.linspace(grid_range[0], grid_range[1], steps=self.num + 1) + grid = grid[None, :].expand(self.in_dim, self.num + 1) + grid = extend_grid(grid, k_extend=self.k) + self.grid = nn.Parameter(grid, requires_grad=False) + + range_t = ( + torch.tensor(grid_range, device=device, dtype=torch.float32) + .unsqueeze(0) + .expand(self.in_dim, -1) + .clone() + ) + self.grid_range = nn.Parameter(range_t, requires_grad=False) + self.grid_intervals = nn.Parameter( + (self.grid_range[:, 1] - self.grid_range[:, 0]) / self.num, + requires_grad=False, + ) + + def _init_coef(self, noise_scale: float) -> None: + noises = (torch.rand(self.num + 1, self.in_dim, self.out_dim) - 0.5) + noises = noises * noise_scale / self.num + inner_grid = self.grid[:, self.k : -self.k].permute(1, 0) + self.coef = nn.Parameter(curve2coef(inner_grid, noises, self.grid, self.k)) + + def _init_linears( + self, + mu: float, + sigma: float, + scale_sp: float, + in_dim: int, + out_dim: int, + sparse_init: bool, + sp_trainable: bool, + sb_trainable: bool, + ) -> None: + inv_sqrt = 1.0 / np.sqrt(in_dim) + base_scale = mu * inv_sqrt + sigma * (torch.rand(in_dim, out_dim) * 2 - 1) * inv_sqrt + + mask = sparse_mask(in_dim, out_dim) if sparse_init else torch.ones(in_dim, out_dim) + self.mask = nn.Parameter(mask, requires_grad=False) + + self.base_linear = nn.Linear(in_dim, out_dim, bias=False) + self.spline_linear = nn.Linear(in_dim, out_dim, bias=False) + + with torch.no_grad(): + self.base_linear.weight.copy_((base_scale * self.mask).T) + self.spline_linear.weight.copy_( + (torch.ones(in_dim, out_dim) * scale_sp * self.mask).T + ) + + self.base_linear.weight.requires_grad_(sb_trainable) + self.spline_linear.weight.requires_grad_(sp_trainable) + + # ------------------------------------------------------------------ + # Weights (pykan-compatible views) + # ------------------------------------------------------------------ + + @property + def scale_base(self) -> torch.Tensor: + return self.base_linear.weight.T + + @scale_base.setter + def scale_base(self, value: torch.Tensor) -> None: + self.base_linear.weight.data.copy_(value.T) + + @property + def scale_sp(self) -> torch.Tensor: + return self.spline_linear.weight.T + + @scale_sp.setter + def scale_sp(self, value: torch.Tensor) -> None: + self.spline_linear.weight.data.copy_(value.T) + + @property + def edge_weight(self) -> torch.Tensor: + """Coef reduced over spline bases, shape (out_dim, in_dim) — matches Linear.weight.""" + return (self.coef.mean(dim=-1) * self.mask).T + + @property + def edge_weight_io(self) -> torch.Tensor: + """Same as edge_weight but shape (in_dim, out_dim), for per-edge plots.""" + return self.coef.mean(dim=-1) * self.mask + + # ------------------------------------------------------------------ + # Basis matrix + # ------------------------------------------------------------------ + + def _compute_basis_matrix(self) -> torch.Tensor: + basis = torch.tensor([[1.0]], dtype=torch.float32, device=self.device) + scalar = 1.0 + + for order in range(2, self.k + 2): + prev = order - 1 + lower = F.pad(basis, (0, 0, 0, 1)) + upper = F.pad(basis, (0, 0, 1, 0)) + + c_pos = torch.zeros(prev, order, device=self.device, dtype=basis.dtype) + c_der = torch.zeros(prev, order, device=self.device, dtype=basis.dtype) + for i in range(prev): + c_pos[i, i] = i + 1 + c_pos[i, i + 1] = order - (i + 2) + c_der[i, i] = -1 + c_der[i, i + 1] = 1 + + basis = lower @ c_pos + upper @ c_der + scalar /= prev + + return basis * scalar + + # ------------------------------------------------------------------ + # Spline evaluation + # ------------------------------------------------------------------ + + def _power_bases(self, x: torch.Tensor): + """Return local monomials [1, u, u², …] and interval membership mask.""" + x3d = x.unsqueeze(2) + grid = self.grid.unsqueeze(0) + + x_intervals = (x3d >= grid[:, :, :-1]) & (x3d < grid[:, :, 1:]) + + interval_idx = torch.argmax(x_intervals.int(), dim=-1, keepdim=True) + grid_start = self.grid[:, 0].unsqueeze(0).expand(x.shape[0], -1) + floor = interval_idx.squeeze(-1) * self.grid_intervals + grid_start + ceil = floor + self.grid_intervals + + u1 = ((x - floor) / (ceil - floor)).unsqueeze(-1) + powers = torch.cat([u1 ** i for i in range(self.k + 1)], dim=-1) + powers[..., 0] = 1.0 + return powers, x_intervals + + def _b_spline_basis(self, x: torch.Tensor) -> torch.Tensor: + """Evaluate all basis functions: (batch, in_dim, num+k).""" + power_bases, x_intervals = self._power_bases(x) + + pad = self.k + self.num + basis_padded = F.pad(self.basis_matrix, (pad, pad)) + basis_exp = basis_padded.unsqueeze(0).unsqueeze(0).expand( + x.shape[0], self.in_dim, -1, -1 + ) + + oob = torch.zeros( + *x_intervals.shape[:2], 1, dtype=torch.bool, device=x.device + ) + intervals = torch.cat([oob, x_intervals], dim=-1) + floor_idx = torch.argmax(intervals.int(), dim=-1, keepdim=True) + + start_col = 2 * self.k + self.num - floor_idx + 1 + col_range = torch.arange(self.k + self.num, device=x.device) + col_idx = (start_col.unsqueeze(-2) + col_range.view(1, 1, 1, -1)).expand( + -1, -1, self.k + 1, -1 + ) + + gathered = torch.gather(basis_exp, -1, col_idx) + out = torch.matmul(power_bases.unsqueeze(-2), gathered).squeeze(-2) + return torch.nan_to_num(out) + + def _b_spline_output(self, x: torch.Tensor) -> torch.Tensor: + """Mean of basis activations per input dim → (batch, in_dim).""" + return self._b_spline_basis(x).mean(dim=-1) + + @staticmethod + def _masked_linear(x: torch.Tensor, linear: nn.Linear, mask_out_in: torch.Tensor) -> torch.Tensor: + """Linear layer with elementwise mask on weight; mask shape (out_dim, in_dim).""" + return F.linear(x, linear.weight * mask_out_in) + + # ------------------------------------------------------------------ + # Forward + # ------------------------------------------------------------------ + + def forward(self, x: torch.Tensor): + mask_out_in = self.mask.T + + spline_sum = self._b_spline_output(x) + base_out = self.base_fun( + self._masked_linear(x, self.base_linear, mask_out_in) + ) + spline_out = self._masked_linear(spline_sum, self.spline_linear, self.edge_weight) + y = base_out + spline_out + + if not self.save_plot_data: + return y, None, None, None + + return y, *self._plot_tensors(x, spline_sum) + + def _plot_tensors(self, x: torch.Tensor, spline_sum: torch.Tensor): + """Per-edge tensors for pykan-style interpretability plots.""" + batch = x.shape[0] + base_w = self.scale_base * self.mask + spline_w = self.scale_sp * self.edge_weight_io + + preacts = x[:, None, :].expand(batch, self.out_dim, self.in_dim).clone() + base_edge = x[:, :, None] * base_w.unsqueeze(0) + spline_edge = spline_sum[:, :, None] * spline_w.unsqueeze(0) + postspline = spline_edge.permute(0, 2, 1).clone() + postacts = (base_edge + spline_edge).permute(0, 2, 1).clone() + return preacts, postacts, postspline + + # ------------------------------------------------------------------ + # Grid updates + # ------------------------------------------------------------------ + + def _adaptive_grid(self, x_sorted: torch.Tensor, num_interval: int) -> torch.Tensor: + batch = x_sorted.shape[0] + ids = [int(batch / num_interval * i) for i in range(num_interval)] + [-1] + grid_adaptive = x_sorted[ids, :].permute(1, 0) + + step = (grid_adaptive[:, [-1]] - grid_adaptive[:, [0]]) / num_interval + grid_uniform = grid_adaptive[:, [0]] + step * torch.arange( + num_interval + 1, device=x_sorted.device + ).unsqueeze(0) + + return self.grid_eps * grid_uniform + (1 - self.grid_eps) * grid_adaptive + + def _apply_new_grid( + self, grid: torch.Tensor, x_pos: torch.Tensor, y_eval: torch.Tensor + ) -> None: + self.grid_range[:, 0] = grid[:, 0] + self.grid_range[:, 1] = grid[:, -1] + self.grid_intervals.data = (self.grid_range[:, 1] - self.grid_range[:, 0]) / self.num + self.grid.data = extend_grid(grid, k_extend=self.k) + self.coef.data = curve2coef(x_pos, y_eval, self.grid, self.k) + + def update_grid_from_samples(self, x: torch.Tensor, mode: str = "sample") -> None: + x_sorted = torch.sort(x, dim=0).values + y_eval = coef2curve(x_sorted, self.grid, self.coef, self.k) + num_interval = self.grid.shape[1] - 1 - 2 * self.k + + grid = self._adaptive_grid(x_sorted, num_interval) + + if mode == "grid": + sample_grid = self._adaptive_grid(x_sorted, 2 * num_interval) + x_sorted = sample_grid.permute(1, 0) + y_eval = coef2curve(x_sorted, self.grid, self.coef, self.k) + + self._apply_new_grid(grid, x_sorted, y_eval) + + def initialize_grid_from_parent( + self, parent: MatrixKANLayer, x: torch.Tensor, mode: str = "sample" + ) -> None: + x_sorted = torch.sort(x, dim=0).values + y_eval = coef2curve(x_sorted, parent.grid, parent.coef, parent.k) + num_interval = self.grid.shape[1] - 1 - 2 * self.k + + grid = self._adaptive_grid(x_sorted, num_interval) + + if mode == "grid": + sample_grid = self._adaptive_grid(x_sorted, 2 * num_interval) + x_sorted = sample_grid.permute(1, 0) + y_eval = coef2curve(x_sorted, parent.grid, parent.coef, parent.k) + + self._apply_new_grid(grid, x_sorted, y_eval) + + def __getattribute__(self, name: str): + if name == "KANLayer": + return MatrixKANLayer + return super().__getattribute__(name)