{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# MNIST classification" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os\n", "\n", "os.environ[\"KMP_WARNINGS\"] = \"0\"\n", "import jax\n", "import jax.numpy as jnp\n", "import numpy as np\n", "import tensorflow as tf\n", "from jax.nn.initializers import *\n", "from tensorflow.keras.datasets import mnist\n", "\n", "from tn4ml.embeddings import *\n", "from tn4ml.eval import *\n", "from tn4ml.initializers import *\n", "from tn4ml.metrics import *\n", "from tn4ml.models.model import *\n", "from tn4ml.models.mps import *\n", "from tn4ml.strategy import *\n", "from tn4ml.util import *" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Enable 64-bit precision and set matmul precision to highest\n", "\n", "jax.config.update(\"jax_enable_x64\", True)\n", "jax.config.update(\"jax_default_matmul_precision\", \"highest\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load dataset\n", "\n", "**MNIST images** → grayscale images\n", "- size: 28x28\n", "- 0-9 numbers" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "train, test = mnist.load_data()\n", "\n", "if os.environ.get(\"CI\"):\n", " train = (train[0][:256], train[1][:256])\n", " test = (test[0][:64], test[1][:64])" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "train_labels = train[1]\n", "train_images = train[0].reshape(-1, 28, 28)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "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bO8piuBo3769ym+99ZbHx69YsULlRx99VOVTp04FZFy4cfnz51e5SpUqKg8ZMkTljHpx074uRTJ+bdrr5j322GMqp6SkeHw+rlW1alWVv/76a5Wzeh3P77//XuVPP/00i0aSvUVFRd3wc6tXr66y/fve7qMsVaqUymFhYSrbaxPar3O793H16tUqX7hwQeU8eXSZtG7dOsnOuFIHAADgABR1AAAADkBRBwAA4ADZpqfunnvucd+uUaOGus9eW8juu8ju0vbq2J9L2r0DceP83dt1586dKh86dMjfIcFH9r6b9nqV9pyWKFFCZbtXxu6Bs9eRs9ersnv2bHZvzf33369y2rUML1686PFYSJ/dT2VnX/naN2lL+3tJRKR169Yqf/vttzc2sBzGfm3Zv8c+/vhjlV988UWvj22vGWrP+aVLl1Q+d+6cyr/88ovKn332mcr23u92D779s37v3r0q23vF//rrr5KdcaUOAADAASjqAAAAHICiDgAAwAGyTU9d2vet7XVnDh8+rPK0adMyZUzeCg8PV/mVV1657mOXLFmi8sCBA4MxpFynf//+KvvaO5PROnYIPPt1bve4zZo1y+PzX331VZXt19bKlStVttfSsh9vr5lmi46OVvnNN99Uec+ePe7bs2fPVvfZa1/hss2bN6vctGlTle19ORcsWKBycnKyX+fv3r27yr169fLreE719NNPq7x7926VGzRocMPHTvu6Ebn2tbN161aVf/jhhxs+V3qefPJJle3Xud1vnd1xpQ4AAMABKOoAAAAcgKIOAADAAbJNT50ndj/KgQMHsmgkl9k9dIMGDVL5+eefVzntujcjRoxQ9yUlJQV4dLmDvZZhixYtfHp+QkKCytu2bfN3SPBC2rXo7J44+3Vjs9cEGz16tMonT55U2e6NmTdvnsp/+9vfVLbXlnvnnXdUtnvu2rVrp/LkyZPdtxcvXqzue/vtt1U+ceKEeJJb16+0e7WGDRsW1PPZ/c/01HnH/n7OyZo1a+bxfl/XPM1qXKkDAABwAIo6AAAAB6CoAwAAcIAc0VOX1Xu92v1bdu/Pgw8+qLLdr9WhQ4egjCs3W7hwocpFixb1+Hh7baNu3boFekhIR2hoqMpDhw51337uuefUfWfPnlV5wIABKn/55Zcq2z10t99+u8r//ve/Vbb3kt2+fbvKPXv2VHnp0qUqFy5c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TmW7f2rlypUq+7qOne3MmTMqT58+XeVvv/3Wr+PDf3af5NixY1W215e09e3bV2V7jTN66ILP7nOMjIxU2d5vd+7cuSrnzZtX5Xvuucfj8exe2SNHjng/WOQILVu2zOohZCtcqQMAAHAAijoAAAAHyBFvv8bExKhcpUoVle23UW699Va/zrd69WqV3333XZXt5Td428Z/69atU9l+C/1f//qXyvbSCBn5/PPPVf75559V3rBhg8r220DIeiVLllQ5o7dbd+zYoXJGy2cg+DLawsnO9tut9jZgH3zwgconTpxQedy4cSqPGTPG67EiZyhXrlxWDyFb4UodAACAA1DUAQAAOABFHQAAgANkm566qKgo9+1PPvlE3WdvAeXve+irVq1SecSIESrb246cP3/er/PBd998843HDOeze2P79evn8fG//fabyq1btw74mOCfv/zlLx7vt5ccWbRokcp33nmnx+c/9thjKs+ZM8eH0SEn+v7771UOCdHXqnJbzztX6gAAAByAog4AAMABKOoAAAAcINN66urVq6fy888/r3LdunXdt+31qHxlbzFlr0/1xhtvqHz27Fm/zgcg8AYPHqzygw8+6PHxo0ePVnn37t0BHxP8s3XrVo/322sP2tt8HT9+XOUPP/xQ5cWLF/sxOuREmzdvVnn79u0q2z345cuXV9lpW8dxpQ4AAMABKOoAAAAcgKIOAADAATKtp+6+++7zmD355ZdfVJ47d67Kly5dUtled+7kyZNenwtA1vjrX/+qcuHChT0+/tNPP1V5yZIlAR8TAsvegzksLExlu49y7dq1Kn/99dcqv/feewEcHZzA7pm39/8dNmyYyr169VLZrjdyGq7UAQAAOABFHQAAgANQ1AEAADiAyxhjvHqgtV4QcgYvpzddzHnOlFPn/O2331bZ3uvVXneuTZs2Km/bti04A8sBcuqc48Yx5+mze3GnT5+ucnx8vMqzZs1S2d4/ODutY+vNnHOlDgAAwAEo6gAAAByAog4AAMAB6KlzOPoucp+cOufNmjVTecGCBSp36NBB5YSEhKCPKafIqXOOG8ece8fusbPXqevZs6fK1apVUzk7rVtHTx0AAEAuQVEHAADgABR1AAAADkBPncPRd5H7MOe5D3Oe+zDnuQ89dQAAALkERR0AAIADUNQBAAA4gNc9dQAAAMi+uFIHAADgABR1AAAADkBRBwAA4AAUdQAAAA5AUQcAAOAAFHUAAAAOQFEHAADgABR1AAAADkBRBwAA4AD/DzrEWgHr2AvzAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "hfont = {\"fontname\": \"Courier New\", \"fontsize\": 15, \"fontweight\": \"bold\"}\n", "\n", "for i in range(10):\n", " plt.subplot(2, 5, i + 1)\n", " # Select the first image of each digit\n", " digit_indices = np.where(train_labels == i)[0]\n", " plt.imshow(train_images[digit_indices[0]], cmap=\"gray\")\n", " plt.title(f\"Label: {i}\", **hfont)\n", " plt.axis(\"off\")\n", "\n", "plt.tight_layout()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "data = {\n", " \"X\": {\"train\": train[0], \"test\": test[0]},\n", " \"y\": {\"train\": train[1], \"test\": test[1]},\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Reduce size of the image**" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def resize_images(images):\n", " \"\"\"Resize a batch of images to 14x14 pixels.\"\"\"\n", " resized_images = tf.image.resize(\n", " images, [14, 14], method=tf.image.ResizeMethod.AREA\n", " )\n", " return resized_images.numpy()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "X_resized = (\n", " resize_images(data[\"X\"][\"train\"].reshape(-1, 28, 28, 1)).reshape(-1, 14, 14) / 255.0\n", ")\n", "\n", "X_test_resized = (\n", " resize_images(data[\"X\"][\"test\"].reshape(-1, 28, 28, 1)).reshape(-1, 14, 14) / 255.0\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Rearagne pixels in zig-zag order\n", "- ref. - *Supervised learning with quantum-inspired tensor networks* (https://arxiv.org/pdf/1605.05775.pdf)\n", "
\n", "\n", "\"MPS" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "def zigzag_order(data):\n", " \"\"\"Flatten image rows into a zigzag-compatible feature order.\"\"\"\n", " data_zigzag = []\n", " for x in data:\n", " image = []\n", " for i in x:\n", " image.extend(i)\n", " data_zigzag.append(image)\n", " return np.asarray(data_zigzag)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "train_data = zigzag_order(X_resized)\n", "test_data = zigzag_order(X_test_resized)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### One-hot encoding of labels\n", "\n", "10 classes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n", "\n", "Label 0 → [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
\n", "Label 1 → [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
\n", "Label 2 → [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
\n", "Label 3 → [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
\n", "Label 4 → [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
\n", "Label 5 → [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
\n", "Label 6 → [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
\n", "Label 7 → [0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
\n", "Label 8 → [0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
\n", "Label 9 → [0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "n_classes = 10" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "y_train = integer_to_one_hot(data[\"y\"][\"train\"], n_classes)\n", "y_test = integer_to_one_hot(data[\"y\"][\"test\"], n_classes)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Take samples for training, validation and testing**" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import train_test_split" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "train_inputs, _, train_targets, _ = train_test_split(\n", " train_data, y_train, test_size=0.8 if os.environ.get(\"CI\") else 0.9, random_state=42\n", ") # take only part of the training data - to speed up the training" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "train_inputs, val_inputs, train_targets, val_targets = train_test_split(\n", " train_inputs, train_targets, test_size=0.2, random_state=42\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## TN as ML model\n", "\n", "MPS-based classifier:\n", "- each circular node represents a tensor ($A^{[i]}$) in the Matrix Product State chain\n", "- vertical legs correspond to local input features ($x_i$)\n", "- horizontal connections represent contracted virtual bonds with bond dimension ($\\chi$)\n", "- designated tensor carries an additional output leg of dimension ($C$), producing the class-score vector ($\\hat{y} \\in \\mathbb{R}^C$) used for classification" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"MPS\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Specify parameters and initialize a tensor network**" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "L = 14 * 14 # number of tensors in the MPS\n", "initializer = randn(1e-2) # MPS tensors are initialized with random normal values\n", "key = jax.random.key(42)\n", "shape_method = \"noteven\"\n", "bond_dim = 10 # bond dimension of the MPS\n", "phys_dim = 3 # when polyomial embedding is used p = 3, when trigonometric embedding is used p = 2\n", "class_dim = 10 # number of classes\n", "index_class = L // 2 if L % 2 == 0 else L // 2 + 1\n", "cyclic = False\n", "add_identity = True\n", "boundary = \"obc\" # open boundary conditions" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "model = MPS_initialize(\n", " L,\n", " initializer=initializer,\n", " key=key,\n", " shape_method=shape_method,\n", " bond_dim=bond_dim,\n", " phys_dim=phys_dim,\n", " cyclic=False,\n", " add_identity=add_identity,\n", " class_dim=class_dim,\n", " class_index=index_class,\n", " canonical_center=index_class,\n", " boundary=boundary,\n", " dtype=jnp.float64,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Define training parameters**" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "def cross_entropy_loss(*args, **kwargs):\n", " \"\"\"Compute softmax cross-entropy loss.\"\"\"\n", " return OptaxWrapper(optax.softmax_cross_entropy)(*args, **kwargs).mean()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "# training parameters\n", "optimizer = optax.adam\n", "strategy = \"global\" # Global Gradient Descent\n", "loss = cross_entropy_loss\n", "train_type = TrainingType.SUPERVISED\n", "embedding = PolynomialEmbedding(degree=2, n=1, include_bias=True) # if using randn\n", "learning_rate = 1e-3\n", "device = (\"cpu\", 0)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "model.configure(\n", " optimizer=optimizer,\n", " strategy=strategy,\n", " loss=loss,\n", " train_type=train_type,\n", " learning_rate=learning_rate,\n", " device=device,\n", ")" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "epochs = 1 if os.environ.get(\"CI\") else 50\n", "batch_size = 16 if os.environ.get(\"CI\") else 1000" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To obtain loss scalar value, contract:\n", "\n", "
\n", " \"MPS\n", "
" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "epoch: 100%|██████████ 50/50 , loss=1.4784, val_loss=1.5175, val_acc=0.9350\n" ] } ], "source": [ "history = model.train(\n", " train_inputs,\n", " targets=train_targets,\n", " val_inputs=val_inputs,\n", " val_targets=val_targets,\n", " epochs=epochs,\n", " batch_size=batch_size,\n", " canonize=(True, index_class),\n", " embedding=embedding,\n", " normalize=True,\n", " display_val_acc=True,\n", " val_batch_size=batch_size,\n", " eval_metric=cross_entropy_loss,\n", " dtype=jnp.float64,\n", ")" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/png": "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dt/nli1btGfPHr7PAODxeORyufgeA8y5556rb7/9Vrm5ud7bhAkTdN1113kf830Gpurqau3YsUNpaWk+/eeSNoNedOedd2ru3LmaMGGCJk2apIcfflg1NTW68cYbrS4NXaiurtb27du9z/Py8pSbm6v4+HhlZmbqjjvu0IMPPqhhw4YpKytLd999t9LT0zVr1izrikaHcnJy9OKLL+r1119XVFSUt08rJiZGYWFhiomJ0c0336w777xT8fHxio6O1m233aYpU6bo1FNPtbh6tDV//nzNmDFDmZmZqqqq0osvvqjly5frvffe43sMMFFRUd6+9RYRERFKSEjwHuf7DAw/+9nPNHPmTA0aNEgFBQW699575XA4dO211/r2n8senY2Aw/z1r381MjMzDafTaUyaNMlYvXq11SXhCD7++GND0mG3uXPnGoZhjue6++67jZSUFCMkJMQ499xzjS1btlhbNDrU0fcoyXj66ae976mrqzNuvfVWIy4uzggPDzdmz55tFBYWWlc0OnTTTTcZgwYNMpxOp5GUlGSce+65xvvvv+99ne8xsLUdzWUYfJ+B4uqrrzbS0tIMp9NpDBgwwLj66quN7du3e1/31fdoMwzD6Nl4DAAAAPgGPbMAAAAIWIRZAAAABCzCLAAAAAIWYRYAAAABizALAACAgEWYBQAAQMAizAIAACBgEWYBoB+x2WxaunSp1WUAQI8hzAKAj9xwww2y2WyH3S688EKrSwOAgBVkdQEA0J9ceOGFevrpp9sdCwkJsagaAAh8rMwCgA+FhIQoNTW13S0uLk6S2QKwaNEizZgxQ2FhYRoyZIheffXVdud/++23OueccxQWFqaEhATdcsstqq6ubveep556SqNHj1ZISIjS0tI0b968dq+XlpZq9uzZCg8P17Bhw/TGG294XysrK9N1112npKQkhYWFadiwYYeFbwDwJ4RZAPAjd999t6644gp9/fXXuu6663TNNddo06ZNkqSamhpdcMEFiouL0xdffKFXXnlFH3zwQbuwumjRIuXk5OiWW27Rt99+qzfeeENDhw5t9zvuv/9+fec739E333yjiy66SNddd50OHjzo/f0bN27UO++8o02bNmnRokVKTEz03R8AABwjm2EYhtVFAEB/cMMNN+j5559XaGhou+O/+tWv9Ktf/Uo2m00/+tGPtGjRIu9rp556qk455RQ99thj+uc//6lf/OIXys/PV0REhCTp7bff1syZM1VQUKCUlBQNGDBAN954ox588MEOa7DZbPr1r3+tBx54QJIZkCMjI/XOO+/owgsv1KWXXqrExEQ99dRTvfSnAAA9i55ZAPChs88+u11YlaT4+Hjv4ylTprR7bcqUKcrNzZUkbdq0SdnZ2d4gK0lTp06Vx+PRli1bZLPZVFBQoHPPPbfLGsaOHet9HBERoejoaBUXF0uSfvzjH+uKK67Ql19+qenTp2vWrFk67bTTjuuzAoAvEGYBwIciIiIO+2v/nhIWFnZU7wsODm733GazyePxSJJmzJih3bt36+2339ayZct07rnnKicnR3/4wx96vF4A6An0zAKAH1m9evVhz0eOHClJGjlypL7++mvV1NR4X//0009lt9s1fPhwRUVFafDgwfrwww+7VUNSUpLmzp2r559/Xg8//LD+8Y9/dOvnAUBvYmUWAHzI5XKpqKio3bGgoCDvRVavvPKKJkyYoNNPP10vvPCC1qxZoyeffFKSdN111+nee+/V3Llzdd9996mkpES33Xabrr/+eqWkpEiS7rvvPv3oRz9ScnKyZsyYoaqqKn366ae67bbbjqq+e+65R+PHj9fo0aPlcrn01ltvecM0APgjwiwA+NC7776rtLS0dseGDx+uzZs3SzInDSxevFi33nqr0tLS9O9//1ujRo2SJIWHh+u9997T7bffrokTJyo8PFxXXHGF/vSnP3l/1ty5c1VfX68///nP+tnPfqbExERdeeWVR12f0+nU/PnztWvXLoWFhemMM87Q4sWLe+CTA0DvYJoBAPgJm82mJUuWaNasWVaXAgABg55ZAAAABCzCLAAAAAIWPbMA4Cfo+gKAY8fKLAAAAAIWYRYAAAABizALAACAgEWYBQAAQMAizAIAACBgEWYBAAAQsAizAAAACFiEWQAAAAQswiwAAAAC1v8PmKsstLWYR44AAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_loss(history, validation=True, figsize=(8, 6))" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "image/png": "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1D83FKiiuk7du4Qos1dXs8sBAABogjCLk1q0qn6KweSRKbJaWfgFAAC8D2EWzdpWVK41eUfkZ7XouuHs+AUAALwTYRbNev3rvZKkSwbEKS4iyORqAAAAmkeYRRMHK6r19rf1vWWnnZNqbjEAAAAtIMyiide+2qOqWqcGJ0fqnN4s/AIAAN7L7TCbmpqqxx57THl5eW1RD0xWWV2n11bWTzG448Le7PgFAAC8mtth9p577tG7776rXr166dJLL9WiRYtUXV3dFrXBBG+tylPZsVr1jAnVuLMSzC4HAACgRacVZtetW6dVq1Zp4MCBuvvuu5WYmKi77rpLa9asaYsa0U5q6pz6y392S5JuP7+X/GjHBQAAvNxpz5kdNmyYnn/+eR04cEBz5szRX/7yF40cOVLp6elauHChDMPwZJ1oBx+s269Ce5Viw226emiy2eUAAACckv/pXlhbW6v33ntPr776qj799FONHj1at9xyi/bt26cHHnhA//73v/Xmm296sla0IafT0J+X75Ik3XxuTwUF+JlcEQAAwKm5HWbXrFmjV199VW+99ZasVqumTp2qZ599VgMGDHCdc/XVV2vkyJEeLRRt69+bi7SjuELhNn9NGd3d7HIAAABaxe0wO3LkSF166aV66aWXNGnSJAUEBDQ5p2fPnrr++us9UiDanmEYmv/lTknSlNE9FBHU9J4CAAB4I7fD7K5du9SjR48WzwkNDdWrr7562kWhfa3ec1hr8o4o0N+qm89NNbscAACAVnN7AVhxcbG++eabJse/+eYbffvttx4pCu3rpS92SJKuHdaNrWsBAIBPcTvMzpgxQ/n5+U2O79+/XzNmzPBIUWg/Wwrt+nxriSyW+nZcAAAAvsTtMPv9999r2LBhTY4PHTpU33//vUeKQvv585f1HQyuODtRPWNCTa4GAADAPW6HWZvNpqKioibHCwoK5O9/2p2+YIL8Q0f14foDkqRfXNDb5GoAAADc53aYveyyyzRr1iyVlZW5jh05ckQPPPCALr30Uo8Wh7a1YMVuOZyGzusTo8HdIs0uBwAAwG1uD6X+4Q9/0Pnnn68ePXpo6NChkqR169YpPj5ef//73z1eINrGocoaLVqdJ4lRWQAA4LvcDrPJycnasGGD3njjDa1fv17BwcGaPn26brjhhmZ7zsI7/fWrPaqqders5Aid26er2eUA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9OWXX5pdFtyUn5+vmTNn6tNPP1VQUJDZ5eAMjB8/3vXnIUOGKCMjQz169NDbb7+t4ODgdquDaQZtJCYmRn5+fk1W7RUVFSkhIcGkqnCmGu4d99W33HXXXfrnP/+pzz//XN26dXMdT0hIUE1NjY4cOdLofO6ndwoMDFSfPn00fPhwZWdnKy0tTc899xz30cfk5uaquLhYw4YNk7+/v/z9/fXll1/q+eefl7+/v+Lj47mfPioqKkr9+vXTjh072vXnkjDbRgIDAzV8+HDl5OS4jjmdTuXk5CgzM9PEynAmevbsqYSEhEb31W6365tvvuG+eiHDMHTXXXfpvffe02effaaePXs2en748OEKCAhodD+3bt2qvLw87qcPcDqdqq6u5j76mEsuuUQbN27UunXrXI8RI0ZoypQprj9zP31TRUWFdu7cqcTExHb9uWSaQRvKysrStGnTNGLECI0aNUpz585VZWWlpk+fbnZpaEFFRYV27Njh+nr37t1at26dunTpou7du+uee+7Rb3/7W/Xt21c9e/bUww8/rKSkJE2aNMm8otGsGTNm6M0339QHH3yg8PBw1zytyMhIBQcHKzIyUrfccouysrLUpUsXRURE6O6771ZmZqZGjx5tcvU40axZszR+/Hh1795d5eXlevPNN/XFF1/ok08+4T76mPDwcNe89QahoaHq2rWr6zj30zfce++9mjhxonr06KEDBw5ozpw58vPz0w033NC+P5ce7Y2AJl544QWje/fuRmBgoDFq1Cjj66+/NrsknMLnn39uSGrymDZtmmEY9e25Hn74YSM+Pt6w2WzGJZdcYmzdutXcotGs5u6jJOPVV191nXPs2DHjzjvvNKKjo42QkBDj6quvNgoKCswrGs26+eabjR49ehiBgYFGbGyscckllxj/+te/XM9zH33bia25DIP76SsmT55sJCYmGoGBgUZycrIxefJkY8eOHa7n2+s+WgzDMDwbjwEAAID2wZxZAAAA+CzCLAAAAHwWYRYAAAA+izALAAAAn0WYBQAAgM8izAIAAMBnEWYBAADgswizANCJWCwWvf/++2aXAQAeQ5gFgHbys5/9TBaLpcnj8ssvN7s0APBZ/mYXAACdyeWXX65XX3210TGbzWZSNQDg+xiZBYB2ZLPZlJCQ0OgRHR0tqX4KwEsvvaTx48crODhYvXr10jvvvNPo+o0bN+riiy9WcHCwunbtqttvv10VFRWNzlm4cKHOOuss2Ww2JSYm6q677mr0fGlpqa6++mqFhISob9+++vDDD13PHT58WFOmTFFsbKyCg4PVt2/fJuEbALwJYRYAvMjDDz+sa6+9VuvXr9eUKVN0/fXXa/PmzZKkyspKjRs3TtHR0Vq9erWWLFmif//7343C6ksvvaQZM2bo9ttv18aNG/Xhhx+qT58+jV7j0Ucf1U9+8hNt2LBBV1xxhaZMmaJDhw65Xv/777/Xxx9/rM2bN+ull15STExM+/0FAICbLIZhGGYXAQCdwc9+9jO9/vrrCgoKanT8gQce0AMPPCCLxaJf/OIXeumll1zPjR49WsOGDdOf/vQnvfLKK7rvvvuUn5+v0NBQSdLSpUs1ceJEHThwQPHx8UpOTtb06dP129/+ttkaLBaLHnroIT3++OOS6gNyWFiYPv74Y11++eW68sorFRMTo4ULF7bR3wIAeBZzZgGgHV100UWNwqokdenSxfXnzMzMRs9lZmZq3bp1kqTNmzcrLS3NFWQl6dxzz5XT6dTWrVtlsVh04MABXXLJJS3WMGTIENefQ0NDFRERoeLiYknSHXfcoWuvvVZr1qzRZZddpkmTJumcc845rfcKAO2BMAsA7Sg0NLTJx/6eEhwc3KrzAgICGn1tsVjkdDolSePHj9fevXu1dOlSffrpp7rkkks0Y8YM/eEPf/B4vQDgCcyZBQAv8vXXXzf5euDAgZKkgQMHav369aqsrHQ9/9///ldWq1X9+/dXeHi4UlNTlZOTc0Y1xMbGatq0aXr99dc1d+5cvfzyy2f0/QCgLTEyCwDtqLq6WoWFhY2O+fv7uxZZLVmyRCNGjNB5552nN954Q6tWrdKCBQskSVOmTNGcOXM0bdo0PfLIIyopKdHdd9+tm266SfHx8ZKkRx55RL/4xS8UFxen8ePHq7y8XP/973919913t6q+2bNna/jw4TrrrLNUXV2tf/7zn64wDQDeiDALAO1o2bJlSkxMbHSsf//+2rJli6T6TgOLFi3SnXfeqcTERL311lsaNGiQJCkkJESffPKJZs6cqZEjRyokJETXXnutnnnmGdf3mjZtmqqqqvTss8/q3nvvVUxMjH784x+3ur7AwEDNmjVLe/bsUXBwsMaMGaNFixZ54J0DQNugmwEAeAmLxaL33ntPkyZNMrsUAPAZzJkFAACAzyLMAgAAwGcxZxYAvASzvgDAfYzMAgAAwGcRZgEAAOCzCLMAAADwWYRZAAAA+CzCLAAAAHwWYRYAAAA+izALAAAAn0WYBQAAgM8izAIAAMBn/X+jjtVWBRiBugAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_accuracy(history, figsize=(8, 6))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Save model**" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "model.save(\n", " \"model\", \"/tmp\", tn=True\n", ") # tn=True because MPS for classification if TensorNetwork object" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Evaluate**\n", "\n", "Calculate accuracy of the classification" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9369860197368421" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.accuracy(\n", " test_data,\n", " y_test,\n", " embedding=embedding,\n", " batch_size=16 if os.environ.get(\"CI\") else 512,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Retrain with exponential decay" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "# Exponential decay of the learning rate.\n", "scheduler = optax.exponential_decay(\n", " init_value=1e-3, transition_steps=1000, decay_rate=0.01\n", ")\n", "\n", "# Combining gradient transforms using `optax.chain`.\n", "gradient_transforms = [\n", " optax.clip_by_global_norm(1.0), # Clip by the gradient by the global norm.\n", " optax.scale_by_adam(), # Use the updates from adam.\n", " optax.scale_by_schedule(scheduler), # Use the learning rate from the scheduler.\n", " # Scale updates by -1 since optax.apply_updates is additive and we want to descend on the loss.\n", " optax.scale(-1.0),\n", "]" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "model.configure(\n", " gradient_transforms=gradient_transforms,\n", " strategy=strategy,\n", " loss=loss,\n", " train_type=train_type,\n", " learning_rate=learning_rate,\n", ")" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "epochs = 1 if os.environ.get(\"CI\") else 50\n", "batch_size = 16 if os.environ.get(\"CI\") else 1000" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "epoch: 100%|██████████ 50/50 , loss=1.4502, val_loss=1.5027, val_acc=0.9360\n" ] } ], "source": [ "history = model.train(\n", " train_inputs,\n", " targets=train_targets,\n", " val_inputs=val_inputs,\n", " val_targets=val_targets,\n", " epochs=epochs,\n", " batch_size=batch_size,\n", " canonize=(True, index_class),\n", " embedding=embedding,\n", " normalize=True,\n", " display_val_acc=True,\n", " eval_metric=cross_entropy_loss,\n", " val_batch_size=batch_size,\n", " dtype=jnp.float64,\n", ")" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9459" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.accuracy(\n", " test_data,\n", " y_test,\n", " embedding=embedding,\n", " batch_size=16 if os.environ.get(\"CI\") else 1000,\n", ")" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 2 }