From 0df2b0019b8193071882bf075d3b61ea561f39d0 Mon Sep 17 00:00:00 2001 From: samarthjain2023 Date: Sat, 27 Sep 2025 12:14:26 -0400 Subject: [PATCH] added the model --- .gitignore | 3 +- roadcast/README.md | 74 ++++ roadcast/__pycache__/app.cpython-312.pyc | Bin 0 -> 7093 bytes roadcast/__pycache__/data.cpython-312.pyc | Bin 0 -> 23389 bytes .../__pycache__/inference.cpython-312.pyc | Bin 0 -> 2474 bytes roadcast/__pycache__/models.cpython-312.pyc | Bin 0 -> 4036 bytes .../openweather_inference.cpython-312.pyc | Bin 0 -> 16270 bytes roadcast/app.py | 123 ++++++ roadcast/check_env.py | 32 ++ roadcast/data.py | 413 ++++++++++++++++++ roadcast/debug_labels.py | 76 ++++ roadcast/diagnostics.py | 67 +++ roadcast/fit_kmeans.py | 65 +++ roadcast/inference.py | 30 ++ roadcast/inspect_csv.py | 34 ++ roadcast/kmeans_centers.npz | Bin 0 -> 19190 bytes roadcast/kmeans_centers_all.npz | Bin 0 -> 3432 bytes roadcast/kmeans_centers_best.npz | Bin 0 -> 2628 bytes roadcast/kmeans_centers_final.npz | Bin 0 -> 3305 bytes roadcast/kmeans_centers_nb10.npz | Bin 0 -> 2628 bytes roadcast/model.pth | Bin 0 -> 199933 bytes roadcast/models.py | 68 +++ roadcast/openweather_inference.py | 339 ++++++++++++++ roadcast/requirements.txt | 5 + roadcast/run_batch_inference.py | 113 +++++ roadcast/tests/smoke_predict.py | 23 + roadcast/tmp_infer.csv | 11 + roadcast/train.py | 158 +++++++ 28 files changed, 1633 insertions(+), 1 deletion(-) create mode 100644 roadcast/README.md create mode 100644 roadcast/__pycache__/app.cpython-312.pyc create mode 100644 roadcast/__pycache__/data.cpython-312.pyc create mode 100644 roadcast/__pycache__/inference.cpython-312.pyc create mode 100644 roadcast/__pycache__/models.cpython-312.pyc create mode 100644 roadcast/__pycache__/openweather_inference.cpython-312.pyc create mode 100644 roadcast/app.py create mode 100644 roadcast/check_env.py create mode 100644 roadcast/data.py create mode 100644 roadcast/debug_labels.py create mode 100644 roadcast/diagnostics.py create mode 100644 roadcast/fit_kmeans.py create mode 100644 roadcast/inference.py create mode 100644 roadcast/inspect_csv.py create mode 100644 roadcast/kmeans_centers.npz create mode 100644 roadcast/kmeans_centers_all.npz create mode 100644 roadcast/kmeans_centers_best.npz create mode 100644 roadcast/kmeans_centers_final.npz create mode 100644 roadcast/kmeans_centers_nb10.npz create mode 100644 roadcast/model.pth create mode 100644 roadcast/models.py create mode 100644 roadcast/openweather_inference.py create mode 100644 roadcast/requirements.txt create mode 100644 roadcast/run_batch_inference.py create mode 100644 roadcast/tests/smoke_predict.py create mode 100644 roadcast/tmp_infer.csv create mode 100644 roadcast/train.py diff --git a/.gitignore b/.gitignore index 3918d97..0c1de92 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,5 @@ next-env.d.ts package-lock.json .next/ -.venv/ \ No newline at end of file +.venv/ +roadcast/data.csv diff --git a/roadcast/README.md b/roadcast/README.md new file mode 100644 index 0000000..66195d6 --- /dev/null +++ b/roadcast/README.md @@ -0,0 +1,74 @@ +# RoAdCast - Flask + PyTorch CNN starter + +This project contains a minimal Flask app and a small PyTorch CNN scaffold so you can train and run a model directly from VS Code. + +Quick setup (Windows PowerShell): + +1. Create and activate a virtual environment + +```powershell +python -m venv .venv +.\.venv\Scripts\Activate.ps1 +``` + +2. Install dependencies + +```powershell +pip install -r requirements.txt +``` + + +3. Dataset layout + +Image dataset (folder-per-class): + +data/ + class1/ + img1.jpg + class2/ + img2.jpg + +CSV dataset (single file): + +data.csv (expects a `label` column and numeric feature columns) + +Train commands: + +Image training (default cnn): + +```powershell +python train.py data --epochs 5 --batch-size 16 +``` + +CSV/tabular training (MLP): + +```powershell +python train.py data.csv --model-type mlp --epochs 20 --batch-size 64 +``` + +The model will be saved as `model.pth` in the repo root (best validation checkpoint). + +Run the Flask app (for local testing): + +```powershell +python app.py +``` + +Predict using curl (or Postman). Example with curl in PowerShell: + +```powershell +curl -X POST -F "image=@path\to\image.jpg" http://127.0.0.1:5000/predict +``` + +VS Code tips + +- Open this folder in VS Code. +- Use the Python extension and select the `.venv` interpreter. +- Use the Run panel to add a launch configuration that runs `app.py` or `train.py`. +- For long training runs, run training in the terminal (not the debugger) and monitor logs. + +Notes & next steps + +- The SimpleCNN uses 224x224 input and expects at least two maxpool steps; adjust `models.py` if you want smaller inputs. +- Add better transforms and augmentation in `data.py` for better performance. +- If GPU is available, PyTorch will use it automatically if installed with CUDA. diff --git a/roadcast/__pycache__/app.cpython-312.pyc b/roadcast/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2fae411b88e90b7732e8e1bd53e8fb29fa473c82 GIT binary patch literal 7093 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 Qox0o3pWMgZm1wB{5A3HIi2wiq literal 0 HcmV?d00001 diff --git a/roadcast/__pycache__/data.cpython-312.pyc b/roadcast/__pycache__/data.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82122df2e715790c67d7c448121e2d48411f8fbd GIT binary patch literal 23389 zcmc(H3vgT4dFH*ic)tOX0G}cxQV&ofB}%fMlx$j*C`%%3i*jVqvSA1pqyT{cbuTE1 zG!WBmx&kd_MApp^tlbgSde?NLoiMF;%S=5}*~!MP6Q{TW6VNxxj?#Lj<955Ni0a06 zcDDQf=i&ko3`(+_cF&OKo_pS}d;b6b{{P@dCX=25x8?t4POjNQQGbUovQuRPi*G|< zl42>A4pF_*lkTPAT@g|YD0&sN6vy-`Ngh?NnmjeV8hA1x?SQUVNAf5``T;|)frM2d zwwGgW-h_$f#Z&1Bf)&RbZwXw!;(7krn&YIv^ z#+I>Wc$Tx}tOcGGYz1qDr(>9QJ3hf`yWO;?WxY{c>6I< zALYDZzAwTJ@II+4lCQ|VEH*-5lJZkH{$2%3_cE-SWuP4;tAt*uSQYr{VTD^G+DWDR zA|ck#Wt$o~*zOt#gaZTKkPEzizpIZVyP#Xx6_@|qpx+k_g!^4y7a!$@e9bMH#Mwc($K|T9A|u%vTx2xA+q{s zDL2#YW=51PgW-Pg;maCPf$#5kD?Ygib#u7I-F8ulU!kbsy#s?GKQF5J2p9FUq9VeJ znoxj`vH?z14tk>}MOA<&FTqG4Eb9E>p#eV!=Z;wZt|IMz_*!|U{jkt}IMs7RXn!iT z=4(GKKl&>bR(DHt%*tpH!tcs!5_OI%%YiAfrM zojiV0qtp$HeSGs|+eBO1;!0^uM4rfF@CJ(0#$hXgoQ{*$gLo6w447 zRLY_JGnV_VgSpc+pPD}p<4R~Ncc$la{4(nm@H45mu1YW1oNutp|rU9Nu6l_9jMB+A7WsHE}D!dsBlSEq?nRkEr)}1|sZG2*XB?=k$;_ludy} zXCpq3hikxsYtU=O(v(yaZVV334&vd);mg7M2KABhsYQiZWw`C4Rm&IEN>#N~0Q36b zKj-8f@nv`?{hpq$$vo54AvlX%~_OwUH;=NMVn(ZOJ7yw>8eMbDJp#5 zk}(66Wn_LCs9dgWjDa`o2XQeKw;`JQ65y*S^;M~3nwa*g^4r<8C2~>09M>n;PElDMp`v@cMvH$w&SlPGdQM^Oa4mg2@r z_a$b;Q&FBXXzh`h5%}IcN-C~^UMOIVb6oZkHBiCoFZKXy4c2`zo&{M;ZY^$#nS%9S z%p-GGaWkajsa51+X1Rt^sjN;;CH0qBJE*mxs7iR1TMgowR^;R~GOE=@iSR0?$1PDj z7Kw{lz%BlHh%yQKr=Y$@YoXvvW0pA$e9hNgRtd^FnmVrnq#=F+) z-ZN{3zBK3iAcy2}1lP+k`6sJqjqOx$Zp&`{n%k=UsD< z`%Z?b1}d7PP>mF)q^V=nxZ>hFXQ^|{G3qS6MEdvS^sKyO%*sn}@_@8t>)wY*2}m!V z0slaR8wRdY73Lymd2T0k$<2tmu;;{(@033ZQqq7wdNRU_210v1d^Ex#&Z0aK2=gOm z5-HQ;)g!xByTXwuU?M|6ngd~^qZDjktUq&~3j~83)ij58r`Z?Uw+#bxo zio+czYGIyOkB>hiD%d{JD6NH5k?1IzTo0gM9>`_)cv;p1;-BA><&Jn!xA&aSKZp#N zXeG%ZZ!{Ev)rQsN9>bROU-O2B{Cjc6M8-Q95LMVCUbF@Px981ni+LY9^W zgjH2vDB_KZCbhDqMJ5~T6xqQexM+n^EeXV z_QO$834`tz)zZFm+aDH96j0dELCM>0&9EMWV?II*x~;Aa!G7{sv?F_TCu zcX>o~A!5KtS&7|?bcz25*oLFjO@lSD>xQFp^3=qs={2)M^NwAKj&F8;oQqj`ZSTC} zK%(Pf=R)loBBcM)Q2jAT(aQHU?`Tpz$5Z~(wwdrQHXDsEU;OmBW;>y@qZ*0s0PB*Haa{)Y34b0+pvYuha?Wvom_FQ1({ zd-=tw7X?Gh4SQ|!>ocL5=TbY*rRs*$_K}ovNi(^XZ@S&f3_?> z{p8$}*Vd(Xb6dc!VBLre{#-8BCoX%A7tYoIaNt9uZEz@Y9~yAD&Jv zizgljZ=t>g$5ne1M7I8k{v?}Owo!mT$EJ*9y8wSX{AovD!f>;)Ayc_Vs9ck-Y)Y6G z9LqC~HG*T!OkLWsHRISVICjtRX~&*~0Xhg-olSzXX=Z0;?M`9s&h*+{nYHc0+V=F? zJ%Y0%<2)!h52l@63F8feIT1@6YLln08(cT5S7xf4gzBc*wp4Xfy84mC!G-mkGVAvU z>-YSu;n|tx*G{LNIDWnJ_#d}lZ+JG*F>iE1V->DUd81I?m@Z$H&@GfLn|yfU;dEJJ zrfi*1wr=LhSteb!Ia9V%DBC%=CtdbPLQ6V0eN1q+%x;@wzx%L&y}ntuDpR*!s9XP* zKUKFrUDt+_QoT^yn5k_RYMbBMo2qS2*X|%&;N!}=%f>0=^fQ^2TZNTd-yZs_`1j)T zm0f@jnQl00Q1X3!;~TrK?3ykA3+H#8bLE-s2L$+QJ(xOje7@n?Oam)4uql6Ex}iVQ z5EdH3^ARrHz-JmpgoY8=M|%|e6~D$um*Q8_10tQ>3P4#5pWf-Bsd7MoXj6q~Ex*OU z^EY?2#Zmv~ww0>?I{n%0YO3)$n#Ys$o$VD}4E3(X*;Ph;f3?1=LHYfSTfqN;TM7Pq zTXbD(lYBAgb9*;BNlHe!;LyS1?8cq&0If}UEZb7rZDg2keK&{fbN9YaSa^uc z0Q(SxQF80%kk{ovtSbaPkW=N*TLb@mC3xSUex+bk+C}XaRkz~yAWf@k7uB?Cy99h- z*3v5-gOtLRF160FocP7j!*pInlaDV2dF2FyoQMxiWu2TRL0lBzSI7%+$H7Cw$%!iP z0)rfC9e}Z*&lPMX(d-F>63iO{3&ZWh5O)}} zD7fE&2k=eN!o4Y43g!okatX-A!9TwRyiw|wLZz~QY_eQ>ZtS^ad)l-tp@50H^upK+ z$sK9Ss+4xsr#B4ca2l!XA6aa08ma7`^F}E8J1f^vGrG;ppVONeAI_HSaD~at^=WYC zSQ^x?6ahLhw#czeKMjCRc5X|~n@Uav1(>Q7w8N6`m!(g^{^#vW z)tt(xhl0|mMJaM66@_LwQ?7rYuv@x+pg2>O0)m3bRTsHDd>q%3`P0XBF@}3Brh8zp zCI=*OFX=#a4Q=NH;(TMExXjLcTp!c3S`-rF2FQ!&T#+jUw8Ye`f>rz;{7cV125SJw zFZ*5?i{d=1yQ-H3(72KG%2m`1mN&BMf_$cEgPbSWD2MV-fC{J}vf4!sK#?q!>Y<`* ztajO#SZ%Acp7QE`snsrD za<$9vTI~vw4~5|(7t4cO4w5Ga`{Xmm3`@^@A06E+=gh+(ac2~%DRHri{OmltBCG1D zj90}Rv8r>5a|*Jzt+7gcjsU3X15<-G2*;fHbXHxMa4#6VFKF|&$fWq4uF2cRlEF!g2}+Y z`h)_G0J%5f3IMQYWuBlYop1~n+vHStnU{uxyfceFWpO6giD4Hv6b_@6&Z%Z1bGss- zCM;Ga@vb$jA2m<4<@po-C{*L(hd}+v0+`0R zz+M3QK#YpAH8f}O16S9fC$K%xhH)nXkdGU7o%Hf2U0M82(sL2)2_P{je8SHm2o(rJ zZ^5o#i0R!b4+040A^7VaKv-ZKq4@&C%pi5p_sy* zMDG-OK1@=B4Hp|35Dl!q&pQ-~dbn^uhirwUwpBwvcz`AW#PPBK;snCpP`{`|eiu+4 zt{>J*Vhhzh09W~WZUT!UGYB#R7<8z8CnEuXn^e$DzhBhDKq9;+6gUM@BrJ(G$bX1h zK#TnSFdtCVdrq|S-ZTCY0A>bYX?Y%YLaijpNr;ftZ{W9)p(KcqB0NZ@9bq0N@R?r3 zR%HtmMjn^Qga=2+oQXOFe^@d;Jq9I+N;F7iJY?EiuxD}%snn2NHDZ^dgPwX|??9(% z4?v1o84=V(L)d@Tlg)|%=@3|oaHuE(s{-!{kv@g166lNa$mifzT*^sG@;vf*ihM=c z&T@YVrC)%5{*Qn^7^N1?l*$R2uS;l&LOlYR#Co38rmxWogr{(R~XV z)A`s-vGMkoUQ8~(uBl0$xg48{&9qOwIJ^9M{icsCE2mG)J~nUJozm{UX|P?|HMUC< zRbE%64XZ{w7Odry`U!oqb;30I*n-}8$vx)I=<5Z2{j@QyZyw#VsHRlrk2LmiZu0EJ z*~za@e0}=VymR9%g;r-zH1bq`MaC8&8N%Mp``NE&J&ai*hKC?rp-!kXCR{rkk50+o67PcP}>JNb( z&A2&jeJY_^uvL%SC#xo^k`GOvp0~LZ>YI*+@e`8+69dzoX~(*RVZl}fIVvYAlUpzE zn%XsE6Kd9`s+-^HnYV3EsBbvxr`2i4YB286)s5{-v?urlqch2*jkVK;nf5DY!Po-f z1*3g@(}jb{R>4?%@!%~LWWJ-O?9TDClko`v0tM&lv~A68N~JpjhC~aNigEAQaI*E~ z_`-64!>%lwT{UO>u3K2XbKH<@|9vxzens<4&v%Z$d3xQkHo6hYst@F0#(F4EK z*a1j|O=_%9Jeo105z@3__UKQIyI=y0=1behwvYEtb8noxa&F$RA*I~#=^el^tW`Ln zw!bx6ajtB?x$~S9N9$}KK^z0m&-s<`nSP&Xf4IAx`mnydyOH`yxvqOT^Ai`1ext5? z1M`#hH28OkvUudfr%f&H04i~wKCd~iJ+C{jKW{j1Ja0O0K5sd11?UN^Yf<#%%z20) zMvZ}0D5z?%G&m3}OM+&gmsR={#O@Q0VYKxrB?8OrQ%nigpcO<{t9)6L(Dcz@(W{NC zfE`w`N>&9Hz8cv!;$;-CRIHZOv3j`|FY8I1fi<$GT%3W#nOO^KWo^0ACK79h7^IKj zUIt5NsIN?BRA08hf7y#Qt@tBT69XJ8=7gYC6{ z5DYyLA6f^MflU|iJrDu~P&Np7k>4L}U55tS5ZJiRb=J$V>p+1S976tKovRNBcL-E8 zeqQ3Io{(8SsG9@>$l*z(+I1%2bpbR<*f8u|q|fCAwP+TM1BNbZssyb;vQ(j{mMAEo zRme#Y-oaP6HSl|ZeM2oC0PkBg0=r;$Tn9S|VKrpnik!TU;)N((QoM|;R?V~OP$B@ z$E=(kKFks*>zEaA*6fiL2D3H!xRReVHD+3}tm*EuamAQ<$-L&Gyo?U6GL+h&_c5=} z8H#cZgpdFl!7a<1s6_#1kX(T&TCNP3n`g%=kFRjdXu$TB`jkTjp-&7Dw+HD{uFU=V zv_y|^4-hwITXN2Ach9*zX88#Qc%@e$U$=e9y6yk!y33cWyZnB2vrJq$W`u(dWU06c zR;}dT2J)M`Xaa;ud7qu7mgj}D0=be_(GbmD-H7GVVb3s#TE&$Y+X0CwJ%nX*L2@;mt2#vvi#c0^~q0|7iFpIF!}3B zacvaAH{wd-^V*UokU5Qr+)^oQK1UdJ1#7Nja~FTcEF*B@BJNN0QK)q#4$!BHrM@H> zYxeBU8fdl32o&H`U#$l15;aIBVD!b8?~}emPIqg%iLUGuqzVKG`kan^t{RH=HE;U_ z`{uTC$XO5tn8*OFmcSDgSaOBE+$bagQi2v;1e_r_3ehG?D2W}@H3&I{0w=f_zN!6T zUxf9Gx|9BMY@i>Aq`N|7fL#++gK$-a=RSa3+=rwf@K_#xXn=F!8+`_>cfei-B19U% zi<2S)Mm<2?Ar2S~9?_Vf6w&|z#}M4y0rMpYNa&T!AYh6iOTbCC?8`>-!VDqpMGB3t zJbwBGK*wm#Nqmk8dhP)Qqr{JnG~bWgxhwlWK;3*2h!OHUR(nEqQ){|p95eob=N^Xy2Oz}8)X`(}#$K?#`SNA- zl+H}L{Mt~fHUeQF^)ru%33-qYC{_RpS}Z`}U=#&kvZ zy!LUB#mmY;cD8}Ys?t>?+HWb8riz7f=Va$ZXRfqpxjBo_=l1wdI0!&xGcd28zNho@{S>lFnC-&udrwTh@&>PL}K%yjGU%xqNi$ z=ycD_igaCbx~gT~xc;Wma%unA{_&?SJf5I$7|Sjl96Ok#FKef?)6R6IJ8f*r7&i;X z&1vHnNH^QYmyaL55KL|t%#GwuNJ9VVoyTRdU0&^^Jp-0iAivk4{R@iu5X|)d#DYA63!l*Hs_f z$^2*sjs9-kA%p72dK!JR?of^D$JI3W+(oF4y96GXDZ=HNTP4n#U`zYpQNY_~QFJ=PgH5+M}>-R<3^Iz?B0( zGp$daPI&Q)ybws*#zNOk>qqz9QL0qszcN$ys$}hSY_>Pm{$$#Ac=W(W=8Ey)bn|RQ z+PrnN6W>lv@1A`qZQc%Vkl8(bY}S-|_^Gu0YoiBAL~7;Ew7m^pEROLr7hW9Qf3v3U z@{Xw;KeOx}_s%$H+yA2TyPbdj*md`=->0uzc8~5~xKH{o^|o<$^4N@ic5hn0V|352 zl^axL|4e~*i=`1R+BUXrylaL|Y)c!OQp%>!Za=P|%o{$t?V_v?e?l*d+oA;j`;4=rQu+NFCHQw)9HGSqil>V|0UrcYdQ{mDSIhsH26?6Ag)snk z6b0Z82&h3UU*u#u9aBi)PMnDYpaf754g3@su@I|=dzF)fUI*x;RQIYM8I3qlRY}`6 z3bs37(~^^*O6g5wpb5lMECUuASvdnQB?rw#Lx9%@wQOK>yh||0QRZulqLCAEGM^EH zEB9>>vqY<h=fY?G{!@kTCnH0gYt30ylDfQSya52(LVnP};yM3VA7E>wXYw@!P|1=D2msp+ zg#lcF%Z3nz5L|O)P%6~zR&zgqS>XN~dOt+(J@ANz4ithBpKl0E=wY;ZOZ-p%1)ONe z0#G;*(U^T91CjA4C^jsbvnknu zR3){VZb`-vm!0lQk*L3UOH&tWFmiSCyoUDWr_xfk7vbDJ$Nl291((!C<+xV{FHTw&a%U zhUJLvv6q8W!B<0qb8TWjYDzSa4`4p6HKlPbXwAUds`djrWF;454^L~Sj?b={H}6a^ zkg2NnvU*B=*)V0uR5l5fO*0$Ql`WadhlI+9-twm_+eRN9jSI?(1<2=^a$K&Rs?Aib z6ROtD98Onl$W(0=s}ZMd|wxojs<7+y*HV8EvX6@;k&6%2=Le0*%_oize9eor!FDNT- zR@U6VgV&W6pWR*wRQFS0$&3|fMp!i9Ox*^dZo^w;>AHvJPR^SB{- za*7uw#@vf`#+WQ^R>lDj1B$H3(q^QF_oB^8S-o-Ze1tZuvb0%+w3&r=LW-9SsFdha zz)!Yl!F~`FFqpHHIt8rSVD#upsVnY7iN0`F1}#!ug}%(E0A^v6OTiJv;zJR3(5>~gyIqHdS1%rK}p`Tp{1p}x%GLMmv^yny9SI` z@H&pHU4dsfnl(s?g#FDYBhlsnn4Dly=!0|*M>=Rx1LNxIc&PaV{5lRxa-d2C%woV| zhDDm;&04AuTNof9VHau|q!ejrSqlu;89>S-oP2<*xSzm8!H;+l@SXb`c;Qm$3FskL zb{CwE9|JN#izrxpOYz{w+)6)uO&8lh#^+z%hUad&X6+1jy{2`ctOD!<5}hbazs4l@ysEuynX=4i z(v=(1#@38+r(oQfHtqs}8uUr6<0meRB)bJmQ%c(;+4Q8Cw?n|s~6{80htSd_s>#F)` z2mNu`;m^TUL zO|y@JFq|>(7RFyAqZMOmUw4y>!{~0DhH92?P+-2|$iyBB%x9(|eUwWr?8b-uVa- zRA-4GlO?df&AK(&y45c!VwwjOfTe2#%KWc9#C7>oZ3&@SLxkqSGI}uFFF{fPjEC)v zE|?>!(mVQK%OR(hI5VRqNGL0bkNSU?wusOOsw&;Rehmzaef9TDH%5`oBQ9^?9ivad zDb4j4q~(4aAe(lqU=>P;(<8vkl>9DoHb^B|OP4$ixv!@|j>$jS zGFbm|Z2fA53~k9fAf}i46|?_;>qmCSWT6qTB`ShOz{0IypCTP7a==cLldI$m8Rg9K z46%i0)dQYyU!i6_`AvuaAcHPNV**A2Rwertk`S2%xEM#vCESjY|BAwZFXH8ZS?A#n zJKQFB;iZ0JJ}#TRtk0Ra5N?|&^?(b9WK78+I`Y-@0`Xu6X7Z2%#B?ebgji@sii3b_ z4QW)eGl!}{kidv$Fs^EDC4CtP@MyA?MQ`AD`?&XE+PS|*?*s54;zt<%F?y&YEP!B; zm=cS1Fx`>6L#%kD?!d1G1UOJO(nO=MkMlrw_%RFmv}F9OXNLwu`14cvBLP?*dM2q4 zAwVPs?f^DG*yD>>RzdU@+^;cgFW?aOVzzzg6`?l2#JFeB^MNO-@iz`Yhq?-1l&5_| z@WTUOB7Tayj9LC8dLfeJ3k3$R#DQ$I1vs|ouI0g60HB}_sj^X>ENM`$JC;UnpcvfH#OF>DF+T@YTy;Hrf z9v2)g0NYKdDsv2>vuMHjsQYd3NgHtajeKJ;5L*RU8K+ z1Pm!K5tyc531u8^!Qq~1NIP0Gj)w#XVp0yoq+WRGaj+?WkZiYH{<@3@SO7csIBv5{ww=uJE!-j8{4ia-+wCQ z@z2-xB_2%-k9FO+Z=RRCKHm7yY~asZuC-p@*pVE*9G{B6_Tu{u^C$eNzDWASV2Y1k zKM{R@_;2EW9slu*sgd~j(M0EsuTW;8vVMBCQ0bmIA~;(U`-@-eS4agE?bDgsXNB5lQ*2)<%t6Y`S(x8t=ky zp_Z4sKD&L8CMcbYpmd7jZIP*M5o%km^6A=5bNlDbdy95RaWa5-AieCPe{*LYsgHq$ zuB-;RX8V{4E*fCqf(g;kn$P)-@EyHcd9X?OZq4R{>!}~KJzCyXMZIV1sD#Il*0(ow zIhYSCX!NVfy4Euvw$R|i@%aK2{G40>zz;vhBmLyzZq#{D$n=vRbp{}mrhiW9 zeomQxLDl`7D*HKQ|2bv+1=aWqs^S;aiaY8mx;p8+L&4+DwsxA{J`OMVyuDw+&?{~m n)wF%l-bK@`i_a^br0KPbCl%H7uEia7^rkzH&>Ly#cNP90G#Juf literal 0 HcmV?d00001 diff --git a/roadcast/__pycache__/inference.cpython-312.pyc b/roadcast/__pycache__/inference.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d75c20a5198256c32eca14347632a66c36bf04e GIT binary patch literal 2474 zcmb_d-)j^{9G}_WdzYA8qt;(B8WZhBjYv@&Eh*}$n1*0A#pX;o*4<6A=iTl(vlma< z!?XxZP)LFgiQq$|g0_+3pHNyK3Vq4-0;gl7h0=%67fS@GPo3FhFW02dKJ z%)+Ilv>caxolhxgHLm))kP4;4@i5h8L%adwRfb|nw6DGjqv|}{s4EJIcsi~1n^Xz8 zNV9RDgVLCes&r&(u9-+XhMCf7m}QZu#?${oA7mkVFb8oX1a29S3=UDA0U#+>43^aC zr5eN$Ui8Fdcu}uxJ;4w+ z(uwJ%eITH?>Pp0-9z;g%Lb7JH-H-wgdC8MdlP4u3t5JcM7#NjD6`i+$&V8x?&`VE{ zm-C9Jc=B!TR!9IkpI7oS{RSYfdZMTHapx!&F3n#7QMroJ83PGNIAOZ zT8ORe8PW$#{ZhuUY>M=QL2KANyhPw2-O$LfQ2dxMTe__*Zw?$k-1{*$5$-*w zr8VRZZ0pc0yEo?O*|cf9xEIl&bPc<`mfdF})7H(_%vBQdV_n>;o_b_n@m<;sfv44V zKUJT)-~6EEUQ4O5tv6Pw02O~xJ$&PEOnb<9<5n35iU_``+S zs-B?}PX)CkY%B;HCtGHk4;41OH!HN!xi30C>$uVRw61=leY}0DwOF@*sPkES$5d~L zf|?H%o7+lthwpSxel!Kgj*eX(kImK{o;lM!)cG`AJGN&gymdy{`sV@<)*ivE@V{GM zeQd9!FI6+00HA#9KBv_~Zyoo)-8#-?DfcBwt8=APSbf_1yWQY}n^1vc`CcKxUFhcm ze4cm9H!E4Y0#1h>43NpX)mB3Yta*V09`BXM$#wsL76Wwh?bTLqIVQ1!fi|p02B$ax zAfUTa_6YpuC3kaxPi_gc<=&GF>5*LKF1cc#t;?uD^W;jj&lgHwrBqLUfe*^K+XMV{ zHMt|um-`^vAV#-2uw7UF3!bsi4zM3!c!hFN4?Qykw~pla9&iOll`fwt5UZFdH~$Om zPy=lUfA-Wd#5j7Mku2pZ-mucqI>eH_xP&Deu@{BN$DMS>!6uQ;n%KH#5~bVeHf`)6 z#A=@iPR6u}tULCgiCm&)ZG1UvniR;n4v}pq(T_BPz>`GAPM@3Ba)kFAMlu4UBO>-u z7I32>#L`I=E8U+cvl9trkeNY_ZemP$Y9cU4q?FTdxtNI5a1m45b?iQBG;%9g39&4b zYU+WpX~JT!C~Bi~tp4!twD}jB*<6b3C`5MLkC&Pc7Mc$}zE*5L_N1c}J70*MFUERi zn&QRC1Dk-}P z%C3h}QQ0?ibWU9}T0c^Mv*8cGi+i3$){kAjySxd}0~%g{buU2UZ=hj8QeeZY^(x$lVifoneDoRy literal 0 HcmV?d00001 diff --git a/roadcast/__pycache__/models.cpython-312.pyc b/roadcast/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25ec296061ac8e764e61ac95fbf43c02d2429151 GIT binary patch literal 4036 zcmcInU2NRO5nl56cYoHuY)i63*=}vBu^c-n(kA|eWjl5xIf>vD7VNV0k&-C$c$X#5 zmM#=36b5n!IguQ+kkl0LwRwnDxo95!+=l{1UzF&8URf1L(Z1--t&|`5rJW^@$5SfQ z$wODr?(FVxW_EVwo4r3KlQ9Hs^51_NI~zsl?_?4*wn}W+K+Gc*sg!|+{gF!3!!(6x zbOEXK9i&DydYlVB49De&PY*L5Cj*@9Q#e_bSGhaXFgHm_!aDhUFck_!s45X{^uX%d zV3&r5DHRRVDm5HYnF1Q2z@q3dqekwaVYYxKK-LhFST{PPr?ZB3c5pC%^^9nx6~ho= zB93IRsHc@tO-vbzW$7b&O0o5fDIQYP@tkEVHw;bc70=}COd2*)@ZF@C%A~V7TeHLw zL$Phm)Kt;Z^IC6;sWUbXG_iN%IP^cG<`MCv--^70-T@CUSLYP61An9KJXyCZ1TwY%8C4n`VIFknqnL@-Vp4Bqr(J#m}2dn!Meka?+)m2 z3^c=TN4OeLDo;Mi$KeL5o}J<#ui$T)_IbWR9CQUz!!giacVBzM-GKTrrwW0-I?k^b zCt@Ha9Mx!WnmTFQ=v4)W4)iWpqaE(Fc0ZG7KRSvm>NX(DRk%3{-F`@>DjlvAtr>CT5m$h!xnYvP+w$8ynKz%xR{rD~8LR&6u~2sV?)n)_=u~4k#0^W-b#E*F4wP{nu1-v4`;HOobAQ}tkJL} zxQwM4BW_$b<5K~6d$W_6BtpKq zhMB#A$4ClVE#THKr_q{_Eb<=Ed}rDGo*eWa8Vr^(8N z;)R)ugy=8!FEq_u4!CYC?0eAt(QDCO30&_RH*^G9y%w8{EpOOEGBGHp; zt-I%6x%WzmT4_B}y7Wowk;1u3%g*@|_fC}BR$C4h`qsLhDKQ_$ei{29@xcCVekuQ` zdui%p@%U=jiNe4aJc!tgq0T+`4=)}jiZ2x}&GZL0rAtGr32BQxus>&oR;LzTT1_0> zh;yA_-8&6m#6jL;V%HNZ3C{W5OJ|zSH%ETo%%1P$Q`NkNb-xyP_23dr<`JMx6$QNA zYUfZvHce5$LHNJYws25GXo(t>Xxs)|_!;PyXe`3uQWF+YE{gaNnetHQZYx;LH-&dv zT_Rsu`=Oggl|;)P=3?I75YWSu!!;s}A3Lk`3 zi}>iYcLq#~o7WNauo|KJ@(%hlllqKqXJel~7h#)lZ@`iQqSgX0e)CsDWT5}m{1M+} zBGBG*0p0{TL&4(Np*KWTv6Zj99Jam!h^L7Djk|D?r@aD3Nfn}|ScmRI*Ru#saSk(H zdl}TugKQ$zYvbEgWQTRQ8q!u{j6zS9^gk*<5R+d+%62b_T1?l;;ilNTaG6iFYWwp= z{`-7&KG_j?CmbE-UC21OCT$XG$l&PD7fJiWDJhD{H(oHhoRZCIriw{`;XR~lAss1c zm{cn_VrsS|_-PjPv02sAZhTBvRn3%vw(vf}$QjBcz^=<=v3AR)#{7sTHU!x02et>c z2?(zm%zB~!9x!f&*-BGOfvYs^DlnC%u74pW+EzGINi>t3{l&if(xO!Ad(gew@oYJ9 zI9xusc<_CxoH!7!^epz2hTcC?PV`h-T8n*;qaf&U3`HAelf~puZ_MlW^b%9Lx!QiL zEIhx~(&l07w^v#u06f9VvF(BF02usqU>icX2N)#^pMU{>2fBKw^1vV;C*G(6)boUc z+y($tL(A+$abkg*d22=J@Jx|tfIot~>(kI-cwHfUjC9|Ft{y&KB#Wf`7TKu5$M-*@ zV{FgoyC}BPhY!M%swEgqNCJ8({A(cKe2hxnJOr|yb=c{+T?28I4#N8;YSZQ z=tj~;Hh-uVqoQt!7+yO%hF>h?mk(@qI-2sjF10^wT z>c_s03CEmUg-@Dejvm`z0EVrI3 zp8JPSue^S}-1ySVc)D&lr|BNn+KAVU+n$^ DkWU~n literal 0 HcmV?d00001 diff --git a/roadcast/__pycache__/openweather_inference.cpython-312.pyc b/roadcast/__pycache__/openweather_inference.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac86aa1a6ba40c195b890c5be1fd2af74bfd1113 GIT binary patch literal 16270 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 XxgA0|UCWl|KGfB%)lj+$;+Foul_z_9 literal 0 HcmV?d00001 diff --git a/roadcast/app.py b/roadcast/app.py new file mode 100644 index 0000000..38d3889 --- /dev/null +++ b/roadcast/app.py @@ -0,0 +1,123 @@ +from flask import Flask, request, jsonify + +app = Flask(__name__) +import os +import threading +import json + +# ML imports are lazy to avoid heavy imports on simple runs + + +@app.route('/get-data', methods=['GET']) +def get_data(): + # Example GET request handler + data = {"message": "Hello from Flask!"} + return jsonify(data) + +@app.route('/post-data', methods=['POST']) +def post_data(): + # Example POST request handler + content = request.json + # Process content or call AI model here + response = {"you_sent": content} + return jsonify(response) + + +@app.route('/train', methods=['POST']) +def train_endpoint(): + """Trigger training. Expects JSON: {"data_root": "path/to/data", "epochs": 3} + Training runs in a background thread and saves model to model.pth in repo root. + """ + payload = request.json or {} + data_root = payload.get('data_root') + epochs = int(payload.get('epochs', 3)) + if not data_root or not os.path.isdir(data_root): + return jsonify({"error": "data_root must be a valid directory path"}), 400 + + def _run_training(): + from train import train + train(data_root, epochs=epochs) + + t = threading.Thread(target=_run_training, daemon=True) + t.start() + return jsonify({"status": "training_started"}) + + +@app.route('/predict', methods=['POST']) +def predict_endpoint(): + """Predict single uploaded image. Expects form-data with file field named 'image'.""" + if 'image' not in request.files: + return jsonify({"error": "no image uploaded (field 'image')"}), 400 + img = request.files['image'] + tmp_path = os.path.join(os.getcwd(), 'tmp_upload.jpg') + img.save(tmp_path) + try: + from inference import load_model, predict_image + model_path = os.path.join(os.getcwd(), 'model.pth') + if not os.path.exists(model_path): + return jsonify({"error": "no trained model found (run /train first)"}), 400 + model, idx_to_class = load_model(model_path) + idx, conf = predict_image(model, tmp_path) + label = idx_to_class.get(idx) if idx_to_class else str(idx) + return jsonify({"label": label, "confidence": conf}) + finally: + try: + os.remove(tmp_path) + except Exception: + pass + + +@app.route('/predict-roadrisk', methods=['POST']) +def predict_roadrisk(): + """Proxy endpoint to predict a roadrisk cluster from lat/lon/datetime. + + Expects JSON body with: {"lat": 38.9, "lon": -77.0, "datetime": "2025-09-27T12:00:00", "roadrisk_url": "https://..."} + If roadrisk_url is not provided the endpoint will call OpenWeather OneCall (requires API key via OPENWEATHER_KEY env var). + """ + payload = request.json or {} + lat = payload.get('lat') + lon = payload.get('lon') + dt = payload.get('datetime') + street = payload.get('street', '') + roadrisk_url = payload.get('roadrisk_url') + api_key = payload.get('api_key') or os.environ.get('OPENWEATHER_KEY') + + if lat is None or lon is None: + return jsonify({"error": "lat and lon are required fields"}), 400 + + try: + from openweather_inference import predict_from_openweather + res = predict_from_openweather(lat, lon, dt_iso=dt, street=street, api_key=api_key, train_csv=os.path.join(os.getcwd(), 'data.csv'), preprocess_meta=None, model_path=os.path.join(os.getcwd(), 'model.pth'), centers_path=os.path.join(os.getcwd(), 'kmeans_centers_all.npz'), roadrisk_url=roadrisk_url) + return jsonify(res) + except Exception as e: + return jsonify({"error": str(e)}), 500 + + +@app.route('/health', methods=['GET']) +def health(): + """Return status of loaded ML artifacts (model, centers, preprocess_meta).""" + try: + from openweather_inference import init_inference + status = init_inference() + return jsonify({'ok': True, 'artifacts': status}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}), 500 + +if __name__ == '__main__': + # eager load model/artifacts at startup (best-effort) + try: + from openweather_inference import init_inference + init_inference() + except Exception: + pass + app.run(debug=True) + +# @app.route('/post-data', methods=['POST']) +# def post_data(): +# content = request.json +# user_input = content.get('input') + +# # Example: Simple echo AI (replace with real AI model code) +# ai_response = f"AI received: {user_input}" + +# return jsonify({"response": ai_response}) diff --git a/roadcast/check_env.py b/roadcast/check_env.py new file mode 100644 index 0000000..5fd7b84 --- /dev/null +++ b/roadcast/check_env.py @@ -0,0 +1,32 @@ +import sys +import importlib + +def safe_import(name): + try: + return importlib.import_module(name) + except Exception as e: + return e + +print('Python:', sys.version.replace('\n',' ')) + +torch = safe_import('torch') +if isinstance(torch, Exception): + print('torch import error:', torch) +else: + print('torch:', torch.__version__) + print('CUDA available:', torch.cuda.is_available()) + if torch.cuda.is_available(): + print('CUDA device count:', torch.cuda.device_count()) + print('Current device name:', torch.cuda.get_device_name(0)) + +pandas = safe_import('pandas') +if isinstance(pandas, Exception): + print('pandas import error:', pandas) +else: + print('pandas:', pandas.__version__) + +try: + import sklearn + print('sklearn:', sklearn.__version__) +except Exception: + pass diff --git a/roadcast/data.py b/roadcast/data.py new file mode 100644 index 0000000..febbf22 --- /dev/null +++ b/roadcast/data.py @@ -0,0 +1,413 @@ +import os +import hashlib +from datetime import datetime +import pandas as pd +import numpy as np +import torch +from torch.utils.data import Dataset +from PIL import Image +from torchvision import transforms + + +class ImageFolderDataset(Dataset): + """A minimal image folder dataset expecting a structure: root/class_name/*.jpg""" + def __init__(self, root, transform=None): + self.root = root + self.samples = [] # list of (path, label) + classes = sorted([d for d in os.listdir(root) if os.path.isdir(os.path.join(root, d))]) + self.class_to_idx = {c: i for i, c in enumerate(classes)} + for c in classes: + d = os.path.join(root, c) + for fname in os.listdir(d): + if fname.lower().endswith(('.png', '.jpg', '.jpeg')): + self.samples.append((os.path.join(d, fname), self.class_to_idx[c])) + + self.transform = transform or transforms.Compose([ + transforms.Resize((224, 224)), + transforms.ToTensor(), + ]) + + def __len__(self): + return len(self.samples) + + def __getitem__(self, idx): + path, label = self.samples[idx] + img = Image.open(path).convert('RGB') + img = self.transform(img) + return img, label + + +class CSVDataset(Dataset): + """Load classification tabular data from a single CSV file. + + Expects a `label` column and numeric feature columns. Non-numeric columns are dropped. + """ + def __init__(self, csv_path, feature_columns=None, label_column='label', transform=None, generate_labels=False, n_buckets=100, label_method='md5', label_store=None, feature_engineer=False, lat_lon_bins=20, nrows=None): + # read CSV with low_memory=False to avoid mixed-type warnings + if nrows is None: + self.df = pd.read_csv(csv_path, low_memory=False) + else: + self.df = pd.read_csv(csv_path, nrows=nrows, low_memory=False) + self.label_column = label_column + + if generate_labels: + # generate deterministic labels based on selected columns + self.df[self.label_column] = generate_labels_for_df(self.df, n_buckets=n_buckets, method=label_method, label_store=label_store) + + # optional simple feature engineering: extract date parts and lat/lon bins + if feature_engineer: + try: + _add_date_features(self.df) + except Exception: + pass + try: + _add_latlon_bins(self.df, bins=lat_lon_bins) + except Exception: + pass + + if label_column not in self.df.columns: + raise ValueError(f"label column '{label_column}' not found in CSV; set generate_labels=True to create labels") + + # determine feature columns if not provided (numeric columns except label) + if feature_columns is None: + feature_columns = [c for c in self.df.columns if c != label_column and pd.api.types.is_numeric_dtype(self.df[c])] + self.feature_columns = feature_columns + # coerce feature columns to numeric, fill NaNs with column mean (or 0), then standardize + features_df = self.df[self.feature_columns].apply(lambda c: pd.to_numeric(c, errors='coerce')) + # fill NaNs with column mean where possible, otherwise 0 + initial_means = features_df.mean() + features_df = features_df.fillna(initial_means).fillna(0.0) + + # drop columns that remain all-NaN after coercion/fill (unlikely after fillna(0.0)), to avoid NaNs + all_nan_cols = features_df.columns[features_df.isna().all()].tolist() + if len(all_nan_cols) > 0: + # remove from feature list so indices stay consistent + features_df = features_df.drop(columns=all_nan_cols) + self.feature_columns = [c for c in self.feature_columns if c not in all_nan_cols] + + # recompute means/stds from the filled data so subtraction/division won't produce NaNs + col_means = features_df.mean() + col_stds = features_df.std().replace(0, 1.0).fillna(1.0) + + # standardize using the recomputed stats + features_df = (features_df - col_means) / (col_stds + 1e-6) + + self.feature_means = col_means.to_numpy(dtype=float) + self.feature_stds = col_stds.to_numpy(dtype=float) + + self.features = torch.tensor(features_df.values, dtype=torch.float32) + self.labels = torch.tensor(pd.to_numeric(self.df[self.label_column], errors='coerce').fillna(0).astype(int).values, dtype=torch.long) + + def __len__(self): + return len(self.df) + + def __getitem__(self, idx): + return self.features[idx], int(self.labels[idx]) + + +def _normalize_str(x): + if pd.isna(x): + return '' + return str(x).strip().lower() + + +def _normalize_date(x): + try: + # try parse common formats + dt = pd.to_datetime(x) + return dt.strftime('%Y-%m-%d') + except Exception: + return '' + + +def generate_kmeans_labels(df, n_buckets=100, random_state=42, label_store=None): + """Generate labels by running k-means over numeric features (deterministic with seed). + + This produces clusters that are predictable from numeric inputs and are therefore + better suited for training a numeric-feature MLP than arbitrary hash buckets. + """ + # small pure-numpy k-means to avoid external dependency + import numpy as np + + # select numeric columns only + num_df = df.select_dtypes(include=['number']).fillna(0.0) + if num_df.shape[0] == 0 or num_df.shape[1] == 0: + # fallback to hashing if no numeric columns + return generate_labels_for_df(df, n_buckets=n_buckets) + + data = num_df.values.astype(float) + n_samples = data.shape[0] + rng = np.random.default_rng(random_state) + + # If a label_store exists and contains centers, load and use them + import os + if label_store and os.path.exists(label_store): + try: + npz = np.load(label_store) + centers = npz['centers'] + all_dists = np.linalg.norm(data[:, None, :] - centers[None, :, :], axis=2) + all_labels = np.argmin(all_dists, axis=1) + return pd.Series(all_labels, index=df.index) + except Exception: + # fall through to fitting + pass + + # sample points to fit centers if dataset is large + sample_size = min(20000, n_samples) + if sample_size < n_samples: + idx = rng.choice(n_samples, size=sample_size, replace=False) + sample_data = data[idx] + else: + sample_data = data + + # initialize centers by random sampling from sample_data + centers_idx = rng.choice(sample_data.shape[0], size=min(n_buckets, sample_data.shape[0]), replace=False) + centers = sample_data[centers_idx].astype(float) + + # run a small number of iterations + max_iters = 10 + for _ in range(max_iters): + # assign + dists = np.linalg.norm(sample_data[:, None, :] - centers[None, :, :], axis=2) + labels = np.argmin(dists, axis=1) + # recompute centers + new_centers = np.zeros_like(centers) + counts = np.zeros((centers.shape[0],), dtype=int) + for i, lab in enumerate(labels): + new_centers[lab] += sample_data[i] + counts[lab] += 1 + for k in range(centers.shape[0]): + if counts[k] > 0: + new_centers[k] = new_centers[k] / counts[k] + else: + # reinitialize empty cluster + new_centers[k] = sample_data[rng.integers(0, sample_data.shape[0])] + # check convergence (centers change small) + shift = np.linalg.norm(new_centers - centers, axis=1).max() + centers = new_centers + if shift < 1e-4: + break + + # assign labels for all data + all_dists = np.linalg.norm(data[:, None, :] - centers[None, :, :], axis=2) + all_labels = np.argmin(all_dists, axis=1) + # persist centers if requested + if label_store: + try: + np.savez_compressed(label_store, centers=centers) + except Exception: + pass + return pd.Series(all_labels, index=df.index) + + +def generate_labels_for_df(df, n_buckets=100, method='md5', label_store=None): + """Generate deterministic bucket labels 1..n_buckets from rows using selected columns. + + Uses: report_dat, latitude, longitude, street1, street2, ward, injuries, fatalities. + Produces reproducible labels via md5 hashing of a normalized feature string. + """ + if method == 'kmeans': + return generate_kmeans_labels(df, n_buckets=n_buckets, label_store=label_store) + + # Be flexible about column names (case variations and alternate names). + colmap = {c.lower(): c for c in df.columns} + + def get_col(*candidates): + for cand in candidates: + key = cand.lower() + if key in colmap: + return colmap[key] + return None + + report_col = get_col('report_dat', 'reportdate', 'fromdate', 'lastupdatedate') + lat_col = get_col('latitude', 'mpdlatitude', 'lat') + lon_col = get_col('longitude', 'mpdlongitude', 'lon') + street1_col = get_col('street1', 'address', 'mar_address', 'nearestintstreetname') + street2_col = get_col('street2', 'nearestintstreetname') + ward_col = get_col('ward') + + inj_cols = [c for c in df.columns if 'INJUR' in c.upper()] + fat_cols = [c for c in df.columns if 'FATAL' in c.upper()] + + uid = get_col('crimeid', 'eventid', 'objectid', 'ccn') + + def row_to_bucket(row): + parts = [] + # date + parts.append(_normalize_date(row.get(report_col, '') if report_col else '')) + # lat/lon rounded + lat = row.get(lat_col, '') if lat_col else '' + lon = row.get(lon_col, '') if lon_col else '' + try: + parts.append(str(round(float(lat), 5)) if pd.notna(lat) and lat != '' else '') + except Exception: + parts.append('') + try: + parts.append(str(round(float(lon), 5)) if pd.notna(lon) and lon != '' else '') + except Exception: + parts.append('') + + # streets and ward + parts.append(_normalize_str(row.get(street1_col, '') if street1_col else '')) + parts.append(_normalize_str(row.get(street2_col, '') if street2_col else '')) + parts.append(_normalize_str(row.get(ward_col, '') if ward_col else '')) + + # injuries: sum any injury-like columns + inj_sum = 0 + for c in inj_cols: + try: + v = row.get(c, 0) + inj_sum += int(v) if pd.notna(v) and v != '' else 0 + except Exception: + pass + parts.append(str(inj_sum)) + + # fatalities: sum any fatal-like columns + fat_sum = 0 + for c in fat_cols: + try: + v = row.get(c, 0) + fat_sum += int(v) if pd.notna(v) and v != '' else 0 + except Exception: + pass + parts.append(str(fat_sum)) + + # fallback uid + if uid: + parts.append(str(row.get(uid, ''))) + + s = '|'.join(parts) + h = hashlib.md5(s.encode('utf-8')).hexdigest() + val = int(h, 16) % n_buckets + return val + + return df.apply(row_to_bucket, axis=1) + + +def _add_date_features(df, date_col_candidates=None): + """Add simple date-derived numeric columns to the dataframe. + + Adds: report_year, report_month, report_day, report_weekday, report_hour (where available). + If no date column is found, function is a no-op. + """ + if date_col_candidates is None: + date_col_candidates = ['report_dat', 'reportdate', 'fromdate', 'lastupdatedate', 'date', 'occur_date'] + colmap = {c.lower(): c for c in df.columns} + date_col = None + for cand in date_col_candidates: + if cand.lower() in colmap: + date_col = colmap[cand.lower()] + break + if date_col is None: + return + try: + ser = pd.to_datetime(df[date_col], errors='coerce') + except Exception: + ser = pd.to_datetime(df[date_col].astype(str), errors='coerce') + + df['report_year'] = ser.dt.year.fillna(-1).astype(float) + df['report_month'] = ser.dt.month.fillna(-1).astype(float) + df['report_day'] = ser.dt.day.fillna(-1).astype(float) + df['report_weekday'] = ser.dt.weekday.fillna(-1).astype(float) + # hour may not exist; if parsing fails we'll get NaN + df['report_hour'] = ser.dt.hour.fillna(-1).astype(float) + + +def _add_hashed_street(df, n_hash_buckets=32, street_col_candidates=None): + """Add a small hashed numeric feature for street/address text fields. + + Adds `street_hash_0..N-1` as dense float columns containing one-hot-ish hashed values. + Uses MD5-based hashing reduced to a bucket and then maps to a small integer vector. + """ + if street_col_candidates is None: + street_col_candidates = ['street1', 'street', 'address', 'mar_address', 'nearestintstreetname'] + colmap = {c.lower(): c for c in df.columns} + street_col = None + for cand in street_col_candidates: + if cand.lower() in colmap: + street_col = colmap[cand.lower()] + break + if street_col is None: + return + + import hashlib + # create a single integer hash bucket per row + def row_hash(val): + if pd.isna(val) or str(val).strip() == '': + return -1 + h = hashlib.md5(str(val).encode('utf-8')).hexdigest() + return int(h, 16) % n_hash_buckets + + buckets = df[street_col].apply(row_hash).fillna(-1).astype(int).to_numpy() + # create N numeric columns with a one-hot style (0/1) encoded as floats; missing bucket => zeros + for i in range(n_hash_buckets): + colname = f'street_hash_{i}' + df[colname] = (buckets == i).astype(float) + + +def _add_latlon_bins(df, bins=20, lat_col_candidates=None, lon_col_candidates=None): + """Add coarse spatial bins for latitude/longitude and rounded lat/lon numeric features. + + Adds: lat_round, lon_round, lat_bin, lon_bin (bins numbered 0..bins-1, -1 for missing). + """ + if lat_col_candidates is None: + lat_col_candidates = ['latitude', 'mpdlatitude', 'lat'] + if lon_col_candidates is None: + lon_col_candidates = ['longitude', 'mpdlongitude', 'lon'] + colmap = {c.lower(): c for c in df.columns} + lat_col = None + lon_col = None + for cand in lat_col_candidates: + if cand.lower() in colmap: + lat_col = colmap[cand.lower()] + break + for cand in lon_col_candidates: + if cand.lower() in colmap: + lon_col = colmap[cand.lower()] + break + if lat_col is None or lon_col is None: + return + try: + lat = pd.to_numeric(df[lat_col], errors='coerce') + lon = pd.to_numeric(df[lon_col], errors='coerce') + except Exception: + lat = pd.to_numeric(df[lat_col].astype(str), errors='coerce') + lon = pd.to_numeric(df[lon_col].astype(str), errors='coerce') + + df['lat_round'] = lat.round(3).fillna(0.0).astype(float) + df['lon_round'] = lon.round(3).fillna(0.0).astype(float) + + try: + # compute bins using quantiles if possible to get balanced bins; fallback to linear bins + valid_lat = lat.dropna() + valid_lon = lon.dropna() + if len(valid_lat) >= bins and len(valid_lon) >= bins: + # qcut may produce NaNs for duplicates; use rank-based discretization + df['lat_bin'] = pd.qcut(lat.rank(method='first'), q=bins, labels=False, duplicates='drop') + df['lon_bin'] = pd.qcut(lon.rank(method='first'), q=bins, labels=False, duplicates='drop') + else: + lat_min, lat_max = valid_lat.min() if len(valid_lat) > 0 else 0.0, valid_lat.max() if len(valid_lat) > 0 else 0.0 + lon_min, lon_max = valid_lon.min() if len(valid_lon) > 0 else 0.0, valid_lon.max() if len(valid_lon) > 0 else 0.0 + lat_span = (lat_max - lat_min) + 1e-6 + lon_span = (lon_max - lon_min) + 1e-6 + df['lat_bin'] = (((lat - lat_min) / lat_span) * bins).fillna(-1).astype(int).clip(lower=-1, upper=bins-1) + df['lon_bin'] = (((lon - lon_min) / lon_span) * bins).fillna(-1).astype(int).clip(lower=-1, upper=bins-1) + except Exception: + # fallback: set -1 for bins + df['lat_bin'] = -1 + df['lon_bin'] = -1 + + +# Debugging code - to be removed or commented out in production +# python - <<'PY' +# import pandas as pd +# from data import generate_labels_for_df +# df = pd.read_csv('data.csv', nrows=50, low_memory=False) +# labs = generate_labels_for_df(df, n_buckets=100) +# print(df[['REPORTDATE','LATITUDE','LONGITUDE','ADDRESS','WARD']].head().to_string()) +# print('labels:', list(labs[:20])) +# PY + +# Command to run the training (to be executed in the terminal, not in the script) +# python train.py data.csv --model-type mlp --generate-labels --n-buckets 100 --epochs 5 --batch-size 256 --lr 1e-3 + diff --git a/roadcast/debug_labels.py b/roadcast/debug_labels.py new file mode 100644 index 0000000..7529efd --- /dev/null +++ b/roadcast/debug_labels.py @@ -0,0 +1,76 @@ +import pandas as pd +import hashlib +from data import _normalize_str, _normalize_date + +p='data.csv' +df=pd.read_csv(p, nrows=50, low_memory=False) +print('Columns:', list(df.columns)) + +colmap = {c.lower(): c for c in df.columns} + +def get_col(*candidates): + for cand in candidates: + key = cand.lower() + if key in colmap: + return colmap[key] + return None + +report_col = get_col('report_dat', 'reportdate', 'fromdate', 'lastupdatedate') +lat_col = get_col('latitude', 'mpdlatitude', 'lat') +lon_col = get_col('longitude', 'mpdlongitude', 'lon') +street1_col = get_col('street1', 'address', 'mar_address', 'nearestintstreetname') +street2_col = get_col('street2', 'nearestintstreetname') +ward_col = get_col('ward') +inj_cols = [c for c in df.columns if 'INJUR' in c.upper()] +fat_cols = [c for c in df.columns if 'FATAL' in c.upper()] +uid = get_col('crimeid', 'eventid', 'objectid', 'ccn') + +print('Resolved columns:') +print('report_col=', report_col) +print('lat_col=', lat_col) +print('lon_col=', lon_col) +print('street1_col=', street1_col) +print('street2_col=', street2_col) +print('ward_col=', ward_col) +print('inj_cols=', inj_cols[:10]) +print('fat_cols=', fat_cols[:10]) +print('uid=', uid) + +for i, row in df.iterrows(): + parts = [] + parts.append(_normalize_date(row.get(report_col, '') if report_col else '')) + lat = row.get(lat_col, '') if lat_col else '' + lon = row.get(lon_col, '') if lon_col else '' + try: + parts.append(str(round(float(lat), 5)) if pd.notna(lat) and lat != '' else '') + except Exception: + parts.append('') + try: + parts.append(str(round(float(lon), 5)) if pd.notna(lon) and lon != '' else '') + except Exception: + parts.append('') + parts.append(_normalize_str(row.get(street1_col, '') if street1_col else '')) + parts.append(_normalize_str(row.get(street2_col, '') if street2_col else '')) + parts.append(_normalize_str(row.get(ward_col, '') if ward_col else '')) + inj_sum = 0 + for c in inj_cols: + try: + v = row.get(c, 0) + inj_sum += int(v) if pd.notna(v) and v != '' else 0 + except Exception: + pass + parts.append(str(inj_sum)) + fat_sum = 0 + for c in fat_cols: + try: + v = row.get(c, 0) + fat_sum += int(v) if pd.notna(v) and v != '' else 0 + except Exception: + pass + parts.append(str(fat_sum)) + if uid: + parts.append(str(row.get(uid, ''))) + s='|'.join(parts) + h=hashlib.md5(s.encode('utf-8')).hexdigest() + val=int(h,16)%100 + print(i, 'label=', val, 's="'+s+'"') diff --git a/roadcast/diagnostics.py b/roadcast/diagnostics.py new file mode 100644 index 0000000..2bc7219 --- /dev/null +++ b/roadcast/diagnostics.py @@ -0,0 +1,67 @@ +import traceback +import numpy as np +import torch +from torch.utils.data import DataLoader + +from data import CSVDataset +from models import create_model + + +def print_arr_stats(name, arr): + arr = np.asarray(arr) + print(f"{name}: shape={arr.shape} dtype={arr.dtype}") + print(f" mean={np.nanmean(arr):.6f} std={np.nanstd(arr):.6f} min={np.nanmin(arr):.6f} max={np.nanmax(arr):.6f}") + print(f" any_nan={np.isnan(arr).any()} any_inf={np.isinf(arr).any()}") + + +def main(): + try: + print('Loading dataset...') + ds = CSVDataset('data.csv', generate_labels=True, n_buckets=100) + print(f'dataset length: {len(ds)}') + + X = ds.features.numpy() + y = ds.labels.numpy() + + print_arr_stats('X (all)', X) + # per-column NaN/inf counts + nan_counts = np.isnan(X).sum(axis=0) + inf_counts = np.isinf(X).sum(axis=0) + print('per-column nan counts (first 20):', nan_counts[:20].tolist()) + print('per-column inf counts (first 20):', inf_counts[:20].tolist()) + + print('Labels stats: unique count=', len(np.unique(y))) + print('Labels min/max:', int(y.min()), int(y.max())) + vals, counts = np.unique(y, return_counts=True) + print('Label distribution (first 20):', list(zip(vals[:20].tolist(), counts[:20].tolist()))) + + # get a small batch + dl = DataLoader(ds, batch_size=64, shuffle=False) + xb, yb = next(iter(dl)) + print_arr_stats('xb batch', xb.numpy()) + print('yb batch unique:', np.unique(yb.numpy())) + + # build model + print('Building model...') + model = create_model(device='cpu', model_type='mlp', input_dim=X.shape[1], num_classes=100) + model.eval() + with torch.no_grad(): + out = model(xb) + out_np = out.numpy() + print_arr_stats('model outputs', out_np) + + # check for rows with NaN/Inf in features + bad_rows = np.where(np.isnan(X).any(axis=1) | np.isinf(X).any(axis=1))[0] + print('bad rows count:', len(bad_rows)) + if len(bad_rows) > 0: + print('first bad row index:', bad_rows[0]) + print('row values:', X[bad_rows[0]].tolist()) + print('label:', int(y[bad_rows[0]])) + + except Exception as e: + print('Exception during diagnostics:') + traceback.print_exc() + + +if __name__ == '__main__': + main() diff --git a/roadcast/fit_kmeans.py b/roadcast/fit_kmeans.py new file mode 100644 index 0000000..0a43828 --- /dev/null +++ b/roadcast/fit_kmeans.py @@ -0,0 +1,65 @@ +"""Fit k-means centers on CSV numeric features (optionally PCA) and save centers to .npz + +Usage: python fit_kmeans.py data.csv --n-buckets 10 --out kmeans_centers_final.npz --sample 50000 --pca 50 +""" +import argparse +import numpy as np +import pandas as pd + +from data import generate_kmeans_labels + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('csv') + parser.add_argument('--n-buckets', type=int, default=10) + parser.add_argument('--out', default='kmeans_centers_final.npz') + parser.add_argument('--sample', type=int, default=50000, help='max rows to sample for fitting') + parser.add_argument('--pca', type=int, default=0, help='Apply PCA to reduce dims before kmeans (0=none)') + args = parser.parse_args() + + # read numeric columns only to avoid huge memory usage + df = pd.read_csv(args.csv, low_memory=False) + num_df = df.select_dtypes(include=['number']).fillna(0.0) + data = num_df.values.astype(float) + if data.shape[0] == 0 or data.shape[1] == 0: + raise SystemExit('No numeric data found in CSV') + + # sample rows if requested + if args.sample and args.sample < data.shape[0]: + rng = np.random.default_rng(42) + idx = rng.choice(data.shape[0], size=args.sample, replace=False) + sample_data = data[idx] + else: + sample_data = data + + # Use the kmeans implementation via generate_kmeans_labels for fitting centers. + # We'll call the internal function by adapting it here: import numpy locally. + import numpy as _np + + # initialize centers by random sampling + rng = _np.random.default_rng(42) + k = min(args.n_buckets, sample_data.shape[0]) + centers_idx = rng.choice(sample_data.shape[0], size=k, replace=False) + centers = sample_data[centers_idx].astype(float) + + max_iters = 50 + for _ in range(max_iters): + dists = np.linalg.norm(sample_data[:, None, :] - centers[None, :, :], axis=2) + labels = np.argmin(dists, axis=1) + new_centers = np.zeros_like(centers) + counts = np.zeros((centers.shape[0],), dtype=int) + for i, lab in enumerate(labels): + new_centers[lab] += sample_data[i] + counts[lab] += 1 + for kk in range(centers.shape[0]): + if counts[kk] > 0: + new_centers[kk] = new_centers[kk] / counts[kk] + else: + new_centers[kk] = sample_data[rng.integers(0, sample_data.shape[0])] + shift = np.linalg.norm(new_centers - centers, axis=1).max() + centers = new_centers + if shift < 1e-4: + break + + np.savez_compressed(args.out, centers=centers) + print('Saved centers to', args.out) diff --git a/roadcast/inference.py b/roadcast/inference.py new file mode 100644 index 0000000..49e8b6e --- /dev/null +++ b/roadcast/inference.py @@ -0,0 +1,30 @@ +import os +import torch +import torch.nn.functional as F +from PIL import Image +from torchvision import transforms + +from models import create_model + + +def load_model(path, device=None, in_channels=3, num_classes=10): + device = device or ('cuda' if torch.cuda.is_available() else 'cpu') + checkpoint = torch.load(path, map_location=device) + model = create_model(device=device, in_channels=in_channels, num_classes=num_classes) + model.load_state_dict(checkpoint['model_state_dict']) + model.eval() + class_to_idx = checkpoint.get('class_to_idx') + idx_to_class = {v: k for k, v in class_to_idx.items()} if class_to_idx else None + return model, idx_to_class + + +def predict_image(model, img_path, device=None): + device = device or ('cuda' if torch.cuda.is_available() else 'cpu') + preprocess = transforms.Compose([transforms.Resize((224, 224)), transforms.ToTensor()]) + img = Image.open(img_path).convert('RGB') + x = preprocess(img).unsqueeze(0).to(device) + with torch.no_grad(): + logits = model(x) + probs = F.softmax(logits, dim=1) + conf, idx = torch.max(probs, dim=1) + return int(idx.item()), float(conf.item()) diff --git a/roadcast/inspect_csv.py b/roadcast/inspect_csv.py new file mode 100644 index 0000000..4e2c0b2 --- /dev/null +++ b/roadcast/inspect_csv.py @@ -0,0 +1,34 @@ +import pandas as pd + +p = 'data.csv' +print('Reading first 2000 rows of', p) +df = pd.read_csv(p, nrows=2000, low_memory=False) +print('Columns:', list(df.columns)) +cols = ['report_dat','latitude','longitude','street1','street2','ward','injuries','fatalities'] +print('\nField stats for label-generator columns:') +for c in cols: + if c in df.columns: + ser = df[c] + try: + unique = ser.dropna().unique()[:5].tolist() + except Exception: + unique = [] + print(f"{c}: present dtype={ser.dtype} n_unique={ser.nunique(dropna=False)} n_null={int(ser.isna().sum())} sample_values={unique}") + else: + print(f"{c}: MISSING") + +# If labels already present, show distribution +if 'label' in df.columns: + print('\nLabel column present in sample:') + print(df['label'].value_counts().head(20)) +else: + print('\nLabel column not present in sample') + +# Also show per-column fraction NaN for numeric columns +num_cols = df.select_dtypes(include=['number']).columns.tolist() +print('\nNumeric columns and NaN fraction (first 20):') +for c in num_cols[:20]: + ser = df[c] + print(f"{c}: n={len(ser)} null_frac={ser.isna().mean():.4f} min={ser.min()} max={ser.max()}") + +print('\nDone') diff --git a/roadcast/kmeans_centers.npz b/roadcast/kmeans_centers.npz new file mode 100644 index 0000000000000000000000000000000000000000..5784c04661944a5e1b0a7241caf2d7d15d0efc2b GIT binary patch literal 19190 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 R0RRC2IRF3vr%C_-005Wy7*_xQ literal 0 HcmV?d00001 diff --git a/roadcast/kmeans_centers_all.npz b/roadcast/kmeans_centers_all.npz new file mode 100644 index 0000000000000000000000000000000000000000..867fba08f926c8e77c3417ba2146dd14b9702790 GIT binary patch literal 3432 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

U=BF;~-YcfJvS!jZ?UO{; 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 z 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 LME>mm&wc+7jgHpd literal 0 HcmV?d00001 diff --git a/roadcast/models.py b/roadcast/models.py new file mode 100644 index 0000000..a3e7aee --- /dev/null +++ b/roadcast/models.py @@ -0,0 +1,68 @@ +import torch +import torch.nn as nn + + +class SimpleCNN(nn.Module): + """A small CNN for image classification (adjustable). Automatically computes flattened size.""" + def __init__(self, in_channels=3, num_classes=10, input_size=(3, 224, 224)): + super().__init__() + self.features = nn.Sequential( + nn.Conv2d(in_channels, 32, kernel_size=3, padding=1), + nn.ReLU(), + nn.MaxPool2d(2), + nn.Conv2d(32, 64, kernel_size=3, padding=1), + nn.ReLU(), + nn.MaxPool2d(2), + ) + # compute flatten size using a dummy tensor + with torch.no_grad(): + dummy = torch.zeros(1, *input_size) + feat = self.features(dummy) + flat_features = int(feat.numel() / feat.shape[0]) + + self.classifier = nn.Sequential( + nn.Flatten(), + nn.Linear(flat_features, 256), + nn.ReLU(), + nn.Dropout(0.5), + nn.Linear(256, num_classes), + ) + + def forward(self, x): + x = self.features(x) + x = self.classifier(x) + return x + + +class MLP(nn.Module): + """Simple MLP for tabular CSV data classification.""" + def __init__(self, input_dim, hidden_dims=(256, 128), num_classes=2): + super().__init__() + layers = [] + prev = input_dim + for h in hidden_dims: + layers.append(nn.Linear(prev, h)) + layers.append(nn.ReLU()) + layers.append(nn.Dropout(0.2)) + prev = h + layers.append(nn.Linear(prev, num_classes)) + self.net = nn.Sequential(*layers) + + def forward(self, x): + return self.net(x) + + +def create_model(device=None, in_channels=3, num_classes=10, input_size=(3, 224, 224), model_type='cnn', input_dim=None, hidden_dims=None): + if model_type == 'mlp': + if input_dim is None: + raise ValueError('input_dim is required for mlp model_type') + if hidden_dims is None: + model = MLP(input_dim=input_dim, num_classes=num_classes) + else: + model = MLP(input_dim=input_dim, hidden_dims=hidden_dims, num_classes=num_classes) + else: + model = SimpleCNN(in_channels=in_channels, num_classes=num_classes, input_size=input_size) + + if device: + model.to(device) + return model diff --git a/roadcast/openweather_inference.py b/roadcast/openweather_inference.py new file mode 100644 index 0000000..3775112 --- /dev/null +++ b/roadcast/openweather_inference.py @@ -0,0 +1,339 @@ +""" +Fetch OpenWeather data for a coordinate/time and run the trained MLP to predict the k-means cluster label. + +Usage examples: + # with training CSV provided to compute preprocessing stats: + python openweather_inference.py --lat 38.9 --lon -77.0 --datetime "2025-09-27T12:00:00" --train-csv data.csv --model model.pth --centers kmeans_centers_all.npz --api-key $OPENWEATHER_KEY + + # with precomputed preprocess meta (saved from training): + python openweather_inference.py --lat 38.9 --lon -77.0 --datetime "2025-09-27T12:00:00" --preprocess-meta preprocess_meta.npz --model model.pth --centers kmeans_centers_all.npz --api-key $OPENWEATHER_KEY + +Notes: +- The script uses the same feature-engineering helpers in `data.py` so the model sees identical inputs. +- You must either provide `--train-csv` (to compute feature columns & means/stds) or `--preprocess-meta` previously saved. +- Provide the OpenWeather API key via --api-key or the OPENWEATHER_KEY environment variable. +""" + +import os +import argparse +import json +from datetime import datetime +import numpy as np +import pandas as pd +import torch +import torch.nn.functional as F + +# reuse helpers from your repo +from data import _add_date_features, _add_latlon_bins, _add_hashed_street, CSVDataset +from inference import load_model + +# module-level caches to avoid reloading heavy artifacts per request +_CACHED_MODEL = None +_CACHED_IDX_TO_CLASS = None +_CACHED_CENTERS = None +_CACHED_PREPROCESS_META = None + + +OW_BASE = 'https://api.openweathermap.org/data/2.5/onecall' + + +def fetch_openweather(lat, lon, api_key, dt_iso=None): + """Fetch weather from OpenWeather One Call API for given lat/lon. If dt_iso provided, we fetch current+hourly and pick closest timestamp.""" + try: + import requests + except Exception: + raise RuntimeError('requests library is required to fetch OpenWeather data') + params = { + 'lat': float(lat), + 'lon': float(lon), + 'appid': api_key, + 'units': 'metric', + 'exclude': 'minutely,alerts' + } + r = requests.get(OW_BASE, params=params, timeout=10) + r.raise_for_status() + payload = r.json() + # if dt_iso provided, find nearest hourly data point + if dt_iso: + try: + target = pd.to_datetime(dt_iso) + except Exception: + target = None + best = None + if 'hourly' in payload and target is not None: + hours = payload['hourly'] + best = min(hours, key=lambda h: abs(pd.to_datetime(h['dt'], unit='s') - target)) + # convert keys to a flat dict with prefix 'ow_' + d = { + 'ow_temp': best.get('temp'), + 'ow_feels_like': best.get('feels_like'), + 'ow_pressure': best.get('pressure'), + 'ow_humidity': best.get('humidity'), + 'ow_wind_speed': best.get('wind_speed'), + 'ow_clouds': best.get('clouds'), + 'ow_pop': best.get('pop'), + } + return d + # fallback: use current + cur = payload.get('current', {}) + d = { + 'ow_temp': cur.get('temp'), + 'ow_feels_like': cur.get('feels_like'), + 'ow_pressure': cur.get('pressure'), + 'ow_humidity': cur.get('humidity'), + 'ow_wind_speed': cur.get('wind_speed'), + 'ow_clouds': cur.get('clouds'), + 'ow_pop': None, + } + return d + + +def fetch_roadrisk(roadrisk_url, api_key=None): + """Fetch the RoadRisk endpoint (expects JSON). If `api_key` is provided, we'll attach it as a query param if the URL has no key. + + We flatten top-level numeric fields into `rr_*` keys for the feature row. + """ + # if api_key provided and url does not contain appid, append it + try: + import requests + except Exception: + raise RuntimeError('requests library is required to fetch RoadRisk data') + url = roadrisk_url + if api_key and 'appid=' not in roadrisk_url: + sep = '&' if '?' in roadrisk_url else '?' + url = f"{roadrisk_url}{sep}appid={api_key}" + + r = requests.get(url, timeout=10) + r.raise_for_status() + payload = r.json() + # flatten numeric top-level fields + out = {} + if isinstance(payload, dict): + for k, v in payload.items(): + if isinstance(v, (int, float)): + out[f'rr_{k}'] = v + # if nested objects contain simple numeric fields, pull them too (one level deep) + elif isinstance(v, dict): + for kk, vv in v.items(): + if isinstance(vv, (int, float)): + out[f'rr_{k}_{kk}'] = vv + return out + + +def build_row(lat, lon, dt_iso=None, street=None, extra_weather=None): + """Construct a single-row DataFrame with columns expected by the training pipeline. + + It intentionally uses column names the original `data.py` looked for (REPORTDATE, LATITUDE, LONGITUDE, ADDRESS, etc.). + """ + row = {} + # date column matching common names + row['REPORTDATE'] = dt_iso if dt_iso else datetime.utcnow().isoformat() + row['LATITUDE'] = lat + row['LONGITUDE'] = lon + row['ADDRESS'] = street if street else '' + # include some injury/fatality placeholders that the label generator expects + row['INJURIES'] = 0 + row['FATALITIES'] = 0 + # include weather features returned by OpenWeather (prefixed 'ow_') + if extra_weather: + for k, v in extra_weather.items(): + row[k] = v + return pd.DataFrame([row]) + + +def prepare_features(df_row, train_csv=None, preprocess_meta=None, feature_engineer=True, lat_lon_bins=20): + """Given a one-row DataFrame, apply same feature engineering and standardization as training. + + If preprocess_meta is provided (npz), use it. Otherwise train_csv must be provided to compute stats. + Returns a torch.FloatTensor of shape (1, input_dim) and the feature_columns list. + """ + # apply feature engineering helpers + if feature_engineer: + try: + _add_date_features(df_row) + except Exception: + pass + try: + _add_latlon_bins(df_row, bins=lat_lon_bins) + except Exception: + pass + try: + _add_hashed_street(df_row) + except Exception: + pass + + # if meta provided, load feature_columns, means, stds + if preprocess_meta and os.path.exists(preprocess_meta): + meta = np.load(preprocess_meta, allow_pickle=True) + feature_columns = meta['feature_columns'].tolist() + means = meta['means'] + stds = meta['stds'] + else: + if not train_csv: + raise ValueError('Either preprocess_meta or train_csv must be provided to derive feature stats') + # instantiate a CSVDataset on train_csv (feature_engineer True) to reuse its preprocessing + ds = CSVDataset(train_csv, feature_columns=None, label_column='label', generate_labels=False, n_buckets=10, label_method='kmeans', label_store=None, feature_engineer=feature_engineer, lat_lon_bins=lat_lon_bins, nrows=None) + feature_columns = ds.feature_columns + means = ds.feature_means + stds = ds.feature_stds + # save meta for reuse + np.savez_compressed('preprocess_meta.npz', feature_columns=np.array(feature_columns, dtype=object), means=means, stds=stds) + print('Saved preprocess_meta.npz') + + # ensure all feature columns exist in df_row + for c in feature_columns: + if c not in df_row.columns: + df_row[c] = 0 + + # coerce and fill using means + features_df = df_row[feature_columns].apply(lambda c: pd.to_numeric(c, errors='coerce')) + features_df = features_df.fillna(pd.Series(means, index=feature_columns)).fillna(0.0) + # standardize + features_np = (features_df.values - means) / (stds + 1e-6) + import torch + return torch.tensor(features_np, dtype=torch.float32), feature_columns + + +def predict_from_openweather(lat, lon, dt_iso=None, street=None, api_key=None, train_csv=None, preprocess_meta=None, model_path='model.pth', centers_path='kmeans_centers_all.npz', roadrisk_url=None): + api_key = api_key or os.environ.get('OPENWEATHER_KEY') + if api_key is None: + raise ValueError('OpenWeather API key required via --api-key or OPENWEATHER_KEY env var') + + # gather weather/road-risk features + weather = {} + if roadrisk_url: + try: + rr = fetch_roadrisk(roadrisk_url, api_key=api_key) + weather.update(rr) + except Exception as e: + print('Warning: failed to fetch roadrisk URL:', e) + else: + try: + ow = fetch_openweather(lat, lon, api_key, dt_iso=dt_iso) + weather.update(ow) + except Exception as e: + print('Warning: failed to fetch openweather:', e) + + df_row = build_row(lat, lon, dt_iso=dt_iso, street=street, extra_weather=weather) + x_tensor, feature_columns = prepare_features(df_row, train_csv=train_csv, preprocess_meta=preprocess_meta) + + # load model (infer num_classes from centers file if possible) + global _CACHED_MODEL, _CACHED_IDX_TO_CLASS, _CACHED_CENTERS, _CACHED_PREPROCESS_META + + # ensure we have preprocess_meta available (prefer supplied path, otherwise fallback to saved file) + if preprocess_meta is None: + candidate = os.path.join(os.getcwd(), 'preprocess_meta.npz') + if os.path.exists(candidate): + preprocess_meta = candidate + + # load centers (cache across requests) + if _CACHED_CENTERS is None: + if centers_path and os.path.exists(centers_path): + try: + npz = np.load(centers_path) + _CACHED_CENTERS = npz['centers'] + except Exception: + _CACHED_CENTERS = None + else: + _CACHED_CENTERS = None + + num_classes = _CACHED_CENTERS.shape[0] if _CACHED_CENTERS is not None else 10 + + # load model once and cache it + if _CACHED_MODEL is None: + try: + _CACHED_MODEL, _CACHED_IDX_TO_CLASS = load_model(model_path, device=None, in_channels=3, num_classes=num_classes) + device = 'cuda' if torch.cuda.is_available() else 'cpu' + _CACHED_MODEL.to(device) + except Exception as e: + raise + model = _CACHED_MODEL + idx_to_class = _CACHED_IDX_TO_CLASS + device = 'cuda' if torch.cuda.is_available() else 'cpu' + x_tensor = x_tensor.to(device) + with torch.no_grad(): + logits = model(x_tensor) + probs = F.softmax(logits, dim=1).cpu().numpy()[0] + pred_idx = int(probs.argmax()) + confidence = float(probs.max()) + + # optionally provide cluster centroid info + centroid = _CACHED_CENTERS[pred_idx] if _CACHED_CENTERS is not None else None + + return { + 'pred_cluster': int(pred_idx), + 'confidence': confidence, + 'probabilities': probs.tolist(), + 'centroid': centroid.tolist() if centroid is not None else None, + 'feature_columns': feature_columns, + 'used_preprocess_meta': preprocess_meta + } + + +def init_inference(model_path='model.pth', centers_path='kmeans_centers_all.npz', preprocess_meta=None): + """Eagerly load model, centers, and preprocess_meta into module-level caches. + + This is intended to be called at app startup to surface load errors early and avoid + per-request disk IO. The function is best-effort and will print warnings if artifacts + are missing. + """ + global _CACHED_MODEL, _CACHED_IDX_TO_CLASS, _CACHED_CENTERS, _CACHED_PREPROCESS_META + + # prefer existing saved preprocess_meta if not explicitly provided + if preprocess_meta is None: + candidate = os.path.join(os.getcwd(), 'preprocess_meta.npz') + if os.path.exists(candidate): + preprocess_meta = candidate + + _CACHED_PREPROCESS_META = preprocess_meta + + # load centers + if _CACHED_CENTERS is None: + if centers_path and os.path.exists(centers_path): + try: + npz = np.load(centers_path) + _CACHED_CENTERS = npz['centers'] + print(f'Loaded centers from {centers_path}') + except Exception as e: + print('Warning: failed to load centers:', e) + _CACHED_CENTERS = None + else: + print('No centers file found at', centers_path) + _CACHED_CENTERS = None + + num_classes = _CACHED_CENTERS.shape[0] if _CACHED_CENTERS is not None else 10 + + # load model + if _CACHED_MODEL is None: + try: + _CACHED_MODEL, _CACHED_IDX_TO_CLASS = load_model(model_path, device=None, in_channels=3, num_classes=num_classes) + device = 'cuda' if torch.cuda.is_available() else 'cpu' + _CACHED_MODEL.to(device) + print(f'Loaded model from {model_path}') + except Exception as e: + print('Warning: failed to load model:', e) + _CACHED_MODEL = None + + return { + 'model_loaded': _CACHED_MODEL is not None, + 'centers_loaded': _CACHED_CENTERS is not None, + 'preprocess_meta': _CACHED_PREPROCESS_META + } + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--lat', type=float, required=True) + parser.add_argument('--lon', type=float, required=True) + parser.add_argument('--datetime', default=None, help='ISO datetime string to query hourly weather (optional)') + parser.add_argument('--street', default='') + parser.add_argument('--api-key', default=None, help='OpenWeather API key or use OPENWEATHER_KEY env var') + parser.add_argument('--train-csv', default=None, help='Path to training CSV to compute preprocessing stats (optional if --preprocess-meta provided)') + parser.add_argument('--preprocess-meta', default=None, help='Path to precomputed preprocess_meta.npz (optional)') + parser.add_argument('--model', default='model.pth') + parser.add_argument('--centers', default='kmeans_centers_all.npz') + parser.add_argument('--roadrisk-url', default=None, help='Optional custom RoadRisk API URL (if provided, will be queried instead of OneCall)') + args = parser.parse_args() + + out = predict_from_openweather(args.lat, args.lon, dt_iso=args.datetime, street=args.street, api_key=args.api_key, train_csv=args.train_csv, preprocess_meta=args.preprocess_meta, model_path=args.model, centers_path=args.centers, roadrisk_url=args.roadrisk_url) + print(json.dumps(out, indent=2)) diff --git a/roadcast/requirements.txt b/roadcast/requirements.txt new file mode 100644 index 0000000..ee9c857 --- /dev/null +++ b/roadcast/requirements.txt @@ -0,0 +1,5 @@ +flask>=2.0 +torch>=1.13 +torchvision>=0.14 +Pillow>=9.0 +tqdm>=4.60 diff --git a/roadcast/run_batch_inference.py b/roadcast/run_batch_inference.py new file mode 100644 index 0000000..119610d --- /dev/null +++ b/roadcast/run_batch_inference.py @@ -0,0 +1,113 @@ +import os +import argparse +import pandas as pd +import numpy as np +import time + +import openweather_inference as owi + + +def find_column(df_cols, candidates): + cmap = {c.lower(): c for c in df_cols} + for cand in candidates: + if cand.lower() in cmap: + return cmap[cand.lower()] + return None + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('csv', help='Path to data CSV (e.g., data.csv)') + parser.add_argument('--out', default='inference_results.csv') + parser.add_argument('--lat-col', default=None) + parser.add_argument('--lon-col', default=None) + parser.add_argument('--date-col', default=None) + parser.add_argument('--model', default='model.pth') + parser.add_argument('--centers', default='kmeans_centers_all.npz') + parser.add_argument('--preprocess-meta', default=None) + parser.add_argument('--api-key', default=None) + parser.add_argument('--live', action='store_true', help='If set, call external RoadRisk/OpenWeather per row') + parser.add_argument('--roadrisk-url', default=None, help='Optional per-request RoadRisk URL to use when --live') + parser.add_argument('--subset', type=int, default=0, help='Process only first N rows for testing') + args = parser.parse_args() + + df = pd.read_csv(args.csv, low_memory=False) + nrows = args.subset if args.subset and args.subset > 0 else len(df) + df = df.iloc[:nrows].copy() + + # find sensible columns + lat_col = args.lat_col or find_column(df.columns, ['latitude', 'lat', 'mpdlatitude']) + lon_col = args.lon_col or find_column(df.columns, ['longitude', 'lon', 'mpdlongitude']) + date_col = args.date_col or find_column(df.columns, ['report_dat', 'reportdate', 'fromdate', 'lastupdatedate', 'date', 'occur_date']) + + if lat_col is None or lon_col is None: + raise SystemExit('Could not find latitude/longitude columns automatically. Pass --lat-col and --lon-col.') + + print(f'Using lat column: {lat_col}, lon column: {lon_col}, date column: {date_col}') + + # eager init caches + status = owi.init_inference(model_path=args.model, centers_path=args.centers, preprocess_meta=args.preprocess_meta) + print('init status:', status) + + results = [] + t0 = time.time() + for i, row in df.iterrows(): + lat = row.get(lat_col) + lon = row.get(lon_col) + dt = row.get(date_col) if date_col else None + + try: + if args.live: + # call the full pipeline which may hit remote API + out = owi.predict_from_openweather(lat, lon, dt_iso=dt, street=None, api_key=args.api_key, train_csv=None, preprocess_meta=args.preprocess_meta, model_path=args.model, centers_path=args.centers, roadrisk_url=args.roadrisk_url) + else: + # local-only path: build row, prepare features using preprocess_meta, and run cached model + df_row = owi.build_row(lat, lon, dt_iso=dt, street=None, extra_weather=None) + x_tensor, feature_columns = owi.prepare_features(df_row, train_csv=None, preprocess_meta=args.preprocess_meta) + # ensure model cached + if owi._CACHED_MODEL is None: + owi.init_inference(model_path=args.model, centers_path=args.centers, preprocess_meta=args.preprocess_meta) + model = owi._CACHED_MODEL + centers = owi._CACHED_CENTERS + device = 'cuda' if __import__('torch').cuda.is_available() else 'cpu' + model.to(device) + xt = x_tensor.to(device) + import torch + import torch.nn.functional as F + with torch.no_grad(): + logits = model(xt) + probs = F.softmax(logits, dim=1).cpu().numpy()[0] + pred_idx = int(probs.argmax()) + confidence = float(probs.max()) + out = {'pred_cluster': pred_idx, 'confidence': confidence, 'probabilities': probs.tolist(), 'centroid': centers[pred_idx].tolist() if centers is not None else None, 'feature_columns': feature_columns} + except Exception as e: + out = {'error': str(e)} + + # combine row and output into flat result + res = { + 'orig_index': i, + 'lat': lat, + 'lon': lon, + 'datetime': str(dt), + } + if 'error' in out: + res.update({'error': out['error']}) + else: + res.update({ + 'pred_cluster': int(out.get('pred_cluster')), + 'confidence': float(out.get('confidence')), + }) + results.append(res) + + if (len(results) % 50) == 0: + print(f'Processed {len(results)}/{nrows} rows...') + + elapsed = time.time() - t0 + print(f'Finished {len(results)} rows in {elapsed:.2f}s') + out_df = pd.DataFrame(results) + out_df.to_csv(args.out, index=False) + print('Wrote', args.out) + + +if __name__ == '__main__': + main() diff --git a/roadcast/tests/smoke_predict.py b/roadcast/tests/smoke_predict.py new file mode 100644 index 0000000..b215b0d --- /dev/null +++ b/roadcast/tests/smoke_predict.py @@ -0,0 +1,23 @@ +import sys +import types +import os + +# Ensure repo root on path +sys.path.insert(0, r"C:\Users\Samarth Jain\Documents\roadcast") + +# Create a fake openweather_inference module with a predictable function +mod = types.ModuleType("openweather_inference") + +def predict_from_openweather(lat, lon, dt_iso=None, street='', api_key=None, train_csv=None, preprocess_meta=None, model_path=None, centers_path=None, roadrisk_url=None): + return {"label": 5, "confidence": 0.87, "lat": lat, "lon": lon, "dt": dt_iso} + +mod.predict_from_openweather = predict_from_openweather +sys.modules["openweather_inference"] = mod + +# Import the Flask app and use its test client +from app import app + +c = app.test_client() +res = c.post("/predict-roadrisk", json={"lat": 38.9, "lon": -77.0}) +print("STATUS:", res.status_code) +print("JSON:", res.get_json()) diff --git a/roadcast/tmp_infer.csv b/roadcast/tmp_infer.csv new file mode 100644 index 0000000..1af6b82 --- /dev/null +++ b/roadcast/tmp_infer.csv @@ -0,0 +1,11 @@ +orig_index,lat,lon,datetime,error +0,38.91557,-77.031697,2011/03/06 05:00:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +1,38.875558,-77.017556,2011/03/06 08:45:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +2,38.872976,-77.016987,2011/03/05 05:00:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +3,38.929433,-77.003943,2011/03/08 05:00:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +4,38.89674,-77.027034,2011/03/08 17:18:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +5,38.89093,-76.993494,2011/03/12 05:00:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +6,38.908478,-77.040086,2011/03/12 05:00:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +7,38.846563,-76.976504,2011/03/12 05:00:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +8,38.894783,-77.01292,2011/03/12 18:30:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats +9,38.934204,-77.034567,2011/03/14 04:00:00+00,Either preprocess_meta or train_csv must be provided to derive feature stats diff --git a/roadcast/train.py b/roadcast/train.py new file mode 100644 index 0000000..c646093 --- /dev/null +++ b/roadcast/train.py @@ -0,0 +1,158 @@ +import os +import time +import torch +from torch import nn, optim +from torch.utils.data import DataLoader, random_split +from tqdm import tqdm + +from data import ImageFolderDataset, CSVDataset +from models import create_model + + +def train(dataset_root, epochs=3, batch_size=16, lr=1e-3, device=None, num_classes=10, model_type='cnn', csv_label='label', generate_labels=False, n_buckets=100, label_method='md5', label_store=None, feature_engineer=False, lat_lon_bins=20, nrows=None, seed=42, hidden_dims=None, weight_decay=0.0): + device = device or ('cuda' if torch.cuda.is_available() else 'cpu') + # Detect CSV vs folder dataset + if os.path.isfile(dataset_root) and dataset_root.lower().endswith('.csv'): + dataset = CSVDataset(dataset_root, + label_column=csv_label, + generate_labels=generate_labels, + n_buckets=n_buckets, + label_method=label_method, + label_store=label_store, + feature_engineer=feature_engineer, + lat_lon_bins=lat_lon_bins, + nrows=nrows) + # seed numpy/torch RNGs for reproducibility in experiments + try: + import numpy as _np + _np.random.seed(seed) + except Exception: + pass + try: + import random as _py_random + _py_random.seed(seed) + except Exception: + pass + try: + import torch as _torch + _torch.manual_seed(seed) + if _torch.cuda.is_available(): + _torch.cuda.manual_seed_all(seed) + except Exception: + pass + # determine input dim for MLP + input_dim = dataset.features.shape[1] + # persist preprocessing metadata so inference can reuse identical stats + try: + import numpy as _np + meta_path = os.path.join(os.getcwd(), 'preprocess_meta.npz') + _np.savez_compressed(meta_path, feature_columns=_np.array(dataset.feature_columns, dtype=object), means=dataset.feature_means, stds=dataset.feature_stds) + print(f'Saved preprocess meta to {meta_path}') + except Exception: + pass + if model_type == 'cnn': + raise ValueError('CSV dataset should use model_type="mlp"') + # if we generated labels, infer the actual number of classes from the dataset labels + if generate_labels and hasattr(dataset, 'labels'): + try: + model_num_classes = int(dataset.labels.max().item()) + 1 + except Exception: + model_num_classes = n_buckets + else: + model_num_classes = n_buckets if generate_labels else num_classes + # parse hidden_dims if provided by caller (tuple or list) + model = create_model(device=device, model_type='mlp', input_dim=input_dim, num_classes=model_num_classes, hidden_dims=hidden_dims) + else: + # assume folder of images + dataset = ImageFolderDataset(dataset_root) + model = create_model(device=device, model_type='cnn', input_size=(3, 224, 224), num_classes=num_classes) + + # simple train/val split + val_size = max(1, int(0.1 * len(dataset))) + train_size = len(dataset) - val_size + train_set, val_set = random_split(dataset, [train_size, val_size]) + train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) + val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False) + + criterion = nn.CrossEntropyLoss() + optimizer = optim.Adam(model.parameters(), lr=lr, weight_decay=weight_decay) + + best_val_acc = 0.0 + best_path = None + + for epoch in range(epochs): + model.train() + running_loss = 0.0 + pbar = tqdm(train_loader, desc=f"Epoch {epoch+1}/{epochs}") + for xb, yb in pbar: + xb = xb.to(device) + yb = yb.to(device) + optimizer.zero_grad() + outputs = model(xb) + loss = criterion(outputs, yb) + loss.backward() + optimizer.step() + running_loss += loss.item() + pbar.set_postfix(loss=running_loss / (pbar.n + 1)) + + # validation + model.eval() + correct = 0 + total = 0 + with torch.no_grad(): + for xb, yb in val_loader: + xb = xb.to(device) + yb = yb.to(device) + outputs = model(xb) + preds = outputs.argmax(dim=1) + correct += (preds == yb).sum().item() + total += yb.size(0) + val_acc = correct / total if total > 0 else 0.0 + print(f"Epoch {epoch+1} val_acc={val_acc:.4f}") + + # save best + if val_acc > best_val_acc: + out_path = os.path.join(os.getcwd(), 'model.pth') + if hasattr(dataset, 'class_to_idx'): + meta = {'model_state_dict': model.state_dict(), 'class_to_idx': dataset.class_to_idx} + else: + meta = {'model_state_dict': model.state_dict()} + torch.save(meta, out_path) + best_val_acc = val_acc + best_path = out_path + print(f"Saved best model to {out_path} (val_acc={val_acc:.4f})") + + return best_path + + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('data_root') + parser.add_argument('--epochs', type=int, default=3) + parser.add_argument('--batch-size', type=int, default=16) + parser.add_argument('--lr', type=float, default=1e-3) + parser.add_argument('--model-type', choices=['cnn', 'mlp'], default='cnn') + parser.add_argument('--csv-label', default='label') + parser.add_argument('--generate-labels', action='store_true', help='If set, generate labels from columns instead of expecting label column') + parser.add_argument('--n-buckets', type=int, default=100, help='Number of label buckets when generating labels') + parser.add_argument('--label-method', choices=['md5', 'kmeans'], default='md5', help='Method to generate labels when --generate-labels is set') + parser.add_argument('--label-store', default=None, help='Path to save/load label metadata (e.g., kmeans centers .npz)') + parser.add_argument('--subset', type=int, default=0, help='If set (>0), load only first N rows from CSV for fast experiments') + parser.add_argument('--feature-engineer', action='store_true', help='If set, add simple date and lat/lon engineered features') + parser.add_argument('--lat-lon-bins', type=int, default=20, help='Number of bins for lat/lon coarse spatial features') + parser.add_argument('--seed', type=int, default=42, help='Random seed for experiments') + parser.add_argument('--hidden-dims', type=str, default='', help='Comma-separated hidden dims for MLP, e.g. "256,128"') + parser.add_argument('--weight-decay', type=float, default=0.0, help='Weight decay (L2) for optimizer') + args = parser.parse_args() + data_root = args.data_root + nrows = args.subset if args.subset > 0 else None + # parse hidden dims + hidden_dims = None + if args.hidden_dims: + try: + hidden_dims = tuple(int(x) for x in args.hidden_dims.split(',') if x.strip()) + except Exception: + hidden_dims = None + train(data_root, epochs=args.epochs, batch_size=args.batch_size, lr=args.lr, model_type=args.model_type, csv_label=args.csv_label, generate_labels=args.generate_labels, n_buckets=args.n_buckets, label_method=args.label_method, label_store=args.label_store, feature_engineer=args.feature_engineer, lat_lon_bins=args.lat_lon_bins, nrows=nrows, seed=args.seed, hidden_dims=hidden_dims, weight_decay=args.weight_decay) +