{
  "nbformat": 4,
  "nbformat_minor": 0,
  "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.7.6"
    },
    "colab": {
      "name": "yamnet_visualization.ipynb",
      "provenance": []
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "xcZmKVHusxQT"
      },
      "source": [
        "# Copyright 2019 The TensorFlow Authors All Rights Reserved.\n",
        "#\n",
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "#     http://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License.\n",
        "# =============================================================================="
      ],
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "0sDpjNbksxQa"
      },
      "source": [
        "# Visualization of the YAMNet audio event classification model.\n",
        "# See https://github.com/tensorflow/models/tree/master/research/audioset/yamnet/\n",
        "#\n",
        "# This notebook can be run in Google Colab at https://colab.research.google.com\n",
        "# by either downloading this ipynb and uploading it, or by looking up the\n",
        "# notebook directly on GitHub in Colab's \"Open notebook\" dialog."
      ],
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hnI3jFRHs-N7",
        "outputId": "24b5696f-e4cb-4d49-bddc-40ab3ef211b9",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "# Install required packages.\n",
        "!pip install soundfile\n",
        "!git clone https://github.com/tensorflow/models.git\n",
        "%cd models/research/audioset/yamnet\n",
        "\n",
        "# Download YAMNet data\n",
        "!curl -O https://storage.googleapis.com/audioset/yamnet.h5\n",
        "\n",
        "# Download audio for testing\n",
        "!curl -O https://storage.googleapis.com/audioset/speech_whistling2.wav\n",
        "\n",
        "!ls -l"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Collecting soundfile\n",
            "  Downloading https://files.pythonhosted.org/packages/eb/f2/3cbbbf3b96fb9fa91582c438b574cff3f45b29c772f94c400e2c99ef5db9/SoundFile-0.10.3.post1-py2.py3-none-any.whl\n",
            "Requirement already satisfied: cffi>=1.0 in /usr/local/lib/python3.6/dist-packages (from soundfile) (1.14.3)\n",
            "Requirement already satisfied: pycparser in /usr/local/lib/python3.6/dist-packages (from cffi>=1.0->soundfile) (2.20)\n",
            "Installing collected packages: soundfile\n",
            "Successfully installed soundfile-0.10.3.post1\n",
            "Cloning into 'models'...\n",
            "remote: Enumerating objects: 67, done.\u001b[K\n",
            "remote: Counting objects: 100% (67/67), done.\u001b[K\n",
            "remote: Compressing objects: 100% (65/65), done.\u001b[K\n",
            "remote: Total 46144 (delta 26), reused 43 (delta 2), pack-reused 46077\u001b[K\n",
            "Receiving objects: 100% (46144/46144), 551.17 MiB | 32.01 MiB/s, done.\n",
            "Resolving deltas: 100% (31621/31621), done.\n",
            "/content/models/research/audioset/yamnet\n",
            "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n",
            "                                 Dload  Upload   Total   Spent    Left  Speed\n",
            "100 14.5M  100 14.5M    0     0  17.0M      0 --:--:-- --:--:-- --:--:-- 17.0M\n",
            "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n",
            "                                 Dload  Upload   Total   Spent    Left  Speed\n",
            "100  153k  100  153k    0     0  1314k      0 --:--:-- --:--:-- --:--:-- 1314k\n",
            "total 15296\n",
            "-rw-r--r-- 1 root root     7816 Oct 22 17:31 export.py\n",
            "-rw-r--r-- 1 root root     7490 Oct 22 17:31 features.py\n",
            "-rw-r--r-- 1 root root     2307 Oct 22 17:31 inference.py\n",
            "-rw-r--r-- 1 root root     1847 Oct 22 17:31 params.py\n",
            "-rw-r--r-- 1 root root     5012 Oct 22 17:31 README.md\n",
            "-rw-r--r-- 1 root root   157484 Oct 22 17:31 speech_whistling2.wav\n",
            "-rw-r--r-- 1 root root    14096 Oct 22 17:31 yamnet_class_map.csv\n",
            "-rw-r--r-- 1 root root 15296092 Oct 22 17:31 yamnet.h5\n",
            "-rw-r--r-- 1 root root     5549 Oct 22 17:31 yamnet.py\n",
            "-rw-r--r-- 1 root root     2564 Oct 22 17:31 yamnet_test.py\n",
            "-rw-r--r-- 1 root root   140923 Oct 22 17:31 yamnet_visualization.ipynb\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "M0woGtbhsxQg"
      },
      "source": [
        "# Imports.\n",
        "import numpy as np\n",
        "import soundfile as sf\n",
        "\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "import params as yamnet_params\n",
        "import yamnet as yamnet_model\n",
        "import tensorflow as tf"
      ],
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jt2v3i94sxQl"
      },
      "source": [
        "# Read in the audio.\n",
        "wav_file_name = 'speech_whistling2.wav'\n",
        "wav_data, sr = sf.read(wav_file_name, dtype=np.int16)\n",
        "waveform = wav_data / 32768.0"
      ],
      "execution_count": 5,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "HiLKl_rVUqHJ",
        "outputId": "1a7c0344-6dd0-4228-9e62-611ad8847f84",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "source": [
        "# The graph is designed for a sampling rate of 16 kHz, but higher rates should work too.\n",
        "# We also generate scores at a 10 Hz frame rate.\n",
        "params = yamnet_params.Params(sample_rate=sr, patch_hop_seconds=0.1)\n",
        "print(\"Sample rate =\", params.sample_rate)"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Sample rate = 16000\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bHNJU9JUsxQs"
      },
      "source": [
        "# Set up the YAMNet model.\n",
        "class_names = yamnet_model.class_names('yamnet_class_map.csv')\n",
        "yamnet = yamnet_model.yamnet_frames_model(params)\n",
        "yamnet.load_weights('yamnet.h5')"
      ],
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XCrhG2WrsxQx"
      },
      "source": [
        "# Run the model.\n",
        "scores, embeddings, spectrogram = yamnet(waveform)\n",
        "scores = scores.numpy()\n",
        "spectrogram = spectrogram.numpy()"
      ],
      "execution_count": 8,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XN67xLQasxQ2",
        "outputId": "9b0744bd-bc2f-4996-c9d9-c7ad2e08725a",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 483
        }
      },
      "source": [
        "# Visualize the results.\n",
        "plt.figure(figsize=(10, 8))\n",
        "\n",
        "# Plot the waveform.\n",
        "plt.subplot(3, 1, 1)\n",
        "plt.plot(waveform)\n",
        "plt.xlim([0, len(waveform)])\n",
        "# Plot the log-mel spectrogram (returned by the model).\n",
        "plt.subplot(3, 1, 2)\n",
        "plt.imshow(spectrogram.T, aspect='auto', interpolation='nearest', origin='bottom')\n",
        "\n",
        "# Plot and label the model output scores for the top-scoring classes.\n",
        "mean_scores = np.mean(scores, axis=0)\n",
        "top_N = 10\n",
        "top_class_indices = np.argsort(mean_scores)[::-1][:top_N]\n",
        "plt.subplot(3, 1, 3)\n",
        "plt.imshow(scores[:, top_class_indices].T, aspect='auto', interpolation='nearest', cmap='gray_r')\n",
        "# Compensate for the patch_window_seconds (0.96s) context window to align with spectrogram.\n",
        "patch_padding = (params.patch_window_seconds / 2) / params.patch_hop_seconds\n",
        "plt.xlim([-patch_padding, scores.shape[0] + patch_padding])\n",
        "# Label the top_N classes.\n",
        "yticks = range(0, top_N, 1)\n",
        "plt.yticks(yticks, [class_names[top_class_indices[x]] for x in yticks])\n",
        "_ = plt.ylim(-0.5 + np.array([top_N, 0]))\n"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "[encoded data, 130220 characters]\n",
            "text/plain": [
              "<Figure size 720x576 with 3 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    }
  ]
}