I am trying to implement MLE using pytorch. I created a simple linear regression data set $\mathcal{D} :=\{X, Y\} = \{(x_1, y_1), ...,(x_N, y_N)\}$, so one can write the likelihood function:
$$ p(y|x) = \mathcal{N}(y|f(\boldsymbol x),\,\sigma^{2}) \ \text{where} \, \boldsymbol x \in \mathbb{R}^D ,y \in \mathbb{R}$$ $$f(x) = \boldsymbol x^T \boldsymbol \theta $$
Assuming that all observations are $\text{i.i.d.}$, likelihood factorizes to: $$ p(Y|X, \theta)=p(y_1,...,y_N|\boldsymbol x_1, ... , \boldsymbol x_N, \boldsymbol \theta) = \prod_{n=1}^{N} p(y_n|\boldsymbol x_n, \boldsymbol \theta) = \prod_{n=1}^{N} \mathcal{N}(y_n|f(\boldsymbol x_n),\,\sigma^{2})$$
And our objective is: $$ \boldsymbol \theta_{ML} = \text{argmax} \ p(Y|X, \boldsymbol \theta)$$
Now, here comes my problem, when I initialize $\boldsymbol \theta$ and calculate the likelihood by multiplying the density function of each observation I end up with a very small number that eventually becomes zero (especially if $N$ is large), and I can't even call tensor.backward()
to use gradient descent to minimize the minus log of the likelihood function.
However, for some cases I managed to get a working solution by multiplying the density function of each observation by a constant to avoid ending up with zero, but it doesn't always work.
Note: I'm aware of the closed-form solution for the optimum $\boldsymbol \theta^*$, I am just trying to reach optimum parameters through gradient descent and backpropagation of negative log likelihood.
So, is there a work around for calculating the likelihood of the training data set without ending up with zero?