From 84e632cceb2b7b588d150a3550415d8816ed5d44 Mon Sep 17 00:00:00 2001 From: akineeic Date: Wed, 4 Dec 2019 10:28:16 +0800 Subject: [PATCH] Dnn example: image-classification initial commit --- dnn/image/panda.jpg | Bin 0 -> 53804 bytes dnn/js_example_style.css | 74 +++ dnn/labels1000.txt | 1000 ++++++++++++++++++++++++++++++++++++++ dnn/main.js | 291 +++++++++++ dnn/scalar.html | 49 ++ dnn/simd.html | 49 ++ dnn/thread.html | 50 ++ dnn/thread_simd.html | 50 ++ 8 files changed, 1563 insertions(+) create mode 100644 dnn/image/panda.jpg create mode 100644 dnn/js_example_style.css create mode 100644 dnn/labels1000.txt create mode 100644 dnn/main.js create mode 100644 dnn/scalar.html create mode 100644 dnn/simd.html create mode 100644 dnn/thread.html create mode 100644 dnn/thread_simd.html diff --git a/dnn/image/panda.jpg b/dnn/image/panda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8b76f304594d1f1c29f68f366d3bf1d71f7aa7be GIT binary patch literal 53804 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 FV(=xeqtKx*DBj9lUq={R)hlNuYdSkHl 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%0A2YhGCLv+xX*#d2&m@e?@qCY| z`!Q`Ae0?hu>0R(4F&XMd6)sEQO){$*d;D~HoUiDt?^LRhm_~g)I+UA=M_Q43 zNM?q5!jxlRTkhhXDxTeVOuUE(m6S z0zubp``{r$sV!WgEuYwck0qn!@m&UYXa4oypX)ST`5A0?f*s2N?YM!E9 zST<-ItghrS8qa3D^%ZdR#maW)88t)*ye=o2Z~|>ouD(m!*;deT`J$w+GU3G=lsgwc z=N~4`SfFwG+`!MH=PV6iB8fjBsK&I8G!b zRq1T>X&H~PAe<1E``X2_I4w8((`LZx1*B*~k()!_9m_Q3bPOKQi#J^kkqj4g42ZNH zGxq4&`(07kX+WvzLTsA;Ut87rW^e(et311uS0HMQF@NN5PGxC1u|XKRIFN-KRWlE%|r+ zik_=AB74x@CAg=y^PvtZDgwHS;f2}coA|4SB>6`+AR^!UyJYI1M&hmo6Ng)IiyUsj z(DUioUyqB3^8=M?{!HG|TQE@Up)a!seCI27C(ior#tU0YN_zTCYz z%8%-;mV$#~8l+NSCV(;XsF=gqpxp}wC~`7rap}SqCZT&-WEO9~TU=P1Q9RZ)xz7rm zVwK83VZp0Wc0w8>KY-SJ*D|QLChtY@S6yiT4lhMM%MMn!VfE=+kleX@f_7 zO*0+&B!sj-zb7`|c9xeynI%n|VkPY|-e5`Jm2)C`FjoEaz}e`TjWHdvX{UJangGyV zJbV%o3pM}RiLv?)L@Rur3YWjvbH-#p(;#b0%^`P9gtrBYnnSe%tKC1K{C06P!!(aj zf2Binb!J~A!gQ9mc#}U#BW_?*v|kV)5c+%SjegZUdvCc4!Sg#4%(wdqNf>>wvh&cB z=j4}Pu++P!S_MU)kHs9}O>{BR;O#9!V>ih^oNO`{;4XujIMjBv7k(nh?k#Niu72ls z(n_(|_P#>*%Ru8COZ8-K>3$j5Y^4SLeac!Rb7DRZ%q$cV|8M0+yPz-_3jN7F7p}ka zxQMLnRR$TZ`DI-!t)d^Xd?|6)muewL!7xT!N!pAzX;7eoa@$E+2I|&cwn;}{d(x?GLkq;ax`t&ZWyXjOB zJ&afXk$sp~FT`C}YiJ^P$TDJGwDb{r3Cz1Dw^6{F+LL}RkGoKfe2Ftr<*CdF%S%R# zrGA1BLK^QBzFD;%oy)owT3j*QvHUl$@wryu^$9pouw=+MWIs+IM z_cCY38pQgaMhhb8nY zD$<#;+!3QGszF<2wJ~UhomtX9{yD4GfY=gU5)@t-9uwkTy-R-@<0%^oFH!tgFH+<3 z&4|_ee?ZzFV5`pviz&!gU~z*#pa5R~C`@_g?l~l6=^+wMc5KhJj^Lz)hLbayo5x)g zD^c5DLt+oQGtM1dxUZXRRFDM~fJ+k}+vm)UeIGoTcy`4zH3PTnU34Q-u47W&0>tLf zN@C&XiPbUM5D2Z+rR;{usUPoh#b=%x)K!CVi~EW@LOU{Vt> zj{WXG_1{o#03GL5B^Q={{n2J)j{ha&yYgcb1%T_@73`^K^Mn?-|Bk_L>Em--79Zz% z=VScGcxNj&x}bV*{(#=izHLSLm#dn57W;iVLU5$Ex*Oe_dmZW7A%SBBsqh7Kp=$Ep zE}Wt^QJX}*&@#@PU(;|2DL0+J0l9w#NhKADY9M!ktpiRf!$^$98mh2Z>KbAH^0P^H@FC+j(hm&AGB zp7{gPdSn6H{R4Wb^tjz-A-t8<&@(UycA_&<^?~p}(7^QV zMe@P%-P@V`&asd926Co(badK!PL@X2!4h}kP{i>c`Z-WzZKrN-7Rg~)@xIqDItTf* zXf5WgTM0tnjLTCkI-y}d0E9KDEONXJ-pQK@r$yo!13&kCS}5C@%gTMf(OV4&RsZ6= z`)X4+{(u4(5|`PaVM@nM!)fb6?*$}I;dO+flQ1=T4F+W|tMq9SO!*{sEk?-sK(@9a zD9!+=k{34;Aj3iX6K3C|lk_)*QsNa+AtO;ognVD+bTxY)T~)`;*Mg4|1Q> zXx(NyVJz!*?TU@bJ4a^n73gpgTFX<^(7g`h)M$rEEYbz*8*sIKhFfLfg0x={=`%W~ zvEnl7dvwRaWich(Ydzl&YNy|IX$^rW?W-!6L1dqIFp=12NQ=(-OFd<0oIqUhI-U^w zUHV^*8#9ZnL#G_{kx`lW6HSB^sYLkep}YRwz5L(+4yiEO#<_dXnjg~PJ=w{z_IqJ; z6!9w;X&hi&xm$&iOEI1#i8)WziYXe4x|g-;AwIx<{M`1D^V;Z*m|4o6z0Xm(hKsy+ z?<75PRrBQsXT1ngEWWlAt4Mzo=3_Aa_U`?rs$sfh*XHZj^qwK&hXbRBaF4bhl?QGLZ5+R&h!}{1c>{igc|84A{{CB@CWPQ)mX@fY z{@eQ@eBwnve;RZn11XGaD`GvFhT|FatF{H*Y_A#gxKFcdlvQ-VI$2G>m1hwBALO23 zDoGWxNh`A$7rp!kG~s{Q16c*f9mCtdyZZ-J!FQ4=m}hA?%EbuNJ<1gL$JqMcI{U-G zE;I*&kGx?MyShk~0it2*y6vo)Tdu#uA+}Ktzd59*Q|LY$kNDig4Ma1^o)U+@hDAq} z*hXw|VoCZ%N~*}nu$+LYsFL?&Rv;Wxo7v(Z{IT8e(3jofr6&2M%k~3MSppc(!o6<% zVIyT5x!P+NyNl}5u^5_#H$W9#RI{fVkO(DgIexltU8mdlKVabPm)o0PysWG*;wH9NM0j>V}fZ<$>? z?cNmhYJF4VIp7TrP zC9U3S&m-*g*bM45wArT?#|@eFN=fR%CJV@RF5Tn>Pe=zG8kb#OxhwEWBUj(J=D-P% zGuqXAMyGgxr|>z`;q(WwwuW?L&A}h-$FI#!4UlEUP-684_hvTpi@@a5Tjp(yG8z{<`(h~oeg^#M+`q9~+Z!ZKEO5T4e zRXuka7GyX{{Mh|5HgQGJepsdhj5{5#UW`^gwXZ-Ac(gQZnH<{4Eu8+q9_8t1O^Kiw zZrsQBZ=keMHahc?0K>AzI<*t}w*!)c$WCrTftUV=FpcQ^s+(;xwG--l3%(;thhc=B zZiLF<9OC)EIn?uV4z%XI_2Xhppb*~8e@j0>AsI&R3Sg#pKt-#9)Pj?e(T36Tf`)-u zP2W83MUQ(Hh0to*iCLcqhsPm&)5(TW#;}Qs;U%x`pMkBH{{t~E>^F(G2|Pr|115>p zgS%h!%c}sd?8?zC@XQau7O6!YtRCxv0Swt5|vu;LH`t>1_L!wI_A716@BjqQ9N^W|TK zT@?tG@jVmiO7Gq`IUd|_*%|WelO_PJu`XS^>f)ciVcN*aIw17&En@nNzJ<{0^uZ~R zJ1x29whNzOIJlCQF=_M9<2}2$dn>ctYN6EmyPCr5H{Rx&?TuFBG-9-pB_iwsc2xZ} zoj!m0{g_EeXA5`R)jyAGL3kdF$~j}fg>U*UmH=y>FubI2o}Do&nyD&LF^aa|3OLPY zX;syMaD;bpc;6PI;K`b#Dt`i2@#=@TH(X;_KMN{1dY8Q{a%L#Rz$iH=0QK8@dS2sU z=F)Dji*!Yw?Nc7un=hRX3MUf={k6Sbz%Nt%3;O1fRU8CF#0xh*Q>meDdI&>hsIM!W?6_TK(oxv?4T zzrzhqdxYOgp&5=r39m+$z3zvz6($#1{^Qz_d`&7*dE(mSB$sh4M_NQ~32rbHA@wwE zs(owg)5zgvW>?kZlhrU6miRv;o;hwW+oDpvquo%y!-!w-&1Y`r5%o|zA$;hO>_4D? zj^m|aeWlk{)CxYoG3rxtYI^(TfdKoszNDQV9FZ&<7FjScsMJb1v@>LT0DUZmxE}mF z`#SF{%6}1rD`kpB^b@eV8%n8)cQk;dhywpdr_X@*X3aZ(WSQoy(ldi}3!dHE##lm) zz0h0Jo}w9bE&Z+PGXRrMqAErnz7_UZDnV)#Nmzj5F$1Q9C3f`{?aPK9U~jE%BIA-~ zPrx?uiSbM89ugR01eQB8+@P#uanb!rpx`8?fjb36<3#iGg(NPId$kRs_#qz3BB(84h!AbwGj|z z*~Fh%YT7?`<~+M|;dN2g@Mas*?Lo|F$Y4;}wEx4=@;3JG!aGHFdMu|-d!^bqd{4e% z1bu<|xMwfxe0lX;YgBPwFt#l)nhKr15og4NS7K)$8swf@k3z@L7Wts&)Cc7U0_}}* z9DZPTJYoqHJ+Qk$k~;gOf5&);gr35I0mC8p+1Q}0?o|73NMpQAn8-j=XJ@c;x#FddI@ ziCs9qZnN8hm`wXYTp9oP?-bMHi@uz7cSyl#?OR`G??+p!VR4s?TvHknk5x=8kF=!q z#N><}q9i0D=B4_|n3E|WzY`A#3GK(7H`V4Ob$Ro_FzQyJwy%Ml21FBLZu=MO8jI^UxDi$$H z+8=o?(-|m|^!;zS4d)xzPqnX{fQG%NsjSU> zE}Oc;1_f&nOr9S66*poOk{|=;7*^QFc)eU|7Kel7H#u!_eglga2mGs$1C1zV*L3%249n_42wI9_@G=4-kq((CTh;4< zZ>l#mr$1g`W9}}IiKG}wRpW-Q=cKv`_ryPj(u`Br4Pj%>9a)WPaoqlUjxi41YNYl)x^OV| z7${0lr094 zNbs+O;iA=1i+X8=Pge`QwI;WmTS|Q<-YiA6SWhiY+f+g$!|TA!X5GCqCA|YB>)|_j z$;+sUjv#2`Tn@Mcb7_joPp^XFr%8UuKZyTQLQFOmnlOQaNBW(Zbxn6*TgwJ31 z6~J_<$fsOTg3$nH_#TH@cW1e%l@5Xe*~eSHCLWuHL^EBDj+iR7?|v*g`AS_Tn8_S) zb>RKyQpKxxYpb_jiywgq=D6W`pVk~)4W#kS4m7Suqe^>DP#b{Qi(-W>M&c50pLs7( z=`XM`8+$}RV6QDM8Sk9GF;@;}j3Ic7?FlQpltZ@E(9>nmNDjBQqI>uch-?HezBJ($ zP2AsiPr6QvaHjA57O0h*jX*2YqFyXd$yYaUO?a0!WreQSOT$9M1KBHZ1KzS5-2rKx zV(qdV4PFsO5JhCXgC`*|-pFvh=xbI$%b|Dt!R`qjSzoAYB8-v0gABp)OYT4~2h}o^ zih+3$Nq?)EBY$J0ZbZDZa}yRQAD$jIz4_;JJ>FfK9fb+&<(-AX1EO{%Upcts9R^*WR|)0);mZ93dX@Vxi#^B5qMhohNuHbp zm$XeUM@ppz9miW!mie(MtHk=SDmojpCw`#VSDJq1bZ^$ry@mI5Plj-+Z4X$qWx zAi+Wfz2wijhgLZ9RXpEfS@6Kn5qMLxDL2o+Y(-^ZJ=!&LaUxxTH_a`1*ew};vHnZW z_~}_LUZa5}<01Ou9#Fj$YwZ${@k#S}Onmmz8#He>kpJMlb{LNAC&kCAv}|Xe6#7-} zQ~&u#s5iyg4(u3w{rmNq(vg13r&j)|83=h~ha6`3NYq%Pi2)~vjC<7EI^N%DlI-FF zt3yXUTr1xqr*|h;*2?Qk5@TYf;%iQ&_kTw}PUGAd2HK<3vfcR;e!BZ5TN}{FWObxT z&TzAMsrm@~skD&%hr3pI=Ol zqw63Sua0aN2TVPz9L>DVw06%Vi2ikE>1)=_D$!>a4>p?1wYVNFq!Ssly(g~LRT}dh zh>}O{RK=tQrk}o6Ai%-rE@47Y_A#0kgBVf}Xb=Dc+6E zY#W$bkDl4#baGJU&OTkEUCuuBgsc4vP_~~=#mce58^po*m8LkE)Q@?q7i30@bY&T5 zLO}*~ZvAFg004ikv?n$!CE=0^ph2s*sr;)SmaHUl4BXfcMq%Ht)MC>+4-!MuL#h@J|Xw6FI{t zTVmoucWbu~Ca#H2eU;pq*stB(H_iuphteq19t^g33x0Ko(ZlLKvjEf2HL7>B8a?Vu zJFne24RcpJ!M?ZbKbweJ^B3W7(RD|FE~y+ff_AU|m3@V68b*y)j^#@%WHL)%YqIoq zbt$4|fUlEJ_4;Ew<@nNVPZPPVJFeeM#6^if`78t~zUtOS3=4i@mgzSqQSVv=S`u?(Ux2H}E4k6rYQNYzr?K z;q~z(qI)B}Mx;J)*6yF~@Pr6NGUuPma+$+|lCoxF1sbWPhgB7S2};L^)$homryVBB z8vkrbRzA7Ca5)`OOR4s5j z7-dr~-iQk2sZw6IAyP+=b9iY7ZW5$E?bNG$&QNKQu}d2Jv8x;sHA)!mzIt01Fy8MD z{P|Ob&7WeLVhRLr^7Qu*3z@7)=<9Td;)j&an$s&qJCbjp$0wu9zWv9orC+gMowzz+ zoDrkew7;~mvfWZ-Odw3nY-578degNw#MBI{6^6B@WoD-b-QH@#hJ_87A-CGcN)|AT zDYmkEo||m)Cu|@AY+weMWhm4}jg({Hj-{t&XDS>xaPSu5LPNuiA!~THq z3IvOrNiA*+HgfGaQ-RjoIs0hht{z!~YV;?(b@-C0LIezB5^f9hxJgmq<9Du@0VdfZp2Ofu@SW>|8b{O6- z@dB`e24A#24v9|A&jq*Ky3g>>Q1r>ZZ$77{$D;oL7u)_K^ZZXyyv4B1o^PpP<7F0$ z4;*@hdSRXOIY!Gnjyyxp&6MRNhaE_>iHyEUJVMT)kF;RtK5Uq-&YF@jY=2IXs^haRWOaFegy^$)^NiQMW;I-D-%d!9dsi>Qx8hex*>XbNXFpJWu19ja+^fBUIq%R@kYi3E4CHWSpyJK#oJ?3y z8|pOCUM05Jc|Ppr`+^7}5v)g-3Z?`ZW84pn&Zv~G5*Yjl% zKYptZC)^yra6tqfnIw~D&&GLmGlz+yUTrYwfcVBP3K(98NnUf|mXFk)) zR!Xey&6Z5h@eQ+hxN&^{02hhi{{VxJ=Jn`ZUVo8fa9(VQ?mPICJqO-+=J2+Iq=InR z^vR99+?~U{%ZzJ{mmEVom3+W&HU`FN3t*=$^ukSTPK}Yf0VIbFkD0_t&^(d#!|k_x z?8C$E9$&ve$M9h#mPs)u;X9f`&;?hYYdes3_$+^aE8A;0$pIEUYpk(jYx1{qDQiBR z%j*9C1Ft}5HkL`UeLTz0^6&VQ>E?MoQ_uVx40COg^$s@i%$`e;I$O=6WDaoJ%wr!% z5wtO6(sW_cc}ESRWr46qnIviAz&>MqNe*0xUU{(TvKz7&XM{1~vN4Y{{}oWtK@Kl1U&E>_zv9Y1$rGFfcq29R0wi#?U$MBX!A3r!dYkYu}++R_a@? z zkjI$_6~|Y~LphssyfQjmgTc%w@<@2<3&4_A4n0a98+)E0J0Rx;wdx2@r#53@W;$#< zzi`70F%jsJSp}9!C6Y#%^XT`M&j*$N040qW@9H;WRuP`Q(BMz9$9%K_q%)=Gp7eCJujxYi>5qC9`>F{$9^Q^CnNHkK+FT4<3cn=r(PcWH`+3 z8zxzh;|O?V*L=>7!Yq#QXg(oMW8%bzh|&C#HKQeN? zT$sc`;>PAiZSGsk_YOl0dIUyhj*xqXQHQ^l0C#q9 zhM$Rbs{;3Cb1L|OJCU49w%$EhC$Cq~^=~oBvY(meLfp64KZtsh>$+$B9sd9i9-XJS zvzRU!m{W-3jl0G1WSI}WqhQXB+!)+5B@^a2c#KYagbpL)1vAZq=1l7MO_wPrGE9fw7d#R}b#kGXM@sG&4bf8^a$XGh$Z8T&o<4RS(bkX)b4!=j_maB z?tOfJGtj)*9ovj|Cp}4cj%HbJ44)EYId8PPIgyA*hD?4X=MkfGkP`F6I7cL5-HLAU zVVd(Ub0h~g9oY^WSC%r{--!4gbiBWD>I^W$>hMd9_n+Xu624c!5Vv#XUj@mPIDTN| zoD$4!_%I@_zj11(6M8aZ(<|VC&0tnQp7vNZo;Z_>1r zeLUVTB*(auA5Sy?01Eat5O{n-;w(l8d5M+ZRH)pwR_O-Tui6!QH^j-;{a^K+p05jT7W0DAYyEDUY zy_|6z_1rSeE=hP~@=8g@!DpXMZTEwSQ|jI{?g4d?&L@1rds`%zUZHbk=d`-(JThIk z(Pf`ud4Bx_MB3Soes3`zj|lP|e*{Ev$vjYaTV6tsZQA~v=#k$OK$xM;#^sw{X6rpi zOs?G{%-(0OSHwq0sXfehGve(lw~2A+yicQfyn6ZdZ!_Pgh>t$LFK<)$oyVB-7n}Vq p(GL9%rP_MD$3(^EJo+8XdN*stzK5bZml564duDw+-evm>|Jj { + runButton.disabled = false; +} + +let imgelement = document.getElementById("imgsrc"); +let inputelement = document.getElementById("fileinput"); +inputelement.addEventListener("change", (e) =>{ + imgelement.src = URL.createObjectURL(e.target.files[0]); +}, false); + +const modelZoo = [ + {name: 'squeezenet', url: 'https://webnnmodel.s3-us-west-2.amazonaws.com/image_classification/model/squeezenet1.1.onnx'}, + {name: 'mobilenetv2', url: 'https://webnnmodel.s3-us-west-2.amazonaws.com/image_classification/model/mobilenetv2-1.0.onnx'}, + {name: 'resnet50v1', url: 'https://webnnmodel.s3-us-west-2.amazonaws.com/image_classification/model/resnet50v1.onnx'}, + {name: 'resnet50v2', url: 'https://webnnmodel.s3-us-west-2.amazonaws.com/image_classification/model/resnet50v2.onnx'} +]; + +/************************* CONTROL PARAMETERS **************************/ + +// Record if the model have been loaded +let modelStatus = ['squeezenet', 'mobilenetv2', 'resnet50v1', 'resnet50v2']; +// The forward iterations set by user +let iterations = Number(document.querySelector('#iterations').value); +// Flag for first run +let initFlag = true; +// Count for iterations finished +let calIteration = 0; +// Number of top result to show +let topNum = 5; +// Save each forward time +let timeSum = []; +// Lables for image classification result +let labels; +// Top result to show +let classes; + +//Detect the click, init the UI and control parameters, +//check if the model have been loaded, then run the test. +function run(){ + initPara(); + let onnxmodel = document.getElementById("modelName").value; + let index = modelStatus.indexOf(onnxmodel); + if ( index != -1){ + modelInfo = getModelById(onnxmodel); + modelUrl = modelInfo.url; + onnxmodel += '.onnx'; + showModel.innerHTML = 'Model loading...'; + createFileFromUrl(onnxmodel, modelUrl, compute, modelState); + modelStatus.splice(index, 1); + } else{ + modelLoad.innerHTML = `${onnxmodel} has been loaded before.`; + compute(); + }; +} + +function getModelById(id){ + for(const modelInfo of modelZoo){ + if (id === modelInfo.name) { + return modelInfo; + }; + }; + return {}; +} + +//Init the UI and the control parameters. +function initPara(){ + iterations = Number(document.querySelector('#iterations').value); + calIteration = 0; + timeSum = []; + + testInfo.innerHTML = ''; + modelLoad.innerHTML = ''; + showModel.innerHTML = ''; + modelProgress.value = 0; + modelProgress.style.visibility = 'hidden'; + iterationProgress.style.visibility = 'hidden'; + showIterations.innerHTML = ''; + + if(initFlag){ + loadLables(); + initFlag = false; + }; +} + +//Load labels from the txt for the first run. +function loadLables(){ + let url = 'labels1000.txt'; + let request = new XMLHttpRequest(); + request.open('GET', url, true); + request.onload = function(ev) { + if (request.readyState ===4 ) { + if(request.status === 200) { + labels = request.response; + labels = labels.split('\n') + }; + }; + }; + request.send(); +} + +//The whole compute pipeline. +function compute (){ + let inputMat = imageToMat(); + let onnxmodel = document.getElementById("modelName").value + '.onnx'; + let net = cv.readNetFromONNX(onnxmodel); + console.log('Start inference...') + let input = cv.blobFromImage(inputMat, 1, new cv.Size(224, 224), new cv.Scalar(0,0,0)); + net.setInput(input); + + eachForward(net); +} + +//Excute forward function one by one, update the UI during each forward. +async function eachForward(net){ + let start = performance.now(); + let result =await excute(net); + let end = performance.now(); + + classes = getTopClasses(result); + let delta = end - start; + console.log(`Iterations: ${calIteration+1} / ${iterations+1}, inference time: ${delta}ms`); + printResult(classes); + timeSum.push(delta); + iterationState(); + ++calIteration; + + if(calIterationBuild type: ${document.getElementById("title").innerHTML.split(/[()]/)[1]}
+ Model: ${document.getElementById("modelName").value}
+ Inference Time: ${finalResult.mean.toFixed(2)}`; + if(iterations != 1){ + testInfo.innerHTML += ` ± ${finalResult.std.toFixed(2)} [ms]

`; + } else{ + testInfo.innerHTML += ` [ms]

`; + }; + testInfo.innerHTML += `label1: ${classes[0].label}, probability: ${classes[0].prob}%
+ label2: ${classes[1].label}, probability: ${classes[1].prob}%
+ label3: ${classes[2].label}, probability: ${classes[2].prob}%
+ label4: ${classes[3].label}, probability: ${classes[3].prob}%
+ label5: ${classes[4].label}, probability: ${classes[4].prob}%` ; +} + +//Load the file from the filesystem. +function createFileFromUrl(path, url, callback, onprogress){ + let request = new XMLHttpRequest(); + request.open('GET', url, true); + request.responseType = 'arraybuffer'; + request.onload = function(ev) { + if (request.readyState === 4) { + if (request.status === 200) { + let data = new Uint8Array(request.response); + cv.FS_createDataFile('/', path, data, true, false, false); + showModel.innerHTML = 'Model loaded.'; + callback(); + } else { + console.log('Failed to load ' + url + ' status: ' + request.status); + } + } + }; + request.send(); + request.onprogress = onprogress; +}; + +//Show the model status when load the model. +function modelState(ev){ + modelProgress.style.visibility = 'visible'; + let totalSize = ev.total / (1000 * 1000); + let loadedSize = ev.loaded / (1000 * 1000); + let percentComplete = ev.loaded / ev.total * 100; + modelLoad.innerHTML = `${loadedSize.toFixed(2)}/${totalSize.toFixed(2)}MB ${percentComplete.toFixed(2)}%`; + modelProgress.value = percentComplete; +} + +//Add softmax layer to gengerate the probility. +function softmax(arr) { + const C = Math.max(...arr); + const d = arr.map((y) => Math.exp(y - C)).reduce((a, b) => a + b); + return arr.map((value, index) => { + return Math.exp(value - C) / d; + }) +} + +//Find the top num labels from the forward result. +function getTopClasses(mat) { + let initdata = mat.data32F; + initdata = softmax(initdata); + let probs = Array.from(initdata); + let indexes = probs.map((prob, index) => [prob, index]); + let sorted = indexes.sort((a, b) => { + if (a[0] === b[0]) {return 0;} + return a[0] < b[0] ? -1 : 1; + }); + sorted.reverse(); + let classes = []; + for (let i = 0; i < topNum; ++i) { + let prob = sorted[i][0]; + let index = sorted[i][1]; + let c = { + label: labels[index], + prob: (prob * 100).toFixed(2) + } + classes.push(c); + } + return classes; +} + +//Print each inference result in the console. +function printResult(classes){ + for (let i = 0; i < topNum; ++i){ + console.log(`label: ${classes[i].label}, probability: ${classes[i].prob}%`) + } +} + +//Generate the summarize result from the collect time. +function summarize(results) { + if (results.length !== 0) { + // remove first run, which is regarded as "warming up" execution + results.shift(); + let d = results.reduce((d, v) => { + d.sum += v; + d.sum2 += v * v; + return d; + }, { + sum: 0, + sum2: 0 + }); + let mean = d.sum / results.length; + let std = Math.sqrt((d.sum2 - results.length * mean * mean) / (results.length - 1)); + return { + mean: mean, + std: std + }; + } else { + return null; + }; +} diff --git a/dnn/scalar.html b/dnn/scalar.html new file mode 100644 index 0000000..7fe8ca6 --- /dev/null +++ b/dnn/scalar.html @@ -0,0 +1,49 @@ + + + + + + OpenCV.js Image Classification Example + + + + + +

OpenCV.js Image Classification Example (Scalar)

+ +
+

Model

+ +

+ + +
+ +
+

Iterations

+ +
+ + +
+ No image +
test image +
+ + +
+ + + + + + + + + + diff --git a/dnn/simd.html b/dnn/simd.html new file mode 100644 index 0000000..67a436b --- /dev/null +++ b/dnn/simd.html @@ -0,0 +1,49 @@ + + + + + + OpenCV.js Image Classification Example + + + + + +

OpenCV.js Image Classification Example (SIMD)

+ +
+

Model

+ +

+ + +
+ +
+

Iterations

+ +
+ + +
+ No image +
test image +
+ + +
+ + + + + + + + + + diff --git a/dnn/thread.html b/dnn/thread.html new file mode 100644 index 0000000..152fca1 --- /dev/null +++ b/dnn/thread.html @@ -0,0 +1,50 @@ + + + + + + OpenCV.js Image Classification Example + + + + + +

OpenCV.js Image Classification Example (Threads)

+ +
+

Model

+ +

+ + +
+ +
+

Iterations

+ +
+ + +
+ No image +
test image +
+ + +
+ + + + + + + + + + + diff --git a/dnn/thread_simd.html b/dnn/thread_simd.html new file mode 100644 index 0000000..9892c7f --- /dev/null +++ b/dnn/thread_simd.html @@ -0,0 +1,50 @@ + + + + + + OpenCV.js Image Classification Example + + + + + +

OpenCV.js Image Classification Example (Threads_SIMD)

+ +
+

Model

+ +

+ + +
+ +
+

Iterations

+ +
+ + +
+ No image +
test image +
+ + +
+ + + + + + + + + + +