From 11ae0e19496f581f6c326f9c1fe4f7f5f65d8ed1 Mon Sep 17 00:00:00 2001 From: Victor Mylle Date: Fri, 17 May 2024 13:24:02 +0200 Subject: [PATCH] Using val set for diffusion trainer --- Reports/Thesis/sections/background.aux | 6 +- Reports/Thesis/sections/background.tex | 39 ++-- .../results/policies/nrv_samples_policy.tex | 6 +- Reports/Thesis/verslag 11.synctex.gz | Bin 301212 -> 311282 bytes Reports/Thesis/verslag 12.synctex.gz | Bin 308009 -> 311282 bytes Reports/Thesis/verslag.aux | 6 +- Reports/Thesis/verslag.log | 169 +++++++++--------- Reports/Thesis/verslag.pdf | Bin 8682452 -> 8683971 bytes Reports/Thesis/verslag.synctex.gz | Bin 358468 -> 364435 bytes src/data/preprocessing.py | 104 ++++++++++- src/trainers/diffusion_trainer.py | 74 ++++---- src/training_scripts/diffusion_training.py | 2 +- .../non_autoregressive_quantiles.py | 56 +++--- 13 files changed, 287 insertions(+), 175 deletions(-) diff --git a/Reports/Thesis/sections/background.aux b/Reports/Thesis/sections/background.aux index 14fb6a4..559138d 100644 --- a/Reports/Thesis/sections/background.aux +++ b/Reports/Thesis/sections/background.aux @@ -14,8 +14,8 @@ \newlabel{tab:imbalance_price}{{2}{6}{Prices paid by the BRPs\relax }{table.caption.2}{}} \@writefile{toc}{\contentsline {section}{\numberline {3}Generative modeling}{7}{section.3}\protected@file@percent } \@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Quantile Regression}{7}{subsection.3.1}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Example of quantiles\relax }}{8}{figure.caption.3}\protected@file@percent } -\newlabel{fig:quantile_example}{{1}{8}{Example of quantiles\relax }{figure.caption.3}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Example of a cumulative distribution function and some quantiles. The quantiles are the values below which a certain proportion of observations fall.\relax }}{8}{figure.caption.3}\protected@file@percent } +\newlabel{fig:quantile_example}{{1}{8}{Example of a cumulative distribution function and some quantiles. The quantiles are the values below which a certain proportion of observations fall.\relax }{figure.caption.3}{}} \@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Example of quantile regression output for one-quarter of the NRV, showing interpolated values for quantiles at 1\%, 5\%, 10\%, 15\%, 30\%, 40\%, 50\%, 60\%, 70\%, 85\%, 90\%, 95\%, and 99\%. These quantiles are used to reconstruct the cumulative distribution function.\relax }}{9}{figure.caption.4}\protected@file@percent } \newlabel{fig:quantile_regression_example}{{2}{9}{Example of quantile regression output for one-quarter of the NRV, showing interpolated values for quantiles at 1\%, 5\%, 10\%, 15\%, 30\%, 40\%, 50\%, 60\%, 70\%, 85\%, 90\%, 95\%, and 99\%. These quantiles are used to reconstruct the cumulative distribution function.\relax }{figure.caption.4}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Autoregressive vs Non-Autoregressive models}{10}{subsection.3.2}\protected@file@percent } @@ -31,7 +31,7 @@ \@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Example of the diffusion process. The image of a cat is generated by starting from noise and iteratively denoising the image.\relax }}{14}{figure.caption.6}\protected@file@percent } \newlabel{fig:diffusion_example}{{4}{14}{Example of the diffusion process. The image of a cat is generated by starting from noise and iteratively denoising the image.\relax }{figure.caption.6}{}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.4.3}Generation process}{14}{subsubsection.3.4.3}\protected@file@percent } -\newlabel{fig:diffusion_process}{{\caption@xref {fig:diffusion_process}{ on input line 298}}{16}{Generation process}{figure.caption.7}{}} +\newlabel{fig:diffusion_process}{{\caption@xref {fig:diffusion_process}{ on input line 309}}{16}{Generation process}{figure.caption.7}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.5}Evaluation}{16}{subsection.3.5}\protected@file@percent } \@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Visualization of the CRPS metric\relax }}{17}{figure.caption.8}\protected@file@percent } \newlabel{fig:crps_visualization}{{5}{17}{Visualization of the CRPS metric\relax }{figure.caption.8}{}} diff --git a/Reports/Thesis/sections/background.tex b/Reports/Thesis/sections/background.tex index c9f84b6..c46b6bb 100644 --- a/Reports/Thesis/sections/background.tex +++ b/Reports/Thesis/sections/background.tex @@ -100,11 +100,13 @@ TODO: Add more information about the imbalance price calculation, alpha? Given the bids of the BSPs for a certain quarter or day and knowing System Imbalance, the imbalance price can be reconstructed using the calculation provided by Elia. 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. \section{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 for a whole day. This can give a better understanding of the uncertainty of the NRV. Better decisions can then be made based on multiple generations of the NRV. +Forecasting the imbalance price is a difficult task. The price is influenced by many different factors like the weather, time of day, ... but also by the formulas used by the TSO to calculate the imbalance price. The formulas can change which results in a different imbalance price distribution. This makes it hard to train a model to forecast the imbalance price using historical data. Another method to forecast the imbalance price is to forecast the Net Regulation Volume (NRV) and then use the formulas provided by the TSO to calculate the imbalance price. This way, the model does not need to learn the imbalance price distribution but only the NRV distribution. -Generative modeling is a type of machine learning that is used to generate new data samples that look like the training data. The goal of generative modeling is to learn the true data distribution and use this distribution to generate new samples. Generative modeling is used in many different fields including image generation, text generation etc. +Another problem occurs when just forecasting the NRV. Forecasting a time series is a difficult task because of the uncertainty in the data and the many different factors that can influence the data. 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 full-day generations of the NRV. This can give a better understanding of the uncertainty of the NRV. Better decisions can then be made based on multiple generations of the NRV. -In this thesis, generative modeling can be used to model the NRV of the Belgian electricity market using different conditional input features like the weather, the load forecast etc. The model can then be used to generate new samples of the NRV. +Generative modeling is a type of machine learning that is used to generate new data samples that look like the training data. The goal of generative modeling is to learn the true data distribution and use this distribution to generate new samples. Generative modeling is used in many different fields including image generation, text generation, audio generation etc. + +In this thesis, generative modeling can be used to model the NRV of the Belgian electricity market using different conditional input features like the weather, the load forecast etc. The model can then be used to generate new full-day generations of the NRV that can be used to make better decisions on when to buy or sell electricity. There exist many different types of generative models. Some of the most popular ones are: \begin{itemize} @@ -115,18 +117,21 @@ There exist many different types of generative models. Some of the most popular \end{itemize} \subsection{Quantile Regression} -Another method can be used to use any feedforward neural network as a generative model. This method is called quantile regression. This method enables the model to output values to reconstruct the distribution of the target variable instead of a single value for a quarter. This distribution can then be used to sample the NRV value for a quarter. The sampling allows for multiple full-day generations of the NRV. +Any feedforward neural network can also be used to output distributions for the target values. For example, if the distribution is assumed to be normal, the model can output the mean and the variance of the target value. This way, the model can output a distribution for the target value instead of a single forecast value. The outputted distribution allows for multiple samples to be drawn from the distribution. This can be used to generate multiple full-day generations of the NRV. -When quantile regression is used, the model outputs the values for multiple quantiles for the target value of a certain quarter. A quantile is a statistical value of a random variable below which a certain proportion of observations fall. Figure \ref{fig:quantile_example} shows the cumulative distribution function of a normal distribution. The figure shows the 25th, 50th and 75th quantiles. The 25th quantile is the value below which 25\% of the observations fall. In the example, this value is -0.67. The other quantiles work in the same way. +This method requires that the distributions of the target values be known in advance, or at least assumed. However, it is common for these distributions to be unknown. Fortunately, there is an alternative approach that can estimate the distribution of the target values without prior knowledge of the distribution. This technique is known as quantile regression. + +Quantile regression is a method that uses feedforward neural networks to estimate multiple quantiles of the target values. A quantile is a statistical value of a random variable below which a certain proportion of observations fall. For example, the 25th quantile is the value below which 25\% of the observations fall. By estimating multiple quantiles using quantile regression, the distribution of the target values can be reconstructed. For each quarter of the day, the quantiles of the NRV are estimated by the model and used to reconstruct the distributions of the NRV. For each quarter of the day, a distribution can be reconstructed and samples can be drawn from this distribution. This way, multiple full-day generations of the NRV can be generated. \begin{figure}[H] \centering \includegraphics[width=0.8\textwidth]{images/quantile_regression/cdf_quantiles_example.png} - \caption{Example of quantiles} + \caption{Example of a cumulative distribution function and some quantiles. The quantiles are the values below which a certain proportion of observations fall.} \label{fig:quantile_example} \end{figure} -Using the outputted quantiles, the cumulative distribution function can be reconstructed and used to sample the NRV value for the quarter to predict. An example of the output of a quantile regression model is shown in figure \ref{fig:quantile_regression_example}. The output values of the different quantiles are plotted and these are interpolated to get the cumulative distribution function. In this thesis, the quantiles used are 1\%, 5\%, 10\%, 15\%, 30\%, 40\%, 50\%, 60\%, 70\%, 85\%, 90\%, 95\%, and 99\%. These are chosen to get a good approximation of the cumulative distribution function. More quantiles at the tails of the distribution are used because the edges of the distribution are more important for the imbalance price calculation. The outputted quantile values are then interpolated using cubic spline and samples can be drawn from the reconstructed cumulative distribution function. +The model outputs quantiles that can be used to reconstruct the cumulative distribution function of a target NRV value. This distribution can then be used to sample the NRV value for a quarter. An example of the output of a quantile regression model is shown in figure \ref{fig:quantile_regression_example}. The output values of the different quantiles are plotted and interpolated to get the cumulative distribution function. In this thesis, the quantiles used are 1\%, 5\%, 10\%, 15\%, 30\%, 40\%, 50\%, 60\%, 70\%, 85\%, 90\%, 95\%, and 99\%. These are chosen to get a good approximation of the cumulative distribution function. More quantiles at the tails of the distribution are used because the edges of the distribution are more important for the imbalance price calculation. +% TODO: edges important? TODO: figure goes under 0, maybe use other values or other interpolation? + inverse the values to real values \begin{figure}[H] @@ -138,7 +143,7 @@ TODO: figure goes under 0, maybe use other values or other interpolation? + inve The NRV value for a quarter can be sampled from the reconstructed cumulative distribution function. A full-day prediction for the NRV exists of 96 values. This means 96 cumulative distributions need to be reconstructed and samples need to be drawn from each of the distributions. -The quantile regression model is trained using the pinball loss function, also known as the quantile loss. The model outputs the quantile values for the NRV. The quantile values themselves are not available in the training data. Only the real NRV values are known. The loss function is defined as: +The model needs to learn the quantiles of the NRV values. These, however, are not available in the training data. Only the historical NRV values are known. A special loss function is needed to train the model to output the quantiles of the NRV values. This loss function is called the pinball loss function. The loss function is defined as: \\ \begin{equation} L_\tau(y, \hat{y}) = \begin{cases} \tau(y - \hat{y}) & \text{if } y \geq \hat{y} \\ @@ -151,7 +156,8 @@ The quantile regression model is trained using the pinball loss function, also k y & = \text{Actual observed value of NRV} \\ \hat{y} & = \text{Predicted quantile value of NRV} \\ \end{align*} -The loss function works by penalizing underestimation and overestimation differently. When a quantile is predicted that is lower than or equal to the actual value, the loss is calculated as the difference between the actual value and the predicted quantile value multiplied by the quantile of interest. This means that underestimations for high quantiles are penalized higher than for lower quantiles. + +The loss function works by penalizing underestimation and overestimation of the quantile predictions differently. When a predicted quantile is lower than or equal to the actual value, the loss is calculated as the difference between the actual value and the predicted quantile value multiplied by the quantile of interest. This implies that the underestimations for high quantiles are penalized more heavily than for lower quantiles, as $\tau$ is larger for higher quantiles. When the quantile value prediction is higher than the real NRV value, the loss is calculated as the difference between the predicted quantile value and the real NRV multiplied by $(1-\tau)$. This means that overestimations are penalized less for high quantiles of interest. @@ -167,16 +173,21 @@ When the quantile value prediction is higher than the real NRV value, the loss i \hat{y}_i & = \text{Predicted quantile value of NRV for sample i} \\ \end{align*} -To calculate the pinball loss, the mean over the quantiles of interest and samples need to be taken. This gives a scalar loss value which can be used to do backpropagation. The lower this value, the better the NRV distribution is modeled. +To calculate the pinball loss, the mean is taken over the quantiles of interest and the samples. This results in a scalar loss value that can be used for backpropagation. A lower pinball loss indicates a better modeling of the NRV distribution. \subsection{Autoregressive vs Non-Autoregressive models} -Two types of generative models exist, autoregressive and non-autoregressive models. Autoregressive models generate samples by sampling from the model one step at a time. The model generates the next value based on the previous values. This means that the model generates samples sequentially. Non-autoregressive models on the other hand generate samples in one step. The model generates the whole sample existing of multiple values at once. This means that the model can generate samples in parallel which can be done way faster than autoregressive models. The downside of non-autoregressive models is that the model itself is more complex and harder to train. It needs to predict all values at once which can be harder than predicting one value at a time. -The quantile regression method can be used with both types of models. The autoregressive model will only output the quantiles for the next quarter based on the given input features. The cumulative distribution function can be reconstructed from these and be used to sample the NRV value. To obtain a full-day sample, the model needs to be run 96 times sequentially. The sample for the next quarter depends on the sample of the previous quarter. +Generative models can be broadly classified into two types: autoregressive and non-autoregressive models. -The non-autoregressive model will output the quantiles for all quarters of the day based on the input features. The cumulative distribution functions all need to be reconstructed and samples can be drawn from each of the distributions. When sampling from the distributions at once, the samples are independent of each other. The sample for the next quarter does not depend on the sample of the previous quarter which can result in some unrealistic samples. +Autoregressive models generate samples sequentially, one step at a time. At each step, the model generates the next value based on the previously generated values. This sequential process ensures that the dependencies between values are naturally captured, but it also results in slower sample generation, as each value must be generated in order. -The input features for autoregressive and non-autoregressive also differ. When forecasted features are used, the autoregressive model only uses the forecasted values for the next quarter while the non-autoregressive model uses the forecasted values for all quarters of the day. In theory, the autoregressive model should also be able to use forecasted values for quarters further in the future but this makes it harder to use in practice. When the last quarter of a day needs to be predicted, the forecasted values for the next day are needed which are not available. For simplicity, during this thesis, the autoregressive model will only be provided with the forecasted values for the next quarter. +Non-autoregressive models, in contrast, generate the entire sample in a single step. Instead of generating values sequentially, these models produce all the values of the sample simultaneously, allowing for parallel generation. This significantly speeds up the sample generation process compared to autoregressive models. However, the complexity of non-autoregressive models is higher, making them more challenging to train. These models must accurately predict all values of the sample at once, which can be more difficult than predicting one value at a time. + +Quantile regression can be applied to both types of models. For autoregressive models, the model outputs the quantiles for the next time step based on the given input features. From these quantiles, the cumulative distribution function (CDF) can be reconstructed and used to sample the NRV value. To obtain a full-day sample, the model needs to run sequentially for each quarter-hour, resulting in 96 iterations per day. Each sample for the next quarter depends on the sample of the previous quarter. + +For non-autoregressive models, the model outputs the quantiles for all quarters of the day simultaneously based on the input features. The CDFs for each quarter are reconstructed, and samples are drawn from these distributions. Since the samples are generated in parallel, they are independent of each other. This independence can sometimes lead to unrealistic samples, as the sample for the next quarter does not depend on the sample of the previous quarter. + +The input features for autoregressive and non-autoregressive models also differ. When using forecasted features, the autoregressive model utilizes forecasted values for the next quarter only, while the non-autoregressive model uses forecasted values for all quarters of the day. Although, in theory, the autoregressive model could use forecasted values for further future quarters, this complicates practical application. For instance, predicting the last quarter of a day would require forecasted values for the next day, which may not be available. Therefore, in this thesis, the autoregressive model is provided only with forecasted values for the next quarter to simplify the approach. \subsection{Model Types} \subsubsection{Linear Model} diff --git a/Reports/Thesis/sections/results/policies/nrv_samples_policy.tex b/Reports/Thesis/sections/results/policies/nrv_samples_policy.tex index 338e051..5a92e1a 100644 --- a/Reports/Thesis/sections/results/policies/nrv_samples_policy.tex +++ b/Reports/Thesis/sections/results/policies/nrv_samples_policy.tex @@ -1,14 +1,16 @@ \subsection{Policy using generated NRV samples} The generated full-day samples can be used to improve the profit of the policy. For each day, the generated samples can be used to determine the buying and selling thresholds. Assume that there are 100 generated full-day NRV samples for the day for which the profit needs to be optimized. The thresholds are determined for each generated sample separately using a simple grid search. All these thresholds can then be reduced by taking the mean to get one value for the buying threshold and one value for the selling threshold. Again, the penalty parameter is optimized for the test set to make sure around 283 charge cycles are used for fair comparison. The policy is evaluated for the different types of models that were trained and discussed in the previous sections. To reduce the computational cost, the policy is only evaluated for the best-performing models based on the CRPS metric. -\begin{table} +\begin{table}[ht] \centering \begin{adjustbox}{max width=\textwidth} \begin{tabular}{lcccccc} \toprule Model & Type & CRPS & Profit (€) & Charge Cycles & Penalty \\ \midrule - \acs{AQR} & Non-Linear & & 189,717.74 & 282.06 & 566.4 \\ + \acs{AQR} & Non-Linear & 79.22 & 189,717.74 & 282.06 & 566.4 \\ + \acs{AQR} & GRU & 80.92 & 188,973.84 & 283.06 & 536.06 \\ + Diffusion & Non-Linear & 80.30 & 191,553.58 & 282.56 & 553.38 \\ \bottomrule \end{tabular} \end{adjustbox} diff --git a/Reports/Thesis/verslag 11.synctex.gz b/Reports/Thesis/verslag 11.synctex.gz index 56a3f1938cc2143c313c302ecad42ea5bb04b77a..aa2b1cf7262711b466de0db26b0bfce01da16fb9 100644 GIT binary patch delta 289017 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