From 94b0ade926eadf561791768e25db7ea73b2819f5 Mon Sep 17 00:00:00 2001 From: Vrushank264 Date: Sat, 23 Sep 2023 02:27:25 -0300 Subject: [PATCH] Add code. --- .gitignore | 5 + README.md | 23 + Requirements | 9 + dataset/.DS_Store | Bin 0 -> 8196 bytes dataset/__init__.py | 0 dataset/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 151 bytes dataset/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 124 bytes dataset/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 143 bytes .../data_augmentation.cpython-36.pyc | Bin 0 -> 2678 bytes .../data_augmentation.cpython-37.pyc | Bin 0 -> 2682 bytes .../__pycache__/dataset_LIP.cpython-36.pyc | Bin 0 -> 2258 bytes dataset/__pycache__/datasets.cpython-310.pyc | Bin 0 -> 5872 bytes dataset/__pycache__/datasets.cpython-36.pyc | Bin 0 -> 5981 bytes dataset/__pycache__/datasets.cpython-37.pyc | Bin 0 -> 5995 bytes .../joint_transformation.cpython-36.pyc | Bin 0 -> 2437 bytes .../joint_transformation.cpython-37.pyc | Bin 0 -> 2378 bytes .../target_generation.cpython-310.pyc | Bin 0 -> 2387 bytes .../target_generation.cpython-36.pyc | Bin 0 -> 2292 bytes .../target_generation.cpython-37.pyc | Bin 0 -> 2311 bytes dataset/__pycache__/voc.cpython-36.pyc | Bin 0 -> 6112 bytes dataset/datasets.py | 259 ++++++++++++ dataset/list/.DS_Store | Bin 0 -> 6148 bytes dataset/target_generation.py | 82 ++++ engine.py | 133 ++++++ evaluate.py | 274 ++++++++++++ evaluate_multi.py | 252 +++++++++++ networks/.DS_Store | Bin 0 -> 6148 bytes networks/CDGNet.py | 334 +++++++++++++++ networks/__pycache__/CDGNet.cpython-310.pyc | Bin 0 -> 10894 bytes networks/__pycache__/CDGNet.cpython-36.pyc | Bin 0 -> 10920 bytes networks/__pycache__/CE2P.cpython-36.pyc | Bin 0 -> 10926 bytes networks/__pycache__/CE2P.cpython-37.pyc | Bin 0 -> 10874 bytes networks/__pycache__/CE2P.cpython-38.pyc | Bin 0 -> 10665 bytes .../__pycache__/CE2PHybrid.cpython-36.pyc | Bin 0 -> 7504 bytes networks/__pycache__/CE2P_test.cpython-36.pyc | Bin 0 -> 10949 bytes requirements.txt | 2 + run.sh | 38 ++ run_evaluate.sh | 18 + run_evaluate_multiScale.sh | 19 + sage_train.sh | 3 + trace_model.py | 120 ++++++ train.py | 359 ++++++++++++++++ train_simplified.py | 299 +++++++++++++ try.py | 148 +++++++ utils/.DS_Store | Bin 0 -> 6148 bytes utils/ImgTransforms.py | 394 ++++++++++++++++++ utils/__init__.py | 0 .../__pycache__/ImgTransforms.cpython-310.pyc | Bin 0 -> 13284 bytes .../__pycache__/ImgTransforms.cpython-36.pyc | Bin 0 -> 14429 bytes .../__pycache__/ImgTransforms.cpython-37.pyc | Bin 0 -> 14153 bytes utils/__pycache__/OCRAttention.cpython-36.pyc | Bin 0 -> 2180 bytes utils/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 149 bytes utils/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 122 bytes utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 141 bytes utils/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 135 bytes utils/__pycache__/attention.cpython-310.pyc | Bin 0 -> 9816 bytes utils/__pycache__/attention.cpython-36.pyc | Bin 0 -> 10138 bytes utils/__pycache__/attention.cpython-37.pyc | Bin 0 -> 9961 bytes utils/__pycache__/attention.cpython-38.pyc | Bin 0 -> 9982 bytes utils/__pycache__/criterion.cpython-310.pyc | Bin 0 -> 2615 bytes utils/__pycache__/criterion.cpython-36.pyc | Bin 0 -> 2562 bytes utils/__pycache__/criterion.cpython-37.pyc | Bin 0 -> 3861 bytes utils/__pycache__/distributed.cpython-36.pyc | Bin 0 -> 4445 bytes utils/__pycache__/distributed.cpython-37.pyc | Bin 0 -> 4449 bytes utils/__pycache__/encoding.cpython-36.pyc | Bin 0 -> 10084 bytes utils/__pycache__/encoding.cpython-37.pyc | Bin 0 -> 10094 bytes utils/__pycache__/logger.cpython-36.pyc | Bin 0 -> 2876 bytes utils/__pycache__/loss.cpython-310.pyc | Bin 0 -> 3096 bytes utils/__pycache__/loss.cpython-36.pyc | Bin 0 -> 3063 bytes utils/__pycache__/loss.cpython-37.pyc | Bin 0 -> 3080 bytes .../__pycache__/lovasz_losses.cpython-310.pyc | Bin 0 -> 7901 bytes .../__pycache__/lovasz_losses.cpython-36.pyc | Bin 0 -> 7826 bytes .../__pycache__/lovasz_losses.cpython-37.pyc | Bin 0 -> 7821 bytes utils/__pycache__/miou.cpython-310.pyc | Bin 0 -> 5692 bytes utils/__pycache__/miou.cpython-36.pyc | Bin 0 -> 5754 bytes utils/__pycache__/miou.cpython-37.pyc | Bin 0 -> 5768 bytes utils/__pycache__/model_store.cpython-36.pyc | Bin 0 -> 3539 bytes utils/__pycache__/pyt_utils.cpython-36.pyc | Bin 0 -> 7063 bytes utils/__pycache__/transforms.cpython-310.pyc | Bin 0 -> 2993 bytes utils/__pycache__/transforms.cpython-36.pyc | Bin 0 -> 2982 bytes utils/__pycache__/transforms.cpython-37.pyc | Bin 0 -> 2971 bytes utils/__pycache__/utils.cpython-310.pyc | Bin 0 -> 3630 bytes utils/__pycache__/utils.cpython-36.pyc | Bin 0 -> 2875 bytes utils/__pycache__/utils.cpython-37.pyc | Bin 0 -> 2869 bytes utils/attention.py | 276 ++++++++++++ utils/criterion.py | 114 +++++ utils/distributed.py | 165 ++++++++ utils/encode_masks.py | 39 ++ utils/encoding.py | 251 +++++++++++ utils/logger.py | 94 +++++ utils/loss.py | 93 +++++ utils/lovasz_losses.py | 250 +++++++++++ utils/miou.py | 204 +++++++++ utils/pyt_utils.py | 217 ++++++++++ utils/transforms.py | 113 +++++ utils/utils.py | 83 ++++ utils/writejson.py | 21 + 97 files changed, 4691 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 Requirements create mode 100644 dataset/.DS_Store create mode 100644 dataset/__init__.py create mode 100644 dataset/__pycache__/__init__.cpython-310.pyc create mode 100644 dataset/__pycache__/__init__.cpython-36.pyc create mode 100644 dataset/__pycache__/__init__.cpython-37.pyc create mode 100644 dataset/__pycache__/data_augmentation.cpython-36.pyc create mode 100644 dataset/__pycache__/data_augmentation.cpython-37.pyc create mode 100644 dataset/__pycache__/dataset_LIP.cpython-36.pyc create mode 100644 dataset/__pycache__/datasets.cpython-310.pyc create mode 100644 dataset/__pycache__/datasets.cpython-36.pyc create mode 100644 dataset/__pycache__/datasets.cpython-37.pyc create mode 100644 dataset/__pycache__/joint_transformation.cpython-36.pyc create mode 100644 dataset/__pycache__/joint_transformation.cpython-37.pyc create mode 100644 dataset/__pycache__/target_generation.cpython-310.pyc create mode 100644 dataset/__pycache__/target_generation.cpython-36.pyc create mode 100644 dataset/__pycache__/target_generation.cpython-37.pyc create mode 100644 dataset/__pycache__/voc.cpython-36.pyc create mode 100644 dataset/datasets.py create mode 100644 dataset/list/.DS_Store create mode 100644 dataset/target_generation.py create mode 100644 engine.py create mode 100644 evaluate.py create mode 100644 evaluate_multi.py create mode 100644 networks/.DS_Store create mode 100644 networks/CDGNet.py create mode 100644 networks/__pycache__/CDGNet.cpython-310.pyc create mode 100644 networks/__pycache__/CDGNet.cpython-36.pyc create mode 100644 networks/__pycache__/CE2P.cpython-36.pyc create mode 100644 networks/__pycache__/CE2P.cpython-37.pyc create mode 100644 networks/__pycache__/CE2P.cpython-38.pyc create mode 100644 networks/__pycache__/CE2PHybrid.cpython-36.pyc create mode 100644 networks/__pycache__/CE2P_test.cpython-36.pyc create mode 100644 requirements.txt create mode 100644 run.sh create mode 100644 run_evaluate.sh create mode 100644 run_evaluate_multiScale.sh create mode 100644 sage_train.sh create mode 100644 trace_model.py create mode 100644 train.py create mode 100644 train_simplified.py create mode 100644 try.py create mode 100644 utils/.DS_Store create mode 100644 utils/ImgTransforms.py create mode 100644 utils/__init__.py create mode 100644 utils/__pycache__/ImgTransforms.cpython-310.pyc create mode 100644 utils/__pycache__/ImgTransforms.cpython-36.pyc create mode 100644 utils/__pycache__/ImgTransforms.cpython-37.pyc create mode 100644 utils/__pycache__/OCRAttention.cpython-36.pyc create mode 100644 utils/__pycache__/__init__.cpython-310.pyc create mode 100644 utils/__pycache__/__init__.cpython-36.pyc create mode 100644 utils/__pycache__/__init__.cpython-37.pyc create mode 100644 utils/__pycache__/__init__.cpython-38.pyc create mode 100644 utils/__pycache__/attention.cpython-310.pyc create mode 100644 utils/__pycache__/attention.cpython-36.pyc create mode 100644 utils/__pycache__/attention.cpython-37.pyc create mode 100644 utils/__pycache__/attention.cpython-38.pyc create mode 100644 utils/__pycache__/criterion.cpython-310.pyc create mode 100644 utils/__pycache__/criterion.cpython-36.pyc create mode 100644 utils/__pycache__/criterion.cpython-37.pyc create mode 100644 utils/__pycache__/distributed.cpython-36.pyc create mode 100644 utils/__pycache__/distributed.cpython-37.pyc create mode 100644 utils/__pycache__/encoding.cpython-36.pyc create mode 100644 utils/__pycache__/encoding.cpython-37.pyc create mode 100644 utils/__pycache__/logger.cpython-36.pyc create mode 100644 utils/__pycache__/loss.cpython-310.pyc create mode 100644 utils/__pycache__/loss.cpython-36.pyc create mode 100644 utils/__pycache__/loss.cpython-37.pyc create mode 100644 utils/__pycache__/lovasz_losses.cpython-310.pyc create mode 100644 utils/__pycache__/lovasz_losses.cpython-36.pyc create mode 100644 utils/__pycache__/lovasz_losses.cpython-37.pyc create mode 100644 utils/__pycache__/miou.cpython-310.pyc create mode 100644 utils/__pycache__/miou.cpython-36.pyc create mode 100644 utils/__pycache__/miou.cpython-37.pyc create mode 100644 utils/__pycache__/model_store.cpython-36.pyc create mode 100644 utils/__pycache__/pyt_utils.cpython-36.pyc create mode 100644 utils/__pycache__/transforms.cpython-310.pyc create mode 100644 utils/__pycache__/transforms.cpython-36.pyc create mode 100644 utils/__pycache__/transforms.cpython-37.pyc create mode 100644 utils/__pycache__/utils.cpython-310.pyc create mode 100644 utils/__pycache__/utils.cpython-36.pyc create mode 100644 utils/__pycache__/utils.cpython-37.pyc create mode 100644 utils/attention.py create mode 100644 utils/criterion.py create mode 100644 utils/distributed.py create mode 100644 utils/encode_masks.py create mode 100644 utils/encoding.py create mode 100644 utils/logger.py create mode 100644 utils/loss.py create mode 100644 utils/lovasz_losses.py create mode 100644 utils/miou.py create mode 100644 utils/pyt_utils.py create mode 100644 utils/transforms.py create mode 100644 utils/utils.py create mode 100644 utils/writejson.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..36d8041 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +sagemaker_job.py +export_model.py +secrets.env +wandb/* +__pycache__/* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..37c6482 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +Implementation + +Dataset + +- This model is trained on CCIHP dataset which contains 22 class labels. + +Please download imagenet pretrained resent-101 from [baidu drive](https://pan.baidu.com/s/1NoxI_JetjSVa7uqgVSKdPw) or [Google drive](https://drive.google.com/open?id=1rzLU-wK6rEorCNJfwrmIu5hY2wRMyKTK), and put it into dataset folder. + +#### Training + +- Set necessary arguments and run `train_simplified.py`. + +Citation: + +@InProceedings{Liu_2022_CVPR, + author = {Liu, Kunliang and Choi, Ouk and Wang, Jianming and Hwang, Wonjun}, + title = {CDGNet: Class Distribution Guided Network for Human Parsing}, + booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)}, + month = {June}, + year = {2022}, + pages = {4473-4482} +} + diff --git a/Requirements b/Requirements new file mode 100644 index 0000000..41c9288 --- /dev/null +++ b/Requirements @@ -0,0 +1,9 @@ +Requirements + +Pytorch 1.9.0 +torchvision 0.11.0 +scipy 1.5.2 +cudatoolkit 11.3.1 +tensorboardX 2.2 +torchvision 0.11.0 +Python 3.7 diff --git a/dataset/.DS_Store b/dataset/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a408936e6ec953b0883d099f32c37de60376582a GIT binary patch literal 8196 zcmeHMU2GIZ9G~A&V7F}Pw(@a&-qD7Fq(YmPk7~f9EeKLV^$KkPJ??Ioc4cq(yxqG3 zwWP!dMtv|UCK?SI^+gk76!ZxqMvVHP5}ObajSu?Z3y(xYqW))R@9YO9F(lf=on+=e z`~RBR-~MK%b7hR7HLo=?7G{h|RJl}VQFD{R?YvGXAzxEL5){u^nkA|BGo2+Scn69A zfdGL3fdGL3fdGN2fB>D@yhxLr`@$Nu0RjO6|4Rh;{t%_gWz3huLV8;VHQp6~WErWw zLVdaicrj65#(X&}q!&s##q9xpDEuo1L^#=_+?{01m%~Dea0U_1;ExRdh5~PNii>*g z3^5^tHb5XiU?Kwi?mmld>j{=+N5S~oN#OY@gEZrpw#bL8mY zV?)PY;%`9vlfRF#O7UE3U#4E^1vMvarf7=XT2hYvE@8d_{%vy#Z32U1p=TuZJYUwv*Qs_&SiD0>NV%QX%fdT#fCp}GCNNhhsa znql>I7YxTpnR=I%%;;62xw1S`tyWcr7lao{YOU0hPZ^Kq4flwrRhEXMvU*n9uhC3) z+8WQOd85=U4J-S&wk@Yqt4Sh_vLbw^tR|%{hfokH>Xp^9>d0M(h!w0 zOzEajty4Bg>JGWPAYM->?@=~NRj8MHXmw@ieH@{VgUy^JI&6pbL>3(l6}j5 zWIwZO>^i%_{$PKCK}I znf>J*I&~{D*G+jce>Yn&c<#LU(dDaFH*MJ1TKf3ozV{ePj%K1qJ;5!Hb45;hgdYhn zSh#5M5+$;m*r*?#Y;mYFIqxLTds$5+qH@BC$GQ~}MFp)1d1TRog<)ky>w~+6M!V_#`b5Nsr@kJb@EL z)o1Y>Ucf25h|@&WH}EFj!n=46?|YOzhx53APw*)&;wxOn)p2C)7)RD0Mw4~i8CY}i z`p5hXERi{5k2&=w*vFo8Q9e{Dwh+%*rfv0+uDEcx{dUVVks!?P|63;i{r`4{3E~3; z0tBWo0w`;bx3|&+C)-^3T{}wk099VN->{Hg2sPY=>%HqZ$g`kg3AgQlR)%i5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HOenx(7s(x8f zX>mqkUbcR4L1kX5zDJO5SY}Cnp1!k-yI*RFzMg(cVo72#kQE=FnU`4-AFo$Xd5gm) TH$SB`C)EyQW-$|xU||3NLt-J{ literal 0 HcmV?d00001 diff --git a/dataset/__pycache__/__init__.cpython-36.pyc b/dataset/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e4fa8a33f243671ad65fa965796afc54f9d0f33 GIT binary patch literal 124 zcmXr!<>d-t+?m7x1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFHQa2yb}HL{Gx0_ y{hZ8FePg`kf}N?MNg(<$h=2h`Aj1KOi&=m~3PUi1CZpd2 QKczG$)edChXCP((0Fr|u4gdfE literal 0 HcmV?d00001 diff --git a/dataset/__pycache__/data_augmentation.cpython-36.pyc b/dataset/__pycache__/data_augmentation.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b897daaf57d4a163af84767d002c274aee393522 GIT binary patch literal 2678 zcmZ8j&u`;I6rLH|iQ^<~+NM92-NOo2h#-~1g0vD^vA>a4qFvNoI9N!=%{Zw`Vn<__ zZB`R5WiLp3;{yKy{{w%Cxgc>^^~wo2@x8IrrkiMH-h1=rc|7m?=K14x+xzL!t#5vA zG4>Z*_*szeqGb}DWRj1VUyj`8Mi;(iM%%Z|==hFYm5!|a$o-mJldfz)s>`ly$`&M7 zuFEC445<-$vh$r#-$qTja>_ZPKV`j*Gdzjyy?*D9e}6do{qH-kfBl7iXLnwcow0xJ z^qo>-9>zM_1GH=(UCxf!DVsUk*47r&PM2wGlg(0@nlb&7FRG7$g zTv+|@Z$gQ(_(fDSAMZVTv>!b9>i**gJ+Bb)*!Qx2IEsQS8V&qr9;#uK2Qtobzfn$% zYv@0HJ#K|KDAsSdXL-|o&~I*xWm@o^p} z!;e1M`Qq`HJCkXis{Y}277fQylAHZ+=V>}RNKbZTn1@-En=uHFFFZb&OpDb;Ltvgt zr=QWYnC0>gce#z`iVdMwVLN*dU0={Ner>b{n#mT!c~;pHT1dXdq(HVfGGb|V#HDqG z&1@stkepl`S=yH3DzZxbKxkx2I``9Q*LzE=r-xVg1g{j zYzsbS4SbM$ZPSi`6AwsmD!Hj^vhJ`eOnbMO#cng`uF;#Nj$Jl1thuLMJRNIK`9Q$h zL~F^0ti7tuTDqlc23y|VkPe2iKkuB;DJcTBfg6xk>mxgnDx5GGjv}>;sh$mP8DKes zQ8>&B?;uq&QoE@H)=K&7aC98?go&cMv`Ca;jck>60(1GCwxW~(Lx4 z#0F3eTnp8M*VzPzcYXtH!9s^-F#YWXrkx7gwH!!1N4LQnP|AUuIpRy3iyNu|T-6Qw zxbz^qkUfKY3k-1vmIV4pY)xk5 z4p}RCkM{!-{A-F+!gAlOSWz&hQ8*Cy;8y>Vd&qlhVWcrRmS1u@t4hTa^yLrzS>ecZg@ zjDdFvXd=!T)v5x_NW;9x3rFVDNmLPx-JMf{pg)&sRnIjHPy_*W%|v(+DWKW{PSM4Q zddpZtrNU`%s|2x^9vlTFLH$}^rIX;K8mE4T0A9`oIjTa2GKfo@Jj^)t-IE|43~ zjuMHui(0jVpqw$gG4j-JmJ!Q|1!ejs1-q9hSiR3S4mf)s9dXbVUEa09J<%1!J}^>{ zMlxoM{Gm`c;r*JH(Cv9%V<@8p1H;EpAzq z_;#@A+o7ubpFcBKXU{GnVs1x!Fp4LI-A^aeo@2mJG{_W8RC-`;GNd^ri|5{{!FD4dC+ m+n&n*LT7GT_x3oI$D`;oqFY9#2Z=5J!dvpTym!5h%l`*nqMFqJ literal 0 HcmV?d00001 diff --git a/dataset/__pycache__/data_augmentation.cpython-37.pyc b/dataset/__pycache__/data_augmentation.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdd82f24372a98e29fee55987d75446db107dea1 GIT binary patch literal 2682 zcmZ8jO>g5w7@is1iQ{}UZPPYo_ppK$A}f_bL0Sn`biY7aXZj#ee2H7U^b>VUe3{$40;$Yfyvl2k zY`(%9d;wA=aCq}26EA`)Up%1{*`JZl>Lq3(yBF{M@$Zj^zyG~`@#`<@ce#C`?1cQY z-L-OwsAZSY9-$?B=u&b<&dJ1*rZn0_S}h`tH8Lql$|)wg&Dn%XCg}|_Da*1fwaCOy z=^>MNC230~8{9axCKXwcc8_5>=B}W~e5tyQk+I$}+BmC+Q5uL*Jn+*njyh&m5`M(v zVPhUm1-Ae8l zhS8PiA7>^HyMfy*d`E*c91X%iOhf$rB(t>Bb@Dm67Y=_TqKW1Hx3hT=4};A?c$9`w z|Km?LpFa6!b2Lt4(LLBmg8ndwQoa6-G>!-R@$n}2Q$Gn({q+2!S;U8KnTHZ{>~w#vj3Y?mLP>oVoWua0J;>C+P1a;dW6Rm?tBoP#&+SXKOF{u#!wpC)b#Xd@$SgnV4+60OSBGh*Xyvkw z*0Pb?6-M*nCP=6eX!QnuKgpc^SnxpX#2lc^cd7q4z4}>495;bP$C7gEXT%85M3V z3SI%;g}Yv8MF>m5%ybMM=-i42ngw~csNd`wfb+N&IFfhKX#_KeI`k&mZTxHaH))ft z0@c7Z6CFfdjY3cff|JUQbO~nt~HfwX_iat%c&)oz`_!D)(LkoADgsbTh_M9m2E{fWlJ{N1Z!TEi*iLSXn756 zSdc4km~6<_8-@Zw-mso}(<-9YU~kIRnH`J*Q^4Q`Ml})9LZ(%@*0=lg98AJ}T%B=d z%7Yo~3w|hKT&l{I0sgU{c4%htbUX?Qx{>=iUsPPj)(j8|0^+6~^EwbfwE>)>3nTH4 zw)#T&<4!vVu@mnfdO1PeQdh(y@3?r5-KGL~?(m%YJj;scw=ICSnrRd$XuFL(gO{L&q=>$*kKLMH)zmw$joo^J5`Y?1485jeWRW?D zIP%VG#R|OKqgSKlv0KeE=8idK{5Az!*C<%L&jvO)xr0t|&}J>#GQmC8Vv2oWBvYD_ z;nDI(Ol%?gLJd*3=T(hSCu*W;K7IyaT4OjxT|wo4X^A$z0t{)0J1IR=mESmL6Em_U zIWzF>V5)D2qVj+BT;IqYGlz)29nIb#9A#!V9*sMe218a+CT}F-eSMSRm}6ye9o6T@ z_4YO_UfTv0_Y8}jR#K*_sENM8aO>QKC$l|o=!cQ#yswE6_ti=we;9aP qW{rfp?N#}o>-0@)-y6pKXb^m%xS6OLg@eui%xO4n=Y6MX)BgcM&Yt%G literal 0 HcmV?d00001 diff --git a/dataset/__pycache__/dataset_LIP.cpython-36.pyc b/dataset/__pycache__/dataset_LIP.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f177d50eb3a42927f14793d9d8fbd8ba1ff92625 GIT binary patch literal 2258 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 literal 0 HcmV?d00001 diff --git a/dataset/__pycache__/datasets.cpython-37.pyc b/dataset/__pycache__/datasets.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02b5cf76b066ea67477eb0382dc488884dd082fa GIT binary patch literal 5995 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 literal 0 HcmV?d00001 diff --git a/dataset/__pycache__/target_generation.cpython-310.pyc b/dataset/__pycache__/target_generation.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd1e8d508dd361e45aa9cc217c286afe849c49ab GIT binary patch literal 2387 zcmaJ?&2Jk;6rYd%^4dwO5=vXD5D-GL5VhzDp{T0Vs&LAIRz<8TSsTyBc5LsO*>ysy z^{G_iKm~t-eS`}q{+SWCBB30)Ar1+@x4Ur?*J4-mX6AjrnfKl#YimBk_wcVjc7Llg z_L?>qKZ(tKjPwbBVu}x0P|iHy#a;xmn61DnW;?Kp*$EuXV(5;%pvIZ1DNEVk^T1cW za+QZwUGc}PSwDtmw$tRs-W;4e`YIp&S7s6QSL9~eE40<{XK~*_I5Nbj2)j6C{}c{xN)iaqwe3m z*FXIJ&!6{>Pw_Rc7(4BScKlU1J^eqeD}h#Ob$_ zD0&Wo=aEiQU`I!@Ba$aFF?_TDfFGb2agcL4p^IHNEdO@__7ak5Z% zqb#U(hGCkLIm3H~9|m4YXm^6OY6TB^3AFUOnSL8#Xi8Nh54)MMdVs$$y$Q^}4_dus z6txcY1o6a!*5mO}9JRju>XWDaEQwnW9)7VCWvx3c6=q?IRi(Zg#gPuF3hp4{^=ccn zdx!0AR)ga79)Qn%?(qi3I#yQ!8yM^28rIkF6CIeP{f4-~8^RZQ3o4GOwBIN(vQU)R z=OCk;C~d_)6$;BNl$`wn7d{aBEzlfAsSmDw`Kkhcyja4ww zgKVtMM1`jQh&tAjC{7b?dg)u+Bf;3|QQf)_0*HEx`=yE;^cKQc}yi4X27<5s;9 z9nKzxyU{T4Bh`)Chkccyy~X+_DY;cBAwosg{cbM{+=6v74jR>>L|-j-yGfQMqXJ`` zL8RkoShT$oyhj?>7QKrkT0o^c0BBQ1bGpuN2_c@IZgJ~$(-QKtlPxYzZwu?>16#=L zlMk!iX0apM7HGFEYHb^Q^Q0j?ZgG7VDw|wWGsE;gO${UP4#@N%BzHujDu2ZhZ@nWEuI)nP-7?{!#PJ3P8VAOX-xH~3bgDRQsm8P6-=lXw{r=Bi50BsD z>0PpJF^cDjb<122MkolK&-&S7Hh*c|L7HcYbwG#Kc`;6oY-^DfKP-~u6%1Y_IxlQc z4C1m(blDXpceE8QMZ{PgHaAIqhYB(z&7+%5G#*{rFBN2zc76ZoPYQCW?8v+l~654G+iE#T(t!1*7VwyAV+~;Zz0s2YpmJSi5w#Q=#u+?kTEr z(sG|k>ba(Gu!a@-1ywIl_2{0u`jlhj8_`svM74Y1c!ppD{cv8o<})LebB#3W8iwUm zuBGREDt9U$A*aUY7Ta0_7;utR9UYiZM>(X-d}QOFda3f;&^RXpcA%p-Guz_#e0I&g z8{3PSo$h=iy8zh*rx|S5TFdJ{v^B%+mgllOXa7H0u460#>ge=~r?A#o%bN2$yT3E1 zdwPCr%dOdMoXtsws6x729N;rQBuqc8NkXe|#eTk1p*iXhmF$*nAed`HvQge!XX$>2 z9emBcVc#=&p*j{*NtH9{)^!aW^AEI#rm4UT=;f;NhP=L1}?~3(#SjVHOANCW(7_+ zEAZ0$(Cu+eV1(fl8ah@0wq^0Mux^d>BAZ(e*sb!Jm4g@iy83%Tbs^l(GEKLK{*1_N jBINT-o`k--N;Y^f%he)H9@3pt(7z1;peJvKhxh&i*|!^% literal 0 HcmV?d00001 diff --git a/dataset/__pycache__/target_generation.cpython-37.pyc b/dataset/__pycache__/target_generation.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b49b120520ef8e9b30335c675dd6e3df8ab0b8b1 GIT binary patch literal 2311 zcmaJ?&5zqe6rb_lb~QSoQ;lxuVzd%3^}`NlvLkKjyy9UX1L;X0 zv##XdvVQj%p4sC*H^IR?8|q1(Mal6c@P-yi@O1IH_#Wabe&>vp?2tXP7S=*&zO+iV z;tTMWV#OA=6V^!KV%=lXA@IYF*{An%3~E1nU<98dd$vyG0$=~$LzE*5oNhu zx+j03?BGuX)n0<7BfS+zymm)r(AovayHf@S0>|q=RyZ(r{EkR9qf^Cc3pq(ge~;h( z^2a}a-9LVZr+>jX#W8kmk&QC7_IA~vF!r^Y!*@<1LV~B++bU401{5Js-puU>L>@4 znTKq!lM^pherp=%WPlPh__|6erBgTU(3!%cK&Gwo3&bb{f9PYxY_bt zmgnsMC(Aa*0vM0RZ~tE#r`2d>&H0_(-Hcx93 z;I#}^?AKcrxT6kH$&T&m;=PGgnDNd;{+`ItOzwFpHPcfl$? z1z`Xr0;V3nY+b{Bc|(-qmUxBnm36%Wr|T7XsXgfSxgs#a@Cgk)V*$lQ@uDzJ4f|F$ zGcKT9=BW|G=XT^Gu!u#;QuzznA86p2YX*3M%N|`T)?A Jx5tA!{{dTmDl-58 literal 0 HcmV?d00001 diff --git a/dataset/__pycache__/voc.cpython-36.pyc b/dataset/__pycache__/voc.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aab1dfdcdb48882f541c3991e2176bc9984f297f GIT binary patch literal 6112 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 literal 0 HcmV?d00001 diff --git a/dataset/datasets.py b/dataset/datasets.py new file mode 100644 index 0000000..a8551c5 --- /dev/null +++ b/dataset/datasets.py @@ -0,0 +1,259 @@ +import os +import numpy as np +import random +import torch +import cv2 +import json +import sys +sys.path.insert(0, '.') +from torch.utils import data +from torch.utils.data import DataLoader +import matplotlib.pyplot as plt +from dataset.target_generation import generate_edge, generate_hw_gt +from utils.transforms import get_affine_transform +from utils.ImgTransforms import AugmentationBlock, autoaug_imagenet_policies +from utils.utils import decode_parsing + + + +# statisticSeg=[ 30462,7026,21054,2404,1660,23165,1201,8182,2178,16224, +# 455,518,634,24418,18539,20033,4763,4832,8126,8166] +class LIPDataSet(data.Dataset): + def __init__(self, root, dataset, crop_size=[473, 473], scale_factor=0.25, + rotation_factor=30, ignore_label=255, transform=None): + """ + :rtype: + """ + self.root = root + self.aspect_ratio = crop_size[1] * 1.0 / crop_size[0] + self.crop_size = np.asarray(crop_size) + self.ignore_label = ignore_label + self.scale_factor = scale_factor + self.rotation_factor = rotation_factor + self.flip_prob = 0.5 + self.flip_pairs = [[0, 5], [1, 4], [2, 3], [11, 14], [12, 13], [10, 15]] + self.transform = transform + self.dataset = dataset + # self.statSeg = np.array( statisticSeg, dtype ='float') + # self.statSeg = self.statSeg/30462 + + list_path = os.path.join(self.root, self.dataset + '_id.txt') + + self.im_list = [i_id.strip() for i_id in open(list_path)] + # if dataset != 'val': + # im_list_2 = [] + # for i in range(len(self.im_list)): + # if i % 5 ==0: + # im_list_2.append(self.im_list[i]) + # self.im_list = im_list_2 + self.number_samples = len(self.im_list) + #================================================================================ + self.augBlock = AugmentationBlock( autoaug_imagenet_policies ) + #================================================================================ + def __len__(self): + return self.number_samples + + def _box2cs(self, box): + x, y, w, h = box[:4] + return self._xywh2cs(x, y, w, h) + + def _xywh2cs(self, x, y, w, h): + center = np.zeros((2), dtype=np.float32) + center[0] = x + w * 0.5 + center[1] = y + h * 0.5 + if w > self.aspect_ratio * h: + h = w * 1.0 / self.aspect_ratio + elif w < self.aspect_ratio * h: + w = h * self.aspect_ratio + scale = np.array([w * 1.0, h * 1.0], dtype=np.float32) + + return center, scale + + def __getitem__(self, index): + # Load training image + im_name = self.im_list[index] + + im_path = os.path.join(self.root, self.dataset + '_images', im_name + '.jpg') + #print(im_path) + parsing_anno_path = os.path.join(self.root, self.dataset + '_segmentations', im_name + '.png') + + im = cv2.imread(im_path, cv2.IMREAD_COLOR) + im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) + #================================================= + if self.dataset != 'val': + im = self.augBlock( im ) + #================================================= + h, w, _ = im.shape + parsing_anno = np.zeros((h, w), dtype=np.long) + + # Get center and scale + center, s = self._box2cs([0, 0, w - 1, h - 1]) + r = 0 + + if self.dataset != 'test': + parsing_anno = cv2.imread(parsing_anno_path, cv2.IMREAD_GRAYSCALE) + + if self.dataset == 'train' or self.dataset == 'trainval': + + sf = self.scale_factor + rf = self.rotation_factor + s = s * np.clip(np.random.randn() * sf + 1, 1 - sf, 1 + sf) + r = np.clip(np.random.randn() * rf, -rf * 2, rf * 2) \ + if random.random() <= 0.6 else 0 + + if random.random() <= self.flip_prob: + im = im[:, ::-1, :] + parsing_anno = parsing_anno[:, ::-1] + + center[0] = im.shape[1] - center[0] - 1 + right_idx = [15, 17, 19] + left_idx = [14, 16, 18] + for i in range(0, 3): + right_pos = np.where(parsing_anno == right_idx[i]) + left_pos = np.where(parsing_anno == left_idx[i]) + parsing_anno[right_pos[0], right_pos[1]] = left_idx[i] + parsing_anno[left_pos[0], left_pos[1]] = right_idx[i] + + trans = get_affine_transform(center, s, r, self.crop_size) + input = cv2.warpAffine( + im, + trans, + (int(self.crop_size[1]), int(self.crop_size[0])), + flags=cv2.INTER_LINEAR, + borderMode=cv2.BORDER_CONSTANT, + borderValue=(0, 0, 0)) + + if self.transform: + input = self.transform(input) + + meta = { + 'name': im_name, + 'center': center, + 'height': h, + 'width': w, + 'scale': s, + 'rotation': r + } + + if self.dataset != 'train': + return input, meta + else: + label_parsing = cv2.warpAffine( + parsing_anno, + trans, + (int(self.crop_size[1]), int(self.crop_size[0])), + flags=cv2.INTER_NEAREST, + borderMode=cv2.BORDER_CONSTANT, + borderValue=(255)) + + # label_edge = generate_edge(label_parsing) + hgt, wgt, hwgt = generate_hw_gt(label_parsing) + label_parsing = torch.from_numpy(label_parsing) + # label_edge = torch.from_numpy(label_edge) + + return input, label_parsing, hgt,wgt,hwgt, meta + +class LIPDataValSet(data.Dataset): + def __init__(self, root, dataset='val', crop_size=[512, 512], transform=None, flip=False): + self.root = root + self.crop_size = crop_size + self.transform = transform + self.flip = flip + self.dataset = dataset + self.root = root + self.aspect_ratio = crop_size[1] * 1.0 / crop_size[0] + self.crop_size = np.asarray(crop_size) + + list_path = os.path.join(self.root, self.dataset + '_id.txt') + val_list = [i_id.strip() for i_id in open(list_path)] + + self.val_list = val_list + self.number_samples = len(self.val_list) + + def __len__(self): + return len(self.val_list) + + def _box2cs(self, box): + x, y, w, h = box[:4] + return self._xywh2cs(x, y, w, h) + + def _xywh2cs(self, x, y, w, h): + center = np.zeros((2), dtype=np.float32) + center[0] = x + w * 0.5 + center[1] = y + h * 0.5 + if w > self.aspect_ratio * h: + h = w * 1.0 / self.aspect_ratio + elif w < self.aspect_ratio * h: + w = h * self.aspect_ratio + scale = np.array([w * 1.0, h * 1.0], dtype=np.float32) + + return center, scale + + def __getitem__(self, index): + val_item = self.val_list[index] + # Load training image + im_path = os.path.join(self.root, self.dataset + '_images', val_item + '.jpg') + im = cv2.imread(im_path, cv2.IMREAD_COLOR) + im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) + h, w, _ = im.shape + # Get person center and scale + person_center, s = self._box2cs([0, 0, w - 1, h - 1]) + r = 0 + trans = get_affine_transform(person_center, s, r, self.crop_size) + input = cv2.warpAffine( + im, + trans, + (int(self.crop_size[1]), int(self.crop_size[0])), + flags=cv2.INTER_LINEAR, + borderMode=cv2.BORDER_CONSTANT, + borderValue=(0, 0, 0)) + input = self.transform(input) + flip_input = input.flip(dims=[-1]) + if self.flip: + batch_input_im = torch.stack([input, flip_input]) + else: + batch_input_im = input + + meta = { + 'name': val_item, + 'center': person_center, + 'height': h, + 'width': w, + 'scale': s, + 'rotation': r + } + + return batch_input_im, meta + +''' +root = '/home/vrushank/Spyne/CCIHP' +dataset = 'train' +data1 = LIPDataValSet(root, dataset, crop_size=[512, 512]) +loader = DataLoader(data1, batch_size = 1, shuffle = True) + +for idx, (input, label_parsing, hgt,wgt,hwgt, meta) in enumerate(loader): + + if idx == 0: + + print(input.shape) + print(label_parsing.shape) + + ip = input.squeeze(0).cpu().numpy() + label = decode_parsing(label_parsing, num_classes = 22) + print(type(label)) + label = label[0].data.cpu().numpy() + label = label.transpose((1,2,0)) + #label = cv2.cvtColor(label, cv2.COLOR_GRAY2BGR) + print(ip.shape) + print(label.shape) + res = np.concatenate((ip, label), axis = 1) + plt.imshow(res) + plt.show() + #print(f'{hgt}: {hgt.shape}') + #print(f'{wgt}: {wgt.shape}') + #print(f'{hwgt}: {hwgt.shape}') + + else: + + break +''' \ No newline at end of file diff --git a/dataset/list/.DS_Store b/dataset/list/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..74dc7d86a3160e77bc0b1481e2b44cc7a4bb0dba GIT binary patch literal 6148 zcmeHK%}(1u5S|SIHbGT$s07Eo^iU~>L{JciN^S@TZb+`$10b+*L@YU8D|Twp5ac)D z46nikapMVi0A8fCKSZD;5?oMKW~AM3Jp0YA_giN-3jnM&2$}#j0N_{@mMU0HG1ach zgq3V$0g>rGQaA<=66ioW!KT2!sDN6#Dy~`x8Jyy(jn~i5)5MRYkL`DU5`}5jXxy{X zTzP(Bk@G6AeyAR}U75R?mkrXE*WXi5yI$7yt^Y&HXzY9b&#;pp);?{?IP=1|)7Qyi z&_T-nuP_c|-jahjNOeE1Y2duVD~Gj};jsC2vo2QGHb-?a+}LQ;#oFrnXjI|LpPS!y zj(VqmhG(PmOQSHuk5Su4i;r-H&eX|9Cr$TQ_7Y9ZZ!c!?da~WNqTny0_;USl^L;iq zcriEWJ{kW;zs1z|{O$JRNX93~c$}jqQ$-4p0;Is}6tG(eUwT~{u}J|^;2kKS_6LDQ zp<}TysJ9NR^c4WHjA3o)tGk5C5f&Ybg+XjVVdF1xSJC3e1_unmYftXW##yC(#orKnna<3b1n9ZMSer_H3P) xoH}a-mLn|66t6HiPC-W>#mH4h@d_4g7#GSxbSxGIF@i>a1hfoPkpge3z+bt$dZYjV literal 0 HcmV?d00001 diff --git a/dataset/target_generation.py b/dataset/target_generation.py new file mode 100644 index 0000000..1b82d28 --- /dev/null +++ b/dataset/target_generation.py @@ -0,0 +1,82 @@ +import os +import sys +import numpy as np +import random +import cv2 +import torch +from torch.nn import functional as F + +def generate_hw_gt( target, class_num = 22 ): + h,w = target.shape + target = torch.from_numpy(target) + target_c = target.clone() + target_c[target_c==255]=0 + target_c = target_c.long() + target_c = target_c.view(h*w) + target_c = target_c.unsqueeze(1) + target_onehot = torch.zeros(h*w,class_num) + target_onehot.scatter_( 1, target_c, 1 ) #h*w,class_num + target_onehot = target_onehot.transpose(0,1) + target_onehot = target_onehot.view(class_num,h,w) + # h distribution ground truth + hgt = torch.zeros((class_num,h)) + hgt=( torch.sum( target_onehot, dim=2 ) ).float() + hgt[0,:] = 0 + max = torch.max(hgt,dim=1)[0] #c,1 + min = torch.min(hgt,dim=1)[0] + max = max.unsqueeze(1) + min = min.unsqueeze(1) + hgt = hgt / ( max + 1e-5 ) + # w distribution gound truth + wgt = torch.zeros((class_num,w)) + wgt=( torch.sum(target_onehot, dim=1 ) ).float() + wgt[0,:]=0 + max = torch.max(wgt,dim=1)[0] #c,1 + min = torch.min(wgt,dim=1)[0] + max = max.unsqueeze(1) + min = min.unsqueeze(1) + wgt = wgt / ( max + 1e-5 ) + #=========================================================== + hwgt = torch.matmul( hgt.transpose(0,1), wgt ) + max = torch.max( hwgt.view(-1), dim=0 )[0] + # print(max) + hwgt = hwgt / ( max + 1.0e-5 ) + #==================================================================== + return hgt, wgt, hwgt #,cch, ccw gt_hw + +def generate_edge(label, edge_width=3): + label = label.type(torch.cuda.FloatTensor) + if len(label.shape) == 2: + label = label.unsqueeze(0) + n, h, w = label.shape + edge = torch.zeros(label.shape, dtype=torch.float).cuda() + # right + edge_right = edge[:, 1:h, :] + edge_right[(label[:, 1:h, :] != label[:, :h - 1, :]) & (label[:, 1:h, :] != 255) + & (label[:, :h - 1, :] != 255)] = 1 + + # up + edge_up = edge[:, :, :w - 1] + edge_up[(label[:, :, :w - 1] != label[:, :, 1:w]) + & (label[:, :, :w - 1] != 255) + & (label[:, :, 1:w] != 255)] = 1 + + # upright + edge_upright = edge[:, :h - 1, :w - 1] + edge_upright[(label[:, :h - 1, :w - 1] != label[:, 1:h, 1:w]) + & (label[:, :h - 1, :w - 1] != 255) + & (label[:, 1:h, 1:w] != 255)] = 1 + + # bottomright + edge_bottomright = edge[:, :h - 1, 1:w] + edge_bottomright[(label[:, :h - 1, 1:w] != label[:, 1:h, :w - 1]) + & (label[:, :h - 1, 1:w] != 255) + & (label[:, 1:h, :w - 1] != 255)] = 1 + + kernel = torch.ones((1, 1, edge_width, edge_width), dtype=torch.float).cuda() + with torch.no_grad(): + edge = edge.unsqueeze(1) + edge = F.conv2d(edge, kernel, stride=1, padding=1) + edge[edge!=0] = 1 + edge = edge.squeeze() + return edge \ No newline at end of file diff --git a/engine.py b/engine.py new file mode 100644 index 0000000..5edee44 --- /dev/null +++ b/engine.py @@ -0,0 +1,133 @@ +import os +import os.path as osp +import time +import argparse + +import torch +import torch.distributed as dist + +from utils.logger import get_logger +from utils.pyt_utils import parse_devices, all_reduce_tensor, extant_file +''' +try: + from apex.parallel import DistributedDataParallel, SyncBatchNorm +except ImportError: + raise ImportError( + "Please install apex from https://www.github.com/nvidia/apex .") +''' + +logger = get_logger() + + +class Engine(object): + def __init__(self, custom_parser=None): + logger.info( + "PyTorch Version {}".format(torch.__version__)) + self.devices = None + self.distributed = False + + if custom_parser is None: + self.parser = argparse.ArgumentParser() + else: + assert isinstance(custom_parser, argparse.ArgumentParser) + self.parser = custom_parser + + self.inject_default_parser() + self.args = self.parser.parse_args() + + self.continue_state_object = self.args.continue_fpath + + # if not self.args.gpu == 'None': + # os.environ["CUDA_VISIBLE_DEVICES"]=self.args.gpu + + if 'WORLD_SIZE' in os.environ: + self.distributed = int(os.environ['WORLD_SIZE']) > 1 + + if self.distributed: + self.local_rank = self.args.local_rank + self.world_size = int(os.environ['WORLD_SIZE']) + torch.cuda.set_device(self.local_rank) + dist.init_process_group(backend="nccl", init_method='env://') + self.devices = [i for i in range(self.world_size)] + else: + gpus = os.environ["CUDA_VISIBLE_DEVICES"] + self.devices = [i for i in range(len(gpus.split(',')))] + + def inject_default_parser(self): + p = self.parser + p.add_argument('-d', '--devices', default='', + help='set data parallel training') + p.add_argument('-c', '--continue', type=extant_file, + metavar="FILE", + dest="continue_fpath", + help='continue from one certain checkpoint') + p.add_argument('--local_rank', default=0, type=int, + help='process rank on node') + + def data_parallel(self, model): + if self.distributed: + model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[self.local_rank], + output_device=self.local_rank,) + else: + model = torch.nn.DataParallel(model) + return model + + def get_train_loader(self, train_dataset): + train_sampler = None + is_shuffle = True + batch_size = self.args.batch_size + + if self.distributed: + train_sampler = torch.utils.data.distributed.DistributedSampler( + train_dataset) + batch_size = self.args.batch_size // self.world_size + is_shuffle = False + + train_loader = torch.utils.data.DataLoader(train_dataset, + batch_size=batch_size, + num_workers=self.args.num_workers, + drop_last=False, + shuffle=is_shuffle, + pin_memory=True, + sampler=train_sampler) + + return train_loader, train_sampler + + def get_test_loader(self, test_dataset): + test_sampler = None + is_shuffle = False + batch_size = self.args.batch_size + + if self.distributed: + test_sampler = torch.utils.data.distributed.DistributedSampler( + test_dataset) + batch_size = self.args.batch_size // self.world_size + + test_loader = torch.utils.data.DataLoader(test_dataset, + batch_size=batch_size, + num_workers=self.args.num_workers, + drop_last=False, + shuffle=is_shuffle, + pin_memory=True, + sampler=test_sampler) + + return test_loader, test_sampler + + + def all_reduce_tensor(self, tensor, norm=True): + if self.distributed: + return all_reduce_tensor(tensor, world_size=self.world_size, norm=norm) + else: + return torch.mean(tensor) + + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + torch.cuda.empty_cache() + if type is not None: + logger.warning( + "A exception occurred during Engine initialization, " + "give up running process") + return False diff --git a/evaluate.py b/evaluate.py new file mode 100644 index 0000000..29d7f99 --- /dev/null +++ b/evaluate.py @@ -0,0 +1,274 @@ +import argparse +import numpy as np +import torch +torch.multiprocessing.set_start_method("spawn", force=True) +from torch.utils import data +from tqdm import tqdm +from networks.CDGNet import Res_Deeplab +from dataset.datasets import LIPDataSet +import os +import torchvision.transforms as transforms +from utils.miou import compute_mean_ioU +from copy import deepcopy + +from PIL import Image as PILImage + +DATA_DIRECTORY = '/ssd1/liuting14/Dataset/LIP/' +DATA_LIST_PATH = './dataset/list/lip/valList.txt' +IGNORE_LABEL = 255 +NUM_CLASSES = 20 +SNAPSHOT_DIR = './snapshots/' +INPUT_SIZE = (473,473) + +# colour map +COLORS = [(0,0,0) + # 0=background + ,(128,0,0),(0,128,0),(128,128,0),(0,0,128),(128,0,128) + # 1=aeroplane, 2=bicycle, 3=bird, 4=boat, 5=bottle + ,(0,128,128),(128,128,128),(64,0,0),(192,0,0),(64,128,0) + # 6=bus, 7=car, 8=cat, 9=chair, 10=cow + ,(192,128,0),(64,0,128),(192,0,128),(64,128,128),(192,128,128) + # 11=diningtable, 12=dog, 13=horse, 14=motorbike, 15=person + ,(0,64,0),(128,64,0),(0,192,0),(128,192,0),(0,64,128)] + # 16=potted plant, 17=sheep, 18=sofa, 19=train, 20=tv/monitor + +def get_ccihp_pallete(): + + palette = [ + 120, 120, 120, + 127, 0, 0, + 254, 0, 0, + 0, 84, 0, + 169, 0, 50, + 254, 84, 0, + 255, 0, 84, + 0, 118, 220, + 84, 84, 0, + 0, 84, 84, + 84, 50, 0, + 51, 85, 127, + 0, 127, 0, + 0, 0, 254, + 50, 169, 220, + 0, 254, 254, + 84, 254, 169, + 169, 254, 84, + 254, 254, 0, + 254, 169, 0, + 102, 254, 0, + 182, 255, 0 + + ] + + return palette + +def get_lip_palette(): + palette = [0,0,0, + 128,0,0, + 255,0,0, + 0,85,0, + 170,0,51, + 255,85,0, + 0,0,85, + 0,119,221, + 85,85,0, + 0,85,85, + 85,51,0, + 52,86,128, + 0,128,0, + 0,0,255, + 51,170,221, + 0,255,255, + 85,255,170, + 170,255,85, + 255,255,0, + 255,170,0] + return palette +def get_palette(num_cls): + """ Returns the color map for visualizing the segmentation mask. + + Inputs: + =num_cls= + Number of classes. + + Returns: + The color map. + """ + n = num_cls + palette = [0] * (n * 3) + for j in range(0, n): + lab = j + palette[j * 3 + 0] = 0 + palette[j * 3 + 1] = 0 + palette[j * 3 + 2] = 0 + i = 0 + while lab: + palette[j * 3 + 0] |= (((lab >> 0) & 1) << (7 - i)) + palette[j * 3 + 1] |= (((lab >> 1) & 1) << (7 - i)) + palette[j * 3 + 2] |= (((lab >> 2) & 1) << (7 - i)) + i += 1 + lab >>= 3 + return palette + +def get_arguments(): + """Parse all the arguments provided from the CLI. + + Returns: + A list of parsed arguments. + """ + parser = argparse.ArgumentParser(description="CE2P Network") + parser.add_argument("--batch-size", type=int, default=1, + help="Number of images sent to the network in one step.") + parser.add_argument("--data-dir", type=str, default=DATA_DIRECTORY, + help="Path to the directory containing the PASCAL VOC dataset.") + parser.add_argument("--dataset", type=str, default='val', + help="Path to the file listing the images in the dataset.") + parser.add_argument("--ignore-label", type=int, default=IGNORE_LABEL, + help="The index of the label to ignore during the training.") + parser.add_argument("--num-classes", type=int, default=NUM_CLASSES, + help="Number of classes to predict (including background).") + parser.add_argument("--restore-from", type=str, + help="Where restore model parameters from.") + parser.add_argument("--gpu", type=str, default='0', + help="choose gpu device.") + parser.add_argument("--input-size", type=str, default=INPUT_SIZE, + help="Comma-separated string with height and width of images.") + + return parser.parse_args() + +def valid(model, valloader, input_size, num_samples, gpus): + + model.eval() + parsing_preds = np.zeros((num_samples, input_size[0], input_size[1]), + dtype=np.uint8) + + scales = np.zeros((num_samples, 2), dtype=np.float32) + centers = np.zeros((num_samples, 2), dtype=np.int32) + + idx = 0 + interp = torch.nn.Upsample(size=(input_size[0], input_size[1]), mode='bilinear', align_corners=True) + with torch.no_grad(): + loop = tqdm(valloader, position = 0, leave = True) + for index, batch in enumerate(valloader): + image, meta = batch + num_images = image.size(0) + if index % 100 == 0: + print('%d processed' % (index * num_images)) + + c = meta['center'].numpy() + s = meta['scale'].numpy() + scales[idx:idx + num_images, :] = s[:, :] + centers[idx:idx + num_images, :] = c[:, :] + #==================================================================================== + org_img = image.numpy() + normal_img = org_img + flipped_img = org_img[:,:,:,::-1] + fused_img = np.concatenate( (normal_img,flipped_img), axis=0 ) + with torch.no_grad(): + outputs = model( torch.from_numpy(fused_img).cuda()) + prediction = interp( outputs[0][-1].cpu()).data.numpy().transpose(0, 2, 3, 1) #N,H,W,C + single_out = prediction[:num_images,:,:,:] + single_out_flip = np.zeros( single_out.shape ) + single_out_tmp = prediction[num_images:, :,:,:] + for c in range(14): + single_out_flip[:,:, :, c] = single_out_tmp[:, :, :, c] + single_out_flip[:, :, :, 14] = single_out_tmp[:, :, :, 15] + single_out_flip[:, :, :, 15] = single_out_tmp[:, :, :, 14] + single_out_flip[:, :, :, 16] = single_out_tmp[:, :, :, 17] + single_out_flip[:, :, :, 17] = single_out_tmp[:, :, :, 16] + single_out_flip[:, :, :, 18] = single_out_tmp[:, :, :, 19] + single_out_flip[:, :, :, 19] = single_out_tmp[:, :, :, 18] + single_out_flip = single_out_flip[:, :, ::-1, :] + # Fuse two outputs + single_out = ( single_out+single_out_flip ) / 2 + parsing_preds[idx:idx + num_images, :, :] = np.asarray(np.argmax(single_out, axis=3), dtype=np.uint8) + #==================================================================================== + # outputs = model(image.cuda()) + # if gpus > 1: + # for output in outputs: + # parsing = output[0][-1] + # nums = len(parsing) + # parsing = interp(parsing).data.cpu().numpy() + # parsing = parsing.transpose(0, 2, 3, 1) # NCHW NHWC + # parsing_preds[idx:idx + nums, :, :] = np.asarray(np.argmax(parsing, axis=3), dtype=np.uint8) + + # idx += nums + # else: + # parsing = outputs[0][-1] + # parsing = interp(parsing).data.cpu().numpy() + # parsing = parsing.transpose(0, 2, 3, 1) # NCHW NHWC + # parsing_preds[idx:idx + num_images, :, :] = np.asarray(np.argmax(parsing, axis=3), dtype=np.uint8) + + idx += num_images + + parsing_preds = parsing_preds[:num_samples, :, :] + print(f'Parsing preds: {parsing_preds.shape}') + + return parsing_preds, fused_img, scales, centers + +def main(): + """Create the model and start the evaluation process.""" + args = get_arguments() + + os.environ["CUDA_VISIBLE_DEVICES"]=args.gpu + gpus = [int(i) for i in args.gpu.split(',')] + + h, w = map(int, args.input_size.split(',')) + + input_size = (h, w) + + model = Res_Deeplab(num_classes=args.num_classes) + + normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + + transform = transforms.Compose([ + transforms.ToTensor(), + normalize, + ]) + + lip_dataset = LIPDataSet(args.data_dir, 'val', crop_size=input_size, transform=transform) + num_samples = len(lip_dataset) + + valloader = data.DataLoader(lip_dataset, batch_size=args.batch_size * len(gpus), + shuffle=False, pin_memory=True) + + restore_from = args.restore_from + + state_dict = model.state_dict().copy() + state_dict_old = torch.load(restore_from) + + for key, nkey in zip(state_dict_old.keys(), state_dict.keys()): + if key != nkey: + # remove the 'module.' in the 'key' + state_dict[key[7:]] = deepcopy(state_dict_old[key]) + else: + state_dict[key] = deepcopy(state_dict_old[key]) + + model.load_state_dict(state_dict) + + model.eval() + model.cuda() + + parsing_preds, scales, centers = valid(model, valloader, input_size, num_samples, len(gpus)) + + #================================================================= + # list_path = os.path.join(args.data_dir, args.dataset + '_id.txt') + # val_id = [i_id.strip() for i_id in open(list_path)] + # pred_root = os.path.join( args.data_dir, 'pred_parsing') + # if not os.path.exists( pred_root ): + # os.makedirs( pred_root ) + # palette = get_lip_palette() + # output_parsing = parsing_preds + # for i in range( num_samples ): + # output_image = PILImage.fromarray( output_parsing[i] ) + # output_image.putpalette( palette ) + # output_image.save( os.path.join( pred_root, str(val_id[i])+'.png')) + #================================================================= + + mIoU = compute_mean_ioU(parsing_preds, scales, centers, args.num_classes, args.data_dir, input_size) + + print(mIoU) + +if __name__ == '__main__': + main() diff --git a/evaluate_multi.py b/evaluate_multi.py new file mode 100644 index 0000000..956baa0 --- /dev/null +++ b/evaluate_multi.py @@ -0,0 +1,252 @@ +import argparse +import numpy as np +import torch +torch.multiprocessing.set_start_method("spawn", force=True) +from torch.utils import data +from networks.CDGNet import Res_Deeplab +from dataset.datasets import LIPDataValSet +import os +import torchvision.transforms as transforms +from utils.miou import compute_mean_ioU +from copy import deepcopy +import cv2 + +from PIL import Image as PILImage + +DATA_DIRECTORY = '/ssd1/liuting14/Dataset/LIP/' +DATA_LIST_PATH = './dataset/list/lip/valList.txt' +IGNORE_LABEL = 255 +NUM_CLASSES = 20 +SNAPSHOT_DIR = './snapshots/' +INPUT_SIZE = (473,473) + +# colour map +COLORS = [(0,0,0) + # 0=background + ,(128,0,0),(0,128,0),(128,128,0),(0,0,128),(128,0,128) + # 1=aeroplane, 2=bicycle, 3=bird, 4=boat, 5=bottle + ,(0,128,128),(128,128,128),(64,0,0),(192,0,0),(64,128,0) + # 6=bus, 7=car, 8=cat, 9=chair, 10=cow + ,(192,128,0),(64,0,128),(192,0,128),(64,128,128),(192,128,128) + # 11=diningtable, 12=dog, 13=horse, 14=motorbike, 15=person + ,(0,64,0),(128,64,0),(0,192,0),(128,192,0),(0,64,128)] + # 16=potted plant, 17=sheep, 18=sofa, 19=train, 20=tv/monitor +def get_lip_palette(): + palette = [0,0,0, + 128,0,0, + 255,0,0, + 0,85,0, + 170,0,51, + 255,85,0, + 0,0,85, + 0,119,221, + 85,85,0, + 0,85,85, + 85,51,0, + 52,86,128, + 0,128,0, + 0,0,255, + 51,170,221, + 0,255,255, + 85,255,170, + 170,255,85, + 255,255,0, + 255,170,0] + return palette +def get_palette(num_cls): + """ Returns the color map for visualizing the segmentation mask. + + Inputs: + =num_cls= + Number of classes. + + Returns: + The color map. + """ + n = num_cls + palette = [0] * (n * 3) + for j in range(0, n): + lab = j + palette[j * 3 + 0] = 0 + palette[j * 3 + 1] = 0 + palette[j * 3 + 2] = 0 + i = 0 + while lab: + palette[j * 3 + 0] |= (((lab >> 0) & 1) << (7 - i)) + palette[j * 3 + 1] |= (((lab >> 1) & 1) << (7 - i)) + palette[j * 3 + 2] |= (((lab >> 2) & 1) << (7 - i)) + i += 1 + lab >>= 3 + return palette + +def get_arguments(): + """Parse all the arguments provided from the CLI. + + Returns: + A list of parsed arguments. + """ + parser = argparse.ArgumentParser(description="CE2P Network") + parser.add_argument("--batch-size", type=int, default=1, + help="Number of images sent to the network in one step.") + parser.add_argument("--data-dir", type=str, default=DATA_DIRECTORY, + help="Path to the directory containing the PASCAL VOC dataset.") + parser.add_argument("--dataset", type=str, default='val', + help="Path to the file listing the images in the dataset.") + parser.add_argument("--ignore-label", type=int, default=IGNORE_LABEL, + help="The index of the label to ignore during the training.") + parser.add_argument("--num-classes", type=int, default=NUM_CLASSES, + help="Number of classes to predict (including background).") + parser.add_argument("--restore-from", type=str, + help="Where restore model parameters from.") + parser.add_argument("--gpu", type=str, default='0', + help="choose gpu device.") + parser.add_argument("--input-size", type=str, default=INPUT_SIZE, + help="Comma-separated string with height and width of images.") + + return parser.parse_args() + +# def scale_image(image, scale): +# image = image[0, :, :, :] +# image = image.transpose((1, 2, 0)) +# image = cv2.resize(image, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR) +# image = image.transpose((2, 0, 1)) +# return image + +def valid(model, valloader, input_size, num_samples, gpus): + model.eval() + + parsing_preds = np.zeros((num_samples, input_size[0], input_size[1]), + dtype=np.uint8) + + scales = np.zeros((num_samples, 2), dtype=np.float32) + centers = np.zeros((num_samples, 2), dtype=np.int32) + + hpreds_lst = [] + wpreds_lst = [] + + idx = 0 + interp = torch.nn.Upsample(size=(input_size[0], input_size[1]), mode='bilinear', align_corners=True) + eval_scale=[0.75,1.0,1.25] + # eval_scale=[1.0] + flipped_idx = (15, 14, 17, 16, 19, 18) + with torch.no_grad(): + for index, batch in enumerate(valloader): + image, meta = batch + # num_images = image.size(0) + # print( image.size() ) + image = image.squeeze() + if index % 10 == 0: + print('%d processd' % (index * 1)) + c = meta['center'].numpy()[0] + s = meta['scale'].numpy()[0] + scales[idx, :] = s + centers[idx, :] = c + #==================================================================================== + mul_outputs = [] + for scale in eval_scale: + interp_img = torch.nn.Upsample(scale_factor=scale, mode='bilinear', align_corners=True) + scaled_img = interp_img( image ) + # print( scaled_img.size() ) + outputs = model( scaled_img.cuda() ) + prediction = outputs[0][-1] + #========================================================== + hPreds = outputs[2][0] + wPreds = outputs[2][1] + hpreds_lst.append( hPreds[0].data.cpu().numpy() ) + wpreds_lst.append( wPreds[0].data.cpu().numpy() ) + #========================================================== + single_output = prediction[0] + flipped_output = prediction[1] + flipped_output[14:20,:,:]=flipped_output[flipped_idx,:,:] + single_output += flipped_output.flip(dims=[-1]) + single_output *=0.5 + # print( single_output.size() ) + single_output = interp( single_output.unsqueeze(0) ) + mul_outputs.append( single_output[0] ) + fused_prediction = torch.stack( mul_outputs ) + fused_prediction = fused_prediction.mean(0) + fused_prediction = fused_prediction.permute(1, 2, 0) # HWC + fused_prediction = torch.argmax(fused_prediction, dim=2) + fused_prediction = fused_prediction.data.cpu().numpy() + parsing_preds[idx, :, :] = np.asarray(fused_prediction, dtype=np.uint8) + #==================================================================================== + idx += 1 + + parsing_preds = parsing_preds[:num_samples, :, :] + + + return parsing_preds, scales, centers, hpreds_lst, wpreds_lst + +def main(): + """Create the model and start the evaluation process.""" + args = get_arguments() + + os.environ["CUDA_VISIBLE_DEVICES"]=args.gpu + gpus = [int(i) for i in args.gpu.split(',')] + + h, w = map(int, args.input_size.split(',')) + + input_size = (h, w) + + model = Res_Deeplab(num_classes=args.num_classes) + + normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + + transform = transforms.Compose([ + transforms.ToTensor(), + normalize, + ]) + + lip_dataset = LIPDataValSet(args.data_dir, 'val', crop_size=input_size, transform=transform, flip = True ) + num_samples = len(lip_dataset) + + valloader = data.DataLoader(lip_dataset, batch_size=args.batch_size * len(gpus), + shuffle=False, pin_memory=True) + + restore_from = args.restore_from + + state_dict = model.state_dict().copy() + state_dict_old = torch.load(restore_from) + + for key, nkey in zip(state_dict_old.keys(), state_dict.keys()): + if key != nkey: + # remove the 'module.' in the 'key' + state_dict[key[7:]] = deepcopy(state_dict_old[key]) + else: + state_dict[key] = deepcopy(state_dict_old[key]) + + model.load_state_dict(state_dict) + + model.eval() + model.cuda() + + parsing_preds, scales, centers, hpredLst, wpredLst = valid(model, valloader, input_size, num_samples, len(gpus)) + + #================================================================= + # list_path = os.path.join(args.data_dir, args.dataset + '_id.txt') + # val_id = [i_id.strip() for i_id in open(list_path)] + # # pred_root = os.path.join( args.data_dir, 'pred_parsing') + # pred_root = os.path.join( os.getcwd(), 'pred_parsing') + # print( pred_root ) + # if not os.path.exists( pred_root ): + # os.makedirs( pred_root ) + # palette = get_lip_palette() + # output_parsing = parsing_preds + # for i in range( num_samples ): + # output_image = PILImage.fromarray( output_parsing[i] ) + # output_image.putpalette( palette ) + # output_image.save( os.path.join( pred_root, str(val_id[i])+'.png')) + # i=0 + # for i in range(len( hpredLst )): + # filenameh = os.path.join( pred_root, str( val_id[i] ) + "_h" ) + # np.save( filenameh, hpredLst[i] ) + # filenamew = os.path.join( pred_root, str( val_id[i] ) + "_w" ) + # np.save( filenamew, wpredLst[i] ) + #================================================================= + mIoU = compute_mean_ioU(parsing_preds, scales, centers, args.num_classes, args.data_dir, input_size) + + print(mIoU) + +if __name__ == '__main__': + main() diff --git a/networks/.DS_Store b/networks/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..820d82b06924c491bf708e3c1f00a1d3733c7d1d GIT binary patch literal 6148 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 literal 0 HcmV?d00001 diff --git a/networks/__pycache__/CE2P.cpython-38.pyc b/networks/__pycache__/CE2P.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb8c87eb59722e9a16ffa9c9632afcae8e2e0035 GIT binary patch literal 10665 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 jG9vnp{3^2k#O6f%De5v`raIWgo literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f57f139 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +wandb +tqdm \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..7914403 --- /dev/null +++ b/run.sh @@ -0,0 +1,38 @@ +#!/bin/bash +uname -a +#date +#env +date +CS_PATH='/mnt/data/humanparsing/LIP' +LR=3.0e-3 +WD=5e-4 +BS=8 +GPU_IDS=0,1,2,3 +RESTORE_FROM='./dataset/resnet101-imagenet.pth' +INPUT_SIZE='473,473' +SNAPSHOT_DIR='./snapshots' +DATASET='train' +NUM_CLASSES=20 +EPOCHS=150 + +if [[ ! -e ${SNAPSHOT_DIR} ]]; then + mkdir -p ${SNAPSHOT_DIR} +fi + + python -m torch.distributed.launch --nproc_per_node=4 --nnode=1 \ + --node_rank=0 --master_addr=222.32.33.224 --master_port 29500 train.py \ + --data-dir ${CS_PATH} \ + --random-mirror\ + --random-scale\ + --restore-from ${RESTORE_FROM}\ + --gpu ${GPU_IDS}\ + --learning-rate ${LR}\ + --weight-decay ${WD}\ + --batch-size ${BS} \ + --input-size ${INPUT_SIZE}\ + --snapshot-dir ${SNAPSHOT_DIR}\ + --dataset ${DATASET}\ + --num-classes ${NUM_CLASSES} \ + --epochs ${EPOCHS} + +# python evaluate.py diff --git a/run_evaluate.sh b/run_evaluate.sh new file mode 100644 index 0000000..d604a46 --- /dev/null +++ b/run_evaluate.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# CS_PATH='./dataset/LIP' +CS_PATH='/mnt/data/humanparsing/LIP' +BS=1 +GPU_IDS='1' +INPUT_SIZE='473,473' +SNAPSHOT_FROM='./snapshots/LIP_epoch_149.pth' +DATASET='val' +NUM_CLASSES=20 + +CUDA_VISIBLE_DEVICES=1 python evaluate.py --data-dir ${CS_PATH} \ + --gpu ${GPU_IDS} \ + --batch-size ${BS} \ + --input-size ${INPUT_SIZE}\ + --restore-from ${SNAPSHOT_FROM}\ + --dataset ${DATASET}\ + --num-classes ${NUM_CLASSES} diff --git a/run_evaluate_multiScale.sh b/run_evaluate_multiScale.sh new file mode 100644 index 0000000..9c36623 --- /dev/null +++ b/run_evaluate_multiScale.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# CS_PATH='./dataset/LIP' +CS_PATH='/mnt/data/humanparsing/LIP' +# CS_PATH='/mnt/data/humanparsing/CIHP' +BS=1 +GPU_IDS='1' +INPUT_SIZE='473,473' +SNAPSHOT_FROM='./snapshots/LIP_epoch_149.pth' +DATASET='val' +NUM_CLASSES=20 + +CUDA_VISIBLE_DEVICES=1 python evaluate_multi.py --data-dir ${CS_PATH} \ + --gpu ${GPU_IDS} \ + --batch-size ${BS} \ + --input-size ${INPUT_SIZE}\ + --restore-from ${SNAPSHOT_FROM}\ + --dataset ${DATASET}\ + --num-classes ${NUM_CLASSES} diff --git a/sage_train.sh b/sage_train.sh new file mode 100644 index 0000000..7be137f --- /dev/null +++ b/sage_train.sh @@ -0,0 +1,3 @@ +pip3 install -r requirements.txt + +python train_simplified.py \ No newline at end of file diff --git a/trace_model.py b/trace_model.py new file mode 100644 index 0000000..b3a0826 --- /dev/null +++ b/trace_model.py @@ -0,0 +1,120 @@ +import torch +import torch.nn as nn +import torch.nn.functional as fun +import torchvision.transforms as T +import numpy as np +import cv2 +from PIL import Image +import os + +from networks.CDGNet import Res_Deeplab + +net = Res_Deeplab(22).cuda() +net.load_state_dict(torch.load('')) + +data = cv2.imread() +data = cv2.cvtColor(data, cv2.COLOR_BGR2RGB) +data = cv2.resize(data, (512,512)) +data = torch.from_numpy(data[None]).to('cuda') + +def visualize_segmap(input, multi_channel=True, tensor_out=True, batch=0, agnostic = False) : + + if not agnostic: + palette = [ + 0, 0, 0, 128, 0, 0, 254, 0, 0, 0, 85, 0, 169, 0, 51, + 254, 85, 0, 0, 0, 85, 0, 119, 220, 85, 85, 0, 0, 85, 85, + 85, 51, 0, 52, 86, 128, 0, 128, 0, 0, 0, 254, 51, 169, 220, + 0, 254, 254, 85, 254, 169, 169, 254, 85, 254, 254, 0, 254, 169, 0, + 0,0,0,0,0,0,0,0,0 + ] + if agnostic: + palette = [ + 0, 0, 0, 128, 0, 0, 254, 0, 0, 0, 0, 0, 169, 0, 51, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 85, 85, + 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 254, 0, 0, 0, + 0, 0, 0, 85, 254, 169, 169, 254, 85, 254, 254, 0, 254, 169, 0, + 0,0,0,0,0,0,0,0,0 + ] + input = input.detach() + if multi_channel : + input = ndim_tensor2im(input,batch=batch) + else : + input = input[batch][0].cpu() + input = np.asarray(input) + input = input.astype(np.uint8) + input = Image.fromarray(input, 'P') + input.putpalette(palette) + + if tensor_out : + trans = T.ToTensor() + return trans(input.convert('RGB')) + + return input + + +def ndim_tensor2im(image_tensor, imtype=np.uint8, batch=0): + image_numpy = image_tensor[batch].cpu().float().numpy() + result = np.argmax(image_numpy, axis=0) + return result.astype(imtype) + + + +class WrappedModel(nn.Module): + + def __init__(self, model): + + super().__init__() + self.model = model + self.mean = torch.Tensor([0.485, 0.456, 0.406]).cuda().reshape([1, 3, 1, 1]) + self.std = torch.Tensor([0.229, 0.224, 0.225]).cuda().reshape([1, 3, 1, 1]) + + @torch.inference_mode() + def forward(self, data, fp16=True): + + data = data.permute(0, 3, 1, 2).contiguous() + data = data.div(255).sub(self.mean).div_(self.std) + pred = self.model(data) + pred = fun.interpolate(pred[0][-1], (1024, 768), mode = 'bilinear') + + return pred.contiguous() + + +wrp_model = WrappedModel(net).cuda().eval() +torch.cuda.synchronize() + +with torch.no_grad(): + svd_out = wrp_model(data) + +torch.cuda.synchronize() +print(svd_out.shape) + +w1 = visualize_segmap(svd_out, tensor_out = False) +w1.save('w1.png') + +OUT_PATH = "out" +os.makedirs(OUT_PATH, exist_ok=True) + +wrp_model = wrp_model.half() + +with torch.inference_mode(), torch.jit.optimized_execution(True): + traced_script_module = torch.jit.trace(wrp_model, data) + traced_script_module = torch.jit.optimize_for_inference( + traced_script_module) + + +print(traced_script_module.code) +print(f"{OUT_PATH}/model.pt") +traced_script_module.save(f"{OUT_PATH}/model.pt") + +traced_script_module = torch.jit.load(f"{OUT_PATH}/model.pt") + +torch.cuda.synchronize() +with torch.no_grad(): + o = traced_script_module(data) +torch.cuda.synchronize() +print(o.shape) +w2 = visualize_segmap(o, tensor_out = False) +w2.save('w2.png') + + + diff --git a/train.py b/train.py new file mode 100644 index 0000000..65438ad --- /dev/null +++ b/train.py @@ -0,0 +1,359 @@ +import argparse + +import torch +torch.multiprocessing.set_start_method("spawn", force=True) +from torch.utils import data +import numpy as np +from PIL import Image +import torch.optim as optim +import torchvision.utils as vutils +import torch.backends.cudnn as cudnn +import os +import os.path as osp +from tqdm import tqdm +from networks.CDGNet import Res_Deeplab +from dataset.datasets import LIPDataSet +from dataset.target_generation import generate_edge +import torchvision.transforms as transforms +import timeit +import torch.distributed as dist +import wandb +#from tensorboardX import SummaryWriter +from utils.utils import decode_parsing, inv_preprocess +from utils.criterion import CriterionAll +from torch.nn.parallel import DistributedDataParallel as DDP +from torch.utils.data.distributed import DistributedSampler + +from utils.miou import compute_mean_ioU +from evaluate import get_ccihp_pallete, valid + +start = timeit.default_timer() + +BATCH_SIZE = 2 +DATA_DIRECTORY = '/home/vrushank/Spyne/HR-Viton/CCIHP' +#DATA_LIST_PATH = './dataset/list/cityscapes/train.lst' +IGNORE_LABEL = 255 +INPUT_SIZE = '32, 32' +LEARNING_RATE = 3e-4 +MOMENTUM = 0.9 +NUM_CLASSES = 22 +POWER = 0.9 +RANDOM_SEED = 1234 +RESTORE_FROM= '/home/vrushank/Spyne/HR-Viton/CCIHP/resnet101-imagenet.pth' +SAVE_NUM_IMAGES = 2 +SAVE_PRED_EVERY = 10000 +SNAPSHOT_DIR = './snapshots/' +WEIGHT_DECAY = 0.0005 +GPU_IDS = '0' + + + + +def reduce_loss(tensor, rank, world_size): + with torch.no_grad(): + dist.reduce(tensor, dst=0) + if rank == 0: + tensor /= world_size + +def str2bool(v): + if v.lower() in ('yes', 'true', 't', 'y', '1'): + return True + elif v.lower() in ('no', 'false', 'f', 'n', '0'): + return False + else: + raise argparse.ArgumentTypeError('Boolean value expected.') + + +def get_arguments(): + """Parse all the arguments provided from the CLI. + + Returns: + A list of parsed arguments. + """ + parser = argparse.ArgumentParser(description="CE2P Network") + parser.add_argument("--batch-size", type=int, default=BATCH_SIZE, + help="Number of images sent to the network in one step.") + parser.add_argument("--data-dir", type=str, default=DATA_DIRECTORY, + help="Path to the directory containing the dataset.") + parser.add_argument("--dataset", type=str, default='train', choices=['train', 'val', 'trainval', 'test'], + help="Path to the file listing the images in the dataset.") + parser.add_argument("--ignore-label", type=int, default=IGNORE_LABEL, + help="The index of the label to ignore during the training.") + parser.add_argument("--input-size", type=str, default=INPUT_SIZE, + help="Comma-separated string with height and width of images.") + parser.add_argument("--learning-rate", type=float, default=LEARNING_RATE, + help="Base learning rate for training with polynomial decay.") + parser.add_argument("--momentum", type=float, default=MOMENTUM, + help="Momentum component of the optimiser.") + parser.add_argument("--num-classes", type=int, default=NUM_CLASSES, + help="Number of classes to predict (including background).") + parser.add_argument("--start-iters", type=int, default=0, + help="Number of classes to predict (including background).") + parser.add_argument("--power", type=float, default=POWER, + help="Decay parameter to compute the learning rate.") + parser.add_argument("--weight-decay", type=float, default=WEIGHT_DECAY, + help="Regularisation parameter for L2-loss.") + parser.add_argument("--random-mirror", action="store_true", + help="Whether to randomly mirror the inputs during the training.") + parser.add_argument("--random-scale", action="store_true", + help="Whether to randomly scale the inputs during the training.") + parser.add_argument("--random-seed", type=int, default=RANDOM_SEED, + help="Random seed to have reproducible results.") + parser.add_argument("--restore-from", type=str, default=RESTORE_FROM, + help="Where restore model parameters from.") + parser.add_argument("--save-num-images", type=int, default=SAVE_NUM_IMAGES, + help="How many images to save.") + parser.add_argument("--snapshot-dir", type=str, default=SNAPSHOT_DIR, + help="Where to save snapshots of the model.") + parser.add_argument("--gpu", type=str, default=GPU_IDS, + help="choose gpu device.") + parser.add_argument("--start-epoch", type=int, default=0, + help="choose the number of recurrence.") + parser.add_argument("--epochs", type=int, default=150, + help="choose the number of recurrence.") + parser.add_argument('--local_rank', type=int, default = 0, help="local gpu id") + # os.environ['MASTER_ADDR'] = '202.30.29.226' + # os.environ['MASTER_PORT'] = '8888' + return parser.parse_args() + + +args = get_arguments() + + +def lr_poly(base_lr, iter, max_iter, power): + return base_lr * ((1 - float(iter) / max_iter) ** (power)) + + +def adjust_learning_rate(optimizer, i_iter, total_iters): + """Sets the learning rate to the initial LR divided by 5 at 60th, 120th and 160th epochs""" + lr = lr_poly(args.learning_rate, i_iter, total_iters, args.power) + optimizer.param_groups[0]['lr'] = lr + return lr + + +def adjust_learning_rate_pose(optimizer, epoch): + decay = 0 + if epoch + 1 >= 135: + decay = 0.05 + elif epoch + 1 >= 100: + decay = 0.1 + elif epoch + 1 >= 60: + decay = 0.25 + elif epoch + 1 >= 40: + decay = 0.5 + else: + decay = 1 + + lr = args.learning_rate * decay + for param_group in optimizer.param_groups: + param_group['lr'] = lr + return lr + + +def set_bn_eval(m): + classname = m.__class__.__name__ + if classname.find('BatchNorm') != -1: + m.eval() + + +def set_bn_momentum(m): + classname = m.__class__.__name__ + if classname.find('BatchNorm') != -1 or classname.find('InPlaceABN') != -1: + m.momentum = 0.0003 + + +def main(): + """Create the model and start the training.""" + + if not os.path.exists(args.snapshot_dir): + os.makedirs(args.snapshot_dir) + + #writer = SummaryWriter(args.snapshot_dir) + gpus = [int(i) for i in args.gpu.split(',')] + if not args.gpu == 'None': + os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu + + h, w = map(int, args.input_size.split(',')) + input_size = [h, w] + + cudnn.enabled = True + # cudnn related setting + cudnn.benchmark = True + torch.backends.cudnn.deterministic = False + torch.backends.cudnn.enabled = True + + dist.init_process_group( backend='nccl', init_method='env://' ) + torch.cuda.set_device( int(args.local_rank) ) + gloabl_rank = dist.get_rank() + world_size = dist.get_world_size() + print( world_size ) + #if world_size == 1: + # return + #dist.barrier() + print('Loading model') + deeplab = Res_Deeplab(num_classes=args.num_classes) + + saved_state_dict = torch.load(args.restore_from) + new_params = deeplab.state_dict().copy() + for i in saved_state_dict: + i_parts = i.split('.') + # print(i_parts) + if not i_parts[0] == 'fc': + new_params['.'.join(i_parts[0:])] = saved_state_dict[i] + + deeplab.load_state_dict(new_params) + print('Model Loaded') + deeplab.cuda() + #model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(deeplab) + model = DDP(deeplab, device_ids=[args.local_rank], output_device=args.local_rank ) + print(model) + + criterion = CriterionAll() + # criterion = DataParallelCriterion(criterion) + criterion.cuda() + + normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + + transform = transforms.Compose([ + transforms.ToTensor(), + normalize, + ]) + lipDataset = LIPDataSet(args.data_dir, args.dataset, crop_size=[128, 128], transform=transform) + sampler = DistributedSampler(lipDataset) + trainloader = data.DataLoader(lipDataset, + batch_size=args.batch_size, shuffle=False, + sampler = sampler, + num_workers=4, + pin_memory=True) + lip_dataset = LIPDataSet(args.data_dir, 'val', crop_size=input_size, transform=transform) + num_samples = len(lip_dataset) + + valloader = data.DataLoader(lip_dataset, batch_size=args.batch_size * len(gpus), + shuffle=False, pin_memory=True) + + optimizer = optim.Adam( + model.parameters(), + lr=args.learning_rate, + betas= (0.5, 0.999), + weight_decay=args.weight_decay, + ) + scaler = torch.cuda.amp.grad_scaler.GradScaler() + optimizer.zero_grad(set_to_none = True) + total_iters = args.epochs * len(trainloader) + + # path = osp.join( args.snapshot_dir, 'model_LIP'+'.pth') + # if os.path.exists( path ): + # checkpoint = torch.load(path) + # model.load_state_dict(checkpoint['model']) + # optimizer.load_state_dict(checkpoint['optimizer']) + # epoch = checkpoint['epoch'] + # print( epoch ) + # args.start_epoch = epoch + # print( 'Load model first!') + # else: + # print( 'No model exits from beginning!') + + model.train() + for epoch in range(args.start_epoch, args.epochs): + sampler.set_epoch(epoch) + + loop = tqdm(trainloader, position = 0, leave = True) + for i_iter, batch in enumerate(loop): + i_iter += len(trainloader) * epoch + lr = adjust_learning_rate(optimizer, i_iter, total_iters) + + images, labels, hgt, wgt, hwgt, _= batch + labels = labels.cuda(non_blocking=True) + edges = generate_edge(labels) + labels = labels.type(torch.cuda.LongTensor) + edges = edges.type(torch.cuda.LongTensor) + hgt = hgt.float().cuda(non_blocking=True) + wgt = wgt.float().cuda(non_blocking=True) + hwgt = hwgt.float().cuda(non_blocking=True) + optimizer.zero_grad(set_to_none = True) + #[[seg0, seg1, seg2], [edge],[fea_h1,fea_w1]] + with torch.cuda.amp.autocast_mode.autocast(): + preds = model(images) + loss = criterion(preds, [labels, edges],[hgt,wgt,hwgt]) + + scaler.scale(loss).backward() + scaler.step(optimizer) + scaler.update() + torch.cuda.synchronize() + + reduce_loss( loss, gloabl_rank, world_size ) + + if i_iter % 500 == 0: + + wandb.log({'Learning rate': lr, 'Loss': loss.data.cpu().numpy()}) + #writer.add_scalar('learning_rate', lr, i_iter) + #writer.add_scalar('loss', loss.data.cpu().numpy(), i_iter) + + if i_iter % 2000 == 0: + + images_inv = inv_preprocess(images, args.save_num_images) + labels_colors = decode_parsing(labels, args.save_num_images, args.num_classes, is_pred=False) + edges_colors = decode_parsing(edges, args.save_num_images, 2, is_pred=False) + #[[seg0, seg1, seg2], [edge],[fea_h1,fea_w1]] + if isinstance(preds, list): + preds = preds[0] + preds_colors = decode_parsing(preds[-1], args.save_num_images, args.num_classes, is_pred=True) + pred_edges = decode_parsing(preds[-1], args.save_num_images, 2, is_pred=True) + + img = vutils.make_grid(images_inv*255, normalize=False, scale_each=True) + lab = vutils.make_grid(labels_colors, normalize=False, scale_each=True) + pred = vutils.make_grid(preds_colors, normalize=False, scale_each=True) + edge = vutils.make_grid(edges_colors, normalize=False, scale_each=True) + pred_edge = vutils.make_grid(pred_edges, normalize=False, scale_each=True) + + img_wb = wandb.Image(img.to(torch.uint8).cpu().numpy().transpose((1, 2, 0)), caption = f'{i_iter}') + label_wb = wandb.Image(lab.to(torch.uint8).cpu().numpy().transpose((1, 2, 0)), caption = f'{i_iter}') + pred_wb = wandb.Image(pred.to(torch.uint8).cpu().numpy().transpose((1, 2, 0)), caption = f'{i_iter}') + edge_wb = wandb.Image(edge.to(torch.uint8).cpu().numpy().transpose((1, 2, 0)), caption = f'{i_iter}') + pred_edge_wb = wandb.Image(pred_edge.to(torch.uint8).cpu().numpy().transpose((1, 2, 0)), caption = f'{i_iter}') + + wandb.log({ + 'Image': img_wb, + 'Target': label_wb, + 'Pred': pred_wb, + 'Target Edge': edge_wb, + 'Predicted Edge': pred_edge_wb + }) + + + if gloabl_rank == 0 and i_iter % 500 == 0 : + print('Epoch:{} iter = {} of {} completed, loss = {}'.format(epoch, i_iter, total_iters, loss.data.cpu().numpy())) + + if epoch > 140 and gloabl_rank == 0: + torch.save(model.state_dict(), osp.join(args.snapshot_dir, 'CCIHP_epoch_' + str(epoch) + '.pth')) + + if epoch % 5 == 0 and gloabl_rank == 0: + path = osp.join(args.snapshot_dir, 'CCIHP_epoch_' + str(epoch) + '.pth') + state = { 'model': model.state_dict(), 'optimizer':optimizer.state_dict(), 'epoch': epoch } + torch.save(state, path) + + if epoch % 2 == 0: + num_samples = len(lip_dataset) + parsing_preds, scales, centers = valid(model, valloader, input_size, num_samples, len(gpus)) + output_parsing = parsing_preds + mIoU, pixel_acc, mean_acc = compute_mean_ioU(parsing_preds, scales, centers, args.num_classes, args.data_dir, input_size) + print(mIoU) + palette = get_ccihp_pallete() + wandb.log({'Valid MIou': mIoU, 'Valid Pixel Accuracy': pixel_acc, 'Valid Mean Accuracy': mean_acc}) + for i in range(10): + output_image = Image.fromarray( output_parsing[i] ) + output_image.putpalette( palette ) + output_label_wb = wandb.Image(output_image) + wandb.log({'Valid pred': output_label_wb}) + + + + end = timeit.default_timer() + print(end - start, 'seconds') + + +if __name__ == '__main__': + + wandb.init(project="Viton_Segmentation_CDGNet",config={"name": "Virtual Try-on"}) + main() diff --git a/train_simplified.py b/train_simplified.py new file mode 100644 index 0000000..eaf9623 --- /dev/null +++ b/train_simplified.py @@ -0,0 +1,299 @@ +import torch +import torch.nn as nn +import torchvision.transforms as T +import torchvision.utils as vutils +import torch.nn.functional as fun +from torch.utils.data import Dataset, DataLoader +import numpy as np +from PIL import Image +import os +from tqdm import tqdm +import argparse +import wandb + +from networks.CDGNet import Res_Deeplab +from dataset.datasets import LIPDataSet, LIPDataValSet +from dataset.target_generation import generate_edge +from utils.utils import decode_parsing, inv_preprocess, AverageMeter +from utils.criterion import CriterionAll +from utils.miou import compute_mean_ioU +from evaluate import get_ccihp_pallete, valid + + +def get_arguments(): + """Parse all the arguments provided from the CLI. + + Returns: + A list of parsed arguments. + """ + + BATCH_SIZE = 8 + try: + DATA_DIRECTORY = os.environ['SM_CHANNEL_TRAIN'] + except KeyError: + DATA_DIRECTORY = '/home/vrushank/Spyne/HR-Viton/CCIHP' + + IGNORE_LABEL = 255 + INPUT_SIZE = '512, 512' + LEARNING_RATE = 3e-4 + MOMENTUM = 0.9 + NUM_CLASSES = 22 + POWER = 0.9 + RANDOM_SEED = 1234 + try: + RESTORE_FROM= 'resnet101-imagenet.pth' + except FileNotFoundError: + RESTORE_FROM = '/home/vrushank/Spyne/HR-Viton/CCIHP/resnet101-imagenet.pth' + SAVE_NUM_IMAGES = 2 + SAVE_PRED_EVERY = 10000 + try: + SNAPSHOT_DIR = '/opt/ml/checkpoints/' + except KeyError: + SNAPSHOT_DIR = 'snapshots/' + + WEIGHT_DECAY = 0.0005 + + parser = argparse.ArgumentParser(description="CDG Network") + parser.add_argument("--batch-size", type=int, default=BATCH_SIZE, + help="Number of images sent to the network in one step.") + parser.add_argument("--data-dir", type=str, default=DATA_DIRECTORY, + help="Path to the directory containing the dataset.") + parser.add_argument("--dataset", type=str, default='train', choices=['train', 'val', 'trainval', 'test'], + help="Path to the file listing the images in the dataset.") + parser.add_argument("--ignore-label", type=int, default=IGNORE_LABEL, + help="The index of the label to ignore during the training.") + parser.add_argument("--input-size", type=str, default=INPUT_SIZE, + help="Comma-separated string with height and width of images.") + parser.add_argument("--learning-rate", type=float, default=LEARNING_RATE, + help="Base learning rate for training with polynomial decay.") + parser.add_argument("--momentum", type=float, default=MOMENTUM, + help="Momentum component of the optimiser.") + parser.add_argument("--num-classes", type=int, default=NUM_CLASSES, + help="Number of classes to predict (including background).") + parser.add_argument("--start-iters", type=int, default=0, + help="Number of classes to predict (including background).") + parser.add_argument("--power", type=float, default=POWER, + help="Decay parameter to compute the learning rate.") + parser.add_argument("--weight-decay", type=float, default=WEIGHT_DECAY, + help="Regularisation parameter for L2-loss.") + parser.add_argument("--random-mirror", action="store_true", + help="Whether to randomly mirror the inputs during the training.") + parser.add_argument("--random-scale", action="store_true", + help="Whether to randomly scale the inputs during the training.") + parser.add_argument("--random-seed", type=int, default=RANDOM_SEED, + help="Random seed to have reproducible results.") + parser.add_argument("--restore-from", type=str, default=RESTORE_FROM, + help="Where restore model parameters from.") + parser.add_argument("--save-num-images", type=int, default=SAVE_NUM_IMAGES, + help="How many images to save.") + parser.add_argument("--snapshot-dir", type=str, default=SNAPSHOT_DIR, + help="Where to save snapshots of the model.") + parser.add_argument("--start-epoch", type=int, default=0, + help="choose the number of recurrence.") + parser.add_argument("--num_epochs", type=int, default=150, + help="choose the number of recurrence.") + + return parser.parse_args() + + + +def lr_poly(base_lr, iter, max_iter, power): + return base_lr * ((1 - float(iter) / max_iter) ** (power)) + + +def adjust_learning_rate(optimizer, i_iter, total_iters): + """Sets the learning rate to the initial LR divided by 5 at 60th, 120th and 160th epochs""" + args = get_arguments() + lr = lr_poly(args.learning_rate, i_iter, total_iters, args.power) + optimizer.param_groups[0]['lr'] = lr + return lr + + +def set_bn_eval(m): + classname = m.__class__.__name__ + if classname.find('BatchNorm') != -1: + m.eval() + + +def set_bn_momentum(m): + classname = m.__class__.__name__ + if classname.find('BatchNorm') != -1 or classname.find('InPlaceABN') != -1: + m.momentum = 0.0003 + + +def train(loader, valid_loader, model, opt, scaler, criterion, total_iters, epoch, args): + + + model.train() + loop = tqdm(loader, position = 0, leave = True) + loss_ = AverageMeter() + for idx, batch in enumerate(loop): + + idx += len(loader) * epoch + lr = adjust_learning_rate(opt, idx, total_iters) + + imgs, labels, hgt, wgt, hwgt, _ = batch + imgs, labels = imgs.cuda(non_blocking = True), labels.cuda(non_blocking = True) + edges = generate_edge(labels) + labels = labels.type(torch.cuda.LongTensor) #Check LongStorage which torch.cuda recommended + edges = edges.type(torch.cuda.LongTensor) + hgt = hgt.float().cuda(non_blocking = True) + wgt = wgt.float().cuda(non_blocking = True) + hwgt = hwgt.float().cuda(non_blocking = True) + opt.zero_grad(set_to_none = True) + + with torch.cuda.amp.autocast_mode.autocast(): + + preds = model(imgs) + loss = criterion(preds, [labels, edges], [hgt, wgt, hwgt]) + + loss_.update(loss.detach(), imgs.size(0)) + scaler.scale(loss).backward() + scaler.step(opt) + scaler.update() + + if idx % 500 == 0: + + wandb.log({'Training Loss': loss_.avg, 'Learning Rate': lr}) + print(f'Epoch [{epoch}/{args.num_epochs}] iter [{idx}/{len(loader)}] Learning Rate: {lr} Loss: {loss_.avg}') + + if idx % 2000 == 0: + + #print(imgs.shape) + imgs_inv = inv_preprocess(imgs, args.save_num_images) + labels_colors = decode_parsing(labels, args.save_num_images, is_pred = False) + edges_colors = decode_parsing(edges, args.save_num_images, is_pred = False) + #if isinstance(preds, list): + # preds = preds[0] + pred = fun.interpolate(preds[0][-1],(512,512), mode='bilinear', align_corners=True ) + pred_edge = fun.interpolate(preds[1][-1],(512,512), mode='bilinear', align_corners=True ) + preds_colors = decode_parsing(pred, args.save_num_images, is_pred = True) + #Check the position of edges in the list + pred_edges_colors = decode_parsing(pred_edge, args.save_num_images, 2, is_pred = True) + + #preds_colors = fun.interpolate(preds_colors, (512, 512), mode = 'bilinear', align_corners = True) + #pred_edges_colors = fun.interpolate(pred_edges_colors, (512, 512), mode = 'bilinear', align_corners = True) + + img = vutils.make_grid(imgs_inv*255, normalize = False, scale_each = True) + lab = vutils.make_grid(labels_colors, normalize = False, scale_each = True) + pred = vutils.make_grid(preds_colors, normalize = False, scale_each = True) + edge = vutils.make_grid(edges_colors, normalize = False, scale_each = True) + pred_edge = vutils.make_grid(pred_edges_colors, normalize = False, scale_each = True) + + img_wb = wandb.Image(img.to(torch.uint8).cpu().numpy().transpose((1,2,0))) + labels_wb = wandb.Image(lab.to(torch.uint8).cpu().numpy().transpose((1,2,0))) + pred_wb = wandb.Image(pred.to(torch.uint8).cpu().numpy().transpose((1,2,0))) + edge_wb = wandb.Image(edge.to(torch.uint8).cpu().numpy().transpose((1,2,0))) + pred_edge_wb = wandb.Image(pred_edge.to(torch.uint8).cpu().numpy().transpose((1,2,0))) + + wandb.log({ + 'Images': img_wb, + 'Target': labels_wb, + 'Pred': pred_wb, + 'Edges': edge_wb, + 'Pred Edges': pred_edge_wb + }) + + if epoch % 2 == 0: + + num_samples = len(valid_loader) * args.batch_size + parsing_preds, img, scales, centers = valid(model, valid_loader, [512, 512], num_samples, 1) + if isinstance(parsing_preds, np.ndarray): + output_parsing = parsing_preds.copy() + if isinstance(parsing_preds, torch.Tensor): + output_parsing = parsing_preds.clone() + else: + output_parsing = parsing_preds + + mIoU, pixel_acc, mean_acc = compute_mean_ioU(parsing_preds, scales, centers, args.num_classes, args.data_dir, [512, 512]) + print('Printing MIoU Values...') + for k, v in mIoU.items(): + print(f'{k}: {v}') + print(f'Pixel Accuracy: {pixel_acc}') + print(f'Mean Accuracy: {mean_acc}') + palette = get_ccihp_pallete() + wandb.log({ + 'Valid MIoU': mIoU, + 'Valid Pixel Accuracy': pixel_acc, + 'Valid Mean Accuracy': mean_acc + }) + print('Values Logged on wandb') + for i in range(10): + print('Inside Loop') + #ip_img = Image.fromarray(img[i]) + op_img = Image.fromarray(output_parsing[i]) + op_img.putpalette(palette) + #ip_img_wb = wandb.Image(ip_img) + op_label_wb = wandb.Image(op_img) + wandb.log({'Valid Pred': op_label_wb}) + + + + +def main(): + + transform = T.Compose([ + T.ToTensor(), + T.Normalize(mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225]) + ]) + args = get_arguments() + dataset = LIPDataSet(args.data_dir, args.dataset, [512, 512], transform = transform) + train_loader = DataLoader(dataset, + batch_size = args.batch_size, + shuffle = True, + num_workers = 4, + pin_memory = True) + + val_dataset = LIPDataValSet(args.data_dir, transform = transform) + valid_loader = DataLoader(val_dataset, + batch_size = args.batch_size, + shuffle = False, + pin_memory= True) + + model = Res_Deeplab(num_classes = args.num_classes) + print("Loading Model...") + ckpt = torch.load(os.path.join(os.getcwd(), args.restore_from)) + new_params = model.state_dict().copy() + + for i in ckpt: + i_parts = i.split('.') + if not i_parts[0] == 'fc': + new_params['.'.join(i_parts[0:])] = ckpt[i] + + model.load_state_dict(new_params) + model.cuda() + print('Model Loaded.') + + criterion = CriterionAll().cuda() + opt = torch.optim.SGD( + model.parameters(), + lr = args.learning_rate, + momentum = 0.9, + weight_decay = args.weight_decay, + nesterov = True + ) + + scaler = torch.cuda.amp.grad_scaler.GradScaler() + total_iters = len(train_loader) * args.num_epochs + + for epoch in range(args.num_epochs): + + train(train_loader, + valid_loader, + model, + opt, + scaler, + criterion, + total_iters, + epoch, + args + ) + + +if __name__ == '__main__': + + wandb.init(project = 'Human Parsing') + main() + + + \ No newline at end of file diff --git a/try.py b/try.py new file mode 100644 index 0000000..f4e19b2 --- /dev/null +++ b/try.py @@ -0,0 +1,148 @@ +import torch +import torchvision.transforms as T +import torch.nn.functional as fun +import torchvision.transforms as T +import cv2 +import numpy as np +from PIL import Image +import os +import matplotlib.pyplot as plt +from concurrent.futures import ThreadPoolExecutor +from glob import glob +CUDA_LAUNCH_BLOCKING = 1 +from networks.CDGNet import Res_Deeplab +from utils.utils import decode_parsing, decode_parsing_agnostic, inv_preprocess + +imgs = glob('/home/ubuntu/Vrushank/CDGNet/VITON-data/train/image/*') +print(len(imgs)) + +model = Res_Deeplab(22).cuda() +model.load_state_dict(torch.load('/home/ubuntu/Vrushank/CDGNet/snapshots/model_latest.pth')) +print('Done') +model.eval() + +out_dir = '/home/ubuntu/Vrushank/CDGNet/VITON-data/train/image-parse-agnosticv3.2' +#out_dir1 = '/home/ubuntu/Vrushank/CDGNet/VITON-data/train/image-parse-agnostic' +#out_dir2 = '/home/ubuntu/Vrushank/CDGNet/VITON-data/parse-down' + +if not os.path.exists(out_dir): + os.makedirs(out_dir, exist_ok = True) + +#if not os.path.exists(out_dir1): +# os.makedirs(out_dir1, exist_ok = True) + +#if not os.path.exists(out_dir2): +# os.makedirs(out_dir2, exist_ok = True) +def visualize_segmap(input, multi_channel=True, tensor_out=True, batch=0, agnostic = False) : + + if not agnostic: + palette = [ + 0, 0, 0, 128, 0, 0, 254, 0, 0, 0, 85, 0, 169, 0, 51, + 254, 85, 0, 0, 0, 85, 0, 119, 220, 85, 85, 0, 0, 85, 85, + 85, 51, 0, 52, 86, 128, 0, 128, 0, 0, 0, 254, 51, 169, 220, + 0, 254, 254, 85, 254, 169, 169, 254, 85, 254, 254, 0, 254, 169, 0, + 0,0,0,0,0,0,0,0,0 + ] + if agnostic: + palette = [ + 0, 0, 0, 128, 0, 0, 254, 0, 0, 0, 0, 0, 169, 0, 51, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 0, 0, 85, 85, + 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 254, 0, 0, 0, + 0, 0, 0, 85, 254, 169, 169, 254, 85, 254, 254, 0, 254, 169, 0, + 0,0,0,0,0,0,0,0,0 + ] + input = input.detach() + if multi_channel : + input = ndim_tensor2im(input,batch=batch) + else : + input = input[batch][0].cpu() + input = np.asarray(input) + input = input.astype(np.uint8) + input = Image.fromarray(input, 'P') + input.putpalette(palette) + + if tensor_out : + trans = T.ToTensor() + return trans(input.convert('RGB')) + + return input + + +def ndim_tensor2im(image_tensor, imtype=np.uint8, batch=0): + image_numpy = image_tensor[batch].cpu().float().numpy() + result = np.argmax(image_numpy, axis=0) + return result.astype(imtype) + + +transform = T.Compose([ + T.Resize((512, 512)), + T.ToTensor(), + T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) +]) + +def get_outputs(p): + + #og = cv2.imread(p) + #og = cv2.resize(og, (768, 1024)) + name = p.split('/')[-1].split('.')[0] + img = Image.open(p).convert('RGB') + w, h = img.size # + img = transform(img) + img = img.unsqueeze(0).cuda() + + with torch.no_grad(): + + preds = model(img) + + #img_inv = inv_preprocess(img, 1) + pred = fun.interpolate(preds[0][-1], (1024, 768), mode = 'bilinear') + #p1 = pred.squeeze(0).cpu().numpy() + #print(p1.shape) + + label = visualize_segmap(pred, tensor_out=False, agnostic=True) + #print(label.getbands()) + #arr = np.array(label) + #print(arr.max()) + #print(arr) + label.save(f'{out_dir}/{name}.png') + #y = label.cpu().numpy().transpose(2,1,0) + #y = y * 255.0 + #print(type(y)) + #print(y.shape) + #print(y.max()) + #cv2.imwrite('y.png', y) + #y = Image.fromarray(y) + + + #print(y.getbands()) + #y.save('y.png') + #label = decode_parsing(pred, 1, is_pred = True) + #label_ag = decode_parsing_agnostic(pred, 1, is_pred = True) + + #img1 = img_inv.squeeze(0).to(torch.uint8).cpu().numpy().transpose((1,2,0)) + #pred = label.squeeze(0).to(torch.uint8).cpu().numpy().transpose((1,2,0)) + #pred = cv2.cvtColor(pred, cv2.COLOR_RGB2BGR) + #pred = cv2.resize(pred, (w, h)) + #cv2.imwrite('x.png', pred) + #cv2.imwrite(f'{out_dir}/{name}.png', pred) + + #pred1 = label_ag.squeeze(0).to(torch.uint8).cpu().numpy().transpose((1,2,0)) + #pred1 = cv2.cvtColor(pred1, cv2.COLOR_RGB2BGR) + #pred1 = cv2.resize(pred1, (w, h)) + #cv2.imwrite(f'{out_dir1}/{name}.png', pred1) + #pred_gs = np.argmax(pred1, axis = -1) + #pred_gs = (pred_gs / 22) * 255 + #pred_gs = np.expand_dims(pred_gs, axis = -1) + #pred_gs = cv2.resize(pred_gs, (768, 1024)) + #cv2.imwrite(f'{out_dir1}/{name}.png', pred_gs) + #pred_gs_down = cv2.resize(pred_gs, (384, 512)) + #cv2.imwrite(f'{out_dir2}/{name}.png', pred_gs_down) + #print(pred1.shape) + #pred1 = cv2.cvtColor(pred1, cv2.COLOR_RGB2GRAY) + #res = np.concatenate((og, pred1), axis = 1) + +#for p in imgs: +# get_outputs(p) +with ThreadPoolExecutor() as executor: + + executor.map(get_outputs, imgs) \ No newline at end of file diff --git a/utils/.DS_Store b/utils/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..3bbdb5223cbcc6432613be1ad9b92dc48eac9863 GIT binary patch literal 6148 zcmeHKJ5B>J5S@V(kwTG@(pN}NVWQ0ma)5mThlqH-U(bl9L^MVdWKjl0rU#eK+;{|JjnU98HMF5Sss{r7#VN^s zf^2K*=mELE^r{{FRZ&Geo}MdY#4no5DfGgIJe(4DhI0R&#um->n}$Pwv`;c7rA&c108j^xh)?135=7b 0.5: + v = -v + return img.transform(img.size, Image.AFFINE, (1, v, 0, 0, 1, 0), + RESAMPLE_MODE) + +def ShearY(img, v): # [-0.3, 0.3] + assert -0.3 <= v <= 0.3 + if random_mirror and random.random() > 0.5: + v = -v + return img.transform(img.size, Image.AFFINE, (1, 0, 0, v, 1, 0), + RESAMPLE_MODE) + +def TranslateX(img, v): # [-150, 150] => percentage: [-0.45, 0.45] + assert -0.45 <= v <= 0.45 + if random_mirror and random.random() > 0.5: + v = -v + v = v * img.size[0] + return img.transform(img.size, Image.AFFINE, (1, 0, v, 0, 1, 0), + RESAMPLE_MODE) + +def TranslateY(img, v): # [-150, 150] => percentage: [-0.45, 0.45] + assert -0.45 <= v <= 0.45 + if random_mirror and random.random() > 0.5: + v = -v + v = v * img.size[1] + return img.transform(img.size, Image.AFFINE, (1, 0, 0, 0, 1, v), + RESAMPLE_MODE) + +def TranslateXabs(img, v): # [-150, 150] => percentage: [-0.45, 0.45] + assert 0 <= v + if random.random() > 0.5: + v = -v + return img.transform(img.size, Image.AFFINE, (1, 0, v, 0, 1, 0), + RESAMPLE_MODE) + + +def TranslateYabs(img, v): # [-150, 150] => percentage: [-0.45, 0.45] + assert 0 <= v + if random.random() > 0.5: + v = -v + return img.transform(img.size, Image.AFFINE, (1, 0, 0, 0, 1, v), + RESAMPLE_MODE) + +def Rotate(img, v): # [-30, 30] + assert -30 <= v <= 30 + if random_mirror and random.random() > 0.5: + v = -v + return img.rotate(v) + +def AutoContrast(img, _): + return PIL.ImageOps.autocontrast(img,1) + +def Invert(img, _): + return PIL.ImageOps.invert(img) + +def Equalize(img, _): + return PIL.ImageOps.equalize(img) + +def Flip(img, _): # not from the paper + return PIL.ImageOps.mirror(img) + +def Solarize(img, v): # [0, 256] + assert 0 <= v <= 256 + return PIL.ImageOps.solarize(img, v) + +def SolarizeAdd(img, addition=0, threshold=128): + img_np = np.array(img).astype(np.int) + img_np = img_np + addition + img_np = np.clip(img_np, 0, 255) + img_np = img_np.astype(np.uint8) + img = Image.fromarray(img_np) + return PIL.ImageOps.solarize(img, threshold) + +def Posterize(img, v): # [4, 8] + #assert 4 <= v <= 8 + v = int(v) + return PIL.ImageOps.posterize(img, v) + +def Contrast(img, v): # [0.1,1.9] + assert 0.1 <= v <= 1.9 + return PIL.ImageEnhance.Contrast(img).enhance(v) + +def Color(img, v): # [0.1,1.9] + assert 0.1 <= v <= 1.9 + return PIL.ImageEnhance.Color(img).enhance(v) + +def Brightness(img, v): # [0.1,1.9] + assert 0.1 <= v <= 1.9 + return PIL.ImageEnhance.Brightness(img).enhance(v) + +def Sharpness(img, v): # [0.1,1.9] + assert 0.1 <= v <= 1.9 + return PIL.ImageEnhance.Sharpness(img).enhance(v) + +def CutoutAbs(img, v): # [0, 60] => percentage: [0, 0.2] + # assert 0 <= v <= 20 + if v < 0: + return img + w, h = img.size + x0 = np.random.uniform(w) + y0 = np.random.uniform(h) + + x0 = int(max(0, x0 - v / 2.)) + y0 = int(max(0, y0 - v / 2.)) + x1 = min(w, x0 + v) + y1 = min(h, y0 + v) + + xy = (x0, y0, x1, y1) + color = (125, 123, 114) + # color = (0, 0, 0) + img = img.copy() + PIL.ImageDraw.Draw(img).rectangle(xy, color) + return img + +def Cutout(img, v): # [0, 60] => percentage: [0, 0.2] + assert 0.0 <= v <= 0.2 + if v <= 0.: + return img + + v = v * img.size[0] + return CutoutAbs(img, v) + +def TranslateYAbs(img, v): # [-150, 150] => percentage: [-0.45, 0.45] + assert 0 <= v <= 10 + if random.random() > 0.5: + v = -v + return img.transform(img.size, Image.AFFINE, (1, 0, 0, 0, 1, v), + resample=RESAMPLE_MODE) + + +def TranslateXAbs(img, v): # [-150, 150] => percentage: [-0.45, 0.45] + assert 0 <= v <= 10 + if random.random() > 0.5: + v = -v + return img.transform(img.size, Image.AFFINE, (1, 0, v, 0, 1, 0), + resample=RESAMPLE_MODE) + +def Posterize2(img, v): # [0, 4] + assert 0 <= v <= 4 + v = int(v) + return PIL.ImageOps.posterize(img, v) + +def SamplePairing(imgs): # [0, 0.4] + def f(img1, v): + i = np.random.choice(len(imgs)) + img2 = Image.fromarray(imgs[i]) + return Image.blend(img1, img2, v) + + return f + +def augment_list(for_autoaug=True): # 16 oeprations and their ranges + l = [ + (ShearX, -0.3, 0.3), # 0 + (ShearY, -0.3, 0.3), # 1 + (TranslateX, -0.45, 0.45), # 2 + (TranslateY, -0.45, 0.45), # 3 + (Rotate, -30, 30), # 4 + (AutoContrast, 0, 1), # 5 + (Invert, 0, 1), # 6 + (Equalize, 0, 1), # 7 + (Solarize, 0, 256), # 8 + (Posterize, 4, 8), # 9 + (Contrast, 0.1, 1.9), # 10 + (Color, 0.1, 1.9), # 11 + (Brightness, 0.1, 1.9), # 12 + (Sharpness, 0.1, 1.9), # 13 + (Cutout, 0, 0.2), # 14 + # (SamplePairing(imgs), 0, 0.4), # 15 + ] + if for_autoaug: + l += [ + (CutoutAbs, 0, 20), # compatible with auto-augment + (Posterize2, 0, 4), # 9 + (TranslateXAbs, 0, 10), # 9 + (TranslateYAbs, 0, 10), # 9 + ] + return l + +augment_dict = {fn.__name__: (fn, v1, v2) for fn, v1, v2 in augment_list()} + +PARAMETER_MAX = 10 + + +def float_parameter(level, maxval): + return float(level) * maxval / PARAMETER_MAX + + +def int_parameter(level, maxval): + return int(float_parameter(level, maxval)) + +def rand_augment_list(): # 16 oeprations and their ranges + l = [ + (AutoContrast, 0, 1), + (Equalize, 0, 1), + (Invert, 0, 1), + (Rotate, 0, 30), + (Posterize, 0, 4), + (Solarize, 0, 256), + (SolarizeAdd, 0, 110), + (Color, 0.1, 1.9), + (Contrast, 0.1, 1.9), + (Brightness, 0.1, 1.9), + (Sharpness, 0.1, 1.9), + (ShearX, 0., 0.3), + (ShearY, 0., 0.3), + (CutoutAbs, 0, 40), + (TranslateXabs, 0., 100), + (TranslateYabs, 0., 100), + ] + + return l + +def autoaug2fastaa(f): + def autoaug(): + mapper = defaultdict(lambda: lambda x: x) + mapper.update({ + 'ShearX': lambda x: float_parameter(x, 0.3), + 'ShearY': lambda x: float_parameter(x, 0.3), + 'TranslateX': lambda x: int_parameter(x, 10), + 'TranslateY': lambda x: int_parameter(x, 10), + 'Rotate': lambda x: int_parameter(x, 30), + 'Solarize': lambda x: 256 - int_parameter(x, 256), + 'Posterize2': lambda x: 4 - int_parameter(x, 4), + 'Contrast': lambda x: float_parameter(x, 1.8) + .1, + 'Color': lambda x: float_parameter(x, 1.8) + .1, + 'Brightness': lambda x: float_parameter(x, 1.8) + .1, + 'Sharpness': lambda x: float_parameter(x, 1.8) + .1, + 'CutoutAbs': lambda x: int_parameter(x, 20) + }) + + def low_high(name, prev_value): + _, low, high = get_augment(name) + return float(prev_value - low) / (high - low) + + policies = f() + new_policies = [] + for policy in policies: + new_policies.append([(name, pr, low_high(name, mapper[name](level))) for name, pr, level in policy]) + return new_policies + + return autoaug + +# @autoaug2fastaa +def autoaug_imagenet_policies(): + return [ + # [('Posterize2', 0.4, 8), ('Rotate', 0.6, 9)], + [('Solarize', 0.6, 5), ('AutoContrast', 0.6, 5)], + [('Equalize', 0.8, 8), ('Equalize', 0.6, 3)], + #[('Posterize2', 0.6, 7), ('Posterize2', 0.6, 6)], + [('Equalize', 0.4, 7), ('Solarize', 0.2, 4)], + # [('Equalize', 0.4, 4), ('Rotate', 0.8, 8)], + [('Solarize', 0.6, 3), ('Equalize', 0.6, 7)], + [('Posterize2', 0.8, 5), ('Equalize', 1.0, 2)], + # [('Rotate', 0.2, 3), ('Solarize', 0.6, 8)], + [('Equalize', 0.6, 8), ('Posterize2', 0.4, 6)], + # [('Rotate', 0.8, 8), ('Color', 0.4, 0)], + # [('Rotate', 0.4, 9), ('Equalize', 0.6, 2)], + [('Equalize', 0.0, 7), ('Equalize', 0.8, 8)], + [('Invert', 0.6, 4), ('Equalize', 1.0, 8)], + [('Color', 0.6, 4), ('Contrast', 1.0, 8)], + # [('Rotate', 0.8, 8), ('Color', 1.0, 0)], + [('Color', 0.8, 8), ('Solarize', 0.8, 7)], + [('Sharpness', 0.4, 7), ('Invert', 0.6, 8)], + # [('ShearX', 0.6, 5), ('Equalize', 1.0, 9)], + [('Color', 0.4, 0), ('Equalize', 0.6, 3)], + [('Equalize', 0.4, 7), ('Solarize', 0.2, 4)], + [('Solarize', 0.6, 5), ('AutoContrast', 0.6, 5)], + [('Invert', 0.6, 4), ('Equalize', 1.0, 8)], + [('Color', 0.6, 4), ('Contrast', 1.0, 8)], + [('Equalize', 0.8, 8), ('Equalize', 0.6, 3)], + ] + +class ToPIL(object): + """Convert image from ndarray format to PIL + """ + def __call__(self, img): + x = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) + return x + +class ToNDArray(object): + def __call__(self, img): + x = cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR) + return x + +class RandAugment(object): + def __init__(self, n, m): + self.n = n + self.m = m + self.augment_list = rand_augment_list() + self.topil = ToPIL() + + def __call__(self, img): + img = self.topil(img) + ops = random.choices(self.augment_list, k=self.n) + for op, minval, maxval in ops: + if random.random() > random.uniform(0.2, 0.8): + continue + val = (float(self.m) / 30) * float(maxval - minval) + minval + img = op(img, val) + return img + +def get_augment(name): + return augment_dict[name] + + +def apply_augment(img, name, level): + augment_fn, low, high = get_augment(name) + return augment_fn(img.copy(), level * (high - low) + low) +class PILGaussianBlur(ImageFilter.Filter): + name = "GaussianBlur" + def __init__(self, radius=2, bounds=None): + self.radius = radius + self.bounds = bounds + def filter(self, image): + if self.bounds: + clips = image.crop(self.bounds).gaussian_blur(self.radius) + image.paste(clips, self.bounds) + return image + else: + return image.gaussian_blur(self.radius) +class GaussianBlur(object): + def __init__(self, radius=2 ): + self.GaussianBlur=PILGaussianBlur(radius) + def __call__(self, img): + img = img.filter( self.GaussianBlur ) + return img +class AugmentationBlock(object): + r""" + AutoAugment Block + + Example + ------- + >>> from autogluon.utils.augment import AugmentationBlock, autoaug_imagenet_policies + >>> aa_transform = AugmentationBlock(autoaug_imagenet_policies()) + """ + def __init__(self, policies): + """ + plicies : list of (name, pr, level) + """ + super().__init__() + self.policies = policies() + self.topil = ToPIL() + self.tond = ToNDArray() + self.Gaussian_blue = PILGaussianBlur(2) + self.policy = [GaussianBlur(),transforms.ColorJitter( 0.1026, 0.0935, 0.8386, 0.1592 ), + transforms.Grayscale(num_output_channels=3)] + # self.colorAug = transforms.RandomApply([transforms.ColorJitter( 0.1026, 0.0935, 0.8386, 0.1592 )], p=0.5) + def __call__(self, img): + img = self.topil(img) + trans = random.choice(self.policy) + if random.random() >= 0.5: + img = trans( img ) + img = self.tond(img) + return img + + +# augBlock = AugmentationBlock( autoaug_imagenet_policies ) +# plt.figure() +# for i in range(20): +# catAug = augBlock( cat ) +# plt.subplot(4,5,i+1) +# plt.imshow(catAug) + +# plt.show() +# im_path = os.path.join('D:/testPy/839_482127.jpg') +# img = Image.open( im_path ).convert('RGB') + +# factor = random.uniform(-0.4, 0.4) +# imgb = T.adjust_brightness(img, 1 + factor) + +# imgc = transforms.ColorJitter( 0.4,0.4,0.4,0.4 )(img) + +# imgd = transforms.RandomHorizontalFlip()(img) \ No newline at end of file diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/__pycache__/ImgTransforms.cpython-310.pyc b/utils/__pycache__/ImgTransforms.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2581e41300636c254f4a7fc68d91fcdf87f2a82e GIT binary patch literal 13284 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 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/ImgTransforms.cpython-36.pyc b/utils/__pycache__/ImgTransforms.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7a279ec7c1142083dd551b5b5bdb19b369737e4 GIT binary patch literal 14429 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 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/ImgTransforms.cpython-37.pyc b/utils/__pycache__/ImgTransforms.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..09dbf6351a63577332193291fa652c94cf8a1c80 GIT binary patch literal 14153 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 RSlE4&e?9OGddm;};6EIj{?`Bi literal 0 HcmV?d00001 diff --git a/utils/__pycache__/__init__.cpython-310.pyc b/utils/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e444cf495de7590697e7cfa5d64cd9da567d4735 GIT binary patch literal 149 zcmd1j<>g`kg3AgQlR)%i5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!H8enx(7s(x8f zX>mqkUbcR4L1kX5zDJO5SY}Cnp1!k-yI*RFzMg(*NoG#5etdjpUS>&ryk0@&Ee@O9 S{FKt1R6CG~#Y{kgg#iHiQXwb+ literal 0 HcmV?d00001 diff --git a/utils/__pycache__/__init__.cpython-36.pyc b/utils/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52308eaa5d7e53820faf42226d08c649fb4c41f5 GIT binary patch literal 122 zcmXr!<>d-t+?m7x1dl-k3@`#24nSPY0whuxf*CX!{Z=v*frJsnFLnLgyb}HL{Gx0_ x{hZ8FePg`kf*q-$Ng(<$h=2h`Aj1KOi&=m~3PUi1CZpd-5!pP83g5+AQuPg`k0xO{faUl9Jh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2BpKO;XkRlhW; zG_RyoKP9mwQ9mcMRNvXvC_uloBr~U2KR!M)FS8^*Uaz3?7Kcr4eoARhsvXFb&p^xo E0IuL1hX4Qo literal 0 HcmV?d00001 diff --git a/utils/__pycache__/attention.cpython-310.pyc b/utils/__pycache__/attention.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36f254065c9a5296b0af401c8b24758860674351 GIT binary patch literal 9816 zcmb7KS!^6vcCEdudSjEKC~C3C%UDhW8A+r)nIz*lwka<_B#vTfJee9#I<2l|v#H+v zswm1#F_}OHY){~sah9)al6QS`*$xJ#(yv~eL2XyggbuTG>piI%$^aN^0Y!r zo_1)<)9JgRYqE~jbNXKB^$TI4?}vUr2!nnxEcQ!bsb3Du{YqHrSHo(5E}ZMv!dibm zobNA$3;k2!ss3WP*gqYf?k|N)(wB|C&VTpPoiWls-dKompp}% z`Dg(p3wg=YC^;1^qGYknUOtcf>1YZ0CCNX7{F!JO`DMvpjLe%x{p=yvbG<&FdDn;0 zcCVckZ?@mrZV!@fvzK{m!@=FvD0ALyU;An{|8mqECEdI2>&<&NhQl6SOp0E<+sTUx z>({Pb8^&=~cxCNXNz~R9@~;jOH5|PwCBaek;Hb0UMpHHW?WC#=+w=uxUoHGCEekm*+b5MtEsxp+r2i@rB|9s zYjb_5`m51Qb|q@r{Pz4JD;03B;r_uDki^(BQzJD~E43o?92h6EKXMZ*HSe2=v2Pz3 z9edA4Ehn|VW85?zIO~TN+Pzk{vcjk-Gs~RY-DX^OGixwV96_BXaY;D%11BqX2aVQd zb1-Q4!VPa;F;g>FN4*TuPchz=`rgtvi9KAbe zUw-4wFTB-FhJ(v%S6^RmCzrRAZZE#vOcL(qaByk#ZsxUQL+8-R4=7qomS=jV^P{4t zo<{bOE27Tety%`DyXpcSnl)A;wZs>b4^odY%Qx3XtGRa695lsGJxH_Wi!KZylg*>O|&QQtPZ?S$p1IA$9ls z#7>-jH?j`E3#rlYj^zu9zaOMtWNn}Z-WQpVthA8lOG%l071{S~ysgaSs;E1c_**sb zosCbo@N**fBM;^C2gZSg77IT{ol{eF%+$x|e&m6RkN36sW7a#JETv{-FG3>nd7p{E z_4UHK!lD_6Lb!;x9@v=|C#oB@)j8zVd6Kgr_2tZsw?}QIo<%P68;$Oun=~4#!mOJN zRckYIhJ$vTxt(Ue--P(Ilcw;S;>KkKHQX6N^JInAu*Zb3QWlWG8k?PD!f9++9s(3SAfPjY6I548$H=@ZVcnhU05 z*79G~tRlAv8TCGKobhux&+F%svwM1)?=OwlwMBI_zN$!&@7Hk0{{@no`^JIswzFsL z*?Z2On;QFOY95&T5V`|%&qLnM^Wb9ey|M44UjD{S3wfC*Wj@{(q%1(npVSNTdft9f zdM%~}q}X36DQ%V0V(O&sh8A)6BWJHDrKMw~rPSD}q$Tj4u~kiri^dsaj}lZ~H1;aV z9Aw2zD`~l7Q#E{K?Lp@D=Q($z!24;iVS`isb#)2fEv%UNx4S)om|G95%;^uKc2;Tj zx*aIvA=Ivl)fZ3~J7!1Setki`!j@kG$qF&xv5o!xX%_tq$X zV<+?^H`33Yk+5ZBb30G$AfapQghi>j(`asYjw|QF#!&4vRmAzm)XtjqiY9(mej~kv z-=gW8i!3vD7iSnQ@8W?+nH~Vb8;z{kXkb-gP#|4yG~U^6_VgQJclA|_lvQ$RXtjI2 zu|$Yiyo$G4HmE5mBr$o{H!hg9^P)Xk$j)4Lo{N7Hi7|W#TmVAe^8put5yC~}MjoDk z62OK>4F=d)U7Ns0%bDtz=`wEi9$$oxJBAL_?lv^F(SQ{I>Ly-N*!Rinf(*g2d{Ocx z)U^*RsZoBYq>@wx9ZW%oxtUxoncrW)eTp)KHyArYy<~oC5wkD>m(b2y#~*M$r*(aK zYtOvp%$NS3y`AA)B2O?t&u$q#oIQYCHqJrj&J!`ms37uVi5O`@gt(<(#^-2oL9HQKXTpeQ?*~+ z8LVXE)T#y)ZmFP(7-mG2!QHQpRt7~mkO()=s{6N4o~wHrV4kS^1*m?l@O{V_l>Lt!7xYud9_JU_qFFYf z?x*Rx(t*qa2Z&0xMkOf^^70_{_dQDOR)I*fXdKw68$47Nz{>NJ zV7~|q@%KxVtpf``bFY{daU1(UFj{z96(CY^QaeCj)3r-!X%85N+9j!7MeUOAcU&(m zj#CGm_hhvFxdUT*UIz}WPtIsELRy+?IW_VLEs4#w)W`gZ?(=D&*KTVerA!-Jr_#bP zYz?3}Dya$MTd!yp?M|mvw5z5-;a1%C{{`%uw)B=XV76Egk!+BB1qAq+dvXrA zYDXj_b5y&xt%1<%H=_2#!ANTqb(8OIk&wSMsA`aG<}iw9s~0ym^XE=8v|FuBlARo2QB=}++7v+L zP{&YJ;4MM9$aoFX%wJXRMF_+>71XU*l-MMDleK zDoznN8B&GJ9*N@-j#A4Kb7LRGH_E1ezGjQ=og_}t;>BdR7 z^=KTOcv(FRFpHxJEKQ;py=*}}hb7F@2a*yX>wY2ewtSS(UOe)Py!{~ei;B7xczNtw zl|-$1>%x_qNofOW7^;^w0>voN3;8rs+DC4zv!|QpZ=Pk4tU))Yki|ib)gFrx`G9jQ) zZ!qYotf2Gv;Y=dsa8Xld*?{5fCN@GBX6jCan@YhIH40Ncbv7&*NA{Fx0~^TGYMbOP z2~Afe^0tFi-PdsNCer%j5qr=Hh?F=>jTn5Azk@AG(a||z!W7>MjF4S_4|h!0MN3dw zq{BCN&z-P7xr``c>r`JyGQfTQ9y`>wWZA4070Vuy04^x6_zK8a0-`{yNm`K%J`}}{ zG+|HbaNdzUS;~SNH*e@@+5_i^=@c!~!xD&a<4mlDGUwvvGbV>pK0YwVQHaFeN0{S% z6P}V-v#EL2xQ|W#z-+j};r4n9P&v8CA^gZwxMRjWI^c_M`g>?V?)U&t>R$==;#Vr;`)qKL-U3hpFGYifwp2!UumWK2lOO++;N3f&Zz-^=|LHRk9!`Mi< z1=H^wyn7b!M1kQg6w|n6-PN+g<%Jd?1W8gPfxAR(Zej zU9t}21s_@;8i*NK9L_}$1LTkg0aZ(2=#Ce!E`FX;dk0T+xS)!{B zhQ}ZuSRcR|J+L*0*3H9DalzCapl;n#DIVYjvc>~jusow%oWvU3C;X{?9Too;w=m}8 z#_lsmADyd;llW4-&tV*Gzx)Q$M@kN%&zD&6ZIH}tWS*>j44^=O6;Ul2`a{-`O`!hz z8{7i9HFKHUVD8R8Gz)ywyKF?hz-P+iWSr-=eg@7{oc)eq?L{6nWs^p zox8@p)p6o^?H)D|=~Fef?UQgdGkX+|G7ka$wU@8w0+?0EapO=u!j;Uz@8o0kB&7d) zbR&1rM-S`bvo40reo? z#l+pmTX;1V;&EQ&pE4vSSH^hdw2W&)d`(A>8uKUo&m!C ziS7$4T?v7eotxYJuz)8I;v~^%Zft}u8aATP=R;!W9#iUWX45nkoh4+Vv;GMakSLn= zTXf`)_SZS^Y+1aRnt9>VC0MMB@M7q%K(Cd^$De6}eFuI29sAcN7}^JlWsg=)7x8vt zf_b8rpdrKr!&bgGef|Tr^g7fM1%5^&*(l(6e8$&6rZv)@l~^>dCLufM9B3zuA^J#; za-fCs5*(I*@eWKmhSAPNj`E@nb%6P83^DdCMB`LYpqb-&roKq>G)U%bb~|gw!co}i zVLP{Z)bFsC+uD4i+c`XGs1^nsT&$NX>cECVL3m%@AsBxaVUDTy0oJ(yg;QEK zN;m~SPbB~~q1!VM15qvG=nIDi`2m2Bo&tDF^Qs z?5)C`c6$WFRl@*Or*TNlDl#r24nTN?1%E*Dha{BU%o!lSB_f;I{q7*M+xJFO^39FQ z^QnWoyyoT|;o5u;N?0CGPt;T40JSJlY}pee{;GTk?Ys zFSJ%tENkJOxrph!W`gS-{NLjHW^O7xN+!L`zP5H9>@4^!ZMd_NKTot1{u}ki{;mi# zEd^Q$Si~c7p0*O^&|)Ia|BOs(&sqry!oF}^j$=PdaUwlqCqT8OMTj|Ll{}%Kc=FT_ z3J>ROY;gh}Bi_oBIf^IFG7wP>a1uAhS;hTy NSgf6{J-PVA{{sBcW6%Hq literal 0 HcmV?d00001 diff --git a/utils/__pycache__/attention.cpython-36.pyc b/utils/__pycache__/attention.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f1dd56f068dd5d64b64c74caec1ce7df95c52d8 GIT binary patch literal 10138 zcmb_iTZ|lMR<2uDSM_ar#_jPn+41JWHW%A739zss8)qDcUF?ZBPO?jprMKPH)6?y~ z<*#awGpZ4RG1vilSBTpathBHXc|`~z@qhpcc;&SuBqUy#cb@hIzVH0i-P7YqHUg^k zpZf2A)&HM!zH?6XOXYIm-+uVFclS38<3EfemxKIkNYRFA7@-lGeIqdCZUvUy?ZB41 z)5`@pW{d0r!!FkD>{R_bbwCB)%F}NsoF7nR=&mf-< zy@y8dZ0Lst+`sUq5f;PJLnAD;b3OOK4%Sdp4lAgsWHpyivlLcQQ_X6=h??ba1vM*K z&2y+Z71mHwYjc+8Q9d26qP!~Q7f?PEo<;erlwSE?*4o-|8`R~2kp46Quk(e*lwycf2Z3SjJhE*qwRRm ze30g^W0uh*PW?9qciUmu9d_zwTG*ZpTXAW+}hb1sli6L zP+SjNHs2i=nJAC6i4Su!i4~gX!8D=$Bo|wWd0?W=J}^4=zKxud*xxm< zjn3Agg>g6PR+=9-<*8EVZnqiLbE!2PDz2bTljKOaaNS7@-C?7((;N=l{j`X8niuZ1 z6)GE1cdwng{pN>l6@6l;FJRb@zI0_UjIZpD)V=j9{qE$-=JhwX+VPc1-0eqKnsLmd z8x1dyKTO@0oZb>fMIMM@t(vY`u+=5x|6gBToxzNFd36?dbq=JSQ|EEh9JC&)RW=-X zcXfdk7fGHWd6tClr^y;}`uW#G&bj#f&!MJ;G`rj^7rl&3TQmTq-{i4TwmMemZs#5u z+os5#4~?K@&v}Hi4{|uba$3ShUYl-T*T8We8qg_+HB8z4h`B0qhvbvibUhyhCZ1>X zI{L&$48}RIde#93Cr)UdBel+9zI}H;pXBzv*p8u#68iwmlo$;+&iA~;4XtfU%0A1X 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 Zh22hSdA?Uzxwi6^mDZR)1{{Wl*YLox~ literal 0 HcmV?d00001 diff --git a/utils/__pycache__/attention.cpython-37.pyc b/utils/__pycache__/attention.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c991476288548f4d6d909d20a01ffa407b758764 GIT binary patch literal 9961 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 F{u>dPcn<&o literal 0 HcmV?d00001 diff --git a/utils/__pycache__/attention.cpython-38.pyc b/utils/__pycache__/attention.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33daa998413b51610a4098e7e703dfaabeb113c6 GIT binary patch literal 9982 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 AO#lD@ literal 0 HcmV?d00001 diff --git a/utils/__pycache__/criterion.cpython-310.pyc b/utils/__pycache__/criterion.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e2019a0f18e7e111c82dd98af77500798b3f64c GIT binary patch literal 2615 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 G?SBB^t&K4N literal 0 HcmV?d00001 diff --git a/utils/__pycache__/criterion.cpython-37.pyc b/utils/__pycache__/criterion.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1987bb603d5d1d7373102236c92b9dac8cd482b7 GIT binary patch literal 3861 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 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/encoding.cpython-36.pyc b/utils/__pycache__/encoding.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b55c09d55457796e7ad53347a1cf5fccee1e6b9 GIT binary patch literal 10084 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 Lu3wtBt0(>&+k@U_ literal 0 HcmV?d00001 diff --git a/utils/__pycache__/encoding.cpython-37.pyc b/utils/__pycache__/encoding.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c76626aea85daa21d7c5ecde0447a2ca6b138377 GIT binary patch literal 10094 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 d1pcQHn%TN-RP5{}&we=g0s6 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/logger.cpython-36.pyc b/utils/__pycache__/logger.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3bc51550544b0d0d31094994fb6b6196fc4e392 GIT binary patch literal 2876 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 Dd5;by literal 0 HcmV?d00001 diff --git a/utils/__pycache__/loss.cpython-36.pyc b/utils/__pycache__/loss.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..76d018e9da6d1f0e261581cfb1f7311d983b6a58 GIT binary patch literal 3063 zcmZuzTXW<_74Ft;G#Y6bTPjV?)V1EEl^&0?27|qG3ebday%#o$@?93P$U>UhH>x??I^>9aBUFv1Mk^eDa zCbOOqW^p46mgcC>=x@o;K8JS6;gBl#cd{wWF6){BQTOK^Wbf>HRiM6867#F6N`*G(91w={A$W)k40Hk9~HGI=cf;3b;{+W_<7qSu?0298=)l>ZhjGEL`lBJOuOG1eRJ2Goa8cVe7+L5NVI?{q~ zx9(;zb4eL}j^#chFcJf&>Zg;U6g)}`#-9!YWmk(i7XtfIZUotB9Yrs^^7x47${y!s zTq~!Z3SLc>nHIHjXK4`~^EqUX_fJZ3{O*39F7_Y)^y5Qb?=R{!ul93j zcW-_wJgA6mRXzZredxVyS z-Uap{jxA;|^SRkry4<)@3M|v5wzM+y_g3RHoyKjt(4r+xX>O4_r17Mk*-Mf+btiL| zwCTaSE1_N3TTgbFGlo5FeA$Cqy<@Wppxl?ik}~TyY5I^Kzs9?b=3 zX;P~$*mW!>ylw~9xhQbjTty2-6Gf+rp0tDPrNw+vN3Be}_G2!}Bjr7b^OQy7Jf2+G zptwret!uYf%p&cgx~;0poGD9J1>~?G$5B0n5%H5K79u_!1!%tT6-e6_Zs9cgV`%D@{hV9vo(CJ@kO*tsZw+dyKDny)|Xy}n(66$_>#dRQg3B9Am4*oZ!gJ`E@^fXR^k?X z-^TA|Q*MGjoI`ONmTaX4aTn~f;1i6p)j{}&2L9p=$Q#~K7K`gxnaO;iY+wrnx_emh zM+k2sga~gT>>#|2@KppISigqWI|yG#xDTN0xxmovj7u?tcy1+d7Ab3-=DAqMa&Iik zS)@CI7@eMRW#wft0mlW4l?S?r7=Mx`e7L2>Bff=A?;(5>VHaT^0jVe6MReg6VL8Y67w5x+Fb-#Nv54~!;%EW^tC)l-y3J zu9`m|hq?(EbzEUPM;v-K=98NDGV!`h?uGVhgHQP za+k$NLcm>v{!DeMa$L{ir{Wi|2LfZ!(7wV-<+QVDS$Bm%9ZmL0UpkZAN9`*77}(z4&hU)!wDLUj{{b8VegFUf literal 0 HcmV?d00001 diff --git a/utils/__pycache__/loss.cpython-37.pyc b/utils/__pycache__/loss.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..916b3b75248c65ae7cbe75ef9782ab3aa034620b GIT binary patch literal 3080 zcmZuzTXP#p74Dv!Mq`aEU*g=B?5u$$0%Jp#%VGk1Nd<~xF;GxEOl>hWo^DBFk7l$z ztvEKV7aZ89RPhs}NB#r9q-)=(g7OC^Y_?>pTehhabgxSn_Mwr8`qww60yNv#h^xX>>fgJRy_WzKIJUuLUhMvoWGr?5955P%G8Hp{{ z{hSOabD8(79owwM{AVO~Sepg#>#|kWVc|0xd!G}B#4Q-5r`LZy;^Rl6s_Vz46xHPP z0lWATy8QRRq?T6Z}rxPv&j-~ws+__AW7qyD? zkQdq=6jdsrU)c!axlVd&s_aMz=CA15WjkHykx_5Q8pTNR(I}^F&BCpE6 ztDTw`1F-@_3OIctRuOstFu!(^WJOxnN%D8{zx#WmYRvbhhtpC{_gE^^y&|9PJ$n4$ zH+xf=7xi8No$pRg1@Z|ytUCaNcBw}LD*!yZ`{wTNUam94Wn;PtUkkoR@YN3~A&MN4 znJwv&g`0?f%DxL^L>xHGV)k=;=9qHpwNjv(DRq@|WPj?+yjg4J&)U$Vqikhwk~?G; zD0l8I$lQ~yBY#0>E3!3jE9iG&%>&h9?!W?XN3B4sm1BDrLU~7p3(B0^WYz_L2*0Z; zoQDfC>#0EXj$QE&MrUiKQa$DzJAb3%eFX>4$X_fK4lJm@uGZBmjM$Z{YW1Ar*vxxw znX(NSsW)3w!DU;y2DLVTRKdB$tXpKZ33FIi8)|c5&2Fe0Y7=_gQd`(=IocMqUjw4G z4u-IgkpA<*1?(jrt6K>MG{fA*mypoKH_XWcZCLD_Rn-_6IZA<&NDA$W^a&8q zOKYqPl_uH+_PzH&`=Tm}^l4t}7LpQM;Q4F!WW)v6c0CrBZ4?d%uZB!0DB6AAdhCns5m31Wt{5Ohl8%-!OM@2ZmC*b}odI*dj zY(|Y9JO&&^l>pBhJ#>s7I-my|SQvu81HWC>F?s-YGyB*PU#OKO|2u}`J=Ig)CI7oi z{yR(l19MgTn1V(^wT^wt9&_iYfeyd}~1#bV27gVJB`u{x;@k8)^ge;T?$Euw~*dLL(6I7T9OuCm3(*{pe3K`0wA* z4#qrfXOpRRfh`c|?qQpsAiRwbA-sdIjqp{3uOXP|`gOG4Mfe87eE{uF1jcV~P>C@F zbti)hNjrnQD8w3;2Ln-!6EheD>imprr>M#yRGhL@2cV0D@h5r4`_7Q#z5V!GaSt`eHzER|Bgx?tQl8aRG z<{k84Msi$Kyp zQ)$g@yfc8+a1{f?;gSa10^5aa8*IFa(=9mnAi9!162p4`6%Q6JgU|l`awp1mqR~!t z(to2;6PQe$>noh_d^nQP{onJluEb7MO)&bUMSnj^qj6eJ(;|W>nnAcKhtab3Fn_|! zNLCR~vr%L&<=r=izOsPV&0h>6(*?{rt+Ag&4x=?wh^j$^+={kK(=o5NUvzD>(f4#H z_-E4`rj-mu%5?Xmy55E%IcJ{1Y?S?&&|W!4Zkl3&;8p0mDih)>%F|-7Q%@ rPKP{hEe-J%DAeAs%o@!kUe5Z;jpRRUcHyTO<;>g6H}{OWY3%<4ODYbO literal 0 HcmV?d00001 diff --git a/utils/__pycache__/lovasz_losses.cpython-310.pyc b/utils/__pycache__/lovasz_losses.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..535cb34beb3f9f8d3e0d6de441b9759c3c393e66 GIT binary patch literal 7901 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 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/lovasz_losses.cpython-36.pyc b/utils/__pycache__/lovasz_losses.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f2c3d69c386aa39753a0cc0df3e92142f1d7b27 GIT binary patch literal 7826 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 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/lovasz_losses.cpython-37.pyc b/utils/__pycache__/lovasz_losses.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e17eaf8f65590db7b2b044d83fb69ce0c3a62eaa GIT binary patch literal 7821 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 Q)|`baBP(y>>d4gp4O*+Sv;Y7A literal 0 HcmV?d00001 diff --git a/utils/__pycache__/miou.cpython-37.pyc b/utils/__pycache__/miou.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd36a43948ec1af3edb9d26c1279457fbd26a6a5 GIT binary patch literal 5768 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 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/transforms.cpython-36.pyc b/utils/__pycache__/transforms.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..557b2b3c10318b67ad1ed21de4e04d66dc8922b9 GIT binary patch literal 2982 zcma)8&2Jn@6|buPnD%_xG2X< z{fPhd_(v_q{>j!pAN|i!^zTqfCi$36c+5HV1^OZuuJ57m#h&Z?V?PeS_s3xz%0Py1 zSX`4e8KI5R;B*5#HWKL7<;FW9*-*&3Y`o!dLpEg#Qcc;Gn`m2dOWs1;mOFA=eghJl z(tp9aA6!5i*5!6HIo8E^YSMl-DGOylie&aG(^-+D-!4^_oBnW`4-6>1fuMQ#=vWcT zQxyGoR24hL;a&>8ZMYP3{##x#=}GUcxLM2atvB@VvKjl$?<@X{ef?%8E@dkrgS*$} zk>shEvzfOh1KRqkB(uhSZ-oO^{m>Q_^U;STeecij@SVvKH@gIC$&-%H{Cbs=V>r|0%4wWjD^#?_H-u2`5^&R8Z zgmg}2zf6?T)-RJxS(n$R;ZUh*c)fly{FH9)=SOa)MR75XH=5w zVWB4aVR>#h$SnQiWbkqmGxZiK<~MmLJ`r_(pC9o1LJ?;W5(ggz$|_h6Ffgp*a5b+2 ziST$A%tFIY5d>9eyvmz%)c%|g1*kqsAi4D4g|k{!gNuTmvxB155u#p}zk)e};W!y- zTR$$8Ox2f#Ol@P)|3xyMrrpr)j8fB2hQlmR`>O+4Z}4j0*3S}EK5;Bs&)C)%y`#hD z{odh|=Z7zj?B-9udj1UKr(gA696jkBbt70%rP79jG&iZTfgU8|)CSJ;He3XPt!FuT zodU%MZp*k~5=DB@Y-jjI)y7%ut(8{fC7tD?4#;{N6%*Us=K_Blt|)#| zw^#lSyThs$91UoDD~19&%c=%wS3CgSiWf=Ds5Yp^?(Ow?SUG?WYy3H{npmlgU|X$V z>g&4!KU!DZyKF8n4r#Y*GuHOOjJ5ULjP}hLRqzL{{%9JfWP_+`Be1D$%{lC{neVPR zpj=82r`klAH`l`a;?HpD2nF9iKD+SHTo4j>x%vdnCFgIePFJY=V5o1B(0adxphRS8 zljMWcioCS7C8}9}oM~eNhxj&dNM}Wv*&4;G1YFdH<03JS_HFPwRfV=KVmwm76v99C z0rs-npe+*V=n^x!Tk1p7(1gAw}=#y+{6a{X);nJuNSc(I!2K_T!gW6m+ zC$@&!eU-?#MqH;8@u}m1Vm*vhhc+WjyGkv!gW*FI{QwmU@9~JYg)btsk!bU6ep_tu zExyY?!v8I?&-X>h?}=UEX0C2MGCTpg%dUNN3_GQJ4%vYkxgxz0;OkV(1UMdn9Q-K& zb-2vmf`0?Pmj3$JXA4L9>f2aTeGir8M>tJkfNY{PmYX=t)3bhQZk)_+-9)q_%+?Nh z`90p`>c<#gJ3s(}JHU6*L6Y%Z1{JwG3NZODYcMDbWs$(+3~ zO-5H~sUDFa1+>c^JT{S4Byl~B@VZb%nL$i9Q8DCDh%4zfuM2gEF`|NADBUev@8ivA zrYi0C6#?@1klV@SBv~UUVzk-sa7Zqc94h`hNiux1wqQ literal 0 HcmV?d00001 diff --git a/utils/__pycache__/transforms.cpython-37.pyc b/utils/__pycache__/transforms.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..293819448820f7d7ca7426b40f81f68b0e3129ba GIT binary patch literal 2971 zcma)8y>A@H6`z^?xaED3VrYr9UC@S;_#8$ICI!*F>bH~$>3XJSxKHq%3_kQm;^J%M9 zXZZe_etrCLi?M%FGl0BHf6v2W5qvX-@KTLtFe`k z!Pd2TH1b?ru&K8+CVX?ulJt!g_F46vv-jC=@BbPaz%aGvU(~np6_auTy+>JDrtjO6xly8WB~Yprh%FaLv2aV&O8S;w<}F0-+1KhQc=Rqut?ToaA36N@w|C_u;|b zSMl+aNx3^Q*+}mimE^i#sIk6Vp4t_%Qhc2Bo~&Xay@rhWO&*H(MV)`Z_xT4xk)#)r z1RvpMft`Ic468Ui&#OQJEw6%UX!r>*QH927uVX|1ZkW5J;_ zi>hHEAlA$Br?5`YA0-2A>&JzXsrsUjscp>aze+}vv=iEmL2BZp-_P zf0n57ffLbs#SXw(K@cqUann+xcOZwV{i>wKx?yjU2I!ZoQ6-iFNLC zfxnH?=aEqFp%>~0(wvs*!qnspGP?`YZ-E>#H5vCz=p9%0T+Ofe892%C^8l{k198Ep zD5qf+N{&#iRh|?mBb3x$!5U#DHV~@suxZ`Y;JljjH^53&{Y*?7v=aKFSszA67h>8( zxgrB<$?%n!wr;fBu{JoOgVx9jMeh04(tD|FV>I}oXNN$#n_*v6cVX3*EetZx)Sv%BH~B?b?51Fd@T zGu(UHToprG!|YfkvRfmmI}^#N;-SZSXsK=5j7aQt@Td(m?;`0PWGuYRBiMp{*KTsw z5oT-0t^94?b3Fi}EC=Tox)T74 zfY=P#KgCJ9Lg!ZWbhl3ZD%F$G8`}LC<6jumxwAFaXpOioKQuXVVG_rV~C*;m(Fco7wQ0Qpu)XI)@(h- zBhgG$8pn#rNKxb{a;**A<7tK)q73&KaQBr1zJt+B1wyXFhclqtVd+5bXzpf=_Q!>s fjMATzY4s+uCV=0h==P#p(fT@Xz88g25Y_(+A1|q# literal 0 HcmV?d00001 diff --git a/utils/__pycache__/utils.cpython-310.pyc b/utils/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78964dfa6a37aca5aab339bc36d95a4acc9a3b18 GIT binary patch literal 3630 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 hAlHD_J5itOBqTZ_4}<7a4>> net = encoding.nn.DataParallelModel(model, device_ids=[0, 1, 2]) + >>> y = net(x) + """ + def gather(self, outputs, output_device): + return outputs + + def replicate(self, module, device_ids): + modules = super(DataParallelModel, self).replicate(module, device_ids) + execute_replication_callbacks(modules) + return modules + + +class DataParallelCriterion(DataParallel): + """ + Calculate loss in multiple-GPUs, which balance the memory usage for + Semantic Segmentation. + + The targets are splitted across the specified devices by chunking in + the batch dimension. Please use together with :class:`encoding.parallel.DataParallelModel`. + + Reference: + Hang Zhang, Kristin Dana, Jianping Shi, Zhongyue Zhang, Xiaogang Wang, Ambrish Tyagi, + Amit Agrawal. “Context Encoding for Semantic Segmentation. + *The IEEE Conference on Computer Vision and Pattern Recognition (CVPR) 2018* + + Example:: + + >>> net = encoding.nn.DataParallelModel(model, device_ids=[0, 1, 2]) + >>> criterion = encoding.nn.DataParallelCriterion(criterion, device_ids=[0, 1, 2]) + >>> y = net(x) + >>> loss = criterion(y, target) + """ + def forward(self, inputs, *targets, **kwargs): + # input should be already scatterd + # scattering the targets instead + if not self.device_ids: + return self.module(inputs, *targets, **kwargs) + targets, kwargs = self.scatter(targets, kwargs, self.device_ids) + if len(self.device_ids) == 1: + return self.module(inputs, *targets[0], **kwargs[0]) + replicas = self.replicate(self.module, self.device_ids[:len(inputs)]) + outputs = _criterion_parallel_apply(replicas, inputs, targets, kwargs) + return Reduce.apply(*outputs) / len(outputs) + #return self.gather(outputs, self.output_device).mean() + + +def _criterion_parallel_apply(modules, inputs, targets, kwargs_tup=None, devices=None): + assert len(modules) == len(inputs) + assert len(targets) == len(inputs) + if kwargs_tup: + assert len(modules) == len(kwargs_tup) + else: + kwargs_tup = ({},) * len(modules) + if devices is not None: + assert len(modules) == len(devices) + else: + devices = [None] * len(modules) + + lock = threading.Lock() + results = {} + if torch_ver != "0.3": + grad_enabled = torch.is_grad_enabled() + + def _worker(i, module, input, target, kwargs, device=None): + if torch_ver != "0.3": + torch.set_grad_enabled(grad_enabled) + if device is None: + device = get_a_var(input).get_device() + try: + if not isinstance(input, tuple): + input = (input,) + with torch.cuda.device(device): + output = module(*(input + target), **kwargs) + with lock: + results[i] = output + except Exception as e: + with lock: + results[i] = e + + if len(modules) > 1: + threads = [threading.Thread(target=_worker, + args=(i, module, input, target, + kwargs, device),) + for i, (module, input, target, kwargs, device) in + enumerate(zip(modules, inputs, targets, kwargs_tup, devices))] + + for thread in threads: + thread.start() + for thread in threads: + thread.join() + else: + _worker(0, modules[0], inputs[0], kwargs_tup[0], devices[0]) + + outputs = [] + for i in range(len(inputs)): + output = results[i] + if isinstance(output, Exception): + raise output + outputs.append(output) + return outputs + + +########################################################################### +# Adapted from Synchronized-BatchNorm-PyTorch. +# https://github.com/vacancy/Synchronized-BatchNorm-PyTorch +# +class CallbackContext(object): + pass + + +def execute_replication_callbacks(modules): + """ + Execute an replication callback `__data_parallel_replicate__` on each module created + by original replication. + + The callback will be invoked with arguments `__data_parallel_replicate__(ctx, copy_id)` + + Note that, as all modules are isomorphism, we assign each sub-module with a context + (shared among multiple copies of this module on different devices). + Through this context, different copies can share some information. + + We guarantee that the callback on the master copy (the first copy) will be called ahead + of calling the callback of any slave copies. + """ + master_copy = modules[0] + nr_modules = len(list(master_copy.modules())) + ctxs = [CallbackContext() for _ in range(nr_modules)] + + for i, module in enumerate(modules): + for j, m in enumerate(module.modules()): + if hasattr(m, '__data_parallel_replicate__'): + m.__data_parallel_replicate__(ctxs[j], i) + + +def patch_replication_callback(data_parallel): + """ + Monkey-patch an existing `DataParallel` object. Add the replication callback. + Useful when you have customized `DataParallel` implementation. + + Examples: + > sync_bn = SynchronizedBatchNorm1d(10, eps=1e-5, affine=False) + > sync_bn = DataParallel(sync_bn, device_ids=[0, 1]) + > patch_replication_callback(sync_bn) + # this is equivalent to + > sync_bn = SynchronizedBatchNorm1d(10, eps=1e-5, affine=False) + > sync_bn = DataParallelWithCallback(sync_bn, device_ids=[0, 1]) + """ + + assert isinstance(data_parallel, DataParallel) + + old_replicate = data_parallel.replicate + + @functools.wraps(old_replicate) + def new_replicate(module, device_ids): + modules = old_replicate(module, device_ids) + execute_replication_callbacks(modules) + return modules + + data_parallel.replicate = new_replicate \ No newline at end of file diff --git a/utils/logger.py b/utils/logger.py new file mode 100644 index 0000000..6113a37 --- /dev/null +++ b/utils/logger.py @@ -0,0 +1,94 @@ +import os +import sys +import logging + +# from . import pyt_utils +# from utils.pyt_utils import ensure_dir + +_default_level_name = os.getenv('ENGINE_LOGGING_LEVEL', 'INFO') +_default_level = logging.getLevelName(_default_level_name.upper()) + + +class LogFormatter(logging.Formatter): + log_fout = None + date_full = '[%(asctime)s %(lineno)d@%(filename)s:%(name)s] ' + date = '%(asctime)s ' + msg = '%(message)s' + + def format(self, record): + if record.levelno == logging.DEBUG: + mcl, mtxt = self._color_dbg, 'DBG' + elif record.levelno == logging.WARNING: + mcl, mtxt = self._color_warn, 'WRN' + elif record.levelno == logging.ERROR: + mcl, mtxt = self._color_err, 'ERR' + else: + mcl, mtxt = self._color_normal, '' + + if mtxt: + mtxt += ' ' + + if self.log_fout: + self.__set_fmt(self.date_full + mtxt + self.msg) + formatted = super(LogFormatter, self).format(record) + # self.log_fout.write(formatted) + # self.log_fout.write('\n') + # self.log_fout.flush() + return formatted + + self.__set_fmt(self._color_date(self.date) + mcl(mtxt + self.msg)) + formatted = super(LogFormatter, self).format(record) + + return formatted + + if sys.version_info.major < 3: + def __set_fmt(self, fmt): + self._fmt = fmt + else: + def __set_fmt(self, fmt): + self._style._fmt = fmt + + @staticmethod + def _color_dbg(msg): + return '\x1b[36m{}\x1b[0m'.format(msg) + + @staticmethod + def _color_warn(msg): + return '\x1b[1;31m{}\x1b[0m'.format(msg) + + @staticmethod + def _color_err(msg): + return '\x1b[1;4;31m{}\x1b[0m'.format(msg) + + @staticmethod + def _color_omitted(msg): + return '\x1b[35m{}\x1b[0m'.format(msg) + + @staticmethod + def _color_normal(msg): + return msg + + @staticmethod + def _color_date(msg): + return '\x1b[32m{}\x1b[0m'.format(msg) + + +def get_logger(log_dir=None, log_file=None, formatter=LogFormatter): + logger = logging.getLogger() + logger.setLevel(_default_level) + del logger.handlers[:] + + if log_dir and log_file: + if not os.path.isdir(log_dir): + os.makedirs(log_dir) + LogFormatter.log_fout = True + file_handler = logging.FileHandler(log_file, mode='a') + file_handler.setLevel(logging.INFO) + file_handler.setFormatter(formatter) + logger.addHandler(file_handler) + + stream_handler = logging.StreamHandler() + stream_handler.setFormatter(formatter(datefmt='%d %H:%M:%S')) + stream_handler.setLevel(0) + logger.addHandler(stream_handler) + return logger diff --git a/utils/loss.py b/utils/loss.py new file mode 100644 index 0000000..09456e0 --- /dev/null +++ b/utils/loss.py @@ -0,0 +1,93 @@ +import torch +import torch.nn.functional as F +import torch.nn as nn +from torch.autograd import Variable +import numpy as np +import scipy.ndimage as nd + + +class OhemCrossEntropy2d(nn.Module): + + def __init__(self, ignore_label=255, thresh=0.7, min_kept=100000, factor=8): + super(OhemCrossEntropy2d, self).__init__() + self.ignore_label = ignore_label + self.thresh = float(thresh) + # self.min_kept_ratio = float(min_kept_ratio) + self.min_kept = int(min_kept) + self.factor = factor + self.criterion = torch.nn.CrossEntropyLoss(ignore_index=ignore_label) + + def find_threshold(self, np_predict, np_target): + # downsample 1/8 + factor = self.factor + predict = nd.zoom(np_predict, (1.0, 1.0, 1.0/factor, 1.0/factor), order=1) + target = nd.zoom(np_target, (1.0, 1.0/factor, 1.0/factor), order=0) + + n, c, h, w = predict.shape + min_kept = self.min_kept // (factor*factor) #int(self.min_kept_ratio * n * h * w) + + input_label = target.ravel().astype(np.int32) + input_prob = np.rollaxis(predict, 1).reshape((c, -1)) + + valid_flag = input_label != self.ignore_label + valid_inds = np.where(valid_flag)[0] + label = input_label[valid_flag] + num_valid = valid_flag.sum() + if min_kept >= num_valid: + threshold = 1.0 + elif num_valid > 0: + prob = input_prob[:,valid_flag] + pred = prob[label, np.arange(len(label), dtype=np.int32)] + threshold = self.thresh + if min_kept > 0: + k_th = min(len(pred), min_kept)-1 + new_array = np.partition(pred, k_th) + new_threshold = new_array[k_th] + if new_threshold > self.thresh: + threshold = new_threshold + return threshold + + + def generate_new_target(self, predict, target): + np_predict = predict.data.cpu().numpy() + np_target = target.data.cpu().numpy() + n, c, h, w = np_predict.shape + + threshold = self.find_threshold(np_predict, np_target) + + input_label = np_target.ravel().astype(np.int32) + input_prob = np.rollaxis(np_predict, 1).reshape((c, -1)) + + valid_flag = input_label != self.ignore_label + valid_inds = np.where(valid_flag)[0] + label = input_label[valid_flag] + num_valid = valid_flag.sum() + + if num_valid > 0: + prob = input_prob[:,valid_flag] + pred = prob[label, np.arange(len(label), dtype=np.int32)] + kept_flag = pred <= threshold + valid_inds = valid_inds[kept_flag] + print('Labels: {} {}'.format(len(valid_inds), threshold)) + + label = input_label[valid_inds].copy() + input_label.fill(self.ignore_label) + input_label[valid_inds] = label + new_target = torch.from_numpy(input_label.reshape(target.size())).long().cuda(target.get_device()) + + return new_target + + + def forward(self, predict, target, weight=None): + """ + Args: + predict:(n, c, h, w) + target:(n, h, w) + weight (Tensor, optional): a manual rescaling weight given to each class. + If given, has to be a Tensor of size "nclasses" + """ + assert not target.requires_grad + + input_prob = F.softmax(predict, 1) + target = self.generate_new_target(input_prob, target) + return self.criterion(predict, target) diff --git a/utils/lovasz_losses.py b/utils/lovasz_losses.py new file mode 100644 index 0000000..a3f23a5 --- /dev/null +++ b/utils/lovasz_losses.py @@ -0,0 +1,250 @@ +""" +Lovasz-Softmax and Jaccard hinge loss in PyTorch +Maxim Berman 2018 ESAT-PSI KU Leuven (MIT License) +""" + +from __future__ import print_function, division + +import torch +from torch.autograd import Variable +import torch.nn.functional as F +import numpy as np +try: + from itertools import ifilterfalse +except ImportError: # py3k + from itertools import filterfalse as ifilterfalse + + +def lovasz_grad(gt_sorted): + """ + Computes gradient of the Lovasz extension w.r.t sorted errors + See Alg. 1 in paper + """ + p = len(gt_sorted) + gts = gt_sorted.sum() + intersection = gts - gt_sorted.float().cumsum(0) + union = gts + (1 - gt_sorted).float().cumsum(0) + jaccard = 1. - intersection / union + if p > 1: # cover 1-pixel case + jaccard[1:p] = jaccard[1:p] - jaccard[0:-1] + return jaccard + + +def iou_binary(preds, labels, EMPTY=1., ignore=None, per_image=True): + """ + IoU for foreground class + binary: 1 foreground, 0 background + """ + if not per_image: + preds, labels = (preds,), (labels,) + ious = [] + for pred, label in zip(preds, labels): + intersection = ((label == 1) & (pred == 1)).sum() + union = ((label == 1) | ((pred == 1) & (label != ignore))).sum() + if not union: + iou = EMPTY + else: + iou = float(intersection) / float(union) + ious.append(iou) + iou = mean(ious) # mean accross images if per_image + return 100 * iou + + +def iou(preds, labels, C, EMPTY=1., ignore=None, per_image=False): + """ + Array of IoU for each (non ignored) class + """ + if not per_image: + preds, labels = (preds,), (labels,) + ious = [] + for pred, label in zip(preds, labels): + iou = [] + for i in range(C): + if i != ignore: # The ignored label is sometimes among predicted classes (ENet - CityScapes) + intersection = ((label == i) & (pred == i)).sum() + union = ((label == i) | ((pred == i) & (label != ignore))).sum() + if not union: + iou.append(EMPTY) + else: + iou.append(float(intersection) / float(union)) + ious.append(iou) + ious = [mean(iou) for iou in zip(*ious)] # mean accross images if per_image + return 100 * np.array(ious) + + +# --------------------------- BINARY LOSSES --------------------------- + + +def lovasz_hinge(logits, labels, per_image=True, ignore=None): + """ + Binary Lovasz hinge loss + logits: [B, H, W] Variable, logits at each pixel (between -\infty and +\infty) + labels: [B, H, W] Tensor, binary ground truth masks (0 or 1) + per_image: compute the loss per image instead of per batch + ignore: void class id + """ + if per_image: + loss = mean(lovasz_hinge_flat(*flatten_binary_scores(log.unsqueeze(0), lab.unsqueeze(0), ignore)) + for log, lab in zip(logits, labels)) + else: + loss = lovasz_hinge_flat(*flatten_binary_scores(logits, labels, ignore)) + return loss + + +def lovasz_hinge_flat(logits, labels): + """ + Binary Lovasz hinge loss + logits: [P] Variable, logits at each prediction (between -\infty and +\infty) + labels: [P] Tensor, binary ground truth labels (0 or 1) + ignore: label to ignore + """ + if len(labels) == 0: + # only void pixels, the gradients should be 0 + return logits.sum() * 0. + signs = 2. * labels.float() - 1. + errors = (1. - logits * Variable(signs)) + errors_sorted, perm = torch.sort(errors, dim=0, descending=True) + perm = perm.data + gt_sorted = labels[perm] + grad = lovasz_grad(gt_sorted) + loss = torch.dot(F.relu(errors_sorted), Variable(grad)) + return loss + + +def flatten_binary_scores(scores, labels, ignore=None): + """ + Flattens predictions in the batch (binary case) + Remove labels equal to 'ignore' + """ + scores = scores.view(-1) + labels = labels.view(-1) + if ignore is None: + return scores, labels + valid = (labels != ignore) + vscores = scores[valid] + vlabels = labels[valid] + return vscores, vlabels + + +class StableBCELoss(torch.nn.modules.Module): + def __init__(self): + super(StableBCELoss, self).__init__() + def forward(self, input, target): + neg_abs = - input.abs() + loss = input.clamp(min=0) - input * target + (1 + neg_abs.exp()).log() + return loss.mean() + + +def binary_xloss(logits, labels, ignore=None): + """ + Binary Cross entropy loss + logits: [B, H, W] Variable, logits at each pixel (between -\infty and +\infty) + labels: [B, H, W] Tensor, binary ground truth masks (0 or 1) + ignore: void class id + """ + logits, labels = flatten_binary_scores(logits, labels, ignore) + loss = StableBCELoss()(logits, Variable(labels.float())) + return loss + + +# --------------------------- MULTICLASS LOSSES --------------------------- + + +def lovasz_softmax(probas, labels, classes='present', per_image=False, ignore=None): + """ + Multi-class Lovasz-Softmax loss + probas: [B, C, H, W] Variable, class probabilities at each prediction (between 0 and 1). + Interpreted as binary (sigmoid) output with outputs of size [B, H, W]. + labels: [B, H, W] Tensor, ground truth labels (between 0 and C - 1) + classes: 'all' for all, 'present' for classes present in labels, or a list of classes to average. + per_image: compute the loss per image instead of per batch + ignore: void class labels + """ + if per_image: + loss = mean(lovasz_softmax_flat(*flatten_probas(prob.unsqueeze(0), lab.unsqueeze(0), ignore), classes=classes) + for prob, lab in zip(probas, labels)) + else: + loss = lovasz_softmax_flat(*flatten_probas(probas, labels, ignore), classes=classes) + return loss + + +def lovasz_softmax_flat(probas, labels, classes='present'): + """ + Multi-class Lovasz-Softmax loss + probas: [P, C] Variable, class probabilities at each prediction (between 0 and 1) + labels: [P] Tensor, ground truth labels (between 0 and C - 1) + classes: 'all' for all, 'present' for classes present in labels, or a list of classes to average. + """ + if probas.numel() == 0: + # only void pixels, the gradients should be 0 + return probas * 0. + C = probas.size(1) + losses = [] + class_to_sum = list(range(C)) if classes in ['all', 'present'] else classes + for c in class_to_sum: + fg = (labels == c).float() # foreground for class c + if (classes is 'present' and fg.sum() == 0): + continue + if C == 1: + if len(classes) > 1: + raise ValueError('Sigmoid output possible only with 1 class') + class_pred = probas[:, 0] + else: + class_pred = probas[:, c] + errors = (Variable(fg) - class_pred).abs() + errors_sorted, perm = torch.sort(errors, 0, descending=True) + perm = perm.data + fg_sorted = fg[perm] + losses.append(torch.dot(errors_sorted, Variable(lovasz_grad(fg_sorted)))) + return mean(losses) + + +def flatten_probas(probas, labels, ignore=None): + """ + Flattens predictions in the batch + """ + if probas.dim() == 3: + # assumes output of a sigmoid layer + B, H, W = probas.size() + probas = probas.view(B, 1, H, W) + B, C, H, W = probas.size() + probas = probas.permute(0, 2, 3, 1).contiguous().view(-1, C) # B * H * W, C = P, C + labels = labels.view(-1) + if ignore is None: + return probas, labels + valid = (labels != ignore) + vprobas = probas[valid.nonzero().squeeze()] + vlabels = labels[valid] + return vprobas, vlabels + +def xloss(logits, labels, ignore=None): + """ + Cross entropy loss + """ + return F.cross_entropy(logits, Variable(labels), ignore_index=255) + + +# --------------------------- HELPER FUNCTIONS --------------------------- +def isnan(x): + return x != x + + +def mean(l, ignore_nan=False, empty=0): + """ + nanmean compatible with generators. + """ + l = iter(l) + if ignore_nan: + l = ifilterfalse(isnan, l) + try: + n = 1 + acc = next(l) + except StopIteration: + if empty == 'raise': + raise ValueError('Empty mean') + return empty + for n, v in enumerate(l, 2): + acc += v + if n == 1: + return acc + return acc / n diff --git a/utils/miou.py b/utils/miou.py new file mode 100644 index 0000000..286839c --- /dev/null +++ b/utils/miou.py @@ -0,0 +1,204 @@ +import numpy as np +import cv2 +import os +import json +from collections import OrderedDict +import argparse +from PIL import Image as PILImage +from utils.transforms import transform_parsing + +LABELS = ['background', 'hat', 'hair', 'glove', 'sunglasses', 'upperclothes', 'facemask', 'coat', 'socks', 'pants', 'torso-skin', 'scarf', 'skirt', 'face', 'left-arm', 'right-arm', 'left-leg', 'right-leg', 'left-shoe', 'right-shoe', 'bag', 'others'] + +def get_palette(num_cls): + """ Returns the color map for visualizing the segmentation mask. + Args: + num_cls: Number of classes + Returns: + The color map + """ + + n = num_cls + palette = [0] * (n * 3) + for j in range(0, n): + lab = j + palette[j * 3 + 0] = 0 + palette[j * 3 + 1] = 0 + palette[j * 3 + 2] = 0 + i = 0 + while lab: + palette[j * 3 + 0] |= (((lab >> 0) & 1) << (7 - i)) + palette[j * 3 + 1] |= (((lab >> 1) & 1) << (7 - i)) + palette[j * 3 + 2] |= (((lab >> 2) & 1) << (7 - i)) + i += 1 + lab >>= 3 + return palette + +def get_confusion_matrix(gt_label, pred_label, num_classes): + """ + Calcute the confusion matrix by given label and pred + :param gt_label: the ground truth label + :param pred_label: the pred label + :param num_classes: the nunber of class + :return: the confusion matrix + """ + index = (gt_label * num_classes + pred_label).astype('int32') + label_count = np.bincount(index) + confusion_matrix = np.zeros((num_classes, num_classes)) + + for i_label in range(num_classes): + for i_pred_label in range(num_classes): + cur_index = i_label * num_classes + i_pred_label + if cur_index < len(label_count): + confusion_matrix[i_label, i_pred_label] = label_count[cur_index] + + return confusion_matrix + + +def compute_mean_ioU(preds, scales, centers, num_classes, datadir, input_size=[473, 473], dataset='val'): + list_path = os.path.join(datadir, dataset + '_id.txt') + val_id = [i_id.strip() for i_id in open(list_path)] + + confusion_matrix = np.zeros((num_classes, num_classes)) + + for i, im_name in enumerate(val_id): + gt_path = os.path.join(datadir, dataset + '_segmentations', im_name + '.png') + gt = cv2.imread(gt_path, cv2.IMREAD_GRAYSCALE) + h, w = gt.shape + pred_out = preds[i] + s = scales[i] + c = centers[i] + pred = transform_parsing(pred_out, c, s, w, h, input_size) + + gt = np.asarray(gt, dtype=np.int32) + pred = np.asarray(pred, dtype=np.int32) + + ignore_index = gt != 255 + + gt = gt[ignore_index] + pred = pred[ignore_index] + + confusion_matrix += get_confusion_matrix(gt, pred, num_classes) + + pos = confusion_matrix.sum(1) + res = confusion_matrix.sum(0) + tp = np.diag(confusion_matrix) + + pixel_accuracy = (tp.sum() / pos.sum()) * 100 + mean_accuracy = ((tp / np.maximum(1.0, pos)).mean()) * 100 + IoU_array = (tp / np.maximum(1.0, pos + res - tp)) + IoU_array = IoU_array * 100 + mean_IoU = IoU_array.mean() + print('Pixel accuracy: %f \n' % pixel_accuracy) + print('Mean accuracy: %f \n' % mean_accuracy) + print('Mean IoU: %f \n' % mean_IoU) + name_value = [] + + for i, (label, iou) in enumerate(zip(LABELS, IoU_array)): + name_value.append((label, iou)) + + name_value.append(('Pixel accuracy', pixel_accuracy)) + name_value.append(('Mean accuracy', mean_accuracy)) + name_value.append(('Mean IU', mean_IoU)) + name_value = OrderedDict(name_value) + return name_value, pixel_accuracy, mean_accuracy + +def compute_mean_ioU_file(preds_dir, num_classes, datadir, dataset='val'): + list_path = os.path.join(datadir, dataset + '_id.txt') + val_id = [i_id.strip() for i_id in open(list_path)] + + confusion_matrix = np.zeros((num_classes, num_classes)) + + for i, im_name in enumerate(val_id): + gt_path = os.path.join(datadir, dataset + '_segmentations', im_name + '.png') + gt = cv2.imread(gt_path, cv2.IMREAD_GRAYSCALE) + + pred_path = os.path.join(preds_dir, im_name + '.png') + pred = np.asarray(PILImage.open(pred_path)) + + gt = np.asarray(gt, dtype=np.int32) + pred = np.asarray(pred, dtype=np.int32) + + ignore_index = gt != 255 + + gt = gt[ignore_index] + pred = pred[ignore_index] + + confusion_matrix += get_confusion_matrix(gt, pred, num_classes) + + pos = confusion_matrix.sum(1) + res = confusion_matrix.sum(0) + tp = np.diag(confusion_matrix) + + pixel_accuracy = (tp.sum() / pos.sum())*100 + mean_accuracy = ((tp / np.maximum(1.0, pos)).mean())*100 + IoU_array = (tp / np.maximum(1.0, pos + res - tp)) + IoU_array = IoU_array*100 + mean_IoU = IoU_array.mean() + print('Pixel accuracy: %f \n' % pixel_accuracy) + print('Mean accuracy: %f \n' % mean_accuracy) + print('Mean IU: %f \n' % mean_IoU) + name_value = [] + + for i, (label, iou) in enumerate(zip(LABELS, IoU_array)): + name_value.append((label, iou)) + + name_value.append(('Pixel accuracy', pixel_accuracy)) + name_value.append(('Mean accuracy', mean_accuracy)) + name_value.append(('Mean IU', mean_IoU)) + name_value = OrderedDict(name_value) + return name_value + +def write_results(preds, scales, centers, datadir, dataset, result_dir, input_size=[473, 473]): + palette = get_palette(20) + if not os.path.exists(result_dir): + os.makedirs(result_dir) + + json_file = os.path.join(datadir, 'annotations', dataset + '.json') + with open(json_file) as data_file: + data_list = json.load(data_file) + data_list = data_list['root'] + for item, pred_out, s, c in zip(data_list, preds, scales, centers): + im_name = item['im_name'] + w = item['img_width'] + h = item['img_height'] + pred = transform_parsing(pred_out, c, s, w, h, input_size) + #pred = pred_out + save_path = os.path.join(result_dir, im_name[:-4]+'.png') + + output_im = PILImage.fromarray(np.asarray(pred, dtype=np.uint8)) + output_im.putpalette(palette) + output_im.save(save_path) + +def get_arguments(): + """Parse all the arguments provided from the CLI. + + Returns: + A list of parsed arguments. + """ + parser = argparse.ArgumentParser(description="DeepLabLFOV NetworkEv") + parser.add_argument("--pred-path", type=str, default='', + help="Path to predicted segmentation.") + parser.add_argument("--gt-path", type=str, default='', + help="Path to the groundtruth dir.") + + return parser.parse_args() + + +if __name__ == "__main__": + args = get_arguments() + palette = get_palette(20) + # im_path = '/ssd1/liuting14/Dataset/LIP/val_segmentations/100034_483681.png' + # #compute_mean_ioU_file(args.pred_path, 20, args.gt_path, 'val') + # im = cv2.imread(im_path, cv2.IMREAD_GRAYSCALE) + # print(im.shape) + # test = np.asarray( PILImage.open(im_path)) + # print(test.shape) + # if im.all()!=test.all(): + # print('different') + # output_im = PILImage.fromarray(np.zeros((100,100), dtype=np.uint8)) + # output_im.putpalette(palette) + # output_im.save('test.png') + pred_dir = '/ssd1/liuting14/exps/lip/snapshots/results/epoch4/' + num_classes = 20 + datadir = '/ssd1/liuting14/Dataset/LIP/' + compute_mean_ioU_file(pred_dir, num_classes, datadir, dataset='val') \ No newline at end of file diff --git a/utils/pyt_utils.py b/utils/pyt_utils.py new file mode 100644 index 0000000..ecb239a --- /dev/null +++ b/utils/pyt_utils.py @@ -0,0 +1,217 @@ +# encoding: utf-8 +import os +import sys +import time +import argparse +from collections import OrderedDict, defaultdict + +import torch +import torch.utils.model_zoo as model_zoo +import torch.distributed as dist + +from .logger import get_logger + +logger = get_logger() + +# colour map +label_colours = [(0,0,0) + # 0=background + ,(128,0,0),(0,128,0),(128,128,0),(0,0,128),(128,0,128) + # 1=aeroplane, 2=bicycle, 3=bird, 4=boat, 5=bottle + ,(0,128,128),(128,128,128),(64,0,0),(192,0,0),(64,128,0) + # 6=bus, 7=car, 8=cat, 9=chair, 10=cow + ,(192,128,0),(64,0,128),(192,0,128),(64,128,128),(192,128,128) + # 11=diningtable, 12=dog, 13=horse, 14=motorbike, 15=person + ,(0,64,0),(128,64,0),(0,192,0),(128,192,0),(0,64,128)] + # 16=potted plant, 17=sheep, 18=sofa, 19=train, 20=tv/monitor + + +def reduce_tensor(tensor, dst=0, op=dist.ReduceOp.SUM, world_size=1): + tensor = tensor.clone() + dist.reduce(tensor, dst, op) + if dist.get_rank() == dst: + tensor.div_(world_size) + + return tensor + + +def all_reduce_tensor(tensor, op=dist.ReduceOp.SUM, world_size=1, norm=True): + tensor = tensor.clone() + dist.all_reduce(tensor, op) + if norm: + tensor.div_(world_size) + + return tensor + + +def load_model(model, model_file, is_restore=False): + t_start = time.time() + if isinstance(model_file, str): + device = torch.device('cpu') + state_dict = torch.load(model_file, map_location=device) + if 'model' in state_dict.keys(): + state_dict = state_dict['model'] + else: + state_dict = model_file + t_ioend = time.time() + + if is_restore: + new_state_dict = OrderedDict() + for k, v in state_dict.items(): + name = 'module.' + k + new_state_dict[name] = v + state_dict = new_state_dict + + model.load_state_dict(state_dict, strict=False) + ckpt_keys = set(state_dict.keys()) + own_keys = set(model.state_dict().keys()) + missing_keys = own_keys - ckpt_keys + unexpected_keys = ckpt_keys - own_keys + + if len(missing_keys) > 0: + logger.warning('Missing key(s) in state_dict: {}'.format( + ', '.join('{}'.format(k) for k in missing_keys))) + + if len(unexpected_keys) > 0: + logger.warning('Unexpected key(s) in state_dict: {}'.format( + ', '.join('{}'.format(k) for k in unexpected_keys))) + + del state_dict + t_end = time.time() + logger.info( + "Load model, Time usage:\n\tIO: {}, initialize parameters: {}".format( + t_ioend - t_start, t_end - t_ioend)) + + return model + + +def parse_devices(input_devices): + if input_devices.endswith('*'): + devices = list(range(torch.cuda.device_count())) + return devices + + devices = [] + for d in input_devices.split(','): + if '-' in d: + start_device, end_device = d.split('-')[0], d.split('-')[1] + assert start_device != '' + assert end_device != '' + start_device, end_device = int(start_device), int(end_device) + assert start_device < end_device + assert end_device < torch.cuda.device_count() + for sd in range(start_device, end_device + 1): + devices.append(sd) + else: + device = int(d) + assert device < torch.cuda.device_count() + devices.append(device) + + logger.info('using devices {}'.format( + ', '.join([str(d) for d in devices]))) + + return devices + + +def extant_file(x): + """ + 'Type' for argparse - checks that file exists but does not open. + """ + if not os.path.exists(x): + # Argparse uses the ArgumentTypeError to give a rejection message like: + # error: argument input: x does not exist + raise argparse.ArgumentTypeError("{0} does not exist".format(x)) + return x + + +def link_file(src, target): + if os.path.isdir(target) or os.path.isfile(target): + os.remove(target) + os.system('ln -s {} {}'.format(src, target)) + + +def ensure_dir(path): + if not os.path.isdir(path): + os.makedirs(path) + + +def _dbg_interactive(var, value): + from IPython import embed + embed() + +def decode_labels(mask, num_images=1, num_classes=21): + """Decode batch of segmentation masks. + + Args: + mask: result of inference after taking argmax. + num_images: number of images to decode from the batch. + num_classes: number of classes to predict (including background). + + Returns: + A batch with num_images RGB images of the same size as the input. + """ + mask = mask.data.cpu().numpy() + n, h, w = mask.shape + assert(n >= num_images), 'Batch size %d should be greater or equal than number of images to save %d.' % (n, num_images) + outputs = np.zeros((num_images, h, w, 3), dtype=np.uint8) + for i in range(num_images): + img = Image.new('RGB', (len(mask[i, 0]), len(mask[i]))) + pixels = img.load() + for j_, j in enumerate(mask[i, :, :]): + for k_, k in enumerate(j): + if k < num_classes: + pixels[k_,j_] = label_colours[k] + outputs[i] = np.array(img) + return outputs + +def decode_predictions(preds, num_images=1, num_classes=21): + """Decode batch of segmentation masks. + + Args: + mask: result of inference after taking argmax. + num_images: number of images to decode from the batch. + num_classes: number of classes to predict (including background). + + Returns: + A batch with num_images RGB images of the same size as the input. + """ + if isinstance(preds, list): + preds_list = [] + for pred in preds: + preds_list.append(pred[-1].data.cpu().numpy()) + preds = np.concatenate(preds_list, axis=0) + else: + preds = preds.data.cpu().numpy() + + preds = np.argmax(preds, axis=1) + n, h, w = preds.shape + assert(n >= num_images), 'Batch size %d should be greater or equal than number of images to save %d.' % (n, num_images) + outputs = np.zeros((num_images, h, w, 3), dtype=np.uint8) + for i in range(num_images): + img = Image.new('RGB', (len(preds[i, 0]), len(preds[i]))) + pixels = img.load() + for j_, j in enumerate(preds[i, :, :]): + for k_, k in enumerate(j): + if k < num_classes: + pixels[k_,j_] = label_colours[k] + outputs[i] = np.array(img) + return outputs + +def inv_preprocess(imgs, num_images, img_mean): + """Inverse preprocessing of the batch of images. + Add the mean vector and convert from BGR to RGB. + + Args: + imgs: batch of input images. + num_images: number of images to apply the inverse transformations on. + img_mean: vector of mean colour values. + + Returns: + The batch of the size num_images with the same spatial dimensions as the input. + """ + imgs = imgs.data.cpu().numpy() + n, c, h, w = imgs.shape + assert(n >= num_images), 'Batch size %d should be greater or equal than number of images to save %d.' % (n, num_images) + outputs = np.zeros((num_images, h, w, c), dtype=np.uint8) + for i in range(num_images): + outputs[i] = (np.transpose(imgs[i], (1,2,0)) + img_mean).astype(np.uint8) + return outputs diff --git a/utils/transforms.py b/utils/transforms.py new file mode 100644 index 0000000..da53eee --- /dev/null +++ b/utils/transforms.py @@ -0,0 +1,113 @@ +# ------------------------------------------------------------------------------ +# Copyright (c) Microsoft +# Licensed under the MIT License. +# Written by Bin Xiao (Bin.Xiao@microsoft.com) +# ------------------------------------------------------------------------------ + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import cv2 + + +def flip_back(output_flipped, matched_parts): + ''' + ouput_flipped: numpy.ndarray(batch_size, num_joints, height, width) + ''' + assert output_flipped.ndim == 4,\ + 'output_flipped should be [batch_size, num_joints, height, width]' + + output_flipped = output_flipped[:, :, :, ::-1] + + for pair in matched_parts: + tmp = output_flipped[:, pair[0], :, :].copy() + output_flipped[:, pair[0], :, :] = output_flipped[:, pair[1], :, :] + output_flipped[:, pair[1], :, :] = tmp + + return output_flipped + + +def transform_parsing(pred, center, scale, width, height, input_size): + + trans = get_affine_transform(center, scale, 0, input_size, inv=1) + target_pred = cv2.warpAffine( + pred, + trans, + (int(width), int(height)), #(int(width), int(height)), + flags=cv2.INTER_NEAREST, + borderMode=cv2.BORDER_CONSTANT, + borderValue=(0)) + + return target_pred + + +def get_affine_transform(center, + scale, + rot, + output_size, + shift=np.array([0, 0], dtype=np.float32), + inv=0): + if not isinstance(scale, np.ndarray) and not isinstance(scale, list): + print(scale) + scale = np.array([scale, scale]) + + scale_tmp = scale + + src_w = scale_tmp[0] + dst_w = output_size[1] + dst_h = output_size[0] + + rot_rad = np.pi * rot / 180 + src_dir = get_dir([0, src_w * -0.5], rot_rad) + dst_dir = np.array([0, dst_w * -0.5], np.float32) + + src = np.zeros((3, 2), dtype=np.float32) + dst = np.zeros((3, 2), dtype=np.float32) + src[0, :] = center + scale_tmp * shift + src[1, :] = center + src_dir + scale_tmp * shift + dst[0, :] = [dst_w * 0.5, dst_h * 0.5] + dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5]) + dst_dir + + src[2:, :] = get_3rd_point(src[0, :], src[1, :]) + dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) + + if inv: + trans = cv2.getAffineTransform(np.float32(dst), np.float32(src)) + else: + trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) + + return trans + + +def affine_transform(pt, t): + new_pt = np.array([pt[0], pt[1], 1.]).T + new_pt = np.dot(t, new_pt) + return new_pt[:2] + + +def get_3rd_point(a, b): + direct = a - b + return b + np.array([-direct[1], direct[0]], dtype=np.float32) + + +def get_dir(src_point, rot_rad): + sn, cs = np.sin(rot_rad), np.cos(rot_rad) + + src_result = [0, 0] + src_result[0] = src_point[0] * cs - src_point[1] * sn + src_result[1] = src_point[0] * sn + src_point[1] * cs + + return src_result + + +def crop(img, center, scale, output_size, rot=0): + trans = get_affine_transform(center, scale, rot, output_size) + + dst_img = cv2.warpAffine(img, + trans, + (int(output_size[1]), int(output_size[0])), + flags=cv2.INTER_LINEAR) + + return dst_img diff --git a/utils/utils.py b/utils/utils.py new file mode 100644 index 0000000..0a709ea --- /dev/null +++ b/utils/utils.py @@ -0,0 +1,83 @@ +from PIL import Image +import numpy as np +import torchvision +import torch + +# colour map +COLORS = [[120, 120, 120], [127, 0, 0], [254, 0, 0], [0, 84, 0], [169, 0, 50], [254, 84, 0], [255, 0, 84], [0, 118, 220], [84, 84, 0], [0, 84, 84], [84, 50, 0], [51, 85, 127], [0, 127, 0], [0, 0, 254], [50, 169, 220], [0, 254, 254], [84, 254, 169], [169, 254, 84], [254, 254, 0], [254, 169, 0], [102, 254, 0], [182, 255, 0]] + # 16=potted plant, 17=sheep, 18=sofa, 19=train, 20=tv/monitor + + +def decode_parsing(labels, num_images=1, num_classes=22, is_pred=False): + """Decode batch of segmentation masks. + + Args: + mask: result of inference after taking argmax. + num_images: number of images to decode from the batch. + num_classes: number of classes to predict (including background). + + Returns: + A batch with num_images RGB images of the same size as the input. + """ + pred_labels = labels[:num_images].clone().cpu().data + if is_pred: + pred_labels = torch.argmax(pred_labels, dim=1) + n, h, w = pred_labels.size() + + labels_color = torch.zeros([n, 3, h, w], dtype=torch.uint8) + for i, c in enumerate(COLORS): + c0 = labels_color[:, 0, :, :] + c1 = labels_color[:, 1, :, :] + c2 = labels_color[:, 2, :, :] + + c0[pred_labels == i] = c[0] + c1[pred_labels == i] = c[1] + c2[pred_labels == i] = c[2] + + return labels_color + +def inv_preprocess(imgs, num_images): + """Inverse preprocessing of the batch of images. + Add the mean vector and convert from BGR to RGB. + + Args: + imgs: batch of input images. + num_images: number of images to apply the inverse transformations on. + img_mean: vector of mean colour values. + + Returns: + The batch of the size num_images with the same spatial dimensions as the input. + """ + rev_imgs = imgs[:num_images].clone().cpu().data + rev_normalize = NormalizeInverse(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + for i in range(num_images): + rev_imgs[i] = rev_normalize(rev_imgs[i]) + + return rev_imgs + +class NormalizeInverse(torchvision.transforms.Normalize): + """ + Undoes the normalization and returns the reconstructed images in the input domain. + """ + + def __init__(self, mean, std): + mean = torch.as_tensor(mean) + std = torch.as_tensor(std) + std_inv = 1 / (std + 1e-7) + mean_inv = -mean * std_inv + super().__init__(mean=mean_inv, std=std_inv) + + +class AverageMeter: + def __init__(self, name=None): + self.name = name + self.reset() + + def reset(self): + self.sum = self.count = self.avg = 0 + + def update(self, val, n=1): + self.sum += val * n + self.count += n + self.avg = self.sum / self.count diff --git a/utils/writejson.py b/utils/writejson.py new file mode 100644 index 0000000..69aca6b --- /dev/null +++ b/utils/writejson.py @@ -0,0 +1,21 @@ +import json +import os +import cv2 + +json_file = os.path.join('/ssd1/liuting14/Dataset/LIP', 'annotations', 'test.json') + +with open(json_file) as data_file: + data_json = json.load(data_file) + data_list = data_json['root'] + +for item in data_list: + name = item['im_name'] + im_path = os.path.join('/ssd1/liuting14/Dataset/LIP', 'test_images', name) + im = cv2.imread(im_path, cv2.IMREAD_COLOR) + h, w, c = im.shape + item['img_height'] = h + item['img_width'] = w + item['center'] = [h/2, w/2] + +with open(json_file, "w") as f: + json.dump(data_json, f, indent=2)