Newer
Older
notebooks / tfp_keras_embedding_playground.ipynb
{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "tfp_keras_embedding_playground.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "authorship_tag": "ABX9TyOUTUu0qPp27YU64gUuClas",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/morteza/notebooks/blob/master/tfp_keras_embedding_playground.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 204
        },
        "id": "zNYhsni5Q_yO",
        "outputId": "d7373ff1-dc2c-436d-9240-703c3fe5461d"
      },
      "source": [
        "import pandas as pd\n",
        "import numpy as np\n",
        "import scipy.stats as stats\n",
        "\n",
        "import tensorflow as tf\n",
        "import tensorflow.keras.layers as layers\n",
        "import tensorflow_probability as tfp\n",
        "\n",
        "tfd = tfp.distributions\n",
        "\n",
        "# Data\n",
        "n_samples = 10000\n",
        "n_labels = 64\n",
        "n_topics = 12\n",
        "n_categories = 2\n",
        "\n",
        "\n",
        "data = pd.DataFrame({\n",
        "    'category': np.random.choice(n_categories, (n_samples,)),\n",
        "    'label': np.random.choice(n_labels, (n_samples,)),\n",
        "})\n",
        "\n",
        "features = stats.truncnorm(0,1).rvs(size=(n_samples, n_topics))\n",
        "\n",
        "data = pd.concat([data, pd.DataFrame(features)], axis=1)\n",
        "\n",
        "data.tail()\n"
      ],
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>category</th>\n",
              "      <th>label</th>\n",
              "      <th>0</th>\n",
              "      <th>1</th>\n",
              "      <th>2</th>\n",
              "      <th>3</th>\n",
              "      <th>4</th>\n",
              "      <th>5</th>\n",
              "      <th>6</th>\n",
              "      <th>7</th>\n",
              "      <th>8</th>\n",
              "      <th>9</th>\n",
              "      <th>10</th>\n",
              "      <th>11</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>9995</th>\n",
              "      <td>0</td>\n",
              "      <td>29</td>\n",
              "      <td>0.338359</td>\n",
              "      <td>0.200292</td>\n",
              "      <td>0.366758</td>\n",
              "      <td>0.512287</td>\n",
              "      <td>0.421813</td>\n",
              "      <td>0.412299</td>\n",
              "      <td>0.298286</td>\n",
              "      <td>0.217234</td>\n",
              "      <td>0.876204</td>\n",
              "      <td>0.026990</td>\n",
              "      <td>0.553567</td>\n",
              "      <td>0.579650</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>9996</th>\n",
              "      <td>0</td>\n",
              "      <td>48</td>\n",
              "      <td>0.733919</td>\n",
              "      <td>0.308699</td>\n",
              "      <td>0.425183</td>\n",
              "      <td>0.713357</td>\n",
              "      <td>0.932479</td>\n",
              "      <td>0.623409</td>\n",
              "      <td>0.803112</td>\n",
              "      <td>0.768884</td>\n",
              "      <td>0.677390</td>\n",
              "      <td>0.269333</td>\n",
              "      <td>0.232070</td>\n",
              "      <td>0.141412</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>9997</th>\n",
              "      <td>1</td>\n",
              "      <td>13</td>\n",
              "      <td>0.382530</td>\n",
              "      <td>0.146689</td>\n",
              "      <td>0.508429</td>\n",
              "      <td>0.578849</td>\n",
              "      <td>0.205561</td>\n",
              "      <td>0.785769</td>\n",
              "      <td>0.299319</td>\n",
              "      <td>0.671348</td>\n",
              "      <td>0.469920</td>\n",
              "      <td>0.164159</td>\n",
              "      <td>0.239871</td>\n",
              "      <td>0.142832</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>9998</th>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0.192772</td>\n",
              "      <td>0.806608</td>\n",
              "      <td>0.066029</td>\n",
              "      <td>0.309884</td>\n",
              "      <td>0.230482</td>\n",
              "      <td>0.110686</td>\n",
              "      <td>0.390677</td>\n",
              "      <td>0.798374</td>\n",
              "      <td>0.489189</td>\n",
              "      <td>0.558733</td>\n",
              "      <td>0.274848</td>\n",
              "      <td>0.120094</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>9999</th>\n",
              "      <td>1</td>\n",
              "      <td>29</td>\n",
              "      <td>0.570087</td>\n",
              "      <td>0.859802</td>\n",
              "      <td>0.116288</td>\n",
              "      <td>0.976016</td>\n",
              "      <td>0.820458</td>\n",
              "      <td>0.020163</td>\n",
              "      <td>0.373489</td>\n",
              "      <td>0.004759</td>\n",
              "      <td>0.964626</td>\n",
              "      <td>0.957332</td>\n",
              "      <td>0.215921</td>\n",
              "      <td>0.497364</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "      category  label         0  ...         9        10        11\n",
              "9995         0     29  0.338359  ...  0.026990  0.553567  0.579650\n",
              "9996         0     48  0.733919  ...  0.269333  0.232070  0.141412\n",
              "9997         1     13  0.382530  ...  0.164159  0.239871  0.142832\n",
              "9998         1      1  0.192772  ...  0.558733  0.274848  0.120094\n",
              "9999         1     29  0.570087  ...  0.957332  0.215921  0.497364\n",
              "\n",
              "[5 rows x 14 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 1
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ZZOR3g1CfOqu"
      },
      "source": [
        "train_dataset = data.sample(frac=.8, random_state=0)\n",
        "test_dataset = data.drop(train_dataset.index)"
      ],
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "K6mPL9FqRBGj",
        "outputId": "44826208-aa38-4198-8455-73ab9a16a7a9"
      },
      "source": [
        "Root = tfd.JointDistributionCoroutine.Root  # alias.\n",
        "\n",
        "# Model\n",
        "def model():\n",
        "\n",
        "  rv_cat = yield Root(tfd.Categorical(tf.ones(n_categories)/n_categories, name='category'))\n",
        "\n",
        "  cat_to_lbl = tf.stack([\n",
        "      tf.constant(np.ones(n_labels, dtype='float32')),\n",
        "      tf.constant(np.ones(n_labels, dtype='float32'))      \n",
        "  ])[rv_cat,]\n",
        "\n",
        "  rv_lbl = yield tfd.Categorical(cat_to_lbl, name='label')\n",
        "  lbl_to_prb = tf.constant(np.ones(n_labels, dtype='float32'))[rv_lbl]\n",
        "  \n",
        "  rv_prb = yield tfd.HalfNormal(lbl_to_prb, name='prob')\n",
        "\n",
        "joint = tfd.JointDistributionCoroutineAutoBatched(model)\n",
        "\n",
        "x = joint.sample(100)\n",
        "x\n",
        "# joint.prob(**x._asdict())"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "WARNING:tensorflow:Note that Multinomial inside pfor op may not give same output as inside a sequential loop.\n",
            "WARNING:tensorflow:Using a while_loop for converting StridedSlice\n",
            "WARNING:tensorflow:Note that Multinomial inside pfor op may not give same output as inside a sequential loop.\n",
            "WARNING:tensorflow:Using a while_loop for converting StridedSlice\n",
            "WARNING:tensorflow:Note that RandomStandardNormal inside pfor op may not give same output as inside a sequential loop.\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "StructTuple(\n",
              "  category=<tf.Tensor: shape=(100,), dtype=int32, numpy=\n",
              "    array([1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0,\n",
              "           1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,\n",
              "           0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0,\n",
              "           0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1,\n",
              "           1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1], dtype=int32)>,\n",
              "  label=<tf.Tensor: shape=(100,), dtype=int32, numpy=\n",
              "    array([43, 55,  2, 50, 42,  0, 34, 14, 24, 47, 61, 62, 29,  3, 14,  8, 17,\n",
              "           54, 24, 14, 51,  5, 11,  5, 26,  8, 12, 54, 36, 56, 63, 36, 29, 10,\n",
              "           25, 42, 40, 48, 49, 23, 37, 27, 37, 22, 44, 58, 11, 21, 29, 27,  2,\n",
              "           33, 17, 33, 51, 53, 29, 10, 38, 18, 52, 31, 39, 29, 23, 52,  8, 57,\n",
              "           37, 62, 49, 31, 40, 56, 59,  8,  4, 28, 34, 60, 36, 62,  5,  6, 53,\n",
              "            3, 33, 25,  9, 25, 48,  0, 61, 55, 12, 12, 60,  6, 25, 21],\n",
              "          dtype=int32)>,\n",
              "  prob=<tf.Tensor: shape=(100,), dtype=float32, numpy=\n",
              "    array([0.2061744 , 1.3268954 , 0.28608376, 0.5018161 , 0.8876709 ,\n",
              "           0.78586996, 0.5411243 , 0.92167425, 0.27939665, 1.697958  ,\n",
              "           0.04098056, 0.6506136 , 0.00351702, 1.3415766 , 0.26065996,\n",
              "           0.5004551 , 0.7516069 , 0.8970741 , 2.0565538 , 0.63262844,\n",
              "           0.05982151, 0.8660924 , 1.6724459 , 0.76789826, 0.2253358 ,\n",
              "           0.37048152, 1.4438678 , 0.40929222, 0.8248749 , 0.2818029 ,\n",
              "           1.4797125 , 0.97030205, 0.35326475, 0.6848987 , 1.453644  ,\n",
              "           1.2331146 , 0.2721199 , 0.5857292 , 0.23221932, 0.35422876,\n",
              "           1.2386101 , 0.5032205 , 0.52406746, 1.1228805 , 0.29127055,\n",
              "           0.60625225, 0.553615  , 0.13891475, 0.56372494, 0.00725707,\n",
              "           0.92716783, 0.48368752, 1.3187152 , 0.07450034, 0.77724415,\n",
              "           0.7997414 , 1.1254249 , 0.32463244, 1.5539621 , 0.27223244,\n",
              "           0.48015985, 1.4723798 , 0.35986656, 0.6532424 , 0.7155228 ,\n",
              "           0.82778835, 1.0893906 , 0.43777695, 0.73064435, 1.857151  ,\n",
              "           1.1450212 , 0.17804307, 1.8402802 , 0.10580592, 0.45151055,\n",
              "           1.1693316 , 0.26372057, 1.1572653 , 0.3721436 , 0.03066089,\n",
              "           1.3131375 , 1.4629443 , 1.2486721 , 0.01426138, 1.181778  ,\n",
              "           0.72616667, 1.1811308 , 0.02107091, 0.0120546 , 1.1253365 ,\n",
              "           2.0932848 , 1.317094  , 0.47295582, 0.78921187, 0.09134816,\n",
              "           1.269546  , 0.5230746 , 0.8522933 , 0.4456092 , 0.70865494],\n",
              "          dtype=float32)>\n",
              ")"
            ]
          },
          "metadata": {},
          "execution_count": 4
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "dl3VgDZPkyNJ",
        "outputId": "41821217-211e-4fd5-a45e-c9920096a55c"
      },
      "source": [
        "X = data['label'].astype('category').cat.codes.values\n",
        "y = data.drop(columns=['category','label'])\n",
        "\n",
        "model = tf.keras.Sequential()\n",
        "model.add(layers.Embedding(n_labels, n_topics))\n",
        "model.compile('adam', 'mse')\n",
        "history = model.fit(X, y, epochs=5)\n",
        "y_pred = model.predict(data['label'])\n",
        "z = model.get_layer(index=0).get_weights()[0]"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Epoch 1/5\n",
            "313/313 [==============================] - 1s 1ms/step - loss: 0.2228\n",
            "Epoch 2/5\n",
            "313/313 [==============================] - 0s 2ms/step - loss: 0.1344\n",
            "Epoch 3/5\n",
            "313/313 [==============================] - 0s 1ms/step - loss: 0.0965\n",
            "Epoch 4/5\n",
            "313/313 [==============================] - 0s 1ms/step - loss: 0.0838\n",
            "Epoch 5/5\n",
            "313/313 [==============================] - 0s 1ms/step - loss: 0.0805\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 308
        },
        "id": "sVNkLaXEmpsC",
        "outputId": "53e16992-b0af-48dd-fdbb-5a0aa813cd05"
      },
      "source": [
        "import seaborn as sns\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "plt.plot(np.arange(len(history.history['loss'])), history.history['loss'])\n",
        "plt.suptitle('training loss history')\n",
        "plt.xlabel('Epoch')\n",
        "plt.ylabel('MSE')\n",
        "plt.show()"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    }
  ]
}