{"cells":[{"metadata":{},"cell_type":"markdown","source":"# 1 Crop Image"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nfrom tqdm import tqdm_notebook\n\nComputeLB = True\nDogsOnly = True\n\nimport numpy as np, pandas as pd, os\nimport xml.etree.ElementTree as ET \nimport matplotlib.pyplot as plt, zipfile \nfrom PIL import Image \n\nROOT = '../input/generative-dog-images/'\nif not ComputeLB: ROOT = '../input/'\ndogs_path = ROOT + 'all-dogs/all-dogs/'\nIMAGES = os.listdir(dogs_path)\nbreeds = os.listdir(ROOT + 'annotation/Annotation/') \n\nidxIn = 0; namesIn = []\nimagesIn = np.zeros((25000, 64, 64, 3))\n# imagesIn = np.zeros((25000, 3, 64, 64))\n\n# CROP WITH BOUNDING BOXES TO GET DOGS ONLY\n# https://www.kaggle.com/paulorzp/show-annotations-and-breeds\nif DogsOnly:\n    for breed in tqdm_notebook(breeds):\n        for dog in os.listdir(ROOT+'annotation/Annotation/'+breed):\n            try: img = Image.open(ROOT+'all-dogs/all-dogs/'+dog+'.jpg') \n            except: continue           \n            tree = ET.parse(ROOT+'annotation/Annotation/'+breed+'/'+dog)\n            root = tree.getroot()\n            objects = root.findall('object')\n            for o in objects:\n                bndbox = o.find('bndbox') \n                xmin = int(bndbox.find('xmin').text)\n                ymin = int(bndbox.find('ymin').text)\n                xmax = int(bndbox.find('xmax').text)\n                ymax = int(bndbox.find('ymax').text)\n                w = np.min((xmax - xmin, ymax - ymin))\n                img2 = img.crop((xmin, ymin, xmin+w, ymin+w))\n                img2 = img2.resize((64,64), Image.ANTIALIAS)\n                imagesIn[idxIn,:,:,:] = np.asarray(img2)\n                #if idxIn%1000==0: print(idxIn)\n                namesIn.append(breed)\n                idxIn += 1\n    idx = np.arange(idxIn)\n    np.random.shuffle(idx)\n    imagesIn = imagesIn[idx,:,:,:]\n    namesIn = np.array(namesIn)[idx]\n    \n# RANDOMLY CROP FULL IMAGES\nelse:\n    IMAGES = np.sort(IMAGES)\n    np.random.seed(810)\n    x = np.random.choice(np.arange(20579),10000)\n    np.random.seed(None)\n    for k in tqdm_notebook(range(len(x))):\n        img = Image.open(ROOT + 'all-dogs/all-dogs/' + IMAGES[x[k]])\n        w = img.size[0]; h = img.size[1];\n        if (k%2==0)|(k%3==0):\n            w2 = 100; h2 = int(h/(w/100))\n            a = 18; b = 0          \n        else:\n            a=0; b=0\n            if w<h:\n                w2 = 64; h2 = int((64/w)*h)\n                b = (h2-64)//2\n            else:\n                h2 = 64; w2 = int((64/h)*w)\n                a = (w2-64)//2\n        img = img.resize((w2,h2), Image.ANTIALIAS)\n        img = img.crop((0+a, 0+b, 64+a, 64+b))    \n        imagesIn[idxIn,:,:,:] = np.asarray(img)\n        namesIn.append(IMAGES[x[k]])\n        #if idxIn%1000==0: print(idxIn)\n        idxIn += 1\n    \n#DISPLAY CROPPED IMAGES\nx = np.random.randint(0,idxIn,25)\nfor k in range(5):\n    plt.figure(figsize=(15,3))\n    for j in range(5):\n        plt.subplot(1,5,j+1)\n        img = Image.fromarray( imagesIn[x[k*5+j],:,:,:].astype('uint8') )\n        plt.axis('off')\n        if not DogsOnly: plt.title(namesIn[x[k*5+j]],fontsize=11)\n        else: plt.title(namesIn[x[k*5+j]].split('-')[1],fontsize=11)\n        plt.imshow(img)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# the number of the dog breed\ndognamesIn = [namesIn[i].split('-')[-1] for i in range(len(namesIn))]\nprint(len(dognamesIn))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from collections import defaultdict\ndog_names = list(set(dognamesIn))\ndog_names[:5]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dog_name2ID = defaultdict(int)\nfor i in range(len(dog_names)):\n    dog_name2ID[dog_names[i]] = i\ndog_name2ID","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dogIDIn = [dog_name2ID[dognamesIn[i]] for i in range(len(dognamesIn))]\ndogIDIn[:3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nEYE_matrix = np.eye(120)\nX_all = imagesIn\nY_all = np.array([EYE_matrix[i] for i in tqdm_notebook(dogIDIn)])\nX_all.shape, Y_all.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2 BigGAN"},{"metadata":{},"cell_type":"markdown","source":"The code below is based on:\n- https://github.com/MingtaoGuo/BigGAN-tensorflow\n- https://github.com/ajbrock/BigGAN-PyTorch\n- https://github.com/AaronLeong/BigGAN-pytorch\n- https://github.com/ANIME305/Anime-GAN-tensorflow"},{"metadata":{},"cell_type":"markdown","source":"# 3 Generate dog images"},{"metadata":{"trusted":true},"cell_type":"code","source":"# -*- coding: utf-8 -*-\nimport tensorflow as tf\nimport numpy as np\nimport os\nimport matplotlib.pyplot as plt\n%matplotlib inline\nfrom imageio import imread, imsave, mimsave\nimport cv2\nimport glob\nfrom tqdm import tqdm, tqdm_notebook","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 256\nz_dim = 10000\nWIDTH = 64\nHEIGHT = 64\nLABEL = 120\nLAMBDA = 10\nDIS_ITERS = 3 # 5\n\nOUTPUT_DIR = 'samples'\nif not os.path.exists(OUTPUT_DIR):\n    os.mkdir(OUTPUT_DIR)\n\nX = tf.placeholder(dtype=tf.float32, shape=[batch_size, HEIGHT, WIDTH, 3], name='X')\nY = tf.placeholder(dtype=tf.float32, shape=[batch_size, LABEL], name='Y')\nnoise = tf.placeholder(dtype=tf.float32, shape=[batch_size, z_dim], name='noise')\nis_training = tf.placeholder(dtype=tf.bool, name='is_training')\n\ndef lrelu(x, leak=0.2):\n    return tf.maximum(x, leak * x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def discriminator(image, reuse=None, is_training=is_training):\n    momentum = 0.9\n    with tf.variable_scope('discriminator', reuse=reuse):\n        h0 = lrelu(tf.layers.conv2d(image, kernel_size=5, filters=64, strides=2, padding='same'))\n        \n        h1 = lrelu(tf.layers.conv2d(h0, kernel_size=5, filters=128, strides=2, padding='same'))\n        \n        h2 = lrelu(tf.layers.conv2d(h1, kernel_size=5, filters=256, strides=2, padding='same'))\n        \n        h3 = lrelu(tf.layers.conv2d(h2, kernel_size=5, filters=512, strides=2, padding='same'))\n        \n        h4 = tf.contrib.layers.flatten(h3)\n        Y_ = tf.layers.dense(h4, units=LABEL)\n        h4 = tf.layers.dense(h4, units=1)\n        return h4, Y_","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def generator(z, label, is_training=is_training):\n    momentum = 0.9\n    with tf.variable_scope('generator', reuse=None):\n        d = 4\n        z = tf.concat([z, label], axis=1)\n        h0 = tf.layers.dense(z, units=d * d * 512)\n        h0 = tf.reshape(h0, shape=[-1, d, d, 512])\n        h0 = tf.nn.relu(tf.contrib.layers.batch_norm(h0, is_training=is_training, decay=momentum))\n        \n        h1 = tf.layers.conv2d_transpose(h0, kernel_size=5, filters=256, strides=2, padding='same')\n        h1 = tf.nn.relu(tf.contrib.layers.batch_norm(h1, is_training=is_training, decay=momentum))\n        \n        h2 = tf.layers.conv2d_transpose(h1, kernel_size=5, filters=128, strides=2, padding='same')\n        h2 = tf.nn.relu(tf.contrib.layers.batch_norm(h2, is_training=is_training, decay=momentum))\n        \n        h3 = tf.layers.conv2d_transpose(h2, kernel_size=5, filters=64, strides=2, padding='same')\n        h3 = tf.nn.relu(tf.contrib.layers.batch_norm(h3, is_training=is_training, decay=momentum))\n        \n        h4 = tf.layers.conv2d_transpose(h3, kernel_size=5, filters=3, strides=2, padding='same', activation=tf.nn.tanh, name='g')\n        return h4","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"g = generator(noise, Y)\nd_real, y_real = discriminator(X)\nd_fake, y_fake = discriminator(g, reuse=True)\n\nloss_d_real = -tf.reduce_mean(d_real)\nloss_d_fake = tf.reduce_mean(d_fake)\n\nloss_cls_real = tf.losses.mean_squared_error(Y, y_real)\nloss_cls_fake = tf.losses.mean_squared_error(Y, y_fake)\n\nloss_d = loss_d_real + loss_d_fake + loss_cls_real\nloss_g = -tf.reduce_mean(d_fake) + loss_cls_fake\n\nalpha = tf.random_uniform(shape=[batch_size, 1, 1, 1], minval=0., maxval=1.)\ninterpolates = alpha * X + (1 - alpha) * g\ngrad = tf.gradients(discriminator(interpolates, reuse=True), [interpolates])[0]\nslop = tf.sqrt(tf.reduce_sum(tf.square(grad), axis=[1]))\ngp = tf.reduce_mean((slop - 1.) ** 2)\nloss_d += LAMBDA * gp\n\nvars_g = [var for var in tf.trainable_variables() if var.name.startswith('generator')]\nvars_d = [var for var in tf.trainable_variables() if var.name.startswith('discriminator')]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)\nwith tf.control_dependencies(update_ops):\n    optimizer_d = tf.train.AdamOptimizer(learning_rate=0.0002, beta1=0.5).minimize(loss_d, var_list=vars_d)\n    optimizer_g = tf.train.AdamOptimizer(learning_rate=0.0002, beta1=0.5).minimize(loss_g, var_list=vars_g)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def montage(images):    \n    if isinstance(images, list):\n        images = np.array(images)\n    img_h = images.shape[1]\n    img_w = images.shape[2]\n    n_plots = int(np.ceil(np.sqrt(images.shape[0])))\n    if len(images.shape) == 4 and images.shape[3] == 3:\n        m = np.ones(\n            (images.shape[1] * n_plots + n_plots + 1,\n             images.shape[2] * n_plots + n_plots + 1, 3)) * 0.5\n    elif len(images.shape) == 4 and images.shape[3] == 1:\n        m = np.ones(\n            (images.shape[1] * n_plots + n_plots + 1,\n             images.shape[2] * n_plots + n_plots + 1, 1)) * 0.5\n    elif len(images.shape) == 3:\n        m = np.ones(\n            (images.shape[1] * n_plots + n_plots + 1,\n             images.shape[2] * n_plots + n_plots + 1)) * 0.5\n    else:\n        raise ValueError('Could not parse image shape of {}'.format(images.shape))\n    for i in range(n_plots):\n        for j in range(n_plots):\n            this_filter = i * n_plots + j\n            if this_filter < images.shape[0]:\n                this_img = images[this_filter]\n                m[1 + i + i * img_h:1 + i + (i + 1) * img_h,\n                  1 + j + j * img_w:1 + j + (j + 1) * img_w] = this_img\n    return m","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(10):\n    img = Image.fromarray( X_all[i,:,:,:].astype('uint8') )\n    plt.imshow(img)\n    plt.show()\n    print(Y_all[i, :])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_random_batch():\n    data_index = np.arange(X_all.shape[0])\n    np.random.shuffle(data_index)\n    data_index = data_index[:batch_size]\n    X_batch = X_all[data_index, :, :, :]\n    Y_batch = Y_all[data_index, :]\n    \n    return X_batch, Y_batch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sess = tf.Session()\nsess.run(tf.global_variables_initializer())\nzs = np.random.uniform(-1.0, 1.0, [batch_size // 2, z_dim]).astype(np.float32)\nz_samples = []\ny_samples = []\nfor i in range(batch_size // 2):\n    LABEL_i = i % LABEL\n    z_samples.append(zs[i, :])\n    y_samples.append(Y_all[LABEL_i])\n    z_samples.append(zs[i, :])\n    y_samples.append(Y_all[-LABEL_i])\nloss = {'d': [], 'g': []}\n\nfor i in tqdm_notebook(range(30000)):\n    for j in range(DIS_ITERS):\n        n = np.random.uniform(-1.0, 1.0, [batch_size, z_dim]).astype(np.float32)\n        X_batch, Y_batch = get_random_batch()\n        _, d_ls = sess.run([optimizer_d, loss_d], feed_dict={X: X_batch, Y: Y_batch, noise: n, is_training: True})\n    \n    _, g_ls = sess.run([optimizer_g, loss_g], feed_dict={X: X_batch, Y: Y_batch, noise: n, is_training: True})\n    \n    loss['d'].append(d_ls)\n    loss['g'].append(g_ls)\n    \n    if i % 500 == 0:\n        print(i, d_ls, g_ls)\n        gen_imgs = sess.run(g, feed_dict={noise: z_samples, Y: y_samples, is_training: False})\n        gen_imgs = (gen_imgs + 1) / 2\n        imgs = [img[:, :, :] for img in gen_imgs]\n        gen_imgs = montage(imgs)\n        plt.axis('off')\n        plt.imshow(gen_imgs)\n        plt.show()\n\nplt.plot(loss['d'], label='Discriminator')\nplt.plot(loss['g'], label='Generator')\nplt.legend(loc='upper right')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Generate data\nn_batches = 10000 // batch_size\nlast_batch_size = 10000 % batch_size\n\nfor i in tqdm_notebook(range(n_batches)):\n    n = np.random.uniform(-1.0, 1.0, [batch_size, z_dim]).astype(np.float32)\n    y_samples = Y_all[i * batch_size : (i+1) * batch_size]\n    gen_imgs = sess.run(g, feed_dict={noise: z_samples, Y: y_samples, is_training: False})\n    gen_imgs = (gen_imgs + 1) / 2\n    for j in range(batch_size):\n        imsave(os.path.join(GEN_DIR, f'sample_{i}_{j}.png'), gen_imgs[j])\n\nfor i in range(last_batch_size):\n    n = np.random.uniform(-1.0, 1.0, [batch_size, z_dim]).astype(np.float32)\n    gen_imgs = sess.run(g, feed_dict={noise: z_samples, Y: y_samples, is_training: False})\n    gen_imgs = (gen_imgs + 1) / 2\n    imsave(os.path.join(GEN_DIR, f'sample_{n_batches}_{i}.png'), gen_imgs[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4 Test FID"},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import absolute_import, division, print_function\nimport numpy as np\nimport os\nimport gzip, pickle\nimport tensorflow as tf\nfrom scipy import linalg\nimport pathlib\nimport urllib\nimport warnings\nfrom tqdm import tqdm\nfrom PIL import Image\n\nclass KernelEvalException(Exception):\n    pass\n\nmodel_params = {\n    'Inception': {\n        'name': 'Inception', \n        'imsize': 64,\n        'output_layer': 'Pretrained_Net/pool_3:0', \n        'input_layer': 'Pretrained_Net/ExpandDims:0',\n        'output_shape': 2048,\n        'cosine_distance_eps': 0.1\n        }\n}\n\ndef create_model_graph(pth):\n    \"\"\"Creates a graph from saved GraphDef file.\"\"\"\n    # Creates graph from saved graph_def.pb.\n    with tf.gfile.FastGFile( pth, 'rb') as f:\n        graph_def = tf.GraphDef()\n        graph_def.ParseFromString( f.read())\n        _ = tf.import_graph_def( graph_def, name='Pretrained_Net')\n\ndef _get_model_layer(sess, model_name):\n    # layername = 'Pretrained_Net/final_layer/Mean:0'\n    layername = model_params[model_name]['output_layer']\n    layer = sess.graph.get_tensor_by_name(layername)\n    ops = layer.graph.get_operations()\n    for op_idx, op in enumerate(ops):\n        for o in op.outputs:\n            shape = o.get_shape()\n            if shape._dims != []:\n              shape = [s.value for s in shape]\n              new_shape = []\n              for j, s in enumerate(shape):\n                if s == 1 and j == 0:\n                  new_shape.append(None)\n                else:\n                  new_shape.append(s)\n              o.__dict__['_shape_val'] = tf.TensorShape(new_shape)\n    return layer\n\ndef get_activations(images, sess, model_name, batch_size=50, verbose=False):\n    \"\"\"Calculates the activations of the pool_3 layer for all images.\n\n    Params:\n    -- images      : Numpy array of dimension (n_images, hi, wi, 3). The values\n                     must lie between 0 and 256.\n    -- sess        : current session\n    -- batch_size  : the images numpy array is split into batches with batch size\n                     batch_size. A reasonable batch size depends on the disposable hardware.\n    -- verbose    : If set to True and parameter out_step is given, the number of calculated\n                     batches is reported.\n    Returns:\n    -- A numpy array of dimension (num images, 2048) that contains the\n       activations of the given tensor when feeding inception with the query tensor.\n    \"\"\"\n    inception_layer = _get_model_layer(sess, model_name)\n    n_images = images.shape[0]\n    if batch_size > n_images:\n        print(\"warning: batch size is bigger than the data size. setting batch size to data size\")\n        batch_size = n_images\n    n_batches = n_images//batch_size + 1\n    pred_arr = np.empty((n_images,model_params[model_name]['output_shape']))\n    for i in tqdm(range(n_batches)):\n        if verbose:\n            print(\"\\rPropagating batch %d/%d\" % (i+1, n_batches), end=\"\", flush=True)\n        start = i*batch_size\n        if start+batch_size < n_images:\n            end = start+batch_size\n        else:\n            end = n_images\n                    \n        batch = images[start:end]\n        pred = sess.run(inception_layer, {model_params[model_name]['input_layer']: batch})\n        pred_arr[start:end] = pred.reshape(-1,model_params[model_name]['output_shape'])\n    if verbose:\n        print(\" done\")\n    return pred_arr\n\n\n# def calculate_memorization_distance(features1, features2):\n#     neigh = NearestNeighbors(n_neighbors=1, algorithm='kd_tree', metric='euclidean')\n#     neigh.fit(features2) \n#     d, _ = neigh.kneighbors(features1, return_distance=True)\n#     print('d.shape=',d.shape)\n#     return np.mean(d)\n\ndef normalize_rows(x: np.ndarray):\n    \"\"\"\n    function that normalizes each row of the matrix x to have unit length.\n\n    Args:\n     ``x``: A numpy matrix of shape (n, m)\n\n    Returns:\n     ``x``: The normalized (by row) numpy matrix.\n    \"\"\"\n    return np.nan_to_num(x/np.linalg.norm(x, ord=2, axis=1, keepdims=True))\n\n\ndef cosine_distance(features1, features2):\n    # print('rows of zeros in features1 = ',sum(np.sum(features1, axis=1) == 0))\n    # print('rows of zeros in features2 = ',sum(np.sum(features2, axis=1) == 0))\n    features1_nozero = features1[np.sum(features1, axis=1) != 0]\n    features2_nozero = features2[np.sum(features2, axis=1) != 0]\n    norm_f1 = normalize_rows(features1_nozero)\n    norm_f2 = normalize_rows(features2_nozero)\n\n    d = 1.0-np.abs(np.matmul(norm_f1, norm_f2.T))\n    print('d.shape=',d.shape)\n    print('np.min(d, axis=1).shape=',np.min(d, axis=1).shape)\n    mean_min_d = np.mean(np.min(d, axis=1))\n    print('distance=',mean_min_d)\n    return mean_min_d\n\n\ndef distance_thresholding(d, eps):\n    if d < eps:\n        return d\n    else:\n        return 1\n\ndef calculate_frechet_distance(mu1, sigma1, mu2, sigma2, eps=1e-6):\n    \"\"\"Numpy implementation of the Frechet Distance.\n    The Frechet distance between two multivariate Gaussians X_1 ~ N(mu_1, C_1)\n    and X_2 ~ N(mu_2, C_2) is\n            d^2 = ||mu_1 - mu_2||^2 + Tr(C_1 + C_2 - 2*sqrt(C_1*C_2)).\n            \n    Stable version by Dougal J. Sutherland.\n\n    Params:\n    -- mu1 : Numpy array containing the activations of the pool_3 layer of the\n             inception net ( like returned by the function 'get_predictions')\n             for generated samples.\n    -- mu2   : The sample mean over activations of the pool_3 layer, precalcualted\n               on an representive data set.\n    -- sigma1: The covariance matrix over activations of the pool_3 layer for\n               generated samples.\n    -- sigma2: The covariance matrix over activations of the pool_3 layer,\n               precalcualted on an representive data set.\n\n    Returns:\n    --   : The Frechet Distance.\n    \"\"\"\n\n    mu1 = np.atleast_1d(mu1)\n    mu2 = np.atleast_1d(mu2)\n\n    sigma1 = np.atleast_2d(sigma1)\n    sigma2 = np.atleast_2d(sigma2)\n\n    assert mu1.shape == mu2.shape, \"Training and test mean vectors have different lengths\"\n    assert sigma1.shape == sigma2.shape, \"Training and test covariances have different dimensions\"\n\n    diff = mu1 - mu2\n\n    # product might be almost singular\n    covmean, _ = linalg.sqrtm(sigma1.dot(sigma2), disp=False)\n    if not np.isfinite(covmean).all():\n        msg = \"fid calculation produces singular product; adding %s to diagonal of cov estimates\" % eps\n        warnings.warn(msg)\n        offset = np.eye(sigma1.shape[0]) * eps\n        # covmean = linalg.sqrtm((sigma1 + offset).dot(sigma2 + offset))\n        covmean = linalg.sqrtm((sigma1 + offset).dot(sigma2 + offset))\n    \n    # numerical error might give slight imaginary component\n    if np.iscomplexobj(covmean):\n        if not np.allclose(np.diagonal(covmean).imag, 0, atol=1e-3):\n            m = np.max(np.abs(covmean.imag))\n            raise ValueError(\"Imaginary component {}\".format(m))\n        covmean = covmean.real\n\n    # covmean = tf.linalg.sqrtm(tf.linalg.matmul(sigma1,sigma2))\n\n    print('covmean.shape=',covmean.shape)\n    # tr_covmean = tf.linalg.trace(covmean)\n\n    tr_covmean = np.trace(covmean)\n    return diff.dot(diff) + np.trace(sigma1) + np.trace(sigma2) - 2 * tr_covmean\n    # return diff.dot(diff) + tf.linalg.trace(sigma1) + tf.linalg.trace(sigma2) - 2 * tr_covmean\n#-------------------------------------------------------------------------------\n\n\ndef calculate_activation_statistics(images, sess, model_name, batch_size=50, verbose=False):\n    \"\"\"Calculation of the statistics used by the FID.\n    Params:\n    -- images      : Numpy array of dimension (n_images, hi, wi, 3). The values\n                     must lie between 0 and 255.\n    -- sess        : current session\n    -- batch_size  : the images numpy array is split into batches with batch size\n                     batch_size. A reasonable batch size depends on the available hardware.\n    -- verbose     : If set to True and parameter out_step is given, the number of calculated\n                     batches is reported.\n    Returns:\n    -- mu    : The mean over samples of the activations of the pool_3 layer of\n               the incption model.\n    -- sigma : The covariance matrix of the activations of the pool_3 layer of\n               the incption model.\n    \"\"\"\n    act = get_activations(images, sess, model_name, batch_size, verbose)\n    mu = np.mean(act, axis=0)\n    sigma = np.cov(act, rowvar=False)\n    return mu, sigma, act\n    \ndef _handle_path_memorization(path, sess, model_name, is_checksize, is_check_png):\n    path = pathlib.Path(path)\n    files = list(path.glob('*.jpg')) + list(path.glob('*.png'))\n    imsize = model_params[model_name]['imsize']\n\n    # In production we don't resize input images. This is just for demo purpose. \n    x = np.array([np.array(img_read_checks(fn, imsize, is_checksize, imsize, is_check_png)) for fn in files])\n    m, s, features = calculate_activation_statistics(x, sess, model_name)\n    del x #clean up memory\n    return m, s, features\n\n# check for image size\ndef img_read_checks(filename, resize_to, is_checksize=False, check_imsize = 64, is_check_png = False):\n    im = Image.open(str(filename))\n    if is_checksize and im.size != (check_imsize,check_imsize):\n        raise KernelEvalException('The images are not of size '+str(check_imsize))\n    \n    if is_check_png and im.format != 'PNG':\n        raise KernelEvalException('Only PNG images should be submitted.')\n\n    if resize_to is None:\n        return im\n    else:\n        return im.resize((resize_to,resize_to),Image.ANTIALIAS)\n\ndef calculate_kid_given_paths(paths, model_name, model_path, feature_path=None, mm=[], ss=[], ff=[]):\n    ''' Calculates the KID of two paths. '''\n    tf.reset_default_graph()\n    create_model_graph(str(model_path))\n    with tf.Session() as sess:\n        sess.run(tf.global_variables_initializer())\n        m1, s1, features1 = _handle_path_memorization(paths[0], sess, model_name, is_checksize = True, is_check_png = True)\n        if len(mm) != 0:\n            m2 = mm\n            s2 = ss\n            features2 = ff\n        elif feature_path is None:\n            m2, s2, features2 = _handle_path_memorization(paths[1], sess, model_name, is_checksize = False, is_check_png = False)\n        else:\n            with np.load(feature_path) as f:\n                m2, s2, features2 = f['m'], f['s'], f['features']\n\n        print('m1,m2 shape=',(m1.shape,m2.shape),'s1,s2=',(s1.shape,s2.shape))\n        print('starting calculating FID')\n        fid_value = calculate_frechet_distance(m1, s1, m2, s2)\n        print('done with FID, starting distance calculation')\n        distance = cosine_distance(features1, features2)        \n        return fid_value, distance, m2, s2, features2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if ComputeLB:\n  \n    # UNCOMPRESS OUR IMGAES\n    with zipfile.ZipFile(\"../working/images.zip\",\"r\") as z:\n        z.extractall(\"../tmp/images2/\")\n\n    # COMPUTE LB SCORE\n    m2 = []; s2 =[]; f2 = []\n    user_images_unzipped_path = '../tmp/images2/'\n    images_path = [user_images_unzipped_path,'../input/generative-dog-images/all-dogs/all-dogs/']\n    public_path = '../input/dog-face-generation-competition-kid-metric-input/classify_image_graph_def.pb'\n\n    fid_epsilon = 10e-15\n\n    fid_value_public, distance_public, m2, s2, f2 = calculate_kid_given_paths(images_path, 'Inception', public_path, mm=m2, ss=s2, ff=f2)\n    distance_public = distance_thresholding(distance_public, model_params['Inception']['cosine_distance_eps'])\n    print(\"FID_public: \", fid_value_public, \"distance_public: \", distance_public, \"multiplied_public: \",\n            fid_value_public /(distance_public + fid_epsilon))\n    \n    # REMOVE FILES TO PREVENT KERNEL ERROR OF TOO MANY FILES\n    ! rm -r ../tmp","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}