From dad64d00bee5c89877d32e131598e5c645515a18 Mon Sep 17 00:00:00 2001 From: Victor Mylle Date: Wed, 20 Mar 2024 22:14:18 +0100 Subject: [PATCH] Updated some stuff --- Reports/Thesis/verslag.log | 26 +++++- Reports/Thesis/verslag.pdf | Bin 435646 -> 436330 bytes Reports/Thesis/verslag.synctex.gz | Bin 32839 -> 36457 bytes Reports/Thesis/verslag.tex | 14 ++- src/trainers/quantile_trainer.py | 86 ++++++++++-------- src/trainers/trainer.py | 50 ++++------ .../non_autoregressive_quantiles.py | 4 +- 7 files changed, 105 insertions(+), 75 deletions(-) diff --git a/Reports/Thesis/verslag.log b/Reports/Thesis/verslag.log index cc0dabe..deebed7 100644 --- a/Reports/Thesis/verslag.log +++ b/Reports/Thesis/verslag.log @@ -1,4 +1,4 @@ -This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) (preloaded format=pdflatex 2023.9.17) 20 MAR 2024 16:47 +This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) (preloaded format=pdflatex 2023.9.17) 20 MAR 2024 22:13 entering extended mode restricted \write18 enabled. file:line:error style messages enabled. @@ -1055,7 +1055,27 @@ Underfull \hbox (badness 10000) in paragraph at lines 226--233 [] -[3{/usr/local/texlive/2023/texmf-dist/fonts/enc/dvips/libertinust1math/libusMI.enc}] [4] (./verslag.aux) +[3{/usr/local/texlive/2023/texmf-dist/fonts/enc/dvips/libertinust1math/libusMI.enc}] +Underfull \hbox (badness 10000) in paragraph at lines 237--246 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 237--246 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 237--246 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 237--246 + + [] + +[4] (./verslag.aux) Package rerunfilecheck Info: File `verslag.out' has not changed. (rerunfilecheck) Checksum: 93BB3520344D4F0680BD23B0E2A0C01A;781. Package logreq Info: Writing requests to 'verslag.run.xml'. @@ -1071,7 +1091,7 @@ Here is how much of TeX's memory you used: 1141 hyphenation exceptions out of 8191 72i,11n,108p,1343b,5180s stack positions out of 10000i,1000n,20000p,200000b,200000s -Output written on verslag.pdf (5 pages, 435646 bytes). +Output written on verslag.pdf (5 pages, 436330 bytes). PDF statistics: 97 PDF objects out of 1000 (max. 8388607) 75 compressed objects within 1 object stream diff --git a/Reports/Thesis/verslag.pdf b/Reports/Thesis/verslag.pdf index 640a7163f51ee86cbb0bb29433c4fd1b7183cdd4..e2047099e00cd7d48d9c37f033d147840feabd5c 100644 GIT binary patch delta 4996 zcmV-~6MO8w%Npv?8n9(@1Ti!>F_$ri1}T3R%W~T`@Sd;Gk(x#{2|m?Jr@7!l3f+|y=*F7_4HX*r|mBDs75&Qda&vqGcQ92U`pH>`zg=`5ROBl;GXI{~@gYL&do3D~?59%K8 znNeFMx2hZnGGT{PvW}|PQZe~IqwFC9SEW2NQCltqf%A8>tcd72D-i*ceF}f`>#XjMg!=9Q5HckjcssEXJ*_B$Do>1t-b|OR5%%#cRR9hWl!d2 zu0w~9>+B0r-06gI@1Rs46=i>^Q7t%+3=GXSC+X41@0IN?Mu8gO z8N>(q-TGzF&uG4fA#(sYkr=|zOE27Mg zl8{~@d@&>6d5XNSuR-3WbisF_-MROKVjsn623{H}r zr$%<3n>Gt*?n1~(nZsX_j``C8adKWSRl(gUw@p7c1&A?)30!}$MXEK-@c4UKvvjQT zm4MB9u^o)lrhR9k*4Xy12H%RAj_*Y!U?gXiU@)eM!71^8#5&XNKuFX7kWCgx)iM&2 zsBay=K1w~8G-*wE-;rPr2+IIjus9K1N-YV3;I0lxi0a@|x>L&zBWl?I35qOY7KIO2 z^XDSQL>Y)p=D~lrc?_eD%ms~;m5^zOD;4xp1;d9z4R@qgST^AAVHt3Wkkwzy(`y$y zA#5EBHpInP%r)Ym7n$=KUQ;13Gi^HnTrvkfE-nY5CeOu_?kJu(NwAaPyhPGqS97(I zEw}g*XLVAU!mxWM)<9L4gWVI0dMtUJ!SN#xoaC2swL5K2eTM@$%B%8S$tgAumzndjZT&4 zkmCpdvLk;8fq{;}jBI5A+0rzFv}*_6V_+dqW3F>RO-BQKKGQL^+dO8ybCST5rQ}i< z_~nXM}K0|VspxT5hgM3H!<4E zn^Uy9H~pzJsvRf)b)WTEo}XKoazD1K82>n12_r}EdaJwBPuI?81i3{>+1SYPc)zM- z_)m`DRvfQ7;=OfsZFA}uIw?gshx;Hm3egKNiYRH%2 zDFYLOvvr5FbpeO7bpnU8bpwa9bp(gAbp^Mxbq1;+DKauKGc-6WFfk`EFefPrFHLV` zL}7GgASgsSGB7eUFf%eRGBPnUG&q-rmIlHBGM6!j1}J~6TH8|F$QFI~SM=L~n!>HV zcb`h73PNDW0O0`1OomXDF#4G@e_Ggu*B27=;ErwD!QJ zH6SVj5KJZjj)qbs3DX{>Ry|ae!aHUxY`|znGpQWv;k`)|vuJ0uWd^300Q1q_TF)%% zIg7#Y+(#Zz8r75F!UxMN%nK?oFrgAqf+i}#OP7DZ5OnTfumd=!U?@Pq08Lgp7-Ry7 z0TDsUo(B}d2cC?@AOtOdX^XCfM2W679ALq$p-xd!Jw>lPI>q|{qhXp8BJ>Qpke*z` zoQBb!hK3{1l`|ejCCph3$_a`F9_xZx&qN&C7K0=5+(=D zyoLkAfC4&9#Hb zOfY>+KL{?-_u;aK zehPFzQBAcv>mg2x{AM~#3%0R;a>(}Y^GP`w7TIITLf@EvvWbz4bU>8t4$72m?EY6K zQV1z9!wAfVKPBQnN%EIIng(cpo9|n0mMkCTclpfnmf24@!T> zPm3?3%SjCnWtO$h9tM+|YFo<^c0U(~4D#?y=&Bq-o`UlX>V=t)kK<;2rbF z6RJw*`q)oDsVaIEpzsOg&Iw(d+SikNVWhw8T_~hIbkQE)D9Rp?`%%h7B~k~24CN`8 zq_oRWePk#`#8P9+6Fl+_B!U(Z;3%o1bOyPh!R+Rc5c-&8;(|aN{9=$cdE}SW#!-?g zbSxcVL0)393Q{|Nhs;kTSg9P+Q%mU+E`@YUB`%hR(pFEPU>F8Ani5S*xfh;eDh-rE z3Kml=B((~Ft)L{;ASpubMFWx{l($iChp{x)TO!80uv>>Z~-OHlx{=a)|*JLB<8>Z;es%b`$5*^hJ@@8Rq3lXl++?Kjjjk_$iilW ztk)(a9bllOG)kfNfF*X&HdHKAo5vE2$RF09gW01~A$9U3O z5iLe5l~XmHPDmF^oz#wzAxh0cN;EE!K}I{og+rPyk$@|i#Cl|; z2caZ+r^$&SmX=725=XsgsECe<(uEK$$vYlnRAtA1F;oZRY3d(B&~#3NnA3q`G|UNv z10)>o5ne`x%5jo-p_2;CAp!G_PU0M*F`GF_;YO!57EYm4of!QzIxI3Y8_+?9rIRMG zN$+XqfJ6g=lJ+=`5QM6<#2lPT?sJfX1tLLPH~L`Fk;QbPF|8;>FqLf+4e7;`i%AD$ zu8-$`S`@jMx?|)kiWfS%0u^-F6e*=TQSYQJ=#6FyqpLm)#WqT)4Rl<#)+(B!chf3K z$%|^rJ{~;a&Fc?ue&6}<(_wa<7G*Y`PR_;Apu9(w(cli-tE%o!T)wshow;o(hoF&! zMq24;WuFXb1+(5`Jsdp#oMw0T_^KtAk+gb$w0x`*>Mh9%&6 ziyUKVdGkTF%`zRcjO&=?)|lm!mRU-+&D!QW{1xBjulYVUQg8SnKjO#ygrD*Ee87i) zoD#b+zu_rQ$2Wt?J-_9**i-O3e$O-hiI4aLAM>2&+{44)EE%FYD_BkZ}{@c#chl37@JKtu}RV-pDY||K2herD}bqJzvjXZYv z9{4-rr~DkeU4uE|>~@K#$C{VOMu!N0{~RLr-<|EhIVK`z(UN{!PG&{~68g5DTvt!F zLqziYFq!LV4~nAA`7gDm-a=KU(A7DA2W|aYvsCG8m_IxWYQ}D_;&qkr>KgIe>~lI( z-5nh+qy<>L|N3~JjzR7p%QB>G>?pl0t4{?1?P&8){^vBE(4k0l$0YrXo+cxI()Xfd zzwp0EwoAhG$#eYmzjr6Uo}YF7^-bj}>1WCndhReMbjM-RcN`|xDz`HOsIJGzUzK`~ zYadmGrEq2THUp1D`~D_AjSt)+)BnRK4cRuGqo>qL=lRe zMmtCwhN?JSNl_=}9y|W8c1VV(&sYu`l9#(UnLi7Twr@qcG`zc+jtgS9$NL z@Pw$B{mbPzZyig}Lqy)rV3NlCbIn@cnH=cnub7eVWyPeVXk-$791iL)g1-Hl-IVte z`UNdkouQ6UQ1=i^+z$zE{0Swt#2`kedS+C`vd z3FwN=4V_s{=+J5kSlHJ7lHE+26Z`sXw?5~r&(^9#poLg`J1wDI>M0^+_4zpgrJs7^ zmud{%G>pGu$QtD~a?k2hefs5VJ)9KjXZn@6jl60pW-WzZ-?DyxbxbEpQZM%+T+@s0 z_R{J^$Q2D$(=b`pFpenfa>FodXV;_FZPZCi0y8KTvvv11vsvpQ>*R1X%3@vNui@%)vn_TiGwbl*OvFgZd+L^C%tMnN||T?#KuWo~D5Xdp5+Fqbfg1}T3X(Md0Z zQ544U=e*SyHMHh=9!m{16h&)l4Lgb0vK2ckv6YZYEG#70*|72Ie7O4aFz#xE5*o7EWK^N>m96}g}ZK#GCn1C&)g#=7O5$d2G8ce~h zOz9I}qt&FOr)Fq@HCTmBXoP>HDRtv>DQGffOMYyJZfG-|e)?S=`k)_rOlMzS^ujs} z!UznQE^^)u!3GRN8b(c5$KH;?3QR!`rePT}umm$OYq~!7XLA-j6g$aII{5NJ{tbG)IS6j4j$!~m8AwB O3OF%23MC~)PeuyS3~B`c delta 4280 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 aANmJ>iy-NjL8t~F3NbS>3MC~)PeuxLL=pS| diff --git a/Reports/Thesis/verslag.synctex.gz b/Reports/Thesis/verslag.synctex.gz index becbae79614c2bd34e64cdf62fa91168f863c8bf..82ddfe33ce71f90b3523c84908023bd798ce5852 100644 GIT binary patch delta 10149 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 T@u%;<{_6h$3*cAC&{qNg0v?U; delta 6502 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 M0kWrVn!OzY0ApvlivR!s diff --git a/Reports/Thesis/verslag.tex b/Reports/Thesis/verslag.tex index ad58921..c3a4d67 100644 --- a/Reports/Thesis/verslag.tex +++ b/Reports/Thesis/verslag.tex @@ -231,9 +231,21 @@ The imbalance price calculation includes the following variables: \\ % TODO: Add more information about the imbalance price calculation, alpha? TODO: Add more information about the imbalance price calculation, alpha? -The imbalance price can be reconstructed given the bids of a certain quarter / day and the System Imbalance. During this thesis, the system imbalance is assumed to be almost the same as the Net Regulation Volume. This is a simplification but it is a good approximation. The goal of this thesis is to model the Net Regulation Volume which can then be used to reconstruct the imbalance price and to make decisions on when to buy or sell electricity. +The imbalance price can be reconstructed given the bids of a certain quarter/day and the System Imbalance. During this thesis, the system imbalance is assumed to be almost the same as the Net Regulation Volume. This is a simplification but it is a good approximation. The goal of this thesis is to model the Net Regulation Volume which can then be used to reconstruct the imbalance price and to make decisions on when to buy or sell electricity. \subsection{Generative modeling} +Simple forecasting of the NRV is often not accurate and defining a policy using this forecast will lead to wrong decisions. A better method would be to try to model the NRV and sample multiple generations of the NRV. This gives a better prediction and confidence intervals can be calculated from this. +\\\\ +Generative modeling is a type of machine learning that is used to generate new data samples. The goal of generative modeling is to learn the true data distribution of the training data. From this learned distribution, new samples can be generated. Generative modeling is used in many different fields including image generation, text generation etc. +\\\\ +TODO: Formulas of generative modeling +\\\\ +In this thesis, generative modeling can be used to model the NRV of the Belgian electricity market using different input features like the weather, the electricity price etc. The model can then be used to generate new samples of the NRV. +\\\\ +Multiple methods can be used to generatively model the NRV. + + + \section{Literature Study} diff --git a/src/trainers/quantile_trainer.py b/src/trainers/quantile_trainer.py index 38bfe66..a6dff73 100644 --- a/src/trainers/quantile_trainer.py +++ b/src/trainers/quantile_trainer.py @@ -558,8 +558,7 @@ class NonAutoRegressiveQuantileRegression(Trainer): outputs = self.model(inputs) outputted_samples = [ - sample_from_dist(self.quantiles, output.cpu().numpy()) - for output in outputs + sample_from_dist(self.quantiles, output.cpu()) for output in outputs ] outputted_samples = torch.tensor(outputted_samples) @@ -618,20 +617,24 @@ class NonAutoRegressiveQuantileRegression(Trainer): def debug_plots(self, task, train: bool, data_loader, sample_indices, epoch): for actual_idx, idx in sample_indices.items(): - initial, target, _ = data_loader.dataset[idx] + features, target, _ = data_loader.dataset[idx] - # get predictions - initial = initial.to(self.device) + features = features.to(self.device) + target = target.to(self.device) - predicted_quantiles = self.model(initial) - predictions = predicted_quantiles.reshape(-1, len(self.quantiles)) + self.model.eval() + with torch.no_grad(): + predicted_quantiles = self.model(features) + predictions = predicted_quantiles.reshape(-1, len(self.quantiles)) samples = [ sample_from_dist(self.quantiles, predictions) for _ in range(100) ] samples = torch.tensor(samples) - fig = self.get_plot(initial, target, samples, show_legend=(0 == 0)) + fig, fig2 = self.get_plot( + features[:96], target, samples, show_legend=(0 == 0) + ) task.get_logger().report_matplotlib_figure( title="Training" if train else "Testing", @@ -640,17 +643,12 @@ class NonAutoRegressiveQuantileRegression(Trainer): figure=fig, ) - fig, ax = plt.subplots(figsize=(20, 10)) - for i in range(10): - ax.plot(samples[i], label=f"Sample {i}") - - ax.plot(target, label="Real NRV", linewidth=3) - ax.legend() task.get_logger().report_matplotlib_figure( - title="Training" if train else "Testing", - series=f"Sample {actual_idx} Samples", + title="Training Samples" if train else "Testing Samples", + series=f"Sample {actual_idx} samples", iteration=epoch, - figure=fig, + figure=fig2, + report_interactive=False, ) plt.close() @@ -750,6 +748,8 @@ class NonAutoRegressiveQuantileRegression(Trainer): ] ) + ax.set_ylim(-1500, 1500) + fig2, ax2 = plt.subplots(figsize=(20, 10)) for i in range(10): ax2.plot(predictions_np[i], label=f"Sample {i}") @@ -757,6 +757,8 @@ class NonAutoRegressiveQuantileRegression(Trainer): ax2.plot(next_day_np, label="Real NRV", linewidth=3) ax2.legend() + ax2.set_ylim(-1500, 1500) + return fig, fig2 def calculate_crps_from_samples(self, task, dataloader, epoch: int): @@ -812,26 +814,36 @@ class NonAutoRegressiveQuantileRegression(Trainer): # using the policy evaluator, evaluate the policy with the generated samples if self.policy_evaluator is not None: - _, test_loader = self.data_processor.get_dataloaders( - predict_sequence_length=self.model.output_size, full_day_skip=True + optimal_penalty, profit, charge_cycles = ( + self.policy_evaluator.optimize_penalty_for_target_charge_cycles( + idx_samples=generated_samples, + test_loader=dataloader, + initial_penalty=500, + target_charge_cycles=283, + learning_rate=2, + max_iterations=100, + tolerance=1, + ) ) - self.policy_evaluator.evaluate_test_set(generated_samples, test_loader) - df = self.policy_evaluator.get_profits_as_scalars() - # for each row, report the profits - for idx, row in df.iterrows(): - task.get_logger().report_scalar( - title="Profit", - series=f"penalty_{row['Penalty']}", - value=row["Total Profit"], - iteration=epoch, - ) + print( + f"Optimal Penalty: {optimal_penalty}, Profit: {profit}, Charge Cycles: {charge_cycles}" + ) - df = self.policy_evaluator.get_profits_till_400() - for idx, row in df.iterrows(): - task.get_logger().report_scalar( - title="Profit_till_400", - series=f"penalty_{row['Penalty']}", - value=row["Profit_till_400"], - iteration=epoch, - ) + task.get_logger().report_scalar( + title="Optimal Penalty", + series="test", + value=optimal_penalty, + iteration=epoch, + ) + + task.get_logger().report_scalar( + title="Optimal Profit", series="test", value=profit, iteration=epoch + ) + + task.get_logger().report_scalar( + title="Optimal Charge Cycles", + series="test", + value=charge_cycles, + iteration=epoch, + ) diff --git a/src/trainers/trainer.py b/src/trainers/trainer.py index c01b2ba..6e3769e 100644 --- a/src/trainers/trainer.py +++ b/src/trainers/trainer.py @@ -7,6 +7,7 @@ import numpy as np from plotly.subplots import make_subplots from clearml.config import running_remotely from torchinfo import summary +import matplotlib.pyplot as plt class Trainer: @@ -329,18 +330,7 @@ class Trainer: return fig def debug_plots(self, task, train: bool, data_loader, sample_indices, epoch): - num_samples = len(sample_indices) - rows = num_samples # One row per sample since we only want one column - - cols = 1 - - fig = make_subplots( - rows=rows, - cols=cols, - subplot_titles=[f"Sample {i+1}" for i in range(num_samples)], - ) - - for i, idx in enumerate(sample_indices): + for actual_idx, idx in sample_indices.items(): features, target, _ = data_loader.dataset[idx] features = features.to(self.device) @@ -350,30 +340,26 @@ class Trainer: with torch.no_grad(): predictions = self.model(features).cpu() - sub_fig = self.get_plot( - features[:96], target, predictions, show_legend=(i == 0) + fig, fig2 = self.get_plot( + features[:96], target, predictions, show_legend=(0 == 0) ) - row = i + 1 - col = 1 + task.get_logger().report_matplotlib_figure( + title="Training" if train else "Testing", + series=f"Sample {actual_idx}", + iteration=epoch, + figure=fig, + ) - for trace in sub_fig.data: - fig.add_trace(trace, row=row, col=col) + task.get_logger().report_matplotlib_figure( + title="Training Samples" if train else "Testing Samples", + series=f"Sample {actual_idx} samples", + iteration=epoch, + figure=fig2, + report_interactive=False, + ) - # loss = self.criterion(predictions.to(self.device), target.squeeze(-1).to(self.device)).item() - - # fig['layout']['annotations'][i].update(text=f"{loss.__class__.__name__}: {loss:.6f}") - - # y axis same for all plots - # fig.update_yaxes(range=[-1, 1], col=1) - - fig.update_layout(height=1000 * rows) - task.get_logger().report_plotly( - title=f"{'Training' if train else 'Test'} Samples", - series="full_day", - iteration=epoch, - figure=fig, - ) + plt.close() def debug_scatter_plot(self, task, train: bool, samples, epoch): X, y = samples diff --git a/src/training_scripts/non_autoregressive_quantiles.py b/src/training_scripts/non_autoregressive_quantiles.py index 1749ab8..754e0d0 100644 --- a/src/training_scripts/non_autoregressive_quantiles.py +++ b/src/training_scripts/non_autoregressive_quantiles.py @@ -85,7 +85,7 @@ time_embedding = TimeEmbedding( non_linear_model = NonLinearRegression( time_embedding.output_dim(inputDim), - len(quantiles), + len(quantiles) * 96, hiddenSize=model_parameters["hidden_size"], numLayers=model_parameters["num_layers"], dropout=model_parameters["dropout"], @@ -94,7 +94,7 @@ non_linear_model = NonLinearRegression( # linear_model = LinearRegression(time_embedding.output_dim(inputDim), len(quantiles)) model = nn.Sequential(time_embedding, non_linear_model) -model.output_size = 1 +model.output_size = 96 optimizer = torch.optim.Adam(model.parameters(), lr=model_parameters["learning_rate"]) ### Policy Evaluator ###