diff --git a/notebooks/NamedTensor.ipynb b/notebooks/NamedTensor.ipynb
index f45a79d..e48aadc 100644
--- a/notebooks/NamedTensor.ipynb
+++ b/notebooks/NamedTensor.ipynb
@@ -1,1897 +1,1957 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "ZskQMOXCDP9O"
- },
- "source": [
- "*Alexander Rush* - @harvardnlp"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "XSVljWusuNti"
- },
- "source": [
- "\n",
- " \n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "dnuYLZwvDYVP"
- },
- "source": [
- "\n",
- "TL;DR: Despite its ubiquity in deep learning, Tensor is broken. It forces bad habits such as exposing private dimensions, broadcasting based on absolute position, and keeping type information in documentation. This post presents a proof-of-concept of an alternative approach, **named tensors**, with named dimensions. This change eliminates the need for indexing, dim arguments, einsum-style unpacking, and documentation-based coding. The prototype **PyTorch library** accompanying this blog post is available as [namedtensor](https://github.com/harvardnlp/NamedTensor).\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "Ae7BMj9HAUmD"
- },
- "source": [
- "* Table of Contents \n",
- "{:toc} "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "2GEkZv2b7eDs"
- },
- "source": [
- "*Changelog*\n",
- "* Updated the syntax of the prototype to be a subest of xarray whereever possible. \n",
- "* Dropped the einops style string DSL notation to be more explicit. \n",
- "\n",
- "*Implementations* \n",
- "* Jon Malmaud points out that the [xarray](http://xarray.pydata.org/en/stable/) project has very similar goals as this note with the addition of extensive Pandas and scientific computing support. \n",
- "* Tongfei Chen's [Nexus](https://github.com/ctongfei/nexus) project proposes statically type-safe tensors in Scala. \n",
- "* Stephan Hoyer and Eric Christiansen have a labeled tensor library for Tensorflow that is the same as this appraoch. [Labed Tensor](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/labeled_tensor)\n",
- "* Nishant Sinha has a [TSA library](https://towardsdatascience.com/introducing-tensor-shape-annotation-library-tsalib-963b5b13c35b) that uses type annotations to define dimension names."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "cellView": "both",
- "colab": {},
- "colab_type": "code",
- "id": "wd9yuKJ2Hhdj"
- },
- "outputs": [],
- "source": [
- "#@title Setup\n",
- "#!rm -fr NamedTensor/; git clone -q https://github.com/harvardnlp/NamedTensor.git\n",
- "#!cd NamedTensor; pip install -q .; pip install -q torch numpy opt_einsum"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "colab": {},
- "colab_type": "code",
- "id": "7b48OTgB7gso"
- },
- "outputs": [],
- "source": [
- "\n",
- "import numpy \n",
- "import torch\n",
- "from namedtensor import NamedTensor, ntorch\n",
- "from namedtensor import _im_init\n",
- "_im_init()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "X1XnmQLgDeHy"
- },
- "source": [
- "# Tensor Traps\n",
- "\n",
- "\n",
- "This post is about the tensor class, a multi-dimensional array object that is the central object of deep learning frameworks such as Torch, TensorFlow and Chainer, as well as numpy. Tensors carry around a blob of storage and expose a tuple of dimension information to users."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "9LZarsn5HgUa",
- "outputId": "747daa9e-5fab-4c92-fb6b-2f2d29a987ed"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "torch.Size([6, 96, 96, 3])"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "ims = torch.tensor(numpy.load('test_images.npy'))\n",
- "ims.shape"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "_A4CksffJ5sT"
- },
- "source": [
- "Here there are 4 dimensions, corresponding to *batch_size*, *height*, *width*, and *channels*. Most of the time you can figure this out by some comment in the code that looks like this: "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "euWWfx_yKh85",
- "outputId": "23b7c7a6-87e2-4256-f1ad-8e4dabea4b72"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# batch_size x height x width x channels\n",
- "ims[0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "oec2Ah5eRgEp"
- },
- "source": [
- "This approch is concise and pseudo-mathy. However from a programming point of view it is not a great way to build complex software."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "ampMvKRpHYvv"
- },
- "source": [
- "\n",
- "## Trap 1: Privacy by Convention\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "tFP--oUNnb8V"
- },
- "source": [
- "\n",
- "\n",
- "Code that manipulates tensors does so by dimension identifiers in the tuple. If you want to rotate the image you read the comment, decide what dimensions need to be changed and alter them. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "JuYMwAFtLBcl",
- "outputId": "35ba6c2e-d0a1-4696-a2dd-2f8506b509fe"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "def rotate(ims):\n",
- " # batch_size x height x width x channels\n",
- " rotated = ims.transpose(1, 2)\n",
- " \n",
- " # batch_size x width x height x channels\n",
- " return rotated\n",
- "rotate(ims)[0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "gjjCOsyBLvtV"
- },
- "source": [
- "This code is simple and in theory well documented. However, it does not reflect the semantics of the target function. The property of rotation is independent of the batch, or for that matter, the channels. The function should not have to account for these dimensions in determining the dimensions to alter. \n",
- "\n",
- "This leads to two problems. FIrst, it's quite worrisome that if we pass in a singleton image this function runs fine but fails to work. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "bnh57z49L9Lu",
- "outputId": "1456af26-07bf-4f4d-fe00-650dc6d3329d"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "torch.Size([96, 3, 96])"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "rotate(ims[0]).shape"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "tqw1mFdDk2Fi"
- },
- "source": [
- "However, even more worrisome is that the function may actually use the batch dimensions by mistake and mix together properties of different images. This can lead to nasty bugs that would be easy to avoid if this dimension was hidden from the code. "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "1DV0yQ09L7AR"
- },
- "source": [
- "## Trap 2: Broadcasting by Alignment\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "p9LuwkU9naX_"
- },
- "source": [
- "\n",
- "The most useful aspect of Tensors is that they can quickly do array operations without directly requiring for loops. For this to work dimensions need to be directly aligned so that they can be broadcasts. Again this is done by convention and code documentation that makes it \"easy\" to line up dimensions. For instance, let's assume we want to apply a mask to the above image. \n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "Sp0TsC0yOBxr",
- "outputId": "c4545451-c659-45da-db08-4f69c3fbe38e"
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAAAAADH8yjkAAAIBklEQVR4nG1Z2ZLkNgwDXf3/v4w8kDg02dnKTLdtSTwAkHQAkiSI++H+4v4liP1MUg/c8wR2HfVJ17UWtSnB+rOn6kMt5x1ObYu7v/vYUlnNGLQP3qY+SFtTzsm3WEtZ6G0fe38ghgCGAwzAacfu74ADDoEhhkMMBqND544Y7I3abz6UnTJyzqrbxLGfmXVlRjnAgLsX524Qs4YSAH9rHcjd6xwYWcwZzO6+R+guiHXG1nDO1FwC8CniA4dz7pQ17HzbAF7QL0BziRqcGYPBzK2fMZJIXHoCGSOtkGIoFYiNTtQKAZmXsYuKY4NN12ZhvTsfcSnePG/aL7t6lJi6MB+ImZkBZhwdPbZrJpkfBY+ChtLp7S92swG8XON2tRdcYK4RZ6ihCgHD/p9bZx/zCfOjQQExQdgXRhNGk4QDztz3i5lwCC1UbC0s/Z9T5xyH5C04fcmPMU/b3oiM88+C0yLE0fQnI08uvkgC+S1YL3YHbSEGw+PXXQt/fNQE7rez0joCyJlrIS3hYElZy2N8CnlqSVhB/qRlkjLD5RRHXE3qIjSAyKLHD7KXaIlgYtf5Rhl39NVV2WpSP8VDyd/vH4d8LJLFHMzKolMaaU14JTuTLDEhAL4lAHkaIabEdKettFrSdsGpmIUKy6Q5Eg2lRbpfgBn2ZSYXzhggCSrR2s+/7C9CS/dUQ2ye+Hw0P1SPhcG2n7ns0xFzOPoHyedpU3kFCxu0wGqWzRKyrBMMthGA5CKAsZYgn57CIfzsr0kMLOX7F7bqNfg0NQooDBhUF3Ql9ul1IOB09yNT9SMaPwpZrjRvigBr+LRD1n+lLt3AqEnZHOBPGgLYioIKTGF2ccAnNIGoEKyDcR2MHhAwItuKC+zogwERj4mLe7mgJADoRs8XtEXLa0L+P7z9OZP+4oR+ALfxGqhNWyWQLh4UXGUN5CFXY7Ci5cCPmiwqZQdKCbceTKwFRLqtYWCqRuZhrn++9XHEOx6UXdiq9htEF5fcgjVxF4+XDcQCVLJEg7Rw6QGp5PP9ozy517tdfyPGjZNm1D3B3xLLPDnVVu8F96+VqJ9F+jDNLfVXLhLswgB0uJxNk2mNvV3TerMC49IeGlTwCoOqoZY3ob14kAo+NsD9IGyYXRHuYMAIzlEORcOM6zzKhQqAMiwa2WcxtSloMGj1Bwxd6NNVat2yrrRgtNGq2PiKzNvI7aYDfFZuR31pOdiuzcm8NAMwMasJGUnBAKMBkCQ+7obC0ZoxrkC6M07r6CTqxjxtmAavc/Bbn66FnIrEyK3RLvtPaZiLHcQCCsgokyp2fBFpQP6BaOk0rL1P2xoQOOUwDALvQpR0oEljWNmu2ts1H//YNn6xi0AwWCXZmNGjgXg2rsdtkV16Zw7WsGHqSwD+EdMEp24oDbWnH6iDHSK70byrnAKP3TapUxWOa3VRNx6+UbQieGD4fyGrRgXuD6JZ5qdKULbpLiTn/5GSFqPKWaCQAJVjrcoJBQtFVCa1swNYyA9hlJmnrpVx4E9vbXBs1HsfWGiwM7ZHOQ0B1XxtWEoz6A4w7fbFjh11lzOmpVFe9D5EOat6UorRua0JMSMI3gKkrludeAzDWZoC78ZGOahsh0qV8U50slPYENCLN3TsEwS0kUJg5gi/aEHQmYGuZoaLyQdyrrgoc12i7i1Rys6CZgSzqyVbvlSSZsb0/0KSfSNxxrhpR4Fgd5v6u36TM8W9MWxB/A4vd4I7nHEBgWCE5G5NUa5lmCpiDzGx8hlvp5AmKD7V3XMafMu68Rbun3cFXXnPKIMx++f12jmdsVHsEC00B1sVA0mPJo3WUo5WzqC21EQAB8BfAtKMufJPFH4EvxtQ1kWjLT5dCxNchIR+3EQA7Os0sGAsJCCBeOZCJjuV7p65JUliGr23FQqdJ53Fgph4Jzn1Eh1T8Iku1pd+YxOin7E/uB9T3799oAR+gx7NCJppZCmQmhelocQ2vwei0SSucXuEK7903YlrtUXvjUQC3jw0ehe/7aF00UhJ66Av1tyopAdiVMksQUYe+92wSCEKsZ+uWs7mU+KPR1RvfW9Zp5OJD/5fCxqOLMTn8wWV416diINHiMFIZ+EJb8K/dLIGOp/QuRfoKJjkWePI6VODNSXyyCkYqRsQE1Ia3Qe94O0uXlvqiODOxd9EaL5lzBNum+dmMR7bjeAqeacSPgkqE0WtllQJy4bsfR0ZvExds2KjgnIH/nk1MnFNMqBC73DL8Dglb4WtDrn7HcveuC7eDspVLXmkbezcO4V13akA/E2ZwxJOoktMvgj36spF3DT1+FNtrtf94FJKd5cZUerNgoJ9lVyupwg/NnliDcqdPTacWkZdN9QHd9ieecAdyfC7CXi/riMxWII6g5nViqmIGdQE5dsE6hhgfn5atWXoljl3aEfcWbwthlDSND2DJa4aKCIoTgTzAHTJ4170KgJV3fEPtGIW1Ir1bGYoc3O6qRImCm9HaMqal6aJlcSNwhOADknIaArmZafjBMNQqle6Z6+6D/aIw1CuvqnLCaglhLSBnbjgTp1PqnuGCiVmPE2kZw+r3Cx29Lv2Fv2KT864qfa8gPAummLrl3YV0G2EsFaLjZqawP485QlLxxqX6YO1Lhr1pxGWQ0wT4maBCdwRJrJgtzIQpJ0r6BjkAnC6kJ4Cn3Sj9rqD9Oo07YfPzmgT4D1pDYuZsOFx29lLMmpRsfhi+FNdgQd/xyros+1/J6WDokaF28EcAPAfyzkLX3G5obsAAAAASUVORK5CYII=\n",
- "text/plain": []
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# height x width\n",
- "mask = torch.randint(0, 2, [96, 96]).byte()\n",
- "mask"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "cO9IWw46O33Z",
- "outputId": "e8993083-0126-40fd-e294-b03a89aa05ed"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'Broadcasting fail torch.Size([96, 96]) torch.Size([6, 96, 96, 3])'"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "try:\n",
- " ims.masked_fill(mask, 0)\n",
- "except RuntimeError:\n",
- " error = \"Broadcasting fail %s %s\"%(mask.shape, ims.shape)\n",
- "error"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "9BsD5FpGQMqv"
- },
- "source": [
- "This fails because even though we knew that we were building a *height* and *width* shaped mask, the rules of broadcasting do not have the correct semantics. To make this work, you are encouraged to use either `view` or `squeeze` my least favorite functions. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "AYso46ojPfuQ",
- "outputId": "9a533e09-fbda-4364-c736-bec10dbb28d1"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# either \n",
- "mask = mask.unsqueeze(-1)\n",
- "# or \n",
- "mask = mask.view(96, 96, 1)\n",
- "\n",
- "# height x width x channels\n",
- "ims.masked_fill(mask, 1)[0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "Whz5pqd_SRXH"
- },
- "source": [
- "Note we do not need to do this for the left-most dimensions so there is a bit of abstraction here. However reading through real code, dozens of right side `view`s and `squeeze`s become completely unreadable."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "5UyG7El7Snbi"
- },
- "source": [
- "## Trap 3: Access by Comments\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "9LWcPiviTwWc"
- },
- "source": [
- "It is possible that you look at the top two issues and think that as long as you are careful, these issues will be caught by run time errors. \n",
- "However, even well used the combination of broadcasting and indexing can lead to problems that are very tough to catch. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "HfkPrgC1TPWh",
- "outputId": "3eaf3337-a1f2-4b5c-90a5-e90c272f397e"
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAIAAABt+uBvAAADuklEQVR4nO3cz0vbYBjA8SRNtVUril1X+gNatCIqS8EhIkPHcGPSi4oibLA/QMH/wqO3gQcRdpvM4nXgZIdZN1DQSQUdMnKw1R2GumitbUy7g3MI0zxvJHnfDJ7PUd/mffhSNY0kfLlc5tDtBNYD2J3IbOfT0y+pVDabLRQK97xeKR6/39zMbJjb8fR/xH7K8ru5OUEQHA6HQxD4KxzPh0OhJ0NDlOfRRzvQ+/n59OZmldstiuK/gXiOczgcL8fHaY6kj+rvoJ21tdXVVf01mqa9nZ6mMw8JqoGSySTJMlVVt1Ipq4chRC/Q/s4O+eL19XXrJjGEXqBPy8vU9jIRvUCZTMbYC3I5awYxhl4gVVUNrc8dH1sziDH0AomisZPS6tpaiyYxhF6gQCBg7AUejzWDGEMvUG9PD7W9TEQvUKi1lXyxJEnWTWII1RPFwcFBkmWiKEq9vVYPQ4hqoLaurocdHfprBEF4MTZGZx4SDD7N/9jdXUgmb/w0HwwE+oaHKc+jj0GgPxTl88rKfjZ7fnk9SJL8LS1sJtHFLtB/Ai+5AjAQAAMBMBAAAwHM/LfP16WlX4pyenaWz+cLxWKhWCwWi+rFFU3TNE0rldyVlToX7a97NTFh4nh3g+8gAAYCYCAABgJgIAAGAmAgAAYCYCAABgKY+VEj3tdHuPL15KSJ+1oK30EADATAQAAMBMBAAAwEwEAADATAQAAMBMBAAAwEwEAADATAQAAMBMBAAAwEwEAADATAQAA2gWrscScPCTaB6uvqmOx7B2wC+f1+kmVpG9z7zCZQOBwmWbZhg3uf2QQKNDYSrtzf3rZ0EhCjv2IVFYQLPywucicnls6ij93TX4i9mZ2NRCKPBwZu/raqftvY2Eqn3S5XQ329z+uNdnaauDuzQJFIZG9vj3CxLMvfp6YuNO28UCiXywLP84Ig8LwgCJf3nVU4nW6Xi+M4xey3G7MTxef9/ay2NoTdmbQ9bosHsfyo0d3dzXB3QiwDtWEg0OjoqOnHPDTyHB4Q40DVwWDM7Ge7HR4dmXg09pc7HiUSwWCQ9RS3Yh+I47inIyNSPG7W0SqcTrMOxdnttvD5mZl8Pn/9K+UrpVJJ/0TR29DwoL09ZPZDP+wV6NLHhYW/j6siCRSNRp8lElxVlRXD2DHQX/mDA1mWM5mMoii5XE4rlZxOZ43H4/P5YrGYr6mJwgy2DmQHtvglbWcYCICBABgIgIEAGAiAgQAYCICBABgIgIEAGAiAgQAYCICBABgIgIEAGAjwG07fGJpVBe+AAAAAAElFTkSuQmCC\n",
- "text/plain": []
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "\n",
- "a = ims[1].mean(2, keepdim=True)\n",
- "# height x width x 1\n",
- "\n",
- "# (Lots of code in between)\n",
- "# .......................\n",
- "\n",
- "# Code comment explaining what should be happening.\n",
- "dim = 1\n",
- "b = a + ims.mean(dim, keepdim=True)[0]\n",
- "\n",
- "\n",
- "# (Or maybe should be a 2? or a 0?)\n",
- "index = 2\n",
- "b = a + ims.mean(dim, keepdim=True)[0]\n",
- "b"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "P4WyEXyYVFGp"
- },
- "source": [
- "Here we assume that the coder is trying to combine two tensor using both reduction operations and dimension indexing. (Honestly at this point I have forgotten what the dimensions stand for). \n",
- "\n",
- "The main point though is that this code will run fine for whatever value dim is given. The comment here might descibe what is happening but the code itself doesn't throw a run time error. "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "b9gDFB-WV9_h"
- },
- "source": [
- "# Named Tensor: A Prototype"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "khfYKuBcWPMz"
- },
- "source": [
- "Based on these issues, I think deep learning code should move to a better central object. There are several of these proposed. Here for fun, I will develop a new prototype. I have the following goals. \n",
- "\n",
- "*1) Dimensions should have human-readable names.*\n",
- "\n",
- "*2) No function should have a dim argument.*\n",
- "\n",
- "*3) Broadcast should be by name matching.*\n",
- "\n",
- "*4) Transposition should be explicit.*\n",
- "\n",
- "*5) Ban dimension based indexing.*\n",
- "\n",
- "*6) Private dimensions should be protected.*\n",
- "\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "cmFZCfgZYm3i"
- },
- "source": [
- "\n",
- "\n",
- "To experiment with these ideas I have built a library known as `NamedTensor`. Currently it is PyTorch specific, but in theory a similar idea could be used in other frameworks. The code is available at [github.com/harvardnlp/namedtensor](https://github.com/harvardnlp/namedtensor). "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "SYth2yPxZobO"
- },
- "source": [
- "## Proposal 1: Assigning Names"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "0177b_0vZ303"
- },
- "source": [
- "The core of the library is an object that wraps a tensor and provides names for each dimension. Here we simply wrap a given torch tensor with dimension names."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "sLnQA8VOZsEx",
- "outputId": "2691d54b-389c-4155-c7b2-54696cd603e7"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "OrderedDict([('batch', 6), ('height', 96), ('width', 96), ('channels', 3)])"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "named_ims = NamedTensor(ims, (\"batch\", \"height\", \"width\", \"channels\"))\n",
- "named_ims.shape"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "eLjL4O7_ZiyW"
- },
- "source": [
- "Alternatively the library has wrappers for the pytorch constructors to turn them into named tensors. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "eiYe47t6aRnd",
- "outputId": "b25c559e-9ed9-4661-c27b-13e0847e4dfa"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "ex = ntorch.randn(dict(height=96, width=96, channels=3))\n",
- "ex"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "lNgHsAmDbxMc"
- },
- "source": [
- "Most simple operations simply keep around the named tensor properties. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "colab": {},
- "colab_type": "code",
- "id": "T-wGpWZAb4AL"
- },
- "outputs": [],
- "source": [
- "ex.log()\n",
- "\n",
- "# or \n",
- "\n",
- "ntorch.log(ex)\n",
- "\n",
- "None"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "GfVktrThcIF2"
- },
- "source": [
- "## Proposal 2: Accessors and Reduction"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "iNCJcWeccTZW"
- },
- "source": [
- "The first benefit of names comes from the ability to replace the need for dim and axis style arguments entirely. For example, lets say we wanted to sort each column. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "-HdhRVfqcyd2",
- "outputId": "d5b13a77-a81f-4433-98a4-f55e7a22d2bd"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "sortex, _ = ex.sort(\"width\")\n",
- "sortex"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "JRljeAlweL7X"
- },
- "source": [
- "Another common operation is a *reduction* where one or more dimensions is pooled out. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "6Rji52BmemX9",
- "outputId": "cf3d7322-7d7b-46be-bd7a-ab49aebb71a1"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "named_ims.mean(\"batch\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "5Ky7Q3Kge8Mh",
- "outputId": "93734d7d-319d-4e13-bbb8-4d3aba2c55ae"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "named_ims.mean((\"batch\", \"channels\"))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "m88W0sfufEq1"
- },
- "source": [
- "## Proposal 3: Broadcasting and Contraction\n",
- "\n",
- "The names that are provided also provide the basis for broadcasting operations. When there is a binary operations between two named tensors they first ensure that all dimension are matched in name and then apply standard broadcasting. To demonstrate let's return to the masking example above. Here we simply declare the names of the dimensions of our mask, and ask the library to figure out the broadcasting. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "ffjF33e4fhLs",
- "outputId": "1f1eadce-bf24-46a7-d35d-0b8840fa673d"
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAIAAABt+uBvAAAPjklEQVR4nI1cXahdxRVe59xjfjR/xkvMNlSoQgqRBOGiYBEUqQUDDTQPxmoKbRBR8NIHQRLSh0IJ/jwXSvGlUlAUifggtJQGTKrEB/OQQm9MNIaoZyNtb/5oK6Q504d999w13/etuWcIh31m1qxZ65v1N7NPrqWujcdLn92Df/afnphpoIeH5FdJL4m5gVT8Ty7EAoDirg1SSta21jTWtbY1M2ua4iGP+tb1d2TQmJun99zkdM9HruL5gPDymVdnhgHZcIm0bYs5+TmPQicwygs0zVK/h8ZrBXyAwP/zlMzHo5bZApReNS8ni+2b59M0gzQe40zYnIqN1HevYpgAGW+1n2VVk4m4SQuyAHQgcEO9i4HyXsPIVo1gBQjYmEGCFfVnFJjeaCPlHksJJSvfb9ZbEEwAlVjKaTaZw1mFD3MzBZYFW11HRBJPA3HbDoWU5sJBFlq6ayS3ZyJhyp8c44AJBL4oOPrAx9yMTNsjAvQl5XB5gShief09alICacZSaCmflVsNImUBpKpZNhnmAWjgL03EzMyGghekDKm/9Bc/pZIveMdAN4bMyAQyJZgDQFAREvQF6PPcWuEnv0aVXtSiWVCV1atKEE/OlfQwCzRlyWnKEHeJQWXrMCs2zTsdbD7MgibdUE5howBP9EvnfxWzAl2stFM3NDRuUThk42dxYQHQPCLzAW4alNlhYUfZX6SnezGCOOPSPLt0pKc5H+YQIIOoR4cZsvNDg93mflabCaScUl8n8zCcnzthP/0ugRA85Jlk62As/DbCP26+X4ZzT8PG6CUEc2bdl9K87+JpwNocat7pQGiZxSQHgJVzf8Xu8kPeA5kEeUfZEhmjpjGzUSGWVJIDs9xAaa7sGuDqAHRDZY7XUOLllwY4vNlG0JiJHrfEqOhlRqC2EdhsFNw4psoVYYoMZL4/muuxhumwf+AirOwSQOwmMAGeZQg3C0EEpCIspAvUBfBDbDhSHQ8iiwGu3baDlBLOl8r7ZcxwpYoovkfiJdOHkWf5KawhIxKxklECODs+w4IIVLIgi0WNY0db1mx5kz0B6wn9jUpn0ZbIYAfhX+LuRXWjvQVJq6kEHbYjGVC5MVlktuxTwKdiy9JUQaNI/lLOIfICJ5Q5BVbNE73RcaDx3MDgYWnfA7O89TWNgIOhiWgqVuynhO8A5ClOngklQXRA5bcISZ145RuO+tmVT5sVjeqHVfcwWoaNsfSQe4uIwlBk2JGDeLuQjb07WqKyOsjPpudDpH/oWmgysNvyqqHyDit6z1Xy+eDo0fy8ZXb25rVrZ2Zm1t1yS0ppx/btKaX5Awf0tq/0Pku/CKubKjAZj1NKJuawKBXuFaRY6JTSeDz5+uuU0lN796aUzCx/wtfc6Z/PfvhhqHPlZkpubUUvN2WE5Zb0Ag7kbNvsnlT7TCaT4bZt92zfvnDuXEppMBjkocHAVWRBGwwGw+Hwxo0bhfMaHYbBm7j2Acm5RHKf/aW9TAS5bPGfnPKbsoo1ncg+PnXq/t27B4PB38+eBUQAGm9EgOCNGzfMbNWqVYfm57+9cGF5IakC51mplKz18vM0147aSlPg54r41y++mAKvgR6ApkIjWiVCAU3kdOSAJoZZYVhe9kvJxuN/f/45K2kUa9iCoCcFoerMiROFkok2iXeRIQPJnQpW0FWx1NBUOlNaXFh4YG5O6h/hBQ8ME0zftnXr+ZMnUU+GQ/YTHIEFTZmDInYsRN8evP9+tgIwE8YiAiuV5gYcsLFsEiw2tFJT9erZt0q0M7pqMeOs0aWqThmftuqd1kfl/JlHPcNM+cz+/b979VUsKfnIbkFtGRWcTaPei1X8K9oQ9cA6y56URNDNQ5V+K23qr++9p0WVMiey98Di3GE1Q145Z8OdgOma6Mxnn1nsU+ZyPHR2Lc/tnv1npmTE5w8fNm58p8H9cMsBp27hjQCwjMS+RwUmxoX3PPd7i2D6aMik9UkLYhdhvYKE495qgJlA9SWvJmCu/+wV6IwluWgC6GzcsOHAE0+Y2cLx42Z2/eLFjv6d1177+b59t27cOI0FZdNDIfnyxMpACacIuHJZjkFRNcTBSEYc929u1y62IG8m/uvB55/XO99/XVxYeOHZZ4fDYSI7snosizI3CayNqEjzDI2SVaCj6CNQQKX169ZpTbhzPE4prVm9GhCx0gG7nq5k1xEDwJLqEFl55QqfuXGnvGl0ed3Dkd0qe9lgMJhMJmjbfPVXpgLvnj79A2q6NLGgOrEgXPRD9OrZz+djMS/g+q98+mm3zxIdr8lkMtHHYy8l3OG17Q8fesinOXMWlOPUzMzMlatXl3hGgZJP9nBp55N1zczYIKMyun8GNcH+Q5uHFvj7n996C3oscDrhrRxJ6k7XDw3RwvlKyF++yAujPvI/tXevBMUnMrQUv2lWpg+yoB88/vj6deu6b50pAc/iK1slNHkJy9cmofl4+JkgQl01o3Sjl4hWLLfUyvDPPfv27CmWrwdsVqp8KF8cTnN/HmzON6dPg4HIyiVBTvDMoaKFaqVtzezxPXskf3M2tXDuHFZAlZwjlXL3Z+UPqMylAI5kRrmmJKhklujImlxWyj2ZWM5KdHaFKbfdeus/Fxe1LgwZq+NnLb16zsp7uuhYDzHCrZrKbOXPVoAUkJnzFEbHwyEdNhN0D4uXL1+/eBGB8GLnBkaUO51Swc9fLA5yQGbLWwTBmPX3BZFRfZTKg0jqK6akrvcBOL/QYDD4x+LiHTfdBOIVenFSCjyjv7RndHxgB8ikiZUqmTsfcTDynpW19VhEsHpjkcRdu+PeewvJfEKE+s7KIxuNjgpSmCatkTEqa2iIPuYiRQbCSteQs3wDvBgdzzOl9Ldjx3Y+8ghykUYgDw/O6Mq3UZXawUcfxe6n8/N/eOcdC8Jt1tMvN1C3hewvMCrpmTlqBIWykWcAQb/3wc9fOCTDqspjswKgKutWgUMqLIOa5LZMydB4Y5HYKWsqf7xQOTcCdp51CVOUjzgfe65sWTCaPavijJn56WPHdrGLmYseFpiMkTXI8lEfuJI6v/T9v3j6aZ+AQHPPg/slZUQmG68SKhKdPWG0b6NlzCCymDOWaMihPrt5M7iVVU9M7IMmPUUBkRs4aW5ffvLJd+bminLZKIz0kguNnKbDwhU51flCK6qh29ba9pevvOI1BwhMuR5oDiACaj7BQ/XAZcTmTZtQ7XoYhSE/BU2Rza9+Fu1Hj7/7rkfBq8qf4UUnO4X8Gt1a1F2GJ0a3HHijCIXmiqFalQ+Lly/ftmOHB8XiTIRrRV+NihejfGLB5SHko0qq4sLFr7XyPsiLDjVl+113gQV1I4CaXgh2Mgqu9f66aVQUjHUsD6tWvkXjvY1Gzaxpvn/ffb6KS3EkEjU6W4G0CLnhfH6W3IAJnD/kyQH/tw8sA7xkqLNlL/jRo48ml7xMpaEV5JaLVnw8Y7Gix0lW8lBZokb3QaC8XA806du3Fy5s2bnz6rVrETrevvRaIDqk3ihQ8lB0EogCayVghYGmEn3qfj7FK+P89YOjRyt8dNApI86f3nwzpfSrF14QsUbmO+YfzUopLf31F7+TgGI9qVFcWDh+/J6HH55MJnxktbIOTOXJ6z/nz9+8dm2xe3XjMjOz2c2b/3XpEkMvVJA2xUGN02hYibO9eIyh333du3t3ZC9ds9K+utE1q1f7ff3q1KnLZ87AZv/myJGf7duXUpqZmWFutfqoXkP5RjhYMbNUVUNT8YjxOKV0/uTJtWvWSIy4M8kycoozHXSORiPUkLWVgSIi6HuCP24CAT+K/4H9Hzl48PDLL09zH8ZnNHOemGkSeSXfDS1xieSUgULee4DfhZbCLbJhZXqPPPigNITck0oX83ZRoQR6GNKGLz1gSoNaKhSjYslcUeAxlluU96dpzOwvJ06AnjAv20JSoSo/wNE0uipKXH9aNamz5HkKQIG4eluowwxmBVPG488++mjb1q0rQuAbY5rKMJTiOMUCIPdK1cLq9MSjAt26seR+SIpQB/df737gga/KrUt0u5jK248UXAzBEEjEPTqMyhzvA5AKRu69mFGZYFTpmCoujNzTLXDpypWfPPccqyTv2CsHFL4YgNEts7PfnD6N6nTNR4D6KKWdQRqPkZQbE3DxDl9dfxqPf/v664deeunqtWteSalwUjfzbFl+Yh69dObMpg0bQrH5UAKUYApmJv4KnhkqLHu48YmJhHhm//7fv/329evXMxZsC7nJUTAuvuTVFwNRUq/sbqYRhd+UdbOMfLJOo54ts7O+21Sdncp47B88WF3/008++cc33si/kBXS1hO/pyn7TahUKRkqWFRq7lSinFLW5Lt33ilxMZXFfP/qVasy/f++/LKmuRRekimBDccknJ5jXZRpTInXcu17d9+dn2dmZjasX3/H7benlOZ27frxY48dmp9PKX38/vv//eKLMJ3zQlJ4gCnhLnYPynVXPFVEFYD08Khak6x4irzokRxkQJG6MIFczsyKLFa9WCjmezVkvvccZEnCcERHP6mS3CHOQZEY0Y2Kiu6jYkmZy1isSEqoMlr6NQiI5etMPrIY3n6GitW1bdVv8VRGl8lutCJFsR5LGVWSFmwmMIwUk19l0R/ZLKvgxavMssL7qJLOw6B55AUN/UVTdjq/KmsIqzMuFTJTJhPtpaePwqjXvWls6S9xSqGJdBkLIy8ATMF9Mtu2/PGp1wcsRboAoNCon8fnh0omscJGRD5xZPReDOTOM9vgh7VRJJJR2chII4P3IrGnyOhWiVAeOym/9BIzK/6edEyEy0fuIyEGoTkrSQKICFOKUZGEwytHaCZrmvK/ZHKDECPjjrdPcAQ/i82B3Qqsr1XXddJ8WGz4NLLTrAhbsYNpiCz8J4c9UwbPiQMiESsDrAARKQ80WML7XSVbsSSgCO29+hEnKCx9myMciMuI1BOcVEZ6vXQ9Ty8foFNO9/z70ZFWxmvFz6xJhr8iQeYgPaWyzwCuxBomSpg4rvG+0gaPCkYsK2vFDlUXRW5mBIqVJmkr7bYpO/VfgS0IzMbhdWxba5qR1g28oOJooCpj5/mAiUnzhPAUTQFKKQO3aFfYhXsOI71d0bZE8divzbHJSktsqZAD82RZW5XjgAxUnSY2g0P5wJ87xQXNiq+AKtcucJ9C1ytiYv2ahu+3eJRvsuTcyopyleTvgxhIbjLpyGAkAxbMlXxMBQ7wMtkqubUuHq9YtvJv2ks46upF+vhRpvScgaZZ6Se7bVv8Y0oWgxOi0SYxWG1rRZqHyZWMwwsAjpW06DlYED7kEEciwFHaFyccK+0IuJHp/R/aTlQp5Ow8QwAAAABJRU5ErkJggg==\n",
- "text/plain": []
- },
- "execution_count": 17,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "im = NamedTensor(ims[0], (\"height\", \"width\", \"channels\"))\n",
- "im2 = NamedTensor(ims[1], (\"height\", \"width\", \"channels\"))\n",
- "\n",
- "mask = NamedTensor(torch.randint(0, 2, [96, 96]).byte(), (\"height\", \"width\"))\n",
- "im.masked_fill(mask, 1)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "SB93TbaxhBpS"
- },
- "source": [
- "Similar operations can be used for standard matrix operations such as addition and multiplication."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "tnnPgP5xjlwa",
- "outputId": "595909e0-4bde-4ff8-e304-0bf036ae1468"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "im * mask.double()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "Woje-ckrj4Bm"
- },
- "source": [
- "A more general feature is the `dot` method for tensor contraction between name tensors. Tensor contraction, the machinery behind `einsum`, is an elegant way of thinking about generalizations of dot-products, matrix-vector products, matrix-matrix products, etc."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "t0H4P6NnkK4t",
- "outputId": "d4175fef-b8aa-41f8-ceb4-993f5fc9c097"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "OrderedDict([('width', 96), ('channels', 3)])"
- ]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Runs torch.einsum(ijk,ijk->jk, tensor1, tensor2)\n",
- "im.dot(\"height\", im2).shape"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "C-RpMMgd1qT6",
- "outputId": "ffa233ff-b206-4fd9-9fab-ce0c8d38938e"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "OrderedDict([('height', 96), ('channels', 3)])"
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Runs torch.einsum(ijk,ijk->il, tensor1, tensor2)\n",
- "im.dot(\"width\", im2).shape"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "5X7dclfr1rFp",
- "outputId": "59816bde-943b-4b8e-8af7-96e29384e1d8"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "OrderedDict([('channels', 3)])"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Runs torch.einsum(ijk,ijk->l, tensor1, tensor2)\n",
- "im.dot((\"height\", \"width\"), im2).shape"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "2T3wTh88lb7h"
- },
- "source": [
- "Similar notation can be used for sparse indexing (inspired by the [einindex](https://pypi.org/project/einindex/) library). This is useful for embedding lookups and other sparse operations. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 67
- },
- "colab_type": "code",
- "id": "iKWmZyHYlsQV",
- "outputId": "970f2e45-99e4-49f4-e336-7994f64aea1b"
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAAAyCAIAAAAsvEmTAAACxElEQVR4nO2YX0haURzHj6K51tLJQrcFgcTYQyVbgygYckExEDZoYeAKfFhTag+OyV4atO016GHQy6CHHoZv6cbCNCfoWlBB9yFGkxUGMqSJ012D2cI/exD2NP3d9Jy2we/z/Lvfc/j4Oz/vPZJyMkmQ6kj/9gb+dVAQAAoCQEEAKAgABQGgIAAUBICCAFAQAAoCQEEAKAgABQGgIADZqa20wfMPpqa2trcbj5LL5W6n86nbfUahaDytNthBABLWN4o/8nmrw+EPh1mEX9RoIouLVzs7WYRXYNtBWUEwjYwwskMIOUiljFbrfiLBKJ8w6qDY3l6v2Zw/OqKeXIPr3d1bwaBEIqEbizMIAAUB0D9iS6HQLbtdfL2ytXXYYjEZDL09PRfU6vNKpXB4mM5kPsZi/nDYt7z8PZcTGWXo7496vXXtuio0BQm5nFav/3l8DFY6xsZezsycNH/QZluJRmvXSKXSzM6OSqk8aXjVQFpBhJDXgYAYO4qmpmdudx35jycnwZpSqfRhc7OO8GrQFAT+vBUsRuMlrbaOfG5g4FxLC1hG5WX9NzikAajNoIfT0y/m56lENc7ntbUrOh2VKGoddEOvpxXVOJfrOsJ/hOa/mNfvHx4fF1N5d2jo1dwc9bdeFuAMAqAp6I7Fcs9mE1Pp8fmk7e3XTKb36+uNrFgsFleiUbvL9Xx2tpGcGlB+k/60u9vFceVyWfwjN/v6Hjmdgxx3trlZ5CNCLvdudfVtKLQUCn3LZgkht83mNwsLdWwYBI8YAP1vsf1EoovjTvmuQyaT5eNxmYz+DTL9DtJ1dDxxuajH1qZQKMTZXJsxv3LNCoJtYiIYiTBdhRCiaWv7SvUjowLOIADmgtQqVcDjKSeTX3j+/uioXC5ntFAqnd7geeqx2EEAzGfQ/w52EAAKAkBBACgIAAUBoCAAFASAggB+Af5O3Eljg09DAAAAAElFTkSuQmCC\n",
- "text/plain": []
- },
- "execution_count": 22,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "pick, _ = NamedTensor(torch.randint(0, 96, [50]).long(), (\"lookups\",)) \\\n",
- " .sort(\"lookups\")\n",
- "\n",
- "# Select 50 random rows.\n",
- "im.index_select(\"height\", pick)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "AKTInxARmYgY"
- },
- "source": [
- "## Proposal 4: Shifting Dimensions "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "S5GfSRZQnDq4"
- },
- "source": [
- "Behind the scenes all of the named tensors are acting as tensor objects. As such thing like order and stride of dimensions does matter. Operations like `transpose` and `view` are crucial for maintaining this, but are unfortunately quite error-prone. \n",
- "\n",
- "Instead consider a domain specific langauge `shift` that borrows heavily from the Alex Rogozhnikov's excellent [einops](https://github.com/arogozhnikov/einops) package.\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "KyBAO9_3qj41",
- "outputId": "1a0a182f-696a-45c8-e177-e6d1e5f32341"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 23,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor = NamedTensor(ims[0], (\"h\", \"w\", \"c\"))\n",
- "tensor"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "w2hdSaRKoHky"
- },
- "source": [
- "Standard calls to transpose dimensions."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "YJBHGKpLsX8a",
- "outputId": "6e58ddcb-9fac-45ce-e7e0-8585ab466209"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor.transpose(\"w\", \"h\", \"c\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "4C7y6HsOoGvz"
- },
- "source": [
- "Calls for splitting and stacking together dimensions."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "p731PTUs2HXW",
- "outputId": "795aab42-7ba9-47e5-9319-15a5404a200d"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "OrderedDict([('height', 8), ('q', 12), ('w', 96), ('c', 3)])"
- ]
- },
- "execution_count": 25,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor = NamedTensor(ims[0], (\"h\", \"w\", \"c\"))\n",
- "tensor.split(h=(\"height\", \"q\"), height=8).shape"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "uD1iruomtanM",
- "outputId": "2949d2be-f901-44c2-8e94-6c6e50353b89"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "OrderedDict([('bh', 576), ('w', 96), ('c', 3)])"
- ]
- },
- "execution_count": 26,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
- "tensor.stack(bh = ('b', 'h')).shape\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "8h6ZCcrgoeEg"
- },
- "source": [
- "Ops can be chained."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "74kpc4j-t1Sb",
- "outputId": "5a6005a6-7f84-486b-b865-e33721e5c0bd"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 27,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor.stack(bw=('b', 'w')).transpose('h', 'bw', 'c')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "ZKXtJ4gSonIZ"
- },
- "source": [
- "Just for fun, here are some of the crazier examples from *einops* in this notation."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 305
- },
- "colab_type": "code",
- "id": "JnsFFFGPkxBs",
- "outputId": "cd77b524-ccb1-4dbc-be71-62562ff6d4a5"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 28,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor.split(b=('b1', 'b2'), b1=2).stack(a=('b2', 'h'), d=('b1', 'w'))\\\n",
- " .transpose('a', 'd', 'c')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 209
- },
- "colab_type": "code",
- "id": "6XHpOv62kelh",
- "outputId": "f2b86a46-4509-4482-e57e-65db52b639d5"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 29,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor.split(w=('w1', 'w2'), w2=2).stack(a=('h', 'w2'), d=('b', 'w1'))\\\n",
- " .transpose('a', 'd', 'c')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 30,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "9xusGrzNkVKW",
- "outputId": "390964c0-70d0-4255-88f5-71f3c68fc05b"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 30,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor.stack(a=('b', 'w')).transpose('h', 'a', 'c')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 31,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "nsR9xjHMCXv2",
- "outputId": "90198be8-4aa0-4ec3-a34e-a24da230797b"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 31,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor.stack(a=('w', 'b')).transpose('h', 'a', 'c')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 32,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "OowFiE4jCkXH",
- "outputId": "f674c4d0-07bc-4519-a1e8-3a74f5c57203"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 32,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
- "tensor.mean('b')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 33,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 305
- },
- "colab_type": "code",
- "id": "FYX0z4-aEsLh",
- "outputId": "40cc5f3c-c325-4c06-9fbd-a7a3f8f2a399"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 33,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
- "tensor.split(h = ('h1', 'h2'), h2 =2).split(w = ('w1', 'w2'), w2=2) \\\n",
- " .mean(('h2', 'w2')).stack(bw=('b', 'w1'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 34,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 305
- },
- "colab_type": "code",
- "id": "BssZDH91Kjdv",
- "outputId": "0a1949cd-98b1-4842-9930-17757fe740f3"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 34,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
- "tensor.split(b = ('b1', 'b2'), b1 = 2).mean('c') \\\n",
- " .stack(bw=(\"b1\", \"w\"), bh=('b2', 'h')).transpose('bh', 'bw')\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 35,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 209
- },
- "colab_type": "code",
- "id": "tesLBQTbM2IO",
- "outputId": "fe141320-4db3-42e2-968a-85db3f0972a6"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 35,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor.split(b = ('b1', 'b2'), b1=2).stack(h=('h', 'b1'), w=('w', 'b2'))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "RONa1_CvpIJl"
- },
- "source": [
- "## Proposal 5: Ban Indexing"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "95TGZJB5pXbW"
- },
- "source": [
- "\n",
- "Generally indexing is discouraged in this named tensor paradigm. Instead use functions like `index_select` above.\n",
- "\n",
- "There are some useful named alternative functions pulled over from torch. For example `unbind` pulls apart a dimension to a tuple.\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 36,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "3jMIuUxIpn74",
- "outputId": "7df9941c-0391-44bc-b901-337c7e32be25"
- },
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": []
- },
- "execution_count": 36,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
- "\n",
- "# Returns a tuple\n",
- "images = tensor.unbind(\"b\")\n",
- "images[3]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "FZcHQ_BvqJ6X"
- },
- "source": [
- "The function `get` directly selects a slice of from a named dimension."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 37,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 113
- },
- "colab_type": "code",
- "id": "qQCELxUgqB_v",
- "outputId": "fd38412c-b3b8-4fd9-bf60-515aa0b6b402"
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAAAAADH8yjkAAADBElEQVR4nGN8xkBbwERj80ctGLVg1IJRC0YtGLVg1IJRC6gEWIhW+evciev3Xn79xcEpJCdnYKJApDZG4hpe/w+s3fkVRUTRL0yRahb8WzP1NqYok3eROnUsOFd1CbsEa3oxO+UW/JvU+xenpP48SUot+J62F5+02Fpl/PoJJdOPYXjNZ3gV+ogiC37GnyXggheJPyixIPcUAfMZGK7XUWDB/C0EzWdgWHIanyzeSL7jht/7UKCzkxG3JF4f1BJlPsOVPXgk8ZVFuw+i8nm97HQF+T6/u7F3+ycUiemuuA3BF0QeKBmYOTObH8b+OHHWP2S5Ywo4DcETREdQzOdZXAU3n4G/bjZKGbEBtyl4LJiHzGGc4oAi6dmOzNtOjgWf9iHzot3QpCPskThXPzHgArgt2PELicNWjCGfhcT+hzs/4rYAJQk5i2PIW3IjcXCU53gtOIPM8cSUZ9FF4twi3YLXj5F5+lhUiCKxsVR4MHfgkriDwrPHoQoGXuCUwemDx7gksIIPv2lswf93JFvwkSQLGL6RbMF30izAWe7itIC4khoOfuGSGLjGLydp5rCRbAEHaRawkmyBEGkWcJFsgQxpFgjgksBZVMii8C6K4lBGEOD0AWrLnED7kBwLBJSQeQeobwGDKTJn4RfqW4DS1nlT/p/qFjjzIPPWF+MskMm1gN0XhbvC8wQ2VX8P5vfitQBPy+62A1qwmKU7oBYgnw7v3v2ewW0BmRYwpGxDF2G3MVBTEeTi/vHp4/sbly7e/svAwMCgfJhcCx45EFVms9zD14LGV1zL5RNjPsMfvLkQb32QY0OUDXfJtoB5mjQxFtzBJ4m/RhNZLUGEBeT7gIFBYa0CbS1gUNzuQFsLGPiXtvESUPIGd++AmFYFY8LBaJw1LgTgi2XiBqSezF37BpecsLuPDZ6cRuSIF8Of/XsOYmYoNhMrG2NmvBqJtYCBgYHh2dWr9148//jjx38uLm4eaRUVFS2C41EkWUAWGPrjpqMWjFowasGoBaMWjFrAwMDAAAAx6rlALW9LlAAAAABJRU5ErkJggg==\n",
- "text/plain": []
- },
- "execution_count": 37,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Returns a tuple\n",
- "images = tensor.get(\"b\", 0).unbind(\"c\")\n",
- "images[1]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "kx75vFJdp0Rm"
- },
- "source": [
- "Finally `narrow` can be used to replace fancy indexing. However you must give a new dim name (since it can no longer broadcast)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 38,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 67
- },
- "colab_type": "code",
- "id": "lufRXyjoqbI5",
- "outputId": "893463c5-1536-45d3-dce9-dfcf4bbb7814"
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAAAyCAIAAAAsvEmTAAAFFUlEQVR4nO2abUxTVxyHz11LC32hlJfBUu1AGCwg0yEQIQ12oMUywRiXxQQXdME4UcMy4lxcJNuHyZeZxU34gBE14kaivCxDChTBDsYMQiaMSqWIGwh2UCm3OFqkL/tA4kyQ9tD7P1WMT/rx1+fc/nJ6c+65h3KOjyNimGj6/d27f+/pITeEJCysva4uQiol5H+NkBchZJ2by8nLI9oOQmjMYNi+d6/FaiXkJ1jQR4cPd3R1kfM/4c+BgU+LiwnJSRVUeu7clfp6QvLFlFdW/nbzJgkzReIepBsaSlAoyE37Z/Lu2rU9TU0URcFqicygwuPHvdwOQuiP/v6rLS3gWvgZVK9WZ+fl4ef9hcKdWVmb09IS4uODxOIAf396ZsY4NdWv0zVcu1arUk2bzZiqtI0bNTU1Hl31ksAXlLh1a09fH06SxWIdOXDg84MHxSLRUhkTTX9z6tR35eUOhwPHqe/sjAoPx7xUHID/Yq0dHZjtCAWCqxcvlhw75qIdhJBYJPq2uPjKmTO+XC6OtqquDieGD3BBP1RU4MQoiqo8fTpTLsfU7lAqS0tKcJK1KhWmExPIgmizWdXaipPcl5ubo1AsS/7xrl2KTZvcxm5ptTT2PQsHyILqGhvnHj92G+NyOF8VFXngP1JQ4DbjcDhgV6eQBTVrNDixrIyMN0JDPfDLU1IEfL7bGOZNEBPIgjq7u3FiO5RKz/xsNjshPt5t7PbgoGf+ZwJW0D+Tk3+NjuIkE9et83iU0JAQt5kBvd5j/2LYUCLd0BBmMhbjXsuEMYMB0AY2gzCnjxeYmp6en5+Hsr2EBTmdzsmpKSgbWEEmmoZSMeff2VkoFVhBsxYLlIo5Vri9BLCCvL+/4QKc9SomBLdcXw7ACuL5+UGpmMPhcKBUYAX5+fpCqZjD8fGBUoEVFBwYCKViDp/Hg1KBFfTmqlVQKuYEBgRAqcAeNcJXr8ZMGnp7cR6pXhDAZlBcTAxm8t7ICNSgXgCsoMCAgOg1a3CSTdevQw3qBSDXQalJSTixsgsXZh49AhyXKJAFZW/ZghObMBo/OXrU6XQCDk0OyIKyMjKEAgFO8sfa2vyiIsBNCXJAFuTL5X6YnY0ZrqiqSlIqf71xg8mIdru9WaPJKyz8+uRJJh4XAL9ZHdDr4+TyZf19ZMnJn+3fnymX4z+s0GZzS3v7L2p1vVr90GRCCOUoFD+fP+/BBbsF/tXzzvz8moaG5X7Ll8tNl8mS16+PjY6OiYoKEosFPJ6Az7dYrdNm8zRNPzSZ+nW67r6+7t7eAb3ebrc//fWYyEhdezvcj/gf+ILujYzEyeVe3v1gs9mW4WE2G2zd+wT47Y4IqfTLwkJwrWtsNtswmfUnkf2gLw4dSpfJSJhdcOfuXRJaIgWxWKyfysqkEgkJ+VLcwX7vtCxI7Si+HhzcevmyJCyMkH8xK2kGLRAZHt5WXQ17nMkFK68ghNBbERFdKhX+OSAmrMiCEEJikUh16VLpiRP+QiHRgSaMRvzTjPh4460GRVEFe/bc1mj25eb6wO0WL4bEfZrIOWkX/H3//vdnz1ZWV08YjVDOkKCg7ZmZH2zbliGTga8VvV3QAjabrbGtrb6lpVmj8WyDkcvhpCQmvpeami6TpWzYwGKxwC9ygedT0NOMjo/f0mp7tdrB4eExg2HswQMTTVusVovV6nQ6+TzewkOZUCCQSiRvR0UtfN6JjcU898qQ51/QC86rV89ueFWQG/4DFh7LAE9HyhsAAAAASUVORK5CYII=\n",
- "text/plain": []
- },
- "execution_count": 38,
- "metadata": {},
- "output_type": "execute_result"
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZskQMOXCDP9O"
+ },
+ "source": [
+ "*Alexander Rush* - @harvardnlp"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XSVljWusuNti"
+ },
+ "source": [
+ "\n",
+ " \n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2Rbx8_nj1bap"
+ },
+ "source": [
+ "### (Update: July 2022)\n",
+ "\n",
+ "Many ideas in this post have been incorporated into the prototype [PyTorch Named Tensor Feature](https://pytorch.org/docs/stable/named_tensor.html#named-tensors-doc). The [namedtensor](https://github.com/harvardnlp/NamedTensor) library underlying this notebook is no longer maintained, and as such some of the original code in this notebook doesn't work. \n",
+ "\n",
+ "Where possible, the demonstrations of Named Tensors use cases have been re-written using the PyTorch feature, keeping the original code (based on the custom library) in comments for reference. Many operations demonstrated by the original library are not yet implemented by PyTorch's Named Tensors: that code remains as-is."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "dnuYLZwvDYVP"
+ },
+ "source": [
+ "\n",
+ "TL;DR: Despite its ubiquity in deep learning, Tensor is broken. It forces bad habits such as exposing private dimensions, broadcasting based on absolute position, and keeping type information in documentation. This post presents a proof-of-concept of an alternative approach, **named tensors**, with named dimensions. This change eliminates the need for indexing, dim arguments, einsum-style unpacking, and documentation-based coding. The prototype **PyTorch library** accompanying this blog post is available as [namedtensor](https://github.com/harvardnlp/NamedTensor).\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Ae7BMj9HAUmD"
+ },
+ "source": [
+ "* Table of Contents \n",
+ "{:toc} "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2GEkZv2b7eDs"
+ },
+ "source": [
+ "*Changelog*\n",
+ "* Updated the syntax of the prototype to be a subest of xarray whereever possible. \n",
+ "* Dropped the einops style string DSL notation to be more explicit. \n",
+ "\n",
+ "*Implementations* \n",
+ "* Jon Malmaud points out that the [xarray](http://xarray.pydata.org/en/stable/) project has very similar goals as this note with the addition of extensive Pandas and scientific computing support. \n",
+ "* Tongfei Chen's [Nexus](https://github.com/ctongfei/nexus) project proposes statically type-safe tensors in Scala. \n",
+ "* Stephan Hoyer and Eric Christiansen have a [labeled tensor library](https://git.ecdf.ed.ac.uk/s1886313/tensorflow/-/tree/b1d8c59e9b014b527fb2fbef9ce9afc14dbc4938/tensorflow/contrib/labeled_tensor) for Tensorflow that is the same as this approach.\n",
+ "* Nishant Sinha has a [TSA library](https://towardsdatascience.com/introducing-tensor-shape-annotation-library-tsalib-963b5b13c35b) that uses type annotations to define dimension names."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "wd9yuKJ2Hhdj",
+ "outputId": "fb53886c-3525-4214-e8e9-2fb0f9dbb4cf"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "/content/NamedTensor/notebooks/NamedTensor\n",
+ "\u001b[33m DEPRECATION: A future pip version will change local packages to be built in-place without first copying to a temporary directory. We recommend you use --use-feature=in-tree-build to test your packages with this new behavior before it becomes the default.\n",
+ " pip 21.3 will remove support for this functionality. You can find discussion regarding this at https://github.com/pypa/pip/issues/7555.\u001b[0m\n",
+ " Building wheel for namedtensor (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ "/content/NamedTensor/notebooks/NamedTensor/notebooks\n",
+ "/content/NamedTensor/notebooks/NamedTensor/notebooks\n"
+ ]
+ }
+ ],
+ "source": [
+ "# @title Setup for Colab\n",
+ "!rm -fr NamedTensor/; git clone -q https://github.com/harvardnlp/NamedTensor.git\n",
+ "%cd NamedTensor\n",
+ "!pip install -q .; pip install -q torch numpy opt_einsum\n",
+ "%cd notebooks\n",
+ "!pwd"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 52,
+ "metadata": {
+ "id": "7b48OTgB7gso"
+ },
+ "outputs": [],
+ "source": [
+ "import numpy \n",
+ "import torch\n",
+ "from namedtensor import NamedTensor, ntorch\n",
+ "from namedtensor import _im_init\n",
+ "_im_init()\n",
+ "\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {
+ "id": "wdAHtiai1bat"
+ },
+ "outputs": [],
+ "source": [
+ "## Helper Functions\n",
+ "\n",
+ "from collections import OrderedDict\n",
+ "\n",
+ "def show_dimensions(t):\n",
+ " d = OrderedDict()\n",
+ " for dim_name, size in zip(t.names, t.shape):\n",
+ " d[dim_name] = size\n",
+ " return d"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "X1XnmQLgDeHy"
+ },
+ "source": [
+ "# Tensor Traps\n",
+ "\n",
+ "\n",
+ "This post is about the tensor class, a multi-dimensional array object that is the central object of deep learning frameworks such as Torch, TensorFlow and Chainer, as well as numpy. Tensors carry around a blob of storage and expose a tuple of dimension information to users."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 54,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "9LZarsn5HgUa",
+ "outputId": "0c14ba33-9c7d-4f67-96d7-d847ef085269"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "torch.Size([6, 96, 96, 3])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 54
+ }
+ ],
+ "source": [
+ "ims = torch.tensor(numpy.load('test_images.npy'))\n",
+ "ims.shape"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_A4CksffJ5sT"
+ },
+ "source": [
+ "Here there are 4 dimensions, corresponding to *batch_size*, *height*, *width*, and *channels*. Most of the time you can figure this out by some comment in the code that looks like this: "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "euWWfx_yKh85",
+ "outputId": "1fa60228-e279-4ce0-a134-9ec521707f1d"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 55
+ }
+ ],
+ "source": [
+ "# batch_size x height x width x channels\n",
+ "ims[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oec2Ah5eRgEp"
+ },
+ "source": [
+ "This approch is concise and pseudo-mathy. However from a programming point of view it is not a great way to build complex software."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ampMvKRpHYvv"
+ },
+ "source": [
+ "\n",
+ "## Trap 1: Privacy by Convention\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tFP--oUNnb8V"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "Code that manipulates tensors does so by dimension identifiers in the tuple. If you want to rotate the image you read the comment, decide what dimensions need to be changed and alter them. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 56,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "JuYMwAFtLBcl",
+ "outputId": "d5154011-dda5-4d32-e7c9-82befe0fba3b"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 56
+ }
+ ],
+ "source": [
+ "def rotate(ims):\n",
+ " # batch_size x height x width x channels\n",
+ " rotated = ims.transpose(1, 2)\n",
+ " \n",
+ " # batch_size x width x height x channels\n",
+ " return rotated\n",
+ "rotate(ims)[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gjjCOsyBLvtV"
+ },
+ "source": [
+ "This code is simple and in theory well documented. However, it does not reflect the semantics of the target function. The property of rotation is independent of the batch, or for that matter, the channels. The function should not have to account for these dimensions in determining the dimensions to alter. \n",
+ "\n",
+ "This leads to two problems. FIrst, it's quite worrisome that if we pass in a singleton image this function runs fine but fails to work. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 57,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "bnh57z49L9Lu",
+ "outputId": "85790dec-30fd-44a8-b3d3-1fde873304df"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "torch.Size([96, 3, 96])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 57
+ }
+ ],
+ "source": [
+ "rotate(ims[0]).shape"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "tqw1mFdDk2Fi"
+ },
+ "source": [
+ "However, even more worrisome is that the function may actually use the batch dimensions by mistake and mix together properties of different images. This can lead to nasty bugs that would be easy to avoid if this dimension was hidden from the code. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1DV0yQ09L7AR"
+ },
+ "source": [
+ "## Trap 2: Broadcasting by Alignment\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "p9LuwkU9naX_"
+ },
+ "source": [
+ "\n",
+ "The most useful aspect of Tensors is that they can quickly do array operations without directly requiring for loops. For this to work dimensions need to be directly aligned so that they can be broadcasts. Again this is done by convention and code documentation that makes it \"easy\" to line up dimensions. For instance, let's assume we want to apply a mask to the above image. \n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 58,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "Sp0TsC0yOBxr",
+ "outputId": "a9244d17-b44b-479f-898c-0c0907ece737"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 58
+ }
+ ],
+ "source": [
+ "# height x width\n",
+ "mask = torch.randint(0, 2, [96, 96]).byte()\n",
+ "mask"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 59,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ },
+ "id": "cO9IWw46O33Z",
+ "outputId": "e5e69c0f-6a8d-4c6c-e1fe-1cecd4f4fdcd"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "'Broadcasting fail torch.Size([96, 96]) torch.Size([6, 96, 96, 3])'"
+ ],
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ }
+ },
+ "metadata": {},
+ "execution_count": 59
+ }
+ ],
+ "source": [
+ "try:\n",
+ " ims.masked_fill(mask, 0)\n",
+ "except RuntimeError:\n",
+ " error = \"Broadcasting fail %s %s\"%(mask.shape, ims.shape)\n",
+ "error"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9BsD5FpGQMqv"
+ },
+ "source": [
+ "This fails because even though we knew that we were building a *height* and *width* shaped mask, the rules of broadcasting do not have the correct semantics. To make this work, you are encouraged to use either `view` or `squeeze`, my least favorite functions. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 60,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "AYso46ojPfuQ",
+ "outputId": "127b661a-5028-4536-a7cb-0230d5146001"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 60
+ }
+ ],
+ "source": [
+ "# either \n",
+ "mask = mask.unsqueeze(-1)\n",
+ "# or \n",
+ "mask = mask.view(96, 96, 1)\n",
+ "\n",
+ "# height x width x channels\n",
+ "ims.masked_fill(mask, 1)[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Whz5pqd_SRXH"
+ },
+ "source": [
+ "Note we do not need to do this for the left-most dimensions so there is a bit of abstraction here. However reading through real code, dozens of right side `view`s and `squeeze`s become completely unreadable."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5UyG7El7Snbi"
+ },
+ "source": [
+ "## Trap 3: Access by Comments\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "9LWcPiviTwWc"
+ },
+ "source": [
+ "It is possible that you look at the top two issues and think that as long as you are careful, these issues will be caught by run time errors. \n",
+ "However, even well used combinations of broadcasting and indexing can lead to problems that are very tough to catch. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 61,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "HfkPrgC1TPWh",
+ "outputId": "f041d649-e60d-4fee-be10-a5f917adb167"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAIAAABt+uBvAAADR0lEQVR4nO2cz0sbQRTHZzf+auqWHIw/EAK5SS/iqYhSRCkWD+pBsIH+Cf453r306KF491iKokaPTTzkYLCKHkIa16350YMgbUn2jdu3850t70NOZnzv5cPMmJmd0el0OkrojYsuwHbQghoNdXsLriEUBzPErq5Uu93l5xMTxkshQAi6vAx7N5VSo6OmSqExPsTC7SilWi11c2OkFC3MCiLtPPLwEHMdzwA9SfdCU2X82CrIGgwKsmlm0cegIJtmFn0MCurrM5eLD4OCsllzufiQSZrAVkHWrDnMCtL82DbNVsZ7EOnIda2arWQ1TwAS9ESjoXxfjYwgawgFLch6bP0rZg0iiEAEEYggAhFEwPmd9Wx/nzGaUmp6aYk3YAQ4Bf1oNBijWQKnIN/3GaNZAqeg+yBgjGYJnIJ+JnNTNRwRRMAp6EEEhdNstRijWQKroGaTMZolcApqSQ8Kp9V1kzDhYDbMPm1v6zT7uLUVdyUkmOcHL9NpSN4IYAT19/dD8kYAIyjlJmabBSPIFUHhOI4DyRsBEUSQmK6OQgQRYIbYYbGo0+zd5mbclZBgBCXoebcMMQJQD4JkjQToLJcMsf8GEUQggghAc1BylhqgtRgkayRkiBFgetCH9XVI3ghIDyLACBoeHobkjQBGUCaT6WgAqe0vMIKGxsa0BFlwIgs0Bw0MdNpt8vXt6AhT3m/ALh4FCTkrA7ur8WVvT7Pl3OrqM+IGgRocjFJQD2CCPu/s6DfO5/PTCwu93r09Py+enDyesX3leYsbG/9e3hOwITaUTlcqFc3G36+vvx4caLZcjF5UF2BfFN+vrDjxwFsn7nao5yXi8SFyqTE/P+/GQJP1X1ohBb2enY1DULlcZiwSvFgtFAop1+V9lUslxgrBN9RfjI9PTU2VWD9SrVZjjIa/wv9meTm4v69Wq+hCuoMXpJR6u7ZWOjw8Oz1licZ7vs+ua+H7u7v+3V3kX5+cnJzhvoNnl6BHKsfHFxcX+u1zuVxuZiamYmwU9AftdlCt1ut13/cdx/E8z/M8N5tVqZSZ/NYLQiOb9gQiiEAEEYggAhFEIIIIRBCBCCIQQQQiiEAEEYggAhFEIIIIRBCBCCIQQQQiiOAXxNA9mVxVfQQAAAAASUVORK5CYII=\n"
+ },
+ "metadata": {},
+ "execution_count": 61
+ }
+ ],
+ "source": [
+ "a = ims[1].mean(2, keepdim=True)\n",
+ "# height x width x 1\n",
+ "\n",
+ "# (Lots of code in between)\n",
+ "# .......................\n",
+ "\n",
+ "# Code comment explaining what should be happening.\n",
+ "dim = 1\n",
+ "b = a + ims.mean(dim, keepdim=True)[0]\n",
+ "\n",
+ "\n",
+ "# (Or maybe should be a 1? or a 0?) All these values will give different results without throwing run time errors.\n",
+ "dim = 2\n",
+ "b = a + ims.mean(dim, keepdim=True)[0]\n",
+ "b"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "P4WyEXyYVFGp"
+ },
+ "source": [
+ "Here we assume that the coder is trying to combine two tensor using both reduction operations and dimension indexing. (Honestly at this point I have forgotten what the dimensions stand for). \n",
+ "\n",
+ "The main point though is that this code will run fine for whatever value dim is given. The comment here might descibe what is happening but the code itself doesn't throw a run time error. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "b9gDFB-WV9_h"
+ },
+ "source": [
+ "# Named Tensor: A Prototype"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "khfYKuBcWPMz"
+ },
+ "source": [
+ "Based on these issues, I think deep learning code should move to a better central object. There are several of these proposed. Here for fun, I will develop a new prototype. I have the following goals. \n",
+ "\n",
+ "*1) Dimensions should have human-readable names.*\n",
+ "\n",
+ "*2) No function should have a dim argument.*\n",
+ "\n",
+ "*3) Broadcast should be by name matching.*\n",
+ "\n",
+ "*4) Transposition should be explicit.*\n",
+ "\n",
+ "*5) Ban dimension based indexing.*\n",
+ "\n",
+ "*6) Private dimensions should be protected.*\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "cmFZCfgZYm3i"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "To experiment with these ideas I have built a library known as `NamedTensor`. Currently it is PyTorch specific, but in theory a similar idea could be used in other frameworks. The code is available at [github.com/harvardnlp/namedtensor](https://github.com/harvardnlp/namedtensor). "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SYth2yPxZobO"
+ },
+ "source": [
+ "## Proposal 1: Assigning Names"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0177b_0vZ303"
+ },
+ "source": [
+ "The core of the library is an object that wraps a tensor and provides names for each dimension. Here we simply wrap a given torch tensor with dimension names."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 62,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "sLnQA8VOZsEx",
+ "outputId": "a91230f6-8bbe-4917-c2ab-e34fa2e3d3d1"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "OrderedDict([('batch', 6), ('height', 96), ('width', 96), ('channels', 3)])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 62
+ }
+ ],
+ "source": [
+ "''' \n",
+ "Legacy Code:\n",
+ "\n",
+ "named_ims = NamedTensor(ims, (\"batch\", \"height\", \"width\", \"channels\"))\n",
+ "named_ims.shape\n",
+ "'''\n",
+ "\n",
+ "named_ims = torch.tensor(ims, names=(\"batch\", \"height\", \"width\", \"channels\"))\n",
+ "show_dimensions(named_ims)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eLjL4O7_ZiyW"
+ },
+ "source": [
+ "Alternatively the library has wrappers for the pytorch constructors to turn them into named tensors. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 63,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "eiYe47t6aRnd",
+ "outputId": "7a4aec1a-c164-4804-f843-7b9dd7a2b889"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 63
+ }
+ ],
+ "source": [
+ "'''\n",
+ "Legacy Code:\n",
+ "\n",
+ "ex = ntorch.randn((96, 96, 3), names=(\"height\", \"width\", \"channels\"))\n",
+ "'''\n",
+ "\n",
+ "ex = torch.randn((96, 96, 3), names=(\"height\", \"width\", \"channels\"))\n",
+ "ex"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "lNgHsAmDbxMc"
+ },
+ "source": [
+ "Most simple operations simply keep around the named tensor properties. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 64,
+ "metadata": {
+ "id": "T-wGpWZAb4AL"
+ },
+ "outputs": [],
+ "source": [
+ "ex.log()\n",
+ "\n",
+ "# or \n",
+ "\n",
+ "ntorch.log(ex)\n",
+ "\n",
+ "None"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "GfVktrThcIF2"
+ },
+ "source": [
+ "## Proposal 2: Accessors and Reduction"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iNCJcWeccTZW"
+ },
+ "source": [
+ "The first benefit of names comes from the ability to replace the need for dim and axis style arguments entirely. For example, lets say we wanted to sort each column. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 65,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "-HdhRVfqcyd2",
+ "outputId": "deeb5a7e-cd66-4944-f8e2-5787cc22d40e"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 65
+ }
+ ],
+ "source": [
+ "'''\n",
+ "Legacy Code:\n",
+ "\n",
+ "sortex, _ = ex.sort(\"width\")\n",
+ "'''\n",
+ "\n",
+ "# PyTorch Named Tensors don't support sorting. For now, workarounds like this are required.\n",
+ "\n",
+ "def named_sort(named_tensor, named_dimension):\n",
+ " all_dim_names = named_tensor.names\n",
+ " idx = all_dim_names.index(named_dimension)\n",
+ "\n",
+ " unnamed_tensor = named_tensor.rename(None)\n",
+ " values, indices = unnamed_tensor.sort(idx)\n",
+ " named_values, named_indices = (torch.tensor(values, names=all_dim_names), torch.tensor(indices, names=all_dim_names))\n",
+ " \n",
+ " return (named_values, named_indices)\n",
+ "\n",
+ "sortex, _ = named_sort(ex, \"width\")\n",
+ "sortex"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JRljeAlweL7X"
+ },
+ "source": [
+ "Another common operation is a *reduction* where one or more dimensions is pooled out. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 66,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "6Rji52BmemX9",
+ "outputId": "20d56723-63b9-4cf0-a116-556955dbcd5e"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 66
+ }
+ ],
+ "source": [
+ "named_ims.mean(\"batch\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 67,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "5Ky7Q3Kge8Mh",
+ "outputId": "3bffe421-b6eb-41b9-bca8-1c44df8253f3"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 67
+ }
+ ],
+ "source": [
+ "named_ims.mean((\"batch\", \"channels\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "m88W0sfufEq1"
+ },
+ "source": [
+ "## Proposal 3: Broadcasting and Contraction\n",
+ "\n",
+ "The names that are provided also provide the basis for broadcasting operations. When there is a binary operation between two named tensors they first ensure that all dimensions are matched in name and then apply standard broadcasting. To demonstrate let's return to the masking example above. Here we simply declare the names of the dimensions of our mask, and ask the library to figure out the broadcasting. \n",
+ "\n",
+ "> This is *not* how broadcasting is currently implemented in PyTorch Named Tensors (details [here](https://pytorch.org/docs/stable/named_tensor.html#explicit-alignment-by-names)). Broadcasting ignores dimension names and aligns by dimension order, as usual.\n",
+ "> However, the Named Tensor API offers helper functions `Tensor.align_to()` and `Tensor.align_as()` to align dimensions by name before an operation."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 68,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "ffjF33e4fhLs",
+ "outputId": "4cd6e356-1473-40c5-a6f2-469f0faceb38"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 68
+ }
+ ],
+ "source": [
+ "'''\n",
+ "Legacy Code:\n",
+ "\n",
+ "im = NamedTensor(ims[0], (\"height\", \"width\", \"channels\"))\n",
+ "im2 = NamedTensor(ims[1], (\"height\", \"width\", \"channels\"))\n",
+ "\n",
+ "mask = NamedTensor(torch.randint(0, 2, [96, 96]).byte(), (\"height\", \"width\"))\n",
+ "im.masked_fill(mask, 1)\n",
+ "'''\n",
+ "\n",
+ "im = torch.tensor(ims[0], names = (\"height\", \"width\", \"channels\"))\n",
+ "im2 = torch.tensor(ims[1], names = (\"height\", \"width\", \"channels\"))\n",
+ "\n",
+ "mask = torch.tensor(torch.randint(0, 2, [96, 96]).byte(), names = (\"height\", \"width\"))\n",
+ "\n",
+ "im.masked_fill(mask.align_as(im), 1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SB93TbaxhBpS"
+ },
+ "source": [
+ "Similar operations can be used for standard matrix operations such as addition and multiplication."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 69,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "tnnPgP5xjlwa",
+ "outputId": "c63b0572-d9c0-49a8-da51-2178443268c2"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 69
+ }
+ ],
+ "source": [
+ "im * mask.align_as(im).double()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Woje-ckrj4Bm"
+ },
+ "source": [
+ "A more general feature is the `dot` method for tensor contraction between named tensors. Tensor contraction, the machinery behind `einsum`, is an elegant way of thinking about generalizations of dot-products, matrix-vector products, matrix-matrix products, etc."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 70,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "t0H4P6NnkK4t",
+ "outputId": "3c9993a5-f38b-4a59-ac33-4a2243a86584"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "OrderedDict([('width', 96), ('channels', 3)])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 70
+ }
+ ],
+ "source": [
+ "'''\n",
+ "Legacy Code:\n",
+ "\n",
+ "# Runs torch.einsum(ijk,ijk->jk, tensor1, tensor2)\n",
+ "im.dot(\"height\", im2).shape\n",
+ "'''\n",
+ "\n",
+ "# Another workaround...\n",
+ "def named_einsum(dims_to_contract, t1, t2):\n",
+ " if isinstance(dims_to_contract, str): dims_to_contract = [dims_to_contract]\n",
+ "\n",
+ " # The case where the tensors have non-identical dimension names is hard. Ignore it for now.\n",
+ " assert t1.names == t2.names\n",
+ "\n",
+ " dim_names = t1.names\n",
+ " contracted_dim_names = [x for x in dim_names if x not in dims_to_contract]\n",
+ " idx = [dim_names.index(dim) for dim in dims_to_contract]\n",
+ "\n",
+ " dimstring = ''.join([chr(x) for x in range(97, 97+len(dim_names))])\n",
+ " contracted_dimstring = ''.join([dim_char for i, dim_char in enumerate(dimstring) if i not in idx])\n",
+ "\n",
+ " t1 = t1.rename(None)\n",
+ " t2 = t2.rename(None)\n",
+ "\n",
+ " # Contract out the last dimensions\n",
+ " contracted = torch.einsum(f\"{dimstring}, {dimstring}->{contracted_dimstring}\", t1, t2)\n",
+ " return torch.tensor(contracted, names=contracted_dim_names)\n",
+ "\n",
+ "height_contracted = named_einsum(\"height\", im, im2)\n",
+ "show_dimensions(height_contracted)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 71,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "C-RpMMgd1qT6",
+ "outputId": "e47e2cb4-d24a-432d-bf4f-9727323ab278"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "OrderedDict([('height', 96), ('channels', 3)])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 71
+ }
+ ],
+ "source": [
+ "# Runs torch.einsum(ijk,ijk->il, tensor1, tensor2)\n",
+ "show_dimensions(named_einsum(\"width\", im, im2))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 72,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "5X7dclfr1rFp",
+ "outputId": "cdbc85fe-94f5-4f4b-f306-c1b036750a9a"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "OrderedDict([('channels', 3)])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 72
+ }
+ ],
+ "source": [
+ "# Runs torch.einsum(ijk,ijk->l, tensor1, tensor2)\n",
+ "show_dimensions(named_einsum((\"height\", \"width\"), im, im2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "2T3wTh88lb7h"
+ },
+ "source": [
+ "Similar notation can be used for sparse indexing (inspired by the [einindex](https://pypi.org/project/einindex/) library). This is useful for embedding lookups and other sparse operations. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 73,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 67
+ },
+ "id": "iKWmZyHYlsQV",
+ "outputId": "6d5c304a-065e-4c8f-c49a-71f2b9109ed2"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAAAyCAIAAAAsvEmTAAADL0lEQVR4nO2aX0hTURzHz83pLN1M0pIFivogpEOaCipLKXMww3/0YiRMLbDhi3gDQRCjB18C3+zR4YOxl9weXHOpqPQP/8wHF23osJhMpt5cm5J/Jq2HXqLmfsfrOVpwPs8/vr/DZ79z7t29lwuvrSHG0Zw76wX86zBBAEwQgOTUOs0sLLR1ddkXF08eFRsby7e29vB8vFR68rTocFQPaX8gcKex8YPdTq/F1bS0N2ZzZno6pXy2xQCYIACKgvb292t0Oqr7CyHk9flqm5t39/Yo5dMS1G8wnM/MfDs7Syn/dxxO54WsrHdzczTCqRzSLrdbpdHQ+1Ujcj0vz26zcRxHNpa8oJGxsWqdDr9eLpPdraq6XVamUiovJSdflMsD29vC1tZHl+vVxITJav0WDGJGlRUXTw8Pi1r1kRAWVN/SYh4dhbtynNlgqNFo8JMHjMYHHR1gmUqptNts+LEgJM+g+21tOHbqtdofXu+x7CCEWhoaQh5PYkJC9LIFh+NpX9+xkqPDLvMATBAASUHv5+dxyuq1WnH5EolEpVSCZZ+WlsTlR4SYoPXNzS+rqziVhfn5ortcSU0Fa5zLy6Lz/4ZtMQBijztcbjdm5bXyclJNI+L1+QimsQkCICZoiPQtrGi++v0Op5NUGpsgACYIgJigU/7vHp39gwNSUWyCAIgJysnOJhV1cnDuJzEh+bgjR61eWlkBy57wfA/Pk2pKG5JbrLSoCKfs+eDg9s4Owb5UISmourISp2xDEB51dobDYYKt6UFSUFVFhSwxEafyhcn0kOdDoRDB7pQgKSheKp2xWDAfmw8YjXEZGZxCcaOuzmS1ft/dxW8UCAZfWixN7e0pubmcQsEpFLVNTSIXDUHr1fOGIBRptR6vl0Z4RJ51dz/W64nHsvsgACYIgAkCoPv5C0LIHwjc0+ttU1NUuyCELqekrJP4+OgPqE9QclKSdWiov7dXLpNRbbQhCPjvYPFhWwyA+haLyOHh4ejk5Mj4+Ovp6c8ej4gEaVxcSWHhzdLSW2p1SUFBTEwM8UX+gk0QwNlM0H8EmyAAJgiACQJgggCYIAAmCIAJAmCCAH4Ceaz8VoI1H4AAAAAASUVORK5CYII=\n"
+ },
+ "metadata": {},
+ "execution_count": 73
+ }
+ ],
+ "source": [
+ "'''\n",
+ "Legacy Code:\n",
+ "\n",
+ "pick, _ = NamedTensor(torch.randint(0, 96, [50]).long(), (\"lookups\",)) \\\n",
+ " .sort(\"lookups\")\n",
+ "\n",
+ "# Select 50 random rows.\n",
+ "im.index_select(\"height\", pick)\n",
+ "'''\n",
+ "\n",
+ "# More workarounds...\n",
+ "def named_index_select(named_dimension, named_tensor, indices):\n",
+ " all_dim_names = named_tensor.names\n",
+ " idx = all_dim_names.index(named_dimension)\n",
+ "\n",
+ " unnamed_tensor = named_tensor.rename(None)\n",
+ " result = unnamed_tensor.index_select(idx, indices.rename(None))\n",
+ " return torch.tensor(result, names=all_dim_names)\n",
+ "\n",
+ "lookups = torch.tensor(torch.randint(0, 96, [50]), names=(\"lookups\",))\n",
+ "pick, _ = named_sort(lookups, \"lookups\")\n",
+ "\n",
+ "# Select 50 random rows.\n",
+ "named_index_select(\"height\", im, pick)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "AKTInxARmYgY"
+ },
+ "source": [
+ "## Proposal 4: Shifting Dimensions "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "S5GfSRZQnDq4"
+ },
+ "source": [
+ "Behind the scenes all of the named tensors are acting as tensor objects. As such thing like order and stride of dimensions does matter. Operations like `transpose` and `view` are crucial for maintaining this, but are unfortunately quite error-prone. \n",
+ "\n",
+ "Instead consider a domain specific language `shift` that borrows heavily from the Alex Rogozhnikov's excellent [einops](https://github.com/arogozhnikov/einops) package.\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 74,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "KyBAO9_3qj41",
+ "outputId": "9df2cb13-50d4-42db-d351-ce1acbe75058"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 74
+ }
+ ],
+ "source": [
+ "tensor = NamedTensor(ims[0], (\"h\", \"w\", \"c\"))\n",
+ "tensor"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "w2hdSaRKoHky"
+ },
+ "source": [
+ "Standard calls to transpose dimensions."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 75,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "YJBHGKpLsX8a",
+ "outputId": "52745e72-3f9f-460f-d783-d0be8cac8ccb"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 75
+ }
+ ],
+ "source": [
+ "tensor.transpose(\"w\", \"h\", \"c\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4C7y6HsOoGvz"
+ },
+ "source": [
+ "Calls for splitting and stacking together dimensions."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 76,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "p731PTUs2HXW",
+ "outputId": "b14c1d53-363c-4ecf-af23-3d52862d8db0"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "OrderedDict([('height', 8), ('q', 12), ('w', 96), ('c', 3)])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 76
+ }
+ ],
+ "source": [
+ "tensor = NamedTensor(ims[0], (\"h\", \"w\", \"c\"))\n",
+ "tensor.split(\"h\", (\"height\", \"q\"), height=8).shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "uD1iruomtanM",
+ "outputId": "bb4d884d-1c72-46c4-972b-4109cab5ed56"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "OrderedDict([('bh', 576), ('w', 96), ('c', 3)])"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 77
+ }
+ ],
+ "source": [
+ "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
+ "tensor.stack(('b', 'h'), \"bh\").shape\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8h6ZCcrgoeEg"
+ },
+ "source": [
+ "Ops can be chained."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 78,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "74kpc4j-t1Sb",
+ "outputId": "f357ed95-4ce2-45ca-eabb-25eb9ef115c2"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 78
+ }
+ ],
+ "source": [
+ "tensor.stack(('b', 'w'), \"bw\").transpose('h', 'bw', 'c')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZKXtJ4gSonIZ"
+ },
+ "source": [
+ "Just for fun, here are some of the crazier examples from *einops* in this notation."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 79,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 305
+ },
+ "id": "JnsFFFGPkxBs",
+ "outputId": "7a30c82c-0315-41d4-9279-745a7ddb649b"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 79
+ }
+ ],
+ "source": [
+ "tensor.split(\"b\", ('b1', 'b2'), b1=2)\\\n",
+ " .stack(('b2', 'h'), \"a\")\\\n",
+ " .stack(('b1', 'w'), \"d\")\\\n",
+ " .transpose('a', 'd', 'c')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 80,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 209
+ },
+ "id": "6XHpOv62kelh",
+ "outputId": "5c8a1f10-b136-4d95-d842-ec1f944fb122"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 80
+ }
+ ],
+ "source": [
+ "tensor.split(\"w\", ('w1', 'w2'), w2=2)\\\n",
+ " .stack(('h', 'w2'), 'a')\\\n",
+ " .stack(('b', 'w1'), 'd')\\\n",
+ " .transpose('a', 'd', 'c')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 81,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "9xusGrzNkVKW",
+ "outputId": "d84af7fc-ff4b-4b2d-bcd4-e2b5baca1a9c"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 81
+ }
+ ],
+ "source": [
+ "tensor.stack(('b', 'w'), 'a').transpose('h', 'a', 'c')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 82,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "nsR9xjHMCXv2",
+ "outputId": "b8fbd96b-1305-4914-ad26-e1f0025dddd2"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 82
+ }
+ ],
+ "source": [
+ "tensor.stack(('w', 'b'), 'a').transpose('h', 'a', 'c')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 83,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "OowFiE4jCkXH",
+ "outputId": "9b4014d7-c550-4a03-feb5-c3801ac944f2"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAIAAABt+uBvAAAM50lEQVR4nO1cWXMbV3a+ve/dWIiFBLiAEkHRkjIzkq3Y1qRmPDXOL0jVvEzlIQ/5OXlM3lKVh1SlkockldSU4/F4XOXKWIqtsWRLshaLIsAFG7H1vt7OA2haEonuBnUBMxV8T0D3wcXpD3c595zvAuv1emCO8cB/aAfOO8gf5Ftdxx32h6ZheJ4fhiFBEAzLiLIoKzKGYT+IS+OAzXiIhWHYbraH/SEIT7lLUmSxVOQFfpYuRWOmQwxCuLuzO+ydzg4AwPf8vdqeOlBn6VU0ZkpQ66Blm3aMUQiaB03LtGbiUTxmR5Bt2dpQS2Qagk6zPWV3kmJ2BA37w+TGtuU4dlxfmwlmR5BpmBPZG/pk9lPC7AjyPG8ie9/zp+TJRJgRQRDCcSvXOARBMB1fJsOMCMJxHEwYAOLEuYjyZ+cESU0WtVMUNSVPJsLsCJo0Pj4n8fTsCFLSSnJjhmNYjp2eM8kxO4I4jpMUKZEpBvKF3JTdSYqZToSFpUJ8v8BAYanAnY/xBWZMEI7j5bWyklbGrWgkRZZXy0pqgsE4bcw63TGC6ziD/tA0TN/zIYQESbAsK0qinPp/nw/6P4dzEYydZ8wJisGcoBjMCYrB7KoaMISmZZqWYVmmZVumbXY6nefPtvf299utTq/X0zTNtm0IQ4qiWJbLpLP5fKG0VNq4uLmxUc2kUzRN0TTFMDRJEjNzGxlBvudvP9l+8UoAg4E66A97A7WvagPN0GAAQxCqA+3xN08ePXzUarVhGJUEWa4scxwHAKAoamPj0p++9e61H7/J8wJNkzzPiiIvihxBTJcsZMv8MUGe727Xn7UPW71BF0J4bBCGYbvZufP5l08eP3FcN0mbxwQdQ0ml3/v5+7/42fsCLwAAMAxIEp9Oy6I4rcgbPUF9tffJH373yl1NM+7c/uO9e1/Zk2SaTxI0Qq5Q/NVf/PrHV39yHFWWSrlUKtlGb0JMfZIOQViv7f/bv/z77dv/MxE7Eei0mn/7d3/zz//6T55/lMal6Wklj6Y7SYdh+M39J598/Imm62hbhhB++F//0e12/uov/5plWIah0bZ/jOn2oIf3H3/04UfI2TnGnS9u/cM//j0MA2Jq+dkpElR/Xv/4tx9bUy5vffH5Hz746D9fXA3QYloEGbr+wW8+NK2pV5AhhHe++OzW559Nqf2pEAQh/PT3n/YHE5RSXweeZ/3u9x+22s1pND4Vgg5qtQcPH0+j5VPBMHS/d/jBb38TRoadZwN6ghzL/vLLu74/u7Ifw9CqOjw42P/m8UPkjSNb5kmKrF6uAgAGw3Yqt1DFxrYcBMGzx88AAFcv/UgUJFmWr169slG9WCgUREkEAA6Gg929nbtf/dH2TE3XHce1HdexXcOwT5ZbaZrCcAyG0LKMW7f/+1J1C8dR/uqI4yDbNGv1mm0n2kmUl1beevPae+//nGNfCpdFQSovLd948103tO7cvfXo4cNuvxcCAEJg246mmapmON99BcMchYiGoXcOO7Xa80rlAsInQkxQY2/Pth3fj9cd4Dh+8+Y7v/zzX4wzIHCiWtmSZVmSlQf37u41DiAIWY5hOSaXT3uup2qmphosy4zsbccGAHx9/975JSgIgnq9DkZShThUq9WrP/mTGCMMlEsrhqFbphEEwX7r+3WKoqlsVslmv69/uI4DANipb5uGzgvi2R7hJFAOV20wGAXNGBbTbDaTWa9WXTdeEENRdEpJbVYvFwoFkRciLAMY+L5v2U6jsT+R29FASVCz0RgttNGBP4Zh1UuXcBzvdoduAtGQIEgpKVVYKi1k0tGWrusAAHZ2tqPNJgIygsIwPGwfCQuj99ayJGVyOQBAEATPn+/rccozluUwDKyurMuygkf2Tc9zAQCNViMIkImvkBHkOY5hHj0qxzMRlsXFxeM8ju8HtVqjvts0rbFbNoZhAQCyIEmKwrFRLY/mPs3QrQnlfhFARpCh68fjRZKiJouFXP6VK5pmPH++v7291+ur/olIB8dxHCdxHM8XFkkialUZEeS4jqoOJvV/HJCtYvoLOQ2SJBRFHA5Pz3Lstpq17ToAYLX8hGVOahkwUeQkSZAkXvMslucAALWdbcexO73DoR4lJB4R5Pu+aSBLsCAjyDJf6tX5fEbXzSB4db3HCZyMkY6Fum7qutloAIJmC4s5WRJGmXmeFwiCiNAuwhACAIIAmhayITYtgiiaXCrld+uv7rApOmoSeQW6YQX77QaGDYeHJAV4nqFoOhifQgm/i78Mw0j+LdFARpB3InqWJD6XS3c6/RcvnkGaGYajPqURBNHtqiyNE3F1sdFyhgTICDq15+fyaYIkmo3D4ys4fpYy1mjVC4Kg39e14SCdlvL5TATXSfY6CYFsFRu3vchk5JXV4nEt9DXlPyRJhmHY66lPv90d9MdO2Ag11sgIinhyUeQvXlzOZhUMw14zp3X8MwR+cHDQ2d9vn9ogwowHsiEWXQLGCbxQzKYzsuUEr+O977+0NRkOdM/zV5aLrww3gkT2XOiYTuATTVOFfLpaXSkWFzj+LCrfkwc4TMPe22u/cs4BoQgdGUEMk2j99hyXIIhMVq5UlqrV1WIxyyXWQwcwcJxTdiS6bna7gxev8ByyUj2yrsjxiXwKYHC8kyRJQhSETEbx/UBVDU0zDMMG4w+9GIYejlkK2u2eKPJAPnqLMB+EjCBBTOpTpVTmcQYAcHlzk6Vf6j4BDHTdUlVD10wYwuW1FY7nAABpSdC04f5+/Y1qdVyzsiy+Ua0WiyUAgCQiEzIgI0hWkoqbh4P+uFsETiiyqMhiAKGq6jT9knvtyMqXphnHOxtJRqa0RjYHsRzHsYlmk06rheMx0RCB4+mUvLa6WC7nR+k3CGG71Yj4SBiGhmEBAAicEND1IJQZxWwu0QGLdqdjJJMzOI6jKOLa2hKGYc39PTduA2HbDgAgnckgjINQElQoFo9eRQaDfhA8efQoTHACcZT3Yllakflvnz2KtXddHwCwsFBI4GxSoCQoXyyOwkXLsr99utvp9D339D1Rf9D/5sGD2KjathzXccMwbOzXhlp8pR9CiGEgX1g8g/PjgLQISZJLpRIAwLZd1/U67f7Tp/WdnYN+Tw1erkTTNP3sydP7Dx4YcYmbTqvT3Nu9//CrcQaGaR40m51ud/RWkBRZQnkWBnHhcP3ixa+/vuc4308WpmGbht1oHPI8K8uCKPEjKS8A4NZnnw4HgwsXq9lMWhSEkwl53/fufn57Z6/WandfvA4hNExT03XNMEb7UlEQTMM8bHUwSKA9DoOYIFlRCovFU0vPpmmbpg2aXYoiKYrodgf7zUZv2L//8N7iUjmfL+ZzeUVRGIoJg8AwjGbjoFZ7ftBqmYbVajcAHhIk4cHAdV3LtiGEnuf5ru84jmVaYQDXV1flK1I6tYD2idBrFLcuX3bHTD0jeJ7veX6vp9XrTZIkAdgDXz6IbrPR2NO0mH88CcOwcuECS7O+5096gDgC6OUvLMtX1tdjzYTIyscZwPD8pc0tDGCO4yBsFj1BtuNWty6lUqloM7THCnGCWNu4kFHSAADXQZZvBVMRUNkujhPXb9yg6ShpLsMynHCKSPxsyJdKWxubGMAAAG4yGX9CTKEH2Q4AgBeEG2+/TUUmiRZyaCbUTKGwtbUlS0fbCzeZOikhpjLERi/S2exbb78dUafnBU5W5HF3EyKdy61WKteuXDnuOI57juegMAxfFLVkc7l3bt6UpLGZkPxinn4NkXwmn19eW/vpjRskSR4fkIE+DNApJBETBCFkX04tyqn0Oz/9s5Vy+dQNJI7jpZXSGVZlHMeLKysXqhffu3mT5zgAQBAEwXfpNIQLGWKCCIKorJcqlVIqJWHf5TQYlr16/fr169fTqdTJMJeiqJXKCpssVTKCIEnrW5euXfvRz95598Xf46gTYSCEyPTAUznMwnEMx+WKxayq6oOBbpo2juPFcjmTy7UPDuq12lBV/SAQONHxnDAMSZJcXl/pdbq9bn9cUnUElucXl8sra8ub6xfS8pGeiiAISRRlUZQkMZvLKhklSQUhIaZ42gfH8VRKTqVkz/NV1dB0A2CgXKkUSiW1328eHFzZeMN23Havreqq7drZXDaVSfW7fXWo+S8rz3CCyC8WF5eXyuXSUqGYElMEQXAsK/C8wPOKLAmSKMlicXEpm8+ifQr0BLEsW91849RbEIa25di26ziu5/nLC2XbsFRVVYdqr9/t9ruaruq5fAADx3E83ydJUhCETDaTz+dFXkjLaUWSOY7lOV6SRYZhaIbmOA7hxuIkZvpXpTiO8QLLC0fTzebqhWhB1HnA/Fh4DOYExWBOUAzmBMVgTlAM5gTFYE5QDOYExWBOUAzmBMVgTlAM5gTFYE5QDOYExWBOUAzmBMVg/lelMZj3oBj8L6WiqRlzbKpoAAAAAElFTkSuQmCC\n"
+ },
+ "metadata": {},
+ "execution_count": 83
+ }
+ ],
+ "source": [
+ "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
+ "tensor.mean('b')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 84,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 305
+ },
+ "id": "FYX0z4-aEsLh",
+ "outputId": "2b225fb2-26bf-44e7-ce91-4618af50caea"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 84
+ }
+ ],
+ "source": [
+ "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
+ "tensor.split('h', ('h1', 'h2'), h2 =2).split('w', ('w1', 'w2'), w2=2) \\\n",
+ " .mean(('h2', 'w2')).stack(('b', 'w1'), \"bw\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 85,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 305
+ },
+ "id": "BssZDH91Kjdv",
+ "outputId": "b613b0af-002c-4801-d43e-81c5388c5633"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 85
+ }
+ ],
+ "source": [
+ "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
+ "tensor.split('b', ('b1', 'b2'), b1 = 2)\\\n",
+ " .mean('c')\\\n",
+ " .stack((\"b1\", \"w\"), 'bw')\\\n",
+ " .stack(('b2', 'h'), 'bh')\\\n",
+ " .transpose('bh', 'bw')\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 86,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 209
+ },
+ "id": "tesLBQTbM2IO",
+ "outputId": "5a352787-f651-4c07-cc07-790496f540e1"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 86
+ }
+ ],
+ "source": [
+ "tensor.split('b', ('b1', 'b2'), b1=2).stack(('h', 'b1'), 'h').stack(('w', 'b2'), 'w')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "RONa1_CvpIJl"
+ },
+ "source": [
+ "## Proposal 5: Ban Indexing"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "95TGZJB5pXbW"
+ },
+ "source": [
+ "\n",
+ "Generally indexing is discouraged in this named tensor paradigm. Instead use functions like `index_select` above.\n",
+ "\n",
+ "There are some useful named alternative functions pulled over from torch. For example `unbind` pulls apart a dimension to a tuple.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "3jMIuUxIpn74",
+ "outputId": "32c2a1b7-c983-454e-9f18-1f34e9b445b8"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "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\n"
+ },
+ "metadata": {},
+ "execution_count": 87
+ }
+ ],
+ "source": [
+ "tensor = NamedTensor(ims, ('b', 'h', 'w', 'c'))\n",
+ "\n",
+ "# Returns a tuple\n",
+ "images = tensor.unbind(\"b\")\n",
+ "images[3]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FZcHQ_BvqJ6X"
+ },
+ "source": [
+ "The function `get` directly selects a slice of from a named dimension."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 88,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 113
+ },
+ "id": "qQCELxUgqB_v",
+ "outputId": "273666a5-404e-407e-dd32-199db529a516"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ ""
+ ],
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAAAAADH8yjkAAADBElEQVR4nGN8xkBbwERj80ctGLVg1IJRC0YtGLVg1IJRC6gEWIhW+evciev3Xn79xcEpJCdnYKJApDZG4hpe/w+s3fkVRUTRL0yRahb8WzP1NqYok3eROnUsOFd1CbsEa3oxO+UW/JvU+xenpP48SUot+J62F5+02Fpl/PoJJdOPYXjNZ3gV+ogiC37GnyXggheJPyixIPcUAfMZGK7XUWDB/C0EzWdgWHIanyzeSL7jht/7UKCzkxG3JF4f1BJlPsOVPXgk8ZVFuw+i8nm97HQF+T6/u7F3+ycUiemuuA3BF0QeKBmYOTObH8b+OHHWP2S5Ywo4DcETREdQzOdZXAU3n4G/bjZKGbEBtyl4LJiHzGGc4oAi6dmOzNtOjgWf9iHzot3QpCPskThXPzHgArgt2PELicNWjCGfhcT+hzs/4rYAJQk5i2PIW3IjcXCU53gtOIPM8cSUZ9FF4twi3YLXj5F5+lhUiCKxsVR4MHfgkriDwrPHoQoGXuCUwemDx7gksIIPv2lswf93JFvwkSQLGL6RbMF30izAWe7itIC4khoOfuGSGLjGLydp5rCRbAEHaRawkmyBEGkWcJFsgQxpFgjgksBZVMii8C6K4lBGEOD0AWrLnED7kBwLBJSQeQeobwGDKTJn4RfqW4DS1nlT/p/qFjjzIPPWF+MskMm1gN0XhbvC8wQ2VX8P5vfitQBPy+62A1qwmKU7oBYgnw7v3v2ewW0BmRYwpGxDF2G3MVBTEeTi/vHp4/sbly7e/svAwMCgfJhcCx45EFVms9zD14LGV1zL5RNjPsMfvLkQb32QY0OUDXfJtoB5mjQxFtzBJ4m/RhNZLUGEBeT7gIFBYa0CbS1gUNzuQFsLGPiXtvESUPIGd++AmFYFY8LBaJw1LgTgi2XiBqSezF37BpecsLuPDZ6cRuSIF8Of/XsOYmYoNhMrG2NmvBqJtYCBgYHh2dWr9148//jjx38uLm4eaRUVFS2C41EkWUAWGPrjpqMWjFowasGoBaMWjFrAwMDAAAAx6rlALW9LlAAAAABJRU5ErkJggg==\n"
+ },
+ "metadata": {},
+ "execution_count": 88
+ }
+ ],
+ "source": [
+ "# Returns a tuple\n",
+ "images = tensor.get(\"b\", 0).unbind(\"c\")\n",
+ "images[1]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "JeYS9if9qwjI"
+ },
+ "source": [
+ "## Proposal 6: Private Dimensions"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "zYF2PvGthqWR"
+ },
+ "source": [
+ "Finally named tensor attempts to let you directly hide dimensions that should not be accessed by internal functions. The function `mask_to` will keep around a left side mask that protects any earlier dimensions from manipulations by functions. The simplest example uses a mask to drop the `batch` dimension. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 89,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ },
+ "id": "Ror8wojh1ba-",
+ "outputId": "95351f3b-b5b4-4819-8f4a-ace0cdff99bc"
+ },
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "'Error received: Dimension batch is masked'"
+ ],
+ "application/vnd.google.colaboratory.intrinsic+json": {
+ "type": "string"
+ }
+ },
+ "metadata": {},
+ "execution_count": 89
+ }
+ ],
+ "source": [
+ "def bad_function(x, y):\n",
+ " # Accesses the private batch dimension\n",
+ " return x.mean(\"batch\")\n",
+ "\n",
+ "x = ntorch.randn((10, 100, 100), names=(\"batch\", \"height\", \"width\"))\n",
+ "y = ntorch.randn((10, 100, 100), names=(\"batch\", \"height\", \"width\"))\n",
+ "\n",
+ "try:\n",
+ " bad_function(x.mask_to(\"batch\"), y)\n",
+ "except RuntimeError as e:\n",
+ " error = \"Error received: \" + str(e)\n",
+ "error"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hpwkRrV0q8JL"
+ },
+ "source": [
+ "This is weak dynamic check and can be turned off by internal functions. In future versions, perhaps we can add function annotations to lift non-named functions to respect these properties. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "QcTNI7Iuh8AT"
+ },
+ "source": [
+ "# Example: Neural Attention"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uUG43UwVrZbc"
+ },
+ "source": [
+ "To demonstrate why these choices lead to better encapsulation properties, let's consider a real-world deep learning example. \n",
+ "\n",
+ "This example was proposed by my colleague Tim Rocktashel in the blog post describing einsum (https://rockt.github.io/2018/04/30/einsum). Tim's code was proposed as a better alternative to raw PyTorch. While I agree that einsum is a step forward, it still falls into many of the traps described above. \n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Gs3HJEErsTvs"
+ },
+ "source": [
+ "Consider the problem of neural attention, which requires computing,\n",
+ "\n",
+ "$$\n",
+ "\\begin{align*}\n",
+ "\\mathbf{M}_t &= \\tanh(\\mathbf{W}^y\\mathbf{Y}+(\\mathbf{W}^h\\mathbf{h}_t+\\mathbf{W}^r\\mathbf{r}_{t-1})\\otimes \\mathbf{e}_L) & \\mathbf{M}_t &\\in\\mathbb{R}^{k\\times L}\\\\\n",
+ "\\alpha_t &= \\text{softmax}(\\mathbf{w}^T\\mathbf{M}_t)&\\alpha_t&\\in\\mathbb{R}^L\\\\\n",
+ "\\mathbf{r}_t &= \\mathbf{Y}\\alpha^T_t + \\tanh(\\mathbf{W}^t\\mathbf{r}_{t-1})&\\mathbf{r}_t&\\in\\mathbb{R}^k\n",
+ "\\end{align*}\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CGvKocKguAdu"
+ },
+ "source": [
+ "First we setup the parameters. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 90,
+ "metadata": {
+ "id": "PP3eiilYtUu9"
+ },
+ "outputs": [],
+ "source": [
+ "def random_ntensors(names, num=1, requires_grad=False):\n",
+ " tensors = [ntorch.randn(tuple(names.values()), names=tuple(names.keys()), requires_grad=requires_grad)\n",
+ " for i in range(0, num)]\n",
+ " return tensors[0] if num == 1 else tensors\n",
+ "\n",
+ "class Param:\n",
+ " def __init__(self, in_hid, out_hid):\n",
+ " torch.manual_seed(0)\n",
+ " self.WY, self.Wh, self.Wr, self.Wt = \\\n",
+ " random_ntensors(dict(inhid=in_hid, outhid=out_hid),\n",
+ " num=4, requires_grad=True)\n",
+ " self.bM, self.br, self.w = \\\n",
+ " random_ntensors(dict(outhid=out_hid), \n",
+ " num=3,\n",
+ " requires_grad=True)\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iERFd2mquEc2"
+ },
+ "source": [
+ "Now consider the tensor-based einsum implementation of this function. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 91,
+ "metadata": {
+ "id": "oD5eGKI_sZTJ"
+ },
+ "outputs": [],
+ "source": [
+ "# Einsum Implementation\n",
+ "import torch.nn.functional as F\n",
+ "def einsum_attn(params, Y, ht, rt1):\n",
+ " # -- [batch_size x hidden_dimension]\n",
+ " tmp = torch.einsum(\"ik,kl->il\", [ht, params.Wh.values]) + \\\n",
+ " torch.einsum(\"ik,kl->il\", [rt1, params.Wr.values])\n",
+ "\n",
+ " Mt = torch.tanh(torch.einsum(\"ijk,kl->ijl\", [Y, params.WY.values]) + \\\n",
+ " tmp.unsqueeze(1).expand_as(Y) + params.bM.values)\n",
+ " # -- [batch_size x sequence_length]\n",
+ " at = F.softmax(torch.einsum(\"ijk,k->ij\", [Mt, params.w.values]), dim=-1)\n",
+ "\n",
+ " # -- [batch_size x hidden_dimension]\n",
+ " rt = torch.einsum(\"ijk,ij->ik\", [Y, at]) + \\\n",
+ " torch.tanh(torch.einsum(\"ij,jk->ik\", [rt1, params.Wt.values]) + \n",
+ " params.br.values)\n",
+ "\n",
+ " # -- [batch_size x hidden_dimension], [batch_size x sequence_dimension]\n",
+ " return rt, at"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FGbiXmf2uKN5"
+ },
+ "source": [
+ "This implementation is an improvement over the naive PyTorch implementation. It removes many of the \n",
+ "views and transposes that would be necessary to make this work. *However, it still uses `squeeze`, references the private batch dim, and usees comments that are not enforced.*"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TzmJKd1UuyQd"
+ },
+ "source": [
+ "Consider instead the `namedtensor` version: "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 92,
+ "metadata": {
+ "id": "f5_BX7z7szLk"
+ },
+ "outputs": [],
+ "source": [
+ "def namedtensor_attn(params, Y, ht, rt1):\n",
+ " tmp = ht.dot(\"inhid\", params.Wh) + rt1.dot(\"inhid\", params.Wr)\n",
+ " at = ntorch.tanh(Y.dot(\"inhid\", params.WY) + tmp + params.bM) \\\n",
+ " .dot(\"outhid\", params.w) \\\n",
+ " .softmax(\"seqlen\")\n",
+ "\n",
+ " rt = Y.dot(\"seqlen\", at) + \\\n",
+ " ntorch.tanh(rt1.dot(\"inhid\", params.Wt) + params.br)\n",
+ " return rt, at\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KvtY1nWAsWVm"
+ },
+ "source": [
+ "This code avoids all three traps.\n",
+ "\n",
+ "(Trap 1) The code never mentions the `batch` dim.\n",
+ "\n",
+ "(Trap 2) All broadcasting is done directly with contractions, there are no views.\n",
+ "\n",
+ "(Trap 3) Operations across dims are explicit. For instance, the softmax is clearly over the seqlen. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 93,
+ "metadata": {
+ "id": "BKolTWWlvkzO"
+ },
+ "outputs": [],
+ "source": [
+ "# Run Einsum\n",
+ "in_hid = 7; out_hid = 7\n",
+ "Y = torch.randn(3, 5, in_hid)\n",
+ "ht, rt1 = torch.randn(3, in_hid), torch.randn(3, in_hid)\n",
+ "params = Param(in_hid, out_hid)\n",
+ "r, a = einsum_attn(params, Y, ht, rt1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 94,
+ "metadata": {
+ "id": "jmqZQbzg-x8_"
+ },
+ "outputs": [],
+ "source": [
+ "# Run Named Tensor (hiding batch)\n",
+ "Y = NamedTensor(Y, names=(\"batch\", \"seqlen\", \"inhid\"), mask=1)\n",
+ "ht = NamedTensor(ht, names=(\"batch\", \"inhid\"), mask=1)\n",
+ "rt1 = NamedTensor(rt1, names=(\"batch\", \"inhid\"), mask=1)\n",
+ "nr, na = namedtensor_attn(params, Y, ht, rt1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bHUQllYYw4Zc"
+ },
+ "source": [
+ "# Conclusion / Request for Help"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vzmW3BZnxFGD"
+ },
+ "source": [
+ "Tools for deep learning help researchers implement standard models, but they also impact what researchers try. Current models can be built fine with the tools we have, but the programming practices are not going to scale to new models. \n",
+ "\n",
+ "(For instance, one space we have been working on recently is discrete latent variable models which often have many problem specific variables each with their own variable dimension. This setting breaks the current tensor paradigm almost immediately. )\n",
+ "\n",
+ "This blog post is just a prototype of where this approach could go. If you are interested, I would love contributors to the build out this library properly. Some ideas if you want to send a PR to [namedtensor](https://github.com/harvardnlp/NamedTensor). Some ideas:\n",
+ "\n",
+ "1) **Extending beyond PyTorch**: Can we generalize this approach in a way that supports NumPy and Tensorflow? \n",
+ "\n",
+ "\n",
+ "2) **Interacting with PyTorch Modules**: Can we \"lift\" PyTorch modules with type annotations, so that we know how they change inputs?\n",
+ "\n",
+ "\n",
+ "3) **Error Checking**: Can we add annotations to functions giving pre- and post -conditions so that dimensions are automatically checked.\n",
+ "\n"
+ ]
}
- ],
- "source": [
- "tensor.narrow( 30, 50, h='narowedheight').get(\"b\", 0)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "JeYS9if9qwjI"
- },
- "source": [
- "## Proposal 6: Private Dimensions"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "zYF2PvGthqWR"
- },
- "source": [
- "Finally named tensor attempts to let you directly hide dimensions that should not be accessed by internal functions. The function `mask_to` will keep around a left side mask that protects any earlier dimensions from manipulations by functions. The simplest example uses a mask to drop the `batch` dimension. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 39,
- "metadata": {
+ ],
+ "metadata": {
"colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "colab_type": "code",
- "id": "6TruEsQqhltl",
- "outputId": "5765f493-531e-4a58-bc47-ed4cb99ec2ed"
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'Error received: Dimension batch is masked'"
- ]
- },
- "execution_count": 39,
- "metadata": {},
- "output_type": "execute_result"
+ "collapsed_sections": [],
+ "name": "NamedTensor.ipynb",
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3.9.7 ('raffellab')",
+ "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.9.7"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "c17af479b4f924a1749320f1b412e40fcea5ba5f8714a0861f33494f35331f04"
+ }
}
- ],
- "source": [
- "def bad_function(x, y):\n",
- " # Accesses the private batch dimension\n",
- " return x.mean(\"batch\")\n",
- "\n",
- "x = ntorch.randn(dict(batch=10, height=100, width=100))\n",
- "y = ntorch.randn(dict(batch=10, height=100, width=100))\n",
- "\n",
- "try:\n",
- " bad_function(x.mask_to(\"batch\"), y)\n",
- "except RuntimeError as e:\n",
- " error = \"Error received: \" + str(e)\n",
- "error"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "hpwkRrV0q8JL"
- },
- "source": [
- "This is weak dynamic check and can be turned off by internal functions. In future versions, perhaps we can add function annotations to lift non-named functions to respect these properties. "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "QcTNI7Iuh8AT"
- },
- "source": [
- "# Example: Neural Attention"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "uUG43UwVrZbc"
- },
- "source": [
- "To demonstrate why these choices lead to better encapsulation properties, let's consider a real-world deep learning example. \n",
- "\n",
- "This example was proposed by my colleague Tim Rocktashel in the blog post describing einsum (https://rockt.github.io/2018/04/30/einsum). Tim's code was proposed as a better alternative to raw PyTorch. While I agree that einsum is a step forward, it still falls into many of the traps described above. \n",
- "\n",
- "\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "Gs3HJEErsTvs"
- },
- "source": [
- "Consider the problem of neural attention, which requires computing,\n",
- "\n",
- "$$\n",
- "\\begin{align*}\n",
- "\\mathbf{M}_t &= \\tanh(\\mathbf{W}^y\\mathbf{Y}+(\\mathbf{W}^h\\mathbf{h}_t+\\mathbf{W}^r\\mathbf{r}_{t-1})\\otimes \\mathbf{e}_L) & \\mathbf{M}_t &\\in\\mathbb{R}^{k\\times L}\\\\\n",
- "\\alpha_t &= \\text{softmax}(\\mathbf{w}^T\\mathbf{M}_t)&\\alpha_t&\\in\\mathbb{R}^L\\\\\n",
- "\\mathbf{r}_t &= \\mathbf{Y}\\alpha^T_t + \\tanh(\\mathbf{W}^t\\mathbf{r}_{t-1})&\\mathbf{r}_t&\\in\\mathbb{R}^k\n",
- "\\end{align*}\n",
- "$$"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "CGvKocKguAdu"
- },
- "source": [
- "First we setup the parameters. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 40,
- "metadata": {
- "colab": {},
- "colab_type": "code",
- "id": "PP3eiilYtUu9"
- },
- "outputs": [],
- "source": [
- "def random_ntensors(names, num=1, requires_grad=False):\n",
- " tensors = [ntorch.randn(names, requires_grad=requires_grad)\n",
- " for i in range(0, num)]\n",
- " return tensors[0] if num == 1 else tensors\n",
- "\n",
- "class Param:\n",
- " def __init__(self, in_hid, out_hid):\n",
- " torch.manual_seed(0)\n",
- " self.WY, self.Wh, self.Wr, self.Wt = \\\n",
- " random_ntensors(dict(inhid=in_hid, outhid=out_hid),\n",
- " num=4, requires_grad=True)\n",
- " self.bM, self.br, self.w = \\\n",
- " random_ntensors(dict(outhid=out_hid), \n",
- " num=3,\n",
- " requires_grad=True)\n",
- " "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "iERFd2mquEc2"
- },
- "source": [
- "Now consider the tensor-based einsum implementation of this function. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 41,
- "metadata": {
- "colab": {},
- "colab_type": "code",
- "id": "oD5eGKI_sZTJ"
- },
- "outputs": [],
- "source": [
- "# Einsum Implementation\n",
- "import torch.nn.functional as F\n",
- "def einsum_attn(params, Y, ht, rt1):\n",
- " # -- [batch_size x hidden_dimension]\n",
- " tmp = torch.einsum(\"ik,kl->il\", [ht, params.Wh.values]) + \\\n",
- " torch.einsum(\"ik,kl->il\", [rt1, params.Wr.values])\n",
- "\n",
- " Mt = torch.tanh(torch.einsum(\"ijk,kl->ijl\", [Y, params.WY.values]) + \\\n",
- " tmp.unsqueeze(1).expand_as(Y) + params.bM.values)\n",
- " # -- [batch_size x sequence_length]\n",
- " at = F.softmax(torch.einsum(\"ijk,k->ij\", [Mt, params.w.values]), dim=-1)\n",
- "\n",
- " # -- [batch_size x hidden_dimension]\n",
- " rt = torch.einsum(\"ijk,ij->ik\", [Y, at]) + \\\n",
- " torch.tanh(torch.einsum(\"ij,jk->ik\", [rt1, params.Wt.values]) + \n",
- " params.br.values)\n",
- "\n",
- " # -- [batch_size x hidden_dimension], [batch_size x sequence_dimension]\n",
- " return rt, at"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "FGbiXmf2uKN5"
- },
- "source": [
- "This implementation is an improvement over the naive PyTorch implementation. It removes many of the \n",
- "views and transposes that would be necessary to make this work. *However, it still uses `squeeze`, references the private batch dim, and usees comments that are not enforced.*"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "TzmJKd1UuyQd"
- },
- "source": [
- "Consider instead the `namedtensor` version: "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 42,
- "metadata": {
- "colab": {},
- "colab_type": "code",
- "id": "f5_BX7z7szLk"
- },
- "outputs": [],
- "source": [
- "def namedtensor_attn(params, Y, ht, rt1):\n",
- " tmp = ht.dot(\"inhid\", params.Wh) + rt1.dot(\"inhid\", params.Wr)\n",
- " at = ntorch.tanh(Y.dot(\"inhid\", params.WY) + tmp + params.bM) \\\n",
- " .dot(\"outhid\", params.w) \\\n",
- " .softmax(\"seqlen\")\n",
- "\n",
- " rt = Y.dot(\"seqlen\", at).stack(inhid=('outhid',)) + \\\n",
- " ntorch.tanh(rt1.dot(\"inhid\", params.Wt) + params.br)\n",
- " return rt, at\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "KvtY1nWAsWVm"
- },
- "source": [
- "This code avoids all three traps.\n",
- "\n",
- "(Trap 1) The code never mentions the `batch` dim.\n",
- "\n",
- "(Trap 2) All broadcasting is done directly with contractions, there are no views.\n",
- "\n",
- "(Trap 3) Operations across dims are explicit. For instance, the softmax is clearly over the seqlen. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 43,
- "metadata": {
- "colab": {},
- "colab_type": "code",
- "id": "BKolTWWlvkzO"
- },
- "outputs": [],
- "source": [
- "# Run Einsum\n",
- "in_hid = 7; out_hid = 7\n",
- "Y = torch.randn(3, 5, in_hid)\n",
- "ht, rt1 = torch.randn(3, in_hid), torch.randn(3, in_hid)\n",
- "params = Param(in_hid, out_hid)\n",
- "r, a = einsum_attn(params, Y, ht, rt1)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 44,
- "metadata": {
- "colab": {},
- "colab_type": "code",
- "id": "jmqZQbzg-x8_"
- },
- "outputs": [],
- "source": [
- "# Run Named Tensor (hiding batch)\n",
- "Y = NamedTensor(Y, (\"batch\", \"seqlen\", \"inhid\"), mask=1)\n",
- "ht = NamedTensor(ht, (\"batch\", \"inhid\"), mask=1)\n",
- "rt1 = NamedTensor(rt1, (\"batch\", \"inhid\"), mask=1)\n",
- "nr, na = namedtensor_attn(params, Y, ht, rt1)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "bHUQllYYw4Zc"
- },
- "source": [
- "# Conclusion / Request for Help"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "colab_type": "text",
- "id": "vzmW3BZnxFGD"
- },
- "source": [
- "Tools for deep learning help researchers implement standard models, but they also impact what researchers try. Current models can be built fine with the tools we have, but the programming practices are not going to scale to new models. \n",
- "\n",
- "(For instance, one space we have been working on recently is discrete latent variable models which often have many problem specific variables each with their own variable dimension. This setting breaks the current tensor paradigm almost immediately. )\n",
- "\n",
- "This blog post is just a prototype of where this approach could go. If you are interested, I would love contributors to the build out this library properly. Some ideas if you want to send a PR to [namedtensor](https://github.com/harvardnlp/NamedTensor). Some ideas:\n",
- "\n",
- "1) **Extending beyond PyTorch**: Can we generalize this approach in a way that supports NumPy and Tensorflow? \n",
- "\n",
- "\n",
- "2) **Interacting with PyTorch Modules**: Can we \"lift\" PyTorch modules with type annotations, so that we know how they change inputs?\n",
- "\n",
- "\n",
- "3) **Error Checking**: Can we add annotations to functions giving pre- and post -conditions so that dimensions are automatically checked.\n",
- "\n"
- ]
- }
- ],
- "metadata": {
- "colab": {
- "collapsed_sections": [],
- "name": "NamedTensor.ipynb",
- "provenance": [],
- "version": "0.3.2"
- },
- "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.8"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
\ No newline at end of file