began writing computational approach
parent
3ca5312fab
commit
226f344f02
@ -0,0 +1,242 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "departmental-hardware",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import torch\n",
|
||||
"from torch.autograd.functional import jacobian"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "differential-shock",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"a = torch.tensor([1,2,3,4.2],requires_grad=False)\n",
|
||||
"b = torch.tensor([2,2,2,2.0],requires_grad=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "separated-pursuit",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def test(x,y):\n",
|
||||
" return (x@y)**2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"id": "french-trunk",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"tensor(416.1600, grad_fn=<PowBackward0>)"
|
||||
]
|
||||
},
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"test(a,b)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 57,
|
||||
"id": "adverse-ceremony",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"((tensor([81.6000, 81.6000, 81.6000, 81.6000]),\n",
|
||||
" tensor([ 40.8000, 81.6000, 122.4000, 171.3600])),\n",
|
||||
" tensor([2., 2., 2., 2.], requires_grad=True),\n",
|
||||
" tensor(416.1600, grad_fn=<PowBackward0>))"
|
||||
]
|
||||
},
|
||||
"execution_count": 57,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"j = jacobian(test,(a,b))\n",
|
||||
"j,b,test(a,b)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 58,
|
||||
"id": "lovely-apple",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"((tensor([-12.8304, -3.9878, 4.8547, 15.4658]),\n",
|
||||
" tensor([-10.8365, -21.6729, -32.5094, -45.5132])),\n",
|
||||
" tensor([ 1.1840, 0.3680, -0.4480, -1.4272], grad_fn=<SubBackward0>),\n",
|
||||
" tensor(29.3573, grad_fn=<PowBackward0>))"
|
||||
]
|
||||
},
|
||||
"execution_count": 58,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"b2 = b - j[1]*b*0.01\n",
|
||||
"j2 = jacobian(test,(a,b2))\n",
|
||||
"j2,b2,test(a,b2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 63,
|
||||
"id": "stretch-selection",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"((tensor([-13.6581, -4.2906, 5.2787, 17.0284]),\n",
|
||||
" tensor([-11.4119, -22.8239, -34.2358, -47.9301])),\n",
|
||||
" tensor([ 1.1968, 0.3760, -0.4626, -1.4922], grad_fn=<SubBackward0>),\n",
|
||||
" tensor(32.5580, grad_fn=<PowBackward0>))"
|
||||
]
|
||||
},
|
||||
"execution_count": 63,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"b3 = b2 - j2[1]*b2*0.001\n",
|
||||
"j3 = jacobian(test,(a,b3))\n",
|
||||
"j3,b3,test(a,b3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 64,
|
||||
"id": "colored-visit",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"((tensor([-14.5816, -4.6324, 5.7628, 18.8361]),\n",
|
||||
" tensor([-12.0461, -24.0921, -36.1382, -50.5935])),\n",
|
||||
" tensor([ 1.2105, 0.3846, -0.4784, -1.5637], grad_fn=<SubBackward0>),\n",
|
||||
" tensor(36.2769, grad_fn=<PowBackward0>))"
|
||||
]
|
||||
},
|
||||
"execution_count": 64,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"b4 = b3 - j3[1]*b3*0.001\n",
|
||||
"j4 = jacobian(test,(a,b4))\n",
|
||||
"j4,b4,test(a,b4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 65,
|
||||
"id": "familiar-pizza",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"((tensor([-15.6173, -5.0205, 6.3191, 20.9424]),\n",
|
||||
" tensor([-12.7481, -25.4962, -38.2443, -53.5421])),\n",
|
||||
" tensor([ 1.2251, 0.3938, -0.4957, -1.6428], grad_fn=<SubBackward0>),\n",
|
||||
" tensor(40.6286, grad_fn=<PowBackward0>))"
|
||||
]
|
||||
},
|
||||
"execution_count": 65,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"b5 = b4 - j4[1]*b4*0.001\n",
|
||||
"j5 = jacobian(test,(a,b5))\n",
|
||||
"j5,b5,test(a,b5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 66,
|
||||
"id": "brilliant-squad",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"((tensor([-15.6173, -5.0205, 6.3191, 20.9424]),\n",
|
||||
" tensor([-12.7481, -25.4962, -38.2443, -53.5421])),\n",
|
||||
" tensor([ 1.2407, 0.4039, -0.5146, -1.7307], grad_fn=<SubBackward0>),\n",
|
||||
" tensor(45.7605, grad_fn=<PowBackward0>))"
|
||||
]
|
||||
},
|
||||
"execution_count": 66,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"b6 = b5 - j5[1]*b5*0.001\n",
|
||||
"j6 = jacobian(test,(a,b5))\n",
|
||||
"j6,b6,test(a,b6)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "discrete-engineer",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
\documentclass[../Main.tex]{subfiles}
|
||||
\graphicspath{{\subfix{Assets/img/}}}
|
||||
|
||||
\begin{document}
|
||||
\subsection{Introduction to }
|
||||
The computational approach I have decided to take is an application of
|
||||
\cite{MALIAR2018}, where the policy function is approximated using a
|
||||
neural network.
|
||||
|
||||
The approach uses the fact that the euler equation implicitly defines the
|
||||
optimal policy function, for example:
|
||||
$[0] = f(x(\theta),\theta)$.
|
||||
This can easily be turned into a mean square loss function by squaring both
|
||||
sides,
|
||||
$0 = f^2(x(\theta),\theta)$,
|
||||
allowing one to find $x(\dot)$ as the solution to a minimization problem.
|
||||
|
||||
By choosing a neural network as the functional approximation, we are able to
|
||||
take advantage of the significant computational and practical improvements
|
||||
currently revolutionizing Machine Learning.
|
||||
In particular, we can now use common frameworks, such as python, PyTorch,
|
||||
and various online accerators (Google Colab)
|
||||
which have been optimized for relatively high performance and
|
||||
straightforward development.
|
||||
|
||||
\subsection{Computational Plan}
|
||||
I have decided to use python and the PyTorch Neural Network library for this project.
|
||||
|
||||
The most difficult step is creating the euler equations.
|
||||
When working with high dimensioned problems involving differentiation,
|
||||
three general computational approaches exist:
|
||||
\begin{itemize}
|
||||
\item Using a symbolic library (sympy) or language (mathematica) to create the
|
||||
euler equations.
|
||||
This has the disadvantage of being (very) slow, but the advantage that
|
||||
for a single problem specification it only needs completed once.
|
||||
It requires taking a matrix inverse, which can easily complicate formulas,
|
||||
and is computationally expensive.
|
||||
\item Using numerical differentiation (ND).
|
||||
The primary issue with ND is that errors can grow quite quickly when
|
||||
performing algebra on numerical derivatives.
|
||||
This requires tracking how errors can grow and compound within your
|
||||
specific formulation of the problem.
|
||||
\item Using automatic differentiation (AD) to differentiate the computer code
|
||||
directly.
|
||||
This approach has a few major benefits.
|
||||
\begin{itemize}
|
||||
\item Precision is high, because you are calcuating symbolic
|
||||
derivatives of your computer functions.
|
||||
\item ML is heavily dependent on AD, thus the tools are plentiful
|
||||
and tested.
|
||||
\item The coupling of AD and ML lead to a tight integration with
|
||||
the neural network libraries, simplifying the calibration procedure.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
I have chosen to use the AD to generate a euler equation function, which will
|
||||
then be the basis of our loss function.
|
||||
|
||||
|
||||
The first step is to construct the intertemporal transition functions
|
||||
(e.g \ref{put_refs_here}).
|
||||
%Not sure how much detail to use.
|
||||
%I'm debating on describing how it is done.
|
||||
These take derivatives of the value function at time $t$ as an input, and output
|
||||
derivatives of the value function at time $t+1$.
|
||||
Once this function has been finished, it can be combined with the laws of motion
|
||||
in an iterated manner to transition between times $t$ and times $t+k$.
|
||||
I did so by coding a function that iteratively compose the transition
|
||||
and laws of motion functions, retuning a $k$-period transition function.
|
||||
|
||||
The second step is to generate functions that represent the optimality conditions.
|
||||
By taking the appropriate derivatives with respect to the laws of motion and
|
||||
utility functions, this can be constructed explicitly.
|
||||
|
||||
Once these two functions are completed, they can be combined to create
|
||||
the euler equations, as described in appendix \ref{appx??}.
|
||||
|
||||
\subsection{Training}
|
||||
|
||||
With the euler equation and resulting loss function in place,
|
||||
standard training approachs can be used to fit the function.
|
||||
I plan on using some variation on stochastic gradient descent.
|
||||
|
||||
Normally, neural networks are trained on real world data.
|
||||
As this is a synthetic model, I am planning on training it on random selections
|
||||
from the state space.
|
||||
If I can data on how satellites are and have been distributed, I plan on
|
||||
selecting from that distribution.
|
||||
|
||||
\subsections{Extensions}
|
||||
One key question is how to handle the case of heterogeneous agents.
|
||||
I believe I can address this in the constellation operator's case
|
||||
by solving for the policy functions of each class of operator
|
||||
simultaneously.
|
||||
I still have some questions about this approach and have not dived into
|
||||
some of the mathemeatics that deeply.
|
||||
|
||||
|
||||
|
||||
\subsection{Existence concerns}
|
||||
%check matrix inverses etc.
|
||||
%
|
||||
|
||||
\end{document}
|
||||
Loading…
Reference in New Issue