{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "33442feb-6868-af07-38c4-c7fb46afede2"
      },
      "source": [
        "# In this notebook, we'll show how to explore data in the TFRecord format on a smaller scale. To reach the scalability that TensorFlow/Google Cloud can do, please refer to the code in their github https://github.com/google/youtube-8m"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "0d24983c-6c8c-829d-2423-5db0cc6d5ced"
      },
      "outputs": [],
      "source": [
        "# This Python 3 environment comes with many helpful analytics libraries installed\n",
        "# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n",
        "# For example, here's several helpful packages to load in \n",
        "\n",
        "import numpy as np # linear algebra\n",
        "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n",
        "\n",
        "# Input data files are available in the \"../input/\" directory.\n",
        "# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n",
        "\n",
        "from subprocess import check_output\n",
        "print(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))\n",
        "\n",
        "# Any results you write to the current directory are saved as output."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "d27744ac-7d20-6535-1ecd-c3f81a04567b"
      },
      "outputs": [],
      "source": [
        "import tensorflow as tf\n",
        "import numpy as np\n",
        "from IPython.display import YouTubeVideo\n",
        "\n",
        "\n",
        "video_lvl_record = \"../input/video_level/train-1.tfrecord\"\n",
        "frame_lvl_record = \"../input/frame_level/train-1.tfrecord\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "26264c1a-1ed5-ce2c-44e0-a2e2296ff458"
      },
      "outputs": [],
      "source": [
        "vid_ids = []\n",
        "labels = []\n",
        "mean_rgb = []\n",
        "mean_audio = []\n",
        "\n",
        "for example in tf.python_io.tf_record_iterator(video_lvl_record):\n",
        "    tf_example = tf.train.Example.FromString(example)\n",
        "\n",
        "    vid_ids.append(tf_example.features.feature['video_id'].bytes_list.value[0].decode(encoding='UTF-8'))\n",
        "    labels.append(tf_example.features.feature['labels'].int64_list.value)\n",
        "    mean_rgb.append(tf_example.features.feature['mean_rgb'].float_list.value)\n",
        "    mean_audio.append(tf_example.features.feature['mean_audio'].float_list.value)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "a25d68b9-2e5a-470f-4f18-2c5762948049"
      },
      "outputs": [],
      "source": [
        "print('Number of videos in this tfrecord: ',len(mean_rgb))\n",
        "print('First video feature length',len(mean_rgb[0]))\n",
        "print('First 20 features of the first youtube video (',vid_ids[0],')')\n",
        "print(mean_rgb[0][:20])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "23cafa43-2562-821f-5a84-e91131812b71"
      },
      "outputs": [],
      "source": [
        "def play_one_vid(record_name, video_index):\n",
        "    return vid_ids[video_index]\n",
        "    \n",
        "# this worked on my local jupyter notebook, but doesn't show on kaggle kernels:\n",
        "YouTubeVideo(play_one_vid(video_lvl_record, 7))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "e4f90219-9815-2c6e-f48a-315a718bc0f7"
      },
      "outputs": [],
      "source": [
        "print('mean_audio has length of: ')\n",
        "print([len(x) for x in mean_audio][:5])\n",
        "print('mean_rgb has length of: ')\n",
        "print([len(x) for x in mean_rgb][:5])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "2c1cd925-f7f0-3b81-4630-86ff8b1f407e"
      },
      "outputs": [],
      "source": [
        "# now, let's read the frame-level data\n",
        "# due to execution time, we're only going to read the first video\n",
        "\n",
        "feat_rgb = []\n",
        "feat_audio = []\n",
        "\n",
        "for example in tf.python_io.tf_record_iterator(frame_lvl_record):        \n",
        "    tf_seq_example = tf.train.SequenceExample.FromString(example)\n",
        "    n_frames = len(tf_seq_example.feature_lists.feature_list['audio'].feature)\n",
        "    sess = tf.InteractiveSession()\n",
        "    rgb_frame = []\n",
        "    audio_frame = []\n",
        "    # iterate through frames\n",
        "    for i in range(n_frames):\n",
        "        rgb_frame.append(tf.cast(tf.decode_raw(\n",
        "                tf_seq_example.feature_lists.feature_list['rgb'].feature[i].bytes_list.value[0],tf.uint8)\n",
        "                       ,tf.float32).eval())\n",
        "        audio_frame.append(tf.cast(tf.decode_raw(\n",
        "                tf_seq_example.feature_lists.feature_list['audio'].feature[i].bytes_list.value[0],tf.uint8)\n",
        "                       ,tf.float32).eval())\n",
        "        \n",
        "        \n",
        "    sess.close()\n",
        "    feat_rgb.append(rgb_frame)\n",
        "    feat_audio.append(audio_frame)\n",
        "    break"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "fa352887-c661-bb07-aa4c-c1bc2afc93c6"
      },
      "outputs": [],
      "source": [
        "print('The first video has %d frames' %len(feat_rgb[0]))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "2189f322-5ab7-d928-2b6a-7f1d2945363c"
      },
      "outputs": [],
      "source": [
        "from matplotlib import pyplot as plt\n",
        "%matplotlib inline\n",
        "from sklearn.manifold import TSNE\n",
        "import numpy as np"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "cb51a109-e999-7bee-d8e0-43ce3b1c5013"
      },
      "source": [
        "# now let's explore a little on the labels\n",
        "Find the most commonly appeared label in this record:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "0fd1f8de-82ea-3fa7-de9e-28b86c197e28"
      },
      "outputs": [],
      "source": [
        "n=10\n",
        "from collections import Counter\n",
        "label_mapping = pd.Series.from_csv('../input/label_names.csv',header=0).to_dict()\n",
        "\n",
        "top_n = Counter([item for sublist in labels for item in sublist]).most_common(n)\n",
        "top_n_labels = [int(i[0]) for i in top_n]\n",
        "top_n_label_names = [label_mapping[x] for x in top_n_labels]\n",
        "top_n_label_names"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "a24caad7-a3c8-55cb-0ae8-356014e2b327"
      },
      "outputs": [],
      "source": [
        "import networkx as nx\n",
        "from itertools import combinations\n",
        "\n",
        "G=nx.Graph()\n",
        "\n",
        "G.clear()\n",
        "for list_of_nodes in labels:\n",
        "    filtered_nodes = set(list_of_nodes).intersection(set(top_n_labels))  \n",
        "    for node1,node2 in list(combinations(filtered_nodes,2)): \n",
        "        node1_name = label_mapping[node1]\n",
        "        node2_name = label_mapping[node2]\n",
        "        G.add_node(node1_name)\n",
        "        G.add_node(node2_name)\n",
        "        G.add_edge(node1_name, node2_name)\n",
        "\n",
        "nx.draw_networkx(G)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "01a7ef6a-4109-83cf-53f0-2446bd992515"
      },
      "outputs": [],
      "source": [
        "colors = plt.cm.rainbow(np.linspace(0, 1, n))\n",
        "mean_rgb_top_n = []\n",
        "labels_for_tsne = []\n",
        "# filtering mean_rgb so it only contains top n labels\n",
        "for idx, list_of_nodes in enumerate(labels):\n",
        "    for node in list_of_nodes:\n",
        "        if node in top_n_labels:\n",
        "            mean_rgb_top_n.append(mean_rgb[idx])\n",
        "            labels_for_tsne.append(node)\n",
        "\n",
        "\n",
        "X_embedded = TSNE(n_components=2, random_state=0).fit_transform(mean_rgb_top_n) \n",
        "\n",
        "\n",
        "fig = plt.figure()\n",
        "ax = fig.add_subplot(111)\n",
        "\n",
        "handles = []\n",
        "for indx, color in enumerate(colors):\n",
        "    this_label = top_n_labels[indx]\n",
        "    X_embedded_filtered = X_embedded[np.array([x==this_label for x in labels_for_tsne])]\n",
        "    handles.append(ax.scatter(X_embedded_filtered[:, 0], X_embedded_filtered[:, 1], c=color, marker=\"o\",edgecolor='none'))\n",
        "\n",
        "ax.legend(handles, top_n_labels)\n",
        "\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "ea548c00-8c98-5806-317b-a64552c87a84"
      },
      "outputs": [],
      "source": [
        ""
      ]
    }
  ],
  "metadata": {
    "_change_revision": 0,
    "_is_fork": false,
    "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.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}