From 5e72fe57d36ef231693b2792f8ca8d420ac57d1f Mon Sep 17 00:00:00 2001 From: lucasdelimanogueira Date: Mon, 20 May 2024 20:16:41 -0300 Subject: [PATCH] softmax v1 need fix some erros yet --- build/tensor.o | Bin 50416 -> 50768 bytes norch/__pycache__/tensor.cpython-38.pyc | Bin 18460 -> 18512 bytes norch/csrc/tensor.cpp | 28 +++++++++--- norch/libtensor.so | Bin 194792 -> 194800 bytes .../nn/__pycache__/activation.cpython-38.pyc | Bin 1201 -> 1616 bytes norch/nn/activation.py | 11 ++++- norch/nn/functional.py | 13 ++++++ norch/tensor.py | 15 ++++-- test.py | 15 ++++-- tests/test_nn.py | 43 ++++++++++++++++-- 10 files changed, 106 insertions(+), 19 deletions(-) diff --git a/build/tensor.o b/build/tensor.o index bcc09bcf292ec24c4a1201335bb53e4de60a905c..d12bc526f48941d9271926bd72e9a6df3e846ecd 100644 GIT binary patch literal 50768 zcmeI54}4VBmB(KKXhekIKd@>$SSSbx;h%sY1Y}?os3-&#sUakTMDwr7M9?*Y4Wi?S zOaExy*0$8e*0#1{^<$%DH6RvjsisP8w5-iqv|#8;TUxbM*>mna=gsfknU?^y-F7$c z^GP!Ez4!g@x#ynq?wkAGysV1OnVFlD;P4Uw2lzLvv*7WN_^Rm$E?VaHLq0dME zTog;b9&6lR7)v&^#*+0d$)cUH}lSwVz^O_e;@!sUi~1kJ*u;*EQAlF@^W4F|oIQ&lfjbTC%>LTt-xxv`wBspx@ZZYp|^Z9N%mZAp2lq62*% z+M0|WXskS#)BZ!={n@8slnZo}%VMeSgNAT7X>><5Q|sL4?a_n$hjwdC6%LsgJ=icY zYdbuMt+7;LUTQAc^=xd*f013rRan~l{@ts9#kTNmB` zcrI0aqC1-))!WasO=0DnmOu2#r`YWq-A^xQ%&3=Tu`#wki5_NT1HI0tUcW=JeSm5n z$h7Bd7RYXDZ&ReUOv%3g;PCx>;r{CbMir7#JIJVJXDDco9Vwd}JO*16=Mrg7#W-DT zfuDoEXPel=rr&||YmTKTg=ja^xpdy#(wvyUqOnv=in-ch%ZgmK#ErI5#<;QxGP)}j-Q{LcbT93^*Q;NAgjo!xcYajb9&KS~QF2d;?&`Dd8G0=q%1;%w zXgub$r1GtY3iDHQ38!P6Mr5&H6xbs#R7hQ$s&AQ=ga`~7H+HaNjcsUMue;cIIt=cO z<@`A1C3732Ejjx}((z2%&XR8PxF}UP91a)jDF4#oU=Gr$xfBjGX36I?_2?~S>D;zd z(XLpkey`&88`FA$gCM0=W5a2kWJasfr?E!Q1KC^LzB(cO(t7!I*z>4L@(Qqr5DUPj`hQuuly->dvphnKaGY-r6%jA?Axos)3vA4c*WoDx`pn|jdS_HL=@ZVIi&H*55(ut2--$;IdEZQ8v82o+M|ciJ z7PW0RC&1gI%^WiOZlPanr;Y2338!s)bQ{&6^B$8|QgdQ-Tf_8JblarpqlvM$mwY(h zrjx_EUip-P>*nPoDR40a+xX-xha-1ePW$)M?Ixpif|U`&&6zPw0!I?Vd&wz6q?Tz3FJ!~4DBOKPtBaVO9zo0 zP4imdutR&uoVqKg{i~_yqwe5}p4djCitd8+YwsUYu%39wdAWq9uLqL#8#ymGWKLlZ z*r_XPUdpK#=OtCkIQ435*!UsjWh>3`tw%n`M_V;7%?zY@`9Mfswr-DZ=250Jmcizl z6Qi3sFE>w$ZZvtx&Y-;9tV3$@vf1Qib71IN{k+_4^HSPPMw{pWVCRCJS&Pj8I>^>j#!8x%m^9=4f@f87 zQtV8$oqYCAHEg6dTKS;Gr*0GxFn_IX*g#qKGI^E@$gvr1lK*!G9KVyZY@^9Cp4-w{ z#-4#JlOfruL&8~R-lQjY+C#Ezr^&L7A$npPjS+e)MIRD$8m1#qs)$QlsVo$hgsrfXHi9Hly+ z*1A?jx>iN#vOw3WNXMVPx@Mn@j{;q5^7eDmj;`6qo(I~C0kGQ9`RrrTim%sg%Usc5 zzZUo(=>k`Q|H&>UHSk*D5r#=SeLgq)WVvoLpNl%aZX=)YNg?^%vOZN?eLvczJa=`v zeN|dAxX5r+OL-Iz^a0%Vz-|91uig}Ll+gVL4Oy;=(rVk`L<&{QSo@-GH`6*t$CqOM zeka%_Qn)*`dUd#`vnEok3o_Q5I8vy89bMt$HIkxcUdH8Rl3!4;G}{lj9Yl&qen^oL z*8b5(3V%@SI;PlFy1?b&u49VVb)$tn(Er06@w#rbkVK`!@c)q;Etc?=D!S1k0gwVJD#Z6T(+lTuBPJYTf#za$Pu}$m)-0YvBYd^wP_tM!!ouvh-{!Ukersry}9%` z++Lgw&aC$O-QW7|Cv#oR7-eqt;A?7p-pW0svl0JV8eh0EZ_*cT(w9f+D%yXfCFnXR zoqq6rl+y|F2++8h>q->rXKzXJrL@N8Tyt5AWt+pUx;E#uKbGZs+|JDFaeAFRa6Qgm zbPM|Qs21k-7qYLDNg&eOrE~OWT)Ga^A<*v zTlku#f3llS%~<2M{J?#V)Q-tJmd%p&RD5(dc3HWOvVO8PKO^hu`e`>h;{R`@x$o?J zdexTX-`3@+B09=!?ap@&Y8^T+XO@>L%uD9}gQTAwNPp<{y85_|)9>$;XB19+-;95? z8IwDhXPw;Z(OI6E*^^qM12g9r$C`bYJ!yP*r86avC7N`3Xdb7k{h8UeRNzMr z&*oX%JbR3a|8Tk6$$cVSOPcNtyLvZz z*Ybn2{LrD<~Kh?Hh?lI71`I@SNbUDE8jLXtY{)yz3GjqK=n-P_#dOqWOel>pkM zmCo2QE{&{AYXv_-{uLj|___=IUHEZxMn+-Cb?h&_7H4YnqFzfo@lzHPv z*U_RYESv>7zH_WAEV{xX7#8MgTxM7t#`+4MTTnG~d8;k(A=^B7AQ^43&#DN1l>Zyv zSnq$vl&|s9W#~!KmWK0W@q+I2Xfco7=;&*@=?Bcv*L0thwGCP>5{)biAhUztz|Zz+ zjW7DZ8icOIwU{p{>ldMaV@^ghpAK|X3vrDNE!`4R`1h*0^gAb!N569u{n}~J_^ye7 zMeUbmgLGF*W=-eo*kj4&%vB?Q9PDz7?dB0Jx0s;h$8;1O;X^v)t|Sc2)}ZhCnHWi0 zJ~iuZ!O;90-ihS9M84W@?i|`-PJ21iC^XIOLFPeco!l$5O+u0O*@WLWe>D63Md{k6 zg0^6G&AiEpYtv#L-Kr(~We<4#GQ9gWf4&^86FJuVNBCKxmxwH81$E6QYzUg-GE!Cr_t$@`r(*#E{-8?QZjM zlyr5!AW+>Gv27R~{b*+lIh-rAw3l2M2u8L&hV)tUIdZwJllkz2cjyrp^svLe*z&%m zw8QpjD=)~&e&#WKyXhfF^q4++lu=;u`W^F>zE*Snop`>D2-2y?r&Hkk1O;a0Z6U3qzY(+|LyG$ zl3Tc@9ku<~bf1T|8dF?s$fIRN7=go~*R@Yu1DXFNa zE-guvS64-rm6TV+%X)gH^<^bqX-&PYw;*0sS6y2dsjRO{M3$Fa7mp;C$0KzmmGMYb zedW@4ZKQfxq^!J>s*y-tWKdb8q^gYnEUT`Kl$4c~vv^N0ptCd{p$2`SviNo7rSbD3 zgX-+Qbv?ac{b0Lw%S&qF&`?PtQeIUSUzyn`bzweNCf!=Hw>l9it*)%0?k=r}8~c{l zR+p5OmeeK6tFER-X$#mHZ1*twTUWm{QCm`KyWE*xXZ;9>{dIQ5E8;XliE~zz*Trcl zD-z{373Fr^ZMQq>cV~8XD1KoTxZEh!8P8XiBx=i7I=0XVuJi+lUXg8K`}-poFN-WK zNt7<9zlWu1WwZ3x#I%u0$FmI*mS=HtTsrK;Zx@tQaa`5Lt(OueT}DI}R3}O*AVb7Q zbrh+Qs`!eCtzA}4p~<_GI5oiuQCeSHOCuGjE5Ct~WSLe@tI#M)dJsjrD7sv~34F0C6u?a#X4g7YFnik8+_ zCF&y+M~od&aL%ZD^KR5lqYFk9j2$uhY|Bj&(Jy{5RzCgk4dt^wS>(}UOq-eUJ)pdu zZ2x#UH(cuFtjy0jz1OjM>uD}IgE;^2_6E-_(cbxMb1yjIm~Q`>Lsd-KWK-&Sf8xJd zp8H!aHsy<@+&mf5FTcYtzfsCBV`H?u+b6rJ{=HH@I8gpkzkIWl-xDbRSHFC>l&=ny zukg#?>!kb)?l)~=_Dz=ZF#8sFvj2@zK9rv=>-T>^uHXMo$~SjXzPpq5-;?rJ0{;1# z@1HZ+F4~p{%8UK-$x^;KQ2vNtzF5k``gda|<@ZW?KmP0cr?>B)%~HNDP`<`5-!0`~ z`QlE>Z|tP}UMasT(7!wU{%w}>G5pu}&rsk0yQTbD9%sM2 z+2k+xE8E6ZyL-Pol&!2=)+c!Lu|yhjcIsx1J`SX}-OSM_8$UJ^n)-A=$+C6xj>|$> z|CkKki^z#!zd5E6`w0E;@zLE12xQ~qL->>s9u46ah44#4_~pdeezn^ibBUFN)L$OL z>q7V%;;gSZV~*Lx?hL8_jS$X{a%7!POGud9Blc`a{hx(!K6YpG|N9~QObT3XcZUqU z$!V%PmUuRuvJn1x(RoWk%gimL^VN|0-wNT|L-=zc{4L^a|E(ubW3;Un|NS|n{^@i~ z;QC*hXzQC}Aid;cE%RghTCO_dh-dS|LaBeNoCxT6m4wv)ObEYEbYAUe+g1PbbJMf6 zyDxo0%@Y_UZ@kgzWnSsurfnJt})SoZ)>qgr8I)`ltslPLXzb!f=$5 zP-j_4{X0VV!=ls369jGMoPqvs4ypf22!A_-_ot~bTfZg{XZr_FHqF{|ReBi>slPmg z-!3{gO|?3jzyBUm|K}n67@Dftp8Ka;9rZ&$;@Rw<6vD3(oy{|XIyE8n?+W3Mi_VKP zgF4$n>c1Ak4~fp3v7k;*nkTaLYe)!>5@-M9%(gn_+>Tx@45@!Z2;UIGe-y&^6X$mC zo@?7R=Zy3+mp)Z8e|Dbb=3J3po=7}fzdZR+U0PG)mDa{f67gb7yy97NE}lMZPVvPv zXU>ln2IXR z`%2QL)ihdbg;zgrI(UMy+5#C|mx%Oke+j1_01r}|pc+u$b*^4sU zm{(p-&5S-btiIDESFfwD)Rx3+b@2q-IxbxjXoz}J>i2joR!XbSTUO56l_e`xn>(L= zTTE_Ow@O`E%hCFkV1`V{b%!KghQCVuG<++kn zC@a4X`k~@!YQ&eNqkuc0;#jMu9xK_yMKM>f?eK1+GiX-Jv(yS&4i)T6S6nLK(L%#& z^r(!zF;unMs0nsSQ(P0U)2}n$sgt(SR>1(3W!U1tE@bzZ@txMnX5Z*@vkGRlbM&~7 zx~{$AnVRYqSq3dl1C407W$cSqL%6Ywt!oBNf-p^uI7SkL8`cVjTSfKNY1L8V(r*K{ z%E28=(=M=u6H4mp%CFXAT9&=XI~4)~abEldL&hTri1{&eZm>#P&epJ{7$RxsO$;l{ zY)OuF6T8Dodq+ zbe%u{P;}AM=)cVr8#NY711hCtp6}*S zvM(l+bu!c%eOR@|gw#s6R^F!dg zM56Uy67JghTj8#qzXu((Q?Dt|$8HbpoKEXFyfH_6_^f* zW&zq%=T!UFs}|1ooJ2qBhpz(XB_ZW60Y3%!+rs$|eI)l({}9wi{S#^3gg31(%RJsk zguC_(1z+S_TOu(d25BU9QuDfaMXXv z(b4#P73yO=-Nbq<%XM_!+2PO#zPfCxD~h)(Usq{fcmH zSN(P$=%C*o1di>_q;)9XT>Vc8SN%P(afTR9?M@QrEAk;@cpG@mYyt#2W z8u-VkT>Cp0IF4^AaP()raJRpA2-p6q{%1i4`}<|!*x$#2N5IZqz|qcqz%dTb;!3o! zAMp6ecWv;-9Q!p7I37Psg%73rc)oOlaJRp!KnMGq1djdvJaDw z*zQk&W4rGH$96XzPYu$h`WkOd!r5;aZ>_-bxc4XEXVE?y565w1w6V^|=|_14IGd(? zJn(_QFBCqM7>>&l;cCC?#6buBQw<#ba|iH2(C&AD^GnsA&qmP3{X+XILio+VF>ap# zj&b`V;Mne7;25`m5$^iuMD9Fou7COoXZz7V1AwD{h5<)=&KK^syFj?x?iHZJFV&x= zz_H!W0>^e^T!}W-*SMW0oco1wTLT>9_Ez9Hj$Z+e?LH*j?eC9-t3BGUpMVbb_vgU* zrPlvF@WH_Qa&XYb{X%;l2afi?2z&_bqx$=SWBnWsCfZmZSKH!0FLo_ELReJ9IrEhV}C~qcl$e2xZ0!RG8=TTzeT{YzqP=*4b}N9aI|Nl z+}FVVLHp+e$M~!Oj`eQ_j`8_Z;ckC_Azb@=vV1<@13Gw~`QN~?zsGT7w6Xo%MeXlE z;cmMlgloGMyfbZ+KnL560>^fXfMed307pMJ0_RXwJHHAX>wjOkYyY#t)qd4^4snQGbdNSM^h%gZ{h=IQI8J;OBrnPXk9g zTY>Y?X}kS-v4%D`U&aV`?LS|*+FxOJ_bvh*9Ipky(f-?kqu=fo?za1gaBWxZZvq|k z+g9M%?&8y|!LELtaMj-<{aPuU{e$|S0gn2)+`Jz$2gqLou|#Uvq-qw`Jfyh zmI`NovZUHy0UYhT6*wLT?i22|`=D@bSL6I~(7|?}29E8%2ps2yUjfJQ%Hc&Q+PGgh zFPs4!>lX-j?VlxF?N|TI0UaFQg}~ANPlf0wLiDc(9n^0Gj{5J1=%2ugT(qhEz4!%f z9}(`3`#|8Re~qJ~`B)3}F&^#)&O@Yr`!4X&z_$U%IR7PZ9IxLBcgL%{+;^${)pm~) z&izGyo&+5GI~4dBuyY!4v~wYF%*Q)`W8B^Y9Q*YIaE#lZ1IPONgu8z5c=3xi*AG2} zyME{c9Q|;ra997F5dG1hgMOY29QE&XbTqE+hWZ#+PXNcb+68PWAxDxH<$J z>z_2hGuu%5%}Xrm&!NIyKa3Ra`e7n)^h05Y{$(Nhi$MqDY8i0UZ*p`ru9~4f#?>C+ z7*`(vp8$S1gPqEgZ(W7j{Us}_(agT3pm>O zZQvMJZNM?E_5;U$_2$J*+IZYCuFeLI_0JdX`eA|aT+%^5Tmd@hhf?6^higLgZw}F4 z3p%L39ysd1=ICf#y$SU(u6hq-?^yp}Tnzy}iOO}{rvk_ES_mBdxm>vG&sD-*f35)? z?C+hxvA+)hpA2?B1sv_%1svll!i&qaxpoc}u6F8q>3HGYX&*d4oCX~2Tnrrjze2d% z?#;rr-3ntJeeVc#u-$urW4jLk$9#DdIF8p#z%gHb2OR77_=Gjgwf_v^YQM(M0O9O6 z9N%HU(f-jP`WJ@ie-d<1|8n4{|3ZlVYmUCISG)x}=>K@uz9XR^mJKO5H?e-L|?P@;u6Yd@d1^~x) zM*+utJRdlYS21wR$F;z*{+EQi_CG9K?bq>r40LdOn}MVK+e7qU4blHK=%D^@fusH_ zY&dP~Pwdxz;cmaW4KvmK{L+5q31=N__e9{>?f^$e^Ym<}k8yG#aLm&sz^75$YR?Mb zJ%Qg29Q%8(aJRpY2zSS^33RZ(TY+PLUj{xM>^T4&?d&m}D$&ON#5`Ru+_m$5;cDkb zenH#!K?n1+893VcOW^4LKM8l+^>~q#Hf^`UzV%KJ?&fJf;Mne9;FzalfcGM89p570 zn5UJ%vHs1%UHk75uJ)_`S3n2H_nW}c{_ln8KNF(=W6(kUUBFTQiV@baZk}E%-0jzA zguDH^6?A%oKR*i`+uh*kXr4X*^)XI%0LMK274V+W?(c!)cy%9X`|I}Wbm4BlBEsF{ z&rslfpxtS}X8^w(INDhW9P{xR;jW#}3-|5h7qsmL9n8l!fcK$#8i(f>nB6kYljjOo zeVvyV33v0Z3^?kq0*>SOCE;$rHVW5vHQyfw9qiW+fn&Qr0iF;2{RME0hj)QvzV{tv z{p04vAmOh4lZC7O>gQ>o(;MuW4IJ&iG(^8VM867jP=6(G)c*iD`XQeeNojNYHCVXY zui?Voyf_y)wi|VHG~ee!eTbjOyFmy2 z{04CB@B6@KfjuXWp*OU#-_Xvpf#Y$Y7&ylBwZO4o>wx#AHq<{40LS{9g}Z)uQMl`e zR?tB|yapWourEa48_Qlu&+lqy58-ZH^#P9hC6129RXNl@iP};9b-*#Mz6tz7sQ)Bz z9Iu}PM}PiCxa-dkguDLiHjceu;{pA70&wi_VBi8e#+4~)tcvh z9_nLU{Qx+|)z5&>Aq^d`y})t24gp7h_8o5xaQiz%xZB@zgu8h(9ys>*65w;e&gH<- z&IaJ8K>hCl$GCa|IQDBdaEzM z7*|&TNBvEX&Z)LLUK7;ExY`XI~9fp?C)~m^T;l>a}{umt1ke@xY`LExaq0T|Z0% z9rVL&;OK`-L-fl-^s7Jz^;ZH%{k%!GU#|Th6R!5p=w|B;6z=B52;iuHzN4dY8-@B9 zx8=Z3hjG6V_$9zU4;Mv7zZ5vyxe_?$V-s-n&x^uc z`~Oq8+OPTYCg|XJ9R!Z{4=rTx*y9HJZE~T(8Gf5DT-(+DUM}4A+fv}z?t8-Bex1aN z+O(&tbyd z{!SO3OFBJ3e-`LqUS9$n`&$kCa?rUQINJF&;24K3!14IG8#wms1K@c4JnaH9f;RRK z);~wM>xUV_bE!W1;X=?sKgp%zfR|7}=7aSdpt5={t#?=SFF|PW~ zVDDJ}ETX>}S3`i~cufV4{=7uE>(AxFU4K@B4)%8iaP05xz^?>5zYZMjd<;0o)o*}f zT>Sw!_Un`=d&l|*uP#@#!6kcQ$|6p7V0sbi}*SMMr9LH-RaP;SL;jTYd33vUu26V8$cLK-$ejWH# zU}qC>wDYIHF|IxUj&aqK7dL6^PCwYM;lMGjW&y|gR|&(Vwe?yZ*de zxa-d^gAVrhe&E>OCg3Gt=kvhP&ON{}u1?{_R@&G<7*_*;W4|r{j&XGraI9Y|-1S3J zxa)^IK?nVC4{-Fu*Fy9k3(@}}=%D^Hz)`>7MaDfDarH6bZd_de9OG&s@KTc0xT*x+ z6Zjh7=+C=_52d;%K>hCucm4T&(82z029EuG9(Wn(zX7}_@V@}ZxEem2D$(Y~)db+! zuSLKyuIhnf{iN`r)CT%tgK*am_k#}l;UVDYhsQ$ne;T6y0_dRrZs4dtWsY%AMqJGl z?#9(J;22le17Ajx8dvLq<9K}ocrU2mB;57q^TJ(!?gAa`@2kMEzsK{UHf`LmtLaDW zi~wH_d>rs{;8TRVb`}X&J7;i1v@HT1w6hF2+W9ZQ(QoU4W1MdXj>pdzf%hUiw7-7@ zj&YvutJU&pk+uupTwZE!g2s*u?-HU)@e=ia4>Ms}W>Q{nJZ_r->9Q8+DZ2P4; zIxmkG?#B6Lz%kCR0e%UzdoyqxuP*{e|9?xk+uvs4YNz`18PLK0J`cPP*z+22T(^7| zINJH0dDcJdhigISY2X-dZvw}D^=7Bg#yZFc0k5Dk?blK^jyA53yf%bKxH4_*AO6v; zP+ln4{~xi$;rf3cRy$n(kHZFs>;GA3cDVlEgf@rk|23dTO`A>a(f?Brak&0Jf|;T%Sw7!QuLx`DTaf|AT0AxIQ1=>lXCCKJPu^aD9Gzp~Llg>`NT3&sSgVaD86- z28ZkO&zl{t&nItlxIUlU8&P+CWujy${Y})`zsvPiZM>pnL?XU2;f*LONtAdame$pI zBWkPd8~T50{J-415%iD4;v?vPVVz?hD=zP^uBsnVQ(IjVuT5M}`>;}cdGWGZ`iFhi zVSnZC2<^`yb&R7^DDOWfd9B3~e)`sYr=O1ng+8$_4piH}tL6B0JiX<8^DOrI%im83 z7q<%ayce8ywZLtEI2Eww(e6Kr_GL{8OL}FuR%yS1I|rNEuZS;K^8N)19tX+1lnkH(bfTJ#PX}dbIVTAAafX&zg>jL_Dum(xad3Zy^10 W{nwXRw*4>PYWGO!j`G*t|9=3Qdz{Vy literal 50416 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 V2b)**V^YYXx~SlNd3)%ke*mFgX=?xg delta 1322 zcmchWNlcSL6vw~!wG=}wp+IQ@7K$`N5m7{0#X_}3*-9iv#f5EvNZA}0B&nhi_pSQe zF)|eUQ7NiOEz6Z?4ik*x$;@vH4t!WODbZe=7fTJT1SFtxMPH{eHyQFGc22JoXRH77P= z6x;g>BG{CA2P&~4Gac<|haiY!X?f72y-Iry(2Iv1dGq=>go|+3DBY|F7|R&T^-4ZE z-l%55^G-%LK6YkPph@R|9{5^@z9GoAK}K{dE4|QNTI~F10J}Mvc@HmhGATK>UbNL^ zH^2b8v&StVvbfc$GNv8yNA^0?KHd{;v^}SB>Wp6IJmj5$^7-1;ym0_MrnVt}BbX1* zlIY!HuR7(Ey)*>oV}JT+FA6`a8NW5k<{pOLM>4A*zAhT3wpSHzv-QuIbSK?@QhQuH z0Wq?KZ1}u9)#w5e=Sl+wp^z$jLrRZ1WNa}DwHsI`D>R$C)qH_Pt98ESc9Og`mMaMDwRPs$ztB2jXzJWVOwN!XZVgR@vzk%bQz znDCg#xwLJsx2+>M)FwsrbB4(=dQQI%tBckW4T`dJy3%6&Rx$5?RNCU%1Yx>A$(FwD z{mW-c&?Y?_K;2}(veI0wttu1L-l)Fsy$^5@x32yKBj>#t*zW6uF?{7~4b*X8HM2BV zPiqf2vWbKOCNQaPLxW7AiQf$kbc^{8`2QL)=r5sHecN9&Qb}f6#qcp|85~qLGW3Vt z!Dndim) * sizeof(int)); for (int i = 0; i < tensor->ndim; i++) { - shape[i] = tensor->shape[i]; + if (axis == -1) { + shape[i] = 1; + } else { + shape[i] = tensor->shape[i]; + } } shape[axis] = 1; ndim = tensor->ndim; - + Tensor* new_tensor = create_tensor(result_data, shape, ndim, device); + return reshape_tensor(new_tensor, shape, ndim); } return create_tensor(result_data, shape, ndim, device); + } } @@ -289,11 +295,16 @@ extern "C" { if (keepdim) { shape = (int*) malloc((tensor->ndim) * sizeof(int)); for (int i = 0; i < tensor->ndim; i++) { - shape[i] = tensor->shape[i]; + if (axis == -1) { + shape[i] = 1; + } else { + shape[i] = tensor->shape[i]; + } } shape[axis] = 1; ndim = tensor->ndim; - + Tensor* new_tensor = create_tensor(result_data, shape, ndim, device); + return reshape_tensor(new_tensor, shape, ndim); } return create_tensor(result_data, shape, ndim, device); @@ -353,11 +364,16 @@ extern "C" { if (keepdim) { shape = (int*) malloc((tensor->ndim) * sizeof(int)); for (int i = 0; i < tensor->ndim; i++) { - shape[i] = tensor->shape[i]; + if (axis == -1) { + shape[i] = 1; + } else { + shape[i] = tensor->shape[i]; + } } shape[axis] = 1; ndim = tensor->ndim; - + Tensor* new_tensor = create_tensor(result_data, shape, ndim, device); + return reshape_tensor(new_tensor, shape, ndim); } return create_tensor(result_data, shape, ndim, device); diff --git a/norch/libtensor.so b/norch/libtensor.so index d1b1cd0abda25d6f7180b68a7f9c04a092883ca5..5d6e518858f33e23124f274788b4c26e00a07c7e 100755 GIT binary patch delta 27770 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
5`hLyr?3Iu+DdnyyTP{K{z@1dBm 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 delta 26417 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 Le5T~TA@%+bFuzzu diff --git a/norch/nn/__pycache__/activation.cpython-38.pyc b/norch/nn/__pycache__/activation.cpython-38.pyc index ac065b476d96e84f7f2267f3d9318b15a8069e5a..0a2693bd37ebd5120abcdc7c9f3ff0a7df7ece86 100644 GIT binary patch delta 393 zcmY*UJxc>Y5S`h*cr&wa-p>69qEQ%nKrwp1%x=Ug>f_bwY;Z6H}5lnh4D&={|$c5HdszJjCDT761_#iFusXcbG5imPEsV`#fF123he@Y{jpl z)JN1A+j+fIi^N3LB7aKz#2r)Sl|7vAH8SVfOg~Mu(%t_{)uHB1v^wnOkT>}l2ZL7S YFLBMab&5SxS|<_v3ot-O#C~l50R9z0?EnA( delta 68 zcmcb>vyqc8l$V!_0SFX)ywm10PUMqebeX8_%$C9u%%I7+v1JA`qvm8;7B41Ej>#Wc WwI(aDDe-UsmGdz2Fmf;na03ANAq?37 diff --git a/norch/nn/activation.py b/norch/nn/activation.py index 5f93936..a1361f6 100644 --- a/norch/nn/activation.py +++ b/norch/nn/activation.py @@ -18,4 +18,13 @@ class Sigmoid(Activation): super().__init__() def forward(self, x): - return F.sigmoid(x) \ No newline at end of file + return F.sigmoid(x) + +class Softmax(Activation): + def __init__(self, dim): + super(Softmax, self).__init__() + + self.dim = dim + + def forward(self, x): + return F.softmax(x, self.dim) \ No newline at end of file diff --git a/norch/nn/functional.py b/norch/nn/functional.py index b865379..9b5c3ec 100644 --- a/norch/nn/functional.py +++ b/norch/nn/functional.py @@ -3,3 +3,16 @@ import math def sigmoid(x): return 1.0 / (1.0 + (math.e) ** (-x)) +def softmax(x, dim=None): + e = math.e ** x + s = e.sum(axis=dim, keepdim=True) + #l = s.log() + print('x', x) + print('\n\n') + #print('log', l) + + print('\n\n') + #print('x-log', x - l) + + + #return math.e ** (x - sum.log()) \ No newline at end of file diff --git a/norch/tensor.py b/norch/tensor.py index 7e60d7f..52a5558 100644 --- a/norch/tensor.py +++ b/norch/tensor.py @@ -697,7 +697,7 @@ class Tensor: elif self.ndim == other.ndim - 1: self = self.reshape([1] + self.shape) - + # Call equal_broadcasted_tensor if broadcasting is needed Tensor._C.equal_broadcasted_tensor.argtypes = [ctypes.POINTER(CTensor), ctypes.POINTER(CTensor)] Tensor._C.equal_broadcasted_tensor.restype = ctypes.POINTER(CTensor) @@ -748,7 +748,9 @@ class Tensor: return result_data - def sum(self, axis=-1, keepdim=False): + def sum(self, axis=None, keepdim=False): + if axis == None: + axis = -1 Tensor._C.sum_tensor.argtypes = [ctypes.POINTER(CTensor), ctypes.c_int, ctypes.c_bool] Tensor._C.sum_tensor.restype = ctypes.POINTER(CTensor) @@ -783,10 +785,13 @@ class Tensor: return result_data - def max(self, axis=-1, keepdim=False): + def max(self, axis=None, keepdim=False): + if axis == None: + axis = -1 Tensor._C.max_tensor.argtypes = [ctypes.POINTER(CTensor), ctypes.c_int, ctypes.c_bool] Tensor._C.max_tensor.restype = ctypes.POINTER(CTensor) + print(axis, keepdim) result_tensor_ptr = Tensor._C.max_tensor(self.tensor, axis, keepdim) result_data = Tensor() @@ -818,7 +823,9 @@ class Tensor: return result_data - def min(self, axis=-1, keepdim=False): + def min(self, axis=None, keepdim=False): + if axis == None: + axis = -1 Tensor._C.min_tensor.argtypes = [ctypes.POINTER(CTensor), ctypes.c_int, ctypes.c_bool] Tensor._C.min_tensor.restype = ctypes.POINTER(CTensor) diff --git a/test.py b/test.py index 2306f6a..f6125ae 100644 --- a/test.py +++ b/test.py @@ -6,11 +6,16 @@ import norch.optim as optim import random random.seed(1) -torch_tensor = norch.Tensor([[[10, 10], [-4, -4]], [[5., 6], [7, 8]]], requires_grad=True)#.to(self.device) -torch_tensor2 = norch.Tensor([[[10.0,], [-4.0,]],[[6.0,], [8.0,]]]) -torch_tensor3 = torch_tensor.max(axis=2, keepdim=True) -print(torch_tensor3) -print(torch_tensor.equal(torch_tensor3)) +torch_tensor = norch.Tensor([[[2, 2], [-1, -1]], [[1., 2], [3, 3]]], requires_grad=True)#.to(self.device) +b = norch.nn.functional.softmax(torch_tensor) + + +"""a = norch.Tensor([[[4.186502456665039]]]) +b = norch.Tensor([[[2.0, 2.0,],[-1.0, -1.0,]],[[1.0, 2.0,],[3.0, 3.0,]]]) + +print(b) +print(a.shape) +print(b-a)""" """print(torch_tensor.shape) print('\n\n') diff --git a/tests/test_nn.py b/tests/test_nn.py index e790fa9..daaac21 100644 --- a/tests/test_nn.py +++ b/tests/test_nn.py @@ -60,11 +60,11 @@ class TestNNModuleActivationFn(unittest.TestCase): sigmoid_fn_torch = torch.nn.Sigmoid() # Test case 1: Positive input - x = norch.Tensor([1, 2, 3]).to(self.device) + x = norch.Tensor([[1, 2, 3]]).to(self.device) sigmoid_norch = sigmoid_fn_norch.forward(x) sigmoid_torch_result = utils.to_torch(sigmoid_norch).to(self.device) - x = torch.tensor([1, 2, 3]).to(self.device) + x = torch.tensor([[1, 2, 3]]).to(self.device) sigmoid_torch_expected = sigmoid_fn_torch.forward(x) self.assertTrue(utils.compare_torch(sigmoid_torch_result, sigmoid_torch_expected)) @@ -87,4 +87,41 @@ class TestNNModuleActivationFn(unittest.TestCase): x = torch.tensor([0, 0, 0]).to(self.device) sigmoid_torch_expected = sigmoid_fn_torch.forward(x) - self.assertTrue(utils.compare_torch(sigmoid_torch_result, sigmoid_torch_expected)) \ No newline at end of file + self.assertTrue(utils.compare_torch(sigmoid_torch_result, sigmoid_torch_expected)) + + def test_softmax_activation(self): + """ + Test Softmax activation function + """ + + # Test different axes + axes = [None, 0, 1, -1] + + # Define the input tensors for different test cases + test_cases = [ + (norch.Tensor([[1., 2, 3], [4, 5, 6]]), torch.tensor([[1., 2, 3], [4, 5, 6]])), + (norch.Tensor([[1., -1, 0], [2, -2, 0]]), torch.tensor([[1., -1, 0], [2, -2, 0]])), + (norch.Tensor([[0., 0, 0], [0, 0, 0]]), torch.tensor([[0., 0, 0], [0, 0, 0]])) + ] + + for dim in axes: + softmax_fn_norch = norch.nn.Softmax(dim=dim) + softmax_fn_torch = torch.nn.Softmax(dim=dim) + + for norch_input, torch_input in test_cases: + # Move tensors to the correct device + norch_input = norch_input.to(self.device) + torch_input = torch_input.to(self.device) + + # Forward pass using norch + softmax_norch = softmax_fn_norch.forward(norch_input) + softmax_torch_result = utils.to_torch(softmax_norch).to(self.device) + + # Forward pass using torch + softmax_torch_expected = softmax_fn_torch.forward(torch_input) + + # Compare the results + print(softmax_torch_result) + print(softmax_torch_expected) + self.assertTrue(utils.compare_torch(softmax_torch_result, softmax_torch_expected)) +