From ed7926b766bede6f4758e76e1b299ddcb922ea83 Mon Sep 17 00:00:00 2001 From: agisga <11449372+agisga@users.noreply.github.com> Date: Mon, 18 Mar 2024 17:17:06 -0400 Subject: [PATCH] docs update --- docs/build/doctrees/about_link.doctree | Bin 54162 -> 54162 bytes docs/build/doctrees/domid.algos.doctree | Bin 35073 -> 42317 bytes docs/build/doctrees/domid.compos.doctree | Bin 180666 -> 191182 bytes docs/build/doctrees/domid.doctree | Bin 7739 -> 16935 bytes docs/build/doctrees/domid.models.doctree | Bin 130289 -> 35865 bytes docs/build/doctrees/domid.tasks.doctree | Bin 104312 -> 103583 bytes docs/build/doctrees/domid.tests.doctree | Bin 42340 -> 52448 bytes docs/build/doctrees/domid.trainers.doctree | Bin 89765 -> 88621 bytes docs/build/doctrees/environment.pickle | Bin 583854 -> 595179 bytes docs/build/doctrees/readme_link.doctree | Bin 569649 -> 582120 bytes .../html/_modules/domid/algos/builder_ae.html | 37 +- .../_modules/domid/algos/builder_dec.html | 37 +- .../_modules/domid/algos/builder_m2yd.html | 21 +- .../_modules/domid/algos/builder_sdcn.html | 38 +- .../_modules/domid/algos/builder_vade.html | 39 +- .../build/html/_modules/domid/arg_parser.html | 5 +- .../html/_modules/domid/compos/cnn_AE.html | 10 +- .../html/_modules/domid/compos/cnn_VAE.html | 11 +- .../html/_modules/domid/compos/linear_AE.html | 13 +- .../_modules/domid/compos/linear_VAE.html | 8 + .../_modules/domid/compos/predict_basic.html | 20 +- .../domid/compos/tensorboard_fun.html | 77 ++- .../dsets/a_dset_mnist_color_rgb_solo.html | 2 +- .../html/_modules/domid/dsets/make_graph.html | 16 +- .../domid/models/a_model_cluster.html | 80 ++- .../html/_modules/domid/models/model_ae.html | 260 ++++---- .../html/_modules/domid/models/model_dec.html | 330 +++++------ .../_modules/domid/models/model_m2yd.html | 218 +++---- .../_modules/domid/models/model_sdcn.html | 466 +++++++-------- .../_modules/domid/models/model_vade.html | 505 ++++++++-------- .../domid/tasks/task_mnist_color.html | 4 +- .../html/_modules/domid/tasks/task_wsi.html | 14 +- .../html/_modules/domid/tests/test_graph.html | 40 +- .../_modules/domid/tests/test_losses.html | 48 +- .../domid/tests/test_mnist_dataset.html | 7 +- .../domid/tests/test_model_builder.html | 60 +- .../domid/tests/test_model_trainer.html | 212 ++++--- .../domid/trainers/pretraining_GMM.html | 3 +- .../domid/trainers/pretraining_KMeans.html | 2 +- .../domid/trainers/pretraining_sdcn.html | 15 +- .../_modules/domid/trainers/trainer_ae.html | 49 +- .../domid/trainers/trainer_cluster.html | 41 +- .../_modules/domid/trainers/trainer_sdcn.html | 70 ++- .../html/_modules/domid/utils/storing.html | 20 +- docs/build/html/_modules/index.html | 4 + docs/build/html/_sources/domid.algos.rst.txt | 8 + docs/build/html/_sources/domid.rst.txt | 8 + docs/build/html/_sources/domid.tests.rst.txt | 8 + .../html/_sources/domid.trainers.rst.txt | 8 + docs/build/html/domid.algos.html | 51 ++ docs/build/html/domid.compos.html | 64 ++ docs/build/html/domid.html | 144 +++-- docs/build/html/domid.models.html | 555 ++---------------- docs/build/html/domid.tasks.html | 10 +- docs/build/html/domid.tests.html | 85 ++- docs/build/html/domid.trainers.html | 148 +++-- docs/build/html/genindex.html | 236 ++++---- docs/build/html/index.html | 2 + docs/build/html/modules.html | 7 + docs/build/html/objects.inv | Bin 8867 -> 8749 bytes docs/build/html/py-modindex.html | 20 + docs/build/html/searchindex.js | 2 +- docs/domid.algos.rst | 8 + docs/domid.rst | 8 + docs/domid.tests.rst | 8 + docs/domid.trainers.rst | 8 + domid/mk_exp.py | 1 - 67 files changed, 2118 insertions(+), 2053 deletions(-) diff --git a/docs/build/doctrees/about_link.doctree b/docs/build/doctrees/about_link.doctree index a01fb06200fd370188d544c3aa822caf6ee95be1..d42a181f5567dbe419d6b24ec808164b40d57950 100644 GIT binary patch delta 1262 zcmY+CT}TvB6vub`*!5%SA=7GC%c8I_w#+{415L;bj0|6bL}hgb-Rpkn?hZw%8-eE9 znCsrrGR*xlrO--72&0czv!aYxsR&~2#iR%6MS`GnXJ)VUa_%|5|K0OH=g#`a6aC|f zkLx=<$>w?o?-qq*)?u@-qL411Cb!wu>;h`Bv)m<7(AgX;Z{>ifI`6hv*DBV_pTnjT;=c7NV|G$`ZHJY_W6BwF}_Hk=AMQV0BiDy%}7coSC(8 z@k*VMbGfD5uG|D;RIAaHmwxKVe|tq(Krvc%q&4B{?&1of_ldiNbQ|YxaokYcenSb3IXMf4kfi~d096strO!{574F;SfFEn#A~*;@#C zz*`M@z?+3<`?GLf&yif>hYUIhWEPYM880Nc9SttA9sHvBYR^0qm8x!}GjP-jIpk>T zHNt_-g9Z52&1E^ukY@WB0_S`Wz=H1&K+N>7Kr|0#NCvEDAgvV&@dfb*WNp3sFh8)& z#3b`zHj&^Kp6%O$AKhAnYRvSf_i|b zgG9O*EQL4|EQYumEP+@QIt;NTbR3483>{3BUu!*l4RA5&Py=Kzmp;4$^n&nCovbf1 zxHz;~hh`FFwLN?Y)amd6h)d!95VIrY|8+9r>k-mnB61SqN~G+cJ_dY#GzVyVcq0}@ zD?MZz^{0){BKqky{T?~eF{{Ui8yG|c8MPJFkT|n zbczDibeaOy^a%y3=~D_+)8_=pkM{yHSj{NEEZLR3HUQwog+Etz-l-dVDnt$`GWMV8Qxe(g*2_1VQJ{%--tDx##@Ox#xfGnej~|`zDf~ zHTP`MSZu7z%sB);m9<$+EcW(fyPcfF2}Eb-I$b6^XW^_Q++=LFxtvXAleJyo)1_*I z)97f2loGKHjudWIa(1K1%GpUH8MN3e9X1G4rAG9Y(cCIgla=MJ0k!9FM%Kb9Ldsnj zlQWA2y#-17xLT#EuKd)tb$02S8pUX|tS!X#edRSIKPVLQ=@!n}W@8wV%_a@298EPpB!BSdN{Dr zUxMGmd=TFZ z>`@cUZ^xZ{CVm|#gTzMQ0@$kH#T1glA9iKp$)EvHELb5`BOl%!)#Fnk9l-M;lDZnI z1UnZh2fGof09zJ54z?qF8itz+AJt0R+6JEhRB|<_1w5Eb7b%2%No21^%C9iEJiJ4L z=8~jrcjOpkXCg?RND~n} zX!4fIypv_#CjfaHT1-SpnPQ0oWs2o8N|Y%+Q=m-og#u-YxCF3w{N&$1`Q!K*`6rBt JITP0p`~mXay6pe} diff --git a/docs/build/doctrees/domid.algos.doctree b/docs/build/doctrees/domid.algos.doctree index 74c6ed908767afbcfda6eac0a6e070e33b7aa466..90f06fe50b6fb66aee3f888e42eb9122c7e71c8a 100644 GIT binary patch delta 4361 zcmb_fT})e59H)0HY;9pMMje!r%NV3(qZZh*@*!JcUs(s)#x@s)l$Kt0?_Ft2KXe7P zj={*1J9VDxi!US^-GeVK_+pGPCW}ij&g?~BX5t?3MYE3wO^h+|f6lod9o%+bzTBSv z&-s7<|G)D;7v5)nSZ2&`n?LCPksw*JlkrF<%E^4$ zsLb1?)u&1xJvA?1kl&PDyhCiUpsIiu{Wu-)IjM*qc9jOoDogcrzist4>YHg`q+wLG zcl$;#h#p7&z0REWPv#qjGGVdTR8r!mn$6OlaXuu(*!TpS~={ausH9LHN1oPBsMb;n7uRkeRTcV}o8MhMjPt#X&o!n1q(fSr8b;?$q<^c&8LA zmKslCjgYl~DHGL9sCh6Sg4sm0D)hf^HpdK2u|ucUf$QhUQDf4)_5^_;ljcA9#iT zUXsP#>J~2aH+ZL(X|O72LG2+2VtY2#*7k=|T&kPxPGq~sqoGu)dn_Inq2bX~kCS<5 zLGSg{AK1KRcZ>u|JPJzGjEMh$Vg&_DsSH_<)W6W#!$+9Eag-X+m0kx^WR@mc?%uN?z+JJuFw`ilU~)b@xJhVT zd1$pkbxjSrPS7KIz>1N`=C{(+LPfp)jNq)9rK0rzhhsGcKsJI)!Aaojj8%iLli$PHp%N0X73T*`B zJ_Ls;$bAGWso3=+>G@xvI4Ct2G;Ui`%csjNt5`XV%Y=?3eOAEAz2$wFLT+^&i3eLc z&^vXd_9bl9pBTKpz^lLL3MEEZ2I|{CI*>b&Ap12FU zl(ETUY{r_NRGpOO*LFv*mh~b~QAiQGYj4c?3Z@}hfX_uxc5Tnw3;9E*6XWd)F7HCR zMFC-1%d3&g`XK!bE-OQv4i9GH3`MED!6T2FH{KAcLxnVjRmZaxy>;*Et@{gJwwCKo ziFfka_MnzPy={x(Z-E$-CSImZeB-H_*lJUoxEfZ)o7gyooUFEVXI?G!4LtftC{#>( zgWthvrwx7+H@E{W?x@He6eid-&#{>lmt<23Zd{nivY{BOwl15}(}qE6BbjuZAPIfDe`k46nS02v2<%RDf27X7Ph$Ud+S_@sJ* zNo_a?sWvDyWd&C^ejRgs6FiTbN8vGRh+U}B(QNXfdmRl(obF_fVK=>%gP@RtF2579 zFb&E46|rk+Vj@Ry0R=b^feo5n(b;ig4c)e zX9|B}@X1IUV<8x6vI#DQU*lrdhR)A6Z^1_|lVg`Nd?Vff8K2FbVpeSEc6k^@E_#{Y zY^eQG9s2y@HcX8-bEs?1r&6!X5$g51MU@hrS129m_tS0Y{`@|=(~G&U&vl?*qr1^h zm)upv!X^l$h@&YgYFZbzZCC-Tj0fO=-p@)cV*$$KI*P^MhnLt3RUzV=T)crl7#v6# eL>yj-AbhAg2BP`y9E(jGS~v|sUix(5Rnvd7;pprD delta 282 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

h^v$<_Qd!hiA+UIMx(AFexg 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 delta 17874 zcmaKUcVJaT_CIq#Lm)2@g@ja6NO^hbFTID}%OXuc2rC#KQepy%N>fy-lnaavCCh?J z5fEJ#ktV{riW;P-sEDE>0#aNA{Zf9X+Z!w;pf4 zdH=6^SEfoeF8&&%`zW=?*nYK(9tdj3*6r6o={?yh(AagNslHXCn(7nTD%806+d>^N zMHLvY|DLp>AKa-IPf;dbZYI9gTows)GU<;s6~qeiL` z{WDhG7Tnk~B~(`{$bjjgM)f#1ObInITO=4G*5Brbjg5X^Rq7G`%3r_zsA{RN z&wxPvT65LZ*!*!K7@@|J`wJZpn0-c zQ&C2A^I*6$%-9>2pyH*bd}gq^Q*Ugk5|x{3B8`)wnbc?2b3A^(AT?U`^ip>f>bq@f z=o+T?E>Web%1e%&O!B_7RR=Z8OFm7=7kSC2g{_EHxoV}C8v6*fv87jXKtnwmvu;*3 z_N)%o8Ld?~JP>Ncyb=oILybdc%8ILQ_uLNX3aiP)epLD(%zS-vnaAI1nq1|odX#N~ zri|*Ls=_@J(acN3_2wh0gI3y*`qKAmC>#$nzNrpZU+TThRg~WRxk^=^=_M^x zTfJxwj{ifL(eIt?03N1P`0JNKR4LLMb#r6&$#%+5H*KTF!-ru;b>|BG&o*i%l`F0$ z>o@1A*PvB6`2n;H*D<{zT~8`kO^m)bvh~E(=qbCy)OK)%vp*z;vp>Xzi$8Rb+A_PA z{b8uo4zg?6A8Mp_qFqb=0Q05xsc`ZIcsAUa73hYi!u4w{RRX*mZd5vY;Vat#2PG$f zJwo!fkbER0Z-=w-;Y%UGMlv0ekm2EqkX%9z|K zkt3FPilrUM)3Ws3cFGA|BM4QC#t^!z7l#>M;Ke$IblMCQSFS^8dy2E6u_gX~{{RzPL{L z!MF$p?z{g_jjOp zG#$%&iBkDGDhrqChF*{d3vdp&dgesxUZC!yMH8f->kU2OZ#ZQH(HA3m(L5iiW3pAU zV-CrV;EnctF4D)hx*!jBsmCM#;8O3=j2KMnBgv)uJDwvh;!RH=m!;tt@kYQ2Qm@

e3l0}Ir0NQ=^Y?}8^FgBnwek-2^j7k0q809rI9iaCX0r;WJnw(U*nsDU39NfHHpfEhG$CEK6n}1DeP{F;;{R26ouW}A4BO@N9l@k zwHMxv;?TMphcPX=4`W(=U-%@7T%mtl!VpQQM?vjL|yle*Y%TCxE))MkbQYM zL`7qXUaiN%7l!1xXm4m8FjtKD9uA8sMN~f(b19>BCJQB^0@?f+$iso8n=q;Ub=e8!A zZEi%1n{16{H!-jl-2_S4O%4jldqQ$tNZyNLdHQtQg+cbrdRmBdWhJ6>4uwf90YHlE0{N zUaI?qYN}A(7sEcIo)WVAEHVzx_oB_sWj7_7e5T5H-^)#psKjp^#n)cTdM~^!hG_qO@`Dd^Lo` zO0>H(miyzM*M2U>jd9&QXn~fo4Z7T`WN{0A2v#LgRy4+ z(cE7zAA(r%?@KXU(3|g3@i5AVXv1GscUWo?JuQRapMYO7)YCG^e4qXtvUiyMw@LqP zu^h71HX(R}3DkFF)3$o%7}XrUiJ_>W>bc68f$Gh$m*^W-a5)IBjO8W8*kjkD(rs zp7=O#W;#7iyx?J+A7-Wx$8lz=9;OLo!-H`gW5>ivwEk70=14AIR9h)w5Dp-&JL)b_|+08%}3m7y66=ZLooI;XMt=Uu!4n>_^gx zvfLbBH>sCYcJsE+r78QYh`<%fDN%CzfN(e2wR5$IPj)KA}OR+$XIZDfb|A1iU%%94RT8RVTRFh{i~H zJb^LqIBte1pT$>-l%FPW=sS|&&1d}*1tc3MGC|`+$!GBu2~;Dk7UEvIZ|f#{u@kdG zladqL43jcNC{q$8vBg)SbpCfr&TxmAlmmovK%!1hRrjbc>)(=#-QIA44f5K72|gjt`&WaF_t&sxm`q8iBN*KHmmmzHb#~ zx|r@pVf!DFVm)sOZm2WDu3O=^5WZ*cpX9#uftm;N}@4xM-#_6TaTWbs43jp zQRHo*Kgz~4l5>gdu%{Dkhi&b3*pwv8VY79=H3b~ z()III`xP&vh9z4Vdo$kFs z6~Shi`bL@hq9j~Ft@W4GvL{K0Zp6Ru{ArNJxNF@dgKU&R9OfX@f?{x5ULbUomY->8 z1$+1K6OJj~ah6K#9cPnF@9^#(j`~Dw+C5ye34gN*e-lE?#4(=_hQ(3(*-h#QG<8ab zew$O*ZB`m?b8?10Ym4$wnSedyb*wLN%1)xf$vcSxr@fQNaq5pVAXiU%Tb1f;a(?&2ZwLV*Keq&;9(~_=oBY!9v;AcWx@LEH_-`}O3Tv? zTDrqJsa$JS>W{uv-F46!j21|{xko7+mmbHg9vp>z2IhmH@_#F5W6v0;B)~aNcK8ew zpm)5nc~YRBxm|^1k3mUfqv@B7C3>}@FqN$+Jb(li-_JrdSy;`HzMS z=l+Nwu`wJ8Vj@q5p`-Wzr*qM6 z^#q~{c8)UY>q1mA+p03zwiO=tb0d9gnAV`RJMPHrhUHcR+e~fowrsRo$bjnK-iG~l z107)WMjMzBb|i|AC&g&QWIcYLa;x4tbGr(IuF19mFYZ$f<^j~~gwIHj~!YeP+3Tp}mW3QidJr;4=khV5+Lrq`27O z6J7sHU-y#?tgl*^=eTRlp%K>x!m-e`F?@sBRYQx3eUn!;3< z{^qEfs^;4S!H#*tlOS@cYugLQ5OrXsiy2T1=&BNHRt}j9K%N z9Zqi@>d~_F2^x(p{WX=?(qFTsY0cTkrdb3F!f*iM8shUgoAA6%cwPt*b1CeneC5U8 zcfLYR+@8Ytt7q?`{p|V>tgsOnQW$|(oKXdO_}6Lx9`EnnjT_?nWl;`Du?LS$ArKDJ ztxu{HmC0S$t^Uvl;W${YI;pBv7wVG@9a6-nQgqC>*fj4Om90id)6j-Z-PMCqTVvM} zDyv0OJKw71)%~(muC^=bgI~kRYPC;|YwU5SNRkA)ZXYh}8(v3cWOk!?;+{vSM6VVy zQ`ti1SS*|FddqfK^ON7_DT2(WQrNq`r-_-!{0%Cd4kj<8uy^qg>|Ho3PLZ;`pzwK$ zFFunsnk_R2J(gm@^rPyS-n$FGS!A418z3r`)1|OfUxW_V#k $q0~>%7HO6m5q>^ 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 E0b9LT5&!@I diff --git a/docs/build/doctrees/domid.doctree b/docs/build/doctrees/domid.doctree index 08ae700b9594b86c2181f60baa25c2af92c657a3..482a123e6b24e797917642788ee9118c8420ddf3 100644 GIT binary patch literal 16935 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 b4ckOj2xu%5T%3gcsUtpuu;LR!FXsOrP}aZQ literal 130289 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 delta 9587 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 G^#23Id}5ve delta 5764 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 diff --git a/docs/build/doctrees/domid.trainers.doctree b/docs/build/doctrees/domid.trainers.doctree index 837b6a717bef0c283cdad58fb4552df200a04a14..7bfd306e2a86231ad762ba200c16821efb9ae826 100644 GIT binary patch delta 12172 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 XtM7H%Qs^(AFRFFS^FJ&Wd)faFJb#ZE literal 583854 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 z zbI=!*bt&2;&3!oI+3xEWA%ggcL_2z+b`(n95Z;((M8D)W5-+EhH>GgZnbb;-GWnJ@ zX40bMGx^i0RMnYuc)3izJ%tNL5xOMf#^9Yu=as&`bQkKGbuK9Wz>wda=p~zv1SGGP z_oVsI+c_g-YUZ@^z7%al4z-qp9RB=TbErY`IedRA(})}zxLgi@F+~f<0q6jFo#h}u zzl=0qnTKP2^?maIR-)woOOW!zi6+9D6erGW;G?O`deKLhaRP(a8m7X5>nBo-uw)Yq z+(bCiT3ib9^XWCC+pN#8% z9f`g24D}Es<3Uk^V00Jg;eV2SFsKXba2ZIxe19v|hd%S5^-&53Z-Y86mhk^gF~jjj zDW;sS!znXvq6V4%N(xz1Oa*yFZOjIke~@D8g}_l+w_@^n&kiOtu?GG)h1RFA>p@f8 zGVK4AVuy2h?~!@&Oyo~Q|2GnQ<`-H{ln^)XdV|IO)FPZyv>wI|a#*XsMmgeYaJF9! z0&RaiKA9h1|t= z74E(3_Jc9>-!nHstvaZ(GA_Ez<>=fKYRc`d6)Fq=X=tjojEy5b7M^<)^>XHbLE)JbzMFc+k9>v@MKh1A19 z@QXsh^Ok#S{XJ()7r2l_m#G4But1+*0@y-KeK;h9uY@b}><+(Wp| z89-c1=0WAxbM{dv`FeCiniqY)WF(&U%ep+*X_==?{8s9jDRSB@^69!Dd$)udN}EM_ z>~1&uaCtG&XZWl{GikFJq|R&P_Ec`Yi{)#CkNg=a)KY!FJBz1z=38A{oSyFDT_In# zJ5o@+;OBwj9kd|PvqN3zkzJTTgy55UKDWJzCiL7QpEj?D1F6XRsF6YmdPS6n7=iST z%F}``&~w9_=<#nY98qquGz(8g^H}H&)q03B#^cUlC^$mO=JMjQjIURE%dPH0dp0V! z`*REex7ec?sADw??P;9&>0nE23SO9l!g@iD#hrc&I*Nrl`HVS2XF$iqE%yjW!05po zqoBukj-;IP`s}6?A0;6)<`0JWRZB!2E1qXH|eWUx$-Y zt%aklWjqETQpX2q=pcO}Kuivy!^vE>iJ%kZTb&aK`SpVBeeK>Sdl-RPlT7Cw&Q$deukIvvbLkDik;DFQpVgEh@6nP{LT=n@9{cMUfLSein z!DmqdnD?eIdPG?!5Eh5!o?nXfb19adE5ul`dQY$HevW>D$>V{e9t#BkGwxij6#55{ z(5v721XG+uS)F$nSJHlvOoO_q&o`7N&l}!{(!A>h@N%G>FH~P4A4xHD#sYQNyy4iQ zad++`eJn-Fm2w^_GQ3ZwSbEQ`Jg4P0^O+QFWC3Ii`SU5zC2H^)h~*z!76bTIr1Oj? z=ZKVPl!nERxUbkRl51c-VJ9KHOFe}9NWYQFpHpinOW^t2NBiv*O)p6#+Hg73#$)_> z`*^>T;^hn|k}hwIzn5a=%sRq~HVdWf{xC(Vq5iD-{7DL>S5Z@iWm~VW5+H89au(>H z3YT2`IZ}?WKsjx_pW_SvD7d8lOY$9QfgwP?3HwH>f?OF#Q28?cn-nW&&1G0olk@i} znw~)gg%hETYF_^-Ma@}HgqpRUQx2dI!kKS44ihLNK9ustk zQhRzKaYK93Yak;;q?J}!)QeKwk-k}di)>4NBP-C0aj|6KaU3bi86@{?K`+YZ6Nc)N zqX65s1{OU_VFJTAZojC0UW-&$C1s#;niW`kIrVWDM2C?9-lFEYYfwd*eJ|zU#}GU< z_CXH$_O%OM*^(YfwZ3~i78TXtSjt47H1G-_K4~Bp{C!C2S#a8Jm{isp;?o8K^ZgVc zFx|A#C`BqO`5z=`+)L{1z)Zdp3AHal-&TJp2dVezYC%?(^(%=UwsQIsYHjR_LjK_t zJsreYC1*RmAC>G!&0RWn@=sex@&4aP=UGXHZS2f2XxLWCHn5I#>?9{Hc!By5MsGZ` zQDzmdmpnwxO*(c;@zMt14LPWE?36-PTER~eHMD|EWr!6f{bxn#zd1!shdUx^w&dR` zS&d3wA1(2W(>q!s1^+fA^9o+iE5Zb}-g&!_lK36u85Fyoij}7?EA)4X_)($jy@d+2 zw8(!p2bA{P+!i&)h-_64Zr)4Gu)tFz${|)1_s^x6dgCg}Znm_4L2?N@}Qu^Tx3onhs!J71qP!2+R5M|PWb%1d@098uLXK}QBLFn`F?YhDpi`)HIdK$ z%Q^ODcIHY&Ly0akzVUp--_0TFQ+7#)l!Y0@AbY=`!!gZig=EgBoiEiN<2ijBqxzNvK$@!lv?v=0Pq?cvl38}H1am*OY#>vNz6F03{DD938#F+1?v8*9Hg0a zjE0oDWxdV?$luH%XVk`x73&+$&+XraYBM7#PbfcW?8MDS`iGn-nPLd=l+hdKY(CsS z=it)HqqZGNJ+AqPkHHgRNxPahk{Lv9)CFpPTn?&C?fT8&0N@M&c-C5$FP*fynOT<; z#`KYKK^jC+ytLfbYg!=SIXTc#VtSy$CqO(ehiFDNHN+G|@v-F>>V-K}eR7)O=q^_k zYMOb~ZKc9qoP*Vmn5_*qk@$%@XftW7E3w@Op(i$9A5YGq>$CME1kZZv^0A+m!@gCI zoJLEIb)eL{S0Ma`9E18M;>I8W>eF+mW{^HwY=!F1a!GG9k;62DNMZ&OT!XK@+HM*O z^PaXTOumytPgq*#bfZ;l36q)?m6D{sYnK3KJLL@q(MGK`kdjffNOnCT!+DCSAayWJ zrh`LP0(@f%Y+AEAz{XRQuf>~FNHadkK`QS-fdX#@f>(s5pDa&ZS`<4eOHdRy=qgkX zEMFSC(;S*Mr6z27f!vj1o54#>Y}Ne2ZBwAr=cKr1xjl!=0{}t#{YdYXiRqon()uOh zA2Jc6yN9v_rBY?gau(qp=Om7B`Eog!=Fu$T)s-{yMdaJ{^HTKZR2WlM>A#VM{?HI9o{mqw&g z>qf&bq#sC8FN>NRBW==H|6fS!6>vO|@zX`31Q~ldMF>ha9>`Q6<%{;wG*@fE%$Dmg z#Wa(WSpU)}A5v6(x1yxZzB&ahYX)+lxmx?$6!P4#L<8;r7(Vw3QLp%`_uH)}6m2nd zo>KfonBY={9VQTuCVrwfQmA+VRCft!QhRAY7``c&Hef5)L82x|lD;LBRUgGr4E;ob z6B1wUpC<3XHgz*rjgeTTNb`1rWrx=z&~h$9d@0|V0_##}QocI{(=CDr z<~&pwW0JJ*L0Zq4^zbd4F6SyEz4i=n;(JxAUrf^@%}=q51jC}~~~A5P`f`x;6QF-T7SkER%U#8!ggJFW07_!B9R zUb`*h+Yd2fr8Tb6@2Tgex>*={HEiEKOp@N33S$e zaV?wi$1wNhxi5>8gW~J_`gadmZwvH+;9~#U#aed#qNw^`Q*2Y-R)xKnKC}?O~&Wn>?1bFnu>v3yg@ z#qNk=`Rgig^PVp6w7BHT=U9`-WzqX&xm4q!Oz7$FN)<2E*E<&iskJZ7yHI2mbV&Q?5Cnwp1yXmpLMaaQO-lw zF80@>SRR3PvEPVdd9c;Ru0LosDabtP=wh2uERT`7*ga7!j}N)nnJAWLOkC{uN3lGT z;9_4D#d5RX#r}wkwfp)mb~TFS=DUl1YZS}~BZ0+(~k= zXQ4~b{esBMm1h@wu8WoR6D}^h*vq3>E_u4x>!MgLzPZ@FQ7l(xT1s zrs!f{6UA~0;$mOtVr5Lp`G$-AsVJ5sd>8wkD3;?<7yHXmEJt51_P3%~_UblPxnvri z+Q%bG&L@-d6?N(Wz9K;!o`vH_vx`f7qJkcxjB}~e^@AP!67AB6pfqMV(p8n!d<-lnPUk}&g?T<%};VDb?K?km#iZ5eMHatVU z>@vSPJZ+Dl)45Zzj5HEotnjZR2wt)J^3|zVtPUTKbvq>oq&_xjf6aZl=;O1ADDCiU zHGpZ9qrb#MKYf6gqNnFpi`N_e`!a^I~unM~E8eWiz8D78}U_|T8HxBC00ryl3H$CGe zix8g>L>g|xi+1hyP<_}ZSyd*kOjLS6EnPktK3y^+$PV% zWnzXG&@EC5ccIN`zk`e3a3I0Qk)#~fd6eP0dtEg2{^Tt-ou_uASxH~K8kSI2ZfDx` ziWv;?KZ!{VpK4<^W=lbDHxUf-%IB5MdYQ=l!QwE zCP|+!lP5Uoy&_QQ-pX`QVO%a{f%`zchni>vvo(vZ@YYnbu82T`!f^FVaMxVF8WDJ= zkOa7XEsJ%KD>$WtOiWo_i$QaxsX#L^Wi{@JQQrL`7O<*%rw!YcwScL0uT}API6TWI z4bR%i_O`KmabeHQDk|=JWm^_NB|`Q4H5eA+H$?HJ##DSjEZA#6y=M7}7$vYC+e|RK z#V--3yeeNFLzUP{@nPcRD|C{nj17qLijPUA^3^&)$rQRm`IMmKEBBM){KVy7e2%H3 zDt@V6u4DCyXm?5JOW7aLkb+>(yK5?^2;C*O-^6 zuU({en@yX(#FN2?(&@QaGhDx4Bx~SM4Bmgkff1y;+DjM1C%!htODDZ-77RwEj{R&( zYI@i#7$Ef(nz!;3=!#W-yTav)(NHZ_PKHsM+7zl^(C5X-s|8U|+>d*nu)Zw*fQ4>K zM!p?Z6iy3U9p8BHTh{{5 z>aFp)DmT=JB|?0DG%f?SLYe^=_VNt)(YOpaG}8>YHkfC?k30q&Yp6(Laz!y)v7VV= z=;{@FeC=U8Pkm}zpxaon7W#TE7@(%yH8vQYpXuT@^U45^a`Kfbfu_UPf&rkftqaX7 zLzJ~e*RKLYr>_MAz}#F529_wtpuPM$1Evetf&t+690y!B%k<+~FaY>PC9}b>SNG4 zdGMLX#dKC9xcKgRa9vbqgS(SMeOf>RL?3#bo?gp-G%|NKv*W!xQxrAe)BJNyOA|zW zEC|hw_AxDrx)y8-255WlJ~7DNDGOmim(T?RusCpnSlIUjg#-OU7Yr&o5ZxOz(Pr^~ zt!4UqE*KzXrV<8<)hXlb(d%=;01#%n=GjsfA{3vlp9=;+*fv5zw#j8C{DRy|5C#Cr zbV9Khs!_Heai-|fxnKY^Gr_3HRE!qpkA9sC1~o);jlSF@58X9OVc$UrM(p)eYGwT{H&N^K+7YxSC zx`7R|PJhh>1E7vFN0t*zvZ~nWgSlV;xZO3%rwlI6JUuZN3~K7M6gSL0-7yyo#?5_L z^7P4EFc>%Yri`5bH>phY%v>-SH}?iN%>C;K%K)%9jwmeMV4(EXU%Iy2Aut^-7Yu;4 zb6l*r)aiD)U;xnD#s&>DP2bA}gE2C#)o3&Q7Gg0NBhwZu&h$?cl))I8cA#OV-%d;h zzugU zigWyaVlo&f#|ASj<6k5s13-=%LaQlW6KL5nQ@ZE*Kn-z>zm)0j3}2f&qZ{jjIVOaNzb>@aassU;zC6$A_Qz zRTc*Hs9Z1rgHh%Yt)1YNpTtM9V1A9541j4iclkuvK#t@{9iNonZoQa?oXzHL7-cqh zh3c;so6TK|yjlnt{Ydo4 zG~RNQSX%Xq4{CzH<2$wd(dVbWHhwy1_YZ&?#*(hN-5ms6A#=B^J;=; z{LE^_@euzoaGK}%Wm0(}m{pq5BA8buHA~(M80xnHRbpXjzVcYqFC9K*sNs3FAX7U0 z!h<&JwWFn%M-HWIcrC#!V|#+*0}t3txGRB2_+HdG;YEj`z5%M>Mx^t^sAYZ5L7L{s z%M+pXxlcUs?YfPu%%e-G9Jh%IdH=$!NvqW1XC4!CE})8u7Mu4rvg^cVHP>ONv5)#) z(X2Gv{6uP9{O8@Q!18_A{ zhP;`QD&0?$e<_#m0zr@M1p`2sDMMWdZ?Gv?blYAq09M+v`z9^oNX-y={LYJh*b4># zG0T`00!1LPNOZf9eGT z@S8p<{N#9n=T}|W(xZC80BpM_jcrK_La*utgOkd@a& zdm8#lFBkyI4CL1e727$Tr56l<`JB-OVwPK zbAHN&1wE7(48Y>Kl{PtwMcz}nFrkm~f&rM^e_Twee3c6;dMPg$fK{~#yYXmK-ay7G zmU7{{i0w7OqSNt$0kG0}m~UwnSh394Cgp0DQAkn6Cg;_?|CvL8TY+f&oy?0g$z$T5q}Z6QoO&p2!OZKz{bv%7>+d zKFLLDdLu6w06U!<*0mPjFS)?dBYDB#ctsBVQw#R@5}N_A)AgCW$l}5~t}w1~eJLRs ztU=r|$hhjfjMxl-UENkWYb(VL%)^_w(${#w08Fae+!{>smO_8y1%ngBB2%*TIbJXT z3v31z??FT;>;;iMfTSX&)3z+p|2JM!ouNw_X~e>%G7-ktQ-p0 zs+B{tvEil1pSTR9mku>O@s4iaaxiDs@*jFD5oRrA1Sg4>)0D!34?>uAD4o)L;bCt{ z^b}rB3Q}V8Nole80KxU`miQA7-JE*VpCo5kgQV)5yvWW6Da@(IR4eG@OKcL0l>|{ zz}n!RA6Ef;7r__+%p3w*I~X0g3f#{Uj=?xe1*#g8?wiLRGa;Xf>6kx#shO1YrOWvrttZBsR7W5sd-R z%$#-&Xjw1MlGl$Am;r$6*@mB2Tv)*a3$2;f5nY}iBOC+3)ho|DoHe#j5|9A^%|LMt z8PA!>X9&pvkYkigWWk>&8Uvu2bEwq<$^|m{OxQ!|0@I}Hf0L-YyUedNgnAl)` zgLn*T>n*}l*__2?L%d-kBK|fZ8358uO4pK8Z7j!HN0z$0Br2f4Lr?|)t!FTioUsM| z9swBuu%1Cjfc7AW$oGeYV*t3Z$|W+FKOr6i;F&$H8cK{>sIL-*0Z{50om_@fjO2!{ zWbQ8s!=QHNLYUa-zCk<&z^hl75nf!Fe?ve90IXO0%K&YI^7n*f07!EUx4Hl#$nv)I zp9sxhTy;jaatcO+1q0xX8n8(gT9K#*uLYZKd51i7-8+@|41iy+LPz+y*7bCPG5}~j z)0FFqBEL7hKASKMYU?tDiA{4o@fZNFo@qvSv1wjFKn4J;XPRYz)-*37B!hADY|2}g z@1?|J0K9tT8;O`J-^&Qf0HF2iPXyY>Z4SNOiHFPlvD;G#%>dA2l~HGYYS9P0oPZ1f zSZ~x6$vWF!84SAZUTbOQ@BqlOTC-OWm;r#z@wVzlqypH(y^6RDfLpJ35ZtJDxSA*o zfMSkqDNl#)p0E6N3ov|9(Hz?fqs*}_q58`&=Gc}+UM+}%)tAqz)tAfk9L;_ZEWQZG zs>K(Rf0rB@c55$+Jk{dAX7;2cDEQ{2IRTRU%$uE?ZJbIb!a{9|%gd8|wbCrRsD$nhmt<}SaGtI(O%tC$WF*5U?(TvQdq2|H| zIL#3(kBj-rV^O~h)P|wxi7$9&%79;Z(3=wz%-9g6Q_HY|%-2875iCz|EHrz-wPdyq zO0`P(a%d>C{lbGbhmxu^t^xVjXm+{CbVv?EO?=hwu+qrO28`fwW4mG`s<;mL1p_oB zrZ3M!lBy1n^sv^;UtWE=i7*TRb8Au}zGQirzz44gwu6WafM}LS)*_g3#4TXA5sU%A zOk=(#Fz!;#cL&&7U0i5)@fN2vgvBo6G61gGOjr5%C>vPW?o2S20%93gliO()|j=L7ZIBQu+7rg zNbIPT+r(f1472Sz3PbfNwwV!a$T_KPTebPk5|sf^?-^}=f>41PKcgaLR*(mSHE6bq z$4qyDD5jZ{<|<(r z0H(&+MGmI!YYa6+;;3lfN(cskNarWXc#_BHOp(ZO5oxpEK@bK2F$=pD6(s^mi}hW^V*osJ z0(1>{exd#>p%?(FMkgDKR#K$zB`O1;)-aVEYPLXsj<^hfo6dQ&r4g0qFA#wN5X^>5 zUUhc9)MWhh97fwLS>$+`?=wijevoJkfM!lZje+JZAPVe<2+IJlc2PxK|9Xom{OuN1 z=sv+NssvGXQH9j(qKZLYEr^0el{+2~)^<_Fd=MpK_y1F-Ox}{)}9nu8rPt2|gW<8IMrm-Ouj)3@u%<^tUC< z{7;XAne44wW^@vg%b76KpL)#fDn^AGbvEc=B)f`X7r87(qF6_09qIH3SWwoWpMq`* z2B@yKmo3K;BU7hwG3fV>mB&qXWN)S=QH}!_z~?$` zV?Dn{J`7FqgX+0{i2Y4sGXS<7S65*BZJIi26RY4Kh{&L(P6Nci9Ch~pnScxcSi`W0I0^NgSIix4kr!CO*-h6ZFsSCk!h@sXqsgH)Z;>&ZCa`WuMf|8}6!#O(+H6Z?{ckSQrjYDmpZ$3>9 zsAu^-#Oq!dE{Tsjda*N4MQ6X>yPscsTc+u0I-KsU|-B%tL+hv)rMsu+{io%L+`;yW#tn{ZIKRfoT&(G5#y#Nk3 zL^?FgBK?`iy>)bM=BH)QMnNZn*;$Jn&G<4$Lihy<)AmhW!*2(C!2tE&9J2{ztB>fd zWJnoYPiO{!wmrpo!dk)gsT;w+k@yUNZ`TgT#D{WPhr7BRDsCn+10dT`ZcSuWqpiSb zRJ5jd5|jZzZO1k?XsqnrL}vhW+p&$0ZVboQ_g!Sc04$8hiMpneYDEvOozkB}cm{yC zBf^?FU?uZa?p4lv2+IJlYqi20Y^?Z$#Ag8f=jOVtiVBp)&#C@-WWoSUUUVXusPZu9 znObd}KAY`zIOo>Z`h0R^0FHL6@iMOH6jz!$afE`9=; zHs>b854-`rId@bEELT6R35!$iw-8)At5a$Hk30tE#K33siw)KSo2d9g3!Oo6BOZ{vzZ!RvSr*6f;8Nw1~-6~e9GFU1mgfHX51hoO3G z_1hF$vrp$LBG?;&R4{y|n>( zjgw^T?L=e%MAJ;K5piy%HwzoV4FI~hgR#tE9YVn0NpJ=LH%s_y1m|@PdD>P0-%UUU z05r?Z6@bnxl`e6Zv!k52tCP2a`95MYsHcHy%vilYPjChRHx2aI0yjftyr0+%fSoo* zzCr6s)C?=zFEc#@q_4KhD1DsC4-<$1fXo_8K9ey}D9}fV!vHvD6{RLl`v_OS&;WPl zwe5X^U?Q~JcY1~Mnl@K!SBuZF6Kst9Zg~0q3aYWZs2o6FHNZQs z9@ORZg1gS~R?z4fC!Q~2UF@PZ`d+1#1l5kFpWvlMKClNm-=5O4pXmt0Gj~hmK14#8 zZCSnSU*_pShL|eDKCAN*`tZC% z9P{B*WWqxE1+g*@w)0&c^bm2+bcErV_t{7YaKRSvqAO?jeD!MaVH)0PVwJ1rUwnJE z|E>B8Hgu=5p=rJu{oAyeG#janE46J+E4P&ExEVHavTe{|PWIiZNCO;%!?5JWc%=o_3!Q@%fYD z&$*pBsf$a}tn(cQ%MI-eSAT!FlGczd^%=Ra7ZcYT%&>QP~ zI=q73**8ngF^COu*bcW(O6f!pAg}^7(}TFZNRc>12)GWjBW&qy+~T4uIDlkSN7s=VkK4l z;zTO1ju!`+##Qjkl8?RmEX`JNKT||C`>G^adueI@7!6I*qm!2dE84IwE{Pppyi+G@ zNNq!hzW>0UgNJD5lcQP4K5W3~$q6I>o8glacDwLSZ-3Gw8f;k_9-pwpfOUZr1`INNLyI z+rbMuaJPl=3yR^2e&>5ux_w#k$N7?@%Nu!Jeqmv;x6tlCwDtO}Go2&2HT5wLDK7D& zCbv#rkN+ilc&Q(=W5?F!_06sDO^TFYu?hOG;Nb%apW;7J&PvGh6G$Z@TFZAL@hetW zhU?lmNr%xg-T_>F@#;jecpqj84CcQ4^3~$|`0K^y*UR{efyDhVe=(3>KgwU9LH3JR z<1ZwAttGrp5q{hfUatsmu!MiF2tQ>BZ&HM}Si)Ns;cb?nxxB*=M2L5qUxnuRZcETS z-(v}y=ld){^Za>B&^+Hy!pE7j58yB4?1Pr@ON#K{E#bq8@KHhen;m;J|pDp2!6yX&3l2JVWR1qFa!e=SO zsrU;*oNfpr#N*Ac;!G8Nwk3Q`0j#%#e^i7EEaCBRpa8^+Ea3@?aH%CU6yY*U*sKUo zwS=!L(1s=awIXb=guhdSD=gt(6yZusc&q}Qu!PeT;c81bOA$6(!numjw1o2&VXGxv zq6ph9;Yo^coh3X)5pJ-Ajf!xiC0wZpH(A0aMYx3o@jbKye?f(}8G;nb?dDgpOGV#l z30oDw9!sG2bpY(M1iDQJ;ciQyqjM1MwFG)62jM-?~Wh zGE1OyTo7Jv33P7@!YeI-UTQ&jl_k*8EC@qOpo>@#e$*1^-4%q_SOOiig78{PplekS zRxN>EQ9<}|OQ2s<5dNJd&><-ZZ?FWq5(VLnmOy8qApDdi(2FMsZ?**b-vr?;mOv+( zApA#5paV=0-ew8(UJ1h6ErBj5LHHRK=+Fvyw?)w zJQ0NVSpr=kg79A~;r)v63zqPUitv6*pf5or`EQm$hkzh_&=Tm_4}@Q~1iI$~;lEn~ zo$P_|5lf)AJPkSPlEyAk1XLL zMfg)opsOr=@n@DmM^+&Gg(cAS6bOH13G^5R!Z$5}E}cO5TT7tFB@q6>66hfbgnzaK zIyVC0F?hE}WtEPHKsePB=n)8n(=36mdO$eC5>8cwGcDnCML5e6&QyeREMdJOtha;< z6ybbJxKt4?v;_KU0o#i#;c`W|#1gJhgeO|URf=$#C0wltPqBnaMR=Me(EA3sTy6<; zodLo|OQ5$45T0%c^j!hMRhB>p6d-J}1UilY;TlVzBM1;CErI?VK-gjlbie?@HcPl) z5w5j_7bwE@mhhk=Ji`*`MF1Gjw1mToaI+=wm41A&!xH$cJ_ygU1ipw5!cI%zL-ru- zvIM?955gUmz<1+8xXTjw*gFV&Ea9b!u-6j!zB<0xZwY)09fZ3rfiIVX@LWsy5k)vi zg1l&W2!G*=`wcg=Ee7EcOL&_ie4i!oxnO+p z5=-Edzaad8CGgQ+5Pr}S`0_3YFS7)`oD0IsErHMAg78X9;FGo>yvh>zDlG^@OWp=LVCGa6S5I#+U+@$^t z{sQ6ih9GtHSIn>CS5@>EErHLu;rrjPgl8ziZ(G9Mitsy@z$ea-!WZAPgdK|TH{5h( zu!K7m;h!vFk0ShwCG1m#$Ka%oQs}*kaH=KTrwFH6!UKwMh9$gE5ze%P7b(J7me5v& zb1Z@H^B{BUErE~efN;Jg@C6(YF0=%`SOdaEmcVCbK)A#b_#g}jPqYL++ycU7mcXZ1 zKzNEJ@Wm7mo@NPr?F59&ErHLIfUwaL_?id^PqzfV3j)GbmcSQ2K-gpne4qn_Yb=3} zY=AIn349#`ge{ivW<}U$32#+|Yc1g&ig3Lp@Vy9NJi`)xRuP_Q3GY>en=Rqz6k&%Y z@ZkhtJj)V3s0cePfv*L7fVCGbKy2rWyvMiHhgf!DY3#f&BJ3N{FbErEBXL71}y zUTOxRumoOA24UV3c&iwMo+a>dFbGSQz}vkb^eurGbwOCR1YWcS;fN*tl_DIqgl{Us zBbLC6sYvpDmcWapAiTs9cq;&NlErHiEL3o)Z@IoaBFSi8Vh6Lf2mcVO_ zAiT;Fc>NHBp(XIjAP7Hd2~Spp*H{9t<>8ChTEYfJSha+wE5eUk!h|CHI}+qh$WP!e zV7$=~#NvL+{3_n0qTgZ(TNJ=gTLSN30pRVHzzb3!ywehRiwT5xTLSMIf$$zn;C&zv z-e(CvrU*Z83A}KFFaE0~@R|$=AFu@8YXRXGErHijK=>s~;8hY3K4b~J{Q<&b)z}pode9RJfF9L*5SOPCHfbc0x;H3i)K4S^I69B^JEP-eELHL3t@DM%-ziJ6Q zJP*RJTLKTggYYFw;8}GLe!~)Y$Q*>z%$(-{Ej8?7&ZuBu>>BR2I2QD zfrp(z_(MzJS!EFZ*b;cc7=%By1fB~9;j5Ow!@MB;Z%g1AToC?(1UcmNHT(s_*9}2T z@SEmW@z*N)?<|4mS@HcpS_03Yg77bvzyqToJQiCViUp5&f^eE8@Q@}5kGBLKvjkzC zCGg}V2xnUYPe6ijt|jmQBM9eN0uLR6aDgT8&>#p;umqm?1L0yz;3+*2F0}+6tpnjn zmcX-eAUxR;c;*d+r&`1Q`fdSOQOifp8@WJeyNog}*?!+7P4+ zHk)6?q>A2Z3ELFmI!m}-5pJ}EXDY%imasz+ZnK1)im;mm9`-5jP=se2f(Y>({^H31 z*`$Yz2P}a*?I7H13EV~p;dz$8U2+g!U`eT;xSN7rr1Rjf8;5OvS@NvtFGmG4i)Difl_9wZ;_#oyr>L2b^;TLy{@DKMV z@DCRS@ekJ>@DHap_=n>w{KHNU|FGe~KeT=PL+isov@-ldsUKWjSy>sL-d(^stikH= ztijS;w|BJ3vz$1Bawi`6=(QI*_w~Bpvm1}|uD)({(@U{W^|(_`c{R3BWfznJzD7td zUmcLj*w;)A&zPA%jN~{J_wWm`eS6OC#fN)5PDspw0vcX`1I@E|c4fXL0<>28U8rJs z=5l9YN!*0;*IC%N=C%6e&e3K0y>JXyk3cxwon0MXBEQ4|XTPb4O`daG9iF>?=AL$c z(CP0|pNi~I^l-h~&u(E$_}J>B!^h7aUNC>3k1S8kcUoZA>G46I!Rp-R;kj^_B;>&{ z92q@|mjAKH)de^JCx`F`@_8Rw0oqwB{rT2ldJdcD$o@C@p=3gxz#FU{7+y5jot>M< z|I7%UpqZLqoPKDq`pV%2@De@+hc-U7_&Xx3U+ykLs^vw#*TW~69v!adUpV#BYWJq+ z7W;$My{8V(H?+b0%4`cRg{Hyo%(>--`4)Uxwb5CiyoMJZUR+%6EiTIg1<0hFOM2z- zyoVS2GXr|QYAtkoE6bhLy&oT*Ggz4#fH`b}x+u;hz_}o{a9R#m7+}kwo-43;YUH8r z;bY+Y$Ro#;VwkC!h4%6s4zSNJKHSn<@UI-6?^D%b;ONsC7{@ZTa-sTkW^siDgF~;~ zUI+O|9G$hW}#hc0enLInTyC+?~N&af8)Y zuMXE+VteK2Ot;S?Fg&u2nz;SY7UXA@CxdW(N9_dA`z7L$5)cz)|h zxAU-A49@QHcqycr7@h}n>&`UW{n?hP9;*`%{OVb!oU&oVhIKeCyTJ3gRAd8R$U*4A zI!3MQ;vj8*xdB65I@V|p8oi};hx>~QIOMF)8#nY94td?WbvQuWfCEp(2_@3)O>DYp zT?79Sl>hGR&khgVnQ3%;ODoHA zaJ1RjBY$^b)JSv{!LJfq;9rX?^YdLoTy+<`T_`&LqTh>#h}@vJx_);`njlFB9EGf9 zEH5mZSy+V}@bz+4k$={Vwy!H+1IHRysdy!9yKxvD%+_h!zZcdJb*p^zur-v!+aRdj(SAX(wxbEJ17E2k`8SwG*^mG;nH5C4+28*kw=F zn84}8m4)6WM9CMpO3`4;rK)R9jiOJHp1Ot9wKOa8*+NlTT|xuS`xKPZNFi6s(2TIk zkj~yqid@QH0CxvuqJTy>8@{ z1|GJX9qia}wMViIqb&+k^>YQJz)=qE<;GwR6?UdEMUz5nIRldtvE|6EQRqlrqBgSB zIiBfv256WEMvH+pZ)k1-J+%^@##&2tbE;bF*25hcaglG9nO}8$lSFd;lFO+I`GO8`{+RfX1Z;2W4qKoea~fN*;$i8A*%NzQ90)pXGSVjK5o$W z!-~2$!di`lAoXZarhicx;{AhBH2@OOJv&F={r2>7R)P&j+EBkXB5~&4Y3T2vHYLI4 zhVGm2EgK1>sMi3ZbfC)CRC^iCd2cqZVHh0Fr@iZ)?fF5+k(GHXr0yefb;mRe11ZG; zs@ec|dm3ol8^UTc{+vIi3Lnk4s7e8riw#|IC=c%p7~w1#RRx2iZMM}?UpDxqvMw~i za!}pY@J;K)4)8|SN+12SOtthtP=2(g7i3H}hzElA@YBX@7bEI$ENBLB0|7SUMum)_ zV0Qe+mJM<0qo!g^+Jw>rItKn~dbL2e|E%n4fXX`Q#qYp~7o%oY+6gFUB1-?ltq*S6 zjPgh$wlQLx;+tT;5Y5^|ca!L{i{u{12W@>q*|eAO9a(N}Y@kpmCOTu7Z~|^p9JJo~ z={gzjpBw6Db$BXTmDRmx?%jpd*Y{l_i69_msxiMf!d5bV?Rm1}bb#ugtVfIzFS0GxOc)j$-cl zPkg|9b8rQ7ss6G1aWTBpcUtAVPYS{bI28yelN>G`NHd}{?Fnk)??x+Qvkp`lK@aqs zJ!mS8x_EPL=Ni zrSyS#Hx{i8ILZ6(_8ZnhO_vI3BUJez$`z*6ZrylNxJP8JicgrbseZZioX46t`Orq~ zGvs}$AtsiYXPPKA@M+xI*y_INEk2Cs4T@1~L*p7W^8E?*a}$1TXwCO6S!9~;E4umC z)Z(W71DF%KU7{FbC1A2&nZ<;anURXq4)u@g1Q{h6+#z8UA=O}q(qcFvETi(?=5V;>GW zCKlR9TOGx;*%@p?2cvZ0Df?lm`(PWi1rzWUiAALy8)iCFE3;czbSNYzt~PTd3v1(q zlpU%CH0W0ot@?)Iw%JpTJae{S!| zu7Ll2YdTNGE9g6Aer7u@Gly`Ushc-2v1tLNEnUIb)*ybXds-H{WlkZ!)7A3%D~@5m z)76gZYS|1)UmK6Z5mC|EUJ!M*__}^?n@ueJXbmAs``gk^6&>!Sxeix68caO!q|;70 zCEV%y|Mj#~O(6BaO;6*n&Nb-T?n`$?x07bOFwCZ~#am}mYm?NTt(rbCGoJRrWC&{} zsVrQRPWsyip1*x}S+~h6^e3#}42Qm()vU;ksclO=&IHqRG38yP`9hR|uF2*->>}XU zx4W1=p5|OhuGsr@Jr~QTmS(?>9Hsq3c^^>LLGUFKOvwh{nUek6 zoRYD8gFb@$DSnR<_JTMb<)_fy;E3f+LY}a$<=^^(CYwF}=S{8t51o@qvD>bmdHT+z z>^qaPy6d0P4#})6?(rCt?Rn4JyCu`}@^d>c;|H0Zcl+LJOL|_FI@|N+3iC(XX zbtqg>@Q!k{aE=y-Ia>M@N6&B`?2yxF-5ESdEr05kzcr1U8aP<8Lmk&_&o9ljcWi6o z;bfb;3!s?{nzq@{N#;Zl_4$A&N%YZOMQ@0X zl0=cnDmAl<(2N#su+a>Idc9TcuQA|XgX!1 z>v2DDJlE4K_}O&7*LefR%!kUKgix7g{(=D8(L2 z;S%Ejn|C6yTJR{}p~9j_YQ5LI#~4q!AcDfvRS@{$c7I0K$fG57=^l7cLC)k-4?o9% zVR5NFtIw~hI|aMc886cSIK$dScOio%c*}+DE;jHWtV%br4QC{I-H2zLm)f|B)^r7~ ztK!j{P^3IPuTI3VCd#qiey7pzVAL`|l@K()7MmqdtalHVbv0f*ylgB;AB?6$2rm`Q z-|DumMGZi7V`F1LJ*tD{)E}A^ly}r3SvEmAs8!|5 z(l*65CVD;j^u3p2()y&#huT*4cTd_of$uIzztjEiX^fW>ui0;Sv36K3j(k!n2)|gV z)1#u_)tB^izkAn#1L$TCj_78ayw%AYbLc~GKkrU8T~dXFijEB*aWSF(^(I%KMxVM4 zMW5rejYM#i)Jdm?0tOS}O1Ex%d=Mr^_wQ17H=`%Oqth*1K2U$4W~e`K%dOXXgn_O= zI0~)XS$FP2^+n*9>3poINyjqV>$SGQs*SJ{J&ZTdco=pNAa2ENy6s`QSl-ff*QV+G z?3JdwE=^~&QJUuZFil=@su5$;-a3q%7ic$I-NUV3r-R!&nO5G^Q4aE&I>E$IxhXP< zrUm^jHw=$92XknkH{p2c_69qz#!<&7>OycjaHf#Mw$L|L)1i+4kG;2xk^8#x#B9uD zY->GZ%a-l&*SOr&tg0z?k=>MJxjpR}nWSV*ks862Z0~e9wbk84c8T3p#j0+S%^A-_ z5M(yHP7ov>AV`oPNOtoO1W6DCdC6N|783*s_AyA1$9>I1fCR`>e!p|hJ@?%IM|C&# z;Tc;ks=Mm{zn|xxd+zzZ_>IY7ya-4+95P3E%Q+LMKEu>C0Kym9-lF+U_JKQvCc7sc z!~xI8kMl_a*F<=^;sOScZjD000OgF4a0(tF8UtT#7o%L?Ovek3x^y(%9pmO{<@ypQ zh>qdYIB#fSqp5`jV!jxHOUC&0CayL$akM|iv3r&lo@}BRmi?$#voO#g zpRvX3jc#|H$1^bw=W%BrXQh0>XYHcB?$zaWfzj=CUs_%l`=Gt<%S-BF_n;zv;XHUK zEYFtMN$L)``+C%V7G$t`wm#E;7H8&{>;PA)nAssiapb5dIP0tP0h;i)I! zcrq|{6(`&D_$YicD!-YTPCw|R?Nd*?&^ES3_~yG&wo2?3<>J?}poTl5h;s&AWi(V~ z+73OGbGg$XGNqH&d^^G(cIKr~a*`qINDQ&-LP~~cbwhaDKN{V97f}kCq($M@j*-+% zmD*Zl;_jJgvmoyAEKo|hE?WhPrXS!42bv@ zdPLR+=rje_&_bGyl!! zpO&ge!VgPHjWLZT@7j5i^esN|OC1iW1eZQ5Y5JwwIpV4s5@%0Ib3-N9vrr8S+blNv z7DyyFzHX$&*7jAL5wGCXSl@UReBgNSXlvtD{@s_q_fY^e760x8DiC>>*KTxdNSP5f z-bnl3L`I;LRmJQuCf-USF((;TDN?1)XzVfam&9+O5lxkCW)PyOB1MmA5oy}^$zF*` zW`x{g%v+NotNdcMNkC+?gH&M1dSjz+>=^)qxGf1smX^Dp$ED{sWZEZ4(nJ- zg^O5Gt;g++`lISpo|wv6;BAL&?gaWnabpRxg}mHZ(12n%7I~_;G)Ux8;*Zuc+-a+Y zEFVp^3?tfVZJ?G^t4pqJ<~5^TZtNlt?>)y|i}e}obFLMvfG#W#)eF7en~x5Tb!81q zU44mV^!DWmAyH{_BbBX}tT$|hH);(NSe1saYQw=eCPQG!dc#)uYHavPYSS>rq@kp} z*4B~=JIvJBLj?hnND!FVVX6F+<`eU}ChS^%VmgdCSBA_Z`(DCW=t3j|6SoR-6X~D0 zy-qn)afnhZ!#~~otDBU9U|oFql}nwM*D-_jD;qB@IbdxDdCAXnz+OTEz%kA`Xntv@ zmD3B^o1lD82bC}Ktgbpn z1jfWprhJB@);V|!@OY9*2`Pmx&PU8eGrEWjRt<)T4~$K?(0TpMpWeD*N&;av2s!{n z5kZV3;9^sf&p!mWc2_Q$h4}$I$q#S*XhUEp38fq+4cvzzsUCRk9wwS35?P?Q!*YA# zd=gG9P>8r9WkD5aSj2@nJzHQRsBP6uSA~pm!KdTBcvRiiM^#^#;|U28dU0M}c%Q_b ztnqa5adEKr1~su)!oM}s z!*$mq=$gFqq!=*HD5^n1i`(N0i!`Rg0@nIVW#C(y zs|U49?y24jnb@|;u95YND_5N-mb{ra%smQ@2|-o#Y~<-=73$o@ldyJ?X-L%G?Se|Z zOaB>PS<^mu9uMH-vk5O7aHCipwWpFXiPU-lPZ5||;ngFgH51579b|A7`kM$WJdsIt zy#jIo(i7-FT!JV}O>w-y1BlDRAI`wP_=&GuxBDbR%wOq#i?1H5+$=6U8L%wj4TEya z8zU=7mc%r*D_I%Op$I6j9(4lH^)9wIFCppTrj{v@0B<$}Ct3IXO6{Myu{?fbX`}_! zu78s#S{3($`a~ixpXska;q#5gqNQr+c}9x-{JEx*ZUtnCvRfnO)o#Djf4A0cDq42? zlm6XWw^q`+eT5}N@!v8yQ3sX7x}nOCFf1u_3LKG$eKL#eBQq3KHG(1Z( z6a^kgPBO^7$j2*Oa3h<+G4n?XCq++{D4bbu1f`IJUs^moj!g6teUFa9#sQ%V<|Fv@ zY@D&SbXsSYo>~>-lW@jE;20G!hsTLoNOO!_NuEI}m7nOGVre_z508-?)~DV~iS0~T zPKkZ^N|OH;DJn>~Z3=m#Cf-$4e+|lnXbK37>BpK1XS+!mfjJ**D(KGnv8IB`i=ZYD zO8l{=V)1LPseri#YUENY^Rc$#9NLPkHOZ$m^ev#fatF&KYs>2j6+e=r(#E-qk2M}t zpJa}};S27mP?!iQi=t(RikGr-RF?#X>KvMrPxrr7Q(+{vf(!GaWBE3{qnBztLAJr;Fj-P*6Dn*WlKj_gNpjhR%->C?e(+b&fdsyhaUve{6H_S96Q&BJKj|T z?)af5xFEe$kmm{ekQW&mUbu=lQZ7{po&#Q?ia4y0r&H+h1R_Ly zhU}__K{8+n^0{XzR>dG0CSuFkLbYragIMaSmZhIXQj5rB09ye?n3Y3Vp6p$gKl>Y5iPRSBiQ+UzZe-)=w@~_H&_s zG56zzte>y(r5tMYfryfR$yDWi`y}PHwHmsOt@`5tz}RYj?^EJyzc9em@dx5r%+skB za$v7i?f*Bp+w&SAZnJ9Oh!x?Iv_`&uoso# zjF&4{=9rYT#ko|eos3qMsxE{yX`x%2kXbC}M&c41LOxC@Fx2=Sgwl%5-GRhL{0qvD zaL2DjaMLw&Yb$ssJ;v-cYz}*oG2V=-P4V8c7+0YjNVUa_Gkt+icLs~|F@ib29Bueb zA)iKT&qAUq+HXhS4~A0NK=M+2&}1o5rF6Br`D9&A;eA2XfD{tR!|kIYTftk++>1w1Q<4zNv8LI~b4l9DQ_5;0Mxp z5&~uSri>c3!g*m)9F63n?Ve5rn#NvyOpbhMO#Z-Zqz=R&Dkn#(%7MmF@lfMm3nC=S zUX)QdeF%q{_l3^Ow)_p+^Uq7$^cgMHJ$_l~n+ak;iV!jEGyShZ^7&F(#w7_U@^wb! z{rtC!A|@JrT3%TXb|_VQSnYo=_mIkzJ#6*g&OKNW>!Hh6B79W`AVN^<}q&LKqlw*;5Qw4)|2Wq%;J}e`$AeAwYAn#k*7c*RE4D_c0 za`^ade1T^S6e?BS3!5`#4SfVr2yLx5v`1&?BJdZRaR=A#rWyD?k>2m_+87m~RlM*f z7;bo_GTytprOpT?E_GggsaC2~6upYD3V~%%_2|Gjj79(lj+x>2fC&JYrjbA8j#)t_ zMOY1{v&bCl-6~i?l;LORyw{`4s85^=Vv?KJ%pDnp@zTn9@?=dt>!hOZiw}g2Y# zyI$1+%S(HH_R-;7m{kH)yp8Zyq^lm#zUWY$f~s@YOuF+Ln03~?*$Nl}LhH?cz?^fCU% zjZ1IqB=K0)YorY6@U%@Sh?kQ0&_ar&?eoFW+&?}X;!0)smh#slc=;FkBp8L`Re;<6 z*>{=jFnf%qav6Ln3#I)bf6G_s85Qxn`j`p8Ft+lsCR)N9{gBBKFHv`h$oyN>j_>S) zX->yB8E8*|HX0%o9^$$e*y>0yA^{K3qZ}W^%%U0WV7(CpamYmYz+EYgRAfkmgsPg8 z&Jt?w9%BV}kI*hMxg{}QAQ4lfDrwpbxlx6g?Lbk4#HdHsq(j5=3jL|Y@0AfCu6)!+ zY&=K%^Xc)ueGTQ{sE}8#ToP~AfQfJm4Whbi3F4rh-GL}jABS`S3FW~tZ#)260yMk( zV9Bh81F0BM_tE|c@pzPBc85C$qszmGLu>+k%EZ3VfYB!a=QD8)0Z$PFkLHpt2e6Xl zrV{D~aB{g7wu{bUcsRpd@sb7_u}d%QI~j*t@2f)xpZ zlfFZV;RH#ZsgGOX%@~!alRRu@LaA2WSs)7vj5}oc`16Fq&3l+5_ybMYC81rIw;h?< zt;JC1dOR@BR#l^~b4?YT(7~d)S8zo#XdxE%=@AZOAF`$`l2|(82U^+AF2WCC>|&H% z^P7{#H+eT#8rz*7GmkiW2$!Ra0YQ)G$&^$ZesRI7N1$?(jv?u3^5FqAqa4Ljm6Y2mx4_~ZrrcCzGyQ7iz?L)Ca)JH6w#F;ySDYEmV)`)W?=W0iwUx%SA54w@R z6?SrsCvcW-3GXpr$U{w>iWd!UU|SRBo!yZev^2gBW6VFUtW z6HPRwz$DTVj1RlRgWY2W?11HmfHOqyZl;aEA#)ek2nhGDnY<|)C9#Nd3=e@FusU{x zvXYRjBqs1dm|Ph{p7!{K&i?V_9%SX=gu@@446s?*_W*tx`mHRmR}{cEUr$z-0aycI z2-71RZ_*|Y`XIjdFn0l(x4~g$f@Y_s%ggp%*(_WqJ*3Z;a7c0$j<=H0!`3~G14EK= zG!3n~o)Eo1`~^iPW5}gk<_~O1&obHfvkn;Z*%!js!OEQAm)^6JR@z`A?1PH5@OyZNlbI z;zI=@k=k+koKQ@3DU20@95rG>H_i#g(@}LP7*SnS&0l=m4~eR-S#yy7ZYWSF&|K;K zQ>cx<5=zBG!wUUre+PwPQ(6eaASJR=d;J5H`c_j@0cciu(mz7sPOUJTte1Y+|8tan zCYLtt_GkE944K6{(JwcHMqb64RDdGy+rd$*UIB!>KOF>8>6$lzrduY6l4z!1~*nb_LgRKPkqfJ2v?-davIAkJ1q5-!EiEK&=9~iqB=tuSy^&u z*RJLjx_>Y@njVpj*d3)$bNd8JpBs~rwX9A5CV-h+3YgVW;o1#U$Q_+C`T;o_flAnYzKs{_|&b#(K~RaWl^1xB6Ru^@~MI2_C46 zQ%+1AsW0e}s#fCRfPV*vIFoSK!SrA{AI$IV3>Nr=)AehA{}Z1emwk;dIvP_TrV8G) z2TPPxc!nj+ygc05O&_O=^hqU*v7 z_M10Tvv1Pyp-**RX(O@c>ngQ`LJwhEgwScNn^c3P2Wg)ypjkKsDC}CF*REq-1mXgG zgmK))B6O`yh~ZSl9l)V}3o!4!_JeD;@W9xDr2bgGY`UL2xB(JJ$KjaQ`l+pSL8TlQ zd^S87;nKFnWl7O^nU~QZ`QD+Q4;wvrcColBDoM zz|E%S3HL^*Cpf}-V!iS4a0i1DDV_Pwz1bIYtA>D_i3@{&M0gB$&@B{M5LuWQ+UZWIYSAhgWveBz zWSwq)E$n69M0sP|WGYJp7X}JknZ(JC&iYHM6LRk@o$4&V;rQo-KsLUA(MtIvc6|BRi;bS-yQ>#Cwz^4d5} zsQ<+reLxW>_T;bwbFIf-kLlt02Cif*h+VFHQC%+L z^ZItipxJcV^wh6+KAj$I$?)X(8BexyD@+ppXhH?>76%i~r>(sAdhbl%5%HRKO79Qj zjTkCI35>woE5JhV^((|9`Ab4@r<{fo-5(DRjz>akyDPeD4v%s91yi&l$`XzfFQ6&j z8P29&Ko}1`v9T}+LaYLK>?iVCU4uf8Mea@y;82!VL9~LT4+r#cAX8>Whi+;Rf=MDV zxf<|cF;MykFpH%`&dcNvU|qr^AP~u5+m&vWA4L7|4Y%BR%iv#;c!WEbKT^p3QNp)a zB^Y9`D&m8%H@-JMS`6q4t}I`<0MgK-ArCu*VX`O&geH%=k8nFSApM92{pObP;Cz79 zmIO37CFI2I6>kGLyt;xUStFA3jf~OKQ`;c5y@uj>jY^5myC}v`E*_4ZTs=cLlLHiQ zIhynG_e*SyrDTm3AnbYchE^zgf}b|OQT^%}gN<(l6B7>2T3E)+C#a+aoG`<17r5T}t=#Fc z=cdhG(h9GCg8Kd?G$RAc97DriKHgDZt>CjKBO}QYa@M@uCAe6_Kz60`2V1EoK7H5m zf@S!l-NC&P{-5(v7b8#QS7`y)LislcKWo6wE;JCI^A={QJZk}=7B8FeB81Y(cD0BZ z`n*)Yn?c--O{W|80T6@yd^q1Sa3Z!vj@74GIwc?w)Ck>sRi7Ktp6pO(S$D zUx1o?2$DvXMBXQ&sKKR_ldcUIkelzUtdeHk#T8#(ofrsZDgKd+(O54IuqvfPyN3H! z?sr$d|0aF_eN@F24{%Uje!Nm__Jy0)P1yJTKZ<$wCZz+GkCRW0@~=(3CQ?;K(%QjhQgd~bw!wtU;kn9 zlhLCglwMHRrffJWe}iur41`#QGtqXn^Ay^ifk+h^HRgcB2~F(X9VD}Y({Gi5!Q_b~ z)!SV>%oJT_gGvirPg7;0Wh+Vn-H+CG-gemHs?k%bADan7BCZIhg0qO2G{68FDmZ}a zJ22JuldP*JDeeGV5g5S%m4pIMr*nR=6Dc5%65w8F&tcJM8RQ?@i)8Mdw0W{NWzaa6EFx=kd)Pvm$O`ErtXgf!bRS6cT3F1K& zl_>lQO4BxhLnQz$p6FQ_z>_^8(FAO{AU(Kj-UI|@+y@nFU*Oh*UPj6apR78Y=^QNk zy(#t4XbJ598YTTT3i;j+Rzr52h(2sa$6X1T*d0(Fl7fwzUyx%Rg8ZSJ3zu#$j-Itu zAWh|<*d6Sk;VV8Iu1XqG-0#BXh<2imb>cf&YlSW0jx!((#khJczSrJ;oLM!e!{tTA zPd6<#&L2#LeL&qr2m-oTPdMqqg1NpVTH^wV2SlambjB9)uoN2#U}-=48w5#>*M0>L zcCVQbS}W~6k@g5k5D&hsE)kU*U24!jk@BN;V$ovU7m)+)oB$S$#QeiOm$5SbwD>F>=G3E zU?AGQ{i;LfbonEc)ObPh)~-Cbj7t<>#^PXnT%{K~U4CDy)LTWUT`IQ|kG|L%6KfUq zyGH;d5<3S$PUEZ(S*gO)Tg>pM6=gVrGuJjU=M~aUP zS~3E;KVF;Qu?ArzOM#K=cO{BO>I2q!YVCc% z7OKQ6>vW+--f`!5y$|!1EB7yMyvl!9y&**bMt+8R7DvX2&P@c|OAQbhn9(55L4$Qw zn<*NpRJZoZvl|eL=X#!3I@O_p$iyoV%cw}qZ#i)3GjZK#;n`W~f-2zdk47_9n+2x< zjUxu(Ctn1eaD9f-oAs-g6O)q^gjfOoB`_w+mr<#yYvKPbsJNw50KtWTLMcekou+fo z#s&BTHE4=sEV#d5P*-DUu(0)Z^ z!P>uHp=IxJA+{J-oZw*0bXvSD#mKs)fhG3eM{LTsg3TuX4~b_yff5jNNp-WliXcpe zNSoV+UOrC4oO&f72(vfBO{#n%sDqiO%K$S+uC4|UT1Yd@odFP<3f5w7FyhLUtxz`m zjiPyfK+3JjBR(e?aDt0`!SxP+9(M5vm zapQvJU9e0TKSeck9ww2c-eRuRm6sV=)5zZ>ffH4ZauD)dLe!&XKGCiZ2r?714syn;=o8YB?#{1so(mCDo9}hcZhBQ+$cW4;R69X@%?S!R3gNaA_J9 z(@8lNd#UbQY3W=LCZ3ppQE4TwsmvzESfiCDJCnf0T4BmmNTwk$J5RoWHI4<*I+W%P zs(1{;>y}103X7p-lL#@DXMXY5|MBHdeu6(g`$hNXFE)ED^_nCv^Je>c|C{i9Usf@5 zb;{pb#cxT9=HFk^V;0`5$^}V0_N|sGDf5UGenIXnXluVD^H${__UB9H!qHc)%2x5H z|8Jt=@3jsL|DU1S^DWg1&cSN@v;IFvjVo<6+SoFy z{Wtyp6}4B|YG-c5%KwZ0|BdorZZ2=p5MN{&iH2w`_dor{CqA(ho5=F1J6gh~Q>)Yw zP^z?{29Z6Yo)kVE>7>|smX#Hb&+f?yug@>xT*F

Ln>YpRinQz{m5?KI_?q;If%q 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 delta 111905 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 MidRGJBmUg~18tv}v;Y7A diff --git a/docs/build/html/_modules/domid/algos/builder_ae.html b/docs/build/html/_modules/domid/algos/builder_ae.html index b9ce240..2591ca2 100644 --- a/docs/build/html/_modules/domid/algos/builder_ae.html +++ b/docs/build/html/_modules/domid/algos/builder_ae.html @@ -309,18 +309,15 @@ diff --git a/docs/build/html/_modules/domid/models/model_ae.html b/docs/build/html/_modules/domid/models/model_ae.html index 25718ca..7eca0fd 100644 --- a/docs/build/html/_modules/domid/models/model_ae.html +++ b/docs/build/html/_modules/domid/models/model_ae.html @@ -310,154 +310,148 @@

Source code for domid.models.model_ae

 import os
-from datetime import datetime
 
 import torch
 import torch.nn as nn
-import torch.nn.functional as F
 from domainlab.dsets.utils_data import mk_fun_label2onehot
 from domainlab.utils.utils_classif import logit2preds_vpic
 from sklearn.cluster import KMeans
-from tensorboardX import SummaryWriter
 
 from domid.compos.cnn_AE import ConvolutionalDecoder, ConvolutionalEncoder
 from domid.compos.linear_AE import LinearDecoderAE, LinearEncoderAE
 from domid.models.a_model_cluster import AModelCluster
 
 
-
[docs]class ModelAE(AModelCluster): -
[docs] def __init__(self, zd_dim, d_dim, device, L, i_c, i_h, i_w, args): - - super(ModelAE, self).__init__() - self.zd_dim = zd_dim - self.d_dim = d_dim - self.device = device - self.L = L - self.args = args - self.loss_epoch = 0 - self.batch_zero = True - self.dim_inject_y = 0 - - if self.args.dim_inject_y: - self.dim_inject_y = self.args.dim_inject_y - - n_z = zd_dim - n_input = i_c * i_h * i_w - n_enc_1, n_enc_2, n_enc_3, n_dec_1, n_dec_2, n_dec_3, = ( - 500, - 500, - 2000, - 2000, - 500, - 500, - ) - - self.cluster_layer = nn.Parameter(torch.Tensor(self.d_dim, self.zd_dim)) - torch.nn.init.xavier_normal_(self.cluster_layer.data) - - if self.args.model == "linear": - self.encoder = LinearEncoderAE(n_enc_1, n_enc_2, n_enc_3, n_input, n_z) - self.decoder = LinearDecoderAE(n_dec_1, n_dec_2, n_dec_3, n_input, n_z) - - else: - self.encoder = ConvolutionalEncoder(zd_dim=zd_dim, num_channels=i_c, i_w=i_w, i_h=i_h).to(device) - self.decoder = ConvolutionalDecoder( - prior=args.prior, - zd_dim=zd_dim, # 50 - domain_dim=self.dim_inject_y, # - # domain_dim=self.dim_inject_y, - h_dim=self.encoder.h_dim, - num_channels=i_c, - ).to(device) - if self.args.pre_tr_weight_path: - self.encoder.load_state_dict( - torch.load(self.args.pre_tr_weight_path + "encoder.pt", map_location=self.device) +
[docs]def mk_ae(parent_class=AModelCluster): + class ModelAE(parent_class): + def __init__( + self, + zd_dim, + d_dim, + device, + i_c, + i_h, + i_w, + bs, + L=5, + random_batching=False, + model_method="cnn", + prior="Bern", + dim_inject_y=0, + pre_tr_weight_path=None, + feat_extract="vae", + ): + + super(ModelAE, self).__init__() + self.zd_dim = zd_dim + self.d_dim = d_dim + self.device = device + self.L = L + + self.loss_epoch = 0 + self.batch_zero = True + self.dim_inject_y = 0 + + self.dim_inject_y = dim_inject_y + self.model_method = model_method + self.prior = prior + self.feat_extract = feat_extract + self.random_batching = random_batching + self.pre_tr_weight_path = pre_tr_weight_path + self.model = "ae" + + n_z = zd_dim + n_input = i_c * i_h * i_w + n_enc_1, n_enc_2, n_enc_3, n_dec_1, n_dec_2, n_dec_3, = ( + 500, + 500, + 2000, + 2000, + 500, + 500, ) - self.decoder.load_state_dict( - torch.load(self.args.pre_tr_weight_path + "decoder.pt", map_location=self.device) - ) - print("Pre-trained weights loaded") - - self.counter = 0 - ex = str(datetime.now()) # .strftime("%H:%M") - self.local_tb = SummaryWriter(log_dir=os.path.join("local_tb", ex)) - self.random_ind = []
-
[docs] def distance_between_clusters(self, cluster_layer): - - pairwise_dist = torch.zeros(cluster_layer.shape[0], cluster_layer.shape[0]) - for i in range(0, cluster_layer.shape[0]): - for j in range(0, cluster_layer.shape[0]): - pairwise_dist[i, j] = torch.cdist( - cluster_layer[i, :].unsqueeze(0).unsqueeze(0), cluster_layer[j, :].unsqueeze(0).unsqueeze(0) + self.cluster_layer = nn.Parameter(torch.Tensor(self.d_dim, self.zd_dim)) + torch.nn.init.xavier_normal_(self.cluster_layer.data) + + if self.model_method == "linear": + self.encoder = LinearEncoderAE(n_enc_1, n_enc_2, n_enc_3, n_input, n_z) + self.decoder = LinearDecoderAE(n_dec_1, n_dec_2, n_dec_3, n_input, n_z) + + else: + self.encoder = ConvolutionalEncoder(zd_dim=zd_dim, num_channels=i_c, i_w=i_w, i_h=i_h).to(device) + self.decoder = ConvolutionalDecoder( + prior=prior, + zd_dim=zd_dim, # 50 + domain_dim=self.dim_inject_y, # + # domain_dim=self.dim_inject_y, + h_dim=self.encoder.h_dim, + num_channels=i_c, + ).to(device) + if self.pre_tr_weight_path: + self.encoder.load_state_dict( + torch.load(os.path.join(self.pre_tr_weight_path, "encoder.pt"), map_location=self.device) + ) + self.decoder.load_state_dict( + torch.load(os.path.join(self.pre_tr_weight_path, "decoder.pt"), map_location=self.device) ) - return pairwise_dist
- - def _inference(self, x, inject_tensor=None): - - if self.args.model == "linear": - x = torch.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3])) - enc_h1, enc_h2, enc_h3, z = self.encoder(x) - # _, _, z, *_ = self._inference(x) - - kmeans = KMeans(n_clusters=self.args.d_dim, n_init=20) - - kmeans.fit_predict(z.detach().cpu().numpy()) - # x_bar, *_ = self.decoder(z) - z_mu = torch.mean(z, dim=0) - z_sigma2_log = torch.std(z, dim=0) - pi = torch.Tensor([0]) - predictions = kmeans.labels_ - preds_c = mk_fun_label2onehot(self.d_dim)(predictions) - logits = torch.Tensor(kmeans.fit_transform(z.detach().cpu().numpy())).to(self.device) - _, probs_c, *_ = logit2preds_vpic(logits) - cluster_layer = torch.tensor(kmeans.cluster_centers_) - - return preds_c, probs_c, z, z_mu, z_sigma2_log, z_mu, z_sigma2_log, pi, logits - -
[docs] def infer_d_v(self, x): - """ - Predict the cluster/domain of the input data. - - :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. - :return tensor preds: One hot encoded tensor of the predicted cluster assignment. - """ - preds, *_ = self._inference(x) - return preds.cpu().detach()
- -
[docs] def infer_d_v_2(self, x, inject_domain): - """ - Used for tensorboard visualizations only. - """ - results = self._inference(x) - if len(inject_domain) > 0: - zy = torch.cat((results[2], inject_domain), 1) - else: - zy = results[2] - x_pro = self.decoder(zy) - - preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = (r.cpu().detach() for r in results) - - return preds, z_mu, z, log_sigma2_c, probs, x_pro
- -
[docs] def cal_loss(self, x, inject_domain, warmup_beta=None): - loss = self.pretrain_loss(x, inject_domain) - return loss
- -
[docs] def pretrain_loss(self, x, inject_domain): - if self.args.model == "linear": - x = torch.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3])) - *_, z = self.encoder(x) - - if len(inject_domain) > 0: - zy = torch.cat((z, inject_domain), 1) - else: - zy = z - x_pro = self.decoder(zy) # FIXME account for different number of outputs from decoder - - loss = F.mse_loss(x_pro, x) - - return loss
+ print("Pre-trained weights loaded") + + self.counter = 0 + self.random_ind = [] + + def distance_between_clusters(self, cluster_layer): + + pairwise_dist = torch.zeros(cluster_layer.shape[0], cluster_layer.shape[0]) + for i in range(0, cluster_layer.shape[0]): + for j in range(0, cluster_layer.shape[0]): + pairwise_dist[i, j] = torch.cdist( + cluster_layer[i, :].unsqueeze(0).unsqueeze(0), cluster_layer[j, :].unsqueeze(0).unsqueeze(0) + ) + return pairwise_dist + + def _inference(self, x, inject_tensor=None): + + if self.model_method == "linear": + x = torch.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3])) + enc_h1, enc_h2, enc_h3, z = self.encoder(x) + # _, _, z, *_ = self._inference(x) + + kmeans = KMeans(n_clusters=self.d_dim, n_init=20) + + kmeans.fit_predict(z.detach().cpu().numpy()) + # x_bar, *_ = self.decoder(z) + z_mu = torch.mean(z, dim=0) + z_sigma2_log = torch.std(z, dim=0) + pi = torch.Tensor([0]) + predictions = kmeans.labels_ + preds_c = mk_fun_label2onehot(self.d_dim)(predictions) + logits = torch.Tensor(kmeans.fit_transform(z.detach().cpu().numpy())).to(self.device) + _, probs_c, *_ = logit2preds_vpic(logits) + cluster_layer = torch.tensor(kmeans.cluster_centers_) + + return preds_c, probs_c, z, z_mu, z_sigma2_log, z_mu, z_sigma2_log, pi, logits + + def infer_d_v_2(self, x, inject_domain): + """ + Used for tensorboard visualizations only. + """ + results = self._inference(x) + if len(inject_domain) > 0: + zy = torch.cat((results[2], inject_domain), 1) + else: + zy = results[2] + x_pro = self.decoder(zy) + + preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = (r.cpu().detach() for r in results) + + return preds, z_mu, z, log_sigma2_c, probs, x_pro + + def cal_loss(self, x, inject_domain, warmup_beta=None): + loss = self._cal_pretrain_loss(x, inject_domain) + return loss + + return ModelAE
[docs]def test_fun(d_dim, zd_dim, device): diff --git a/docs/build/html/_modules/domid/models/model_dec.html b/docs/build/html/_modules/domid/models/model_dec.html index df63caf..ad4286a 100644 --- a/docs/build/html/_modules/domid/models/model_dec.html +++ b/docs/build/html/_modules/domid/models/model_dec.html @@ -309,188 +309,176 @@

Source code for domid.models.model_dec

-import torch
+import os
+
+import torch
 import torch.nn as nn
-import torch.nn.functional as F
 from domainlab.utils.utils_classif import logit2preds_vpic
 
 from domid.compos.DEC_clustering_layer import DECClusteringLayer
 from domid.models.a_model_cluster import AModelCluster
 
 
-
[docs]class ModelDEC(AModelCluster): -
[docs] def __init__(self, zd_dim, d_dim, L, device, i_c, i_h, i_w, args): - """ - DEC model (Xie et al. 2015 "Unsupervised Deep Embedding for Clustering Analysis") with - fully connected encoder and decoder. - - :param zd_dim: dimension of the latent space - :param d_dim: number of clusters for the clustering task - :param device: device to use, e.g., "cuda" or "cpu" - :param i_c: number of channels of the input image - :param i_h: height of the input image - :param i_w: width of the input image - :param args: command line arguments - """ - super(ModelDEC, self).__init__() - self.n_clusters = d_dim - self.d_dim = d_dim - self.zd_dim = zd_dim - self.device = device - - self.alpha = 1 # FIXME - self.hidden = zd_dim - self.cluster_centers = None - self.dim_inject_y = 0 - self.warmup_beta = 0 - self.args = args - - if self.args.feat_extract == "vae": - from domid.compos.cnn_VAE import ConvolutionalDecoder, ConvolutionalEncoder - elif self.args.feat_extract == "ae": - from domid.compos.cnn_AE import ConvolutionalDecoder, ConvolutionalEncoder - - self.encoder = ConvolutionalEncoder(zd_dim=zd_dim, num_channels=i_c, i_w=i_w, i_h=i_h).to(device) - self.decoder = ConvolutionalDecoder( - prior=args.prior, - zd_dim=zd_dim, # 50 - domain_dim=self.dim_inject_y, # - # domain_dim=self.dim_inject_y, - h_dim=self.encoder.h_dim, - num_channels=i_c, - ).to(device) - - self.autoencoder = self.encoder - self.clusteringlayer = DECClusteringLayer( - self.n_clusters, self.hidden, None, self.alpha, self.device - ) # learnable parameter - cluster center - self.mu_c = self.clusteringlayer.cluster_centers - self.log_pi = nn.Parameter( - torch.FloatTensor( - self.d_dim, - ) - .fill_(1.0 / self.d_dim) - .log(), - requires_grad=True, - ) - if self.args.pre_tr_weight_path: - self.encoder.load_state_dict( - torch.load(self.args.pre_tr_weight_path + "encoder.pt", map_location=self.device) +
[docs]def mk_dec(parent_class=AModelCluster): + class ModelDEC(parent_class): + def __init__( + self, + zd_dim, + d_dim, + device, + i_c, + i_h, + i_w, + bs, + L=5, + random_batching=False, + model_method="cnn", + prior="Bern", + dim_inject_y=0, + pre_tr_weight_path=None, + feat_extract="vae", + ): + """ + DEC model (Xie et al. 2015 "Unsupervised Deep Embedding for Clustering Analysis") with + fully connected encoder and decoder. + + :param zd_dim: dimension of the latent space + :param d_dim: number of clusters for the clustering task + :param device: device to use, e.g., "cuda" or "cpu" + :param i_c: number of channels of the input image + :param i_h: height of the input image + :param i_w: width of the input image + :param args: command line arguments + """ + super(ModelDEC, self).__init__() + self.n_clusters = d_dim + self.d_dim = d_dim + self.zd_dim = zd_dim + self.device = device + + self.alpha = 1 # FIXME + self.hidden = zd_dim + self.cluster_centers = None + + self.warmup_beta = 0 + self.dim_inject_y = dim_inject_y + self.model_method = model_method + self.prior = prior + self.feat_extract = feat_extract + self.random_batching = random_batching + self.pre_tr_weight_path = pre_tr_weight_path + self.model = "dec" + + if self.feat_extract == "vae": + from domid.compos.cnn_VAE import ConvolutionalDecoder, ConvolutionalEncoder + elif self.feat_extract == "ae": + from domid.compos.cnn_AE import ConvolutionalDecoder, ConvolutionalEncoder + + self.encoder = ConvolutionalEncoder(zd_dim=zd_dim, num_channels=i_c, i_w=i_w, i_h=i_h).to(device) + self.decoder = ConvolutionalDecoder( + prior=prior, + zd_dim=zd_dim, # 50 + domain_dim=self.dim_inject_y, + h_dim=self.encoder.h_dim, + num_channels=i_c, + ).to(device) + + self.autoencoder = self.encoder + self.clusteringlayer = DECClusteringLayer( + self.n_clusters, self.hidden, None, self.alpha, self.device + ) # learnable parameter - cluster center + self.mu_c = self.clusteringlayer.cluster_centers + self.log_pi = nn.Parameter( + torch.FloatTensor( + self.d_dim, + ) + .fill_(1.0 / self.d_dim) + .log(), + requires_grad=True, ) - self.decoder.load_state_dict( - torch.load(self.args.pre_tr_weight_path + "decoder.pt", map_location=self.device) - ) - print("AE is using pretrained weights. No need for pretraining epochs. ") - self.log_sigma2_c = nn.Parameter(torch.FloatTensor(self.d_dim, self.zd_dim).fill_(0), requires_grad=True) - self.random_ind = []
- -
[docs] def target_distribution(self, q_): - """ - Corresponds to equation 3 from the paper. - Calculates the target distribution for the Kullback-Leibler divergence loss. - - :param q_: A tensor of the predicted cluster probabilities. - :return tensor: The calculated target distribution - """ - weight = (q_**2) / torch.sum(q_, 0) - return (weight.t() / torch.sum(weight, 1)).t()
- - def _inference(self, x): - """ - :return tensor preds_c: One hot encoded tensor of the predicted cluster assignment (shape: [batch_size, self.d_dim]). - :return tensor probs_c: Tensor of the predicted cluster probabilities; this is q(c|x) per eq. (16) or gamma_c in eq. (12) (shape: [batch_size, self.d_dim]). - :return tensor z: Tensor of the latent space representation (shape: [batch_size, self.zd_dim]) - :return tensor z_mu: Tensor of the mean of the latent space representation (shape: [batch_size, self.zd_dim]) - :return tensor z_sigma2_log: Tensor of the log of the variance of the latent space representation (shape: [batch_size, self.zd_dim]) - :return tensor mu_c: Tensor of the estimated cluster means (shape: [self.d_dim, self.zd_dim]) - :return tensor log_sigma2_c: Tensor of the estimated cluster variances (shape: [self.d_dim, self.zd_dim]) - :return tensor pi: Tensor of the estimated cluster prevalences, p(c) (shape: [self.d_dim]) - :return tensor logits: Tensor where each column contains the log-probability p(c)p(z|c) for cluster c=0,...,self.d_dim-1 (shape: [batch_size, self.d_dim]). - """ - if self.args.feat_extract == "vae": - - z_mu, z_sigma2_log = self.encoder(x) - z = z_mu # no reparametrization - elif self.args.feat_extract == "ae": - *_, z_mu = self.encoder(x) - z_sigma2_log = torch.Tensor([]).to(self.device) + if self.pre_tr_weight_path: + self.encoder.load_state_dict( + torch.load(os.path.join(self.pre_tr_weight_path, "encoder.pt"), map_location=self.device) + ) + self.decoder.load_state_dict( + torch.load(os.path.join(self.pre_tr_weight_path, "decoder.pt"), map_location=self.device) + ) + print("AE is using pretrained weights. No need for pretraining epochs. ") + self.log_sigma2_c = nn.Parameter(torch.FloatTensor(self.d_dim, self.zd_dim).fill_(0), requires_grad=True) + self.random_ind = [] + + def target_distribution(self, q_): + """ + Corresponds to equation 3 from the paper. + Calculates the target distribution for the Kullback-Leibler divergence loss. + + :param q_: A tensor of the predicted cluster probabilities. + :return tensor: The calculated target distribution + """ + weight = (q_**2) / torch.sum(q_, 0) + return (weight.t() / torch.sum(weight, 1)).t() + + def _inference(self, x): + """ + :return tensor preds_c: One hot encoded tensor of the predicted cluster assignment (shape: [batch_size, self.d_dim]). + :return tensor probs_c: Tensor of the predicted cluster probabilities; this is q(c|x) per eq. (16) or gamma_c in eq. (12) (shape: [batch_size, self.d_dim]). + :return tensor z: Tensor of the latent space representation (shape: [batch_size, self.zd_dim]) + :return tensor z_mu: Tensor of the mean of the latent space representation (shape: [batch_size, self.zd_dim]) + :return tensor z_sigma2_log: Tensor of the log of the variance of the latent space representation (shape: [batch_size, self.zd_dim]) + :return tensor mu_c: Tensor of the estimated cluster means (shape: [self.d_dim, self.zd_dim]) + :return tensor log_sigma2_c: Tensor of the estimated cluster variances (shape: [self.d_dim, self.zd_dim]) + :return tensor pi: Tensor of the estimated cluster prevalences, p(c) (shape: [self.d_dim]) + :return tensor logits: Tensor where each column contains the log-probability p(c)p(z|c) for cluster c=0,...,self.d_dim-1 (shape: [batch_size, self.d_dim]). + """ + + z_mu = self.encoder.get_z(x) z = z_mu + z_sigma2_log = self.encoder.get_log_sigma2(x) - probs_c = self.clusteringlayer(z_mu) # in dec it is - preds_c, logits, *_ = logit2preds_vpic(probs_c) # preds c is oen hot encoded - mu_c = self.mu_c - # print(mu_c[0, :5]) - log_sigma2_c = self.log_sigma2_c - pi = self.log_pi - - return preds_c, probs_c, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits - -
[docs] def infer_d_v(self, x): - - """ - :param x: input tensor(image) - :return tensor preds: Predicted cluster assignments of shape (shape: [batch_size, self.d_dim]). - """ - preds, *_ = self._inference(x) - return preds.cpu().detach()
- -
[docs] def infer_d_v_2(self, x, inject_domain): - - results = self._inference(x) - if len(inject_domain) > 0: - zy = torch.cat((results[2], inject_domain), 1) - else: - zy = results[2] - - x_pro, *_ = self.decoder(zy) - preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = (r.cpu().detach() for r in results) - return preds, z_mu, z, log_sigma2_c, probs, x_pro
- -
[docs] def pretrain_loss(self, x, inject_domain): - Loss = nn.MSELoss() - # Loss = nn.MSELoss(reduction='sum') - # Loss = nn.HuberLoss() - if self.args.feat_extract == "vae": - - z_mu, z_sigma2_log = self.encoder(x) - z = z_mu # no reparametrization - elif self.args.feat_extract == "ae": - *_, z_mu = self.encoder(x) - z = z_mu + probs_c = self.clusteringlayer(z_mu) # in dec it is + preds_c, logits, *_ = logit2preds_vpic(probs_c) # preds c is oen hot encoded + mu_c = self.mu_c + # print(mu_c[0, :5]) + log_sigma2_c = self.log_sigma2_c + pi = self.log_pi + + return preds_c, probs_c, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits + + def infer_d_v_2(self, x, inject_domain): + + results = self._inference(x) + if len(inject_domain) > 0: + zy = torch.cat((results[2], inject_domain), 1) + else: + zy = results[2] + + x_pro, *_ = self.decoder(zy) + preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = (r.cpu().detach() for r in results) + return preds, z_mu, z, log_sigma2_c, probs, x_pro + + def _cal_kl_loss(self, x, inject_tensor, warmup_beta=0.1): + """ + Calculates the KL-divergence loss between the predicted probabilities and the target distribution. + + :param x: input tensor/image + :param inject_tensor: tensor to inject (not used in DEC, only used in CDVaDE + :param warmup_beta: warm-up beta value + :return tensor loss (float): calculated KL-divergence loss value + """ + + preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = self._inference(x) + + target = self.target_distribution(probs).detach() + loss_function = nn.KLDivLoss(reduction="batchmean") + + loss = loss_function(probs.log(), target) + if self.warmup_beta != warmup_beta: + print(logits[0, :], target[0, :]) + print(loss) + self.warmup_beta = warmup_beta + return loss - # z_mu, z_sigma2_log = self.encoder(x) - # z = z_mu - # z = torch.randn_like(z_mu) * torch.exp(z_sigma2_log / 2) + z_mu - if len(inject_domain) > 0: - zy = torch.cat((z, inject_domain), 1) - else: - zy = z - - x_pro, *_ = self.decoder(zy) - loss = Loss(x, x_pro) - return loss
- -
[docs] def cal_loss(self, x, inject_tensor, warmup_beta): - """ - Calculates the KL-divergence loss between the predicted probabilities and the target distribution. - - :param x: input tensor/image - :param inject_tensor: tensor to inject (not used in DEC, only used in CDVaDE - :param warmup_beta: warm-up beta value - :return tensor loss (float): calculated KL-divergence loss value - """ - - preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = self._inference(x) - - target = self.target_distribution(probs).detach() - loss_function = nn.KLDivLoss(reduction="batchmean") - - loss = loss_function(probs.log(), target) - if self.warmup_beta != warmup_beta: - print(logits[0, :], target[0, :]) - print(loss) - self.warmup_beta = warmup_beta - return loss
+ return ModelDEC
diff --git a/docs/build/html/_modules/domid/models/model_m2yd.html b/docs/build/html/_modules/domid/models/model_m2yd.html index f2c9fe8..4975794 100644 --- a/docs/build/html/_modules/domid/models/model_m2yd.html +++ b/docs/build/html/_modules/domid/models/model_m2yd.html @@ -311,123 +311,143 @@

Source code for domid.models.model_m2yd

 import torch
 import torch.distributions as dist
-import torch.nn as nn
 import torch.nn.functional as F
 from domainlab.compos.vae.compos.decoder_concat_vec_reshape_conv_gated_conv import (
     DecoderConcatLatentFCReshapeConvGatedConv,
 )
-from domainlab.compos.vae.compos.encoder import LSEncoderDense
+from domainlab.compos.vae.compos.encoder import LSEncoderLinear as LSEncoderDense
 from domainlab.models.a_model_classif import AModelClassif
 from domainlab.utils.utils_class import store_args
 from domainlab.utils.utils_classif import get_label_na, logit2preds_vpic
 
 from domid.compos.nn_net import Net_MNIST
+from domid.utils.perf_cluster import PerfCluster
 
 
-
[docs]class ModelXY2D(AModelClassif): - """ - Let zd to be continuous vector, each component of zd represents the "attention" weight. - For a cluster, that means the bigger the $zd_k$ value, the more likely the cluster assignment - to component $k$. Note $zd_k~N(0,1)$. - - Computational Structure: - generative path: (zd,y) -> x (image) - generative path: N(0,I) -> zd (prior for zd) - variational posterior path: - 1. x -> y, - 2. [y, feat(x)] -> z_d - - FIXME: if we change the variational inference order, instead of x->y, then [y,feat(x)]->z_d - if we do first x->d (style extraction, texture prediction), - then [feat(x),d]-> y, will this be better? - - KL divergence between posterior path vs generative(prior) path: - 1. x->y: auxiliary path (not regularized by generative path, but by supervised learning) - no KL for y - 2. KL(q(z_d)|p(z_d)), - q(z_d): [y,feat(x)]-> z_d - p(z_d): N(0,I) - - Auxilliary path: supervised learning of x->y - - FIXME: original M2 has prior Gaussian(0, I) for $z_d$, will this hinder learning of $z_d$ - on each component since the prior is draging each component to zero. - """ - -
[docs] @store_args - def __init__(self, list_str_y, y_dim, zd_dim, gamma_y, device, i_c, i_h, i_w, dim_feat_x=10, list_str_d=None): - """ - :param y_dim: classification task class-label dimension - :param zd_dim: dimension of latent variable $z_d$ dimension - :param aux_y: - """ - super().__init__(list_str_y, list_str_d) - self.d_dim = zd_dim # number of domains - self.infer_y_from_x = Net_MNIST(y_dim, self.i_h) - self.feat_x2concat_y = Net_MNIST(self.dim_feat_x, self.i_h) - # FIXME: shall we share parameters between infer_y_from_x and self.feat_x2concat_y? - self.infer_domain = LSEncoderDense(z_dim=self.zd_dim, dim_input=self.dim_feat_x + self.y_dim) - self.gamma_y = gamma_y - # LN: location scale encoder - self.decoder = DecoderConcatLatentFCReshapeConvGatedConv( - z_dim=zd_dim + y_dim, i_c=self.i_c, i_w=self.i_w, i_h=self.i_h - )
- -
[docs] def cal_logit_y(self, tensor_x): +
[docs]def mk_m2yd(parent_class=AModelClassif): + class ModelXY2D(AModelClassif): """ - calculate the logit for softmax classification + Let zd to be continuous vector, each component of zd represents the "attention" weight. + For a cluster, that means the bigger the $zd_k$ value, the more likely the cluster assignment + to component $k$. Note $zd_k~N(0,1)$. + + Computational Structure: + generative path: (zd,y) -> x (image) + generative path: N(0,I) -> zd (prior for zd) + variational posterior path: + 1. x -> y, + 2. [y, feat(x)] -> z_d + + FIXME: if we change the variational inference order, instead of x->y, then [y,feat(x)]->z_d + if we do first x->d (style extraction, texture prediction), + then [feat(x),d]-> y, will this be better? + + KL divergence between posterior path vs generative(prior) path: + 1. x->y: auxiliary path (not regularized by generative path, but by supervised learning) + no KL for y + 2. KL(q(z_d)|p(z_d)), + q(z_d): [y,feat(x)]-> z_d + p(z_d): N(0,I) + + Auxilliary path: supervised learning of x->y + + FIXME: original M2 has prior Gaussian(0, I) for $z_d$, will this hinder learning of $z_d$ + on each component since the prior is draging each component to zero. """ - return self.infer_y_from_x(tensor_x)
-
[docs] def infer_y_vpicn(self, tensor_x): - """ - :param tensor_x: input tensor - :return: - - vec_one_hot - (list) one-hot encoded classification output - - prob - (list) softmax probabilities per class - - ind - (int) index of maximal output class score - - confidence - (float) maximum probability (already included in prob) - - na_class - (string) class label for the maximum probability class - """ - with torch.no_grad(): - logit_y = self.infer_y_from_x(tensor_x) - vec_one_hot, prob, ind, confidence = logit2preds_vpic(logit_y) - na_class = get_label_na(ind, self.list_str_y) - return vec_one_hot, prob, ind, confidence, na_class
- -
[docs] def infer_d_v(self, tensor_x): - with torch.no_grad(): + @store_args + def __init__(self, list_str_y, y_dim, zd_dim, gamma_y, device, i_c, i_h, i_w, dim_feat_x=10): + """ + :param y_dim: classification task class-label dimension + :param zd_dim: dimension of latent variable $z_d$ dimension + :param aux_y: + """ + super().__init__(list_str_y=list_str_y, net_classifier=None) + self.infer_y_from_x = Net_MNIST(y_dim, self.i_h) + self._net_classifier = self.infer_y_from_x # FIXME: this is a hack, and may not be needed at all + self.d_dim = zd_dim # number of domains + self.feat_x2concat_y = Net_MNIST(self.dim_feat_x, self.i_h) + # FIXME: shall we share parameters between infer_y_from_x and self.feat_x2concat_y? + self.infer_domain = LSEncoderDense(z_dim=self.zd_dim, dim_input=self.dim_feat_x + self.y_dim) + self.gamma_y = gamma_y + # LN: location scale encoder + self.decoder = DecoderConcatLatentFCReshapeConvGatedConv( + z_dim=zd_dim + y_dim, i_c=self.i_c, i_w=self.i_w, i_h=self.i_h + ) + + def cal_logit_y(self, tensor_x): + """ + calculate the logit for softmax classification + """ + return self.infer_y_from_x(tensor_x) + + def infer_y_vpicn(self, tensor_x): + """ + :param tensor_x: input tensor + :return: + - vec_one_hot - (list) one-hot encoded classification output + - prob - (list) softmax probabilities per class + - ind - (int) index of maximal output class score + - confidence - (float) maximum probability (already included in prob) + - na_class - (string) class label for the maximum probability class + """ + with torch.no_grad(): + logit_y = self.infer_y_from_x(tensor_x) + vec_one_hot, prob, ind, confidence = logit2preds_vpic(logit_y) + na_class = get_label_na(ind, self.list_str_y) + return vec_one_hot, prob, ind, confidence, na_class + + def infer_d_v(self, tensor_x): + with torch.no_grad(): + y_hat_logit = self.infer_y_from_x(tensor_x) + feat_x = self.feat_x2concat_y(tensor_x) + feat_y_x = torch.cat((y_hat_logit, feat_x), dim=1) + q_zd, zd_q = self.infer_domain(feat_y_x) + vec_one_hot, *_ = logit2preds_vpic(q_zd.mean) + return vec_one_hot + + def forward(self, tensor_x, vec_y, vec_d=None): y_hat_logit = self.infer_y_from_x(tensor_x) feat_x = self.feat_x2concat_y(tensor_x) feat_y_x = torch.cat((y_hat_logit, feat_x), dim=1) q_zd, zd_q = self.infer_domain(feat_y_x) - vec_one_hot, *_ = logit2preds_vpic(q_zd.mean) - return vec_one_hot
- -
[docs] def forward(self, tensor_x, vec_y, vec_d=None): - y_hat_logit = self.infer_y_from_x(tensor_x) - feat_x = self.feat_x2concat_y(tensor_x) - feat_y_x = torch.cat((y_hat_logit, feat_x), dim=1) - q_zd, zd_q = self.infer_domain(feat_y_x) - return q_zd, zd_q, y_hat_logit
- -
[docs] def cal_loss(self, x, y, d=None, others=None): - q_zd, zd_q, y_hat = self.forward(x, y) - z_con = torch.cat((zd_q, y), dim=1) # FIXME: pay attention to order - - nll, x_mean, x_logvar = self.decoder(z_con, x) - pzd_loc = torch.zeros(1, self.zd_dim).to(self.device) - pzd_scale = torch.ones(self.zd_dim).to(self.device) - pzd = dist.Normal(pzd_loc, pzd_scale) - - pzd_log_prob = pzd.log_prob(zd_q) - qzd_log_prob = q_zd.log_prob(zd_q) - zd_p_minus_zd_q = torch.sum(pzd_log_prob - qzd_log_prob, dim=1) - # FIXME: use analytical expression since using sampling to estimate KL divergence is high variance - _, y_target = y.max(dim=1) # y is the observed class label, not the cluster label! - lc_y = F.cross_entropy(y_hat, y_target, reduction="none") - loss = nll - zd_p_minus_zd_q + self.gamma_y * lc_y - return loss.mean()
+ return q_zd, zd_q, y_hat_logit + + def cal_loss(self, x, y, d=None, others=None): + q_zd, zd_q, y_hat = self.forward(x, y) + z_con = torch.cat((zd_q, y), dim=1) # FIXME: pay attention to order + + nll, x_mean, x_logvar = self.decoder(z_con, x) + pzd_loc = torch.zeros(1, self.zd_dim).to(self.device) + pzd_scale = torch.ones(self.zd_dim).to(self.device) + pzd = dist.Normal(pzd_loc, pzd_scale) + + pzd_log_prob = pzd.log_prob(zd_q) + qzd_log_prob = q_zd.log_prob(zd_q) + zd_p_minus_zd_q = torch.sum(pzd_log_prob - qzd_log_prob, dim=1) + # FIXME: use analytical expression since using sampling to estimate KL divergence is high variance + _, y_target = y.max(dim=1) # y is the observed class label, not the cluster label! + lc_y = F.cross_entropy(y_hat, y_target, reduction="none") + loss = nll - zd_p_minus_zd_q + self.gamma_y * lc_y + return loss.mean() + + def cal_perf_metric(self, loader_tr, device, loader_te=None): + """ + Clustering performance metric on the training and test/validation sets. + """ + self.perf_metric = PerfCluster( + self.d_dim + ) # FIXME: this is a hack because self.perf_metric is actually defined somewhere else (not in this file) + metric_te = None + metric_tr = None + with torch.no_grad(): + metric_tr = self.perf_metric.cal_acc(self, loader_tr, device) + if loader_te is not None: + metric_te = self.perf_metric.cal_acc(self, loader_te, device) + return metric_tr, metric_te, None, None + # FIXME: the None values are a hack, because of the clusteringOnly observer used with M2YD; eventually, need to update M2YD model to use a specializaed observer (probably the clustering observer, which needs refactoring, as opposed to the clusteringOnly one) + + return ModelXY2D
[docs]def test_fun(): diff --git a/docs/build/html/_modules/domid/models/model_sdcn.html b/docs/build/html/_modules/domid/models/model_sdcn.html index 943985c..9e92d9b 100644 --- a/docs/build/html/_modules/domid/models/model_sdcn.html +++ b/docs/build/html/_modules/domid/models/model_sdcn.html @@ -309,7 +309,9 @@

Source code for domid.models.model_sdcn

-import torch
+import os
+
+import torch
 import torch.nn as nn
 import torch.nn.functional as F
 from domainlab.utils.utils_classif import logit2preds_vpic
@@ -320,241 +322,247 @@ 

Source code for domid.models from domid.models.a_model_cluster import AModelCluster -
[docs]class ModelSDCN(AModelCluster): - """ - ModelSDCN is a class that implements the SDCN model.(Bo D et al. 2020) - The model is composed of a convolutional encoder and decoder, a GNN and a clustering layer. - """ - -
[docs] def __init__(self, zd_dim, d_dim, device, L, i_c, i_h, i_w, args): - - super(ModelSDCN, self).__init__() - self.zd_dim = zd_dim - self.d_dim = d_dim - self.device = device - self.L = L - self.args = args - self.loss_epoch = 0 - self.dim_inject_y = 0 - - if self.args.dim_inject_y: - self.dim_inject_y = self.args.dim_inject_y - - n_clusters = d_dim - n_z = zd_dim - n_input = i_c * i_h * i_w - - self.cluster_layer = nn.Parameter(torch.Tensor(self.d_dim, self.zd_dim)) - torch.nn.init.xavier_normal_(self.cluster_layer.data) - - if self.args.model == "linear": - n_enc_1, n_enc_2, n_enc_3, n_dec_1, n_dec_2, n_dec_3, = ( - 500, - 500, - 2000, - 2000, - 500, - 500, - ) - self.encoder = LinearEncoderAE(n_enc_1, n_enc_2, n_enc_3, n_input, n_z) - self.decoder = LinearDecoderAE(n_dec_1, n_dec_2, n_dec_3, n_input, n_z) - - else: - self.encoder = ConvolutionalEncoder(zd_dim=zd_dim, num_channels=i_c, i_w=i_w, i_h=i_h).to(device) - self.decoder = ConvolutionalDecoder( - prior=args.prior, - zd_dim=zd_dim, # 50 - domain_dim=self.dim_inject_y, - h_dim=self.encoder.h_dim, - num_channels=i_c, - ).to(device) - n_enc_1, n_enc_2, n_enc_3, n_dec_1, n_dec_2, n_dec_3, = ( - int((i_w / 2) ** 2 * self.encoder.num_filters[0]), - int((i_w / 4) ** 2 * self.encoder.num_filters[1]), - int((i_w / 8) ** 2 * self.encoder.num_filters[2]), - int((i_w / 8) ** 2 * self.encoder.num_filters[2]), - int((i_w / 4) ** 2 * self.encoder.num_filters[1]), - int((i_w / 2) ** 2 * self.encoder.num_filters[0]), - ) - print("Filter sizes for GNN", n_enc_1, n_enc_2, n_enc_3, n_dec_1, n_dec_2, n_dec_3) - if self.args.pre_tr_weight_path: - self.encoder.load_state_dict( - torch.load(self.args.pre_tr_weight_path + "encoder.pt", map_location=self.device) - ) - self.decoder.load_state_dict( - torch.load(self.args.pre_tr_weight_path + "decoder.pt", map_location=self.device) - ) - print("Pre-trained weights loaded") - else: - raise ValueError("Pre-trianed weight path is not provided") - - self.gnn_model = GNN(n_input, n_enc_1, n_enc_2, n_enc_3, n_z, n_clusters, device) - - if torch.cuda.device_count() > 1: # Check if multiple GPUs are available - print("Using DataParallel with {} GPUs.".format(torch.cuda.device_count())) - # self.gnn_model = torch.nn.DataParallel(self.gnn_model) # Wrap the model for DataParallel - self.encoder = torch.nn.DataParallel(self.encoder) - self.decoder = torch.nn.DataParallel(self.decoder) - - else: - if torch.cuda.device_count() == 1: - print("Using a single GPU.") - else: - print("Using CPU(s).") - - self.v = 1.0 - self.counter = 0 - self.q_activation = torch.zeros((10, 100)) - self.kl_loss_running = 0 - self.re_loss_running = 0 - self.ce_loss_running = 0 - - if "mnist" in self.args.task: - self.graph_method = "heat" - if "wsi" in self.args.task: - self.graph_method = "patch_distance" - if self.args.graph_method is not None: - self.graph_method = args.graph_method - - if args.task == "wsi": - self.random_ind = [torch.randint(0, self.args.bs, (int(self.args.bs / 3),)) for i in range(0, 66)] - else: - self.random_ind = []
- - def _inference(self, x, inject_tensor=None): - """ - :param x: [batch_size, n_channels, height, width] - :return: - - probs_c - [batch_size, n_clusters] - - q - [batch_size, n_clusters] - - z - [batch_size, n_z] - - z_mu - [batch_size, n_z] - - z_sigma2_log - [batch_size, n_z] - - pi - [batch_size, n_clusters] - - logits - [batch_size, n_clusters] +
[docs]def mk_sdcn(parent_class=AModelCluster): + class ModelSDCN(parent_class): """ - if self.args.model == "linear": - x = torch.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3])) - enc_h1, enc_h2, enc_h3, z = self.encoder(x) - - h = self.gnn_model(x, self.adj.to(self.device), enc_h1, enc_h2, enc_h3, z) - probs_c = F.softmax( - h, dim=1 - ) # [batch_size, n_clusters] (batch_zise==number of samples) same as preds in the code - # and p is calculated using preds and target distribution. - - # Dual Self-supervised Module - q = 1.0 / (1.0 + torch.sum(torch.pow(z.unsqueeze(1) - self.cluster_layer, 2), 2)) / self.v - q = q.pow((self.v + 1.0) / 2.0) - q = (q.t() / torch.sum(q, 1)).t() - - logits = q.type(torch.float32) # q in the paper and code - - preds_c, *_ = logit2preds_vpic(h) # probs_c is F.softmax(logit, dim=1) - - return preds_c, probs_c, z, logits - -
[docs] def infer_d_v(self, x): + ModelSDCN is a class that implements the SDCN model.(Bo D et al. 2020) + The model is composed of a convolutional encoder and decoder, a GNN and a clustering layer. """ - Predict the cluster/domain of the input data. - Corresponds to equation (16) in the paper. - :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. - :return tensor preds: One hot encoded tensor of the predicted cluster assignment. - """ - preds, *_ = self._inference(x) - return preds.cpu().detach()
- -
[docs] def infer_d_v_2(self, x): - """ - Used for tensorboard visualizations only. - """ - # import pdb; pdb.set_trace() - results = self._inference(x) - - z = results[2] - - # print(results[2].shape, inject_domain.shape, zy.shape) - x_pro = self.decoder(z) - preds_c, probs_c, z, logits = (r.cpu().detach() for r in results) - - return preds_c, z, probs_c, x_pro
- -
[docs] def target_distribution(self, q): - """ - Compute the target distribution p, where p_i = (sum_j q_j)^2 / sum_j^2 q_j. - Corresponds to equation (12) from the paper. - """ - weight = q**2 / q.sum(0) - return (weight.t() / weight.sum(1)).t()
+ def __init__( + self, + zd_dim, + d_dim, + device, + i_c, + i_h, + i_w, + bs, + task, + L=5, + random_batching=False, + model_method="cnn", + prior="Bern", + dim_inject_y=0, + pre_tr_weight_path=None, + feat_extract="vae", + graph_method="heat", + ): + + super(ModelSDCN, self).__init__() + self.zd_dim = zd_dim + self.d_dim = d_dim + self.device = device + self.L = L + + self.loss_epoch = 0 + self.dim_inject_y = dim_inject_y + self.prior = prior + self.model_method = model_method + self.random_batching = random_batching + self.pre_tr_weight_path = pre_tr_weight_path + self.feat_extract = feat_extract + self.task = task + self.model = "sdcn" + + # if self.args.dim_inject_y: + # self.dim_inject_y = self.args.dim_inject_y + + n_clusters = d_dim + n_z = zd_dim + n_input = i_c * i_h * i_w + + self.cluster_layer = nn.Parameter(torch.Tensor(self.d_dim, self.zd_dim)) + torch.nn.init.xavier_normal_(self.cluster_layer.data) + + if self.model_method == "linear": + n_enc_1, n_enc_2, n_enc_3, n_dec_1, n_dec_2, n_dec_3, = ( + 500, + 500, + 2000, + 2000, + 500, + 500, + ) + self.encoder = LinearEncoderAE(n_enc_1, n_enc_2, n_enc_3, n_input, n_z) + self.decoder = LinearDecoderAE(n_dec_1, n_dec_2, n_dec_3, n_input, n_z) -
[docs] def cal_loss(self, x, warmup_beta=None): - """ - Compute the loss of the model. - Concentrate two different objectives, i.e. clustering objective and classification objective, in one loss function. - Corresponds to equation (15) in the paper. - :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. - :param float warmup_beta: Warmup coefficient for the KL divergence term. - :return tensor loss: Loss tensor. - """ - - preds_c, probs_c, z, logits = self._inference(x) - # logits is q in the paper - # probs_c is pred in the code - q = logits - pred = probs_c - - x_bar = self.decoder(z) - q = q.data - - # if self.counter==1: - p = self.target_distribution(q) - - # self.local_tb.add_histogram('p', p, self.counter) - - if self.args.model == "linear": - x = torch.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3])) - - kl_loss = F.kl_div(q.log(), p, reduction="batchmean") - ce_loss = F.kl_div(pred.log(), p, reduction="batchmean") - re_loss = F.mse_loss(x, x_bar) - - loss = 0.1 * kl_loss + 0.01 * ce_loss + re_loss - - self.kl_loss_running = kl_loss - self.ce_loss_running = ce_loss - self.re_loss_running = re_loss - - return loss.type(torch.double)
- -
[docs] def cal_loss_for_tensorboard(self): - return self.kl_loss_running, self.ce_loss_running, self.re_loss_running
- -
[docs] def pretrain_loss(self, x): - if self.args.model == "linear": - x = torch.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3])) - enc_h1, enc_h2, enc_h3, z = self.encoder(x) - - x_pro = self.decoder(z) - loss = F.mse_loss(x, x_pro) + else: + self.encoder = ConvolutionalEncoder(zd_dim=zd_dim, num_channels=i_c, i_w=i_w, i_h=i_h).to(device) + self.decoder = ConvolutionalDecoder( + prior=prior, + zd_dim=zd_dim, # 50 + domain_dim=self.dim_inject_y, + h_dim=self.encoder.h_dim, + num_channels=i_c, + ).to(device) + n_enc_1, n_enc_2, n_enc_3, n_dec_1, n_dec_2, n_dec_3, = ( + int((i_w / 2) ** 2 * self.encoder.num_filters[0]), + int((i_w / 4) ** 2 * self.encoder.num_filters[1]), + int((i_w / 8) ** 2 * self.encoder.num_filters[2]), + int((i_w / 8) ** 2 * self.encoder.num_filters[2]), + int((i_w / 4) ** 2 * self.encoder.num_filters[1]), + int((i_w / 2) ** 2 * self.encoder.num_filters[0]), + ) + print("Filter sizes for GNN", n_enc_1, n_enc_2, n_enc_3, n_dec_1, n_dec_2, n_dec_3) + if self.pre_tr_weight_path: + self.encoder.load_state_dict( + torch.load(os.path.join(self.pre_tr_weight_path, "encoder.pt"), map_location=self.device) + ) + self.decoder.load_state_dict( + torch.load(os.path.join(self.pre_tr_weight_path, "decoder.pt"), map_location=self.device) + ) + print("Pre-trained weights loaded") + else: + raise ValueError("Pre-trianed weight path is not provided") - return loss
+ self.gnn_model = GNN(n_input, n_enc_1, n_enc_2, n_enc_3, n_z, n_clusters, device) + if torch.cuda.device_count() > 1: # Check if multiple GPUs are available + print("Using DataParallel with {} GPUs.".format(torch.cuda.device_count())) + # self.gnn_model = torch.nn.DataParallel(self.gnn_model) # Wrap the model for DataParallel + self.encoder = torch.nn.DataParallel(self.encoder) + self.decoder = torch.nn.DataParallel(self.decoder) -# def test_fun(d_dim, zd_dim, device): -# device = torch.device("cpu") -# model = ModelVaDE(d_dim=d_dim, zd_dim=zd_dim, device=device) -# x = torch.rand(2, 3, 28, 28) -# import numpy as np -# -# a = np.zeros((2, 10)) -# a = np.double(a) -# a[0, 1] = 1.0 -# a[1, 8] = 1.0 -# a -# y = torch.tensor(a, dtype=torch.float) -# model(x, y) -# model.cal_loss(x) + else: + if torch.cuda.device_count() == 1: + print("Using a single GPU.") + else: + print("Using CPU(s).") + + self.v = 1.0 + self.counter = 0 + self.q_activation = torch.zeros((10, 100)) + self.kl_loss_running = 0 + self.re_loss_running = 0 + self.ce_loss_running = 0 + + if "mnist" in self.task: + self.graph_method = "heat" + if "wsi" in self.task: + self.graph_method = "patch_distance" + if self.graph_method is not None: + self.graph_method = graph_method + + if self.task == "wsi": + self.random_ind = [torch.randint(0, self.bs, (int(self.bs / 3),)) for i in range(0, 66)] + else: + self.random_ind = [] + + def _inference(self, x, inject_tensor=None): + """ + :param x: [batch_size, n_channels, height, width] + :return: + - probs_c - [batch_size, n_clusters] + - q - [batch_size, n_clusters] + - z - [batch_size, n_z] + - z_mu - [batch_size, n_z] + - z_sigma2_log - [batch_size, n_z] + - pi - [batch_size, n_clusters] + - logits - [batch_size, n_clusters] + """ + if self.model_method == "linear": + x = torch.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3])) + enc_h1, enc_h2, enc_h3, z = self.encoder(x) + + h = self.gnn_model(x, self.adj.to(self.device), enc_h1, enc_h2, enc_h3, z) + probs_c = F.softmax( + h, dim=1 + ) # [batch_size, n_clusters] (batch_zise==number of samples) same as preds in the code + # and p is calculated using preds and target distribution. + + # Dual Self-supervised Module + q = 1.0 / (1.0 + torch.sum(torch.pow(z.unsqueeze(1) - self.cluster_layer, 2), 2)) / self.v + q = q.pow((self.v + 1.0) / 2.0) + q = (q.t() / torch.sum(q, 1)).t() + + logits = q.type(torch.float32) # q in the paper and code + + preds_c, *_ = logit2preds_vpic(h) # probs_c is F.softmax(logit, dim=1) + + return preds_c, probs_c, z, logits + + def infer_d_v_2(self, x): + """ + Used for tensorboard visualizations only. + """ + # import pdb; pdb.set_trace() + results = self._inference(x) + + z = results[2] + + # print(results[2].shape, inject_domain.shape, zy.shape) + x_pro = self.decoder(z) + preds_c, probs_c, z, logits = (r.cpu().detach() for r in results) + + return preds_c, z, probs_c, x_pro + + def target_distribution(self, q): + """ + Compute the target distribution p, where p_i = (sum_j q_j)^2 / sum_j^2 q_j. + Corresponds to equation (12) from the paper. + """ + weight = q**2 / q.sum(0) + return (weight.t() / weight.sum(1)).t() + + def _cal_kl_loss(self, x, inject_tensor=None, warmup_beta=None): + """ + Compute the loss of the model. + Concentrate two different objectives, i.e. clustering objective and classification objective, in one loss function. + Corresponds to equation (15) in the paper. + :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. + :param float warmup_beta: Warmup coefficient for the KL divergence term. + :return tensor loss: Loss tensor. + """ + + preds_c, probs_c, z, logits = self._inference(x) + # logits is q in the paper + # probs_c is pred in the code + q = logits + pred = probs_c + + x_bar = self.decoder(z) + q = q.data + + # if self.counter==1: + p = self.target_distribution(q) + + # self.local_tb.add_histogram('p', p, self.counter) + + if self.model == "linear": + x = torch.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3])) + + kl_loss = F.kl_div(q.log(), p, reduction="batchmean") + ce_loss = F.kl_div(pred.log(), p, reduction="batchmean") + re_loss = F.mse_loss(x, x_bar) + + loss = 0.1 * kl_loss + 0.01 * ce_loss + re_loss + + self.kl_loss_running = kl_loss + self.ce_loss_running = ce_loss + self.re_loss_running = re_loss + + return loss.type(torch.double) + + def cal_loss_for_tensorboard(self): + return self.kl_loss_running, self.ce_loss_running, self.re_loss_running + + def hyper_init(self, functor_scheduler): + """hyper_init. + :param functor_scheduler: + """ + return functor_scheduler(trainer=None) + + def hyper_update(self, epoch, fun_scheduler): + """hyper_update. + :param epoch: + :param fun_scheduler: the hyperparameter scheduler object + """ + dict_rst = fun_scheduler(epoch) # the __call__ method of hy + # perparameter scheduler + self.alpha = dict_rst["alpha"] + + return ModelSDCN

diff --git a/docs/build/html/_modules/domid/models/model_vade.html b/docs/build/html/_modules/domid/models/model_vade.html index 34bd65d..26b6fd8 100644 --- a/docs/build/html/_modules/domid/models/model_vade.html +++ b/docs/build/html/_modules/domid/models/model_vade.html @@ -316,281 +316,268 @@

Source code for domid.models import torch.nn as nn import torch.nn.functional as F from domainlab.utils.utils_classif import logit2preds_vpic -from tensorboardX import SummaryWriter from domid.compos.cnn_VAE import ConvolutionalDecoder, ConvolutionalEncoder from domid.compos.linear_VAE import LinearDecoder, LinearEncoder from domid.models.a_model_cluster import AModelCluster - -
[docs]class ModelVaDE(AModelCluster): -
[docs] def __init__(self, zd_dim, d_dim, device, L, i_c, i_h, i_w, args): - """ - VaDE model (Jiang et al. 2017 "Variational Deep Embedding: - An Unsupervised and Generative Approach to Clustering") with - fully connected encoder and decoder. - - :param zd_dim: dimension of the latent space - :param d_dim: number of clusters for the clustering task - :param device: device to use, e.g., "cuda" or "cpu" - :param i_c: number of channels of the input image - :param i_h: height of the input image - :param i_w: width of the input image - :param args: command line arguments - """ - super(ModelVaDE, self).__init__() - self.zd_dim = zd_dim - self.d_dim = d_dim - self.device = device - self.L = L - self.args = args - self.loss_epoch = 0 - - self.dim_inject_y = 0 - - if self.args.dim_inject_y: - self.dim_inject_y = self.args.dim_inject_y - - # self.dim_inject_domain = 0 - # if self.args.path_to_domain: # FIXME: one can simply read from the file to find out the injected dimension - # self.dim_inject_domain = args.d_dim # FIXME: allow arbitrary domain vector to be injected - - if self.args.model == "linear": - self.encoder = LinearEncoder(zd_dim=zd_dim, input_dim=(i_c, i_h, i_w)).to(device) - self.decoder = LinearDecoder(prior=args.prior, zd_dim=zd_dim, input_dim=(i_c, i_h, i_w)).to(device) - if self.dim_inject_y: - warnings.warn("linear model decoder does not support label injection") - else: - self.encoder = ConvolutionalEncoder(zd_dim=zd_dim, num_channels=i_c, i_w=i_w, i_h=i_h).to(device) - self.decoder = ConvolutionalDecoder( - prior=args.prior, - zd_dim=zd_dim, # 50 - domain_dim=self.dim_inject_y, # - # domain_dim=self.dim_inject_y, - h_dim=self.encoder.h_dim, - num_channels=i_c, - ).to(device) - print(self.encoder) - print(self.decoder) - self.log_pi = nn.Parameter( - torch.FloatTensor( - self.d_dim, +# from tensorboardX import SummaryWriter + + + +
[docs]def mk_vade(parent_class=AModelCluster): + class ModelVaDE(parent_class): + def __init__( + self, + zd_dim, + d_dim, + device, + i_c, + i_h, + i_w, + bs, + L=5, + random_batching=False, + model_method="cnn", + prior="Bern", + dim_inject_y=0, + pre_tr_weight_path=None, + feat_extract="vae", + ): + """ + VaDE model (Jiang et al. 2017 "Variational Deep Embedding: + An Unsupervised and Generative Approach to Clustering") with + fully connected encoder and decoder. + + :param zd_dim: dimension of the latent space + :param d_dim: number of clusters for the clustering task + :param device: device to use, e.g., "cuda" or "cpu" + :param i_c: number of channels of the input image + :param i_h: height of the input image + :param i_w: width of the input image + :param args: command line arguments + """ + super(ModelVaDE, self).__init__() + self.zd_dim = zd_dim + self.d_dim = d_dim + self.device = device + self.L = L + self.loss_epoch = 0 + self.prior = prior + self.dim_inject_y = dim_inject_y + self.model_method = model_method + self.model = "vade" + self.random_batching = random_batching + self.bs = bs + self.pre_tr_weight_path = pre_tr_weight_path + self.feat_extract = feat_extract + + # if self.args.dim_inject_y: + # self.dim_inject_y = self.args.dim_inject_y + + # self.dim_inject_domain = 0 + + # if self.args.path_to_domain: # FIXME: one can simply read from the file to find out the injected dimension + # self.dim_inject_domain = args.d_dim # FIXME: allow arbitrary domain vector to be injected + + # if self.args.model_method == "linear": + if self.model_method == "linear": + self.encoder = LinearEncoder(zd_dim=zd_dim, input_dim=(i_c, i_h, i_w)).to(device) + self.decoder = LinearDecoder(prior=prior, zd_dim=zd_dim, input_dim=(i_c, i_h, i_w)).to(device) + if self.dim_inject_y > 0: + warnings.warn("linear model decoder does not support label injection") + else: + self.encoder = ConvolutionalEncoder(zd_dim=zd_dim, num_channels=i_c, i_w=i_w, i_h=i_h).to(device) + self.decoder = ConvolutionalDecoder( + prior=prior, + zd_dim=zd_dim, # 50 + domain_dim=self.dim_inject_y, + h_dim=self.encoder.h_dim, + num_channels=i_c, + ).to(device) + print(self.encoder) + print(self.decoder) + self.log_pi = nn.Parameter( + torch.FloatTensor( + self.d_dim, + ) + .fill_(1.0 / self.d_dim) + .log(), + requires_grad=True, ) - .fill_(1.0 / self.d_dim) - .log(), - requires_grad=True, - ) - self.mu_c = nn.Parameter(torch.FloatTensor(self.d_dim, self.zd_dim).fill_(0), requires_grad=True) - self.log_sigma2_c = nn.Parameter(torch.FloatTensor(self.d_dim, self.zd_dim).fill_(0), requires_grad=True) - - self.loss_writter = SummaryWriter()
- - def _inference(self, x): - """Auxiliary function for inference - - :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. - :return tensor preds_c: One hot encoded tensor of the predicted cluster assignment (shape: [batch_size, self.d_dim]). - :return tensor probs_c: Tensor of the predicted cluster probabilities; this is q(c|x) per eq. (16) or gamma_c in eq. (12) (shape: [batch_size, self.d_dim]). - :return tensor z: Tensor of the latent space representation (shape: [batch_size, self.zd_dim]) - :return tensor z_mu: Tensor of the mean of the latent space representation (shape: [batch_size, self.zd_dim]) - :return tensor z_sigma2_log: Tensor of the log of the variance of the latent space representation (shape: [batch_size, self.zd_dim]) - :return tensor mu_c: Tensor of the estimated cluster means (shape: [self.d_dim, self.zd_dim]) - :return tensor log_sigma2_c: Tensor of the estimated cluster variances (shape: [self.d_dim, self.zd_dim]) - :return tensor pi: Tensor of the estimated cluster prevalences, p(c) (shape: [self.d_dim]) - :return tensor logits: Tensor where each column contains the log-probability p(c)p(z|c) for cluster c=0,...,self.d_dim-1 (shape: [batch_size, self.d_dim]). - """ - - z_mu, z_sigma2_log = self.encoder(x) - z = torch.randn_like(z_mu) * torch.exp(z_sigma2_log / 2) + z_mu - pi = F.softmax(self.log_pi, dim=0) - # if torch.any(pi<0.01): - # for i in range(len(pi)): - # if pi[i]<0.01: - # - # difference = (0.01-pi[i])/(self.d_dim) - # pi+= difference - # pi[i]=0.01 - # pi[:i]+=difference - # pi[i+1:]+=difference - - mu_c = self.mu_c - log_sigma2_c = self.log_sigma2_c - - logits = torch.log(pi.unsqueeze(0)) + self.gaussian_pdfs_log(z, mu_c, log_sigma2_c) - # shape [batch_size, self.d_dim], each column contains the log-probability p(c)p(z|c) for cluster c=0,...,self.d_dim-1. - - preds_c, probs_c, *_ = logit2preds_vpic(logits) - - return preds_c, probs_c, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits - -
[docs] def infer_d_v(self, x): - """ - Predict the cluster/domain of the input data. - Corresponds to equation (16) in the paper. - - :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. - :return tensor preds: One hot encoded tensor of the predicted cluster assignment. - """ - preds, *_ = self._inference(x) - return preds.cpu().detach()
- -
[docs] def infer_d_v_2(self, x, inject_domain): - """ - Used for tensorboard visualizations only. - """ - results = self._inference(x) - if len(inject_domain) > 0: - zy = torch.cat((results[2], inject_domain), 1) - else: - zy = results[2] - - # print(results[2].shape, inject_domain.shape, zy.shape) - x_pro, *_ = self.decoder(zy) - preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = (r.cpu().detach() for r in results) - return preds, z_mu, z, log_sigma2_c, probs, x_pro
- -
[docs] def cal_loss(self, x, inject_domain, warmup_beta): - """Function that is called in trainer_vade to calculate loss - - :param x: tensor with input data - :return: ELBO loss - """ - return self.ELBO_Loss(x, inject_domain, warmup_beta)
- -
[docs] def pretrain_loss(self, x, inject_domain): - - Loss = nn.MSELoss() - # Loss = nn.MSELoss(reduction='sum') - # Loss = nn.HuberLoss() - z_mu, z_sigma2_log = self.encoder(x) - z = torch.randn_like(z_mu) * torch.exp(z_sigma2_log / 2) + z_mu - if len(inject_domain) > 0: - zy = torch.cat((z, inject_domain), 1) - else: - zy = z - x_pro, *_ = self.decoder(zy) - - loss = Loss(x, x_pro) - - return loss
- -
[docs] def reconstruction_loss(self, x, x_pro, log_sigma): - - if self.args.prior == "Bern": - L_rec = F.binary_cross_entropy(x_pro, x) - else: - # print('first part',torch.mean(torch.sum(torch.sum(torch.sum(log_sigma, 2), 2), 1), 0)) - # #torch.sum(log_sigma)*1/log_sigma.shape[0]) - # print('second part', torch.mean( - # torch.sum(torch.sum(torch.sum(0.5 * (x - x_pro) ** 2 / torch.exp(log_sigma) ** 2, 2),2),1), 0)) - # print('MSE', F.mse_loss(x, x_pro)) - # print('constant infront of MSE', torch.sum(torch.exp(log_sigma)**2)) - # print('x pro min/max/mean', torch.min(x_pro), torch.max(x_pro), torch.mean(x_pro)) - # print('log_sigma min/max/mean',torch.min(log_sigma), 'max',torch.max(log_sigma), 'mean', torch.mean(log_sigma)) - - # L_rec = torch.mean(torch.sum(torch.sum(torch.sum(log_sigma, 2), 2), 1), 0) + torch.mean( - # torch.sum(torch.sum(torch.sum(0.5 * (x - x_pro) ** 2 / torch.exp(log_sigma) ** 2, 2), 2), 1), 0 - # ) - - sigma = torch.Tensor([0.9]).to(self.device) # mean sigma of all images - log_sigma_est = torch.log(sigma).to(self.device) - L_rec = torch.mean(torch.sum(torch.sum(torch.sum(0.5 * (x - x_pro) ** 2, 2), 2), 1), 0) / sigma**2 - # L_rec = F.mse_loss(x_pro, x) - # print(L_rec, L_rec0) - - # print('L rec', L_rec) - # print("#"*10) - # L_rec = torch.sum(log_sigma)*1/log_sigma.shape[0]+F.mse_loss(x, x_pro)*(log_sigma.shape[0]/torch.sum(torch.exp(log_sigma)**2)) - - # L_rec = F.mse_loss(x, x_pro)#*(log_sigma.shape[0]/torch.sum(torch.exp(log_sigma)**2)) - - # Note that the mean is taken over the batch dimension, and the sum over the spatial dimensions and the channels. - # Thir is consistent with the computation of other terms of the ELBO loss below. - - return L_rec
- -
[docs] def ELBO_Loss(self, x, inject_domain, warmup_beta): - """ELBO loss function - Using SGVB estimator and the reparametrization trick calculates ELBO loss. - Calculates loss between encoded input and input using ELBO equation (12) in the papaer. - :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. - :param int L: Number of Monte Carlo samples in the SGVB - """ - preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = self._inference(x) - # mu, sigma from the decoder - eps = 1e-10 - - L_rec = 0.0 - for l in range(self.L): - z = torch.randn_like(z_mu) * torch.exp(z_sigma2_log / 2) + z_mu # shape [batch_size, self.zd_dim]4 + self.mu_c = nn.Parameter(torch.FloatTensor(self.d_dim, self.zd_dim).fill_(0), requires_grad=True) + self.log_sigma2_c = nn.Parameter(torch.FloatTensor(self.d_dim, self.zd_dim).fill_(0), requires_grad=True) + + # self.loss_writter = SummaryWriter() + + def _inference(self, x): + """Auxiliary function for inference + + :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. + :return tensor preds_c: One hot encoded tensor of the predicted cluster assignment (shape: [batch_size, self.d_dim]). + :return tensor probs_c: Tensor of the predicted cluster probabilities; this is q(c|x) per eq. (16) or gamma_c in eq. (12) (shape: [batch_size, self.d_dim]). + :return tensor z: Tensor of the latent space representation (shape: [batch_size, self.zd_dim]) + :return tensor z_mu: Tensor of the mean of the latent space representation (shape: [batch_size, self.zd_dim]) + :return tensor z_sigma2_log: Tensor of the log of the variance of the latent space representation (shape: [batch_size, self.zd_dim]) + :return tensor mu_c: Tensor of the estimated cluster means (shape: [self.d_dim, self.zd_dim]) + :return tensor log_sigma2_c: Tensor of the estimated cluster variances (shape: [self.d_dim, self.zd_dim]) + :return tensor pi: Tensor of the estimated cluster prevalences, p(c) (shape: [self.d_dim]) + :return tensor logits: Tensor where each column contains the log-probability p(c)p(z|c) for cluster c=0,...,self.d_dim-1 (shape: [batch_size, self.d_dim]). + """ + + z_mu, z_sigma2_log = self.encoder(x) + z = torch.randn_like(z_mu) * torch.exp(z_sigma2_log / 2) + z_mu + pi = F.softmax(self.log_pi, dim=0) + + mu_c = self.mu_c + log_sigma2_c = self.log_sigma2_c + + logits = torch.log(pi.unsqueeze(0)) + self.gaussian_pdfs_log(z, mu_c, log_sigma2_c) + # shape [batch_size, self.d_dim], each column contains the log-probability p(c)p(z|c) for cluster c=0,...,self.d_dim-1. + + preds_c, probs_c, *_ = logit2preds_vpic(logits) + + return preds_c, probs_c, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits + + def infer_d_v_2(self, x, inject_domain): + """ + Used for tensorboard visualizations only. + """ + results = self._inference(x) if len(inject_domain) > 0: - zy = torch.cat((z, inject_domain), 1) + zy = torch.cat((results[2], inject_domain), 1) + else: + zy = results[2] + + x_pro, *_ = self.decoder(zy) + preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = (r.cpu().detach() for r in results) + return preds, z_mu, z, log_sigma2_c, probs, x_pro + + def cal_loss(self, x, inject_domain, warmup_beta): + """Function that is called in trainer_vade to calculate loss + + :param x: tensor with input data + :return: ELBO loss + """ + + return self._cal_ELBO_loss(x, inject_domain, warmup_beta) + + def _cal_reconstruction_loss(self, x, inject_tensor=[]): + z_mu = self.encoder.get_z(x) + z_sigma2_log = self.encoder.get_log_sigma2(x) + z = z_mu + if len(inject_tensor) > 0: + zy = torch.cat((z, inject_tensor), 1) else: zy = z - x_pro, log_sigma = self.decoder(zy) # x_pro, mu, sigma - L_rec += self.reconstruction_loss(x, x_pro, log_sigma) + x_pro, *_ = self.decoder(zy) + + if self.prior == "Bern": + L_rec = F.binary_cross_entropy(x_pro, x) + else: + + sigma = torch.Tensor([0.9]).to(self.device) # mean sigma of all images + log_sigma_est = torch.log(sigma).to(self.device) + L_rec = torch.mean(torch.sum(torch.sum(torch.sum(0.5 * (x - x_pro) ** 2, 2), 2), 1), 0) / sigma**2 - L_rec /= self.L - Loss = L_rec * x.size(1) - # --> this is the -"first line" of eq (12) in the paper with additional averaging over the batch. + return L_rec - Loss += ( - 0.5 - * warmup_beta - * torch.mean( + def _cal_reconstruction_loss_helper(self, x, x_pro, log_sigma): + + if self.prior == "Bern": + L_rec = F.binary_cross_entropy(x_pro, x) + else: + + sigma = torch.Tensor([0.9]).to(self.device) # mean sigma of all images + log_sigma_est = torch.log(sigma).to(self.device) + L_rec = torch.mean(torch.sum(torch.sum(torch.sum(0.5 * (x - x_pro) ** 2, 2), 2), 1), 0) / sigma**2 + + return L_rec + + def _cal_ELBO_loss(self, x, inject_domain, warmup_beta): + """ELBO loss function + Using SGVB estimator and the reparametrization trick calculates ELBO loss. + Calculates loss between encoded input and input using ELBO equation (12) in the paper. + :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. + :param int L: Number of Monte Carlo samples in the SGVB + """ + preds, probs, z, z_mu, z_sigma2_log, mu_c, log_sigma2_c, pi, logits = self._inference(x) + # mu, sigma from the decoder + eps = 1e-10 + + L_rec = 0.0 + for l in range(self.L): + z = torch.randn_like(z_mu) * torch.exp(z_sigma2_log / 2) + z_mu # shape [batch_size, self.zd_dim]4 + if len(inject_domain) > 0: + zy = torch.cat((z, inject_domain), 1) + else: + zy = z + x_pro, log_sigma = self.decoder(zy) # x_pro, mu, sigma + L_rec += self._cal_reconstruction_loss_helper(x, x_pro, log_sigma) # FIXME + + L_rec /= self.L + Loss = L_rec * x.size(1) + # --> this is the -"first line" of eq (12) in the paper with additional averaging over the batch. + + Loss += ( + 0.5 + * warmup_beta + * torch.mean( + torch.sum( + probs + * torch.sum( + log_sigma2_c.unsqueeze(0) + + torch.exp(z_sigma2_log.unsqueeze(1) - log_sigma2_c.unsqueeze(0)) + + (z_mu.unsqueeze(1) - mu_c.unsqueeze(0)).pow(2) / torch.exp(log_sigma2_c.unsqueeze(0)), + 2, + ), + 1, + ) + ) + ) + # inner sum dimentions: + # [1, d_dim, zd_dim] + exp([batch_size, 1, zd_dim] - [1, d_dim, zd_dim]) + ([batch_size, 1, zd_dim] - [1, d_dim, zd_dim])^2 / exp([1, d_dim, zd_dim]) + # = [batch_size, d_dim, zd_dim] -> sum of zd_dim dimensions + # the next sum is over d_dim dimensions + # the mean is over the batch + # --> overall, this is -"second line of eq. (12)" with additional mean over the batch + + Loss -= warmup_beta * torch.mean( + torch.sum(probs * torch.log(pi.unsqueeze(0) / (probs + eps)), 1) + ) # FIXME: (+eps) is a hack to avoid NaN. Is there a better way? + # dimensions: [batch_size, d_dim] * log([1, d_dim] / [batch_size, d_dim]), where the sum is over d_dim dimensions --> [batch_size] --> mean over the batch --> a scalar + + Loss -= 0.5 * warmup_beta * torch.mean(torch.sum(1.0 + z_sigma2_log, 1)) + # dimensions: mean( sum( [batch_size, zd_dim], 1 ) ) where the sum is over zd_dim dimensions and mean over the batch + # --> overall, this is -"third line of eq. (12)" with additional mean over the batch + + return Loss + + def gaussian_pdfs_log(self, x, mus, log_sigma2s): + """helper function""" + loglik = [] + for c in range(self.d_dim): + loglik.append(self.gaussian_pdf_log(x, mus[c, :], log_sigma2s[c, :]).view(-1, 1)) + return torch.cat(loglik, 1) + + @staticmethod + def gaussian_pdf_log(x, mu, log_sigma2): + """ + subhelper function just one gausian pdf log calculation, used as a basis for gaussian_pdfs_log function + :param x: tensor of shape [batch_size, self.zd_dim] + :param mu: mean for the cluster distribution + :param log_sigma2: variance parameters of the cluster distribtion + :return: tensor with the Gaussian log probabilities of the shape of [batch_size, 1] + """ + return -0.5 * ( torch.sum( - probs - * torch.sum( - log_sigma2_c.unsqueeze(0) - + torch.exp(z_sigma2_log.unsqueeze(1) - log_sigma2_c.unsqueeze(0)) - + (z_mu.unsqueeze(1) - mu_c.unsqueeze(0)).pow(2) / torch.exp(log_sigma2_c.unsqueeze(0)), - 2, - ), + np.log(np.pi * 2) + log_sigma2 + (x - mu).pow(2) / torch.exp(log_sigma2), 1, ) ) - ) - # inner sum dimentions: - # [1, d_dim, zd_dim] + exp([batch_size, 1, zd_dim] - [1, d_dim, zd_dim]) + ([batch_size, 1, zd_dim] - [1, d_dim, zd_dim])^2 / exp([1, d_dim, zd_dim]) - # = [batch_size, d_dim, zd_dim] -> sum of zd_dim dimensions - # the next sum is over d_dim dimensions - # the mean is over the batch - # --> overall, this is -"second line of eq. (12)" with additional mean over the batch - - Loss -= warmup_beta * torch.mean( - torch.sum(probs * torch.log(pi.unsqueeze(0) / (probs + eps)), 1) - ) # FIXME: (+eps) is a hack to avoid NaN. Is there a better way? - # dimensions: [batch_size, d_dim] * log([1, d_dim] / [batch_size, d_dim]), where the sum is over d_dim dimensions --> [batch_size] --> mean over the batch --> a scalar - - Loss -= 0.5 * warmup_beta * torch.mean(torch.sum(1.0 + z_sigma2_log, 1)) - # dimensions: mean( sum( [batch_size, zd_dim], 1 ) ) where the sum is over zd_dim dimensions and mean over the batch - # --> overall, this is -"third line of eq. (12)" with additional mean over the batch - - return Loss
- -
[docs] def gaussian_pdfs_log(self, x, mus, log_sigma2s): - """helper function""" - loglik = [] - for c in range(self.d_dim): - loglik.append(self.gaussian_pdf_log(x, mus[c, :], log_sigma2s[c, :]).view(-1, 1)) - return torch.cat(loglik, 1)
- -
[docs] @staticmethod - def gaussian_pdf_log(x, mu, log_sigma2): - """ - subhelper function just one gausian pdf log calculation, used as a basis for gaussian_pdfs_log function - :param x: tensor of shape [batch_size, self.zd_dim] - :param mu: mean for the cluster distribution - :param log_sigma2: variance parameters of the cluster distribtion - :return: tensor with the Gaussian log probabilities of the shape of [batch_size, 1] - """ - return -0.5 * ( - torch.sum( - np.log(np.pi * 2) + log_sigma2 + (x - mu).pow(2) / torch.exp(log_sigma2), - 1, - ) - )
+ + return ModelVaDE
[docs]def test_fun(d_dim, zd_dim, device): diff --git a/docs/build/html/_modules/domid/tasks/task_mnist_color.html b/docs/build/html/_modules/domid/tasks/task_mnist_color.html index 10548c1..5635fd6 100644 --- a/docs/build/html/_modules/domid/tasks/task_mnist_color.html +++ b/docs/build/html/_modules/domid/tasks/task_mnist_color.html @@ -328,7 +328,7 @@

Source code for domid.t Use the deafult palette with 10 colors """ -
[docs] def init_business(self, args): +
[docs] def init_business(self, args, trainer=None): """ create a dictionary of datasets """ @@ -339,7 +339,7 @@

Source code for domid.t self.wanted_digits = list(range(10)) self._dim_y = len(self.wanted_digits) # note the order of lines: dim_y has to be set before init_business is called - super().init_business(args)

+ super().init_business(args, trainer)
@property def dim_y(self): diff --git a/docs/build/html/_modules/domid/tasks/task_wsi.html b/docs/build/html/_modules/domid/tasks/task_wsi.html index 5d3a905..5711772 100644 --- a/docs/build/html/_modules/domid/tasks/task_wsi.html +++ b/docs/build/html/_modules/domid/tasks/task_wsi.html @@ -362,14 +362,13 @@

Source code for domid.tasks.tas # be evaluated in if statement, in which case, no validation # set will be created. Otherwise, this argument is # the split ratio - dpath = args.dpath # png_files/32, 16))] # , transforms.ToTensor()] ind_global = self.get_list_domains().index(na_domain) df = pd.read_csv(args.meta_data_csv) mask = df[df["subject"] == ind_global] # mask = df['resp'].values == ind_global # response (0 o 1) img_paths = np.array(mask["path"]) # [:400] - trans = [transforms.Resize((self.ImSize.w, self.ImSize.h))] + trans = [transforms.Resize((64, 64))] # [transforms.Resize((self.ImSize.w, self.ImSize.h))] dset = DsetWSI(class_num=ind_global, path=img_paths, args=args, transform=trans) # split dset into training and validation sets @@ -381,17 +380,6 @@

Source code for domid.tasks.tas train_set = dset val_set = dset return train_set, val_set

- - -
[docs]def test_fun(): - from domainlab.arg_parser import mk_parser_main - - parser = mk_parser_main() - args = parser.parse_args(["--te_d", "0", "--dpath", "zout", "--split", "0.2"]) - node = NodeTaskMNIST() - node.get_list_domains() - node.list_str_y - node.init_business(args)
diff --git a/docs/build/html/_modules/domid/tests/test_graph.html b/docs/build/html/_modules/domid/tests/test_graph.html index b62fc34..0598391 100644 --- a/docs/build/html/_modules/domid/tests/test_graph.html +++ b/docs/build/html/_modules/domid/tests/test_graph.html @@ -309,7 +309,8 @@

Source code for domid.tests.test_graph

-import torch
+import numpy as np
+import torch
 from domainlab.tasks.utils_task import DsetDomainVecDecorator
 
 from domid.arg_parser import mk_parser_main
@@ -355,6 +356,35 @@ 

Source code for domid.tests.t return adjacency_matrices, sparse_matrices

+
[docs]def test_data(): + return np.array([[1, 2], [3, 4]])
+ + +
[docs]def test_graph_methods(): + sample_mx = test_data() + dist1 = GraphConstructor("heat", 2).distance_calc(sample_mx) + dist2 = GraphConstructor("cos", 2).distance_calc(sample_mx) + dist3 = GraphConstructor("ncos", 2).distance_calc(sample_mx) + + assert dist1.shape == (2, 2) + assert dist2.shape == (2, 2) + assert dist3.shape == (2, 2)
+ + +
[docs]def test_connection_calc(): + sample_mx = test_data() + GraphConstructor("heat", 1).connection_calc(sample_mx) + GraphConstructor("cos", 1).connection_calc(sample_mx) + GraphConstructor("ncos", 1).connection_calc(sample_mx)
+ + +
[docs]def test_mk_adj_mat(): + sample_mx = test_data() + graph_constructor = GraphConstructor("heat", 1) + dist, inds, connection_pairs = graph_constructor.connection_calc(sample_mx) + adj_mx = graph_constructor.mk_adj_mat(2, connection_pairs)
+ +
[docs]def test_MNISTcolor_SDCN_graph_construction_heat(): print("done") parser = mk_parser_main() @@ -372,7 +402,7 @@

Source code for domid.tests.t "mnistcolor10", "--bs", "50", - "--aname", + "--model", "sdcn", "--zd_dim", "5", @@ -382,7 +412,7 @@

Source code for domid.tests.t "5", "--prior", "Bern", - "--model", + "--model_method", "linear", "--graph_method", "heat", @@ -413,7 +443,7 @@

Source code for domid.tests.t "mnist", "--bs", "50", - "--aname", + "--model", "sdcn", "--zd_dim", "5", @@ -423,7 +453,7 @@

Source code for domid.tests.t "5", "--prior", "Bern", - "--model", + "--model_method", "linear", "--graph_method", "ncos", diff --git a/docs/build/html/_modules/domid/tests/test_losses.html b/docs/build/html/_modules/domid/tests/test_losses.html index 7fe4312..30af98d 100644 --- a/docs/build/html/_modules/domid/tests/test_losses.html +++ b/docs/build/html/_modules/domid/tests/test_losses.html @@ -309,18 +309,14 @@

Source code for domid.tests.test_losses

-from domid.arg_parser import mk_parser_main
-from domid.compos.exp.exp_main import Exp
-
+import pytest
 
-
[docs]def experiment_train(args): - exp = Exp(args) - exp.trainer.before_tr() - exp.trainer.tr_epoch(0)
- # exp.trainer.post_tr() +from domid.arg_parser import mk_parser_main +from domid.compos.exp.exp_main import Exp +from domid.tests.utils import experiment_train -
[docs]def test_VADE_CNN_nonbinary(): +
[docs]def test_VADE_CNN_nonbinary(tmp_path): parser = mk_parser_main() args = parser.parse_args( [ @@ -338,7 +334,7 @@

Source code for domid.tests. "zout", "--task", "mnist", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -354,16 +350,18 @@

Source code for domid.tests. "--nocu", "--prior", "Gaus", - "--model", + "--model_method", "cnn", "--pre_tr", "0", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
-
[docs]def test_VADE_CNN(): +
[docs]def test_VADE_CNN(tmp_path): parser = mk_parser_main() args = parser.parse_args( [ @@ -381,7 +379,7 @@

Source code for domid.tests. "zout", "--task", "mnist", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -395,16 +393,18 @@

Source code for domid.tests. "5", "--debug", "--nocu", - "--model", + "--model_method", "cnn", "--pre_tr", "0", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
-
[docs]def test_VADE_nonbinary(): +
[docs]def test_VADE_nonbinary(tmp_path): parser = mk_parser_main() args = parser.parse_args( [ @@ -422,7 +422,7 @@

Source code for domid.tests. "zout", "--task", "mnist", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -440,12 +440,14 @@

Source code for domid.tests. "Gaus", "--pre_tr", "0", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
-
[docs]def test_VADE(): +
[docs]def test_VADE(tmp_path): parser = mk_parser_main() args = parser.parse_args( [ @@ -463,7 +465,7 @@

Source code for domid.tests. "zout", "--task", "mnist", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -479,9 +481,11 @@

Source code for domid.tests. "--nocu", "--pre_tr", "0", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
diff --git a/docs/build/html/_modules/domid/tests/test_mnist_dataset.html b/docs/build/html/_modules/domid/tests/test_mnist_dataset.html index 4de0e77..6abe29e 100644 --- a/docs/build/html/_modules/domid/tests/test_mnist_dataset.html +++ b/docs/build/html/_modules/domid/tests/test_mnist_dataset.html @@ -312,9 +312,10 @@

Source code for domid import torch from domid.arg_parser import mk_parser_main -from domid.compos.exp.exp_main import Exp -from domid.models.model_m2yd import ModelXY2D -from domid.models.model_vade import ModelVaDE + +# from domid.compos.exp.exp_main import Exp +# from domid.models.model_m2yd import ModelXY2D +# from domid.models.model_vade import ModelVaDE from domid.tasks.task_mnist import NodeTaskMNIST from domid.tasks.task_mnist_color import NodeTaskMNISTColor10 diff --git a/docs/build/html/_modules/domid/tests/test_model_builder.html b/docs/build/html/_modules/domid/tests/test_model_builder.html index 64167b9..aaf5526 100644 --- a/docs/build/html/_modules/domid/tests/test_model_builder.html +++ b/docs/build/html/_modules/domid/tests/test_model_builder.html @@ -313,8 +313,9 @@

Source code for domid import torch.utils.data from domid.arg_parser import mk_parser_main -from domid.models.model_m2yd import ModelXY2D -from domid.models.model_vade import ModelVaDE + +# from domid.models.model_m2yd import ModelXY2D +from domid.models.model_vade import mk_vade from domid.tasks.task_mnist import NodeTaskMNIST @@ -368,12 +369,14 @@

Source code for domid "--prior", "Bern", "--model", + "vade", + "--model_method", "cnn", ] ) i_c, i_w, i_h = 3, 32, 32 - - model = ModelVaDE( + # zd_dim, d_dim, device, L, i_c, i_h, i_w, args + model = mk_vade()( zd_dim=args.zd_dim, d_dim=args.d_dim, device=torch.device("cpu"), @@ -381,8 +384,15 @@

Source code for domid i_c=i_c, i_w=i_w, i_h=i_h, - args=args, + bs=args.bs, + dim_inject_y=args.dim_inject_y, + prior=args.prior, + random_batching=args.random_batching, + model_method=args.model_method, + pre_tr_weight_path=args.pre_tr_weight_path, + feat_extract=args.feat_extract, ) + model_compiler(args, model)

@@ -402,10 +412,14 @@

Source code for domid "0.8", "--L", "5", + "--model", + "vade", + "--model_method", + "linear", ] ) i_c, i_w, i_h = 3, 32, 32 - model = ModelVaDE( + model = mk_vade()( zd_dim=args.zd_dim, d_dim=args.d_dim, device=torch.device("cpu"), @@ -413,7 +427,13 @@

Source code for domid i_c=i_c, i_w=i_w, i_h=i_h, - args=args, + bs=args.bs, + dim_inject_y=args.dim_inject_y, + prior=args.prior, + random_batching=args.random_batching, + model_method=args.model_method, + pre_tr_weight_path=args.pre_tr_weight_path, + feat_extract=args.feat_extract, ) model_compiler(args, model)

@@ -431,7 +451,7 @@

Source code for domid "4", "--task", "mnistcolor10", - "--aname", + "--model", "m2yd", "--d_dim", "2", @@ -441,18 +461,18 @@

Source code for domid "3500", ] ) - y_dim = args.d_dim - model = ModelXY2D( - list_str_y=args.tr_d, - y_dim=y_dim, - zd_dim=args.zd_dim, - gamma_y=args.gamma_y, - device=torch.device("cpu"), - i_c=3, - i_h=32, - i_w=32, - ) - model_compiler(args, model)

+ y_dim = args.d_dim + # model = ModelXY2D( + # list_str_y=args.tr_d, + # y_dim=y_dim, + # zd_dim=args.zd_dim, + # gamma_y=args.gamma_y, + # device=torch.device("cpu"), + # i_c=3, + # i_h=32, + # i_w=32, + # ) + # model_compiler(args, model) diff --git a/docs/build/html/_modules/domid/tests/test_model_trainer.html b/docs/build/html/_modules/domid/tests/test_model_trainer.html index 85ac9a4..a1293d7 100644 --- a/docs/build/html/_modules/domid/tests/test_model_trainer.html +++ b/docs/build/html/_modules/domid/tests/test_model_trainer.html @@ -309,27 +309,81 @@

Source code for domid.tests.test_model_trainer

-from domid.algos.builder_vade import NodeAlgoBuilderVaDE
+import os
+import shutil
+
+import pytest
+
+from domid.algos.builder_vade import NodeAlgoBuilderVaDE
 from domid.algos.observers.b_obvisitor_clustering_only import ObVisitorClusteringOnly
 from domid.arg_parser import mk_parser_main
 from domid.compos.exp.exp_main import Exp
-from domid.models.model_vade import ModelVaDE
+
+# from domid.models.model_vade import ModelVaDE
 from domid.tasks.task_mnist import NodeTaskMNIST
+from domid.tests.utils import experiment_train
 from domid.trainers.trainer_cluster import TrainerCluster
 
-# Note: to run tests 'poetry run pytest domid/tests/test_model_trainer.py '.
-# If there is an error with dependencies, try 'poetry install' first. Or manually add PYTHONPATH to the path of the DomId folder.
+
+
[docs]def train_MNISTcolor_AE(out_dir): + # MNIST color cnn vade with pretraining + parser = mk_parser_main() + args = parser.parse_args( + [ + "--te_d", + "7", + "--tr_d", + "0", + "1", + "2", + "--zd_dim", + "20", + "--d_dim", + "10", + "--dpath", + "zout", + "--task", + "mnistcolor10", + "--model", + "ae", + "--apath", + "domid/algos/builder_ae.py", + "--bs", + "600", + "--split", + "0.8", + "--L", + "5", + "--debug", + "--nocu", + "--model_method", + "cnn", + "--prior", + "Gaus", + "--pre_tr", + "1", + "--epos", + "3", + "--trainer", + "ae", + "--feat_extract", + "ae", + ] + ) + experiment_train(args, save_path=out_dir)
-
[docs]def experiment_train(args): - exp = Exp(args) - # exp.execute() - exp.trainer.before_tr() - exp.trainer.tr_epoch(0)
- # exp.trainer.post_tr() +
[docs]@pytest.fixture(scope="session") +def ae_weights(tmp_path_factory): + # Create a temporary directory accessible by all tests + ae_weights_dir = tmp_path_factory.mktemp("ae_weights_dir") + # this will save the AE weights in that directory; note that the AE training is run only once, no matter how + # often ae_weights() is used in the tests below. + train_MNISTcolor_AE(ae_weights_dir) + return ae_weights_dir
-
[docs]def test_MNIST_pretrain(): +
[docs]def test_MNIST_pretrain(tmp_path): # MNIST vade linear test for pretaining parser = mk_parser_main() args = parser.parse_args( @@ -348,7 +402,7 @@

Source code for domid "zout", "--task", "mnist", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -360,18 +414,20 @@

Source code for domid "5", "--debug", "--nocu", - "--model", + "--model_method", "linear", "--prior", "Bern", "--pre_tr", "1", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
-
[docs]def test_MNIST_train(): +
[docs]def test_MNIST_train(tmp_path): # MNIST vade linear test without pretaining parser = mk_parser_main() args = parser.parse_args( @@ -390,7 +446,7 @@

Source code for domid "zout", "--task", "mnist", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -402,18 +458,20 @@

Source code for domid "5", "--debug", "--nocu", - "--model", + "--model_method", "linear", "--prior", "Bern", "--pre_tr", "0", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
-
[docs]def test_MNIST_train_CNN(): +
[docs]def test_MNIST_train_CNN(tmp_path): # MNIST vade CNN without pretraining parser = mk_parser_main() args = parser.parse_args( @@ -432,7 +490,7 @@

Source code for domid "zout", "--task", "mnist", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -444,18 +502,20 @@

Source code for domid "5", "--debug", "--nocu", - "--model", + "--model_method", "cnn", "--prior", "Bern", "--pre_tr", "0", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
-
[docs]def test_MNISTcolor_train(): +
[docs]def test_MNISTcolor_train(tmp_path): # MNIST color linear vade without pretraining parser = mk_parser_main() args = parser.parse_args( @@ -474,7 +534,7 @@

Source code for domid "zout", "--task", "mnistcolor10", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -486,18 +546,21 @@

Source code for domid "5", "--debug", "--nocu", - "--model", + "--model_method", "linear", "--prior", "Gaus", "--pre_tr", "0", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ + experiment_train(args, save_path=tmp_path)
-
[docs]def test_MNISTcolor_train_CNN(): +
[docs]def test_MNISTcolor_train_CNN(tmp_path): # MNIST color cnn vade without pretraining parser = mk_parser_main() @@ -517,7 +580,7 @@

Source code for domid "zout", "--task", "mnistcolor10", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -529,18 +592,20 @@

Source code for domid "5", "--debug", "--nocu", - "--model", + "--model_method", "cnn", "--prior", "Gaus", "--pre_tr", "0", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
-
[docs]def test_MNISTcolor_pretrain_CNN(): +
[docs]def test_MNISTcolor_pretrain_CNN(tmp_path): # MNIST color cnn vade with pretraining parser = mk_parser_main() args = parser.parse_args( @@ -559,7 +624,7 @@

Source code for domid "zout", "--task", "mnistcolor10", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -571,15 +636,17 @@

Source code for domid "5", "--debug", "--nocu", - "--model", + "--model_method", "cnn", "--prior", "Gaus", "--pre_tr", "1", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
[docs]def test_M2YD_train_MNISTcolor(): @@ -600,7 +667,7 @@

Source code for domid "9", "--task", "mnistcolor10", - "--aname", + "--model", "m2yd", "--zd_dim", "7", @@ -614,12 +681,14 @@

Source code for domid "--nocu", "--gamma_y", "3500", + "--trainer", + "basic", ] ) experiment_train(args)

-
[docs]def test_MNIST_conditionalOne_train(): +
[docs]def test_MNIST_conditionalOne_train(tmp_path): parser = mk_parser_main() args = parser.parse_args( [ @@ -637,7 +706,7 @@

Source code for domid "zout", "--task", "mnist", - "--aname", + "--model", "vade", "--apath", "domid/algos/builder_vade.py", @@ -649,7 +718,7 @@

Source code for domid "5", "--debug", "--nocu", - "--model", + "--model_method", "cnn", "--prior", "Gaus", @@ -659,12 +728,19 @@

Source code for domid "10", "--inject_var", "digit", + "--trainer", + "cluster", ] ) - experiment_train(args)

+ experiment_train(args, save_path=tmp_path)
+ + +
[docs]def test_MNISTcolor_AE(ae_weights): + # MNIST color cnn vade with pretraining + assert os.path.exists(ae_weights)
-
[docs]def test_MNISTcolor_SDCN(): +
[docs]def test_MNISTcolor_SDCN(tmp_path, ae_weights): # MNIST color cnn vade with pretraining parser = mk_parser_main() args = parser.parse_args( @@ -683,7 +759,7 @@

Source code for domid "zout", "--task", "mnistcolor10", - "--aname", + "--model", "sdcn", "--apath", "domid/algos/builder_sdcn.py", @@ -695,63 +771,23 @@

Source code for domid "5", "--debug", "--nocu", - "--model", + "--model_method", "cnn", "--prior", "Gaus", "--pre_tr", "1", "--pre_tr_weight_path", - "./notebooks/2023-11-30 10:52:19.451201_mnist_ae/", + str(ae_weights), "--epos", "3", - ] - ) - experiment_train(args)

- - -
[docs]def test_MNISTcolor_AE(): - # MNIST color cnn vade with pretraining - parser = mk_parser_main() - args = parser.parse_args( - [ - "--te_d", - "7", - "--tr_d", - "0", - "1", - "2", - "--zd_dim", - "20", - "--d_dim", - "10", - "--dpath", - "zout", - "--task", - "mnistcolor10", - "--aname", + "--trainer", + "sdcn", + "--feat_extract", "ae", - "--apath", - "domid/algos/builder_ae.py", - "--bs", - "600", - "--split", - "0.8", - "--L", - "5", - "--debug", - "--nocu", - "--model", - "cnn", - "--prior", - "Gaus", - "--pre_tr", - "1", - "--epos", - "3", ] ) - experiment_train(args)
+ experiment_train(args, save_path=tmp_path)
# def test_MNIST_conditional_train(): @@ -778,7 +814,7 @@

Source code for domid # "zout", # "--task", # "mnist", -# "--aname", +# "--model", # "vade", # "--apath", # "domid/algos/builder_vade.py", diff --git a/docs/build/html/_modules/domid/trainers/pretraining_GMM.html b/docs/build/html/_modules/domid/trainers/pretraining_GMM.html index 4d22a25..9436461 100644 --- a/docs/build/html/_modules/domid/trainers/pretraining_GMM.html +++ b/docs/build/html/_modules/domid/trainers/pretraining_GMM.html @@ -335,8 +335,7 @@

Source code for domid :param tensor_x: the input image :return: the loss """ - # import pdb; pdb.set_trace() - loss = self.model.pretrain_loss(tensor_x, inject_tensor) + loss = self.model._cal_pretrain_loss(tensor_x, inject_tensor) return loss

[docs] def GMM_fit(self): diff --git a/docs/build/html/_modules/domid/trainers/pretraining_KMeans.html b/docs/build/html/_modules/domid/trainers/pretraining_KMeans.html index fc7001c..25f69bd 100644 --- a/docs/build/html/_modules/domid/trainers/pretraining_KMeans.html +++ b/docs/build/html/_modules/domid/trainers/pretraining_KMeans.html @@ -336,7 +336,7 @@

Source code for do :return: the loss """ # import pdb; pdb.set_trace() - loss = self.model.pretrain_loss(tensor_x, inject_tensor) + loss = self.model._cal_pretrain_loss(tensor_x, inject_tensor) return loss

[docs] def model_fit(self): diff --git a/docs/build/html/_modules/domid/trainers/pretraining_sdcn.html b/docs/build/html/_modules/domid/trainers/pretraining_sdcn.html index 9252e1e..7d5ee76 100644 --- a/docs/build/html/_modules/domid/trainers/pretraining_sdcn.html +++ b/docs/build/html/_modules/domid/trainers/pretraining_sdcn.html @@ -333,11 +333,11 @@

Source code for domi self.args = args

[docs] def pretrain_loss(self, tensor_x): - return self.model.pretrain_loss(tensor_x)
+ return self.model._cal_pretrain_loss(tensor_x)
[docs] def kmeans_cluster_assignement(self): num_img = len(self.loader_tr.dataset) - if self.args.task == "wsi" and self.args.aname == "sdcn": + if self.args.task == "wsi" and self.args.model == "sdcn": num_img = int(self.args.bs / 3) Z = np.zeros((num_img, self.model.zd_dim)) counter = 0 @@ -350,13 +350,18 @@

Source code for domi vec_d.to(self.device), ) - if self.args.task == "wsi" and self.args.aname == "sdcn": + if self.args.random_batching: + if len(other_vars) > 0: + inject_tensor, image_id = other_vars + if len(inject_tensor) > 0: + inject_tensor = inject_tensor.to(self.device) + # note that for other tasks the graph is calculated once and the same graph is used for all the epochs; see domid/trainers/trainer_sdcn.py patches_idx = self.model.random_ind[i] # torch.randint(0, len(vec_y), (int(self.args.bs/3),)) tensor_x = tensor_x[patches_idx, :, :, :] image_id = [image_id[patch_idx_num] for patch_idx_num in patches_idx] - adj_mx, spar_mx = GraphConstructorWSI().construct_graph( - tensor_x, image_id, self.model.graph_method, None + adj_mx, spar_mx = GraphConstructorWSI(self.model.graph_method).construct_graph( + tensor_x, image_id, None ) self.model.adj = spar_mx diff --git a/docs/build/html/_modules/domid/trainers/trainer_ae.html b/docs/build/html/_modules/domid/trainers/trainer_ae.html index 0f5a586..d0a8ace 100644 --- a/docs/build/html/_modules/domid/trainers/trainer_ae.html +++ b/docs/build/html/_modules/domid/trainers/trainer_ae.html @@ -314,14 +314,13 @@

Source code for domid.trai from domid.compos.predict_basic import Prediction from domid.compos.tensorboard_fun import tensorboard_write -from domid.dsets.make_graph import GraphConstructor from domid.trainers.pretraining_KMeans import Pretraining from domid.utils.perf_cluster import PerfCluster from domid.utils.storing import Storing -
[docs]class TrainerCluster(AbstractTrainer): -
[docs] def __init__(self, model, task, observer, device, writer, pretrain=True, aconf=None): +
[docs]class TrainerAE(AbstractTrainer): +
[docs] def init_business(self, model, task, observer, device, aconf, flag_accept=True): """ :param model: model to train :param task: task to train on @@ -335,7 +334,11 @@

Source code for domid.trai super().__init__() super().init_business(model, task, observer, device, aconf) print(model) - self.pretrain = pretrain + if aconf.pre_tr > 0: + self.pretrain = True + else: + self.pretrain = False + self.pretraining_finished = not self.pretrain self.lr = aconf.lr self.warmup_beta = 0.1 @@ -346,17 +349,15 @@

Source code for domid.trai self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr) self.epo_loss_tr = None - self.writer = writer + self.writer = None self.thres = aconf.pre_tr # number of epochs for pretraining self.i_h, self.i_w = task.isize.h, task.isize.w self.args = aconf self.storage = Storing(self.args) self.loader_val = task.loader_tr - self.aname = aconf.aname

- - # self.model.adj = GraphConstructor().construct_graph(self.loader_tr).to(self.device) + self.aname = aconf.model
-
[docs] def tr_epoch(self, epoch): +
[docs] def tr_epoch(self, epoch): """ :param epoch: epoch number :return: @@ -447,19 +448,19 @@

Source code for domid.trai loss_val = pretrain.pretrain_loss(tensor_x_val, inject_tensor_val) else: loss_val = self.model.cal_loss(tensor_x_val, inject_tensor_val, self.warmup_beta) - - tensorboard_write( - self.writer, - self.model, - epoch, - self.lr, - self.warmup_beta, - acc_tr_y, - loss, - self.pretraining_finished, - tensor_x, - inject_tensor, - ) + if self.writer != None: + tensorboard_write( + self.writer, + self.model, + epoch, + self.lr, + self.warmup_beta, + acc_tr_y, + loss, + self.pretraining_finished, + tensor_x, + inject_tensor, + ) # _____storing results and Z space__________ self.storage.storing( @@ -477,14 +478,14 @@

Source code for domid.trai # self.storage.csv_dump(epoch) return flag_stop

-
[docs] def before_tr(self): +
[docs] def before_tr(self): """ check the performance of randomly initialized weight """ acc = PerfCluster.cal_acc(self.model, self.loader_tr, self.device) # FIXME change tr to te print("before training, model accuracy:", acc)
-
[docs] def post_tr(self): +
[docs] def post_tr(self): print("training is done") self.observer.after_all()
diff --git a/docs/build/html/_modules/domid/trainers/trainer_cluster.html b/docs/build/html/_modules/domid/trainers/trainer_cluster.html index 94828f3..1149992 100644 --- a/docs/build/html/_modules/domid/trainers/trainer_cluster.html +++ b/docs/build/html/_modules/domid/trainers/trainer_cluster.html @@ -322,7 +322,8 @@

Source code for domid
[docs]class TrainerCluster(AbstractTrainer): -
[docs] def __init__(self, model, task, observer, device, writer, pretrain=True, aconf=None): +
[docs] def init_business(self, model, task, observer, device, aconf, flag_accept=True): + """ :param model: model to train :param task: task to train on @@ -333,10 +334,13 @@

Source code for domid :param aconf: configuration parameters, including learning rate and pretrain threshold """ - super().__init__() + # super().__init__() super().init_business(model, task, observer, device, aconf) - self.pretrain = pretrain + if aconf.pre_tr > 0: + self.pretrain = True + else: + self.pretrain = False self.pretraining_finished = not self.pretrain self.lr = aconf.lr self.warmup_beta = 0.1 @@ -349,13 +353,13 @@

Source code for domid self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr) self.epo_loss_tr = None - self.writer = writer + self.writer = None self.thres = aconf.pre_tr # number of epochs for pretraining self.i_h, self.i_w = task.isize.h, task.isize.w self.args = aconf self.storage = Storing(self.args) self.loader_val = task.loader_val - self.aname = aconf.aname

+ self.aname = aconf.model
[docs] def tr_epoch(self, epoch): """ @@ -416,7 +420,6 @@

Source code for domid print("".join(["#"] * 60)) print("Epoch {}: Finished pretraining and starting to use the full model loss.".format(epoch)) print("".join(["#"] * 60)) - loss = self.model.cal_loss(tensor_x, inject_tensor, self.warmup_beta) loss = loss.sum() @@ -454,19 +457,19 @@

Source code for domid loss_val = pretrain.pretrain_loss(tensor_x_val, inject_tensor_val) else: loss_val = self.model.cal_loss(tensor_x_val, inject_tensor_val, self.warmup_beta) - - tensorboard_write( - self.writer, - self.model, - epoch, - self.lr, - self.warmup_beta, - acc_tr_y, - loss, - self.pretraining_finished, - tensor_x, - inject_tensor, - ) + if self.writer is not None: + tensorboard_write( + self.writer, + self.model, + epoch, + self.lr, + self.warmup_beta, + acc_tr_y, + loss, + self.pretraining_finished, + tensor_x, + inject_tensor, + ) # _____storing results and Z space__________ self.storage.storing( diff --git a/docs/build/html/_modules/domid/trainers/trainer_sdcn.html b/docs/build/html/_modules/domid/trainers/trainer_sdcn.html index fe70010..a396ae8 100644 --- a/docs/build/html/_modules/domid/trainers/trainer_sdcn.html +++ b/docs/build/html/_modules/domid/trainers/trainer_sdcn.html @@ -323,23 +323,32 @@

Source code for domid.tr from domid.utils.storing import Storing -
[docs]class TrainerCluster(AbstractTrainer): -
[docs] def __init__(self, model, task, observer, device, writer, pretrain=True, aconf=None): +
[docs]class TrainerSDCN(AbstractTrainer): +
[docs] def init_business(self, model, task, observer, device, aconf, flag_accept=True): """ - :param model: model to train - :param task: task to train on - :param observer: observer to notify - :param device: device to use - :param writer: tensorboard writer - :param pretrain: whether to pretrain the model with MSE loss - :param aconf: configuration parameters, including learning rate and pretrain threshold + model, task, observer, device, aconf """ - - super().__init__() + # def init_business(self, model, task, observer, device, writer, pretrain=True, aconf=None): + # """ + # :param model: model to train + # :param task: task to train on + # :param observer: observer to notify + # :param device: device to use + # :param writer: tensorboard writer + # :param pretrain: whether to pretrain the model with MSE loss + # :param aconf: configuration parameters, including learning rate and pretrain threshold + # """ + + # super().__init__() super().init_business(model, task, observer, device, aconf) - print(model) - self.pretrain = pretrain + # breakpoint() + # print(model) + if aconf.pre_tr > 0: + self.pretrain = True + else: + self.pretrain = False + self.pretraining_finished = not self.pretrain self.lr = aconf.lr self.warmup_beta = 0.1 @@ -350,13 +359,13 @@

Source code for domid.tr self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr) self.epo_loss_tr = None - self.writer = writer + self.writer = None self.thres = aconf.pre_tr # number of epochs for pretraining self.i_h, self.i_w = task.isize.h, task.isize.w self.args = aconf self.storage = Storing(self.args) self.loader_val = task.loader_tr - self.aname = aconf.aname + self.aname = aconf.model self.graph_method = self.model.graph_method assert self.graph_method, "Graph calculation methos should be specified" @@ -380,7 +389,7 @@

Source code for domid.tr ) self.model.adj = init_spar_mx

-
[docs] def tr_epoch(self, epoch): +
[docs] def tr_epoch(self, epoch): """ :param epoch: epoch number :return: @@ -412,7 +421,10 @@

Source code for domid.tr # _____________one training epoch: start_______________________ for i, (tensor_x, vec_y, vec_d, *other_vars) in enumerate(self.loader_tr): - + if len(other_vars) > 0: + inject_tensor, image_id = other_vars + if len(inject_tensor) > 0: + inject_tensor = inject_tensor.to(self.device) if i == 0: self.model.batch_zero = True if self.args.random_batching: @@ -422,14 +434,15 @@

Source code for domid.tr vec_d = vec_d[patches_idx, :] image_id = [image_id[patch_idx_num] for patch_idx_num in patches_idx] - self.model.adj = self.graph_constr.construct_graph( - tensor_x, image_id, self.graph_method, self.storage.experiment_name + init_adj_mx, init_spar_mx = self.graph_constr.construct_graph( + tensor_x, image_id, self.storage.experiment_name ) + self.model.adj = init_spar_mx else: self.model.adj = self.spar_mx[i] # .to(self.device) - - print("i_" + str(i), vec_y.argmax(dim=1).unique(), vec_d.argmax(dim=1).unique()) + if i < 3: + print("i_" + str(i), vec_y.argmax(dim=1).unique(), vec_d.argmax(dim=1).unique()) tensor_x, vec_y, vec_d = ( tensor_x.to(self.device), @@ -484,15 +497,19 @@

Source code for domid.tr for i, (tensor_x_val, vec_y_val, vec_d_val, *other_vars) in enumerate(self.loader_val): if self.args.random_batching: + if len(other_vars) > 0: + inject_tensor, img_id_val = other_vars + patches_idx = self.model.random_ind[i] # torch.randint(0, len(vec_y), (int(self.args.bs/3),)) tensor_x_val = tensor_x_val[patches_idx, :, :, :] vec_y_val = vec_y_val[patches_idx, :] vec_d_val = vec_d_val[patches_idx, :] img_id_val = [img_id_val[patch_idx_num] for patch_idx_num in patches_idx] - self.model.adj = self.graph_constr.construct_graph( - tensor_x_val, img_id_val, self.graph_method, self.storage.experiment_name + init_adj_mx, init_spar_mx = self.graph_constr.construct_graph( + tensor_x_val, img_id_val, self.storage.experiment_name ) + self.model.adj = init_spar_mx tensor_x_val, vec_y_val, vec_d_val = ( tensor_x_val.to(self.device), @@ -503,7 +520,7 @@

Source code for domid.tr if epoch < self.thres and not self.pretraining_finished: loss_val = pretrain.pretrain_loss(tensor_x_val) else: - loss_val = self.model.cal_loss(tensor_x_val, self.warmup_beta) + loss_val = self.model.cal_loss(tensor_x_val) tensorboard_write( self.writer, @@ -542,14 +559,15 @@

Source code for domid.tr # self.storage.csv_dump(epoch) return flag_stop

-
[docs] def before_tr(self): +
[docs] def before_tr(self): """ check the performance of randomly initialized weight """ + acc = PerfCluster.cal_acc(self.model, self.loader_tr, self.device) # FIXME change tr to te print("before training, model accuracy:", acc)
-
[docs] def post_tr(self): +
[docs] def post_tr(self): print("training is done") self.observer.after_all()
diff --git a/docs/build/html/_modules/domid/utils/storing.html b/docs/build/html/_modules/domid/utils/storing.html index e5ddbed..4367663 100644 --- a/docs/build/html/_modules/domid/utils/storing.html +++ b/docs/build/html/_modules/domid/utils/storing.html @@ -333,10 +333,11 @@

Source code for domid.utils.stor self.r_scores_tr = [] self.r_scores_te = [] - self.experiment_name = str(datetime.datetime.now()) + "_" + str(args.task) + "_" + str(args.aname) + self.experiment_name = str(datetime.datetime.now()) + "_" + str(args.task) + "_" + str(args.model) + self.experiment_name = self.experiment_name.replace(" ", "_") self.last_epoch = args.epos - self.ex_path = "./notebooks/" + self.experiment_name - if not os.path.exists("./notebooks/" + self.experiment_name): + self.ex_path = os.path.join("./notebooks", self.experiment_name) + if not os.path.exists(os.path.join("./notebooks", self.experiment_name)): print("______Created directory to save result_________") os.mkdir(self.ex_path) @@ -347,7 +348,6 @@

Source code for domid.utils.stor
[docs] def storing(self, epoch, acc_tr_y, acc_tr_d, loss_tr, acc_val_y, acc_val_d, loss_val, r_score_tr, r_score_te): - # arguments = [str(args.aname), str(args.model), str(args.prior), str(args.zd_dim), str(args.te_d), str(args.tr_d), str(args.L), str(args.lr), str(args.bs), str(args.pre_tr), str(args.warmup)] self.loss.append(loss_tr) self.val_loss.append(loss_val) @@ -380,14 +380,14 @@

Source code for domid.utils.stor pickle.dump(self.args, open(os.path.join(saving_dir, "commandline_arguments.p"), "wb"))

[docs] def saving_model(self, model): - # path_dict ="./notebooks/"+self.experiment_name + # path_dict =os.path.join("./notebooks", self.experiment_name) - torch.save(model.encoder.state_dict(), self.ex_path + "/encoder.pt") - torch.save(model.decoder.state_dict(), self.ex_path + "/decoder.pt")
+ torch.save(model.encoder.state_dict(), os.path.join(self.ex_path, "encoder.pt")) + torch.save(model.decoder.state_dict(), os.path.join(self.ex_path, "decoder.pt"))

[docs] def storing_z_space(self, Z, predictions, vec_y_labels, vec_d_labels, image_id_labels): - # exp_path =os.path.join("./notebooks/",self.experiment_name) + # exp_path =os.path.join("./notebooks",self.experiment_name) np.save(os.path.join(self.ex_path, "Z_space.npy"), Z) pickle.dump(Z, open(os.path.join(self.ex_path, "Z_space_picle.p"), "wb")) @@ -426,9 +426,9 @@

Source code for domid.utils.stor results_df.to_csv(os.path.join(self.args.path_to_results, "results.csv"), index=False) if self.args.inject_var: - model_name = "cd" + self.args.aname + model_name = "cd" + self.args.model else: - model_name = self.args.aname + model_name = self.args.model if self.last_epoch == epoch: row = [ { diff --git a/docs/build/html/_modules/index.html b/docs/build/html/_modules/index.html index f795694..ff9cfa5 100644 --- a/docs/build/html/_modules/index.html +++ b/docs/build/html/_modules/index.html @@ -313,6 +313,7 @@

All modules for which code is available

  • domid.algos.builder_m2yd
  • domid.algos.builder_sdcn
  • domid.algos.builder_vade
  • +
  • domid.algos.zoo_algos
  • domid.arg_parser
  • domid.compos.DEC_clustering_layer
  • domid.compos.GNN
  • @@ -335,6 +336,7 @@

    All modules for which code is available

  • domid.dsets.generate_dataset_dataframe_her2
  • domid.dsets.make_graph
  • domid.dsets.make_graph_wsi
  • +
  • domid.mk_exp
  • domid.models.a_model_cluster
  • domid.models.model_ae
  • domid.models.model_dec
  • @@ -355,12 +357,14 @@

    All modules for which code is available

  • domid.tests.test_mnist_dataset
  • domid.tests.test_model_builder
  • domid.tests.test_model_trainer
  • +
  • domid.tests.utils
  • domid.trainers.pretraining_GMM
  • domid.trainers.pretraining_KMeans
  • domid.trainers.pretraining_sdcn
  • domid.trainers.trainer_ae
  • domid.trainers.trainer_cluster
  • domid.trainers.trainer_sdcn
  • +
  • domid.trainers.zoo_trainer
  • domid.utils.mean_std
  • domid.utils.perf_cluster
  • domid.utils.perf_similarity
  • diff --git a/docs/build/html/_sources/domid.algos.rst.txt b/docs/build/html/_sources/domid.algos.rst.txt index 4b0553d..c04dc2f 100644 --- a/docs/build/html/_sources/domid.algos.rst.txt +++ b/docs/build/html/_sources/domid.algos.rst.txt @@ -44,6 +44,14 @@ domid.algos.builder\_vade module :undoc-members: :show-inheritance: +domid.algos.zoo\_algos module +----------------------------- + +.. automodule:: domid.algos.zoo_algos + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/docs/build/html/_sources/domid.rst.txt b/docs/build/html/_sources/domid.rst.txt index a385d59..1515987 100644 --- a/docs/build/html/_sources/domid.rst.txt +++ b/docs/build/html/_sources/domid.rst.txt @@ -27,6 +27,14 @@ domid.arg\_parser module :undoc-members: :show-inheritance: +domid.mk\_exp module +-------------------- + +.. automodule:: domid.mk_exp + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/docs/build/html/_sources/domid.tests.rst.txt b/docs/build/html/_sources/domid.tests.rst.txt index 4dce672..40dfc5b 100644 --- a/docs/build/html/_sources/domid.tests.rst.txt +++ b/docs/build/html/_sources/domid.tests.rst.txt @@ -52,6 +52,14 @@ domid.tests.test\_model\_trainer module :undoc-members: :show-inheritance: +domid.tests.utils module +------------------------ + +.. automodule:: domid.tests.utils + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/docs/build/html/_sources/domid.trainers.rst.txt b/docs/build/html/_sources/domid.trainers.rst.txt index c317e8f..830ac03 100644 --- a/docs/build/html/_sources/domid.trainers.rst.txt +++ b/docs/build/html/_sources/domid.trainers.rst.txt @@ -52,6 +52,14 @@ domid.trainers.trainer\_sdcn module :undoc-members: :show-inheritance: +domid.trainers.zoo\_trainer module +---------------------------------- + +.. automodule:: domid.trainers.zoo_trainer + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/docs/build/html/domid.algos.html b/docs/build/html/domid.algos.html index 92d8d96..4eac2db 100644 --- a/docs/build/html/domid.algos.html +++ b/docs/build/html/domid.algos.html @@ -338,6 +338,18 @@ +
  • domid.algos.zoo_algos module +
  • Module contents
  • @@ -386,6 +398,13 @@ domid.algos.builder_vade module + +
  • + + + domid.algos.zoo_algos module + +
  • @@ -493,6 +512,18 @@
  • +
  • domid.algos.zoo_algos module +
  • Module contents
  • @@ -596,6 +627,26 @@

    Submodulesdomid.algos.builder_vade.get_node_na()[source]
    +
    +

    domid.algos.zoo_algos module

    +

    chain of responsibility pattern for algorithm selection

    +
    +
    +class domid.algos.zoo_algos.AlgoBuilderChainNodeGetter(model, apath)[source]
    +

    Bases: object

    +

    1. Hardcoded chain +3. Return selected node

    +
    +
    +__init__(model, apath)[source]
    +
    +
    +
    +register_external_node(chain)[source]
    +

    if the user specify an external python file to implement the algorithm

    +
    +
    +

    Module contents

    diff --git a/docs/build/html/domid.compos.html b/docs/build/html/domid.compos.html index ed9cd62..17e2f72 100644 --- a/docs/build/html/domid.compos.html +++ b/docs/build/html/domid.compos.html @@ -321,6 +321,10 @@ @@ -341,6 +345,10 @@ @@ -361,6 +369,10 @@ @@ -381,6 +393,10 @@ @@ -657,6 +673,10 @@ @@ -677,6 +697,10 @@ @@ -697,6 +721,10 @@ @@ -717,6 +745,10 @@ @@ -958,6 +990,14 @@

    Submodules +
    +get_z(x)[source]
    +
    +
    +
    +get_log_sigma2(x)[source]
    +
    +
    forward(x)[source]
    @@ -1025,6 +1065,14 @@

    Submodules +
    +get_z(x)[source]
    +

    +
    +
    +get_log_sigma2(x)[source]
    +
    +
    forward(x)[source]
    @@ -1083,6 +1131,14 @@

    Submodules +
    +get_z(x)[source]
    +

    +
    +
    +get_log_sigma2(x)[source]
    +
    +
    forward(x)[source]

    Defines the computation performed at every call.

    @@ -1141,6 +1197,14 @@

    Submodules +
    +get_z(x)[source]
    +

    +
    +
    +get_log_sigma2(x)[source]
    +
    +
    forward(x)[source]
    diff --git a/docs/build/html/domid.html b/docs/build/html/domid.html index ee5ad04..c78ab95 100644 --- a/docs/build/html/domid.html +++ b/docs/build/html/domid.html @@ -314,6 +314,12 @@ +
  • domid.mk_exp module +
  • Module contents
  • @@ -375,6 +381,14 @@

    Subpackagesget_node_na() +
  • domid.algos.zoo_algos module +
  • Module contents
  • @@ -419,6 +433,8 @@

    Subpackagesdomid.compos.cnn_AE module

    - -
    -

    domid.models.model_ae module

    -
    -
    -class domid.models.model_ae.ModelAE(zd_dim, d_dim, device, L, i_c, i_h, i_w, args)[source]
    -

    Bases: AModelCluster

    -
    -__init__(zd_dim, d_dim, device, L, i_c, i_h, i_w, args)[source]
    -

    Initializes internal Module state, shared by both nn.Module and ScriptModule.

    +
    +cal_loss(tensor_x, inj_tensor=tensor([]), warmup_beta=None)[source]
    +

    Calculates the loss for the model.

    -
    -distance_between_clusters(cluster_layer)[source]
    -
    -
    -
    -infer_d_v(x)[source]
    -

    Predict the cluster/domain of the input data.

    +
    +infer_d_v(x)[source]
    +

    Predict the cluster/domain of the input data. +Corresponds to equation (16) in the paper.

    Parameters:

    x (tensor) – Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim].

    @@ -698,19 +552,18 @@

    Submodules -
    -infer_d_v_2(x, inject_domain)[source]
    -

    Used for tensorboard visualizations only.

    +
    +extend(model)[source]
    +

    extend the loss of the decoratee

    -
    -
    -cal_loss(x, inject_domain, warmup_beta=None)[source]
    -
    -
    -
    -pretrain_loss(x, inject_domain)[source]
    -
    +
    +
    +

    domid.models.model_ae module

    +
    +
    +domid.models.model_ae.mk_ae(parent_class=<class 'domid.models.a_model_cluster.AModelCluster'>)[source]
    +
    domid.models.model_ae.test_fun(d_dim, zd_dim, device)[source]
    @@ -718,170 +571,17 @@

    Submodules

    domid.models.model_dec module

    -
    -
    -class domid.models.model_dec.ModelDEC(zd_dim, d_dim, L, device, i_c, i_h, i_w, args)[source]
    -

    Bases: AModelCluster

    -
    -
    -__init__(zd_dim, d_dim, L, device, i_c, i_h, i_w, args)[source]
    -

    DEC model (Xie et al. 2015 “Unsupervised Deep Embedding for Clustering Analysis”) with -fully connected encoder and decoder.

    -
    -
    Parameters:
    -
      -
    • zd_dim – dimension of the latent space

    • -
    • d_dim – number of clusters for the clustering task

    • -
    • device – device to use, e.g., “cuda” or “cpu”

    • -
    • i_c – number of channels of the input image

    • -
    • i_h – height of the input image

    • -
    • i_w – width of the input image

    • -
    • args – command line arguments

    • -
    -
    -
    -
    -
    -
    -target_distribution(q_)[source]
    -

    Corresponds to equation 3 from the paper. -Calculates the target distribution for the Kullback-Leibler divergence loss.

    -
    -
    Parameters:
    -

    q – A tensor of the predicted cluster probabilities.

    -
    -
    Return tensor:
    -

    The calculated target distribution

    -
    -
    -
    -
    -
    -infer_d_v(x)[source]
    -
    -
    Parameters:
    -

    x – input tensor(image)

    -
    -
    Return tensor preds:
    -

    Predicted cluster assignments of shape (shape: [batch_size, self.d_dim]).

    -
    -
    -
    -
    -
    -infer_d_v_2(x, inject_domain)[source]
    -
    -
    -
    -pretrain_loss(x, inject_domain)[source]
    +
    +
    +domid.models.model_dec.mk_dec(parent_class=<class 'domid.models.a_model_cluster.AModelCluster'>)[source]
    -
    -
    -cal_loss(x, inject_tensor, warmup_beta)[source]
    -

    Calculates the KL-divergence loss between the predicted probabilities and the target distribution.

    -
    -
    Parameters:
    -
      -
    • x – input tensor/image

    • -
    • inject_tensor – tensor to inject (not used in DEC, only used in CDVaDE

    • -
    • warmup_beta – warm-up beta value

    • -
    -
    -
    Return tensor loss (float):
    -

    calculated KL-divergence loss value

    -
    -
    -
    -

    domid.models.model_m2yd module

    -
    -
    -class domid.models.model_m2yd.ModelXY2D(list_str_y, y_dim, zd_dim, gamma_y, device, i_c, i_h, i_w, dim_feat_x=10, list_str_d=None)[source]
    -

    Bases: AModelClassif

    -

    Let zd to be continuous vector, each component of zd represents the “attention” weight. -For a cluster, that means the bigger the $zd_k$ value, the more likely the cluster assignment -to component $k$. Note $zd_k~N(0,1)$.

    -

    Computational Structure: -generative path: (zd,y) -> x (image) -generative path: N(0,I) -> zd (prior for zd) -variational posterior path: -1. x -> y, -2. [y, feat(x)] -> z_d

    -

    FIXME: if we change the variational inference order, instead of x->y, then [y,feat(x)]->z_d -if we do first x->d (style extraction, texture prediction), -then [feat(x),d]-> y, will this be better?

    -

    KL divergence between posterior path vs generative(prior) path: -1. x->y: auxiliary path (not regularized by generative path, but by supervised learning) -no KL for y -2. KL(q(z_d)|p(z_d)), -q(z_d): [y,feat(x)]-> z_d -p(z_d): N(0,I)

    -

    Auxilliary path: supervised learning of x->y

    -

    FIXME: original M2 has prior Gaussian(0, I) for $z_d$, will this hinder learning of $z_d$ -on each component since the prior is draging each component to zero.

    -
    -
    -__init__(list_str_y, y_dim, zd_dim, gamma_y, device, i_c, i_h, i_w, dim_feat_x=10, list_str_d=None)[source]
    -
    -
    Parameters:
    -
      -
    • y_dim – classification task class-label dimension

    • -
    • zd_dim – dimension of latent variable $z_d$ dimension

    • -
    • aux_y

    • -
    -
    -
    -
    -
    -
    -cal_logit_y(tensor_x)[source]
    -

    calculate the logit for softmax classification

    -
    -
    -
    -infer_y_vpicn(tensor_x)[source]
    -
    -
    Parameters:
    -

    tensor_x – input tensor

    -
    -
    Returns:
    -

      -
    • vec_one_hot - (list) one-hot encoded classification output

    • -
    • prob - (list) softmax probabilities per class

    • -
    • ind - (int) index of maximal output class score

    • -
    • confidence - (float) maximum probability (already included in prob)

    • -
    • na_class - (string) class label for the maximum probability class

    • -
    -

    -
    -
    -
    -
    -
    -infer_d_v(tensor_x)[source]
    +
    +
    +domid.models.model_m2yd.mk_m2yd(parent_class=<class 'domainlab.models.a_model_classif.AModelClassif'>)[source]
    -
    -
    -forward(tensor_x, vec_y, vec_d=None)[source]
    -

    forward.

    -
    -
    Parameters:
    -
      -
    • x

    • -
    • y

    • -
    • d

    • -
    -
    -
    -
    -
    -
    -cal_loss(x, y, d=None, others=None)[source]
    -

    calculate the loss

    -
    -
    domid.models.model_m2yd.test_fun()[source]
    @@ -889,152 +589,17 @@

    Submodules

    domid.models.model_sdcn module

    -
    -
    -class domid.models.model_sdcn.ModelSDCN(zd_dim, d_dim, device, L, i_c, i_h, i_w, args)[source]
    -

    Bases: AModelCluster

    -

    ModelSDCN is a class that implements the SDCN model.(Bo D et al. 2020) -The model is composed of a convolutional encoder and decoder, a GNN and a clustering layer.

    -
    -
    -__init__(zd_dim, d_dim, device, L, i_c, i_h, i_w, args)[source]
    -

    Initializes internal Module state, shared by both nn.Module and ScriptModule.

    -
    -
    -
    -infer_d_v(x)[source]
    -

    Predict the cluster/domain of the input data. -Corresponds to equation (16) in the paper.

    -
    -
    Parameters:
    -

    x (tensor) – Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim].

    -
    -
    Return tensor preds:
    -

    One hot encoded tensor of the predicted cluster assignment.

    -
    -
    -
    -
    -
    -infer_d_v_2(x)[source]
    -

    Used for tensorboard visualizations only.

    -
    -
    -
    -target_distribution(q)[source]
    -

    Compute the target distribution p, where p_i = (sum_j q_j)^2 / sum_j^2 q_j. -Corresponds to equation (12) from the paper.

    -
    -
    -
    -cal_loss(x, warmup_beta=None)[source]
    -

    Compute the loss of the model. -Concentrate two different objectives, i.e. clustering objective and classification objective, in one loss function. -Corresponds to equation (15) in the paper. -:param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. -:param float warmup_beta: Warmup coefficient for the KL divergence term. -:return tensor loss: Loss tensor.

    -
    -
    -
    -cal_loss_for_tensorboard()[source]
    -
    -
    -
    -pretrain_loss(x)[source]
    +
    +
    +domid.models.model_sdcn.mk_sdcn(parent_class=<class 'domid.models.a_model_cluster.AModelCluster'>)[source]
    -

    domid.models.model_vade module

    -
    -
    -class domid.models.model_vade.ModelVaDE(zd_dim, d_dim, device, L, i_c, i_h, i_w, args)[source]
    -

    Bases: AModelCluster

    -
    -
    -__init__(zd_dim, d_dim, device, L, i_c, i_h, i_w, args)[source]
    -

    VaDE model (Jiang et al. 2017 “Variational Deep Embedding: -An Unsupervised and Generative Approach to Clustering”) with -fully connected encoder and decoder.

    -
    -
    Parameters:
    -
      -
    • zd_dim – dimension of the latent space

    • -
    • d_dim – number of clusters for the clustering task

    • -
    • device – device to use, e.g., “cuda” or “cpu”

    • -
    • i_c – number of channels of the input image

    • -
    • i_h – height of the input image

    • -
    • i_w – width of the input image

    • -
    • args – command line arguments

    • -
    -
    -
    -
    -
    -
    -infer_d_v(x)[source]
    -

    Predict the cluster/domain of the input data. -Corresponds to equation (16) in the paper.

    -
    -
    Parameters:
    -

    x (tensor) – Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim].

    -
    -
    Return tensor preds:
    -

    One hot encoded tensor of the predicted cluster assignment.

    -
    -
    -
    -
    -
    -infer_d_v_2(x, inject_domain)[source]
    -

    Used for tensorboard visualizations only.

    -
    -
    -
    -cal_loss(x, inject_domain, warmup_beta)[source]
    -

    Function that is called in trainer_vade to calculate loss

    -
    -
    Parameters:
    -

    x – tensor with input data

    -
    -
    Returns:
    -

    ELBO loss

    -
    -
    -
    -
    -
    -pretrain_loss(x, inject_domain)[source]
    -
    -
    -
    -reconstruction_loss(x, x_pro, log_sigma)[source]
    +
    +
    +domid.models.model_vade.mk_vade(parent_class=<class 'domid.models.a_model_cluster.AModelCluster'>)[source]
    -
    -
    -ELBO_Loss(x, inject_domain, warmup_beta)[source]
    -

    ELBO loss function -Using SGVB estimator and the reparametrization trick calculates ELBO loss. -Calculates loss between encoded input and input using ELBO equation (12) in the papaer. -:param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. -:param int L: Number of Monte Carlo samples in the SGVB

    -
    -
    -
    -gaussian_pdfs_log(x, mus, log_sigma2s)[source]
    -

    helper function

    -
    -
    -
    -static gaussian_pdf_log(x, mu, log_sigma2)[source]
    -

    subhelper function just one gausian pdf log calculation, used as a basis for gaussian_pdfs_log function -:param x: tensor of shape [batch_size, self.zd_dim] -:param mu: mean for the cluster distribution -:param log_sigma2: variance parameters of the cluster distribtion -:return: tensor with the Gaussian log probabilities of the shape of [batch_size, 1]

    -
    -
    domid.models.model_vade.test_fun(d_dim, zd_dim, device)[source]
    diff --git a/docs/build/html/domid.tasks.html b/docs/build/html/domid.tasks.html index 86bf91a..6f31c66 100644 --- a/docs/build/html/domid.tasks.html +++ b/docs/build/html/domid.tasks.html @@ -360,8 +360,6 @@
  • NodeTaskWSI.get_dset_by_domain()
  • - -
  • test_fun()
  • @@ -635,8 +633,6 @@
  • NodeTaskWSI.get_dset_by_domain()
  • - -
  • test_fun()
  • @@ -803,7 +799,7 @@

    Submodules
    -init_business(args)[source]
    +init_business(args, trainer=None)[source]

    create a dictionary of datasets

    @@ -1021,10 +1017,6 @@

    Submodules -
    -domid.tasks.task_wsi.test_fun()[source]
    -

    domid.tasks.zoo_tasks module

    diff --git a/docs/build/html/domid.tests.html b/docs/build/html/domid.tests.html index af8babc..d6142be 100644 --- a/docs/build/html/domid.tests.html +++ b/docs/build/html/domid.tests.html @@ -314,6 +314,14 @@
    +
    +domid.tests.test_graph.test_data()[source]
    +
    +
    +
    +domid.tests.test_graph.test_graph_methods()[source]
    +
    +
    +
    +domid.tests.test_graph.test_connection_calc()[source]
    +
    +
    +
    +domid.tests.test_graph.test_mk_adj_mat()[source]
    +
    +
    domid.tests.test_graph.test_MNISTcolor_SDCN_graph_construction_heat()[source]
    @@ -425,24 +455,20 @@

    Submodules

    domid.tests.test_losses module

    -
    -domid.tests.test_losses.experiment_train(args)[source]
    -
    -
    -domid.tests.test_losses.test_VADE_CNN_nonbinary()[source]
    +domid.tests.test_losses.test_VADE_CNN_nonbinary(tmp_path)[source]
    -domid.tests.test_losses.test_VADE_CNN()[source]
    +domid.tests.test_losses.test_VADE_CNN(tmp_path)[source]
    -domid.tests.test_losses.test_VADE_nonbinary()[source]
    +domid.tests.test_losses.test_VADE_nonbinary(tmp_path)[source]
    -domid.tests.test_losses.test_VADE()[source]
    +domid.tests.test_losses.test_VADE(tmp_path)[source]
    @@ -482,32 +508,36 @@

    Submodules

    domid.tests.test_model_trainer module

    -
    -domid.tests.test_model_trainer.experiment_train(args)[source]
    +
    +domid.tests.test_model_trainer.train_MNISTcolor_AE(out_dir)[source]
    +
    +
    +
    +domid.tests.test_model_trainer.ae_weights(tmp_path_factory)[source]
    -domid.tests.test_model_trainer.test_MNIST_pretrain()[source]
    +domid.tests.test_model_trainer.test_MNIST_pretrain(tmp_path)[source]
    -domid.tests.test_model_trainer.test_MNIST_train()[source]
    +domid.tests.test_model_trainer.test_MNIST_train(tmp_path)[source]
    -domid.tests.test_model_trainer.test_MNIST_train_CNN()[source]
    +domid.tests.test_model_trainer.test_MNIST_train_CNN(tmp_path)[source]
    -domid.tests.test_model_trainer.test_MNISTcolor_train()[source]
    +domid.tests.test_model_trainer.test_MNISTcolor_train(tmp_path)[source]
    -domid.tests.test_model_trainer.test_MNISTcolor_train_CNN()[source]
    +domid.tests.test_model_trainer.test_MNISTcolor_train_CNN(tmp_path)[source]
    -domid.tests.test_model_trainer.test_MNISTcolor_pretrain_CNN()[source]
    +domid.tests.test_model_trainer.test_MNISTcolor_pretrain_CNN(tmp_path)[source]
    @@ -515,15 +545,22 @@

    Submodules
    -domid.tests.test_model_trainer.test_MNIST_conditionalOne_train()[source]
    +domid.tests.test_model_trainer.test_MNIST_conditionalOne_train(tmp_path)[source]

    +
    +
    +
    +domid.tests.test_model_trainer.test_MNISTcolor_AE(ae_weights)[source]
    -domid.tests.test_model_trainer.test_MNISTcolor_SDCN()[source]
    +domid.tests.test_model_trainer.test_MNISTcolor_SDCN(tmp_path, ae_weights)[source]
    +

    +
    +

    domid.tests.utils module

    -
    -domid.tests.test_model_trainer.test_MNISTcolor_AE()[source]
    +
    +domid.tests.utils.experiment_train(args, save_path=None)[source]
    diff --git a/docs/build/html/domid.trainers.html b/docs/build/html/domid.trainers.html index 53fa7ac..0404bce 100644 --- a/docs/build/html/domid.trainers.html +++ b/docs/build/html/domid.trainers.html @@ -331,15 +331,15 @@
  • domid.trainers.trainer_ae module
  • +
    +

    domid.trainers.zoo_trainer module

    +

    select trainer

    +
    +
    +class domid.trainers.zoo_trainer.TrainerChainNodeGetter(str_trainer)[source]
    +

    Bases: object

    +

    Chain of Responsibility: node is named in pattern Trainer[XXX] where the string +after ‘Trainer’ is the name to be passed to args.trainer.

    +
    +
    +__init__(str_trainer)[source]
    +

    __init__. +:param args: command line arguments

    +
    +
    +

    Module contents

    diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html index 6db240b..1e6db85 100644 --- a/docs/build/html/genindex.html +++ b/docs/build/html/genindex.html @@ -335,9 +335,11 @@

    Index

    _

      -
    • __init__() (domid.compos.cnn_AE.ConvolutionalDecoder method) +
    • __init__() (domid.algos.zoo_algos.AlgoBuilderChainNodeGetter method)
        +
      • (domid.compos.cnn_AE.ConvolutionalDecoder method) +
      • (domid.compos.cnn_AE.ConvolutionalEncoder method)
      • (domid.compos.cnn_VAE.ConvolutionalDecoder method) @@ -380,15 +382,7 @@

        _

      • (domid.dsets.make_graph_wsi.GraphConstructorWSI method)
      • -
      • (domid.models.model_ae.ModelAE method) -
      • -
      • (domid.models.model_dec.ModelDEC method) -
      • -
      • (domid.models.model_m2yd.ModelXY2D method) -
      • -
      • (domid.models.model_sdcn.ModelSDCN method) -
      • -
      • (domid.models.model_vade.ModelVaDE method) +
      • (domid.models.a_model_cluster.AModelCluster method)
      • (domid.tasks.zoo_tasks.TaskChainNodeGetter method)
      • @@ -398,11 +392,7 @@

        _

      • (domid.trainers.pretraining_sdcn.PretrainingSDCN method)
      • -
      • (domid.trainers.trainer_ae.TrainerCluster method) -
      • -
      • (domid.trainers.trainer_cluster.TrainerCluster method) -
      • -
      • (domid.trainers.trainer_sdcn.TrainerCluster method) +
      • (domid.trainers.zoo_trainer.TrainerChainNodeGetter method)
      • (domid.utils.perf_cluster.PerfCluster method)
      • @@ -418,9 +408,13 @@

        A

        @@ -429,12 +423,12 @@

        A

        B

        @@ -449,21 +443,7 @@

        C

      • (domid.utils.perf_similarity.PerfCorrelationHER2 class method)
      • -
      • cal_logit_y() (domid.models.model_m2yd.ModelXY2D method) -
      • -
      • cal_loss() (domid.models.model_ae.ModelAE method) - -
      • -
      • cal_loss_for_tensorboard() (domid.models.model_sdcn.ModelSDCN method) +
      • cal_loss() (domid.models.a_model_cluster.AModelCluster method)
      • cal_perf_metric() (domid.models.a_model_cluster.AModelCluster method)
      • @@ -471,8 +451,6 @@

        C

      • cnn_decoding_block() (in module domid.compos.VAE_blocks)
      • - - + - + @@ -1065,10 +1065,6 @@

        F

        G

        +
        • domid.models.model_ae @@ -763,6 +753,8 @@

          D

        • module
        +
        @@ -1139,6 +1145,16 @@

        G

      • get_output_shape() (in module domid.compos.VAE_blocks)
      • +
      • get_z() (domid.compos.cnn_AE.ConvolutionalEncoder method) + +
      • GMM_fit() (domid.trainers.pretraining_GMM.Pretraining method)
      • GNN (class in domid.compos.GNN) @@ -1165,29 +1181,7 @@

        H

        I

      • +
      • get_log_sigma2() (domid.compos.cnn_AE.ConvolutionalEncoder method) + +
      • @@ -1268,10 +1268,22 @@

        M

      • mean_scores_per_experiment() (in module domid.dsets.generate_dataset_dataframe_her2)
      • mk_adj_mat() (domid.dsets.make_graph.GraphConstructor method) +
      • +
      • mk_ae() (in module domid.models.model_ae) +
      • +
      • mk_dec() (in module domid.models.model_dec) +
      • +
      • mk_exp() (in module domid.mk_exp) +
      • +
      • mk_m2yd() (in module domid.models.model_m2yd)
      • mk_parser_main() (in module domid.arg_parser)
      • mk_prediction() (domid.compos.predict_basic.Prediction method) +
      • +
      • mk_sdcn() (in module domid.models.model_sdcn) +
      • +
      • mk_vade() (in module domid.models.model_vade)
      • model_compiler() (in module domid.tests.test_model_builder)
      • @@ -1281,16 +1293,6 @@

        M

      • (domid.trainers.pretraining_sdcn.PretrainingSDCN method)
      • -
      • ModelAE (class in domid.models.model_ae) -
      • -
      • ModelDEC (class in domid.models.model_dec) -
      • -
      • ModelSDCN (class in domid.models.model_sdcn) -
      • -
      • ModelVaDE (class in domid.models.model_vade) -
      • -
      • ModelXY2D (class in domid.models.model_m2yd) -
      • module @@ -1308,6 +1310,8 @@

        M

      • domid.algos.builder_sdcn
      • domid.algos.builder_vade +
      • +
      • domid.algos.zoo_algos
      • domid.arg_parser
      • @@ -1356,6 +1360,8 @@

        M

      • domid.dsets.make_graph
      • domid.dsets.make_graph_wsi +
      • +
      • domid.mk_exp
      • domid.models
      • @@ -1402,6 +1408,8 @@

        M

      • domid.tests.test_model_builder
      • domid.tests.test_model_trainer +
      • +
      • domid.tests.utils
      • domid.trainers
      • @@ -1416,6 +1424,8 @@

        M

      • domid.trainers.trainer_cluster
      • domid.trainers.trainer_sdcn +
      • +
      • domid.trainers.zoo_trainer
      • domid.utils
      • @@ -1482,34 +1492,26 @@

        P

      • PerfCorrelationHER2 (class in domid.utils.perf_similarity)
      • -
      • post_tr() (domid.trainers.trainer_ae.TrainerCluster method) +
      • post_tr() (domid.trainers.trainer_ae.TrainerAE method)
      • + + -
        • Pretraining (class in domid.trainers.pretraining_GMM)
            @@ -1526,7 +1528,7 @@

            P

            R

            + + + + + + + + + + + +
            @@ -430,6 +431,7 @@

            Training a Modeldomid.trainers.trainer_ae module
          • domid.trainers.trainer_cluster module
          • domid.trainers.trainer_sdcn module
          • +
          • domid.trainers.zoo_trainer module
          • Module contents
          • diff --git a/docs/build/html/modules.html b/docs/build/html/modules.html index 3c803be..f319c11 100644 --- a/docs/build/html/modules.html +++ b/docs/build/html/modules.html @@ -321,6 +321,7 @@

            domiddomid.algos.builder_m2yd module
          • domid.algos.builder_sdcn module
          • domid.algos.builder_vade module
          • +
          • domid.algos.zoo_algos module
          • Module contents
          • @@ -387,6 +388,7 @@

            domiddomid.tests.test_mnist_dataset module
          • domid.tests.test_model_builder module
          • domid.tests.test_model_trainer module
          • +
          • domid.tests.utils module
          • Module contents
          • @@ -398,6 +400,7 @@

            domiddomid.trainers.trainer_ae module
          • domid.trainers.trainer_cluster module
          • domid.trainers.trainer_sdcn module
          • +
          • domid.trainers.zoo_trainer module
          • Module contents
          • @@ -418,6 +421,10 @@

            domidparse_cmd_args() +
          • domid.mk_exp module +
          • Module contents
          • diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv index de7b1ff65c56dfbbd242499b6fdf3e53de135c9d..87213fb27fab339e4dd3449e01fc9c5db6393a59 100644 GIT binary patch delta 8704 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 ezkhp`K~T%mX1SkPg(1$sP&ilI;d delta 8823 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 diff --git a/docs/build/html/py-modindex.html b/docs/build/html/py-modindex.html index eff908c..4d4efdf 100644 --- a/docs/build/html/py-modindex.html +++ b/docs/build/html/py-modindex.html @@ -357,6 +357,11 @@

            Python Module Index

                domid.algos.builder_vade
                + domid.algos.zoo_algos +
                @@ -477,6 +482,11 @@

            Python Module Index

                domid.dsets.make_graph_wsi
                + domid.mk_exp +
                @@ -592,6 +602,11 @@

            Python Module Index

                domid.tests.test_model_trainer
                + domid.tests.utils +
                @@ -627,6 +642,11 @@

            Python Module Index

                domid.trainers.trainer_sdcn
                + domid.trainers.zoo_trainer +
                diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js index bb40749..bb6d14a 100644 --- a/docs/build/html/searchindex.js +++ b/docs/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["about", "about_link", "domid", "domid.algos", "domid.compos", "domid.dsets", "domid.models", "domid.tasks", "domid.tests", "domid.trainers", "domid.utils", "index", "modules", "readme_link", "requirements"], "filenames": ["about.md", "about_link.rst", "domid.rst", "domid.algos.rst", "domid.compos.rst", "domid.dsets.rst", "domid.models.rst", "domid.tasks.rst", "domid.tests.rst", "domid.trainers.rst", "domid.utils.rst", "index.rst", "modules.rst", "readme_link.rst", "requirements.txt"], "titles": ["VaDE Model Summary", "About DomId", "domid package", "domid.algos package", "domid.compos package", "domid.dsets package", "domid.models package", "domid.tasks package", "domid.tests package", "domid.trainers package", "domid.utils package", "Welcome to DomId\u2019s documentation!", "domid", "Introduction", "recommonmark==0.5.0.dev0"], "terms": {"variat": [0, 1, 6, 11, 13], "deep": [0, 1, 6, 11, 13], "embed": [0, 1, 6, 11, 13], "1": [0, 1, 4, 5, 6, 7, 13], "i": [0, 1, 4, 5, 6, 7, 11, 13], "an": [0, 1, 6, 13], "unsupervis": [0, 1, 6, 7, 11], "gener": [0, 1, 6, 11, 13], "cluster": [0, 1, 4, 5, 6, 7, 10, 11], "approach": [0, 1, 6, 13], "base": [0, 1, 3, 4, 5, 6, 7, 9, 10, 11], "autoencod": [0, 1], "2": [0, 1, 4, 5, 6, 13], "In": [0, 1, 13], "thi": [0, 1, 4, 5, 6, 7, 10, 11, 13], "librari": [0, 1], "can": [0, 1, 5, 7, 10, 11, 13], "deploi": [0, 1], "us": [0, 1, 4, 5, 6, 7, 9, 10, 11, 13], "both": [0, 1, 4, 5, 6, 11], "artifici": [0, 1], "neural": [0, 1, 9, 13], "network": [0, 1, 9, 13], "ann": [0, 1], "convolut": [0, 1, 4, 6, 11], "cnn": [0, 1, 13], "architectur": [0, 1, 11, 13], "encod": [0, 1, 4, 6, 10, 11, 13], "x": [0, 1, 4, 5, 6], "\u03c6": [0, 1], "decod": [0, 1, 4, 6, 11, 13], "f": [0, 1], "z": [0, 1, 4, 10], "\u03b8": [0, 1], "The": [0, 1, 4, 5, 6, 7, 11, 13], "learn": [0, 1, 6, 7, 9, 11], "compress": [0, 1], "high": [0, 1], "dimension": [0, 1, 13], "input": [0, 1, 4, 6, 9, 10], "imag": [0, 1, 4, 5, 6, 7, 9, 13], "lower": [0, 1], "latent": [0, 1, 4, 6, 13], "represent": [0, 1, 4], "mixtur": [0, 1], "gaussian": [0, 1, 6], "mog": [0, 1], "prior": [0, 1, 4, 6, 13], "distribut": [0, 1, 4, 6], "we": [0, 1, 6, 7, 9, 13], "examin": [0, 1], "sub": [0, 1], "group": [0, 1], "domain": [0, 1, 4, 5, 6, 7, 10, 11], "within": [0, 1, 4, 13], "dataset": [0, 1, 4, 5, 7, 10], "reveal": [0, 1], "individu": [0, 1], "space": [0, 1, 4, 6, 13], "how": [0, 1, 13], "affect": [0, 1], "perform": [0, 1, 4, 6, 7, 9, 10, 11, 13], "infer": [0, 1, 6], "where": [0, 1, 6, 7], "observ": [0, 1, 3, 9, 11], "ar": [0, 1, 4, 5, 7, 9, 11, 13], "map": [0, 1], "seri": [0, 1], "correspond": [0, 1, 4, 6, 13], "variabl": [0, 1, 5, 6, 13], "assign": [0, 1, 4, 6, 10], "c": [0, 1], "denot": [0, 1], "d": [0, 1, 6, 10], "e": [0, 1, 4, 5, 6, 13], "r": [0, 1], "number": [0, 1, 4, 5, 6, 9, 10, 13], "from": [0, 1, 4, 5, 6, 7, 11, 13], "sampl": [0, 1, 6], "thu": [0, 1], "train": [0, 1, 4, 5, 6, 7, 9], "also": [0, 1, 5, 13], "synthet": [0, 1], "algorithm": [0, 1, 10, 13], "identifi": [0, 1, 13], "subgroup": [0, 1, 13], "optim": [0, 1, 10], "stochast": [0, 1], "gradient": [0, 1], "bay": [0, 1, 13], "cite": [0, 1], "kingmaautoencodingvariationalbayes2013": [0, 1], "maxim": [0, 1, 6], "statist": [0, 1], "measur": [0, 1, 10], "call": [0, 1, 4, 5, 6], "evid": [0, 1], "bound": [0, 1], "elbo": [0, 1, 6, 9, 13], "packag": [0, 1, 11, 12, 13], "implement": [0, 1, 5, 6, 11, 13], "condition": [0, 1, 11, 13], "4": [0, 1, 4, 5, 13], "expans": [0, 1], "": [0, 1, 4, 7], "process": [0, 1, 11, 13], "differ": [0, 1, 5, 6, 13], "becaus": [0, 1, 7], "combin": [0, 1, 5, 13], "extra": [0, 1], "y": [0, 1, 6, 10], "shown": [0, 1], "figur": [0, 1], "below": [0, 1, 11], "These": [0, 1], "mai": [0, 1], "includ": [0, 1, 6, 7, 9, 11], "class": [0, 1, 3, 4, 5, 6, 7, 9, 10, 13], "label": [0, 1, 4, 5, 6, 7, 10, 13], "exist": [0, 1], "structur": [0, 1, 5, 6, 13], "do": [0, 1, 6], "need": [0, 1, 4, 5, 7, 13], "It": [0, 1], "expect": [0, 1], "addit": [0, 1, 7], "access": [0, 1], "dure": [0, 1, 9, 13], "test": [0, 1, 2, 5, 6, 7, 10, 12], "3": [0, 1, 4, 5, 6, 7, 13], "method": [0, 1, 5, 7], "techniqu": [0, 1], "discov": [0, 1], "data": [0, 1, 4, 5, 6, 7, 9, 10, 11], "point": [0, 1], "involv": [0, 1], "simultan": [0, 1], "loss": [0, 1, 4, 5, 6, 9, 11, 13], "function": [0, 1, 4, 5, 6, 7, 10, 11], "similar": [0, 1], "gcn": [0, 1, 13], "ae": [0, 1, 4, 13], "purpos": [0, 1, 13], "5": [0, 1, 4, 13], "howev": [0, 1, 11, 13], "origin": [0, 1, 4, 6, 13], "face": [0, 1, 13], "signific": [0, 1, 13], "scalabl": [0, 1, 13], "challeng": [0, 1, 13], "hinder": [0, 1, 6, 13], "its": [0, 1, 13], "deploy": [0, 1, 13], "digit": [0, 1, 5, 7, 13], "pathologi": [0, 1, 13], "particularli": [0, 1, 13], "when": [0, 1, 4, 13], "deal": [0, 1, 13], "whole": [0, 1, 10, 13], "slide": [0, 1, 13], "wsi": [0, 1, 5, 7], "which": [0, 1, 4, 5, 7, 10, 11, 13], "typic": [0, 1, 5, 13], "gigapixel": [0, 1, 13], "size": [0, 1, 4, 7, 13], "larger": [0, 1, 13], "limit": [0, 1, 13], "aris": [0, 1, 13], "construct": [0, 1, 4, 5, 13], "graph": [0, 1, 4, 5, 13], "entir": [0, 1, 13], "imper": [0, 1, 13], "all": [0, 1, 4, 5, 6, 7, 9, 13], "singl": [0, 1, 5, 13], "batch": [0, 1, 4, 5, 13], "To": [0, 1, 13], "overcom": [0, 1, 13], "issu": [0, 1, 13], "propos": [0, 1, 13], "strategi": [0, 1, 13], "introduc": [0, 1, 13], "novel": [0, 1, 13], "tailor": [0, 1, 13], "specif": [0, 1, 4, 11, 13], "experiment": [0, 1, 13], "vae": [0, 1, 4], "supervis": [0, 1, 6], "classif": [0, 1, 6, 7], "task": [0, 1, 2, 4, 5, 6, 9, 12, 13], "At": [0, 1], "current": [0, 1, 4, 5, 7, 11, 13], "stage": [0, 1], "pure": [0, 1], "valid": [0, 1, 4, 6, 7, 11, 13], "recommend": [0, 1, 13], "practic": [0, 1], "unless": [0, 1], "you": [0, 1], "know": [0, 1], "exactli": [0, 1], "what": [0, 1], "jiang": [0, 1, 6, 13], "zhuxi": [0, 1, 13], "et": [0, 1, 6, 13], "al": [0, 1, 6, 13], "ijcai": [0, 1, 13], "2017": [0, 1, 6, 13], "http": [0, 1, 13, 14], "arxiv": [0, 1, 13], "org": [0, 1, 13], "ab": [0, 1, 13], "1611": [0, 1, 13], "05148": [0, 1, 13], "kingma": [0, 1, 13], "well": [0, 1, 10, 13], "auto": [0, 1, 13], "iclr": [0, 1, 13], "2013": [0, 1, 13], "1312": [0, 1, 13], "6114": [0, 1, 13], "xie": [0, 1, 6, 13], "girshick": [0, 1, 13], "farhadi": [0, 1, 13], "analysi": [0, 1, 6, 13], "2016": [0, 1, 13], "1511": [0, 1, 13], "06335": [0, 1, 13], "sidulova": [0, 1, 13], "sun": [0, 1, 13], "gossmann": [0, 1, 13], "condit": [0, 1, 13], "identif": [0, 1, 11], "set": [0, 1, 4, 6, 7, 13], "miccai": [0, 1, 13], "2023": [0, 1, 13], "link": [0, 1, 13], "springer": [0, 1, 13], "com": [0, 1, 13, 14], "chapter": [0, 1, 13], "10": [0, 1, 4, 6, 7, 13], "1007": [0, 1, 13], "978": [0, 1, 13], "031": [0, 1, 13], "43993": [0, 1, 13], "3_64": [0, 1, 13], "bo": [0, 1, 6, 13], "deyu": [0, 1, 13], "proceed": [0, 1, 13], "web": [0, 1, 13], "confer": [0, 1, 13], "2020": [0, 1, 6, 13], "doi": [0, 1, 13], "1145": [0, 1, 13], "3366423": [0, 1, 13], "3380214": [0, 1, 13], "6": [0, 1, 13], "kahaki": [0, 1, 13], "hagemann": [0, 1, 13], "contextu": [0, 1, 13], "2024": [0, 1, 13], "review": [0, 1, 13], "algo": [2, 11, 12, 13], "builder_a": [2, 11, 12, 13], "nodealgobuildera": [2, 3], "init_busi": [2, 3, 7], "get_node_na": [2, 3], "builder_dec": [2, 11, 12, 13], "nodealgobuilderdec": [2, 3], "builder_m2yd": [2, 11, 12, 13], "nodealgobuilderm2yd": [2, 3], "builder_sdcn": [2, 11, 12, 13], "nodealgobuildersdcn": [2, 3], "builder_vad": [2, 11, 12, 13], "nodealgobuildervad": [2, 3], "compo": [2, 11, 12], "dec_clustering_lay": [2, 11, 12], "decclusteringlay": [2, 4], "__init__": [2, 4, 5, 6, 7, 9, 10], "forward": [2, 4, 6], "gnn": [2, 6, 11, 12], "gnn_layer": [2, 11, 12], "gnnlayer": [2, 4], "vae_block": [2, 11, 12], "get_output_shap": [2, 4], "cnn_encoding_block": [2, 4], "cnn_decoding_block": [2, 4], "unflatten": [2, 4], "linear_block": [2, 4], "cnn_ae": [2, 11, 12], "convolutionalencod": [2, 4], "convolutionaldecod": [2, 4], "cnn_vae": [2, 11, 12], "linear_a": [2, 11, 12], "linearencodera": [2, 4], "lineardecodera": [2, 4], "linear_va": [2, 11, 12], "linearencod": [2, 4], "lineardecod": [2, 4], "nn_net": [2, 11, 12], "net_mnist": [2, 4], "probe": [2, 4, 10], "conv_op": [2, 4], "test_net_mnist": [2, 4], "predict_bas": [2, 11, 12], "predict": [2, 4, 5, 6, 10], "mk_predict": [2, 4], "epoch_tr_acc": [2, 4], "epoch_val_acc": [2, 4], "epoch_tr_correl": [2, 4], "epoch_val_correl": [2, 4], "tensorboard_fun": [2, 11, 12], "tensorboard_writ": [2, 4], "dset": [2, 11, 12, 13], "a_dset_mnist_color_rgb_solo": [2, 12, 13], "adsetmnistcolorrgbsolo": [2, 5], "get_foreground_color": [2, 5], "get_background_color": [2, 5], "get_num_color": [2, 5], "generate_datafram": [2, 5], "dset_her2": [2, 12, 13], "dsether2": [2, 5], "dset_mnist": [2, 12], "dsetmnist": [2, 5], "dset_mnist_color_solo_default": [2, 12], "dsetmnistcolorsolodefault": [2, 5], "palett": [2, 5, 7], "dset_unittest": [2, 12], "dsetunittest": [2, 5], "create_the_dataset": [2, 5], "dset_usp": [2, 12], "dsetusp": [2, 5], "get_original_indici": [2, 5], "dset_wsi": [2, 12], "dsetwsi": [2, 5], "generate_dataset_dataframe_her2": [2, 12], "get_jpg_fold": [2, 5], "total_count_imag": [2, 5], "parse_machine_label": [2, 5], "mean_scores_per_experi": [2, 5], "make_graph": [2, 12], "graphconstructor": [2, 5], "sparse_mx_to_torch_sparse_tensor": [2, 5], "get_features_label": [2, 5], "normal": [2, 5], "distance_calc": [2, 5], "connection_calc": [2, 5], "mk_adj_mat": [2, 5], "construct_graph": [2, 5], "make_graph_wsi": [2, 12], "graphconstructorwsi": [2, 5], "distance_calc_wsi": [2, 5], "model": [2, 3, 4, 5, 7, 8, 9, 10, 12], "a_model_clust": [2, 11, 12], "amodelclust": [2, 6], "create_perf_obj": [2, 6], "cal_perf_metr": [2, 6], "model_a": [2, 11, 12], "modela": [2, 6], "distance_between_clust": [2, 6], "infer_d_v": [2, 6], "infer_d_v_2": [2, 6], "cal_loss": [2, 6], "pretrain_loss": [2, 6, 9], "test_fun": [2, 6, 7], "model_dec": [2, 11, 12], "modeldec": [2, 6], "target_distribut": [2, 6], "model_m2yd": [2, 11, 12], "modelxy2d": [2, 6], "cal_logit_i": [2, 6], "infer_y_vpicn": [2, 6], "model_sdcn": [2, 11, 12], "modelsdcn": [2, 6], "cal_loss_for_tensorboard": [2, 6], "model_vad": [2, 11, 12], "modelvad": [2, 6], "reconstruction_loss": [2, 6], "elbo_loss": [2, 6], "gaussian_pdfs_log": [2, 6], "gaussian_pdf_log": [2, 6], "b_task_clust": [2, 12], "nodetaskdictclust": [2, 7], "task_her2": [2, 12, 13], "nodetaskher2": [2, 7], "list_str_i": [2, 6, 7], "isiz": [2, 7], "get_list_domain": [2, 7], "get_dset_by_domain": [2, 7], "calc_corr": [2, 7], "task_mnist": [2, 12], "nodetaskmnist": [2, 7], "task_mnist_color": [2, 12], "nodetaskmnistcolor10": [2, 7], "dim_i": [2, 7], "task_unittest": [2, 12], "nodetaskunittest": [2, 7], "task_usp": [2, 12], "nodetaskusp": [2, 7], "task_wsi": [2, 12], "nodetaskwsi": [2, 7], "zoo_task": [2, 12, 13], "taskchainnodegett": [2, 7], "test_domid": [2, 12], "test_vers": [2, 8], "test_graph": [2, 12], "graph_constructor": [2, 8], "test_mnistcolor_sdcn_graph_construction_heat": [2, 8], "test_mnistcolor_sdcn_graph_construction_nco": [2, 8], "test_loss": [2, 12], "experiment_train": [2, 8], "test_vade_cnn_nonbinari": [2, 8], "test_vade_cnn": [2, 8], "test_vade_nonbinari": [2, 8], "test_vad": [2, 8], "test_mnist_dataset": [2, 12], "node_compil": [2, 8], "test_mnist_length": [2, 8], "test_mnistcolor10_length": [2, 8], "test_model_build": [2, 12], "model_compil": [2, 8], "test_vade_linear": [2, 8], "test_m2yd": [2, 8], "test_model_train": [2, 12], "test_mnist_pretrain": [2, 8], "test_mnist_train": [2, 8], "test_mnist_train_cnn": [2, 8], "test_mnistcolor_train": [2, 8], "test_mnistcolor_train_cnn": [2, 8], "test_mnistcolor_pretrain_cnn": [2, 8], "test_m2yd_train_mnistcolor": [2, 8], "test_mnist_conditionalone_train": [2, 8], "test_mnistcolor_sdcn": [2, 8], "test_mnistcolor_a": [2, 8], "trainer": [2, 3, 5, 11, 12], "pretraining_gmm": [2, 11, 12], "pretrain": [2, 9, 11], "gmm_fit": [2, 9], "pretraining_kmean": [2, 11, 12], "model_fit": [2, 9], "pretraining_sdcn": [2, 11, 12], "pretrainingsdcn": [2, 9], "kmeans_cluster_assign": [2, 9], "trainer_a": [2, 11, 12], "trainerclust": [2, 9], "tr_epoch": [2, 9], "before_tr": [2, 9], "post_tr": [2, 9], "trainer_clust": [2, 11, 12], "trainer_sdcn": [2, 11, 12], "util": [2, 12], "mean_std": [2, 11, 12], "run": [2, 4, 10, 11, 13], "run2": [2, 10], "perf_clust": [2, 11, 12], "perfclust": [2, 10], "hungarian_algorithm": [2, 10], "cal_acc": [2, 10], "perf_similar": [2, 11, 12], "perfcorrelationher2": [2, 10], "store": [2, 4, 7, 11, 12, 13], "saving_model": [2, 10], "storing_z_spac": [2, 10], "csv_dump": [2, 10], "command": [2, 6, 7, 13], "line": [2, 5, 6, 7, 13], "argument": [2, 5, 6, 7, 13], "mk_parser_main": [2, 12], "sourc": [2, 3, 4, 5, 6, 7, 8, 9, 10], "arg": [2, 5, 6, 7, 8, 9, 10], "definit": 2, "parse_cmd_arg": [2, 12], "pars": 2, "given": [2, 4, 5], "success_nod": 3, "none": [3, 4, 5, 6, 7, 9, 10], "nodealgobuild": 3, "exp": 3, "initi": [3, 4, 5, 6, 9, 11], "return": [3, 4, 5, 6, 7, 9, 10], "n_cluster": 4, "hidden": 4, "cluster_cent": 4, "alpha": 4, "0": [4, 5, 6, 7, 13], "devic": [4, 6, 7, 9, 10], "cpu": [4, 6], "paramet": [4, 5, 6, 7, 9, 10], "layer": [4, 6], "center": 4, "student": 4, "t": 4, "g": [4, 5, 6, 13], "cuda": [4, 6], "propag": 4, "clusteringlay": 4, "equat": [4, 6], "paper": [4, 6, 13], "tensor": [4, 5, 6], "featur": [4, 5, 11], "t_dist": 4, "soft": 4, "n_input": 4, "n_enc_1": 4, "n_enc_2": 4, "n_enc_3": 4, "n_z": 4, "intern": [4, 6], "state": [4, 6], "share": [4, 6], "nn": [4, 6], "scriptmodul": [4, 6], "adj": 4, "tra1": 4, "tra2": 4, "tra3": 4, "sigma": 4, "adjac": [4, 5], "matrix": [4, 5, 10], "first": [4, 6], "second": 4, "third": 4, "in_featur": 4, "out_featur": 4, "activ": 4, "relu": 4, "adjec": 4, "image_dim": 4, "in_c": 4, "out_c": 4, "kernel_s": 4, "stride": 4, "pad": 4, "num_channel": 4, "defin": [4, 13], "comput": [4, 6, 10], "everi": 4, "should": [4, 6, 13], "overridden": 4, "subclass": 4, "although": 4, "recip": 4, "pass": [4, 5], "one": [4, 5, 6, 13], "instanc": 4, "afterward": 4, "instead": [4, 6, 7], "sinc": [4, 6], "former": 4, "take": [4, 10], "care": 4, "regist": 4, "hook": 4, "while": [4, 7, 11], "latter": 4, "silent": 4, "ignor": 4, "them": [4, 5], "zd_dim": [4, 6, 13], "num_filt": 4, "32": 4, "64": 4, "128": 4, "i_w": [4, 6, 9], "28": [4, 5], "i_h": [4, 6, 9], "k": [4, 5, 6], "dimens": [4, 5, 6, 7], "channel": [4, 6, 7], "list": [4, 6, 7], "filter": 4, "each": [4, 5, 6, 9, 11], "width": [4, 6, 7, 9], "height": [4, 6, 7, 9], "kernel": 4, "domain_dim": 4, "h_dim": 4, "linear": [4, 11], "output": [4, 6, 13], "have": [4, 6, 11], "twice": 4, "mani": 4, "mean": [4, 5, 6, 10], "log": [4, 6, 11], "revers": 4, "order": [4, 6, 13], "x_pro": [4, 6], "reconstruct": 4, "assum": [4, 13], "equal": 4, "other": [4, 6, 9, 11, 13], "x_log_sigma2": 4, "varianc": [4, 6], "n_dec_1": 4, "n_dec_2": 4, "n_dec_3": 4, "input_dim": 4, "features_dim": 4, "500": 4, "2000": 4, "mnist": [4, 5, 7, 11], "rgb": 4, "format": 4, "y_dim": [4, 6], "img_siz": 4, "loader_tr": [4, 6, 7, 9, 10], "loader_v": [4, 9], "b": [4, 13], "object": [4, 5, 6, 7, 9, 10], "eas": 4, "result": [4, 11], "made": 4, "currect": 4, "dateset": 4, "through": [4, 5], "acquisit": 4, "machin": [4, 5], "applic": 4, "avail": [4, 7], "calcul": [4, 5, 6, 9], "accuraci": [4, 10], "confus": [4, 10, 13], "vec_d": [4, 6], "vec_i": [4, 6], "correl": 4, "her2": [4, 5, 7, 11, 13], "score": [4, 5, 6], "onli": [4, 5, 6, 13], "valiat": 4, "writer": [4, 9], "epoch": [4, 9, 10, 13], "lr": [4, 13], "warmup_beta": [4, 6], "acc_tr": 4, "pretraining_finish": 4, "tensor_x": [4, 6, 9], "inject_tensor": [4, 6, 9], "other_info": 4, "color": [5, 7], "ind_color": 5, "path": [5, 6, 10, 13], "subset_step": 5, "100": [5, 13], "color_schem": 5, "label_transform": 5, "mk_fun_label2onehot": 5, "local": 5, "fun_label2onehot": 5, "list_transform": 5, "raw_split": 5, "flag_rand_color": 5, "fals": [5, 7], "inject_vari": 5, "nomin": 5, "rang": 5, "spectrum": 5, "subdomain": 5, "foreground": 5, "background": 5, "contain": [5, 13], "abstract": 5, "ind": [5, 6], "index": [5, 6], "disk": 5, "storag": 5, "directori": [5, 11, 13], "num": 5, "paint": 5, "accord": 5, "back": 5, "torch": 5, "transform": 5, "default": [5, 7, 10], "part": 5, "flag": 5, "randomli": [5, 9], "depreci": 5, "hot": [5, 6], "vector": [5, 6], "class_num": 5, "d_dim": [5, 6, 13], "metadata_path": 5, "stain": 5, "microscopi": 5, "As": [5, 11], "diagnost": 5, "There": 5, "collect": 5, "site": 5, "integ": [5, 10, 13], "valu": [5, 6, 9, 13], "kept": 5, "note": [5, 6, 11, 13], "actual": 5, "therefor": 5, "ad": [5, 7, 11, 13], "dpath": [5, 13], "name": [5, 7, 13], "inject": [5, 6, 13], "cdvade": [5, 6, 11], "metadata": 5, "csv": [5, 13], "file": [5, 13], "typec": 5, "meta_data_csv": 5, "specifi": [5, 13], "datafram": [5, 13], "load": 5, "9": [5, 7, 13], "subsampl": 5, "fraction": 5, "properti": [5, 7], "sole": 5, "unit": 5, "1x16x16": 5, "random": 5, "path_to_domain": 5, "weah": 5, "root": [5, 13], "previous": 5, "domain_label": [5, 13], "txt": [5, 13], "must": 5, "insid": 5, "keep": 5, "folder": [5, 13], "jpg": 5, "convent": 5, "end": [5, 9], "image_nam": 5, "img_loc": 5, "parser": [5, 14], "get": [5, 7], "per": [5, 6], "cv": 5, "slightli": 5, "graph_method": 5, "topk": 5, "7": [5, 13], "sdcn": [5, 6], "param": [5, 6, 7], "distanc": 5, "between": [5, 6, 10], "heat": 5, "co": 5, "nco": 5, "connect": [5, 6], "sparse_mx": 5, "convert": 5, "scipi": 5, "spars": 5, "funciton": 5, "unbatch": 5, "flatten": 5, "region_label": 5, "region": 5, "mx": 5, "row": 5, "cosin": 5, "shape": [5, 6], "num_img": 5, "pair": 5, "indeci": 5, "top": 5, "self": [5, 6], "n": [5, 6], "connection_pair": 5, "make": 5, "batchsiz": [5, 6], "experiment_fold": 5, "contrain": 5, "patch_dist": 5, "coordin": 5, "patch": 5, "ha": [5, 6, 7, 11, 13], "spacial": 5, "inform": 5, "string": [5, 6, 10, 13], "1carcinoma_coord_39100_39573_patchnumber_98_xy_0_0": 5, "png": 5, "img_id": 5, "oper": 6, "up": 6, "metric": [6, 11, 13], "loader_t": [6, 7, 10], "l": [6, 13], "i_c": 6, "cluster_lay": 6, "horzint": 6, "dim": 6, "vertic": 6, "pred": 6, "One": 6, "inject_domain": 6, "tensorboard": [6, 9], "visual": 6, "dec": [6, 11], "2015": 6, "fulli": 6, "q_": 6, "target": 6, "kullback": 6, "leibler": 6, "diverg": 6, "q": 6, "A": [6, 13], "probabl": 6, "batch_siz": 6, "kl": 6, "warm": 6, "beta": 6, "float": 6, "gamma_i": [6, 13], "dim_feat_x": 6, "list_str_d": 6, "amodelclassif": 6, "let": 6, "zd": 6, "continu": 6, "compon": [6, 11], "repres": 6, "attent": 6, "weight": [6, 9], "For": [6, 11, 13], "bigger": 6, "zd_k": 6, "more": 6, "like": [6, 9], "posterior": 6, "feat": 6, "z_d": 6, "fixm": 6, "chang": 6, "style": 6, "extract": 6, "textur": 6, "better": [6, 7], "v": [6, 10], "auxiliari": 6, "regular": 6, "p": 6, "auxilliari": 6, "m2": 6, "drage": 6, "zero": [6, 7], "aux_i": 6, "logit": 6, "softmax": 6, "vec_one_hot": 6, "prob": 6, "int": 6, "confid": 6, "maximum": [6, 10], "alreadi": 6, "na_class": 6, "compos": 6, "16": 6, "p_i": 6, "sum_j": 6, "q_j": 6, "12": 6, "concentr": 6, "two": [6, 10], "15": 6, "warmup": 6, "coeffici": 6, "term": 6, "vade": [6, 11], "trainer_vad": 6, "log_sigma": 6, "sgvb": 6, "estim": [6, 9], "reparametr": 6, "trick": 6, "papaer": 6, "mont": 6, "carlo": 6, "mu": 6, "log_sigma2": 6, "helper": 6, "static": 6, "subhelp": 6, "just": [6, 7], "gausian": 6, "pdf": 6, "basi": 6, "distribt": 6, "succ": 7, "nodetaskdictclassif": 7, "place": 7, "inherit": 7, "further": [7, 9, 11], "categori": 7, "consid": 7, "so": [7, 11], "dummi": 7, "now": 7, "compat": 7, "domainlab": 7, "type": 7, "na_domain": 7, "split": [7, 13], "true": [7, 9], "whether": [7, 9], "portion": 7, "determin": 7, "python": [7, 11, 13], "evalu": [7, 11], "statement": 7, "case": 7, "separ": 7, "creat": 7, "otherwis": 7, "percentag": 7, "rest": 7, "basic": [7, 11, 13], "regard": 7, "deafult": 7, "dictionari": 7, "getter": 7, "than": 7, "new": [7, 11, 13], "ratio": 7, "usp": 7, "annot": 7, "hardcod": 7, "chain": [7, 13], "select": 7, "node": 7, "loader": [9, 10], "pre": 9, "pi": [9, 13], "mu_c": 9, "log_sigma2_c": 9, "gmm": 9, "after": [9, 10], "updat": 9, "backpropag": 9, "aconf": 9, "abstracttrain": 9, "notifi": 9, "mse": 9, "configur": 9, "rate": 9, "threshold": 9, "check": 9, "num_class": 10, "perfclassif": 10, "classmethod": 10, "cluster_pred_scalar": 10, "cluster_true_scalar": 10, "cost": 10, "arrai": 10, "ani": 10, "element": 10, "appli": 10, "hungarian": 10, "find": 10, "max_batch": 10, "compar": 10, "against": 10, "respect": [10, 11, 13], "matric": [10, 13], "overal": 10, "match": [10, 13], "final": [10, 13], "gpu": 10, "iter": 10, "less": 10, "burden": 10, "travers": 10, "acc_tr_i": 10, "acc_tr_d": 10, "loss_tr": 10, "acc_val_i": 10, "acc_val_d": 10, "loss_val": 10, "r_score_tr": 10, "r_score_t": 10, "vec_y_label": 10, "vec_d_label": 10, "image_id_label": 10, "goal": 11, "provid": 11, "pytorch": 11, "platform": 11, "futur": [11, 13], "additioon": 11, "see": [11, 13], "section": 11, "usag": 11, "exampl": [11, 13], "introduct": 11, "submodul": [11, 12], "been": [11, 13], "develop": [11, 13], "aim": 11, "invari": 11, "multipl": 11, "unseen": 11, "code": [11, 13], "custom": 11, "entail": 11, "could": [11, 13], "found": [11, 13], "detail": 11, "serv": 11, "build": 11, "block": 11, "import": 11, "pleas": 11, "refer": 11, "thei": 11, "modul": [11, 12], "content": [11, 12], "divid": 11, "three": 11, "builder": 11, "go": 11, "experi": 11, "respons": 11, "focus": 11, "itself": 11, "save": 11, "bel0ow": 11, "some": 11, "subpackag": 12, "arg_pars": 12, "prerequisit": 13, "poetri": 13, "depend": 13, "manag": 13, "variou": 13, "workflow": 13, "doc": 13, "without": 13, "possibl": 13, "requir": 13, "clone": 13, "repositori": 13, "git": [13, 14], "github": [13, 14], "agisga": 13, "publish": 13, "pypi": 13, "easi": 13, "pip": 13, "examl": 13, "200": 13, "main_out": 13, "py": [13, 14], "te_d": 13, "tr_d": 13, "epo": 13, "anam": 13, "apath": 13, "8": 13, "pre_tr": 13, "00005": 13, "assess": 13, "14428806": 13, "22498095": 13, "1877629": 13, "24480581": 13, "19816224": 13, "pool": 13, "acc": 13, "7213934426229508": 13, "3407": 13, "13": 13, "5203": 13, "31": 13, "61": 13, "20": 13, "18": 13, "104": 13, "1243": 13, "1293": 13, "1266": 13, "24": 13, "3204": 13, "3299": 13, "178": 13, "34": 13, "46": 13, "265": 13, "230": 13, "4450": 13, "7236065573770492": 13, "848": 13, "1305": 13, "26": 13, "340": 13, "311": 13, "316": 13, "816": 13, "813": 13, "44": 13, "53": 13, "51": 13, "1108": 13, "mnistcolor10": 13, "debug": 13, "50": 13, "09958664": 13, "09956316": 13, "09337884": 13, "0995345": 13, "04938212": 13, "09954792": 13, "2096352": 13, "09956467": 13, "09960268": 13, "05020422": 13, "7561666666666667": 13, "600": 13, "262": 13, "599": 13, "338": 13, "7568333333333334": 13, "259": 13, "341": 13, "describ": 13, "mnist10": 13, "your": 13, "own": 13, "xxxx": 13, "follow": 13, "would": 13, "30": 13, "250": 13, "combined_train": 13, "prio": 13, "gau": 13, "column": 13, "image_id": 13, "option": 13, "present": 13, "same": 13, "zd_path": 13, "If": 13, "different": 13, "csv_file": 13, "diment": 13, "inject_var": 13, "dim_inject_i": 13, "uniqu": 13, "automat": 13, "manual": 13, "0001": 13, "nocu": 13, "pre_tr_weight_path": 13, "pretrained_weight": 13, "toi": 13, "dl": 13, "here": 13, "linkifi": 14, "m2r2": 14, "myst": 14, "rinohtyp": 14, "nbsphinx": 14, "nbsphinx_link": 14, "sphinx_materi": 14, "commonmark": 14, "rtfd": 14}, "objects": {"": [[2, 0, 0, "-", "domid"]], "domid": [[3, 0, 0, "-", "algos"], [2, 0, 0, "-", "arg_parser"], [4, 0, 0, "-", "compos"], [5, 0, 0, "-", "dsets"], [6, 0, 0, "-", "models"], [7, 0, 0, "-", "tasks"], [8, 0, 0, "-", "tests"], [9, 0, 0, "-", "trainers"], [10, 0, 0, "-", "utils"]], "domid.algos": [[3, 0, 0, "-", "builder_ae"], [3, 0, 0, "-", "builder_dec"], [3, 0, 0, "-", "builder_m2yd"], [3, 0, 0, "-", "builder_sdcn"], [3, 0, 0, "-", "builder_vade"]], "domid.algos.builder_ae": [[3, 1, 1, "", "NodeAlgoBuilderAE"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_ae.NodeAlgoBuilderAE": [[3, 2, 1, "", "init_business"]], "domid.algos.builder_dec": [[3, 1, 1, "", "NodeAlgoBuilderDEC"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_dec.NodeAlgoBuilderDEC": [[3, 2, 1, "", "init_business"]], "domid.algos.builder_m2yd": [[3, 1, 1, "", "NodeAlgoBuilderM2YD"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_m2yd.NodeAlgoBuilderM2YD": [[3, 2, 1, "", "init_business"]], "domid.algos.builder_sdcn": [[3, 1, 1, "", "NodeAlgoBuilderSDCN"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_sdcn.NodeAlgoBuilderSDCN": [[3, 2, 1, "", "init_business"]], "domid.algos.builder_vade": [[3, 1, 1, "", "NodeAlgoBuilderVaDE"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_vade.NodeAlgoBuilderVaDE": [[3, 2, 1, "", "init_business"]], "domid.arg_parser": [[2, 3, 1, "", "mk_parser_main"], [2, 3, 1, "", "parse_cmd_args"]], "domid.compos": [[4, 0, 0, "-", "DEC_clustering_layer"], [4, 0, 0, "-", "GNN"], [4, 0, 0, "-", "GNN_layer"], [4, 0, 0, "-", "VAE_blocks"], [4, 0, 0, "-", "cnn_AE"], [4, 0, 0, "-", "cnn_VAE"], [4, 0, 0, "-", "linear_AE"], [4, 0, 0, "-", "linear_VAE"], [4, 0, 0, "-", "nn_net"], [4, 0, 0, "-", "predict_basic"], [4, 0, 0, "-", "tensorboard_fun"]], "domid.compos.DEC_clustering_layer": [[4, 1, 1, "", "DECClusteringLayer"]], "domid.compos.DEC_clustering_layer.DECClusteringLayer": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.GNN": [[4, 1, 1, "", "GNN"]], "domid.compos.GNN.GNN": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.GNN_layer": [[4, 1, 1, "", "GNNLayer"]], "domid.compos.GNN_layer.GNNLayer": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.VAE_blocks": [[4, 1, 1, "", "UnFlatten"], [4, 3, 1, "", "cnn_decoding_block"], [4, 3, 1, "", "cnn_encoding_block"], [4, 3, 1, "", "get_output_shape"], [4, 3, 1, "", "linear_block"]], "domid.compos.VAE_blocks.UnFlatten": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.cnn_AE": [[4, 1, 1, "", "ConvolutionalDecoder"], [4, 1, 1, "", "ConvolutionalEncoder"]], "domid.compos.cnn_AE.ConvolutionalDecoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.cnn_AE.ConvolutionalEncoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.cnn_VAE": [[4, 1, 1, "", "ConvolutionalDecoder"], [4, 1, 1, "", "ConvolutionalEncoder"]], "domid.compos.cnn_VAE.ConvolutionalDecoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.cnn_VAE.ConvolutionalEncoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.linear_AE": [[4, 1, 1, "", "LinearDecoderAE"], [4, 1, 1, "", "LinearEncoderAE"]], "domid.compos.linear_AE.LinearDecoderAE": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.linear_AE.LinearEncoderAE": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.linear_VAE": [[4, 1, 1, "", "LinearDecoder"], [4, 1, 1, "", "LinearEncoder"]], "domid.compos.linear_VAE.LinearDecoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.linear_VAE.LinearEncoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.nn_net": [[4, 1, 1, "", "Net_MNIST"], [4, 3, 1, "", "test_Net_MNIST"]], "domid.compos.nn_net.Net_MNIST": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "conv_op"], [4, 2, 1, "", "forward"], [4, 2, 1, "", "probe"]], "domid.compos.predict_basic": [[4, 1, 1, "", "Prediction"]], "domid.compos.predict_basic.Prediction": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "epoch_tr_acc"], [4, 2, 1, "", "epoch_tr_correlation"], [4, 2, 1, "", "epoch_val_acc"], [4, 2, 1, "", "epoch_val_correlation"], [4, 2, 1, "", "mk_prediction"]], "domid.compos.tensorboard_fun": [[4, 3, 1, "", "tensorboard_write"]], "domid.dsets": [[5, 0, 0, "-", "a_dset_mnist_color_rgb_solo"], [5, 0, 0, "-", "dset_her2"], [5, 0, 0, "-", "dset_mnist"], [5, 0, 0, "-", "dset_mnist_color_solo_default"], [5, 0, 0, "-", "dset_unittest"], [5, 0, 0, "-", "dset_usps"], [5, 0, 0, "-", "dset_wsi"], [5, 0, 0, "-", "generate_dataset_dataframe_her2"], [5, 0, 0, "-", "make_graph"], [5, 0, 0, "-", "make_graph_wsi"]], "domid.dsets.a_dset_mnist_color_rgb_solo": [[5, 1, 1, "", "ADsetMNISTColorRGBSolo"]], "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "generate_dataframe"], [5, 2, 1, "", "get_background_color"], [5, 2, 1, "", "get_foreground_color"], [5, 2, 1, "", "get_num_colors"]], "domid.dsets.dset_her2": [[5, 1, 1, "", "DsetHER2"]], "domid.dsets.dset_her2.DsetHER2": [[5, 2, 1, "", "__init__"]], "domid.dsets.dset_mnist": [[5, 1, 1, "", "DsetMNIST"]], "domid.dsets.dset_mnist.DsetMNIST": [[5, 2, 1, "", "__init__"]], "domid.dsets.dset_mnist_color_solo_default": [[5, 1, 1, "", "DsetMNISTColorSoloDefault"]], "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault": [[5, 2, 1, "", "get_background_color"], [5, 2, 1, "", "get_foreground_color"], [5, 2, 1, "", "get_num_colors"], [5, 4, 1, "", "palette"]], "domid.dsets.dset_unittest": [[5, 1, 1, "", "DsetUnitTest"]], "domid.dsets.dset_unittest.DsetUnitTest": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "create_the_dataset"]], "domid.dsets.dset_usps": [[5, 1, 1, "", "DsetUSPS"]], "domid.dsets.dset_usps.DsetUSPS": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "get_original_indicies"]], "domid.dsets.dset_wsi": [[5, 1, 1, "", "DsetWSI"]], "domid.dsets.dset_wsi.DsetWSI": [[5, 2, 1, "", "__init__"]], "domid.dsets.generate_dataset_dataframe_her2": [[5, 3, 1, "", "get_jpg_folders"], [5, 3, 1, "", "mean_scores_per_experiment"], [5, 3, 1, "", "parse_machine_labels"], [5, 3, 1, "", "total_count_images"]], "domid.dsets.make_graph": [[5, 1, 1, "", "GraphConstructor"]], "domid.dsets.make_graph.GraphConstructor": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "connection_calc"], [5, 2, 1, "", "construct_graph"], [5, 2, 1, "", "distance_calc"], [5, 2, 1, "", "get_features_labels"], [5, 2, 1, "", "mk_adj_mat"], [5, 2, 1, "", "normalize"], [5, 2, 1, "", "sparse_mx_to_torch_sparse_tensor"]], "domid.dsets.make_graph_wsi": [[5, 1, 1, "", "GraphConstructorWSI"]], "domid.dsets.make_graph_wsi.GraphConstructorWSI": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "connection_calc"], [5, 2, 1, "", "construct_graph"], [5, 2, 1, "", "distance_calc_wsi"]], "domid.models": [[6, 0, 0, "-", "a_model_cluster"], [6, 0, 0, "-", "model_ae"], [6, 0, 0, "-", "model_dec"], [6, 0, 0, "-", "model_m2yd"], [6, 0, 0, "-", "model_sdcn"], [6, 0, 0, "-", "model_vade"]], "domid.models.a_model_cluster": [[6, 1, 1, "", "AModelCluster"]], "domid.models.a_model_cluster.AModelCluster": [[6, 2, 1, "", "cal_perf_metric"], [6, 2, 1, "", "create_perf_obj"]], "domid.models.model_ae": [[6, 1, 1, "", "ModelAE"], [6, 3, 1, "", "test_fun"]], "domid.models.model_ae.ModelAE": [[6, 2, 1, "", "__init__"], [6, 2, 1, "", "cal_loss"], [6, 2, 1, "", "distance_between_clusters"], [6, 2, 1, "", "infer_d_v"], [6, 2, 1, "", "infer_d_v_2"], [6, 2, 1, "", "pretrain_loss"]], "domid.models.model_dec": [[6, 1, 1, "", "ModelDEC"]], "domid.models.model_dec.ModelDEC": [[6, 2, 1, "", "__init__"], [6, 2, 1, "", "cal_loss"], [6, 2, 1, "", "infer_d_v"], [6, 2, 1, "", "infer_d_v_2"], [6, 2, 1, "", "pretrain_loss"], [6, 2, 1, "", "target_distribution"]], "domid.models.model_m2yd": [[6, 1, 1, "", "ModelXY2D"], [6, 3, 1, "", "test_fun"]], "domid.models.model_m2yd.ModelXY2D": [[6, 2, 1, "", "__init__"], [6, 2, 1, "", "cal_logit_y"], [6, 2, 1, "", "cal_loss"], [6, 2, 1, "", "forward"], [6, 2, 1, "", "infer_d_v"], [6, 2, 1, "", "infer_y_vpicn"]], "domid.models.model_sdcn": [[6, 1, 1, "", "ModelSDCN"]], "domid.models.model_sdcn.ModelSDCN": [[6, 2, 1, "", "__init__"], [6, 2, 1, "", "cal_loss"], [6, 2, 1, "", "cal_loss_for_tensorboard"], [6, 2, 1, "", "infer_d_v"], [6, 2, 1, "", "infer_d_v_2"], [6, 2, 1, "", "pretrain_loss"], [6, 2, 1, "", "target_distribution"]], "domid.models.model_vade": [[6, 1, 1, "", "ModelVaDE"], [6, 3, 1, "", "test_fun"]], "domid.models.model_vade.ModelVaDE": [[6, 2, 1, "", "ELBO_Loss"], [6, 2, 1, "", "__init__"], [6, 2, 1, "", "cal_loss"], [6, 2, 1, "", "gaussian_pdf_log"], [6, 2, 1, "", "gaussian_pdfs_log"], [6, 2, 1, "", "infer_d_v"], [6, 2, 1, "", "infer_d_v_2"], [6, 2, 1, "", "pretrain_loss"], [6, 2, 1, "", "reconstruction_loss"]], "domid.tasks": [[7, 0, 0, "-", "b_task_cluster"], [7, 0, 0, "-", "task_her2"], [7, 0, 0, "-", "task_mnist"], [7, 0, 0, "-", "task_mnist_color"], [7, 0, 0, "-", "task_unittest"], [7, 0, 0, "-", "task_usps"], [7, 0, 0, "-", "task_wsi"], [7, 0, 0, "-", "zoo_tasks"]], "domid.tasks.b_task_cluster": [[7, 1, 1, "", "NodeTaskDictCluster"]], "domid.tasks.task_her2": [[7, 1, 1, "", "NodeTaskHER2"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_her2.NodeTaskHER2": [[7, 2, 1, "", "calc_corr"], [7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_mnist": [[7, 1, 1, "", "NodeTaskMNIST"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_mnist.NodeTaskMNIST": [[7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_mnist_color": [[7, 1, 1, "", "NodeTaskMNISTColor10"]], "domid.tasks.task_mnist_color.NodeTaskMNISTColor10": [[7, 4, 1, "", "dim_y"], [7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 2, 1, "", "init_business"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_unittest": [[7, 1, 1, "", "NodeTaskUnitTest"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_unittest.NodeTaskUnitTest": [[7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_usps": [[7, 1, 1, "", "NodeTaskUSPS"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_usps.NodeTaskUSPS": [[7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_wsi": [[7, 1, 1, "", "NodeTaskWSI"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_wsi.NodeTaskWSI": [[7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.zoo_tasks": [[7, 1, 1, "", "TaskChainNodeGetter"]], "domid.tasks.zoo_tasks.TaskChainNodeGetter": [[7, 2, 1, "", "__init__"]], "domid.tests": [[8, 0, 0, "-", "test_domid"], [8, 0, 0, "-", "test_graph"], [8, 0, 0, "-", "test_losses"], [8, 0, 0, "-", "test_mnist_dataset"], [8, 0, 0, "-", "test_model_builder"], [8, 0, 0, "-", "test_model_trainer"]], "domid.tests.test_domid": [[8, 3, 1, "", "test_version"]], "domid.tests.test_graph": [[8, 3, 1, "", "graph_constructor"], [8, 3, 1, "", "test_MNISTcolor_SDCN_graph_construction_heat"], [8, 3, 1, "", "test_MNISTcolor_SDCN_graph_construction_ncos"]], "domid.tests.test_losses": [[8, 3, 1, "", "experiment_train"], [8, 3, 1, "", "test_VADE"], [8, 3, 1, "", "test_VADE_CNN"], [8, 3, 1, "", "test_VADE_CNN_nonbinary"], [8, 3, 1, "", "test_VADE_nonbinary"]], "domid.tests.test_mnist_dataset": [[8, 3, 1, "", "node_compiler"], [8, 3, 1, "", "test_mnist_length"], [8, 3, 1, "", "test_mnistcolor10_length"]], "domid.tests.test_model_builder": [[8, 3, 1, "", "model_compiler"], [8, 3, 1, "", "test_VaDE_CNN"], [8, 3, 1, "", "test_VaDE_linear"], [8, 3, 1, "", "test_m2yd"]], "domid.tests.test_model_trainer": [[8, 3, 1, "", "experiment_train"], [8, 3, 1, "", "test_M2YD_train_MNISTcolor"], [8, 3, 1, "", "test_MNIST_conditionalOne_train"], [8, 3, 1, "", "test_MNIST_pretrain"], [8, 3, 1, "", "test_MNIST_train"], [8, 3, 1, "", "test_MNIST_train_CNN"], [8, 3, 1, "", "test_MNISTcolor_AE"], [8, 3, 1, "", "test_MNISTcolor_SDCN"], [8, 3, 1, "", "test_MNISTcolor_pretrain_CNN"], [8, 3, 1, "", "test_MNISTcolor_train"], [8, 3, 1, "", "test_MNISTcolor_train_CNN"]], "domid.trainers": [[9, 0, 0, "-", "pretraining_GMM"], [9, 0, 0, "-", "pretraining_KMeans"], [9, 0, 0, "-", "pretraining_sdcn"], [9, 0, 0, "-", "trainer_ae"], [9, 0, 0, "-", "trainer_cluster"], [9, 0, 0, "-", "trainer_sdcn"]], "domid.trainers.pretraining_GMM": [[9, 1, 1, "", "Pretraining"]], "domid.trainers.pretraining_GMM.Pretraining": [[9, 2, 1, "", "GMM_fit"], [9, 2, 1, "", "__init__"], [9, 2, 1, "", "pretrain_loss"]], "domid.trainers.pretraining_KMeans": [[9, 1, 1, "", "Pretraining"]], "domid.trainers.pretraining_KMeans.Pretraining": [[9, 2, 1, "", "__init__"], [9, 2, 1, "", "model_fit"], [9, 2, 1, "", "pretrain_loss"]], "domid.trainers.pretraining_sdcn": [[9, 1, 1, "", "PretrainingSDCN"]], "domid.trainers.pretraining_sdcn.PretrainingSDCN": [[9, 2, 1, "", "__init__"], [9, 2, 1, "", "kmeans_cluster_assignement"], [9, 2, 1, "", "model_fit"], [9, 2, 1, "", "pretrain_loss"]], "domid.trainers.trainer_ae": [[9, 1, 1, "", "TrainerCluster"]], "domid.trainers.trainer_ae.TrainerCluster": [[9, 2, 1, "", "__init__"], [9, 2, 1, "", "before_tr"], [9, 2, 1, "", "post_tr"], [9, 2, 1, "", "tr_epoch"]], "domid.trainers.trainer_cluster": [[9, 1, 1, "", "TrainerCluster"]], "domid.trainers.trainer_cluster.TrainerCluster": [[9, 2, 1, "", "__init__"], [9, 2, 1, "", "before_tr"], [9, 2, 1, "", "post_tr"], [9, 2, 1, "", "tr_epoch"]], "domid.trainers.trainer_sdcn": [[9, 1, 1, "", "TrainerCluster"]], "domid.trainers.trainer_sdcn.TrainerCluster": [[9, 2, 1, "", "__init__"], [9, 2, 1, "", "before_tr"], [9, 2, 1, "", "post_tr"], [9, 2, 1, "", "tr_epoch"]], "domid.utils": [[10, 0, 0, "-", "mean_std"], [10, 0, 0, "-", "perf_cluster"], [10, 0, 0, "-", "perf_similarity"], [10, 0, 0, "-", "storing"]], "domid.utils.mean_std": [[10, 3, 1, "", "run"], [10, 3, 1, "", "run2"]], "domid.utils.perf_cluster": [[10, 1, 1, "", "PerfCluster"]], "domid.utils.perf_cluster.PerfCluster": [[10, 2, 1, "", "__init__"], [10, 2, 1, "", "cal_acc"], [10, 2, 1, "", "hungarian_algorithm"]], "domid.utils.perf_similarity": [[10, 1, 1, "", "PerfCorrelationHER2"]], "domid.utils.perf_similarity.PerfCorrelationHER2": [[10, 2, 1, "", "__init__"], [10, 2, 1, "", "cal_acc"]], "domid.utils.storing": [[10, 1, 1, "", "Storing"]], "domid.utils.storing.Storing": [[10, 2, 1, "", "__init__"], [10, 2, 1, "", "csv_dump"], [10, 2, 1, "", "saving_model"], [10, 2, 1, "", "storing"], [10, 2, 1, "", "storing_z_space"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:method", "3": "py:function", "4": "py:property"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "method", "Python method"], "3": ["py", "function", "Python function"], "4": ["py", "property", "Python property"]}, "titleterms": {"vade": [0, 1, 13], "model": [0, 1, 6, 11, 13], "summari": [0, 1], "cdvade": [0, 1, 13], "dec": [0, 1, 13], "sdcn": [0, 1, 13], "m2yd": [0, 1, 13], "refer": [0, 1, 13], "about": [1, 11], "domid": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], "packag": [2, 3, 4, 5, 6, 7, 8, 9, 10], "subpackag": 2, "submodul": [2, 3, 4, 5, 6, 7, 8, 9, 10], "arg_pars": 2, "modul": [2, 3, 4, 5, 6, 7, 8, 9, 10], "content": [2, 3, 4, 5, 6, 7, 8, 9, 10], "algo": 3, "builder_a": 3, "builder_dec": 3, "builder_m2yd": 3, "builder_sdcn": 3, "builder_vad": 3, "compo": 4, "dec_clustering_lay": 4, "gnn": 4, "gnn_layer": 4, "vae_block": 4, "cnn_ae": 4, "cnn_vae": 4, "linear_a": 4, "linear_va": 4, "nn_net": 4, "predict_bas": 4, "tensorboard_fun": 4, "dset": 5, "a_dset_mnist_color_rgb_solo": 5, "dset_her2": 5, "dset_mnist": 5, "dset_mnist_color_solo_default": 5, "dset_unittest": 5, "dset_usp": 5, "dset_wsi": 5, "generate_dataset_dataframe_her2": 5, "make_graph": 5, "make_graph_wsi": 5, "a_model_clust": 6, "model_a": 6, "model_dec": 6, "model_m2yd": 6, "model_sdcn": 6, "model_vad": 6, "task": [7, 11], "b_task_clust": 7, "task_her2": 7, "task_mnist": 7, "task_mnist_color": 7, "task_unittest": 7, "task_usp": 7, "task_wsi": 7, "zoo_task": 7, "test": 8, "test_domid": 8, "test_graph": 8, "test_loss": 8, "test_mnist_dataset": 8, "test_model_build": 8, "test_model_train": 8, "trainer": 9, "pretraining_gmm": 9, "pretraining_kmean": 9, "pretraining_sdcn": 9, "trainer_a": 9, "trainer_clust": 9, "trainer_sdcn": 9, "util": [10, 11], "mean_std": 10, "perf_clust": 10, "perf_similar": 10, "store": 10, "welcom": 11, "": 11, "document": 11, "more": 11, "inform": 11, "domainlab": 11, "load": 11, "dataset": [11, 13], "defin": 11, "composit": 11, "train": [11, 13], "ulitili": 11, "introduct": 13, "domain": 13, "identif": 13, "instal": 13, "usag": 13, "appli": 13, "mnist": 13, "color": 13, "custom": 13, "cvade": 13, "modifi": 13, "wsi": 13, "data": 13, "simultan": 13, "unsupervis": 13, "cluster": 13, "supervis": 13, "classif": 13, "recommonmark": 14, "0": 14, "5": 14, "dev0": 14}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx.ext.intersphinx": 1, "sphinx.ext.todo": 2, "nbsphinx": 4, "sphinx": 57}, "alltitles": {"VaDE Model Summary": [[0, "vade-model-summary"], [1, "vade-model-summary"]], "CDVaDE Model Summary": [[0, "cdvade-model-summary"], [1, "cdvade-model-summary"]], "DEC Model Summary": [[0, "dec-model-summary"], [1, "dec-model-summary"]], "SDCN Model Summary": [[0, "sdcn-model-summary"], [1, "sdcn-model-summary"]], "M2YD Model Summary": [[0, "m2yd-model-summary"], [1, "m2yd-model-summary"]], "References": [[0, "references"], [1, "references"], [13, "references"]], "About DomId": [[1, "about-domid"], [11, "about-domid"]], "domid package": [[2, "domid-package"]], "Subpackages": [[2, "subpackages"]], "Submodules": [[2, "submodules"], [3, "submodules"], [4, "submodules"], [5, "submodules"], [6, "submodules"], [7, "submodules"], [8, "submodules"], [9, "submodules"], [10, "submodules"]], "domid.arg_parser module": [[2, "module-domid.arg_parser"]], "Module contents": [[2, "module-domid"], [3, "module-domid.algos"], [4, "module-domid.compos"], [5, "module-domid.dsets"], [6, "module-domid.models"], [7, "module-domid.tasks"], [8, "module-domid.tests"], [9, "module-domid.trainers"], [10, "module-domid.utils"]], "domid.algos package": [[3, "domid-algos-package"]], "domid.algos.builder_ae module": [[3, "module-domid.algos.builder_ae"]], "domid.algos.builder_dec module": [[3, "module-domid.algos.builder_dec"]], "domid.algos.builder_m2yd module": [[3, "module-domid.algos.builder_m2yd"]], "domid.algos.builder_sdcn module": [[3, "module-domid.algos.builder_sdcn"]], "domid.algos.builder_vade module": [[3, "module-domid.algos.builder_vade"]], "domid.compos package": [[4, "domid-compos-package"]], "domid.compos.DEC_clustering_layer module": [[4, "module-domid.compos.DEC_clustering_layer"]], "domid.compos.GNN module": [[4, "module-domid.compos.GNN"]], "domid.compos.GNN_layer module": [[4, "module-domid.compos.GNN_layer"]], "domid.compos.VAE_blocks module": [[4, "module-domid.compos.VAE_blocks"]], "domid.compos.cnn_AE module": [[4, "module-domid.compos.cnn_AE"]], "domid.compos.cnn_VAE module": [[4, "module-domid.compos.cnn_VAE"]], "domid.compos.linear_AE module": [[4, "module-domid.compos.linear_AE"]], "domid.compos.linear_VAE module": [[4, "module-domid.compos.linear_VAE"]], "domid.compos.nn_net module": [[4, "module-domid.compos.nn_net"]], "domid.compos.predict_basic module": [[4, "module-domid.compos.predict_basic"]], "domid.compos.tensorboard_fun module": [[4, "module-domid.compos.tensorboard_fun"]], "domid.dsets package": [[5, "domid-dsets-package"]], "domid.dsets.a_dset_mnist_color_rgb_solo module": [[5, "module-domid.dsets.a_dset_mnist_color_rgb_solo"]], "domid.dsets.dset_her2 module": [[5, "module-domid.dsets.dset_her2"]], "domid.dsets.dset_mnist module": [[5, "module-domid.dsets.dset_mnist"]], "domid.dsets.dset_mnist_color_solo_default module": [[5, "module-domid.dsets.dset_mnist_color_solo_default"]], "domid.dsets.dset_unittest module": [[5, "module-domid.dsets.dset_unittest"]], "domid.dsets.dset_usps module": [[5, "module-domid.dsets.dset_usps"]], "domid.dsets.dset_wsi module": [[5, "module-domid.dsets.dset_wsi"]], "domid.dsets.generate_dataset_dataframe_her2 module": [[5, "module-domid.dsets.generate_dataset_dataframe_her2"]], "domid.dsets.make_graph module": [[5, "module-domid.dsets.make_graph"]], "domid.dsets.make_graph_wsi module": [[5, "module-domid.dsets.make_graph_wsi"]], "domid.models package": [[6, "domid-models-package"]], "domid.models.a_model_cluster module": [[6, "module-domid.models.a_model_cluster"]], "domid.models.model_ae module": [[6, "module-domid.models.model_ae"]], "domid.models.model_dec module": [[6, "module-domid.models.model_dec"]], "domid.models.model_m2yd module": [[6, "module-domid.models.model_m2yd"]], "domid.models.model_sdcn module": [[6, "module-domid.models.model_sdcn"]], "domid.models.model_vade module": [[6, "module-domid.models.model_vade"]], "domid.tasks package": [[7, "domid-tasks-package"]], "domid.tasks.b_task_cluster module": [[7, "module-domid.tasks.b_task_cluster"]], "domid.tasks.task_her2 module": [[7, "module-domid.tasks.task_her2"]], "domid.tasks.task_mnist module": [[7, "module-domid.tasks.task_mnist"]], "domid.tasks.task_mnist_color module": [[7, "module-domid.tasks.task_mnist_color"]], "domid.tasks.task_unittest module": [[7, "module-domid.tasks.task_unittest"]], "domid.tasks.task_usps module": [[7, "module-domid.tasks.task_usps"]], "domid.tasks.task_wsi module": [[7, "module-domid.tasks.task_wsi"]], "domid.tasks.zoo_tasks module": [[7, "module-domid.tasks.zoo_tasks"]], "domid.tests package": [[8, "domid-tests-package"]], "domid.tests.test_domid module": [[8, "module-domid.tests.test_domid"]], "domid.tests.test_graph module": [[8, "module-domid.tests.test_graph"]], "domid.tests.test_losses module": [[8, "module-domid.tests.test_losses"]], "domid.tests.test_mnist_dataset module": [[8, "module-domid.tests.test_mnist_dataset"]], "domid.tests.test_model_builder module": [[8, "module-domid.tests.test_model_builder"]], "domid.tests.test_model_trainer module": [[8, "module-domid.tests.test_model_trainer"]], "domid.trainers package": [[9, "domid-trainers-package"]], "domid.trainers.pretraining_GMM module": [[9, "module-domid.trainers.pretraining_GMM"]], "domid.trainers.pretraining_KMeans module": [[9, "module-domid.trainers.pretraining_KMeans"]], "domid.trainers.pretraining_sdcn module": [[9, "module-domid.trainers.pretraining_sdcn"]], "domid.trainers.trainer_ae module": [[9, "module-domid.trainers.trainer_ae"]], "domid.trainers.trainer_cluster module": [[9, "module-domid.trainers.trainer_cluster"]], "domid.trainers.trainer_sdcn module": [[9, "module-domid.trainers.trainer_sdcn"]], "domid.utils package": [[10, "domid-utils-package"]], "domid.utils.mean_std module": [[10, "module-domid.utils.mean_std"]], "domid.utils.perf_cluster module": [[10, "module-domid.utils.perf_cluster"]], "domid.utils.perf_similarity module": [[10, "module-domid.utils.perf_similarity"]], "domid.utils.storing module": [[10, "module-domid.utils.storing"]], "Welcome to DomId\u2019s documentation!": [[11, "welcome-to-domid-s-documentation"]], "More information about the models": [[11, null]], "DomainLab": [[11, "domainlab"]], "Loading a Datasets and Defining a Task": [[11, "loading-a-datasets-and-defining-a-task"]], "Datasets and Tasks": [[11, null]], "Composition and Defining a Model": [[11, "composition-and-defining-a-model"]], "Models": [[11, null]], "Training a Model": [[11, "training-a-model"], [11, null]], "Ulitilies": [[11, "ulitilies"]], "Utilities": [[11, null]], "domid": [[12, "domid"]], "Introduction": [[13, "introduction"]], "Domain Identification (DomId)": [[13, "domain-identification-domid"]], "Installation": [[13, "installation"]], "Usage": [[13, "usage"]], "VaDE model": [[13, "vade-model"]], "Applying VaDE to MNIST": [[13, "applying-vade-to-mnist"]], "Applying VaDE to Color-MNIST": [[13, "applying-vade-to-color-mnist"]], "DEC model": [[13, "dec-model"]], "Custom datasets": [[13, "custom-datasets"]], "CDVaDE model": [[13, "cdvade-model"]], "Training CVaDE:": [[13, "training-cvade"]], "SDCN, and modified SDCN for WSI data": [[13, "sdcn-and-modified-sdcn-for-wsi-data"]], "Simultaneous unsupervised clustering and supervised classification": [[13, "simultaneous-unsupervised-clustering-and-supervised-classification"]], "M2YD model": [[13, "m2yd-model"]], "recommonmark==0.5.0.dev0": [[14, "recommonmark-0-5-0-dev0"]]}, "indexentries": {"domid": [[2, "module-domid"]], "domid.arg_parser": [[2, "module-domid.arg_parser"]], "mk_parser_main() (in module domid.arg_parser)": [[2, "domid.arg_parser.mk_parser_main"]], "module": [[2, "module-domid"], [2, "module-domid.arg_parser"], [3, "module-domid.algos"], [3, "module-domid.algos.builder_ae"], [3, "module-domid.algos.builder_dec"], [3, "module-domid.algos.builder_m2yd"], [3, "module-domid.algos.builder_sdcn"], [3, "module-domid.algos.builder_vade"], [4, "module-domid.compos"], [4, "module-domid.compos.DEC_clustering_layer"], [4, "module-domid.compos.GNN"], [4, "module-domid.compos.GNN_layer"], [4, "module-domid.compos.VAE_blocks"], [4, "module-domid.compos.cnn_AE"], [4, "module-domid.compos.cnn_VAE"], [4, "module-domid.compos.linear_AE"], [4, "module-domid.compos.linear_VAE"], [4, "module-domid.compos.nn_net"], [4, "module-domid.compos.predict_basic"], [4, "module-domid.compos.tensorboard_fun"], [5, "module-domid.dsets"], [5, "module-domid.dsets.a_dset_mnist_color_rgb_solo"], [5, "module-domid.dsets.dset_her2"], [5, "module-domid.dsets.dset_mnist"], [5, "module-domid.dsets.dset_mnist_color_solo_default"], [5, "module-domid.dsets.dset_unittest"], [5, "module-domid.dsets.dset_usps"], [5, "module-domid.dsets.dset_wsi"], [5, "module-domid.dsets.generate_dataset_dataframe_her2"], [5, "module-domid.dsets.make_graph"], [5, "module-domid.dsets.make_graph_wsi"], [6, "module-domid.models"], [6, "module-domid.models.a_model_cluster"], [6, "module-domid.models.model_ae"], [6, "module-domid.models.model_dec"], [6, "module-domid.models.model_m2yd"], [6, "module-domid.models.model_sdcn"], [6, "module-domid.models.model_vade"], [7, "module-domid.tasks"], [7, "module-domid.tasks.b_task_cluster"], [7, "module-domid.tasks.task_her2"], [7, "module-domid.tasks.task_mnist"], [7, "module-domid.tasks.task_mnist_color"], [7, "module-domid.tasks.task_unittest"], [7, "module-domid.tasks.task_usps"], [7, "module-domid.tasks.task_wsi"], [7, "module-domid.tasks.zoo_tasks"], [8, "module-domid.tests"], [8, "module-domid.tests.test_domid"], [8, "module-domid.tests.test_graph"], [8, "module-domid.tests.test_losses"], [8, "module-domid.tests.test_mnist_dataset"], [8, "module-domid.tests.test_model_builder"], [8, "module-domid.tests.test_model_trainer"], [9, "module-domid.trainers"], [9, "module-domid.trainers.pretraining_GMM"], [9, "module-domid.trainers.pretraining_KMeans"], [9, "module-domid.trainers.pretraining_sdcn"], [9, "module-domid.trainers.trainer_ae"], [9, "module-domid.trainers.trainer_cluster"], [9, "module-domid.trainers.trainer_sdcn"], [10, "module-domid.utils"], [10, "module-domid.utils.mean_std"], [10, "module-domid.utils.perf_cluster"], [10, "module-domid.utils.perf_similarity"], [10, "module-domid.utils.storing"]], "parse_cmd_args() (in module domid.arg_parser)": [[2, "domid.arg_parser.parse_cmd_args"]], "nodealgobuilderae (class in domid.algos.builder_ae)": [[3, "domid.algos.builder_ae.NodeAlgoBuilderAE"]], "nodealgobuilderdec (class in domid.algos.builder_dec)": [[3, "domid.algos.builder_dec.NodeAlgoBuilderDEC"]], "nodealgobuilderm2yd (class in domid.algos.builder_m2yd)": [[3, "domid.algos.builder_m2yd.NodeAlgoBuilderM2YD"]], "nodealgobuildersdcn (class in domid.algos.builder_sdcn)": [[3, "domid.algos.builder_sdcn.NodeAlgoBuilderSDCN"]], "nodealgobuildervade (class in domid.algos.builder_vade)": [[3, "domid.algos.builder_vade.NodeAlgoBuilderVaDE"]], "domid.algos": [[3, "module-domid.algos"]], "domid.algos.builder_ae": [[3, "module-domid.algos.builder_ae"]], "domid.algos.builder_dec": [[3, "module-domid.algos.builder_dec"]], "domid.algos.builder_m2yd": [[3, "module-domid.algos.builder_m2yd"]], "domid.algos.builder_sdcn": [[3, "module-domid.algos.builder_sdcn"]], "domid.algos.builder_vade": [[3, "module-domid.algos.builder_vade"]], "get_node_na() (in module domid.algos.builder_ae)": [[3, "domid.algos.builder_ae.get_node_na"]], "get_node_na() (in module domid.algos.builder_dec)": [[3, "domid.algos.builder_dec.get_node_na"]], "get_node_na() (in module domid.algos.builder_m2yd)": [[3, "domid.algos.builder_m2yd.get_node_na"]], "get_node_na() (in module domid.algos.builder_sdcn)": [[3, "domid.algos.builder_sdcn.get_node_na"]], "get_node_na() (in module domid.algos.builder_vade)": [[3, "domid.algos.builder_vade.get_node_na"]], "init_business() (domid.algos.builder_ae.nodealgobuilderae method)": [[3, "domid.algos.builder_ae.NodeAlgoBuilderAE.init_business"]], "init_business() (domid.algos.builder_dec.nodealgobuilderdec method)": [[3, "domid.algos.builder_dec.NodeAlgoBuilderDEC.init_business"]], "init_business() (domid.algos.builder_m2yd.nodealgobuilderm2yd method)": [[3, "domid.algos.builder_m2yd.NodeAlgoBuilderM2YD.init_business"]], "init_business() (domid.algos.builder_sdcn.nodealgobuildersdcn method)": [[3, "domid.algos.builder_sdcn.NodeAlgoBuilderSDCN.init_business"]], "init_business() (domid.algos.builder_vade.nodealgobuildervade method)": [[3, "domid.algos.builder_vade.NodeAlgoBuilderVaDE.init_business"]], "convolutionaldecoder (class in domid.compos.cnn_ae)": [[4, "domid.compos.cnn_AE.ConvolutionalDecoder"]], "convolutionaldecoder (class in domid.compos.cnn_vae)": [[4, "domid.compos.cnn_VAE.ConvolutionalDecoder"]], "convolutionalencoder (class in domid.compos.cnn_ae)": [[4, "domid.compos.cnn_AE.ConvolutionalEncoder"]], "convolutionalencoder (class in domid.compos.cnn_vae)": [[4, "domid.compos.cnn_VAE.ConvolutionalEncoder"]], "decclusteringlayer (class in domid.compos.dec_clustering_layer)": [[4, "domid.compos.DEC_clustering_layer.DECClusteringLayer"]], "gnn (class in domid.compos.gnn)": [[4, "domid.compos.GNN.GNN"]], "gnnlayer (class in domid.compos.gnn_layer)": [[4, "domid.compos.GNN_layer.GNNLayer"]], "lineardecoder (class in domid.compos.linear_vae)": [[4, "domid.compos.linear_VAE.LinearDecoder"]], "lineardecoderae (class in domid.compos.linear_ae)": [[4, "domid.compos.linear_AE.LinearDecoderAE"]], "linearencoder (class in domid.compos.linear_vae)": [[4, "domid.compos.linear_VAE.LinearEncoder"]], "linearencoderae (class in domid.compos.linear_ae)": [[4, "domid.compos.linear_AE.LinearEncoderAE"]], "net_mnist (class in domid.compos.nn_net)": [[4, "domid.compos.nn_net.Net_MNIST"]], "prediction (class in domid.compos.predict_basic)": [[4, "domid.compos.predict_basic.Prediction"]], "unflatten (class in domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.UnFlatten"]], "__init__() (domid.compos.dec_clustering_layer.decclusteringlayer method)": [[4, "domid.compos.DEC_clustering_layer.DECClusteringLayer.__init__"]], "__init__() (domid.compos.gnn.gnn method)": [[4, "domid.compos.GNN.GNN.__init__"]], "__init__() (domid.compos.gnn_layer.gnnlayer method)": [[4, "domid.compos.GNN_layer.GNNLayer.__init__"]], "__init__() (domid.compos.vae_blocks.unflatten method)": [[4, "domid.compos.VAE_blocks.UnFlatten.__init__"]], "__init__() (domid.compos.cnn_ae.convolutionaldecoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalDecoder.__init__"]], "__init__() (domid.compos.cnn_ae.convolutionalencoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalEncoder.__init__"]], "__init__() (domid.compos.cnn_vae.convolutionaldecoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalDecoder.__init__"]], "__init__() (domid.compos.cnn_vae.convolutionalencoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalEncoder.__init__"]], "__init__() (domid.compos.linear_ae.lineardecoderae method)": [[4, "domid.compos.linear_AE.LinearDecoderAE.__init__"]], "__init__() (domid.compos.linear_ae.linearencoderae method)": [[4, "domid.compos.linear_AE.LinearEncoderAE.__init__"]], "__init__() (domid.compos.linear_vae.lineardecoder method)": [[4, "domid.compos.linear_VAE.LinearDecoder.__init__"]], "__init__() (domid.compos.linear_vae.linearencoder method)": [[4, "domid.compos.linear_VAE.LinearEncoder.__init__"]], "__init__() (domid.compos.nn_net.net_mnist method)": [[4, "domid.compos.nn_net.Net_MNIST.__init__"]], "__init__() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.__init__"]], "cnn_decoding_block() (in module domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.cnn_decoding_block"]], "cnn_encoding_block() (in module domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.cnn_encoding_block"]], "conv_op() (domid.compos.nn_net.net_mnist method)": [[4, "domid.compos.nn_net.Net_MNIST.conv_op"]], "domid.compos": [[4, "module-domid.compos"]], "domid.compos.dec_clustering_layer": [[4, "module-domid.compos.DEC_clustering_layer"]], "domid.compos.gnn": [[4, "module-domid.compos.GNN"]], "domid.compos.gnn_layer": [[4, "module-domid.compos.GNN_layer"]], "domid.compos.vae_blocks": [[4, "module-domid.compos.VAE_blocks"]], "domid.compos.cnn_ae": [[4, "module-domid.compos.cnn_AE"]], "domid.compos.cnn_vae": [[4, "module-domid.compos.cnn_VAE"]], "domid.compos.linear_ae": [[4, "module-domid.compos.linear_AE"]], "domid.compos.linear_vae": [[4, "module-domid.compos.linear_VAE"]], "domid.compos.nn_net": [[4, "module-domid.compos.nn_net"]], "domid.compos.predict_basic": [[4, "module-domid.compos.predict_basic"]], "domid.compos.tensorboard_fun": [[4, "module-domid.compos.tensorboard_fun"]], "epoch_tr_acc() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.epoch_tr_acc"]], "epoch_tr_correlation() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.epoch_tr_correlation"]], "epoch_val_acc() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.epoch_val_acc"]], "epoch_val_correlation() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.epoch_val_correlation"]], "forward() (domid.compos.dec_clustering_layer.decclusteringlayer method)": [[4, "domid.compos.DEC_clustering_layer.DECClusteringLayer.forward"]], "forward() (domid.compos.gnn.gnn method)": [[4, "domid.compos.GNN.GNN.forward"]], "forward() (domid.compos.gnn_layer.gnnlayer method)": [[4, "domid.compos.GNN_layer.GNNLayer.forward"]], "forward() (domid.compos.vae_blocks.unflatten method)": [[4, "domid.compos.VAE_blocks.UnFlatten.forward"]], "forward() (domid.compos.cnn_ae.convolutionaldecoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalDecoder.forward"]], "forward() (domid.compos.cnn_ae.convolutionalencoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalEncoder.forward"]], "forward() (domid.compos.cnn_vae.convolutionaldecoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalDecoder.forward"]], "forward() (domid.compos.cnn_vae.convolutionalencoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalEncoder.forward"]], "forward() (domid.compos.linear_ae.lineardecoderae method)": [[4, "domid.compos.linear_AE.LinearDecoderAE.forward"]], "forward() (domid.compos.linear_ae.linearencoderae method)": [[4, "domid.compos.linear_AE.LinearEncoderAE.forward"]], "forward() (domid.compos.linear_vae.lineardecoder method)": [[4, "domid.compos.linear_VAE.LinearDecoder.forward"]], "forward() (domid.compos.linear_vae.linearencoder method)": [[4, "domid.compos.linear_VAE.LinearEncoder.forward"]], "forward() (domid.compos.nn_net.net_mnist method)": [[4, "domid.compos.nn_net.Net_MNIST.forward"]], "get_output_shape() (in module domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.get_output_shape"]], "linear_block() (in module domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.linear_block"]], "mk_prediction() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.mk_prediction"]], "probe() (domid.compos.nn_net.net_mnist method)": [[4, "domid.compos.nn_net.Net_MNIST.probe"]], "tensorboard_write() (in module domid.compos.tensorboard_fun)": [[4, "domid.compos.tensorboard_fun.tensorboard_write"]], "test_net_mnist() (in module domid.compos.nn_net)": [[4, "domid.compos.nn_net.test_Net_MNIST"]], "adsetmnistcolorrgbsolo (class in domid.dsets.a_dset_mnist_color_rgb_solo)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo"]], "dsether2 (class in domid.dsets.dset_her2)": [[5, "domid.dsets.dset_her2.DsetHER2"]], "dsetmnist (class in domid.dsets.dset_mnist)": [[5, "domid.dsets.dset_mnist.DsetMNIST"]], "dsetmnistcolorsolodefault (class in domid.dsets.dset_mnist_color_solo_default)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault"]], "dsetusps (class in domid.dsets.dset_usps)": [[5, "domid.dsets.dset_usps.DsetUSPS"]], "dsetunittest (class in domid.dsets.dset_unittest)": [[5, "domid.dsets.dset_unittest.DsetUnitTest"]], "dsetwsi (class in domid.dsets.dset_wsi)": [[5, "domid.dsets.dset_wsi.DsetWSI"]], "graphconstructor (class in domid.dsets.make_graph)": [[5, "domid.dsets.make_graph.GraphConstructor"]], "graphconstructorwsi (class in domid.dsets.make_graph_wsi)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI"]], "__init__() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.__init__"]], "__init__() (domid.dsets.dset_her2.dsether2 method)": [[5, "domid.dsets.dset_her2.DsetHER2.__init__"]], "__init__() (domid.dsets.dset_mnist.dsetmnist method)": [[5, "domid.dsets.dset_mnist.DsetMNIST.__init__"]], "__init__() (domid.dsets.dset_unittest.dsetunittest method)": [[5, "domid.dsets.dset_unittest.DsetUnitTest.__init__"]], "__init__() (domid.dsets.dset_usps.dsetusps method)": [[5, "domid.dsets.dset_usps.DsetUSPS.__init__"]], "__init__() (domid.dsets.dset_wsi.dsetwsi method)": [[5, "domid.dsets.dset_wsi.DsetWSI.__init__"]], "__init__() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.__init__"]], "__init__() (domid.dsets.make_graph_wsi.graphconstructorwsi method)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI.__init__"]], "connection_calc() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.connection_calc"]], "connection_calc() (domid.dsets.make_graph_wsi.graphconstructorwsi method)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI.connection_calc"]], "construct_graph() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.construct_graph"]], "construct_graph() (domid.dsets.make_graph_wsi.graphconstructorwsi method)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI.construct_graph"]], "create_the_dataset() (domid.dsets.dset_unittest.dsetunittest method)": [[5, "domid.dsets.dset_unittest.DsetUnitTest.create_the_dataset"]], "distance_calc() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.distance_calc"]], "distance_calc_wsi() (domid.dsets.make_graph_wsi.graphconstructorwsi method)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI.distance_calc_wsi"]], "domid.dsets": [[5, "module-domid.dsets"]], "domid.dsets.a_dset_mnist_color_rgb_solo": [[5, "module-domid.dsets.a_dset_mnist_color_rgb_solo"]], "domid.dsets.dset_her2": [[5, "module-domid.dsets.dset_her2"]], "domid.dsets.dset_mnist": [[5, "module-domid.dsets.dset_mnist"]], "domid.dsets.dset_mnist_color_solo_default": [[5, "module-domid.dsets.dset_mnist_color_solo_default"]], "domid.dsets.dset_unittest": [[5, "module-domid.dsets.dset_unittest"]], "domid.dsets.dset_usps": [[5, "module-domid.dsets.dset_usps"]], "domid.dsets.dset_wsi": [[5, "module-domid.dsets.dset_wsi"]], "domid.dsets.generate_dataset_dataframe_her2": [[5, "module-domid.dsets.generate_dataset_dataframe_her2"]], "domid.dsets.make_graph": [[5, "module-domid.dsets.make_graph"]], "domid.dsets.make_graph_wsi": [[5, "module-domid.dsets.make_graph_wsi"]], "generate_dataframe() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.generate_dataframe"]], "get_background_color() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.get_background_color"]], "get_background_color() (domid.dsets.dset_mnist_color_solo_default.dsetmnistcolorsolodefault method)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault.get_background_color"]], "get_features_labels() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.get_features_labels"]], "get_foreground_color() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.get_foreground_color"]], "get_foreground_color() (domid.dsets.dset_mnist_color_solo_default.dsetmnistcolorsolodefault method)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault.get_foreground_color"]], "get_jpg_folders() (in module domid.dsets.generate_dataset_dataframe_her2)": [[5, "domid.dsets.generate_dataset_dataframe_her2.get_jpg_folders"]], "get_num_colors() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.get_num_colors"]], "get_num_colors() (domid.dsets.dset_mnist_color_solo_default.dsetmnistcolorsolodefault method)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault.get_num_colors"]], "get_original_indicies() (domid.dsets.dset_usps.dsetusps method)": [[5, "domid.dsets.dset_usps.DsetUSPS.get_original_indicies"]], "mean_scores_per_experiment() (in module domid.dsets.generate_dataset_dataframe_her2)": [[5, "domid.dsets.generate_dataset_dataframe_her2.mean_scores_per_experiment"]], "mk_adj_mat() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.mk_adj_mat"]], "normalize() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.normalize"]], "palette (domid.dsets.dset_mnist_color_solo_default.dsetmnistcolorsolodefault property)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault.palette"]], "parse_machine_labels() (in module domid.dsets.generate_dataset_dataframe_her2)": [[5, "domid.dsets.generate_dataset_dataframe_her2.parse_machine_labels"]], "sparse_mx_to_torch_sparse_tensor() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.sparse_mx_to_torch_sparse_tensor"]], "total_count_images() (in module domid.dsets.generate_dataset_dataframe_her2)": [[5, "domid.dsets.generate_dataset_dataframe_her2.total_count_images"]], "amodelcluster (class in domid.models.a_model_cluster)": [[6, "domid.models.a_model_cluster.AModelCluster"]], "elbo_loss() (domid.models.model_vade.modelvade method)": [[6, "domid.models.model_vade.ModelVaDE.ELBO_Loss"]], "modelae (class in domid.models.model_ae)": [[6, "domid.models.model_ae.ModelAE"]], "modeldec (class in domid.models.model_dec)": [[6, "domid.models.model_dec.ModelDEC"]], "modelsdcn (class in domid.models.model_sdcn)": [[6, "domid.models.model_sdcn.ModelSDCN"]], "modelvade (class in domid.models.model_vade)": [[6, "domid.models.model_vade.ModelVaDE"]], "modelxy2d (class in domid.models.model_m2yd)": [[6, "domid.models.model_m2yd.ModelXY2D"]], "__init__() (domid.models.model_ae.modelae method)": [[6, "domid.models.model_ae.ModelAE.__init__"]], "__init__() (domid.models.model_dec.modeldec method)": [[6, "domid.models.model_dec.ModelDEC.__init__"]], "__init__() (domid.models.model_m2yd.modelxy2d method)": [[6, "domid.models.model_m2yd.ModelXY2D.__init__"]], "__init__() (domid.models.model_sdcn.modelsdcn method)": [[6, "domid.models.model_sdcn.ModelSDCN.__init__"]], "__init__() (domid.models.model_vade.modelvade method)": [[6, "domid.models.model_vade.ModelVaDE.__init__"]], "cal_logit_y() (domid.models.model_m2yd.modelxy2d method)": [[6, "domid.models.model_m2yd.ModelXY2D.cal_logit_y"]], "cal_loss() (domid.models.model_ae.modelae method)": [[6, "domid.models.model_ae.ModelAE.cal_loss"]], "cal_loss() (domid.models.model_dec.modeldec method)": [[6, "domid.models.model_dec.ModelDEC.cal_loss"]], "cal_loss() (domid.models.model_m2yd.modelxy2d method)": [[6, "domid.models.model_m2yd.ModelXY2D.cal_loss"]], "cal_loss() (domid.models.model_sdcn.modelsdcn method)": [[6, "domid.models.model_sdcn.ModelSDCN.cal_loss"]], "cal_loss() (domid.models.model_vade.modelvade method)": [[6, "domid.models.model_vade.ModelVaDE.cal_loss"]], "cal_loss_for_tensorboard() (domid.models.model_sdcn.modelsdcn method)": [[6, "domid.models.model_sdcn.ModelSDCN.cal_loss_for_tensorboard"]], "cal_perf_metric() (domid.models.a_model_cluster.amodelcluster method)": [[6, "domid.models.a_model_cluster.AModelCluster.cal_perf_metric"]], "create_perf_obj() (domid.models.a_model_cluster.amodelcluster method)": [[6, "domid.models.a_model_cluster.AModelCluster.create_perf_obj"]], "distance_between_clusters() (domid.models.model_ae.modelae method)": [[6, "domid.models.model_ae.ModelAE.distance_between_clusters"]], "domid.models": [[6, "module-domid.models"]], "domid.models.a_model_cluster": [[6, "module-domid.models.a_model_cluster"]], "domid.models.model_ae": [[6, "module-domid.models.model_ae"]], "domid.models.model_dec": [[6, "module-domid.models.model_dec"]], "domid.models.model_m2yd": [[6, "module-domid.models.model_m2yd"]], "domid.models.model_sdcn": [[6, "module-domid.models.model_sdcn"]], "domid.models.model_vade": [[6, "module-domid.models.model_vade"]], "forward() (domid.models.model_m2yd.modelxy2d method)": [[6, "domid.models.model_m2yd.ModelXY2D.forward"]], "gaussian_pdf_log() (domid.models.model_vade.modelvade static method)": [[6, "domid.models.model_vade.ModelVaDE.gaussian_pdf_log"]], "gaussian_pdfs_log() (domid.models.model_vade.modelvade method)": [[6, "domid.models.model_vade.ModelVaDE.gaussian_pdfs_log"]], "infer_d_v() (domid.models.model_ae.modelae method)": [[6, "domid.models.model_ae.ModelAE.infer_d_v"]], "infer_d_v() (domid.models.model_dec.modeldec method)": [[6, "domid.models.model_dec.ModelDEC.infer_d_v"]], "infer_d_v() (domid.models.model_m2yd.modelxy2d method)": [[6, "domid.models.model_m2yd.ModelXY2D.infer_d_v"]], "infer_d_v() (domid.models.model_sdcn.modelsdcn method)": [[6, "domid.models.model_sdcn.ModelSDCN.infer_d_v"]], "infer_d_v() (domid.models.model_vade.modelvade method)": [[6, "domid.models.model_vade.ModelVaDE.infer_d_v"]], "infer_d_v_2() (domid.models.model_ae.modelae method)": [[6, "domid.models.model_ae.ModelAE.infer_d_v_2"]], "infer_d_v_2() (domid.models.model_dec.modeldec method)": [[6, "domid.models.model_dec.ModelDEC.infer_d_v_2"]], "infer_d_v_2() (domid.models.model_sdcn.modelsdcn method)": [[6, "domid.models.model_sdcn.ModelSDCN.infer_d_v_2"]], "infer_d_v_2() (domid.models.model_vade.modelvade method)": [[6, "domid.models.model_vade.ModelVaDE.infer_d_v_2"]], "infer_y_vpicn() (domid.models.model_m2yd.modelxy2d method)": [[6, "domid.models.model_m2yd.ModelXY2D.infer_y_vpicn"]], "pretrain_loss() (domid.models.model_ae.modelae method)": [[6, "domid.models.model_ae.ModelAE.pretrain_loss"]], "pretrain_loss() (domid.models.model_dec.modeldec method)": [[6, "domid.models.model_dec.ModelDEC.pretrain_loss"]], "pretrain_loss() (domid.models.model_sdcn.modelsdcn method)": [[6, "domid.models.model_sdcn.ModelSDCN.pretrain_loss"]], "pretrain_loss() (domid.models.model_vade.modelvade method)": [[6, "domid.models.model_vade.ModelVaDE.pretrain_loss"]], "reconstruction_loss() (domid.models.model_vade.modelvade method)": [[6, "domid.models.model_vade.ModelVaDE.reconstruction_loss"]], "target_distribution() (domid.models.model_dec.modeldec method)": [[6, "domid.models.model_dec.ModelDEC.target_distribution"]], "target_distribution() (domid.models.model_sdcn.modelsdcn method)": [[6, "domid.models.model_sdcn.ModelSDCN.target_distribution"]], "test_fun() (in module domid.models.model_ae)": [[6, "domid.models.model_ae.test_fun"]], "test_fun() (in module domid.models.model_m2yd)": [[6, "domid.models.model_m2yd.test_fun"]], "test_fun() (in module domid.models.model_vade)": [[6, "domid.models.model_vade.test_fun"]], "nodetaskdictcluster (class in domid.tasks.b_task_cluster)": [[7, "domid.tasks.b_task_cluster.NodeTaskDictCluster"]], "nodetaskher2 (class in domid.tasks.task_her2)": [[7, "domid.tasks.task_her2.NodeTaskHER2"]], "nodetaskmnist (class in domid.tasks.task_mnist)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST"]], "nodetaskmnistcolor10 (class in domid.tasks.task_mnist_color)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10"]], "nodetaskusps (class in domid.tasks.task_usps)": [[7, "domid.tasks.task_usps.NodeTaskUSPS"]], "nodetaskunittest (class in domid.tasks.task_unittest)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest"]], "nodetaskwsi (class in domid.tasks.task_wsi)": [[7, "domid.tasks.task_wsi.NodeTaskWSI"]], "taskchainnodegetter (class in domid.tasks.zoo_tasks)": [[7, "domid.tasks.zoo_tasks.TaskChainNodeGetter"]], "__init__() (domid.tasks.zoo_tasks.taskchainnodegetter method)": [[7, "domid.tasks.zoo_tasks.TaskChainNodeGetter.__init__"]], "calc_corr() (domid.tasks.task_her2.nodetaskher2 method)": [[7, "domid.tasks.task_her2.NodeTaskHER2.calc_corr"]], "dim_y (domid.tasks.task_mnist_color.nodetaskmnistcolor10 property)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.dim_y"]], "domid.tasks": [[7, "module-domid.tasks"]], "domid.tasks.b_task_cluster": [[7, "module-domid.tasks.b_task_cluster"]], "domid.tasks.task_her2": [[7, "module-domid.tasks.task_her2"]], "domid.tasks.task_mnist": [[7, "module-domid.tasks.task_mnist"]], "domid.tasks.task_mnist_color": [[7, "module-domid.tasks.task_mnist_color"]], "domid.tasks.task_unittest": [[7, "module-domid.tasks.task_unittest"]], "domid.tasks.task_usps": [[7, "module-domid.tasks.task_usps"]], "domid.tasks.task_wsi": [[7, "module-domid.tasks.task_wsi"]], "domid.tasks.zoo_tasks": [[7, "module-domid.tasks.zoo_tasks"]], "get_dset_by_domain() (domid.tasks.task_her2.nodetaskher2 method)": [[7, "domid.tasks.task_her2.NodeTaskHER2.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_mnist.nodetaskmnist method)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_mnist_color.nodetaskmnistcolor10 method)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_unittest.nodetaskunittest method)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_usps.nodetaskusps method)": [[7, "domid.tasks.task_usps.NodeTaskUSPS.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_wsi.nodetaskwsi method)": [[7, "domid.tasks.task_wsi.NodeTaskWSI.get_dset_by_domain"]], "get_list_domains() (domid.tasks.task_her2.nodetaskher2 method)": [[7, "domid.tasks.task_her2.NodeTaskHER2.get_list_domains"]], "get_list_domains() (domid.tasks.task_mnist.nodetaskmnist method)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST.get_list_domains"]], "get_list_domains() (domid.tasks.task_mnist_color.nodetaskmnistcolor10 method)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.get_list_domains"]], "get_list_domains() (domid.tasks.task_unittest.nodetaskunittest method)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest.get_list_domains"]], "get_list_domains() (domid.tasks.task_usps.nodetaskusps method)": [[7, "domid.tasks.task_usps.NodeTaskUSPS.get_list_domains"]], "get_list_domains() (domid.tasks.task_wsi.nodetaskwsi method)": [[7, "domid.tasks.task_wsi.NodeTaskWSI.get_list_domains"]], "init_business() (domid.tasks.task_mnist_color.nodetaskmnistcolor10 method)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.init_business"]], "isize (domid.tasks.task_her2.nodetaskher2 property)": [[7, "domid.tasks.task_her2.NodeTaskHER2.isize"]], "isize (domid.tasks.task_mnist.nodetaskmnist property)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST.isize"]], "isize (domid.tasks.task_mnist_color.nodetaskmnistcolor10 property)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.isize"]], "isize (domid.tasks.task_unittest.nodetaskunittest property)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest.isize"]], "isize (domid.tasks.task_usps.nodetaskusps property)": [[7, "domid.tasks.task_usps.NodeTaskUSPS.isize"]], "isize (domid.tasks.task_wsi.nodetaskwsi property)": [[7, "domid.tasks.task_wsi.NodeTaskWSI.isize"]], "list_str_y (domid.tasks.task_her2.nodetaskher2 property)": [[7, "domid.tasks.task_her2.NodeTaskHER2.list_str_y"]], "list_str_y (domid.tasks.task_mnist.nodetaskmnist property)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST.list_str_y"]], "list_str_y (domid.tasks.task_mnist_color.nodetaskmnistcolor10 property)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.list_str_y"]], "list_str_y (domid.tasks.task_unittest.nodetaskunittest property)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest.list_str_y"]], "list_str_y (domid.tasks.task_usps.nodetaskusps property)": [[7, "domid.tasks.task_usps.NodeTaskUSPS.list_str_y"]], "list_str_y (domid.tasks.task_wsi.nodetaskwsi property)": [[7, "domid.tasks.task_wsi.NodeTaskWSI.list_str_y"]], "test_fun() (in module domid.tasks.task_her2)": [[7, "domid.tasks.task_her2.test_fun"]], "test_fun() (in module domid.tasks.task_mnist)": [[7, "domid.tasks.task_mnist.test_fun"]], "test_fun() (in module domid.tasks.task_unittest)": [[7, "domid.tasks.task_unittest.test_fun"]], "test_fun() (in module domid.tasks.task_usps)": [[7, "domid.tasks.task_usps.test_fun"]], "test_fun() (in module domid.tasks.task_wsi)": [[7, "domid.tasks.task_wsi.test_fun"]], "domid.tests": [[8, "module-domid.tests"]], "domid.tests.test_domid": [[8, "module-domid.tests.test_domid"]], "domid.tests.test_graph": [[8, "module-domid.tests.test_graph"]], "domid.tests.test_losses": [[8, "module-domid.tests.test_losses"]], "domid.tests.test_mnist_dataset": [[8, "module-domid.tests.test_mnist_dataset"]], "domid.tests.test_model_builder": [[8, "module-domid.tests.test_model_builder"]], "domid.tests.test_model_trainer": [[8, "module-domid.tests.test_model_trainer"]], "experiment_train() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.experiment_train"]], "experiment_train() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.experiment_train"]], "graph_constructor() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.graph_constructor"]], "model_compiler() (in module domid.tests.test_model_builder)": [[8, "domid.tests.test_model_builder.model_compiler"]], "node_compiler() (in module domid.tests.test_mnist_dataset)": [[8, "domid.tests.test_mnist_dataset.node_compiler"]], "test_m2yd_train_mnistcolor() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_M2YD_train_MNISTcolor"]], "test_mnist_conditionalone_train() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNIST_conditionalOne_train"]], "test_mnist_pretrain() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNIST_pretrain"]], "test_mnist_train() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNIST_train"]], "test_mnist_train_cnn() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNIST_train_CNN"]], "test_mnistcolor_ae() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_AE"]], "test_mnistcolor_sdcn() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_SDCN"]], "test_mnistcolor_sdcn_graph_construction_heat() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.test_MNISTcolor_SDCN_graph_construction_heat"]], "test_mnistcolor_sdcn_graph_construction_ncos() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.test_MNISTcolor_SDCN_graph_construction_ncos"]], "test_mnistcolor_pretrain_cnn() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_pretrain_CNN"]], "test_mnistcolor_train() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_train"]], "test_mnistcolor_train_cnn() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_train_CNN"]], "test_vade() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.test_VADE"]], "test_vade_cnn() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.test_VADE_CNN"]], "test_vade_cnn_nonbinary() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.test_VADE_CNN_nonbinary"]], "test_vade_nonbinary() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.test_VADE_nonbinary"]], "test_vade_cnn() (in module domid.tests.test_model_builder)": [[8, "domid.tests.test_model_builder.test_VaDE_CNN"]], "test_vade_linear() (in module domid.tests.test_model_builder)": [[8, "domid.tests.test_model_builder.test_VaDE_linear"]], "test_m2yd() (in module domid.tests.test_model_builder)": [[8, "domid.tests.test_model_builder.test_m2yd"]], "test_mnist_length() (in module domid.tests.test_mnist_dataset)": [[8, "domid.tests.test_mnist_dataset.test_mnist_length"]], "test_mnistcolor10_length() (in module domid.tests.test_mnist_dataset)": [[8, "domid.tests.test_mnist_dataset.test_mnistcolor10_length"]], "test_version() (in module domid.tests.test_domid)": [[8, "domid.tests.test_domid.test_version"]], "gmm_fit() (domid.trainers.pretraining_gmm.pretraining method)": [[9, "domid.trainers.pretraining_GMM.Pretraining.GMM_fit"]], "pretraining (class in domid.trainers.pretraining_gmm)": [[9, "domid.trainers.pretraining_GMM.Pretraining"]], "pretraining (class in domid.trainers.pretraining_kmeans)": [[9, "domid.trainers.pretraining_KMeans.Pretraining"]], "pretrainingsdcn (class in domid.trainers.pretraining_sdcn)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN"]], "trainercluster (class in domid.trainers.trainer_ae)": [[9, "domid.trainers.trainer_ae.TrainerCluster"]], "trainercluster (class in domid.trainers.trainer_cluster)": [[9, "domid.trainers.trainer_cluster.TrainerCluster"]], "trainercluster (class in domid.trainers.trainer_sdcn)": [[9, "domid.trainers.trainer_sdcn.TrainerCluster"]], "__init__() (domid.trainers.pretraining_gmm.pretraining method)": [[9, "domid.trainers.pretraining_GMM.Pretraining.__init__"]], "__init__() (domid.trainers.pretraining_kmeans.pretraining method)": [[9, "domid.trainers.pretraining_KMeans.Pretraining.__init__"]], "__init__() (domid.trainers.pretraining_sdcn.pretrainingsdcn method)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN.__init__"]], "__init__() (domid.trainers.trainer_ae.trainercluster method)": [[9, "domid.trainers.trainer_ae.TrainerCluster.__init__"]], "__init__() (domid.trainers.trainer_cluster.trainercluster method)": [[9, "domid.trainers.trainer_cluster.TrainerCluster.__init__"]], "__init__() (domid.trainers.trainer_sdcn.trainercluster method)": [[9, "domid.trainers.trainer_sdcn.TrainerCluster.__init__"]], "before_tr() (domid.trainers.trainer_ae.trainercluster method)": [[9, "domid.trainers.trainer_ae.TrainerCluster.before_tr"]], "before_tr() (domid.trainers.trainer_cluster.trainercluster method)": [[9, "domid.trainers.trainer_cluster.TrainerCluster.before_tr"]], "before_tr() (domid.trainers.trainer_sdcn.trainercluster method)": [[9, "domid.trainers.trainer_sdcn.TrainerCluster.before_tr"]], "domid.trainers": [[9, "module-domid.trainers"]], "domid.trainers.pretraining_gmm": [[9, "module-domid.trainers.pretraining_GMM"]], "domid.trainers.pretraining_kmeans": [[9, "module-domid.trainers.pretraining_KMeans"]], "domid.trainers.pretraining_sdcn": [[9, "module-domid.trainers.pretraining_sdcn"]], "domid.trainers.trainer_ae": [[9, "module-domid.trainers.trainer_ae"]], "domid.trainers.trainer_cluster": [[9, "module-domid.trainers.trainer_cluster"]], "domid.trainers.trainer_sdcn": [[9, "module-domid.trainers.trainer_sdcn"]], "kmeans_cluster_assignement() (domid.trainers.pretraining_sdcn.pretrainingsdcn method)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN.kmeans_cluster_assignement"]], "model_fit() (domid.trainers.pretraining_kmeans.pretraining method)": [[9, "domid.trainers.pretraining_KMeans.Pretraining.model_fit"]], "model_fit() (domid.trainers.pretraining_sdcn.pretrainingsdcn method)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN.model_fit"]], "post_tr() (domid.trainers.trainer_ae.trainercluster method)": [[9, "domid.trainers.trainer_ae.TrainerCluster.post_tr"]], "post_tr() (domid.trainers.trainer_cluster.trainercluster method)": [[9, "domid.trainers.trainer_cluster.TrainerCluster.post_tr"]], "post_tr() (domid.trainers.trainer_sdcn.trainercluster method)": [[9, "domid.trainers.trainer_sdcn.TrainerCluster.post_tr"]], "pretrain_loss() (domid.trainers.pretraining_gmm.pretraining method)": [[9, "domid.trainers.pretraining_GMM.Pretraining.pretrain_loss"]], "pretrain_loss() (domid.trainers.pretraining_kmeans.pretraining method)": [[9, "domid.trainers.pretraining_KMeans.Pretraining.pretrain_loss"]], "pretrain_loss() (domid.trainers.pretraining_sdcn.pretrainingsdcn method)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN.pretrain_loss"]], "tr_epoch() (domid.trainers.trainer_ae.trainercluster method)": [[9, "domid.trainers.trainer_ae.TrainerCluster.tr_epoch"]], "tr_epoch() (domid.trainers.trainer_cluster.trainercluster method)": [[9, "domid.trainers.trainer_cluster.TrainerCluster.tr_epoch"]], "tr_epoch() (domid.trainers.trainer_sdcn.trainercluster method)": [[9, "domid.trainers.trainer_sdcn.TrainerCluster.tr_epoch"]], "perfcluster (class in domid.utils.perf_cluster)": [[10, "domid.utils.perf_cluster.PerfCluster"]], "perfcorrelationher2 (class in domid.utils.perf_similarity)": [[10, "domid.utils.perf_similarity.PerfCorrelationHER2"]], "storing (class in domid.utils.storing)": [[10, "domid.utils.storing.Storing"]], "__init__() (domid.utils.perf_cluster.perfcluster method)": [[10, "domid.utils.perf_cluster.PerfCluster.__init__"]], "__init__() (domid.utils.perf_similarity.perfcorrelationher2 method)": [[10, "domid.utils.perf_similarity.PerfCorrelationHER2.__init__"]], "__init__() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.__init__"]], "cal_acc() (domid.utils.perf_cluster.perfcluster class method)": [[10, "domid.utils.perf_cluster.PerfCluster.cal_acc"]], "cal_acc() (domid.utils.perf_similarity.perfcorrelationher2 class method)": [[10, "domid.utils.perf_similarity.PerfCorrelationHER2.cal_acc"]], "csv_dump() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.csv_dump"]], "domid.utils": [[10, "module-domid.utils"]], "domid.utils.mean_std": [[10, "module-domid.utils.mean_std"]], "domid.utils.perf_cluster": [[10, "module-domid.utils.perf_cluster"]], "domid.utils.perf_similarity": [[10, "module-domid.utils.perf_similarity"]], "domid.utils.storing": [[10, "module-domid.utils.storing"]], "hungarian_algorithm() (domid.utils.perf_cluster.perfcluster class method)": [[10, "domid.utils.perf_cluster.PerfCluster.hungarian_algorithm"]], "run() (in module domid.utils.mean_std)": [[10, "domid.utils.mean_std.run"]], "run2() (in module domid.utils.mean_std)": [[10, "domid.utils.mean_std.run2"]], "saving_model() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.saving_model"]], "storing() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.storing"]], "storing_z_space() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.storing_z_space"]]}}) \ No newline at end of file +Search.setIndex({"docnames": ["about", "about_link", "domid", "domid.algos", "domid.compos", "domid.dsets", "domid.models", "domid.tasks", "domid.tests", "domid.trainers", "domid.utils", "index", "modules", "readme_link", "requirements"], "filenames": ["about.md", "about_link.rst", "domid.rst", "domid.algos.rst", "domid.compos.rst", "domid.dsets.rst", "domid.models.rst", "domid.tasks.rst", "domid.tests.rst", "domid.trainers.rst", "domid.utils.rst", "index.rst", "modules.rst", "readme_link.rst", "requirements.txt"], "titles": ["VaDE Model Summary", "About DomId", "domid package", "domid.algos package", "domid.compos package", "domid.dsets package", "domid.models package", "domid.tasks package", "domid.tests package", "domid.trainers package", "domid.utils package", "Welcome to DomId\u2019s documentation!", "domid", "Introduction", "recommonmark==0.5.0.dev0"], "terms": {"variat": [0, 1, 11, 13], "deep": [0, 1, 11, 13], "embed": [0, 1, 11, 13], "1": [0, 1, 3, 4, 5, 7, 13], "i": [0, 1, 4, 5, 7, 9, 11, 13], "an": [0, 1, 2, 3, 13], "unsupervis": [0, 1, 7, 11], "gener": [0, 1, 11, 13], "cluster": [0, 1, 2, 4, 5, 6, 7, 10, 11], "approach": [0, 1, 13], "base": [0, 1, 3, 4, 5, 6, 7, 9, 10, 11], "autoencod": [0, 1], "2": [0, 1, 4, 5, 13], "In": [0, 1, 13], "thi": [0, 1, 4, 5, 7, 10, 11, 13], "librari": [0, 1], "can": [0, 1, 2, 5, 7, 10, 11, 13], "deploi": [0, 1], "us": [0, 1, 2, 4, 5, 6, 7, 9, 10, 11, 13], "both": [0, 1, 4, 5, 6, 11], "artifici": [0, 1], "neural": [0, 1, 9, 13], "network": [0, 1, 9, 13], "ann": [0, 1], "convolut": [0, 1, 4, 11], "cnn": [0, 1, 13], "architectur": [0, 1, 11, 13], "encod": [0, 1, 4, 6, 10, 11, 13], "x": [0, 1, 4, 5, 6], "\u03c6": [0, 1], "decod": [0, 1, 4, 11, 13], "f": [0, 1], "z": [0, 1, 4, 10], "\u03b8": [0, 1], "The": [0, 1, 2, 4, 5, 7, 11, 13], "learn": [0, 1, 7, 9, 11], "compress": [0, 1], "high": [0, 1], "dimension": [0, 1, 13], "input": [0, 1, 2, 4, 6, 9, 10], "imag": [0, 1, 4, 5, 7, 9, 13], "lower": [0, 1], "latent": [0, 1, 4, 13], "represent": [0, 1, 4], "mixtur": [0, 1], "gaussian": [0, 1], "mog": [0, 1], "prior": [0, 1, 4, 13], "distribut": [0, 1, 4], "we": [0, 1, 7, 9, 13], "examin": [0, 1], "sub": [0, 1], "group": [0, 1], "domain": [0, 1, 2, 4, 5, 6, 7, 10, 11], "within": [0, 1, 4, 13], "dataset": [0, 1, 2, 4, 5, 7, 10], "reveal": [0, 1], "individu": [0, 1], "space": [0, 1, 2, 4, 13], "how": [0, 1, 13], "affect": [0, 1], "perform": [0, 1, 4, 6, 7, 9, 10, 11, 13], "infer": [0, 1], "where": [0, 1, 7, 9], "observ": [0, 1, 3, 9, 11], "ar": [0, 1, 4, 5, 7, 9, 11, 13], "map": [0, 1], "seri": [0, 1], "correspond": [0, 1, 4, 6, 13], "variabl": [0, 1, 5, 13], "assign": [0, 1, 4, 6, 10], "c": [0, 1], "denot": [0, 1], "d": [0, 1, 10], "e": [0, 1, 4, 5, 13], "r": [0, 1], "number": [0, 1, 4, 5, 9, 10, 13], "from": [0, 1, 2, 4, 5, 7, 11, 13], "sampl": [0, 1], "thu": [0, 1], "train": [0, 1, 2, 4, 5, 6, 7, 9], "also": [0, 1, 5, 13], "synthet": [0, 1], "algorithm": [0, 1, 3, 10, 13], "identifi": [0, 1, 13], "subgroup": [0, 1, 13], "optim": [0, 1, 10], "stochast": [0, 1], "gradient": [0, 1], "bay": [0, 1, 13], "cite": [0, 1], "kingmaautoencodingvariationalbayes2013": [0, 1], "maxim": [0, 1], "statist": [0, 1], "measur": [0, 1, 10], "call": [0, 1, 4, 5], "evid": [0, 1], "bound": [0, 1], "elbo": [0, 1, 9, 13], "packag": [0, 1, 11, 12, 13], "implement": [0, 1, 3, 5, 11, 13], "condition": [0, 1, 11, 13], "4": [0, 1, 4, 5, 13], "expans": [0, 1], "": [0, 1, 4, 7], "process": [0, 1, 2, 11, 13], "differ": [0, 1, 5, 13], "becaus": [0, 1, 7], "combin": [0, 1, 5, 13], "extra": [0, 1], "y": [0, 1, 10], "shown": [0, 1], "figur": [0, 1], "below": [0, 1, 11], "These": [0, 1], "mai": [0, 1], "includ": [0, 1, 7, 9, 11], "class": [0, 1, 3, 4, 5, 6, 7, 9, 10, 13], "label": [0, 1, 4, 5, 7, 10, 13], "exist": [0, 1], "structur": [0, 1, 5, 13], "do": [0, 1], "need": [0, 1, 4, 5, 7, 13], "It": [0, 1], "expect": [0, 1], "addit": [0, 1, 2, 7], "access": [0, 1], "dure": [0, 1, 9, 13], "test": [0, 1, 2, 5, 6, 7, 10, 12], "3": [0, 1, 3, 4, 5, 6, 7, 13], "method": [0, 1, 5, 7], "techniqu": [0, 1], "discov": [0, 1], "data": [0, 1, 4, 5, 6, 7, 9, 10, 11], "point": [0, 1], "involv": [0, 1], "simultan": [0, 1], "loss": [0, 1, 4, 5, 6, 9, 11, 13], "function": [0, 1, 4, 5, 7, 10, 11], "similar": [0, 1], "gcn": [0, 1, 13], "ae": [0, 1, 2, 4, 13], "purpos": [0, 1, 13], "5": [0, 1, 2, 4, 13], "howev": [0, 1, 11, 13], "origin": [0, 1, 4, 13], "face": [0, 1, 13], "signific": [0, 1, 13], "scalabl": [0, 1, 13], "challeng": [0, 1, 13], "hinder": [0, 1, 13], "its": [0, 1, 13], "deploy": [0, 1, 13], "digit": [0, 1, 5, 7, 13], "pathologi": [0, 1, 13], "particularli": [0, 1, 13], "when": [0, 1, 4, 13], "deal": [0, 1, 13], "whole": [0, 1, 10, 13], "slide": [0, 1, 13], "wsi": [0, 1, 5, 7], "which": [0, 1, 2, 4, 5, 7, 10, 11, 13], "typic": [0, 1, 5, 13], "gigapixel": [0, 1, 13], "size": [0, 1, 2, 4, 7, 13], "larger": [0, 1, 13], "limit": [0, 1, 13], "aris": [0, 1, 13], "construct": [0, 1, 4, 5, 13], "graph": [0, 1, 4, 5, 13], "entir": [0, 1, 13], "imper": [0, 1, 13], "all": [0, 1, 4, 5, 6, 7, 9, 13], "singl": [0, 1, 5, 13], "batch": [0, 1, 2, 4, 5, 13], "To": [0, 1, 13], "overcom": [0, 1, 13], "issu": [0, 1, 13], "propos": [0, 1, 13], "strategi": [0, 1, 13], "introduc": [0, 1, 13], "novel": [0, 1, 13], "tailor": [0, 1, 13], "specif": [0, 1, 4, 11, 13], "experiment": [0, 1, 13], "vae": [0, 1, 4], "supervis": [0, 1], "classif": [0, 1, 7], "task": [0, 1, 2, 4, 5, 6, 9, 12, 13], "At": [0, 1], "current": [0, 1, 4, 5, 7, 11, 13], "stage": [0, 1], "pure": [0, 1], "valid": [0, 1, 4, 6, 7, 11, 13], "recommend": [0, 1, 13], "practic": [0, 1], "unless": [0, 1], "you": [0, 1], "know": [0, 1], "exactli": [0, 1], "what": [0, 1], "jiang": [0, 1, 13], "zhuxi": [0, 1, 13], "et": [0, 1, 13], "al": [0, 1, 13], "ijcai": [0, 1, 13], "2017": [0, 1, 13], "http": [0, 1, 13, 14], "arxiv": [0, 1, 13], "org": [0, 1, 13], "ab": [0, 1, 13], "1611": [0, 1, 13], "05148": [0, 1, 13], "kingma": [0, 1, 13], "well": [0, 1, 10, 13], "auto": [0, 1, 13], "iclr": [0, 1, 13], "2013": [0, 1, 13], "1312": [0, 1, 13], "6114": [0, 1, 13], "xie": [0, 1, 13], "girshick": [0, 1, 13], "farhadi": [0, 1, 13], "analysi": [0, 1, 13], "2016": [0, 1, 13], "1511": [0, 1, 13], "06335": [0, 1, 13], "sidulova": [0, 1, 13], "sun": [0, 1, 13], "gossmann": [0, 1, 13], "condit": [0, 1, 13], "identif": [0, 1, 11], "set": [0, 1, 4, 6, 7, 13], "miccai": [0, 1, 13], "2023": [0, 1, 13], "link": [0, 1, 13], "springer": [0, 1, 13], "com": [0, 1, 13, 14], "chapter": [0, 1, 13], "10": [0, 1, 2, 4, 7, 13], "1007": [0, 1, 13], "978": [0, 1, 13], "031": [0, 1, 13], "43993": [0, 1, 13], "3_64": [0, 1, 13], "bo": [0, 1, 13], "deyu": [0, 1, 13], "proceed": [0, 1, 13], "web": [0, 1, 13], "confer": [0, 1, 13], "2020": [0, 1, 13], "doi": [0, 1, 13], "1145": [0, 1, 13], "3366423": [0, 1, 13], "3380214": [0, 1, 13], "6": [0, 1, 13], "kahaki": [0, 1, 13], "hagemann": [0, 1, 13], "contextu": [0, 1, 13], "2024": [0, 1, 13], "review": [0, 1, 13], "algo": [2, 11, 12, 13], "builder_a": [2, 11, 12, 13], "nodealgobuildera": [2, 3], "init_busi": [2, 3, 7, 9], "get_node_na": [2, 3], "builder_dec": [2, 11, 12, 13], "nodealgobuilderdec": [2, 3], "builder_m2yd": [2, 11, 12, 13], "nodealgobuilderm2yd": [2, 3], "builder_sdcn": [2, 11, 12, 13], "nodealgobuildersdcn": [2, 3], "builder_vad": [2, 11, 12, 13], "nodealgobuildervad": [2, 3], "zoo_algo": [2, 11, 12], "algobuilderchainnodegett": [2, 3], "__init__": [2, 3, 4, 5, 6, 7, 9, 10], "register_external_nod": [2, 3], "compo": [2, 11, 12], "dec_clustering_lay": [2, 11, 12], "decclusteringlay": [2, 4], "forward": [2, 4], "gnn": [2, 11, 12], "gnn_layer": [2, 11, 12], "gnnlayer": [2, 4], "vae_block": [2, 11, 12], "get_output_shap": [2, 4], "cnn_encoding_block": [2, 4], "cnn_decoding_block": [2, 4], "unflatten": [2, 4], "linear_block": [2, 4], "cnn_ae": [2, 11, 12], "convolutionalencod": [2, 4], "get_z": [2, 4], "get_log_sigma2": [2, 4], "convolutionaldecod": [2, 4], "cnn_vae": [2, 11, 12], "linear_a": [2, 11, 12], "linearencodera": [2, 4], "lineardecodera": [2, 4], "linear_va": [2, 11, 12], "linearencod": [2, 4], "lineardecod": [2, 4], "nn_net": [2, 11, 12], "net_mnist": [2, 4], "probe": [2, 4, 10], "conv_op": [2, 4], "test_net_mnist": [2, 4], "predict_bas": [2, 11, 12], "predict": [2, 4, 5, 6, 10], "mk_predict": [2, 4], "epoch_tr_acc": [2, 4], "epoch_val_acc": [2, 4], "epoch_tr_correl": [2, 4], "epoch_val_correl": [2, 4], "tensorboard_fun": [2, 11, 12], "tensorboard_writ": [2, 4], "dset": [2, 11, 12, 13], "a_dset_mnist_color_rgb_solo": [2, 12, 13], "adsetmnistcolorrgbsolo": [2, 5], "get_foreground_color": [2, 5], "get_background_color": [2, 5], "get_num_color": [2, 5], "generate_datafram": [2, 5], "dset_her2": [2, 12, 13], "dsether2": [2, 5], "dset_mnist": [2, 12], "dsetmnist": [2, 5], "dset_mnist_color_solo_default": [2, 12], "dsetmnistcolorsolodefault": [2, 5], "palett": [2, 5, 7], "dset_unittest": [2, 12], "dsetunittest": [2, 5], "create_the_dataset": [2, 5], "dset_usp": [2, 12], "dsetusp": [2, 5], "get_original_indici": [2, 5], "dset_wsi": [2, 12], "dsetwsi": [2, 5], "generate_dataset_dataframe_her2": [2, 12], "get_jpg_fold": [2, 5], "total_count_imag": [2, 5], "parse_machine_label": [2, 5], "mean_scores_per_experi": [2, 5], "make_graph": [2, 12], "graphconstructor": [2, 5], "sparse_mx_to_torch_sparse_tensor": [2, 5], "get_features_label": [2, 5], "normal": [2, 5], "distance_calc": [2, 5], "connection_calc": [2, 5], "mk_adj_mat": [2, 5], "construct_graph": [2, 5], "make_graph_wsi": [2, 12], "graphconstructorwsi": [2, 5], "distance_calc_wsi": [2, 5], "model": [2, 3, 4, 5, 7, 8, 9, 10, 12], "a_model_clust": [2, 11, 12], "amodelclust": [2, 6], "create_perf_obj": [2, 6], "cal_perf_metr": [2, 6], "cal_loss": [2, 6], "infer_d_v": [2, 6], "extend": [2, 6, 9], "model_a": [2, 11, 12], "mk_ae": [2, 6], "test_fun": [2, 6, 7], "model_dec": [2, 11, 12], "mk_dec": [2, 6], "model_m2yd": [2, 11, 12], "mk_m2yd": [2, 6], "model_sdcn": [2, 11, 12], "mk_sdcn": [2, 6], "model_vad": [2, 11, 12], "mk_vade": [2, 6], "b_task_clust": [2, 12], "nodetaskdictclust": [2, 7], "task_her2": [2, 12, 13], "nodetaskher2": [2, 7], "list_str_i": [2, 7], "isiz": [2, 7], "get_list_domain": [2, 7], "get_dset_by_domain": [2, 7], "calc_corr": [2, 7], "task_mnist": [2, 12], "nodetaskmnist": [2, 7], "task_mnist_color": [2, 12], "nodetaskmnistcolor10": [2, 7], "dim_i": [2, 7], "task_unittest": [2, 12], "nodetaskunittest": [2, 7], "task_usp": [2, 12], "nodetaskusp": [2, 7], "task_wsi": [2, 12], "nodetaskwsi": [2, 7], "zoo_task": [2, 12, 13], "taskchainnodegett": [2, 7], "test_domid": [2, 12], "test_vers": [2, 8], "test_graph": [2, 12], "graph_constructor": [2, 8], "test_data": [2, 8], "test_graph_method": [2, 8], "test_connection_calc": [2, 8], "test_mk_adj_mat": [2, 8], "test_mnistcolor_sdcn_graph_construction_heat": [2, 8], "test_mnistcolor_sdcn_graph_construction_nco": [2, 8], "test_loss": [2, 12], "test_vade_cnn_nonbinari": [2, 8], "test_vade_cnn": [2, 8], "test_vade_nonbinari": [2, 8], "test_vad": [2, 8], "test_mnist_dataset": [2, 12], "node_compil": [2, 8], "test_mnist_length": [2, 8], "test_mnistcolor10_length": [2, 8], "test_model_build": [2, 12], "model_compil": [2, 8], "test_vade_linear": [2, 8], "test_m2yd": [2, 8], "test_model_train": [2, 12], "train_mnistcolor_a": [2, 8], "ae_weight": [2, 8], "test_mnist_pretrain": [2, 8], "test_mnist_train": [2, 8], "test_mnist_train_cnn": [2, 8], "test_mnistcolor_train": [2, 8], "test_mnistcolor_train_cnn": [2, 8], "test_mnistcolor_pretrain_cnn": [2, 8], "test_m2yd_train_mnistcolor": [2, 8], "test_mnist_conditionalone_train": [2, 8], "test_mnistcolor_a": [2, 8], "test_mnistcolor_sdcn": [2, 8], "util": [2, 12], "experiment_train": [2, 8], "trainer": [2, 3, 5, 7, 11, 12], "pretraining_gmm": [2, 11, 12], "pretrain": [2, 9, 11], "pretrain_loss": [2, 9], "gmm_fit": [2, 9], "pretraining_kmean": [2, 11, 12], "model_fit": [2, 9], "pretraining_sdcn": [2, 11, 12], "pretrainingsdcn": [2, 9], "kmeans_cluster_assign": [2, 9], "trainer_a": [2, 11, 12], "trainera": [2, 9], "tr_epoch": [2, 9], "before_tr": [2, 9], "post_tr": [2, 9], "trainer_clust": [2, 11, 12], "trainerclust": [2, 9], "trainer_sdcn": [2, 11, 12], "trainersdcn": [2, 9], "zoo_train": [2, 11, 12], "trainerchainnodegett": [2, 9], "mean_std": [2, 11, 12], "run": [2, 4, 10, 11, 13], "run2": [2, 10], "perf_clust": [2, 11, 12], "perfclust": [2, 10], "hungarian_algorithm": [2, 10], "cal_acc": [2, 10], "perf_similar": [2, 11, 12], "perfcorrelationher2": [2, 10], "store": [2, 4, 7, 11, 12, 13], "saving_model": [2, 10], "storing_z_spac": [2, 10], "csv_dump": [2, 10], "command": [2, 7, 9, 13], "line": [2, 5, 7, 9, 13], "argument": [2, 5, 7, 9, 13], "mk_parser_main": [2, 12], "sourc": [2, 3, 4, 5, 6, 7, 8, 9, 10], "arg": [2, 5, 7, 8, 9, 10], "definit": 2, "parse_cmd_arg": [2, 12], "pars": 2, "given": [2, 4, 5], "make": [2, 5], "experi": [2, 11], "str": 2, "train_domain": 2, "test_domain": 2, "batchsiz": [2, 5, 6], "int": 2, "pre_tr": [2, 13], "epo": [2, 13], "nocu": [2, 13], "true": [2, 7, 9], "kwarg": 2, "creat": [2, 7], "custom": [2, 11], "user": [2, 3], "specifi": [2, 3, 5, 13], "paramet": [2, 4, 5, 6, 7, 9, 10], "param": [2, 5, 7, 9], "predefin": 2, "For": [2, 11, 13], "more": 2, "explan": 2, "refer": [2, 11], "document": 2, "found": [2, 11, 13], "domainlab": [2, 6, 7], "task_dset": 2, "py": [2, 13, 14], "nameofmodel": 2, "import": [2, 11], "appropri": 2, "mk_": 2, "concret": 2, "exampl": [2, 11, 13], "model_": 2, "string": [2, 5, 9, 10, 13], "instanc": [2, 4], "sdcn": [2, 5], "see": [2, 11, 13], "avail": [2, 4, 7], "under": 2, "defin": [2, 4, 13], "your": [2, 13], "own": [2, 13], "enumer": 2, "chosen": 2, "separ": [2, 7], "ani": [2, 10], "return": [2, 3, 4, 5, 6, 7, 9, 10], "exp": [2, 3], "object": [2, 3, 4, 5, 7, 9, 10], "success_nod": 3, "none": [3, 4, 5, 6, 7, 8, 9, 10], "nodealgobuild": 3, "initi": [3, 4, 5, 6, 9, 11], "chain": [3, 7, 9, 13], "respons": [3, 9, 11], "pattern": [3, 9], "select": [3, 7, 9], "apath": [3, 13], "hardcod": [3, 7], "node": [3, 7, 9], "extern": 3, "python": [3, 7, 11, 13], "file": [3, 5, 13], "n_cluster": 4, "hidden": 4, "cluster_cent": 4, "alpha": 4, "0": [4, 5, 7, 13], "devic": [4, 6, 7, 9, 10], "cpu": 4, "layer": 4, "center": 4, "student": 4, "t": 4, "g": [4, 5, 13], "cuda": 4, "propag": 4, "clusteringlay": 4, "equat": [4, 6], "paper": [4, 6, 13], "tensor": [4, 5, 6], "featur": [4, 5, 11], "t_dist": 4, "soft": 4, "n_input": 4, "n_enc_1": 4, "n_enc_2": 4, "n_enc_3": 4, "n_z": 4, "intern": [4, 6], "state": [4, 6], "share": [4, 6], "nn": [4, 6], "scriptmodul": [4, 6], "adj": 4, "tra1": 4, "tra2": 4, "tra3": 4, "sigma": 4, "adjac": [4, 5], "matrix": [4, 5, 10], "first": 4, "second": 4, "third": 4, "in_featur": 4, "out_featur": 4, "activ": 4, "relu": 4, "adjec": 4, "image_dim": 4, "in_c": 4, "out_c": 4, "kernel_s": 4, "stride": 4, "pad": 4, "num_channel": 4, "comput": [4, 10], "everi": 4, "should": [4, 6, 13], "overridden": 4, "subclass": 4, "although": 4, "recip": 4, "pass": [4, 5, 9], "one": [4, 5, 13], "afterward": 4, "instead": [4, 7], "sinc": 4, "former": 4, "take": [4, 10], "care": 4, "regist": 4, "hook": 4, "while": [4, 7, 11], "latter": 4, "silent": 4, "ignor": 4, "them": [4, 5], "zd_dim": [4, 6, 13], "num_filt": 4, "32": 4, "64": 4, "128": 4, "i_w": [4, 9], "28": [4, 5], "i_h": [4, 9], "k": [4, 5], "dimens": [4, 5, 7], "channel": [4, 7], "list": [4, 7], "filter": 4, "each": [4, 5, 9, 11], "width": [4, 7, 9], "height": [4, 7, 9], "kernel": 4, "domain_dim": 4, "h_dim": 4, "linear": [4, 11], "output": [4, 13], "have": [4, 6, 11], "twice": 4, "mani": 4, "mean": [4, 5, 10], "log": [4, 11], "revers": 4, "order": [4, 13], "x_pro": 4, "reconstruct": 4, "assum": [4, 13], "equal": 4, "other": [4, 9, 11, 13], "x_log_sigma2": 4, "varianc": 4, "n_dec_1": 4, "n_dec_2": 4, "n_dec_3": 4, "input_dim": 4, "features_dim": 4, "500": 4, "2000": 4, "mnist": [4, 5, 7, 11], "rgb": 4, "format": 4, "y_dim": 4, "img_siz": 4, "loader_tr": [4, 6, 7, 9, 10], "loader_v": [4, 9], "b": [4, 13], "eas": 4, "result": [4, 11], "made": 4, "currect": 4, "dateset": 4, "through": [4, 5], "acquisit": 4, "machin": [4, 5], "applic": 4, "calcul": [4, 5, 6, 9], "accuraci": [4, 10], "confus": [4, 10, 13], "vec_d": 4, "vec_i": 4, "correl": 4, "her2": [4, 5, 7, 11, 13], "score": [4, 5], "onli": [4, 5, 13], "valiat": 4, "writer": [4, 9], "epoch": [4, 9, 10, 13], "lr": [4, 13], "warmup_beta": [4, 6], "acc_tr": 4, "pretraining_finish": 4, "tensor_x": [4, 6, 9], "inject_tensor": [4, 9], "other_info": 4, "color": [5, 7], "ind_color": 5, "path": [5, 10, 13], "subset_step": 5, "100": [5, 13], "color_schem": 5, "label_transform": 5, "mk_fun_label2onehot": 5, "local": 5, "fun_label2onehot": 5, "list_transform": 5, "raw_split": 5, "flag_rand_color": 5, "fals": [5, 7], "inject_vari": 5, "nomin": 5, "rang": 5, "spectrum": 5, "subdomain": 5, "foreground": 5, "background": 5, "contain": [5, 13], "abstract": 5, "ind": 5, "index": 5, "disk": 5, "storag": 5, "directori": [5, 11, 13], "num": 5, "paint": 5, "accord": 5, "back": 5, "torch": 5, "transform": 5, "default": [5, 7, 10], "part": 5, "flag": 5, "randomli": [5, 9], "depreci": 5, "hot": [5, 6], "vector": 5, "class_num": 5, "d_dim": [5, 6, 13], "metadata_path": 5, "stain": 5, "microscopi": 5, "As": [5, 11], "diagnost": 5, "There": 5, "collect": 5, "site": 5, "integ": [5, 10, 13], "valu": [5, 9, 13], "kept": 5, "note": [5, 11, 13], "actual": 5, "therefor": 5, "ad": [5, 7, 11, 13], "dpath": [5, 13], "name": [5, 7, 9, 13], "inject": [5, 13], "cdvade": [5, 11], "metadata": 5, "csv": [5, 13], "typec": 5, "meta_data_csv": 5, "datafram": [5, 13], "load": 5, "9": [5, 7, 13], "subsampl": 5, "fraction": 5, "properti": [5, 7], "sole": 5, "unit": 5, "1x16x16": 5, "random": 5, "path_to_domain": 5, "weah": 5, "root": [5, 13], "previous": 5, "domain_label": [5, 13], "txt": [5, 13], "must": 5, "insid": 5, "keep": 5, "folder": [5, 13], "jpg": 5, "convent": 5, "end": [5, 9], "image_nam": 5, "img_loc": 5, "parser": [5, 14], "get": [5, 7], "per": 5, "cv": 5, "slightli": 5, "graph_method": 5, "topk": 5, "7": [5, 13], "distanc": 5, "between": [5, 10], "heat": 5, "co": 5, "nco": 5, "connect": 5, "sparse_mx": 5, "convert": 5, "scipi": 5, "spars": 5, "funciton": 5, "unbatch": 5, "flatten": 5, "region_label": 5, "region": 5, "mx": 5, "row": 5, "cosin": 5, "shape": [5, 6], "num_img": 5, "pair": 5, "indeci": 5, "top": 5, "self": 5, "n": 5, "connection_pair": 5, "experiment_fold": 5, "contrain": 5, "patch_dist": 5, "coordin": 5, "patch": 5, "ha": [5, 7, 11, 13], "spacial": 5, "inform": 5, "1carcinoma_coord_39100_39573_patchnumber_98_xy_0_0": 5, "png": 5, "img_id": 5, "oper": 6, "up": 6, "metric": [6, 11, 13], "loader_t": [6, 7, 10], "inj_tensor": 6, "16": 6, "horzint": 6, "dim": 6, "vertic": 6, "pred": 6, "One": 6, "decorate": 6, "parent_class": 6, "a_model_classif": 6, "amodelclassif": 6, "succ": 7, "nodetaskdictclassif": 7, "place": 7, "inherit": 7, "further": [7, 9, 11], "categori": 7, "consid": 7, "so": [7, 11], "just": 7, "dummi": 7, "now": 7, "compat": 7, "type": 7, "na_domain": 7, "split": [7, 13], "whether": [7, 9], "portion": 7, "determin": 7, "zero": 7, "evalu": [7, 11], "statement": 7, "case": 7, "otherwis": 7, "percentag": 7, "rest": 7, "basic": [7, 11, 13], "regard": 7, "deafult": 7, "dictionari": 7, "getter": 7, "better": 7, "than": 7, "new": [7, 11, 13], "ratio": 7, "usp": 7, "annot": 7, "tmp_path": 8, "out_dir": 8, "tmp_path_factori": 8, "save_path": 8, "loader": [9, 10], "pre": 9, "estim": 9, "pi": [9, 13], "mu_c": 9, "log_sigma2_c": 9, "gmm": 9, "after": [9, 10], "updat": 9, "backpropag": 9, "like": 9, "weight": 9, "successor_nod": 9, "abstracttrain": 9, "aconf": 9, "flag_accept": 9, "notifi": 9, "tensorboard": 9, "mse": 9, "configur": 9, "rate": 9, "threshold": 9, "check": 9, "str_trainer": 9, "xxx": 9, "num_class": 10, "perfclassif": 10, "classmethod": 10, "cluster_pred_scalar": 10, "cluster_true_scalar": 10, "cost": 10, "two": 10, "arrai": 10, "element": 10, "appli": 10, "hungarian": 10, "find": 10, "max_batch": 10, "compar": 10, "against": 10, "respect": [10, 11, 13], "matric": [10, 13], "overal": 10, "match": [10, 13], "final": [10, 13], "gpu": 10, "maximum": 10, "iter": 10, "less": 10, "burden": 10, "travers": 10, "v": 10, "acc_tr_i": 10, "acc_tr_d": 10, "loss_tr": 10, "acc_val_i": 10, "acc_val_d": 10, "loss_val": 10, "r_score_tr": 10, "r_score_t": 10, "vec_y_label": 10, "vec_d_label": 10, "image_id_label": 10, "goal": 11, "provid": 11, "pytorch": 11, "platform": 11, "vade": 11, "dec": 11, "futur": [11, 13], "additioon": 11, "section": 11, "usag": 11, "introduct": 11, "submodul": [11, 12], "been": [11, 13], "develop": [11, 13], "aim": 11, "invari": 11, "multipl": 11, "unseen": 11, "code": [11, 13], "entail": 11, "could": [11, 13], "detail": 11, "serv": 11, "build": 11, "block": 11, "pleas": 11, "thei": 11, "modul": [11, 12], "content": [11, 12], "divid": 11, "three": 11, "compon": 11, "builder": 11, "go": 11, "focus": 11, "itself": 11, "save": 11, "bel0ow": 11, "some": 11, "subpackag": 12, "arg_pars": 12, "mk_exp": 12, "prerequisit": 13, "poetri": 13, "depend": 13, "manag": 13, "variou": 13, "workflow": 13, "doc": 13, "A": 13, "without": 13, "possibl": 13, "requir": 13, "clone": 13, "repositori": 13, "git": [13, 14], "github": [13, 14], "agisga": 13, "publish": 13, "pypi": 13, "easi": 13, "pip": 13, "examl": 13, "200": 13, "main_out": 13, "te_d": 13, "tr_d": 13, "anam": 13, "8": 13, "00005": 13, "assess": 13, "14428806": 13, "22498095": 13, "1877629": 13, "24480581": 13, "19816224": 13, "pool": 13, "acc": 13, "7213934426229508": 13, "3407": 13, "13": 13, "5203": 13, "31": 13, "61": 13, "20": 13, "18": 13, "104": 13, "1243": 13, "1293": 13, "1266": 13, "24": 13, "3204": 13, "3299": 13, "178": 13, "34": 13, "46": 13, "265": 13, "230": 13, "4450": 13, "7236065573770492": 13, "848": 13, "1305": 13, "26": 13, "340": 13, "311": 13, "316": 13, "816": 13, "813": 13, "44": 13, "53": 13, "51": 13, "1108": 13, "mnistcolor10": 13, "debug": 13, "50": 13, "09958664": 13, "09956316": 13, "09337884": 13, "0995345": 13, "04938212": 13, "09954792": 13, "2096352": 13, "09956467": 13, "09960268": 13, "05020422": 13, "7561666666666667": 13, "600": 13, "262": 13, "599": 13, "338": 13, "7568333333333334": 13, "259": 13, "341": 13, "describ": 13, "mnist10": 13, "xxxx": 13, "follow": 13, "would": 13, "30": 13, "250": 13, "l": 13, "combined_train": 13, "prio": 13, "gau": 13, "column": 13, "image_id": 13, "option": 13, "present": 13, "same": 13, "zd_path": 13, "If": 13, "different": 13, "csv_file": 13, "diment": 13, "inject_var": 13, "dim_inject_i": 13, "uniqu": 13, "automat": 13, "manual": 13, "0001": 13, "pre_tr_weight_path": 13, "pretrained_weight": 13, "toi": 13, "dl": 13, "here": 13, "gamma_i": 13, "linkifi": 14, "m2r2": 14, "myst": 14, "rinohtyp": 14, "nbsphinx": 14, "nbsphinx_link": 14, "sphinx_materi": 14, "commonmark": 14, "rtfd": 14}, "objects": {"": [[2, 0, 0, "-", "domid"]], "domid": [[3, 0, 0, "-", "algos"], [2, 0, 0, "-", "arg_parser"], [4, 0, 0, "-", "compos"], [5, 0, 0, "-", "dsets"], [2, 0, 0, "-", "mk_exp"], [6, 0, 0, "-", "models"], [7, 0, 0, "-", "tasks"], [8, 0, 0, "-", "tests"], [9, 0, 0, "-", "trainers"], [10, 0, 0, "-", "utils"]], "domid.algos": [[3, 0, 0, "-", "builder_ae"], [3, 0, 0, "-", "builder_dec"], [3, 0, 0, "-", "builder_m2yd"], [3, 0, 0, "-", "builder_sdcn"], [3, 0, 0, "-", "builder_vade"], [3, 0, 0, "-", "zoo_algos"]], "domid.algos.builder_ae": [[3, 1, 1, "", "NodeAlgoBuilderAE"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_ae.NodeAlgoBuilderAE": [[3, 2, 1, "", "init_business"]], "domid.algos.builder_dec": [[3, 1, 1, "", "NodeAlgoBuilderDEC"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_dec.NodeAlgoBuilderDEC": [[3, 2, 1, "", "init_business"]], "domid.algos.builder_m2yd": [[3, 1, 1, "", "NodeAlgoBuilderM2YD"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_m2yd.NodeAlgoBuilderM2YD": [[3, 2, 1, "", "init_business"]], "domid.algos.builder_sdcn": [[3, 1, 1, "", "NodeAlgoBuilderSDCN"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_sdcn.NodeAlgoBuilderSDCN": [[3, 2, 1, "", "init_business"]], "domid.algos.builder_vade": [[3, 1, 1, "", "NodeAlgoBuilderVaDE"], [3, 3, 1, "", "get_node_na"]], "domid.algos.builder_vade.NodeAlgoBuilderVaDE": [[3, 2, 1, "", "init_business"]], "domid.algos.zoo_algos": [[3, 1, 1, "", "AlgoBuilderChainNodeGetter"]], "domid.algos.zoo_algos.AlgoBuilderChainNodeGetter": [[3, 2, 1, "", "__init__"], [3, 2, 1, "", "register_external_node"]], "domid.arg_parser": [[2, 3, 1, "", "mk_parser_main"], [2, 3, 1, "", "parse_cmd_args"]], "domid.compos": [[4, 0, 0, "-", "DEC_clustering_layer"], [4, 0, 0, "-", "GNN"], [4, 0, 0, "-", "GNN_layer"], [4, 0, 0, "-", "VAE_blocks"], [4, 0, 0, "-", "cnn_AE"], [4, 0, 0, "-", "cnn_VAE"], [4, 0, 0, "-", "linear_AE"], [4, 0, 0, "-", "linear_VAE"], [4, 0, 0, "-", "nn_net"], [4, 0, 0, "-", "predict_basic"], [4, 0, 0, "-", "tensorboard_fun"]], "domid.compos.DEC_clustering_layer": [[4, 1, 1, "", "DECClusteringLayer"]], "domid.compos.DEC_clustering_layer.DECClusteringLayer": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.GNN": [[4, 1, 1, "", "GNN"]], "domid.compos.GNN.GNN": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.GNN_layer": [[4, 1, 1, "", "GNNLayer"]], "domid.compos.GNN_layer.GNNLayer": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.VAE_blocks": [[4, 1, 1, "", "UnFlatten"], [4, 3, 1, "", "cnn_decoding_block"], [4, 3, 1, "", "cnn_encoding_block"], [4, 3, 1, "", "get_output_shape"], [4, 3, 1, "", "linear_block"]], "domid.compos.VAE_blocks.UnFlatten": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.cnn_AE": [[4, 1, 1, "", "ConvolutionalDecoder"], [4, 1, 1, "", "ConvolutionalEncoder"]], "domid.compos.cnn_AE.ConvolutionalDecoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.cnn_AE.ConvolutionalEncoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"], [4, 2, 1, "", "get_log_sigma2"], [4, 2, 1, "", "get_z"]], "domid.compos.cnn_VAE": [[4, 1, 1, "", "ConvolutionalDecoder"], [4, 1, 1, "", "ConvolutionalEncoder"]], "domid.compos.cnn_VAE.ConvolutionalDecoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.cnn_VAE.ConvolutionalEncoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"], [4, 2, 1, "", "get_log_sigma2"], [4, 2, 1, "", "get_z"]], "domid.compos.linear_AE": [[4, 1, 1, "", "LinearDecoderAE"], [4, 1, 1, "", "LinearEncoderAE"]], "domid.compos.linear_AE.LinearDecoderAE": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.linear_AE.LinearEncoderAE": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"], [4, 2, 1, "", "get_log_sigma2"], [4, 2, 1, "", "get_z"]], "domid.compos.linear_VAE": [[4, 1, 1, "", "LinearDecoder"], [4, 1, 1, "", "LinearEncoder"]], "domid.compos.linear_VAE.LinearDecoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"]], "domid.compos.linear_VAE.LinearEncoder": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "forward"], [4, 2, 1, "", "get_log_sigma2"], [4, 2, 1, "", "get_z"]], "domid.compos.nn_net": [[4, 1, 1, "", "Net_MNIST"], [4, 3, 1, "", "test_Net_MNIST"]], "domid.compos.nn_net.Net_MNIST": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "conv_op"], [4, 2, 1, "", "forward"], [4, 2, 1, "", "probe"]], "domid.compos.predict_basic": [[4, 1, 1, "", "Prediction"]], "domid.compos.predict_basic.Prediction": [[4, 2, 1, "", "__init__"], [4, 2, 1, "", "epoch_tr_acc"], [4, 2, 1, "", "epoch_tr_correlation"], [4, 2, 1, "", "epoch_val_acc"], [4, 2, 1, "", "epoch_val_correlation"], [4, 2, 1, "", "mk_prediction"]], "domid.compos.tensorboard_fun": [[4, 3, 1, "", "tensorboard_write"]], "domid.dsets": [[5, 0, 0, "-", "a_dset_mnist_color_rgb_solo"], [5, 0, 0, "-", "dset_her2"], [5, 0, 0, "-", "dset_mnist"], [5, 0, 0, "-", "dset_mnist_color_solo_default"], [5, 0, 0, "-", "dset_unittest"], [5, 0, 0, "-", "dset_usps"], [5, 0, 0, "-", "dset_wsi"], [5, 0, 0, "-", "generate_dataset_dataframe_her2"], [5, 0, 0, "-", "make_graph"], [5, 0, 0, "-", "make_graph_wsi"]], "domid.dsets.a_dset_mnist_color_rgb_solo": [[5, 1, 1, "", "ADsetMNISTColorRGBSolo"]], "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "generate_dataframe"], [5, 2, 1, "", "get_background_color"], [5, 2, 1, "", "get_foreground_color"], [5, 2, 1, "", "get_num_colors"]], "domid.dsets.dset_her2": [[5, 1, 1, "", "DsetHER2"]], "domid.dsets.dset_her2.DsetHER2": [[5, 2, 1, "", "__init__"]], "domid.dsets.dset_mnist": [[5, 1, 1, "", "DsetMNIST"]], "domid.dsets.dset_mnist.DsetMNIST": [[5, 2, 1, "", "__init__"]], "domid.dsets.dset_mnist_color_solo_default": [[5, 1, 1, "", "DsetMNISTColorSoloDefault"]], "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault": [[5, 2, 1, "", "get_background_color"], [5, 2, 1, "", "get_foreground_color"], [5, 2, 1, "", "get_num_colors"], [5, 4, 1, "", "palette"]], "domid.dsets.dset_unittest": [[5, 1, 1, "", "DsetUnitTest"]], "domid.dsets.dset_unittest.DsetUnitTest": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "create_the_dataset"]], "domid.dsets.dset_usps": [[5, 1, 1, "", "DsetUSPS"]], "domid.dsets.dset_usps.DsetUSPS": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "get_original_indicies"]], "domid.dsets.dset_wsi": [[5, 1, 1, "", "DsetWSI"]], "domid.dsets.dset_wsi.DsetWSI": [[5, 2, 1, "", "__init__"]], "domid.dsets.generate_dataset_dataframe_her2": [[5, 3, 1, "", "get_jpg_folders"], [5, 3, 1, "", "mean_scores_per_experiment"], [5, 3, 1, "", "parse_machine_labels"], [5, 3, 1, "", "total_count_images"]], "domid.dsets.make_graph": [[5, 1, 1, "", "GraphConstructor"]], "domid.dsets.make_graph.GraphConstructor": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "connection_calc"], [5, 2, 1, "", "construct_graph"], [5, 2, 1, "", "distance_calc"], [5, 2, 1, "", "get_features_labels"], [5, 2, 1, "", "mk_adj_mat"], [5, 2, 1, "", "normalize"], [5, 2, 1, "", "sparse_mx_to_torch_sparse_tensor"]], "domid.dsets.make_graph_wsi": [[5, 1, 1, "", "GraphConstructorWSI"]], "domid.dsets.make_graph_wsi.GraphConstructorWSI": [[5, 2, 1, "", "__init__"], [5, 2, 1, "", "connection_calc"], [5, 2, 1, "", "construct_graph"], [5, 2, 1, "", "distance_calc_wsi"]], "domid.mk_exp": [[2, 3, 1, "", "mk_exp"]], "domid.models": [[6, 0, 0, "-", "a_model_cluster"], [6, 0, 0, "-", "model_ae"], [6, 0, 0, "-", "model_dec"], [6, 0, 0, "-", "model_m2yd"], [6, 0, 0, "-", "model_sdcn"], [6, 0, 0, "-", "model_vade"]], "domid.models.a_model_cluster": [[6, 1, 1, "", "AModelCluster"]], "domid.models.a_model_cluster.AModelCluster": [[6, 2, 1, "", "__init__"], [6, 2, 1, "", "cal_loss"], [6, 2, 1, "", "cal_perf_metric"], [6, 2, 1, "", "create_perf_obj"], [6, 2, 1, "", "extend"], [6, 2, 1, "", "infer_d_v"]], "domid.models.model_ae": [[6, 3, 1, "", "mk_ae"], [6, 3, 1, "", "test_fun"]], "domid.models.model_dec": [[6, 3, 1, "", "mk_dec"]], "domid.models.model_m2yd": [[6, 3, 1, "", "mk_m2yd"], [6, 3, 1, "", "test_fun"]], "domid.models.model_sdcn": [[6, 3, 1, "", "mk_sdcn"]], "domid.models.model_vade": [[6, 3, 1, "", "mk_vade"], [6, 3, 1, "", "test_fun"]], "domid.tasks": [[7, 0, 0, "-", "b_task_cluster"], [7, 0, 0, "-", "task_her2"], [7, 0, 0, "-", "task_mnist"], [7, 0, 0, "-", "task_mnist_color"], [7, 0, 0, "-", "task_unittest"], [7, 0, 0, "-", "task_usps"], [7, 0, 0, "-", "task_wsi"], [7, 0, 0, "-", "zoo_tasks"]], "domid.tasks.b_task_cluster": [[7, 1, 1, "", "NodeTaskDictCluster"]], "domid.tasks.task_her2": [[7, 1, 1, "", "NodeTaskHER2"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_her2.NodeTaskHER2": [[7, 2, 1, "", "calc_corr"], [7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_mnist": [[7, 1, 1, "", "NodeTaskMNIST"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_mnist.NodeTaskMNIST": [[7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_mnist_color": [[7, 1, 1, "", "NodeTaskMNISTColor10"]], "domid.tasks.task_mnist_color.NodeTaskMNISTColor10": [[7, 4, 1, "", "dim_y"], [7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 2, 1, "", "init_business"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_unittest": [[7, 1, 1, "", "NodeTaskUnitTest"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_unittest.NodeTaskUnitTest": [[7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_usps": [[7, 1, 1, "", "NodeTaskUSPS"], [7, 3, 1, "", "test_fun"]], "domid.tasks.task_usps.NodeTaskUSPS": [[7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.task_wsi": [[7, 1, 1, "", "NodeTaskWSI"]], "domid.tasks.task_wsi.NodeTaskWSI": [[7, 2, 1, "", "get_dset_by_domain"], [7, 2, 1, "", "get_list_domains"], [7, 4, 1, "", "isize"], [7, 4, 1, "", "list_str_y"]], "domid.tasks.zoo_tasks": [[7, 1, 1, "", "TaskChainNodeGetter"]], "domid.tasks.zoo_tasks.TaskChainNodeGetter": [[7, 2, 1, "", "__init__"]], "domid.tests": [[8, 0, 0, "-", "test_domid"], [8, 0, 0, "-", "test_graph"], [8, 0, 0, "-", "test_losses"], [8, 0, 0, "-", "test_mnist_dataset"], [8, 0, 0, "-", "test_model_builder"], [8, 0, 0, "-", "test_model_trainer"], [8, 0, 0, "-", "utils"]], "domid.tests.test_domid": [[8, 3, 1, "", "test_version"]], "domid.tests.test_graph": [[8, 3, 1, "", "graph_constructor"], [8, 3, 1, "", "test_MNISTcolor_SDCN_graph_construction_heat"], [8, 3, 1, "", "test_MNISTcolor_SDCN_graph_construction_ncos"], [8, 3, 1, "", "test_connection_calc"], [8, 3, 1, "", "test_data"], [8, 3, 1, "", "test_graph_methods"], [8, 3, 1, "", "test_mk_adj_mat"]], "domid.tests.test_losses": [[8, 3, 1, "", "test_VADE"], [8, 3, 1, "", "test_VADE_CNN"], [8, 3, 1, "", "test_VADE_CNN_nonbinary"], [8, 3, 1, "", "test_VADE_nonbinary"]], "domid.tests.test_mnist_dataset": [[8, 3, 1, "", "node_compiler"], [8, 3, 1, "", "test_mnist_length"], [8, 3, 1, "", "test_mnistcolor10_length"]], "domid.tests.test_model_builder": [[8, 3, 1, "", "model_compiler"], [8, 3, 1, "", "test_VaDE_CNN"], [8, 3, 1, "", "test_VaDE_linear"], [8, 3, 1, "", "test_m2yd"]], "domid.tests.test_model_trainer": [[8, 3, 1, "", "ae_weights"], [8, 3, 1, "", "test_M2YD_train_MNISTcolor"], [8, 3, 1, "", "test_MNIST_conditionalOne_train"], [8, 3, 1, "", "test_MNIST_pretrain"], [8, 3, 1, "", "test_MNIST_train"], [8, 3, 1, "", "test_MNIST_train_CNN"], [8, 3, 1, "", "test_MNISTcolor_AE"], [8, 3, 1, "", "test_MNISTcolor_SDCN"], [8, 3, 1, "", "test_MNISTcolor_pretrain_CNN"], [8, 3, 1, "", "test_MNISTcolor_train"], [8, 3, 1, "", "test_MNISTcolor_train_CNN"], [8, 3, 1, "", "train_MNISTcolor_AE"]], "domid.tests.utils": [[8, 3, 1, "", "experiment_train"]], "domid.trainers": [[9, 0, 0, "-", "pretraining_GMM"], [9, 0, 0, "-", "pretraining_KMeans"], [9, 0, 0, "-", "pretraining_sdcn"], [9, 0, 0, "-", "trainer_ae"], [9, 0, 0, "-", "trainer_cluster"], [9, 0, 0, "-", "trainer_sdcn"], [9, 0, 0, "-", "zoo_trainer"]], "domid.trainers.pretraining_GMM": [[9, 1, 1, "", "Pretraining"]], "domid.trainers.pretraining_GMM.Pretraining": [[9, 2, 1, "", "GMM_fit"], [9, 2, 1, "", "__init__"], [9, 2, 1, "", "pretrain_loss"]], "domid.trainers.pretraining_KMeans": [[9, 1, 1, "", "Pretraining"]], "domid.trainers.pretraining_KMeans.Pretraining": [[9, 2, 1, "", "__init__"], [9, 2, 1, "", "model_fit"], [9, 2, 1, "", "pretrain_loss"]], "domid.trainers.pretraining_sdcn": [[9, 1, 1, "", "PretrainingSDCN"]], "domid.trainers.pretraining_sdcn.PretrainingSDCN": [[9, 2, 1, "", "__init__"], [9, 2, 1, "", "kmeans_cluster_assignement"], [9, 2, 1, "", "model_fit"], [9, 2, 1, "", "pretrain_loss"]], "domid.trainers.trainer_ae": [[9, 1, 1, "", "TrainerAE"]], "domid.trainers.trainer_ae.TrainerAE": [[9, 2, 1, "", "before_tr"], [9, 2, 1, "", "init_business"], [9, 2, 1, "", "post_tr"], [9, 2, 1, "", "tr_epoch"]], "domid.trainers.trainer_cluster": [[9, 1, 1, "", "TrainerCluster"]], "domid.trainers.trainer_cluster.TrainerCluster": [[9, 2, 1, "", "before_tr"], [9, 2, 1, "", "init_business"], [9, 2, 1, "", "post_tr"], [9, 2, 1, "", "tr_epoch"]], "domid.trainers.trainer_sdcn": [[9, 1, 1, "", "TrainerSDCN"]], "domid.trainers.trainer_sdcn.TrainerSDCN": [[9, 2, 1, "", "before_tr"], [9, 2, 1, "", "init_business"], [9, 2, 1, "", "post_tr"], [9, 2, 1, "", "tr_epoch"]], "domid.trainers.zoo_trainer": [[9, 1, 1, "", "TrainerChainNodeGetter"]], "domid.trainers.zoo_trainer.TrainerChainNodeGetter": [[9, 2, 1, "", "__init__"]], "domid.utils": [[10, 0, 0, "-", "mean_std"], [10, 0, 0, "-", "perf_cluster"], [10, 0, 0, "-", "perf_similarity"], [10, 0, 0, "-", "storing"]], "domid.utils.mean_std": [[10, 3, 1, "", "run"], [10, 3, 1, "", "run2"]], "domid.utils.perf_cluster": [[10, 1, 1, "", "PerfCluster"]], "domid.utils.perf_cluster.PerfCluster": [[10, 2, 1, "", "__init__"], [10, 2, 1, "", "cal_acc"], [10, 2, 1, "", "hungarian_algorithm"]], "domid.utils.perf_similarity": [[10, 1, 1, "", "PerfCorrelationHER2"]], "domid.utils.perf_similarity.PerfCorrelationHER2": [[10, 2, 1, "", "__init__"], [10, 2, 1, "", "cal_acc"]], "domid.utils.storing": [[10, 1, 1, "", "Storing"]], "domid.utils.storing.Storing": [[10, 2, 1, "", "__init__"], [10, 2, 1, "", "csv_dump"], [10, 2, 1, "", "saving_model"], [10, 2, 1, "", "storing"], [10, 2, 1, "", "storing_z_space"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:method", "3": "py:function", "4": "py:property"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "method", "Python method"], "3": ["py", "function", "Python function"], "4": ["py", "property", "Python property"]}, "titleterms": {"vade": [0, 1, 13], "model": [0, 1, 6, 11, 13], "summari": [0, 1], "cdvade": [0, 1, 13], "dec": [0, 1, 13], "sdcn": [0, 1, 13], "m2yd": [0, 1, 13], "refer": [0, 1, 13], "about": [1, 11], "domid": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], "packag": [2, 3, 4, 5, 6, 7, 8, 9, 10], "subpackag": 2, "submodul": [2, 3, 4, 5, 6, 7, 8, 9, 10], "arg_pars": 2, "modul": [2, 3, 4, 5, 6, 7, 8, 9, 10], "mk_exp": 2, "content": [2, 3, 4, 5, 6, 7, 8, 9, 10], "algo": 3, "builder_a": 3, "builder_dec": 3, "builder_m2yd": 3, "builder_sdcn": 3, "builder_vad": 3, "zoo_algo": 3, "compo": 4, "dec_clustering_lay": 4, "gnn": 4, "gnn_layer": 4, "vae_block": 4, "cnn_ae": 4, "cnn_vae": 4, "linear_a": 4, "linear_va": 4, "nn_net": 4, "predict_bas": 4, "tensorboard_fun": 4, "dset": 5, "a_dset_mnist_color_rgb_solo": 5, "dset_her2": 5, "dset_mnist": 5, "dset_mnist_color_solo_default": 5, "dset_unittest": 5, "dset_usp": 5, "dset_wsi": 5, "generate_dataset_dataframe_her2": 5, "make_graph": 5, "make_graph_wsi": 5, "a_model_clust": 6, "model_a": 6, "model_dec": 6, "model_m2yd": 6, "model_sdcn": 6, "model_vad": 6, "task": [7, 11], "b_task_clust": 7, "task_her2": 7, "task_mnist": 7, "task_mnist_color": 7, "task_unittest": 7, "task_usp": 7, "task_wsi": 7, "zoo_task": 7, "test": 8, "test_domid": 8, "test_graph": 8, "test_loss": 8, "test_mnist_dataset": 8, "test_model_build": 8, "test_model_train": 8, "util": [8, 10, 11], "trainer": 9, "pretraining_gmm": 9, "pretraining_kmean": 9, "pretraining_sdcn": 9, "trainer_a": 9, "trainer_clust": 9, "trainer_sdcn": 9, "zoo_train": 9, "mean_std": 10, "perf_clust": 10, "perf_similar": 10, "store": 10, "welcom": 11, "": 11, "document": 11, "more": 11, "inform": 11, "domainlab": 11, "load": 11, "dataset": [11, 13], "defin": 11, "composit": 11, "train": [11, 13], "ulitili": 11, "introduct": 13, "domain": 13, "identif": 13, "instal": 13, "usag": 13, "appli": 13, "mnist": 13, "color": 13, "custom": 13, "cvade": 13, "modifi": 13, "wsi": 13, "data": 13, "simultan": 13, "unsupervis": 13, "cluster": 13, "supervis": 13, "classif": 13, "recommonmark": 14, "0": 14, "5": 14, "dev0": 14}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx.ext.intersphinx": 1, "sphinx.ext.todo": 2, "nbsphinx": 4, "sphinx": 57}, "alltitles": {"VaDE Model Summary": [[0, "vade-model-summary"], [1, "vade-model-summary"]], "CDVaDE Model Summary": [[0, "cdvade-model-summary"], [1, "cdvade-model-summary"]], "DEC Model Summary": [[0, "dec-model-summary"], [1, "dec-model-summary"]], "SDCN Model Summary": [[0, "sdcn-model-summary"], [1, "sdcn-model-summary"]], "M2YD Model Summary": [[0, "m2yd-model-summary"], [1, "m2yd-model-summary"]], "References": [[0, "references"], [1, "references"], [13, "references"]], "About DomId": [[1, "about-domid"], [11, "about-domid"]], "domid package": [[2, "domid-package"]], "Subpackages": [[2, "subpackages"]], "Submodules": [[2, "submodules"], [3, "submodules"], [4, "submodules"], [5, "submodules"], [6, "submodules"], [7, "submodules"], [8, "submodules"], [9, "submodules"], [10, "submodules"]], "domid.arg_parser module": [[2, "module-domid.arg_parser"]], "domid.mk_exp module": [[2, "module-domid.mk_exp"]], "Module contents": [[2, "module-domid"], [3, "module-domid.algos"], [4, "module-domid.compos"], [5, "module-domid.dsets"], [6, "module-domid.models"], [7, "module-domid.tasks"], [8, "module-domid.tests"], [9, "module-domid.trainers"], [10, "module-domid.utils"]], "domid.algos package": [[3, "domid-algos-package"]], "domid.algos.builder_ae module": [[3, "module-domid.algos.builder_ae"]], "domid.algos.builder_dec module": [[3, "module-domid.algos.builder_dec"]], "domid.algos.builder_m2yd module": [[3, "module-domid.algos.builder_m2yd"]], "domid.algos.builder_sdcn module": [[3, "module-domid.algos.builder_sdcn"]], "domid.algos.builder_vade module": [[3, "module-domid.algos.builder_vade"]], "domid.algos.zoo_algos module": [[3, "module-domid.algos.zoo_algos"]], "domid.compos package": [[4, "domid-compos-package"]], "domid.compos.DEC_clustering_layer module": [[4, "module-domid.compos.DEC_clustering_layer"]], "domid.compos.GNN module": [[4, "module-domid.compos.GNN"]], "domid.compos.GNN_layer module": [[4, "module-domid.compos.GNN_layer"]], "domid.compos.VAE_blocks module": [[4, "module-domid.compos.VAE_blocks"]], "domid.compos.cnn_AE module": [[4, "module-domid.compos.cnn_AE"]], "domid.compos.cnn_VAE module": [[4, "module-domid.compos.cnn_VAE"]], "domid.compos.linear_AE module": [[4, "module-domid.compos.linear_AE"]], "domid.compos.linear_VAE module": [[4, "module-domid.compos.linear_VAE"]], "domid.compos.nn_net module": [[4, "module-domid.compos.nn_net"]], "domid.compos.predict_basic module": [[4, "module-domid.compos.predict_basic"]], "domid.compos.tensorboard_fun module": [[4, "module-domid.compos.tensorboard_fun"]], "domid.dsets package": [[5, "domid-dsets-package"]], "domid.dsets.a_dset_mnist_color_rgb_solo module": [[5, "module-domid.dsets.a_dset_mnist_color_rgb_solo"]], "domid.dsets.dset_her2 module": [[5, "module-domid.dsets.dset_her2"]], "domid.dsets.dset_mnist module": [[5, "module-domid.dsets.dset_mnist"]], "domid.dsets.dset_mnist_color_solo_default module": [[5, "module-domid.dsets.dset_mnist_color_solo_default"]], "domid.dsets.dset_unittest module": [[5, "module-domid.dsets.dset_unittest"]], "domid.dsets.dset_usps module": [[5, "module-domid.dsets.dset_usps"]], "domid.dsets.dset_wsi module": [[5, "module-domid.dsets.dset_wsi"]], "domid.dsets.generate_dataset_dataframe_her2 module": [[5, "module-domid.dsets.generate_dataset_dataframe_her2"]], "domid.dsets.make_graph module": [[5, "module-domid.dsets.make_graph"]], "domid.dsets.make_graph_wsi module": [[5, "module-domid.dsets.make_graph_wsi"]], "domid.models package": [[6, "domid-models-package"]], "domid.models.a_model_cluster module": [[6, "module-domid.models.a_model_cluster"]], "domid.models.model_ae module": [[6, "module-domid.models.model_ae"]], "domid.models.model_dec module": [[6, "module-domid.models.model_dec"]], "domid.models.model_m2yd module": [[6, "module-domid.models.model_m2yd"]], "domid.models.model_sdcn module": [[6, "module-domid.models.model_sdcn"]], "domid.models.model_vade module": [[6, "module-domid.models.model_vade"]], "domid.tasks package": [[7, "domid-tasks-package"]], "domid.tasks.b_task_cluster module": [[7, "module-domid.tasks.b_task_cluster"]], "domid.tasks.task_her2 module": [[7, "module-domid.tasks.task_her2"]], "domid.tasks.task_mnist module": [[7, "module-domid.tasks.task_mnist"]], "domid.tasks.task_mnist_color module": [[7, "module-domid.tasks.task_mnist_color"]], "domid.tasks.task_unittest module": [[7, "module-domid.tasks.task_unittest"]], "domid.tasks.task_usps module": [[7, "module-domid.tasks.task_usps"]], "domid.tasks.task_wsi module": [[7, "module-domid.tasks.task_wsi"]], "domid.tasks.zoo_tasks module": [[7, "module-domid.tasks.zoo_tasks"]], "domid.tests package": [[8, "domid-tests-package"]], "domid.tests.test_domid module": [[8, "module-domid.tests.test_domid"]], "domid.tests.test_graph module": [[8, "module-domid.tests.test_graph"]], "domid.tests.test_losses module": [[8, "module-domid.tests.test_losses"]], "domid.tests.test_mnist_dataset module": [[8, "module-domid.tests.test_mnist_dataset"]], "domid.tests.test_model_builder module": [[8, "module-domid.tests.test_model_builder"]], "domid.tests.test_model_trainer module": [[8, "module-domid.tests.test_model_trainer"]], "domid.tests.utils module": [[8, "module-domid.tests.utils"]], "domid.trainers package": [[9, "domid-trainers-package"]], "domid.trainers.pretraining_GMM module": [[9, "module-domid.trainers.pretraining_GMM"]], "domid.trainers.pretraining_KMeans module": [[9, "module-domid.trainers.pretraining_KMeans"]], "domid.trainers.pretraining_sdcn module": [[9, "module-domid.trainers.pretraining_sdcn"]], "domid.trainers.trainer_ae module": [[9, "module-domid.trainers.trainer_ae"]], "domid.trainers.trainer_cluster module": [[9, "module-domid.trainers.trainer_cluster"]], "domid.trainers.trainer_sdcn module": [[9, "module-domid.trainers.trainer_sdcn"]], "domid.trainers.zoo_trainer module": [[9, "module-domid.trainers.zoo_trainer"]], "domid.utils package": [[10, "domid-utils-package"]], "domid.utils.mean_std module": [[10, "module-domid.utils.mean_std"]], "domid.utils.perf_cluster module": [[10, "module-domid.utils.perf_cluster"]], "domid.utils.perf_similarity module": [[10, "module-domid.utils.perf_similarity"]], "domid.utils.storing module": [[10, "module-domid.utils.storing"]], "Welcome to DomId\u2019s documentation!": [[11, "welcome-to-domid-s-documentation"]], "More information about the models": [[11, null]], "DomainLab": [[11, "domainlab"]], "Loading a Datasets and Defining a Task": [[11, "loading-a-datasets-and-defining-a-task"]], "Datasets and Tasks": [[11, null]], "Composition and Defining a Model": [[11, "composition-and-defining-a-model"]], "Models": [[11, null]], "Training a Model": [[11, "training-a-model"], [11, null]], "Ulitilies": [[11, "ulitilies"]], "Utilities": [[11, null]], "domid": [[12, "domid"]], "Introduction": [[13, "introduction"]], "Domain Identification (DomId)": [[13, "domain-identification-domid"]], "Installation": [[13, "installation"]], "Usage": [[13, "usage"]], "VaDE model": [[13, "vade-model"]], "Applying VaDE to MNIST": [[13, "applying-vade-to-mnist"]], "Applying VaDE to Color-MNIST": [[13, "applying-vade-to-color-mnist"]], "DEC model": [[13, "dec-model"]], "Custom datasets": [[13, "custom-datasets"]], "CDVaDE model": [[13, "cdvade-model"]], "Training CVaDE:": [[13, "training-cvade"]], "SDCN, and modified SDCN for WSI data": [[13, "sdcn-and-modified-sdcn-for-wsi-data"]], "Simultaneous unsupervised clustering and supervised classification": [[13, "simultaneous-unsupervised-clustering-and-supervised-classification"]], "M2YD model": [[13, "m2yd-model"]], "recommonmark==0.5.0.dev0": [[14, "recommonmark-0-5-0-dev0"]]}, "indexentries": {"domid": [[2, "module-domid"]], "domid.arg_parser": [[2, "module-domid.arg_parser"]], "domid.mk_exp": [[2, "module-domid.mk_exp"]], "mk_exp() (in module domid.mk_exp)": [[2, "domid.mk_exp.mk_exp"]], "mk_parser_main() (in module domid.arg_parser)": [[2, "domid.arg_parser.mk_parser_main"]], "module": [[2, "module-domid"], [2, "module-domid.arg_parser"], [2, "module-domid.mk_exp"], [3, "module-domid.algos"], [3, "module-domid.algos.builder_ae"], [3, "module-domid.algos.builder_dec"], [3, "module-domid.algos.builder_m2yd"], [3, "module-domid.algos.builder_sdcn"], [3, "module-domid.algos.builder_vade"], [3, "module-domid.algos.zoo_algos"], [4, "module-domid.compos"], [4, "module-domid.compos.DEC_clustering_layer"], [4, "module-domid.compos.GNN"], [4, "module-domid.compos.GNN_layer"], [4, "module-domid.compos.VAE_blocks"], [4, "module-domid.compos.cnn_AE"], [4, "module-domid.compos.cnn_VAE"], [4, "module-domid.compos.linear_AE"], [4, "module-domid.compos.linear_VAE"], [4, "module-domid.compos.nn_net"], [4, "module-domid.compos.predict_basic"], [4, "module-domid.compos.tensorboard_fun"], [5, "module-domid.dsets"], [5, "module-domid.dsets.a_dset_mnist_color_rgb_solo"], [5, "module-domid.dsets.dset_her2"], [5, "module-domid.dsets.dset_mnist"], [5, "module-domid.dsets.dset_mnist_color_solo_default"], [5, "module-domid.dsets.dset_unittest"], [5, "module-domid.dsets.dset_usps"], [5, "module-domid.dsets.dset_wsi"], [5, "module-domid.dsets.generate_dataset_dataframe_her2"], [5, "module-domid.dsets.make_graph"], [5, "module-domid.dsets.make_graph_wsi"], [6, "module-domid.models"], [6, "module-domid.models.a_model_cluster"], [6, "module-domid.models.model_ae"], [6, "module-domid.models.model_dec"], [6, "module-domid.models.model_m2yd"], [6, "module-domid.models.model_sdcn"], [6, "module-domid.models.model_vade"], [7, "module-domid.tasks"], [7, "module-domid.tasks.b_task_cluster"], [7, "module-domid.tasks.task_her2"], [7, "module-domid.tasks.task_mnist"], [7, "module-domid.tasks.task_mnist_color"], [7, "module-domid.tasks.task_unittest"], [7, "module-domid.tasks.task_usps"], [7, "module-domid.tasks.task_wsi"], [7, "module-domid.tasks.zoo_tasks"], [8, "module-domid.tests"], [8, "module-domid.tests.test_domid"], [8, "module-domid.tests.test_graph"], [8, "module-domid.tests.test_losses"], [8, "module-domid.tests.test_mnist_dataset"], [8, "module-domid.tests.test_model_builder"], [8, "module-domid.tests.test_model_trainer"], [8, "module-domid.tests.utils"], [9, "module-domid.trainers"], [9, "module-domid.trainers.pretraining_GMM"], [9, "module-domid.trainers.pretraining_KMeans"], [9, "module-domid.trainers.pretraining_sdcn"], [9, "module-domid.trainers.trainer_ae"], [9, "module-domid.trainers.trainer_cluster"], [9, "module-domid.trainers.trainer_sdcn"], [9, "module-domid.trainers.zoo_trainer"], [10, "module-domid.utils"], [10, "module-domid.utils.mean_std"], [10, "module-domid.utils.perf_cluster"], [10, "module-domid.utils.perf_similarity"], [10, "module-domid.utils.storing"]], "parse_cmd_args() (in module domid.arg_parser)": [[2, "domid.arg_parser.parse_cmd_args"]], "algobuilderchainnodegetter (class in domid.algos.zoo_algos)": [[3, "domid.algos.zoo_algos.AlgoBuilderChainNodeGetter"]], "nodealgobuilderae (class in domid.algos.builder_ae)": [[3, "domid.algos.builder_ae.NodeAlgoBuilderAE"]], "nodealgobuilderdec (class in domid.algos.builder_dec)": [[3, "domid.algos.builder_dec.NodeAlgoBuilderDEC"]], "nodealgobuilderm2yd (class in domid.algos.builder_m2yd)": [[3, "domid.algos.builder_m2yd.NodeAlgoBuilderM2YD"]], "nodealgobuildersdcn (class in domid.algos.builder_sdcn)": [[3, "domid.algos.builder_sdcn.NodeAlgoBuilderSDCN"]], "nodealgobuildervade (class in domid.algos.builder_vade)": [[3, "domid.algos.builder_vade.NodeAlgoBuilderVaDE"]], "__init__() (domid.algos.zoo_algos.algobuilderchainnodegetter method)": [[3, "domid.algos.zoo_algos.AlgoBuilderChainNodeGetter.__init__"]], "domid.algos": [[3, "module-domid.algos"]], "domid.algos.builder_ae": [[3, "module-domid.algos.builder_ae"]], "domid.algos.builder_dec": [[3, "module-domid.algos.builder_dec"]], "domid.algos.builder_m2yd": [[3, "module-domid.algos.builder_m2yd"]], "domid.algos.builder_sdcn": [[3, "module-domid.algos.builder_sdcn"]], "domid.algos.builder_vade": [[3, "module-domid.algos.builder_vade"]], "domid.algos.zoo_algos": [[3, "module-domid.algos.zoo_algos"]], "get_node_na() (in module domid.algos.builder_ae)": [[3, "domid.algos.builder_ae.get_node_na"]], "get_node_na() (in module domid.algos.builder_dec)": [[3, "domid.algos.builder_dec.get_node_na"]], "get_node_na() (in module domid.algos.builder_m2yd)": [[3, "domid.algos.builder_m2yd.get_node_na"]], "get_node_na() (in module domid.algos.builder_sdcn)": [[3, "domid.algos.builder_sdcn.get_node_na"]], "get_node_na() (in module domid.algos.builder_vade)": [[3, "domid.algos.builder_vade.get_node_na"]], "init_business() (domid.algos.builder_ae.nodealgobuilderae method)": [[3, "domid.algos.builder_ae.NodeAlgoBuilderAE.init_business"]], "init_business() (domid.algos.builder_dec.nodealgobuilderdec method)": [[3, "domid.algos.builder_dec.NodeAlgoBuilderDEC.init_business"]], "init_business() (domid.algos.builder_m2yd.nodealgobuilderm2yd method)": [[3, "domid.algos.builder_m2yd.NodeAlgoBuilderM2YD.init_business"]], "init_business() (domid.algos.builder_sdcn.nodealgobuildersdcn method)": [[3, "domid.algos.builder_sdcn.NodeAlgoBuilderSDCN.init_business"]], "init_business() (domid.algos.builder_vade.nodealgobuildervade method)": [[3, "domid.algos.builder_vade.NodeAlgoBuilderVaDE.init_business"]], "register_external_node() (domid.algos.zoo_algos.algobuilderchainnodegetter method)": [[3, "domid.algos.zoo_algos.AlgoBuilderChainNodeGetter.register_external_node"]], "convolutionaldecoder (class in domid.compos.cnn_ae)": [[4, "domid.compos.cnn_AE.ConvolutionalDecoder"]], "convolutionaldecoder (class in domid.compos.cnn_vae)": [[4, "domid.compos.cnn_VAE.ConvolutionalDecoder"]], "convolutionalencoder (class in domid.compos.cnn_ae)": [[4, "domid.compos.cnn_AE.ConvolutionalEncoder"]], "convolutionalencoder (class in domid.compos.cnn_vae)": [[4, "domid.compos.cnn_VAE.ConvolutionalEncoder"]], "decclusteringlayer (class in domid.compos.dec_clustering_layer)": [[4, "domid.compos.DEC_clustering_layer.DECClusteringLayer"]], "gnn (class in domid.compos.gnn)": [[4, "domid.compos.GNN.GNN"]], "gnnlayer (class in domid.compos.gnn_layer)": [[4, "domid.compos.GNN_layer.GNNLayer"]], "lineardecoder (class in domid.compos.linear_vae)": [[4, "domid.compos.linear_VAE.LinearDecoder"]], "lineardecoderae (class in domid.compos.linear_ae)": [[4, "domid.compos.linear_AE.LinearDecoderAE"]], "linearencoder (class in domid.compos.linear_vae)": [[4, "domid.compos.linear_VAE.LinearEncoder"]], "linearencoderae (class in domid.compos.linear_ae)": [[4, "domid.compos.linear_AE.LinearEncoderAE"]], "net_mnist (class in domid.compos.nn_net)": [[4, "domid.compos.nn_net.Net_MNIST"]], "prediction (class in domid.compos.predict_basic)": [[4, "domid.compos.predict_basic.Prediction"]], "unflatten (class in domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.UnFlatten"]], "__init__() (domid.compos.dec_clustering_layer.decclusteringlayer method)": [[4, "domid.compos.DEC_clustering_layer.DECClusteringLayer.__init__"]], "__init__() (domid.compos.gnn.gnn method)": [[4, "domid.compos.GNN.GNN.__init__"]], "__init__() (domid.compos.gnn_layer.gnnlayer method)": [[4, "domid.compos.GNN_layer.GNNLayer.__init__"]], "__init__() (domid.compos.vae_blocks.unflatten method)": [[4, "domid.compos.VAE_blocks.UnFlatten.__init__"]], "__init__() (domid.compos.cnn_ae.convolutionaldecoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalDecoder.__init__"]], "__init__() (domid.compos.cnn_ae.convolutionalencoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalEncoder.__init__"]], "__init__() (domid.compos.cnn_vae.convolutionaldecoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalDecoder.__init__"]], "__init__() (domid.compos.cnn_vae.convolutionalencoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalEncoder.__init__"]], "__init__() (domid.compos.linear_ae.lineardecoderae method)": [[4, "domid.compos.linear_AE.LinearDecoderAE.__init__"]], "__init__() (domid.compos.linear_ae.linearencoderae method)": [[4, "domid.compos.linear_AE.LinearEncoderAE.__init__"]], "__init__() (domid.compos.linear_vae.lineardecoder method)": [[4, "domid.compos.linear_VAE.LinearDecoder.__init__"]], "__init__() (domid.compos.linear_vae.linearencoder method)": [[4, "domid.compos.linear_VAE.LinearEncoder.__init__"]], "__init__() (domid.compos.nn_net.net_mnist method)": [[4, "domid.compos.nn_net.Net_MNIST.__init__"]], "__init__() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.__init__"]], "cnn_decoding_block() (in module domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.cnn_decoding_block"]], "cnn_encoding_block() (in module domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.cnn_encoding_block"]], "conv_op() (domid.compos.nn_net.net_mnist method)": [[4, "domid.compos.nn_net.Net_MNIST.conv_op"]], "domid.compos": [[4, "module-domid.compos"]], "domid.compos.dec_clustering_layer": [[4, "module-domid.compos.DEC_clustering_layer"]], "domid.compos.gnn": [[4, "module-domid.compos.GNN"]], "domid.compos.gnn_layer": [[4, "module-domid.compos.GNN_layer"]], "domid.compos.vae_blocks": [[4, "module-domid.compos.VAE_blocks"]], "domid.compos.cnn_ae": [[4, "module-domid.compos.cnn_AE"]], "domid.compos.cnn_vae": [[4, "module-domid.compos.cnn_VAE"]], "domid.compos.linear_ae": [[4, "module-domid.compos.linear_AE"]], "domid.compos.linear_vae": [[4, "module-domid.compos.linear_VAE"]], "domid.compos.nn_net": [[4, "module-domid.compos.nn_net"]], "domid.compos.predict_basic": [[4, "module-domid.compos.predict_basic"]], "domid.compos.tensorboard_fun": [[4, "module-domid.compos.tensorboard_fun"]], "epoch_tr_acc() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.epoch_tr_acc"]], "epoch_tr_correlation() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.epoch_tr_correlation"]], "epoch_val_acc() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.epoch_val_acc"]], "epoch_val_correlation() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.epoch_val_correlation"]], "forward() (domid.compos.dec_clustering_layer.decclusteringlayer method)": [[4, "domid.compos.DEC_clustering_layer.DECClusteringLayer.forward"]], "forward() (domid.compos.gnn.gnn method)": [[4, "domid.compos.GNN.GNN.forward"]], "forward() (domid.compos.gnn_layer.gnnlayer method)": [[4, "domid.compos.GNN_layer.GNNLayer.forward"]], "forward() (domid.compos.vae_blocks.unflatten method)": [[4, "domid.compos.VAE_blocks.UnFlatten.forward"]], "forward() (domid.compos.cnn_ae.convolutionaldecoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalDecoder.forward"]], "forward() (domid.compos.cnn_ae.convolutionalencoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalEncoder.forward"]], "forward() (domid.compos.cnn_vae.convolutionaldecoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalDecoder.forward"]], "forward() (domid.compos.cnn_vae.convolutionalencoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalEncoder.forward"]], "forward() (domid.compos.linear_ae.lineardecoderae method)": [[4, "domid.compos.linear_AE.LinearDecoderAE.forward"]], "forward() (domid.compos.linear_ae.linearencoderae method)": [[4, "domid.compos.linear_AE.LinearEncoderAE.forward"]], "forward() (domid.compos.linear_vae.lineardecoder method)": [[4, "domid.compos.linear_VAE.LinearDecoder.forward"]], "forward() (domid.compos.linear_vae.linearencoder method)": [[4, "domid.compos.linear_VAE.LinearEncoder.forward"]], "forward() (domid.compos.nn_net.net_mnist method)": [[4, "domid.compos.nn_net.Net_MNIST.forward"]], "get_log_sigma2() (domid.compos.cnn_ae.convolutionalencoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalEncoder.get_log_sigma2"]], "get_log_sigma2() (domid.compos.cnn_vae.convolutionalencoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalEncoder.get_log_sigma2"]], "get_log_sigma2() (domid.compos.linear_ae.linearencoderae method)": [[4, "domid.compos.linear_AE.LinearEncoderAE.get_log_sigma2"]], "get_log_sigma2() (domid.compos.linear_vae.linearencoder method)": [[4, "domid.compos.linear_VAE.LinearEncoder.get_log_sigma2"]], "get_output_shape() (in module domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.get_output_shape"]], "get_z() (domid.compos.cnn_ae.convolutionalencoder method)": [[4, "domid.compos.cnn_AE.ConvolutionalEncoder.get_z"]], "get_z() (domid.compos.cnn_vae.convolutionalencoder method)": [[4, "domid.compos.cnn_VAE.ConvolutionalEncoder.get_z"]], "get_z() (domid.compos.linear_ae.linearencoderae method)": [[4, "domid.compos.linear_AE.LinearEncoderAE.get_z"]], "get_z() (domid.compos.linear_vae.linearencoder method)": [[4, "domid.compos.linear_VAE.LinearEncoder.get_z"]], "linear_block() (in module domid.compos.vae_blocks)": [[4, "domid.compos.VAE_blocks.linear_block"]], "mk_prediction() (domid.compos.predict_basic.prediction method)": [[4, "domid.compos.predict_basic.Prediction.mk_prediction"]], "probe() (domid.compos.nn_net.net_mnist method)": [[4, "domid.compos.nn_net.Net_MNIST.probe"]], "tensorboard_write() (in module domid.compos.tensorboard_fun)": [[4, "domid.compos.tensorboard_fun.tensorboard_write"]], "test_net_mnist() (in module domid.compos.nn_net)": [[4, "domid.compos.nn_net.test_Net_MNIST"]], "adsetmnistcolorrgbsolo (class in domid.dsets.a_dset_mnist_color_rgb_solo)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo"]], "dsether2 (class in domid.dsets.dset_her2)": [[5, "domid.dsets.dset_her2.DsetHER2"]], "dsetmnist (class in domid.dsets.dset_mnist)": [[5, "domid.dsets.dset_mnist.DsetMNIST"]], "dsetmnistcolorsolodefault (class in domid.dsets.dset_mnist_color_solo_default)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault"]], "dsetusps (class in domid.dsets.dset_usps)": [[5, "domid.dsets.dset_usps.DsetUSPS"]], "dsetunittest (class in domid.dsets.dset_unittest)": [[5, "domid.dsets.dset_unittest.DsetUnitTest"]], "dsetwsi (class in domid.dsets.dset_wsi)": [[5, "domid.dsets.dset_wsi.DsetWSI"]], "graphconstructor (class in domid.dsets.make_graph)": [[5, "domid.dsets.make_graph.GraphConstructor"]], "graphconstructorwsi (class in domid.dsets.make_graph_wsi)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI"]], "__init__() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.__init__"]], "__init__() (domid.dsets.dset_her2.dsether2 method)": [[5, "domid.dsets.dset_her2.DsetHER2.__init__"]], "__init__() (domid.dsets.dset_mnist.dsetmnist method)": [[5, "domid.dsets.dset_mnist.DsetMNIST.__init__"]], "__init__() (domid.dsets.dset_unittest.dsetunittest method)": [[5, "domid.dsets.dset_unittest.DsetUnitTest.__init__"]], "__init__() (domid.dsets.dset_usps.dsetusps method)": [[5, "domid.dsets.dset_usps.DsetUSPS.__init__"]], "__init__() (domid.dsets.dset_wsi.dsetwsi method)": [[5, "domid.dsets.dset_wsi.DsetWSI.__init__"]], "__init__() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.__init__"]], "__init__() (domid.dsets.make_graph_wsi.graphconstructorwsi method)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI.__init__"]], "connection_calc() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.connection_calc"]], "connection_calc() (domid.dsets.make_graph_wsi.graphconstructorwsi method)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI.connection_calc"]], "construct_graph() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.construct_graph"]], "construct_graph() (domid.dsets.make_graph_wsi.graphconstructorwsi method)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI.construct_graph"]], "create_the_dataset() (domid.dsets.dset_unittest.dsetunittest method)": [[5, "domid.dsets.dset_unittest.DsetUnitTest.create_the_dataset"]], "distance_calc() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.distance_calc"]], "distance_calc_wsi() (domid.dsets.make_graph_wsi.graphconstructorwsi method)": [[5, "domid.dsets.make_graph_wsi.GraphConstructorWSI.distance_calc_wsi"]], "domid.dsets": [[5, "module-domid.dsets"]], "domid.dsets.a_dset_mnist_color_rgb_solo": [[5, "module-domid.dsets.a_dset_mnist_color_rgb_solo"]], "domid.dsets.dset_her2": [[5, "module-domid.dsets.dset_her2"]], "domid.dsets.dset_mnist": [[5, "module-domid.dsets.dset_mnist"]], "domid.dsets.dset_mnist_color_solo_default": [[5, "module-domid.dsets.dset_mnist_color_solo_default"]], "domid.dsets.dset_unittest": [[5, "module-domid.dsets.dset_unittest"]], "domid.dsets.dset_usps": [[5, "module-domid.dsets.dset_usps"]], "domid.dsets.dset_wsi": [[5, "module-domid.dsets.dset_wsi"]], "domid.dsets.generate_dataset_dataframe_her2": [[5, "module-domid.dsets.generate_dataset_dataframe_her2"]], "domid.dsets.make_graph": [[5, "module-domid.dsets.make_graph"]], "domid.dsets.make_graph_wsi": [[5, "module-domid.dsets.make_graph_wsi"]], "generate_dataframe() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.generate_dataframe"]], "get_background_color() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.get_background_color"]], "get_background_color() (domid.dsets.dset_mnist_color_solo_default.dsetmnistcolorsolodefault method)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault.get_background_color"]], "get_features_labels() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.get_features_labels"]], "get_foreground_color() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.get_foreground_color"]], "get_foreground_color() (domid.dsets.dset_mnist_color_solo_default.dsetmnistcolorsolodefault method)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault.get_foreground_color"]], "get_jpg_folders() (in module domid.dsets.generate_dataset_dataframe_her2)": [[5, "domid.dsets.generate_dataset_dataframe_her2.get_jpg_folders"]], "get_num_colors() (domid.dsets.a_dset_mnist_color_rgb_solo.adsetmnistcolorrgbsolo method)": [[5, "domid.dsets.a_dset_mnist_color_rgb_solo.ADsetMNISTColorRGBSolo.get_num_colors"]], "get_num_colors() (domid.dsets.dset_mnist_color_solo_default.dsetmnistcolorsolodefault method)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault.get_num_colors"]], "get_original_indicies() (domid.dsets.dset_usps.dsetusps method)": [[5, "domid.dsets.dset_usps.DsetUSPS.get_original_indicies"]], "mean_scores_per_experiment() (in module domid.dsets.generate_dataset_dataframe_her2)": [[5, "domid.dsets.generate_dataset_dataframe_her2.mean_scores_per_experiment"]], "mk_adj_mat() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.mk_adj_mat"]], "normalize() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.normalize"]], "palette (domid.dsets.dset_mnist_color_solo_default.dsetmnistcolorsolodefault property)": [[5, "domid.dsets.dset_mnist_color_solo_default.DsetMNISTColorSoloDefault.palette"]], "parse_machine_labels() (in module domid.dsets.generate_dataset_dataframe_her2)": [[5, "domid.dsets.generate_dataset_dataframe_her2.parse_machine_labels"]], "sparse_mx_to_torch_sparse_tensor() (domid.dsets.make_graph.graphconstructor method)": [[5, "domid.dsets.make_graph.GraphConstructor.sparse_mx_to_torch_sparse_tensor"]], "total_count_images() (in module domid.dsets.generate_dataset_dataframe_her2)": [[5, "domid.dsets.generate_dataset_dataframe_her2.total_count_images"]], "amodelcluster (class in domid.models.a_model_cluster)": [[6, "domid.models.a_model_cluster.AModelCluster"]], "__init__() (domid.models.a_model_cluster.amodelcluster method)": [[6, "domid.models.a_model_cluster.AModelCluster.__init__"]], "cal_loss() (domid.models.a_model_cluster.amodelcluster method)": [[6, "domid.models.a_model_cluster.AModelCluster.cal_loss"]], "cal_perf_metric() (domid.models.a_model_cluster.amodelcluster method)": [[6, "domid.models.a_model_cluster.AModelCluster.cal_perf_metric"]], "create_perf_obj() (domid.models.a_model_cluster.amodelcluster method)": [[6, "domid.models.a_model_cluster.AModelCluster.create_perf_obj"]], "domid.models": [[6, "module-domid.models"]], "domid.models.a_model_cluster": [[6, "module-domid.models.a_model_cluster"]], "domid.models.model_ae": [[6, "module-domid.models.model_ae"]], "domid.models.model_dec": [[6, "module-domid.models.model_dec"]], "domid.models.model_m2yd": [[6, "module-domid.models.model_m2yd"]], "domid.models.model_sdcn": [[6, "module-domid.models.model_sdcn"]], "domid.models.model_vade": [[6, "module-domid.models.model_vade"]], "extend() (domid.models.a_model_cluster.amodelcluster method)": [[6, "domid.models.a_model_cluster.AModelCluster.extend"]], "infer_d_v() (domid.models.a_model_cluster.amodelcluster method)": [[6, "domid.models.a_model_cluster.AModelCluster.infer_d_v"]], "mk_ae() (in module domid.models.model_ae)": [[6, "domid.models.model_ae.mk_ae"]], "mk_dec() (in module domid.models.model_dec)": [[6, "domid.models.model_dec.mk_dec"]], "mk_m2yd() (in module domid.models.model_m2yd)": [[6, "domid.models.model_m2yd.mk_m2yd"]], "mk_sdcn() (in module domid.models.model_sdcn)": [[6, "domid.models.model_sdcn.mk_sdcn"]], "mk_vade() (in module domid.models.model_vade)": [[6, "domid.models.model_vade.mk_vade"]], "test_fun() (in module domid.models.model_ae)": [[6, "domid.models.model_ae.test_fun"]], "test_fun() (in module domid.models.model_m2yd)": [[6, "domid.models.model_m2yd.test_fun"]], "test_fun() (in module domid.models.model_vade)": [[6, "domid.models.model_vade.test_fun"]], "nodetaskdictcluster (class in domid.tasks.b_task_cluster)": [[7, "domid.tasks.b_task_cluster.NodeTaskDictCluster"]], "nodetaskher2 (class in domid.tasks.task_her2)": [[7, "domid.tasks.task_her2.NodeTaskHER2"]], "nodetaskmnist (class in domid.tasks.task_mnist)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST"]], "nodetaskmnistcolor10 (class in domid.tasks.task_mnist_color)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10"]], "nodetaskusps (class in domid.tasks.task_usps)": [[7, "domid.tasks.task_usps.NodeTaskUSPS"]], "nodetaskunittest (class in domid.tasks.task_unittest)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest"]], "nodetaskwsi (class in domid.tasks.task_wsi)": [[7, "domid.tasks.task_wsi.NodeTaskWSI"]], "taskchainnodegetter (class in domid.tasks.zoo_tasks)": [[7, "domid.tasks.zoo_tasks.TaskChainNodeGetter"]], "__init__() (domid.tasks.zoo_tasks.taskchainnodegetter method)": [[7, "domid.tasks.zoo_tasks.TaskChainNodeGetter.__init__"]], "calc_corr() (domid.tasks.task_her2.nodetaskher2 method)": [[7, "domid.tasks.task_her2.NodeTaskHER2.calc_corr"]], "dim_y (domid.tasks.task_mnist_color.nodetaskmnistcolor10 property)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.dim_y"]], "domid.tasks": [[7, "module-domid.tasks"]], "domid.tasks.b_task_cluster": [[7, "module-domid.tasks.b_task_cluster"]], "domid.tasks.task_her2": [[7, "module-domid.tasks.task_her2"]], "domid.tasks.task_mnist": [[7, "module-domid.tasks.task_mnist"]], "domid.tasks.task_mnist_color": [[7, "module-domid.tasks.task_mnist_color"]], "domid.tasks.task_unittest": [[7, "module-domid.tasks.task_unittest"]], "domid.tasks.task_usps": [[7, "module-domid.tasks.task_usps"]], "domid.tasks.task_wsi": [[7, "module-domid.tasks.task_wsi"]], "domid.tasks.zoo_tasks": [[7, "module-domid.tasks.zoo_tasks"]], "get_dset_by_domain() (domid.tasks.task_her2.nodetaskher2 method)": [[7, "domid.tasks.task_her2.NodeTaskHER2.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_mnist.nodetaskmnist method)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_mnist_color.nodetaskmnistcolor10 method)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_unittest.nodetaskunittest method)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_usps.nodetaskusps method)": [[7, "domid.tasks.task_usps.NodeTaskUSPS.get_dset_by_domain"]], "get_dset_by_domain() (domid.tasks.task_wsi.nodetaskwsi method)": [[7, "domid.tasks.task_wsi.NodeTaskWSI.get_dset_by_domain"]], "get_list_domains() (domid.tasks.task_her2.nodetaskher2 method)": [[7, "domid.tasks.task_her2.NodeTaskHER2.get_list_domains"]], "get_list_domains() (domid.tasks.task_mnist.nodetaskmnist method)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST.get_list_domains"]], "get_list_domains() (domid.tasks.task_mnist_color.nodetaskmnistcolor10 method)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.get_list_domains"]], "get_list_domains() (domid.tasks.task_unittest.nodetaskunittest method)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest.get_list_domains"]], "get_list_domains() (domid.tasks.task_usps.nodetaskusps method)": [[7, "domid.tasks.task_usps.NodeTaskUSPS.get_list_domains"]], "get_list_domains() (domid.tasks.task_wsi.nodetaskwsi method)": [[7, "domid.tasks.task_wsi.NodeTaskWSI.get_list_domains"]], "init_business() (domid.tasks.task_mnist_color.nodetaskmnistcolor10 method)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.init_business"]], "isize (domid.tasks.task_her2.nodetaskher2 property)": [[7, "domid.tasks.task_her2.NodeTaskHER2.isize"]], "isize (domid.tasks.task_mnist.nodetaskmnist property)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST.isize"]], "isize (domid.tasks.task_mnist_color.nodetaskmnistcolor10 property)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.isize"]], "isize (domid.tasks.task_unittest.nodetaskunittest property)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest.isize"]], "isize (domid.tasks.task_usps.nodetaskusps property)": [[7, "domid.tasks.task_usps.NodeTaskUSPS.isize"]], "isize (domid.tasks.task_wsi.nodetaskwsi property)": [[7, "domid.tasks.task_wsi.NodeTaskWSI.isize"]], "list_str_y (domid.tasks.task_her2.nodetaskher2 property)": [[7, "domid.tasks.task_her2.NodeTaskHER2.list_str_y"]], "list_str_y (domid.tasks.task_mnist.nodetaskmnist property)": [[7, "domid.tasks.task_mnist.NodeTaskMNIST.list_str_y"]], "list_str_y (domid.tasks.task_mnist_color.nodetaskmnistcolor10 property)": [[7, "domid.tasks.task_mnist_color.NodeTaskMNISTColor10.list_str_y"]], "list_str_y (domid.tasks.task_unittest.nodetaskunittest property)": [[7, "domid.tasks.task_unittest.NodeTaskUnitTest.list_str_y"]], "list_str_y (domid.tasks.task_usps.nodetaskusps property)": [[7, "domid.tasks.task_usps.NodeTaskUSPS.list_str_y"]], "list_str_y (domid.tasks.task_wsi.nodetaskwsi property)": [[7, "domid.tasks.task_wsi.NodeTaskWSI.list_str_y"]], "test_fun() (in module domid.tasks.task_her2)": [[7, "domid.tasks.task_her2.test_fun"]], "test_fun() (in module domid.tasks.task_mnist)": [[7, "domid.tasks.task_mnist.test_fun"]], "test_fun() (in module domid.tasks.task_unittest)": [[7, "domid.tasks.task_unittest.test_fun"]], "test_fun() (in module domid.tasks.task_usps)": [[7, "domid.tasks.task_usps.test_fun"]], "ae_weights() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.ae_weights"]], "domid.tests": [[8, "module-domid.tests"]], "domid.tests.test_domid": [[8, "module-domid.tests.test_domid"]], "domid.tests.test_graph": [[8, "module-domid.tests.test_graph"]], "domid.tests.test_losses": [[8, "module-domid.tests.test_losses"]], "domid.tests.test_mnist_dataset": [[8, "module-domid.tests.test_mnist_dataset"]], "domid.tests.test_model_builder": [[8, "module-domid.tests.test_model_builder"]], "domid.tests.test_model_trainer": [[8, "module-domid.tests.test_model_trainer"]], "domid.tests.utils": [[8, "module-domid.tests.utils"]], "experiment_train() (in module domid.tests.utils)": [[8, "domid.tests.utils.experiment_train"]], "graph_constructor() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.graph_constructor"]], "model_compiler() (in module domid.tests.test_model_builder)": [[8, "domid.tests.test_model_builder.model_compiler"]], "node_compiler() (in module domid.tests.test_mnist_dataset)": [[8, "domid.tests.test_mnist_dataset.node_compiler"]], "test_m2yd_train_mnistcolor() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_M2YD_train_MNISTcolor"]], "test_mnist_conditionalone_train() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNIST_conditionalOne_train"]], "test_mnist_pretrain() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNIST_pretrain"]], "test_mnist_train() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNIST_train"]], "test_mnist_train_cnn() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNIST_train_CNN"]], "test_mnistcolor_ae() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_AE"]], "test_mnistcolor_sdcn() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_SDCN"]], "test_mnistcolor_sdcn_graph_construction_heat() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.test_MNISTcolor_SDCN_graph_construction_heat"]], "test_mnistcolor_sdcn_graph_construction_ncos() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.test_MNISTcolor_SDCN_graph_construction_ncos"]], "test_mnistcolor_pretrain_cnn() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_pretrain_CNN"]], "test_mnistcolor_train() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_train"]], "test_mnistcolor_train_cnn() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.test_MNISTcolor_train_CNN"]], "test_vade() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.test_VADE"]], "test_vade_cnn() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.test_VADE_CNN"]], "test_vade_cnn_nonbinary() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.test_VADE_CNN_nonbinary"]], "test_vade_nonbinary() (in module domid.tests.test_losses)": [[8, "domid.tests.test_losses.test_VADE_nonbinary"]], "test_vade_cnn() (in module domid.tests.test_model_builder)": [[8, "domid.tests.test_model_builder.test_VaDE_CNN"]], "test_vade_linear() (in module domid.tests.test_model_builder)": [[8, "domid.tests.test_model_builder.test_VaDE_linear"]], "test_connection_calc() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.test_connection_calc"]], "test_data() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.test_data"]], "test_graph_methods() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.test_graph_methods"]], "test_m2yd() (in module domid.tests.test_model_builder)": [[8, "domid.tests.test_model_builder.test_m2yd"]], "test_mk_adj_mat() (in module domid.tests.test_graph)": [[8, "domid.tests.test_graph.test_mk_adj_mat"]], "test_mnist_length() (in module domid.tests.test_mnist_dataset)": [[8, "domid.tests.test_mnist_dataset.test_mnist_length"]], "test_mnistcolor10_length() (in module domid.tests.test_mnist_dataset)": [[8, "domid.tests.test_mnist_dataset.test_mnistcolor10_length"]], "test_version() (in module domid.tests.test_domid)": [[8, "domid.tests.test_domid.test_version"]], "train_mnistcolor_ae() (in module domid.tests.test_model_trainer)": [[8, "domid.tests.test_model_trainer.train_MNISTcolor_AE"]], "gmm_fit() (domid.trainers.pretraining_gmm.pretraining method)": [[9, "domid.trainers.pretraining_GMM.Pretraining.GMM_fit"]], "pretraining (class in domid.trainers.pretraining_gmm)": [[9, "domid.trainers.pretraining_GMM.Pretraining"]], "pretraining (class in domid.trainers.pretraining_kmeans)": [[9, "domid.trainers.pretraining_KMeans.Pretraining"]], "pretrainingsdcn (class in domid.trainers.pretraining_sdcn)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN"]], "trainerae (class in domid.trainers.trainer_ae)": [[9, "domid.trainers.trainer_ae.TrainerAE"]], "trainerchainnodegetter (class in domid.trainers.zoo_trainer)": [[9, "domid.trainers.zoo_trainer.TrainerChainNodeGetter"]], "trainercluster (class in domid.trainers.trainer_cluster)": [[9, "domid.trainers.trainer_cluster.TrainerCluster"]], "trainersdcn (class in domid.trainers.trainer_sdcn)": [[9, "domid.trainers.trainer_sdcn.TrainerSDCN"]], "__init__() (domid.trainers.pretraining_gmm.pretraining method)": [[9, "domid.trainers.pretraining_GMM.Pretraining.__init__"]], "__init__() (domid.trainers.pretraining_kmeans.pretraining method)": [[9, "domid.trainers.pretraining_KMeans.Pretraining.__init__"]], "__init__() (domid.trainers.pretraining_sdcn.pretrainingsdcn method)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN.__init__"]], "__init__() (domid.trainers.zoo_trainer.trainerchainnodegetter method)": [[9, "domid.trainers.zoo_trainer.TrainerChainNodeGetter.__init__"]], "before_tr() (domid.trainers.trainer_ae.trainerae method)": [[9, "domid.trainers.trainer_ae.TrainerAE.before_tr"]], "before_tr() (domid.trainers.trainer_cluster.trainercluster method)": [[9, "domid.trainers.trainer_cluster.TrainerCluster.before_tr"]], "before_tr() (domid.trainers.trainer_sdcn.trainersdcn method)": [[9, "domid.trainers.trainer_sdcn.TrainerSDCN.before_tr"]], "domid.trainers": [[9, "module-domid.trainers"]], "domid.trainers.pretraining_gmm": [[9, "module-domid.trainers.pretraining_GMM"]], "domid.trainers.pretraining_kmeans": [[9, "module-domid.trainers.pretraining_KMeans"]], "domid.trainers.pretraining_sdcn": [[9, "module-domid.trainers.pretraining_sdcn"]], "domid.trainers.trainer_ae": [[9, "module-domid.trainers.trainer_ae"]], "domid.trainers.trainer_cluster": [[9, "module-domid.trainers.trainer_cluster"]], "domid.trainers.trainer_sdcn": [[9, "module-domid.trainers.trainer_sdcn"]], "domid.trainers.zoo_trainer": [[9, "module-domid.trainers.zoo_trainer"]], "init_business() (domid.trainers.trainer_ae.trainerae method)": [[9, "domid.trainers.trainer_ae.TrainerAE.init_business"]], "init_business() (domid.trainers.trainer_cluster.trainercluster method)": [[9, "domid.trainers.trainer_cluster.TrainerCluster.init_business"]], "init_business() (domid.trainers.trainer_sdcn.trainersdcn method)": [[9, "domid.trainers.trainer_sdcn.TrainerSDCN.init_business"]], "kmeans_cluster_assignement() (domid.trainers.pretraining_sdcn.pretrainingsdcn method)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN.kmeans_cluster_assignement"]], "model_fit() (domid.trainers.pretraining_kmeans.pretraining method)": [[9, "domid.trainers.pretraining_KMeans.Pretraining.model_fit"]], "model_fit() (domid.trainers.pretraining_sdcn.pretrainingsdcn method)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN.model_fit"]], "post_tr() (domid.trainers.trainer_ae.trainerae method)": [[9, "domid.trainers.trainer_ae.TrainerAE.post_tr"]], "post_tr() (domid.trainers.trainer_cluster.trainercluster method)": [[9, "domid.trainers.trainer_cluster.TrainerCluster.post_tr"]], "post_tr() (domid.trainers.trainer_sdcn.trainersdcn method)": [[9, "domid.trainers.trainer_sdcn.TrainerSDCN.post_tr"]], "pretrain_loss() (domid.trainers.pretraining_gmm.pretraining method)": [[9, "domid.trainers.pretraining_GMM.Pretraining.pretrain_loss"]], "pretrain_loss() (domid.trainers.pretraining_kmeans.pretraining method)": [[9, "domid.trainers.pretraining_KMeans.Pretraining.pretrain_loss"]], "pretrain_loss() (domid.trainers.pretraining_sdcn.pretrainingsdcn method)": [[9, "domid.trainers.pretraining_sdcn.PretrainingSDCN.pretrain_loss"]], "tr_epoch() (domid.trainers.trainer_ae.trainerae method)": [[9, "domid.trainers.trainer_ae.TrainerAE.tr_epoch"]], "tr_epoch() (domid.trainers.trainer_cluster.trainercluster method)": [[9, "domid.trainers.trainer_cluster.TrainerCluster.tr_epoch"]], "tr_epoch() (domid.trainers.trainer_sdcn.trainersdcn method)": [[9, "domid.trainers.trainer_sdcn.TrainerSDCN.tr_epoch"]], "perfcluster (class in domid.utils.perf_cluster)": [[10, "domid.utils.perf_cluster.PerfCluster"]], "perfcorrelationher2 (class in domid.utils.perf_similarity)": [[10, "domid.utils.perf_similarity.PerfCorrelationHER2"]], "storing (class in domid.utils.storing)": [[10, "domid.utils.storing.Storing"]], "__init__() (domid.utils.perf_cluster.perfcluster method)": [[10, "domid.utils.perf_cluster.PerfCluster.__init__"]], "__init__() (domid.utils.perf_similarity.perfcorrelationher2 method)": [[10, "domid.utils.perf_similarity.PerfCorrelationHER2.__init__"]], "__init__() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.__init__"]], "cal_acc() (domid.utils.perf_cluster.perfcluster class method)": [[10, "domid.utils.perf_cluster.PerfCluster.cal_acc"]], "cal_acc() (domid.utils.perf_similarity.perfcorrelationher2 class method)": [[10, "domid.utils.perf_similarity.PerfCorrelationHER2.cal_acc"]], "csv_dump() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.csv_dump"]], "domid.utils": [[10, "module-domid.utils"]], "domid.utils.mean_std": [[10, "module-domid.utils.mean_std"]], "domid.utils.perf_cluster": [[10, "module-domid.utils.perf_cluster"]], "domid.utils.perf_similarity": [[10, "module-domid.utils.perf_similarity"]], "domid.utils.storing": [[10, "module-domid.utils.storing"]], "hungarian_algorithm() (domid.utils.perf_cluster.perfcluster class method)": [[10, "domid.utils.perf_cluster.PerfCluster.hungarian_algorithm"]], "run() (in module domid.utils.mean_std)": [[10, "domid.utils.mean_std.run"]], "run2() (in module domid.utils.mean_std)": [[10, "domid.utils.mean_std.run2"]], "saving_model() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.saving_model"]], "storing() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.storing"]], "storing_z_space() (domid.utils.storing.storing method)": [[10, "domid.utils.storing.Storing.storing_z_space"]]}}) \ No newline at end of file diff --git a/docs/domid.algos.rst b/docs/domid.algos.rst index 4b0553d..c04dc2f 100644 --- a/docs/domid.algos.rst +++ b/docs/domid.algos.rst @@ -44,6 +44,14 @@ domid.algos.builder\_vade module :undoc-members: :show-inheritance: +domid.algos.zoo\_algos module +----------------------------- + +.. automodule:: domid.algos.zoo_algos + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/docs/domid.rst b/docs/domid.rst index a385d59..1515987 100644 --- a/docs/domid.rst +++ b/docs/domid.rst @@ -27,6 +27,14 @@ domid.arg\_parser module :undoc-members: :show-inheritance: +domid.mk\_exp module +-------------------- + +.. automodule:: domid.mk_exp + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/docs/domid.tests.rst b/docs/domid.tests.rst index 4dce672..40dfc5b 100644 --- a/docs/domid.tests.rst +++ b/docs/domid.tests.rst @@ -52,6 +52,14 @@ domid.tests.test\_model\_trainer module :undoc-members: :show-inheritance: +domid.tests.utils module +------------------------ + +.. automodule:: domid.tests.utils + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/docs/domid.trainers.rst b/docs/domid.trainers.rst index c317e8f..830ac03 100644 --- a/docs/domid.trainers.rst +++ b/docs/domid.trainers.rst @@ -52,6 +52,14 @@ domid.trainers.trainer\_sdcn module :undoc-members: :show-inheritance: +domid.trainers.zoo\_trainer module +---------------------------------- + +.. automodule:: domid.trainers.zoo_trainer + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/domid/mk_exp.py b/domid/mk_exp.py index e26a837..3514e73 100644 --- a/domid/mk_exp.py +++ b/domid/mk_exp.py @@ -19,7 +19,6 @@ def mk_exp( ): """ Creates a custom experiment. The user can specify the input parameters. - :param task: use a predefined task in DomId, or create a task to a custom dataset. For more explanation on the input params refer to the documentation found in "domainlab.tasks.task_dset.py". :param model: create a model [NameOfModel] by importing the appropriate "mk_[NameOfModel]". For a concrete example

    Source code for domid.algos.builder_ae

    -import datetime
    -
    -from domainlab.algos.a_algo_builder import NodeAlgoBuilder
    -from domainlab.algos.msels.c_msel import MSelTrLoss
    +from domainlab.algos.a_algo_builder import NodeAlgoBuilder
     from domainlab.algos.msels.c_msel_oracle import MSelOracleVisitor
    +from domainlab.algos.msels.c_msel_val import MSelValPerf
     from domainlab.algos.observers.c_obvisitor_cleanup import ObVisitorCleanUp
     from domainlab.utils.utils_cuda import get_device
    -from tensorboardX import SummaryWriter
     
     from domid.algos.observers.b_obvisitor_clustering_only import ObVisitorClusteringOnly
    -from domid.models.model_ae import ModelAE
    -from domid.trainers.trainer_ae import TrainerCluster
    +from domid.models.model_ae import mk_ae
    +from domid.trainers.zoo_trainer import TrainerChainNodeGetter
     
     
     
    [docs]class NodeAlgoBuilderAE(NodeAlgoBuilder): @@ -330,31 +327,35 @@

    Source code for domid.algos.b """ task = exp.task args = exp.args - device = get_device(args) zd_dim = args.zd_dim d_dim = args.d_dim L = args.L - pretrain = args.pre_tr > 0 - - now = "zd_dim_" + str(zd_dim) + "_lr_" + str(args.lr) + "_" + str(datetime.datetime.now()) - model = ModelAE( + model = mk_ae()( zd_dim=zd_dim, d_dim=d_dim, device=device, - L=L, i_c=task.isize.c, i_h=task.isize.h, i_w=task.isize.w, - args=args, + bs=args.bs, + prior=args.prior, + random_batching=args.random_batching, + model_method=args.model_method, + pre_tr_weight_path=args.pre_tr_weight_path, + feat_extract=args.feat_extract, ) - observer = ObVisitorCleanUp(ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelTrLoss(max_es=args.es)), device)) - writer = SummaryWriter(logdir="debug/" + now) - trainer = TrainerCluster(model, task, observer, device, writer, pretrain=pretrain, aconf=args) - return trainer

    + observer = ObVisitorCleanUp( + ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelValPerf(max_es=args.es)), device) + ) + + trainer = TrainerChainNodeGetter(args.trainer)() + trainer.init_business(model, task, observer, device, args) + + return trainer, model, observer, device
    [docs]def get_node_na(): diff --git a/docs/build/html/_modules/domid/algos/builder_dec.html b/docs/build/html/_modules/domid/algos/builder_dec.html index 271a871..58a3202 100644 --- a/docs/build/html/_modules/domid/algos/builder_dec.html +++ b/docs/build/html/_modules/domid/algos/builder_dec.html @@ -309,18 +309,15 @@

    Source code for domid.algos.builder_dec

    -import datetime
    -
    -from domainlab.algos.a_algo_builder import NodeAlgoBuilder
    -from domainlab.algos.msels.c_msel import MSelTrLoss
    +from domainlab.algos.a_algo_builder import NodeAlgoBuilder
     from domainlab.algos.msels.c_msel_oracle import MSelOracleVisitor
    +from domainlab.algos.msels.c_msel_val import MSelValPerf
     from domainlab.algos.observers.c_obvisitor_cleanup import ObVisitorCleanUp
     from domainlab.utils.utils_cuda import get_device
    -from tensorboardX import SummaryWriter
     
     from domid.algos.observers.b_obvisitor_clustering_only import ObVisitorClusteringOnly
    -from domid.models.model_dec import ModelDEC
    -from domid.trainers.trainer_cluster import TrainerCluster
    +from domid.models.model_dec import mk_dec
    +from domid.trainers.zoo_trainer import TrainerChainNodeGetter
     
     
     
    [docs]class NodeAlgoBuilderDEC(NodeAlgoBuilder): @@ -335,26 +332,30 @@

    Source code for domid.algos. zd_dim = args.zd_dim d_dim = args.d_dim L = args.L - pretrain = False - if args.pre_tr > 0: - pretrain = True - now = "zd_dim_" + str(zd_dim) + "_lr_" + str(args.lr) + "_" + str(datetime.datetime.now()) - model = ModelDEC( + model = mk_dec()( zd_dim=zd_dim, d_dim=d_dim, device=device, - L=L, i_c=task.isize.c, i_h=task.isize.h, i_w=task.isize.w, - args=args, + bs=args.bs, + prior=args.prior, + random_batching=args.random_batching, + model_method=args.model_method, + pre_tr_weight_path=args.pre_tr_weight_path, + feat_extract=args.feat_extract, + ) + + observer = ObVisitorCleanUp( + ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelValPerf(max_es=args.es)), device) ) - observer = ObVisitorCleanUp(ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelTrLoss(max_es=args.es)), device)) - writer = SummaryWriter(logdir="debug/" + now) - trainer = TrainerCluster(model, task, observer, device, writer, pretrain=pretrain, aconf=args) - return trainer

    + trainer = TrainerChainNodeGetter(args.trainer)() + trainer.init_business(model, task, observer, device, args) + + return trainer, model, observer, device
    [docs]def get_node_na(): diff --git a/docs/build/html/_modules/domid/algos/builder_m2yd.html b/docs/build/html/_modules/domid/algos/builder_m2yd.html index d85c198..d13171e 100644 --- a/docs/build/html/_modules/domid/algos/builder_m2yd.html +++ b/docs/build/html/_modules/domid/algos/builder_m2yd.html @@ -310,14 +310,15 @@

    Source code for domid.algos.builder_m2yd

     from domainlab.algos.a_algo_builder import NodeAlgoBuilder
    -from domainlab.algos.msels.c_msel import MSelTrLoss
     from domainlab.algos.msels.c_msel_oracle import MSelOracleVisitor
    +from domainlab.algos.msels.c_msel_val import MSelValPerf
     from domainlab.algos.observers.c_obvisitor_cleanup import ObVisitorCleanUp
    -from domainlab.algos.trainers.train_basic import TrainerBasic
     from domainlab.utils.utils_cuda import get_device
     
     from domid.algos.observers.b_obvisitor_clustering import ObVisitorClustering
    -from domid.models.model_m2yd import ModelXY2D
    +from domid.algos.observers.b_obvisitor_clustering_only import ObVisitorClusteringOnly
    +from domid.models.model_m2yd import mk_m2yd
    +from domid.trainers.zoo_trainer import TrainerChainNodeGetter
     
     
     
    [docs]class NodeAlgoBuilderM2YD(NodeAlgoBuilder): @@ -328,7 +329,7 @@

    Source code for domid.algos task = exp.task args = exp.args device = get_device(args) - model = ModelXY2D( + model = mk_m2yd()( y_dim=len(task.list_str_y), list_str_y=task.list_str_y, zd_dim=args.zd_dim, @@ -338,10 +339,16 @@

    Source code for domid.algos i_h=task.isize.h, i_w=task.isize.w, ) - observer = ObVisitorCleanUp(ObVisitorClustering(exp, MSelOracleVisitor(MSelTrLoss(max_es=args.es)), device)) - trainer = TrainerBasic() + + observer = ObVisitorCleanUp( + ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelValPerf(max_es=args.es)), device) + ) + # FIXME: may need to be ObVisitorClustering instead of ObVisitorClusteringOnly... + + trainer = TrainerChainNodeGetter(args.trainer)() trainer.init_business(model, task, observer, device, args) - return trainer

    + + return trainer, model, observer, device
    [docs]def get_node_na(): diff --git a/docs/build/html/_modules/domid/algos/builder_sdcn.html b/docs/build/html/_modules/domid/algos/builder_sdcn.html index 1bf0942..d032ce1 100644 --- a/docs/build/html/_modules/domid/algos/builder_sdcn.html +++ b/docs/build/html/_modules/domid/algos/builder_sdcn.html @@ -309,18 +309,15 @@

    Source code for domid.algos.builder_sdcn

    -import datetime
    -
    -from domainlab.algos.a_algo_builder import NodeAlgoBuilder
    -from domainlab.algos.msels.c_msel import MSelTrLoss
    +from domainlab.algos.a_algo_builder import NodeAlgoBuilder
     from domainlab.algos.msels.c_msel_oracle import MSelOracleVisitor
    +from domainlab.algos.msels.c_msel_val import MSelValPerf
     from domainlab.algos.observers.c_obvisitor_cleanup import ObVisitorCleanUp
     from domainlab.utils.utils_cuda import get_device
    -from tensorboardX import SummaryWriter
     
     from domid.algos.observers.b_obvisitor_clustering_only import ObVisitorClusteringOnly
    -from domid.models.model_sdcn import ModelSDCN
    -from domid.trainers.trainer_sdcn import TrainerCluster
    +from domid.models.model_sdcn import mk_sdcn
    +from domid.trainers.zoo_trainer import TrainerChainNodeGetter
     
     
     
    [docs]class NodeAlgoBuilderSDCN(NodeAlgoBuilder): @@ -336,26 +333,29 @@

    Source code for domid.algos zd_dim = args.zd_dim d_dim = args.d_dim L = args.L - pretrain = False - if args.pre_tr > 0: - pretrain = True - - now = "zd_dim_" + str(zd_dim) + "_lr_" + str(args.lr) + "_" + str(datetime.datetime.now()) - model = ModelSDCN( + model = mk_sdcn()( zd_dim=zd_dim, d_dim=d_dim, device=device, - L=L, i_c=task.isize.c, i_h=task.isize.h, i_w=task.isize.w, - args=args, + bs=args.bs, + task=args.task, + prior=args.prior, + random_batching=args.random_batching, + model_method=args.model_method, + pre_tr_weight_path=args.pre_tr_weight_path, + feat_extract=args.feat_extract, + ) + + observer = ObVisitorCleanUp( + ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelValPerf(max_es=args.es)), device) ) - observer = ObVisitorCleanUp(ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelTrLoss(max_es=args.es)), device)) - writer = SummaryWriter(logdir="debug/" + now) - trainer = TrainerCluster(model, task, observer, device, writer, pretrain=pretrain, aconf=args) + trainer = TrainerChainNodeGetter(args.trainer)() + trainer.init_business(model, task, observer, device, args) - return trainer

    + return trainer, model, observer, device
    [docs]def get_node_na(): diff --git a/docs/build/html/_modules/domid/algos/builder_vade.html b/docs/build/html/_modules/domid/algos/builder_vade.html index 4e40e67..72ccb8c 100644 --- a/docs/build/html/_modules/domid/algos/builder_vade.html +++ b/docs/build/html/_modules/domid/algos/builder_vade.html @@ -309,18 +309,15 @@

    Source code for domid.algos.builder_vade

    -import datetime
    -
    -from domainlab.algos.a_algo_builder import NodeAlgoBuilder
    -from domainlab.algos.msels.c_msel import MSelTrLoss
    +from domainlab.algos.a_algo_builder import NodeAlgoBuilder
     from domainlab.algos.msels.c_msel_oracle import MSelOracleVisitor
    +from domainlab.algos.msels.c_msel_val import MSelValPerf
     from domainlab.algos.observers.c_obvisitor_cleanup import ObVisitorCleanUp
     from domainlab.utils.utils_cuda import get_device
    -from tensorboardX import SummaryWriter
     
     from domid.algos.observers.b_obvisitor_clustering_only import ObVisitorClusteringOnly
    -from domid.models.model_vade import ModelVaDE
    -from domid.trainers.trainer_cluster import TrainerCluster
    +from domid.models.model_vade import mk_vade
    +from domid.trainers.zoo_trainer import TrainerChainNodeGetter
     
     
     
    [docs]class NodeAlgoBuilderVaDE(NodeAlgoBuilder): @@ -336,26 +333,32 @@

    Source code for domid.algos zd_dim = args.zd_dim d_dim = args.d_dim L = args.L - pretrain = False - if args.pre_tr > 0: - pretrain = True - now = "zd_dim_" + str(zd_dim) + "_lr_" + str(args.lr) + "_" + str(datetime.datetime.now()) - model = ModelVaDE( + model = mk_vade()( zd_dim=zd_dim, d_dim=d_dim, device=device, - L=L, i_c=task.isize.c, i_h=task.isize.h, i_w=task.isize.w, - args=args, + bs=args.bs, + L=L, + dim_inject_y=args.dim_inject_y, + prior=args.prior, + random_batching=args.random_batching, + model_method=args.model_method, + pre_tr_weight_path=args.pre_tr_weight_path, + feat_extract=args.feat_extract, ) - observer = ObVisitorCleanUp(ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelTrLoss(max_es=args.es)), device)) - writer = SummaryWriter(logdir="debug/" + now) - trainer = TrainerCluster(model, task, observer, device, writer, pretrain=pretrain, aconf=args) - return trainer

    + observer = ObVisitorCleanUp( + ObVisitorClusteringOnly(exp, MSelOracleVisitor(MSelValPerf(max_es=args.es)), device) + ) + + trainer = TrainerChainNodeGetter(args.trainer)() + trainer.init_business(model, task, observer, device, args) + + return trainer, model, observer, device
    [docs]def get_node_na(): diff --git a/docs/build/html/_modules/domid/arg_parser.html b/docs/build/html/_modules/domid/arg_parser.html index 17ced57..d535aff 100644 --- a/docs/build/html/_modules/domid/arg_parser.html +++ b/docs/build/html/_modules/domid/arg_parser.html @@ -321,6 +321,7 @@

    Source code for domid.arg_parserSource code for domid.arg_parserSource code for domid.arg_parser

    Source code for domid.compos.cnn_AE

    -import numpy as np
    -import torch
    +import torch
     import torch.nn as nn
     import torch.nn.functional as F
     
    @@ -344,6 +343,13 @@ 

    Source code for domid.compos.cnn self.bsnorm2 = nn.BatchNorm2d(num_filters[1]) self.bsnorm3 = nn.BatchNorm2d(num_filters[2])

    +
    [docs] def get_z(self, x): + *_, z = self.forward(x) + return z
    + +
    [docs] def get_log_sigma2(self, x): + return None
    +
    [docs] def forward(self, x): """ :param x: input data diff --git a/docs/build/html/_modules/domid/compos/cnn_VAE.html b/docs/build/html/_modules/domid/compos/cnn_VAE.html index bc3e1e2..81b947e 100644 --- a/docs/build/html/_modules/domid/compos/cnn_VAE.html +++ b/docs/build/html/_modules/domid/compos/cnn_VAE.html @@ -309,8 +309,7 @@

    Source code for domid.compos.cnn_VAE

    -import numpy as np
    -import torch.nn as nn
    +import torch.nn as nn
     
     from domid.compos.VAE_blocks import UnFlatten, get_output_shape
     
    @@ -341,6 +340,14 @@ 

    Source code for domid.compos.cn self.mu_layer = nn.Linear(self.h_dim, zd_dim) self.log_sigma2_layer = nn.Linear(self.h_dim, zd_dim)

    +
    [docs] def get_z(self, x): + mu, _ = self.forward(x) + return mu
    + +
    [docs] def get_log_sigma2(self, x): + _, log_sigma2 = self.forward(x) + return log_sigma2
    +
    [docs] def forward(self, x): """ :param x: input data diff --git a/docs/build/html/_modules/domid/compos/linear_AE.html b/docs/build/html/_modules/domid/compos/linear_AE.html index 8b4c476..a4849ad 100644 --- a/docs/build/html/_modules/domid/compos/linear_AE.html +++ b/docs/build/html/_modules/domid/compos/linear_AE.html @@ -309,13 +309,9 @@

    Source code for domid.compos.linear_AE

    -import numpy as np
    -import torch
    -import torch.nn as nn
    +import torch.nn as nn
     import torch.nn.functional as F
     
    -from domid.compos.VAE_blocks import linear_block
    -
     
     
    [docs]class LinearEncoderAE(nn.Module):
    [docs] def __init__(self, n_enc_1, n_enc_2, n_enc_3, n_input, n_z): @@ -325,6 +321,13 @@

    Source code for domid.compos. self.enc_3 = nn.Linear(n_enc_2, n_enc_3) self.z_layer = nn.Linear(n_enc_3, n_z)

    +
    [docs] def get_z(self, x): + *_, z = self.forward(x) + return z
    + +
    [docs] def get_log_sigma2(self, x): + return None
    +
    [docs] def forward(self, x): enc_h1 = F.relu(self.enc_1(x)) enc_h2 = F.relu(self.enc_2(enc_h1)) diff --git a/docs/build/html/_modules/domid/compos/linear_VAE.html b/docs/build/html/_modules/domid/compos/linear_VAE.html index fc904f7..23acaec 100644 --- a/docs/build/html/_modules/domid/compos/linear_VAE.html +++ b/docs/build/html/_modules/domid/compos/linear_VAE.html @@ -335,6 +335,14 @@

    Source code for domid.compos self.mu_layer = nn.Linear(features_dim[2], zd_dim) self.log_sigma2_layer = nn.Linear(features_dim[2], zd_dim)

    +
    [docs] def get_z(self, x): + mu, log_sigma2 = self.forward(x) + return mu
    + +
    [docs] def get_log_sigma2(self, x): + mu, log_sigma2 = self.forward(x) + return log_sigma2
    +
    [docs] def forward(self, x): """ :param x: input data, assumed to have 3 channels diff --git a/docs/build/html/_modules/domid/compos/predict_basic.html b/docs/build/html/_modules/domid/compos/predict_basic.html index b621e0f..0c90f6d 100644 --- a/docs/build/html/_modules/domid/compos/predict_basic.html +++ b/docs/build/html/_modules/domid/compos/predict_basic.html @@ -337,9 +337,11 @@

    Source code for domid.com :return: image acquisition machine labels for the input images (when applicable/available) """ - num_img = len(self.loader_tr.dataset) # FIXME: this returns sample size + 1 for some reason - if self.model.args.task == "wsi" and self.model.args.aname == "sdcn": - num_img = int(self.model.args.bs / 3) + num_img = len(self.loader_tr.dataset) + + if self.model.random_batching: + bs = next(iter(self.loader_tr))[0].shape[0] + num_img = int(bs / 3 * num_img) z_proj = np.zeros((num_img, self.model.zd_dim)) prob_proj = np.zeros((num_img, self.model.d_dim)) input_imgs = np.zeros((num_img, 3, self.i_h, self.i_w)) @@ -358,15 +360,16 @@

    Source code for domid.com if len(inject_tensor) > 0: inject_tensor = inject_tensor.to(self.device) - if self.model.args.random_batching: + if self.model.random_batching: patches_idx = self.model.random_ind[i] # torch.randint(0, len(vec_y), (int(self.args.bs/3),)) tensor_x = tensor_x[patches_idx, :, :, :] vec_y = vec_y[patches_idx, :] vec_d = vec_d[patches_idx, :] image_id = [image_id[patch_idx_num] for patch_idx_num in patches_idx] - self.model.adj = GraphConstructorWSI().construct_graph( - tensor_x, image_id, self.model.graph_method, None + adj_mx, spar_mx = GraphConstructorWSI(self.model.graph_method).construct_graph( + tensor_x, image_id, None ) + self.model.adj = spar_mx for ii in range(0, tensor_x.shape[0]): @@ -380,12 +383,11 @@

    Source code for domid.com vec_d.to(self.device), ) - if self.model.args.aname != "sdcn": + if self.model.model != "sdcn": results = self.model.infer_d_v_2(tensor_x, inject_tensor) else: results = self.model.infer_d_v_2(tensor_x) preds, z, probs, x_pro = results[0], results[1], results[-2], results[-1] - z = z.detach().cpu().numpy() # [batch_size, zd_dim] input_imgs[counter : counter + tensor_x.shape[0], :, :, :] = tensor_x.cpu().detach().numpy() z_proj[counter : counter + tensor_x.shape[0], :] = z @@ -394,7 +396,7 @@

    Source code for domid.com preds = preds.detach().cpu() # domain_labels[counter : counter + z.shape[0], 0] = torch.argmax(preds, 1) + 1 predictions += (torch.argmax(preds, 1) + 1).tolist() - counter += z.shape[0] + counter += tensor_x.shape[0] return input_imgs, z_proj, predictions, vec_y_labels, vec_d_labels, image_id_labels

    diff --git a/docs/build/html/_modules/domid/compos/tensorboard_fun.html b/docs/build/html/_modules/domid/compos/tensorboard_fun.html index 2cb726a..9ed96a3 100644 --- a/docs/build/html/_modules/domid/compos/tensorboard_fun.html +++ b/docs/build/html/_modules/domid/compos/tensorboard_fun.html @@ -309,9 +309,7 @@

    Source code for domid.compos.tensorboard_fun

    -import numpy as np
    -import tensorboardX
    -import torch
    +import torch
     
     
     
    [docs]def tensorboard_write( @@ -327,49 +325,50 @@

    Source code for domid.c inject_tensor=None, other_info=None, ): - writer.add_scalar("learning rate", lr, epoch) - writer.add_scalar("warmup", warmup_beta, epoch) - if not pretraining_finished: - writer.add_scalar("Pretraining", acc_tr, epoch) - writer.add_scalar("Pretraining Loss", loss, epoch) - else: - writer.add_scalar("Training acc", acc_tr, epoch) - writer.add_scalar("Loss", loss, epoch) + if lr > 2: + writer.add_scalar("learning rate", lr, epoch) + writer.add_scalar("warmup", warmup_beta, epoch) + if not pretraining_finished: + writer.add_scalar("Pretraining", acc_tr, epoch) + writer.add_scalar("Pretraining Loss", loss, epoch) + else: + writer.add_scalar("Training acc", acc_tr, epoch) + writer.add_scalar("Loss", loss, epoch) - if not pretraining_finished: - name = "Output of the decoder pretraining" - else: - name = "Output of the decoder training" + if not pretraining_finished: + name = "Output of the decoder pretraining" + else: + name = "Output of the decoder training" - if other_info is not None and epoch > 3: - kl_total, ce_total, re_total = other_info - writer.add_scalar("KL", kl_total, epoch) - writer.add_scalar("CE", ce_total, epoch) - writer.add_scalar("RE", re_total, epoch) + if other_info is not None and epoch > 3: + kl_total, ce_total, re_total = other_info + writer.add_scalar("KL", kl_total, epoch) + writer.add_scalar("CE", ce_total, epoch) + writer.add_scalar("RE", re_total, epoch) - if inject_tensor is not None: - preds, *_, x_pro = model.infer_d_v_2(tensor_x, inject_tensor) - else: - preds, *_, x_pro = model.infer_d_v_2(tensor_x) + if inject_tensor is not None: + preds, *_, x_pro = model.infer_d_v_2(tensor_x, inject_tensor) + else: + preds, *_, x_pro = model.infer_d_v_2(tensor_x) - if len(x_pro.shape) < 3: - x_pro = torch.reshape(x_pro, (x_pro.shape[0], tensor_x.shape[1], tensor_x.shape[2], tensor_x.shape[3])) + if len(x_pro.shape) < 3: + x_pro = torch.reshape(x_pro, (x_pro.shape[0], tensor_x.shape[1], tensor_x.shape[2], tensor_x.shape[3])) - imgs = torch.cat( - ( - tensor_x[0:8, :, :, :], - x_pro[0:8, :, :, :], - ), - 0, - ) + imgs = torch.cat( + ( + tensor_x[0:8, :, :, :], + x_pro[0:8, :, :, :], + ), + 0, + ) - # mse = torch.nn.MSELoss()#(dim=1, eps=1e-08) - # sample1 = tensor_x[0, :, :, :].flatten().unsqueeze(0) - # sample2 = x_pro[0, :, :, :].flatten().unsqueeze(0) - # # acc_ = torch.mean(torch.abs(sample1-sample2)/sample1) + # mse = torch.nn.MSELoss()#(dim=1, eps=1e-08) + # sample1 = tensor_x[0, :, :, :].flatten().unsqueeze(0) + # sample2 = x_pro[0, :, :, :].flatten().unsqueeze(0) + # # acc_ = torch.mean(torch.abs(sample1-sample2)/sample1) - # print('SIMILARITY', acc_) - writer.add_images(name, imgs, epoch)

    + # print('SIMILARITY', acc_) + writer.add_images(name, imgs, epoch)
    diff --git a/docs/build/html/_modules/domid/dsets/a_dset_mnist_color_rgb_solo.html b/docs/build/html/_modules/domid/dsets/a_dset_mnist_color_rgb_solo.html index d8cd236..f9b5f63 100644 --- a/docs/build/html/_modules/domid/dsets/a_dset_mnist_color_rgb_solo.html +++ b/docs/build/html/_modules/domid/dsets/a_dset_mnist_color_rgb_solo.html @@ -547,7 +547,7 @@

    Source code if self.inject_variable: inject_tensor = self.df.loc[df_idx, self.inject_variable] - inject_tensor = mk_fun_label2onehot(self.inject_dim)(inject_tensor) + inject_tensor = mk_fun_label2onehot(self.inject_dim)(int(inject_tensor)) else: inject_tensor = [] diff --git a/docs/build/html/_modules/domid/dsets/make_graph.html b/docs/build/html/_modules/domid/dsets/make_graph.html index e7936ae..a23e22b 100644 --- a/docs/build/html/_modules/domid/dsets/make_graph.html +++ b/docs/build/html/_modules/domid/dsets/make_graph.html @@ -312,21 +312,14 @@

    Source code for domid.dsets.m import os import pickle -import matplotlib.pyplot as plt -import networkx as nx import numpy as np -import pandas as pd import scipy.sparse as sp import torch from sklearn.metrics import pairwise_distances as pair -from sklearn.metrics.pairwise import cosine_similarity as cos from sklearn.preprocessing import normalize -from torch.utils.data import Dataset -from torchvision import datasets, transforms
    [docs]class GraphConstructor: - """ Class to construct graph from features. This is only used in training for SDCN model. """ @@ -408,7 +401,6 @@

    Source code for domid.dsets.m """ dist = self.distance_calc(features) - connection_pairs = [] inds = [] for i in range(dist.shape[0]): @@ -469,11 +461,11 @@

    Source code for domid.dsets.m sparse_mx = self.sparse_mx_to_torch_sparse_tensor(adj_mat) sparse_matrices.append(sparse_mx) if experiment_folder is not None: - connect_path = ( - os.path.join("notebooks/", experiment_folder) + "/connection_pairs_" + str(i) + ".pkl" + connect_path = os.path.join( + "notebooks", experiment_folder, "connection_pairs_" + str(i) + ".pkl" ) # FIXME move to zout - feat_path = os.path.join("notebooks/", experiment_folder) + "/features_" + str(i) + ".pkl" - label_path = os.path.join("notebooks/", experiment_folder) + "/labels_" + str(i) + ".pkl" + feat_path = os.path.join("notebooks", experiment_folder, "features_" + str(i) + ".pkl") + label_path = os.path.join("notebooks", experiment_folder, "labels_" + str(i) + ".pkl") with open(connect_path, "wb") as file: pickle.dump(connection_pairs, file) diff --git a/docs/build/html/_modules/domid/models/a_model_cluster.html b/docs/build/html/_modules/domid/models/a_model_cluster.html index 155a685..2ed3f3b 100644 --- a/docs/build/html/_modules/domid/models/a_model_cluster.html +++ b/docs/build/html/_modules/domid/models/a_model_cluster.html @@ -309,8 +309,11 @@

    Source code for domid.models.a_model_cluster

    -import torch
    +import abc
    +
    +import torch
     import torch.nn as nn
    +import torch.nn.functional as F
     
     from domid.utils.perf_cluster import PerfCluster
     
    @@ -320,6 +323,10 @@ 

    Source code for domid.m Operations that all clustering models should have """ +
    [docs] def __init__(self): + super(AModelCluster, self).__init__() + self._decoratee = None # FIXME do i pass it to every model?
    +
    [docs] def create_perf_obj(self, task): """ Sets up the performance metrics used. @@ -346,7 +353,76 @@

    Source code for domid.m with torch.no_grad(): r_score_tr, r_score_te = self.task.calc_corr(self, loader_tr, loader_te, device) - return metric_tr, metric_te, r_score_tr, r_score_te

    + return metric_tr, metric_te, r_score_tr, r_score_te

    + +
    [docs] def cal_loss(self, tensor_x, inj_tensor=torch.Tensor([]), warmup_beta=None): + """ + Calculates the loss for the model. + """ + total_loss = self._cal_reconstruction_loss(tensor_x, inj_tensor) + # if self._decoratee is not None: + + kl_loss = self._cal_kl_loss(tensor_x, inj_tensor) + + total_loss += kl_loss + return total_loss
    + +
    [docs] def infer_d_v(self, x): + """ + Predict the cluster/domain of the input data. + Corresponds to equation (16) in the paper. + + :param tensor x: Input tensor of a shape [batchsize, 3, horzintal dim, vertical dim]. + :return tensor preds: One hot encoded tensor of the predicted cluster assignment. + """ + preds, *_ = self._inference(x) + return preds.cpu().detach()
    + +
    [docs] def extend(self, model): + """ + extend the loss of the decoratee + """ + self._decoratee = model
    + + def _extend_loss(self, tensor_x, tensor_y, tensor_d, others=None): + """ + combine losses from two models + """ + if self._decoratee is not None: + return self._decoratee._cal_kl_loss(tensor_x, tensor_y, tensor_d, others) + return None, None + + @abc.abstractmethod + def _cal_pretrain_loss(self, tensor_x, inject_tensor=torch.Tensor([])): + """ + Pretraining loss for the model. + """ + return self._cal_reconstruction_loss(tensor_x, inject_tensor) + + def _cal_reconstruction_loss(self, tensor_x, inject_domain=torch.Tensor([])): + + if self.model_method == "linear": + tensor_x = torch.reshape(tensor_x, (tensor_x.shape[0], -1)) + z = self.encoder.get_z(tensor_x) + + if len(inject_domain) > 0: + zy = torch.cat((z, inject_domain), 1) + else: + zy = z + + x_pro = self.decoder(zy) + + if isinstance(x_pro, tuple): + x_pro = x_pro[0] + + loss = F.mse_loss(x_pro, tensor_x) + + return loss + + @abc.abstractmethod + def _cal_kl_loss(self, q, p): # FIXME KL loss is different for each of the model, redefined it in every model? + + return NotImplementedError