{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append('..')\n",
    "import numpy as np \n",
    "\n",
    "\n",
    "import neural_nets.data_loaders as dl\n",
    "from relu_nets import ReLUNet\n",
    "from neural_nets import train\n",
    "from hyperbox import Hyperbox\n",
    "from lipMIP import LipProblem\n",
    "from interval_analysis import HBoxIA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 52820 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "params = dl.RandomKParameters(00, k=20, radius=0.02, dimension=2, num_classes=4)\n",
    "dataset = dl.RandomDataset(params, random_seed=420)\n",
    "dataset.plot_2d()\n",
    "dataset.base_data[1]\n",
    "dataset.split_train_val(1.0)\n",
    "trainset = dataset.train_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 00 | Accuracy: 34.50\n",
      "Epoch 50 | Accuracy: 52.00\n",
      "Epoch 100 | Accuracy: 55.00\n",
      "Epoch 150 | Accuracy: 61.50\n",
      "Epoch 200 | Accuracy: 64.50\n",
      "Epoch 250 | Accuracy: 66.00\n",
      "Epoch 300 | Accuracy: 68.50\n",
      "Epoch 350 | Accuracy: 70.50\n",
      "Epoch 400 | Accuracy: 72.50\n",
      "Epoch 450 | Accuracy: 74.50\n",
      "Epoch 500 | Accuracy: 78.00\n",
      "Epoch 550 | Accuracy: 81.00\n",
      "Epoch 600 | Accuracy: 83.00\n",
      "Epoch 650 | Accuracy: 85.00\n",
      "Epoch 700 | Accuracy: 85.50\n",
      "Epoch 750 | Accuracy: 86.50\n",
      "Epoch 800 | Accuracy: 86.50\n",
      "Epoch 850 | Accuracy: 87.00\n",
      "Epoch 900 | Accuracy: 88.50\n",
      "Epoch 950 | Accuracy: 89.00\n"
     ]
    }
   ],
   "source": [
    "test_net = ReLUNet(layer_sizes=[2, 40, 40, 4])\n",
    "train_params = train.TrainParameters(trainset, trainset, 1000, test_after_epoch=50)\n",
    "train.training_loop(test_net, train_params)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_domain = Hyperbox.build_linf_ball(np.array([0.5, 0.5]), 0.5)\n",
    "backprop_domain = Hyperbox.build_linf_ball(np.zeros(4), 1.0)\n",
    "ia_obj = HBoxIA(test_net, input_domain, backprop_domain)\n",
    "ia_obj.compute_forward()\n",
    "ia_obj.compute_backward()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LipMIP Result: \n",
       "\tValue 171.336\n",
       "\tRuntime 0.486"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c_vec = np.array([1.0, -1.0, 0.0, 0.0])\n",
    "prob = LipProblem(test_net, input_domain, 'crossLipschitz', num_threads=4)\n",
    "prob.compute_max_lipschitz()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get all results\n",
    "c_vecs = []\n",
    "for i in range(4):\n",
    "    for j in range(i + 1, 4):\n",
    "        z = np.zeros(4)\n",
    "        z[i] = 1\n",
    "        z[j] = -1\n",
    "        c_vecs.append(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LipMIP Result: \n",
      "\tValue 153.495\n",
      "\tRuntime 0.374\n",
      "LipMIP Result: \n",
      "\tValue 88.296\n",
      "\tRuntime 0.474\n",
      "LipMIP Result: \n",
      "\tValue 109.175\n",
      "\tRuntime 0.345\n",
      "LipMIP Result: \n",
      "\tValue 171.336\n",
      "\tRuntime 0.431\n",
      "LipMIP Result: \n",
      "\tValue 72.800\n",
      "\tRuntime 0.336\n",
      "LipMIP Result: \n",
      "\tValue 140.389\n",
      "\tRuntime 0.246\n"
     ]
    }
   ],
   "source": [
    "for c_vec in c_vecs:\n",
    "    prob = LipProblem(test_net, input_domain, c_vec, num_threads=4)\n",
    "    print(prob.compute_max_lipschitz())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ia_obj.gradient_range.as_twocol()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "vals =[]\n",
    "for i in range(1000):\n",
    "    p = input_domain.random_point(1).squeeze()\n",
    "    c_vec = backprop_domain.random_point(1).squeeze()\n",
    "    vals.append(ia_obj.gradient_range.contains(test_net.get_grad_at_point(p, c_vec)))\n",
    "all(vals)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "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.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
