## 4 Methodology
### Data Generation Module  
After relabeling the training dataset and validating the results, it became evident that certain classes were severely under-represented and that there was a need to use a generative network to accommodate the low instance classes. GANs have a unique approach compared to other popular neural network architectures, as they aim to solve two distinct problems simultaneously. These problems are discrimination, which involves effectively distinguishing between real and fake images, and generating \"realistic\" fake data, which involves creating samples that are perceived as real. Although these objectives are essentially opposites, GANS combine them into a single model. Alternatively, if we were to separate these tasks into different models, we would have a generator (\(G\)) and discriminator (\(D\)) model. The generator model takes a random noise vector of N dimensions as input and uses a learned target distribution to transform it. Its output also are N-dimensional. On the other hand, the discriminator model models a probability distribution function, similar to a classifier, and outputs a probability between 0 and 1 that the input image is real or fake. In this way, the two main objectives of the generation task can be defined:  
1. The objective of training \(G\) is to increase \(D\)'s classification error to the maximum extent possible. This will ensure that the generated images appear authentic and realistic. 2. The objective of training \(D\) is to reduce the final classification error as much as possible. This will enable \(D\) to correctly differentiate between real and fake data. To accomplish this, during the backpropagation process, the weights of \(G\) are adjusted using gradient ascent in order to maximize the error, whereas \(D\) employs gradient descent to minimize it. It is important to note that during training, the two networks do not directly use the actual distribution of images. Instead, they use each other's outputs to evaluate their performance (1). We use the absolute error to estimate the error of \(D\), and then use the same function for \(G\), but with the aim of maximizing it (2). \[E(G,D)=\frac{1}{2}(E_{x\subset P_{t}}[1-D(x)]+E_{x\subset P_{g}}[D(x)]) \tag{1}\]  
\[E=max_{G}(min_{D}E(G,D)) \tag{2}\]  
In this case, \(p_{t}\) represents the true distribution of images, while \(p_{g}\) is the distribution created from \(G\). Deep convolutional generative adversarial networks (DCGANs) incorporate key principles of convolutional neural networks (CNNs) and have become a popular architecture due to their quick convergence and ease of adaptation to more complex variations (such as incorporating labels as conditions or using residual blocks). They address several significant challenges, including:  
* \(D\) is structured to perform a supervised image classification task (for example, identifying if an image contains a driver helmet or not). * The filters learned by the GAN can be utilized to generate specific objects in the resulting image. * \(G\) has vectorized properties that can learn highly intricate semantic representations of objects. Figure 4 (left) presents the structure of a DCGAN generator. The starting input of the Generator is a (1, 100) noise vector. This vector then passes through four convolutional layers with up-sampling and a stride of 2 to generate an RGB image result of size (64, 64, 3). To achieve this, the input vector is projected onto a 1024-dimensional output to match the input of the initial convolutional layer. Figure 4 (right) presents the structure of a DCGAN discriminator. In contrast to the generator, the discriminator takes an input image of size (64, 64, 3), which is the same size as the output generated by the generator. The input image then passes through four standard down-sampling convolutional layers, with a stride of 2.