{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import torch\n", "import torchvision\n", "import torch.nn as nn\n", "from torch.autograd import Variable\n", "\n", "# Relative import of code from distiller, w/o installing the package\n", "import os\n", "import sys\n", "import pandas as pd\n", "import distiller\n", "import distiller.models as models\n", "from distiller.apputils import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Performance overview\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = models.create_model(pretrained=False, dataset='imagenet', arch='resnet50', parallel=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dummy_input = Variable(torch.randn(1, 3, 224, 224), requires_grad=False)\n", "df = distiller.model_performance_summary(model, dummy_input, batch_size=1)\n", "display(df)\n", "\n", "total_macs = df['MACs'].sum()\n", "\n", "print(\"Total MACs: \" + \"{:,}\".format(total_macs))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Let's take a look at how our compute is distibuted:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"MAC distribution:\")\n", "counts = df['MACs'].value_counts()\n", "print(counts)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Let's look at which convolutions kernel sizes we're using, and how many instances:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"Convolution kernel size distribution:\")\n", "counts = df['Attrs'].value_counts()\n", "print(counts)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Let's look at how the MACs are distributed between the layers and the convolution kernel sizes" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "def get_layer_color(layer_type, attrs):\n", " if layer_type == \"Conv2d\":\n", " if attrs == 'k=(1, 1)':\n", " return 'tomato'\n", " elif attrs == 'k=(3, 3)':\n", " return 'limegreen'\n", " else:\n", " return 'steelblue'\n", " return 'indigo'\n", "\n", "df_compute = df['MACs']\n", "ax = df_compute.plot.bar(figsize=[15,10], title=\"MACs\", \n", " color=[get_layer_color(layer_type, attrs) for layer_type,attrs in zip(df['Type'], df['Attrs'])])\n", "\n", "ax.set_xticklabels(df.Name, rotation=90);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### How do the Weights and Feature-maps footprints distribute across the layers:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df['FM volume'] = df['IFM volume'] + df['OFM volume']\n", "df_footprint = df[['FM volume', 'Weights volume']]\n", "ax = df_footprint.plot.bar(figsize=[15,10], title=\"Footprint\");\n", "ax.set_xticklabels(df.Name, rotation=90);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### How the Arithmetic Intensity distributes across the layers:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df_performance = df\n", "df_performance['raw traffic'] = df_footprint['FM volume'] + df_footprint['Weights volume']\n", "df_performance['arithmetic intensity'] = df['MACs'] / df_performance['raw traffic']\n", "df_performance2 = df_performance['arithmetic intensity']\n", "ax = df_performance2.plot.bar(figsize=[15,10], title=\"Arithmetic Intensity\");\n", "ax.set_xticklabels(df.Name, rotation=90);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ResNet20 channel pruning using SSL\n", "\n", "Let's see how many MACs we saved by using SSL to prune filters from ResNet20:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "resnet20_dense = models.create_model(pretrained=False, dataset='cifar10', arch='resnet20_cifar', parallel=True)\n", "resnet20_sparse = models.create_model(pretrained=False, dataset='cifar10', arch='resnet20_cifar', parallel=True)\n", "checkpoint_file = \"../examples/ssl/checkpoints/checkpoint_trained_channel_regularized_resnet20_finetuned.pth.tar\" \n", "load_checkpoint(resnet20_sparse, checkpoint_file);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dummy_input = Variable(torch.randn(1, 3, 32, 32), requires_grad=False)\n", "df_dense = distiller.model_performance_summary(resnet20_dense, dummy_input, batch_size=1)\n", "df_sparse = distiller.model_performance_summary(resnet20_sparse, dummy_input, batch_size=1)\n", "\n", "dense_macs = df_dense['MACs'].sum()\n", "sparse_macs = df_sparse['MACs'].sum()\n", "\n", "print(\"Dense MACs: \" + \"{:,}\".format(int(dense_macs)))\n", "print(\"Sparse MACs: \" + \"{:,}\".format(int(sparse_macs)))\n", "print(\"Saved MACs: %.2f%%\" % ((1 - sparse_macs/dense_macs)*100))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 2 }