text:
"""
Title: Handwriting recognition
Authors: [A_K_Nain](https://twitter.com/A_K_Nain), [Sayak Paul](https://twitter.com/RisingSayak)
Date created: 2021/08/16
Last modified: 2021/08/16
Description: Training a handwriting recognition model with variable-length sequences.
"""
"""
## Introduction

This example shows how the [Captcha OCR](https://keras.io/examples/vision/captcha_ocr/)
example can be extended to the
[IAM Dataset](https://fki.tic.heia-fr.ch/databases/iam-handwriting-database),
which has variable length ground-truth targets. Each sample in the dataset is an image of some
handwritten text, and its corresponding target is the string present in the image.
The IAM Dataset is widely used across many OCR benchmarks, so we hope this example can serve as a
good starting point for building OCR systems.
"""

"""
## Data collection
"""

"""shell
wget -q https://git.io/J0fjL -O IAM_Words.zip
unzip -qq IAM_Words.zip

mkdir data
mkdir data/words
tar -xf IAM_Words/words.tgz -C data/words
mv IAM_Words/words.txt data
"""

"""
Preview how the dataset is organized. Lines prepended by "#" are just metadata information.
"""

"""shell
head -20 data/words.txt
"""

"""
## Imports
"""

from tensorflow.keras.layers.experimental.preprocessing import StringLookup
from tensorflow import keras

import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
import os

np.random.seed(42)
tf.random.set_seed(42)

"""
## Dataset splitting
"""

base_path = "data"
words_list = []

words = open(f"{base_path}/words.txt", "r").readlines()
for line in words:
    if line[0] == "#":
        continue
    if line.split(" ")[1] != "err":  # We don't need to deal with errored entries.
        words_list.append(line)

len(words_list)

np.random.shuffle(words_list)

"""
We will split the dataset into three subsets with a 90:5:5 ratio (train:validation:test).
"""

split_idx = int(0.9 * len(words_list))
train_samples = words_list[:split_idx]
test_samples = words_list[split_idx:]

val_split_idx = int(0.5 * len(test_samples))
validation_samples = test_samples[:val_split_idx]
test_samples = test_samples[val_split_idx:]

assert len(words_list) == len(train_samples) + len(validation_samples) + len(
    test_samples
)

print(f"Total training samples: {len(train_samples)}")
print(f"Total validation samples: {len(validation_samples)}")
print(f"Total test samples: {len(test_samples)}")

"""
## Data input pipeline

We start building our data input pipeline by first preparing the image paths.
"""

base_image_path = os.path.join(base_path, "words")

def get_image_paths_and_labels(samples):
    paths = []
    corrected_samples = []
    for (i, file_line) in enumerate(samples):
        line_split = file_line.strip()
        line_split = line_split.split(" ")

        # Each line split will have this format for the corresponding image:
        # part1/part1-part2/part1-part2-part3.png
        image_name = line_split[0]
        partI = image_name.split("-")[0]
        partII = image_name.split("-")[1]
        img_path = os.path.join(
            base_image_path, partI, partI + "-" + partII, image_name + ".png"
        )
        if os.path.getsize(img_path):
            paths.append(img_path)
            corrected_samples.append(file_line.split("\n")[0])

    return paths, corrected_samples

train_img_paths, train_labels = get_image_paths_and_labels(train_samples)
validation_img_paths, validation_labels = get_image_paths_and_labels(validation_samples)
test_img_paths, test_labels = get_image_paths_and_labels(test_samples)

"""
Then we prepare the ground-truth labels.
"""

# Find maximum length and the size of the vocabulary in the training data.
train_labels_cleaned = []
characters = set()
max_len = 0

for label in train_labels:
    label = label.split(" ")[-1].strip()
    for char in label:
        characters.add(char)

    max_len = max(max_len, len(label))
    train_labels_cleaned.append(label)

print("Maximum length: ", max_len)
print("Vocab size: ", len(characters))

# Check some label samples.
train_labels_cleaned[:10]

"""
Now we clean the validation and the test labels as well.
"""

def clean_labels(labels):
    cleaned_labels = []
    for label in labels:
        label = label.split(" ")[-1].strip()
        cleaned_labels.append(label)
    return cleaned_labels

validation_labels_cleaned = clean_labels(validation_labels)
test_labels_cleaned = clean_labels(test_labels)

"""
### Building the character vocabulary

Keras provides different preprocessing layers to deal with different modalities of data.
[This guide](https://keras.io/guides/preprocessing_layers/) provids a comprehensive introduction.
Our example involves preprocessing labels at the character
level. This means that if there are two labels, e.g. "cat" and "dog", then our character
vocabulary should be {a, c, d, g, o, t} (without any special tokens). We use the
[`StringLookup`](https://keras.io/api/layers/preprocessing_layers/categorical/string_lookup/)
layer for this purpose.
"""

AUTOTUNE = tf.data.AUTOTUNE

# Mapping characters to integers.
char_to_num = StringLookup(vocabulary=list(characters), mask_token=None)

# Mapping integers back to original characters.
num_to_char = StringLookup(
    vocabulary=char_to_num.get_vocabulary(), mask_token=None, invert=True
)

"""
### Resizing images without distortion

Instead of square images, many OCR models work with rectangular images. This will become
clearer in a moment when we will visualize a few samples from the dataset. While
aspect-unaware resizing square images does not introduce a significant amount of
distortion this is not the case for rectangular images. But resizing images to a uniform
size is a requirement for mini-batching. So we need to perform our resizing such that
the following criteria are met:

* Aspect ratio is preserved.
* Content of the images is not affected.
"""

def distortion_free_resize(image, img_size):
    w, h = img_size
    image = tf.image.resize(image, size=(h, w), preserve_aspect_ratio=True)

    # Check tha amount of padding needed to be done.
    pad_height = h - tf.shape(image)[0]
    pad_width = w - tf.shape(image)[1]

    # Only necessary if you want to do same amount of padding on both sides.
    if pad_height % 2 != 0:
        height = pad_height // 2
        pad_height_top = height + 1
        pad_height_bottom = height
    else:
        pad_height_top = pad_height_bottom = pad_height // 2

    if pad_width % 2 != 0:
        width = pad_width // 2
        pad_width_left = width + 1
        pad_width_right = width
    else:
        pad_width_left = pad_width_right = pad_width // 2

    image = tf.pad(
        image,
        paddings=[
            [pad_height_top, pad_height_bottom],
            [pad_width_left, pad_width_right],
            [0, 0],
        ],
    )

    image = tf.transpose(image, perm=[1, 0, 2])
    image = tf.image.flip_left_right(image)
    return image

"""
If we just go with the plain resizing then the images would look like so:

![](https://i.imgur.com/eqq3s4N.png)

Notice how this resizing would have introduced unnecessary stretching.
"""

"""
### Putting the utilities together
"""

batch_size = 64
padding_token = 99
image_width = 128
image_height = 32

def preprocess_image(image_path, img_size=(image_width, image_height)):
    image = tf.io.read_file(image_path)
    image = tf.image.decode_png(image, 1)
    image = distortion_free_resize(image, img_size)
    image = tf.cast(image, tf.float32) / 255.0
    return image

def vectorize_label(label):
    label = char_to_num(tf.strings.unicode_split(label, input_encoding="UTF-8"))
    length = tf.shape(label)[0]
    pad_amount = max_len - length
    label = tf.pad(label, paddings=[[0, pad_amount]], constant_values=padding_token)
    return label

def process_images_labels(image_path, label):
    image = preprocess_image(image_path)
    label = vectorize_label(label)
    return {"image": image, "label": label}

def prepare_dataset(image_paths, labels):
    dataset = tf.data.Dataset.from_tensor_slices((image_paths, labels)).map(
        process_images_labels, num_parallel_calls=AUTOTUNE
    )
    return dataset.batch(batch_size).cache().prefetch(AUTOTUNE)

"""
## Prepare `tf.data.Dataset` objects
"""

train_ds = prepare_dataset(train_img_paths, train_labels_cleaned)
validation_ds = prepare_dataset(validation_img_paths, validation_labels_cleaned)
test_ds = prepare_dataset(test_img_paths, test_labels_cleaned)

"""
## Visualize a few samples
"""

for data in train_ds.take(1):
    images, labels = data["image"], data["label"]

    _, ax = plt.subplots(4, 4, figsize=(15, 8))

    for i in range(16):
        img = images[i]
        img = tf.image.flip_left_right(img)
        img = tf.transpose(img, perm=[1, 0, 2])
        img = (img * 255.0).numpy().clip(0, 255).astype(np.uint8)
        img = img[:, :, 0]

        # Gather indices where label!= padding_token.
        label = labels[i]
        indices = tf.gather(label, tf.where(tf.math.not_equal(label, padding_token)))
        # Convert to string.
        label = tf.strings.reduce_join(num_to_char(indices))
        label = label.numpy().decode("utf-8")

        ax[i // 4, i % 4].imshow(img, cmap="gray")
        ax[i // 4, i % 4].set_title(label)
        ax[i // 4, i % 4].axis("off")

plt.show()

"""
You will notice that the content of original image is kept as faithful as possible and has
been padded accordingly.
"""

"""
## Model

Our model will use the CTC loss as an endpoint layer. For a detailed understanding of the
CTC loss, refer to [this post](https://distill.pub/2017/ctc/).
"""

class CTCLayer(keras.layers.Layer):
    def __init__(self, name=None):
        super().__init__(name=name)
        self.loss_fn = keras.backend.ctc_batch_cost

    def call(self, y_true, y_pred):
        batch_len = tf.cast(tf.shape(y_true)[0], dtype="int64")
        input_length = tf.cast(tf.shape(y_pred)[1], dtype="int64")
        label_length = tf.cast(tf.shape(y_true)[1], dtype="int64")

        input_length = input_length * tf.ones(shape=(batch_len, 1), dtype="int64")
        label_length = label_length * tf.ones(shape=(batch_len, 1), dtype="int64")
        loss = self.loss_fn(y_true, y_pred, input_length, label_length)
        self.add_loss(loss)

        # At test time, just return the computed predictions.
        return y_pred

def build_model():
    # Inputs to the model
    input_img = keras.Input(shape=(image_width, image_height, 1), name="image")
    labels = keras.layers.Input(name="label", shape=(None,))

    # First conv block.
    x = keras.layers.Conv2D(
        32,
        (3, 3),
        activation="relu",
        kernel_initializer="he_normal",
        padding="same",
        name="Conv1",
    )(input_img)
    x = keras.layers.MaxPooling2D((2, 2), name="pool1")(x)

    # Second conv block.
    x = keras.layers.Conv2D(
        64,
        (3, 3),
        activation="relu",
        kernel_initializer="he_normal",
        padding="same",
        name="Conv2",
    )(x)
    x = keras.layers.MaxPooling2D((2, 2), name="pool2")(x)

    # We have used two max pool with pool size and strides 2.
    # Hence, downsampled feature maps are 4x smaller. The number of
    # filters in the last layer is 64. Reshape accordingly before
    # passing the output to the RNN part of the model.
    new_shape = ((image_width // 4), (image_height // 4) * 64)
    x = keras.layers.Reshape(target_shape=new_shape, name="reshape")(x)
    x = keras.layers.Dense(64, activation="relu", name="dense1")(x)
    x = keras.layers.Dropout(0.2)(x)

    # RNNs.
    x = keras.layers.Bidirectional(
        keras.layers.LSTM(128, return_sequences=True, dropout=0.25)
    )(x)
    x = keras.layers.Bidirectional(
        keras.layers.LSTM(64, return_sequences=True, dropout=0.25)
    )(x)

    # +2 is to account for the two special tokens introduced by the CTC loss.
    # The recommendation comes here: https://git.io/J0eXP.
    x = keras.layers.Dense(
        len(char_to_num.get_vocabulary()) + 2, activation="softmax", name="dense2"
    )(x)

    # Add CTC layer for calculating CTC loss at each step.
    output = CTCLayer(name="ctc_loss")(labels, x)

    # Define the model.
    model = keras.models.Model(
        inputs=[input_img, labels], outputs=output, name="handwriting_recognizer"
    )
    # Optimizer.
    opt = keras.optimizers.Adam()
    # Compile the model and return.
    model.compile(optimizer=opt)
    return model

# Get the model.
model = build_model()
model.summary()

"""
## Evaluation metric

[Edit Distance](https://en.wikipedia.org/wiki/Edit_distance)
is the most widely used metric for evaluating OCR models. In this section, we will
implement it and use it as a callback to monitor our model.
"""

"""
We first segregate the validation images and their labels for convenience.
"""
validation_images = []
validation_labels = []

for batch in validation_ds:
    validation_images.append(batch["image"])
    validation_labels.append(batch["label"])

"""
Now, we create a callback to monitor the edit distances.
"""

def calculate_edit_distance(labels, predictions):
    # Get a single batch and convert its labels to sparse tensors.
    saprse_labels = tf.cast(tf.sparse.from_dense(labels), dtype=tf.int64)

    # Make predictions and convert them to sparse tensors.
    input_len = np.ones(predictions.shape[0]) * predictions.shape[1]
    predictions_decoded = keras.backend.ctc_decode(
        predictions, input_length=input_len, greedy=True
    )[0][0][:, :max_len]
    sparse_predictions = tf.cast(
        tf.sparse.from_dense(predictions_decoded), dtype=tf.int64
    )

    # Compute individual edit distances and average them out.
    edit_distances = tf.edit_distance(
        sparse_predictions, saprse_labels, normalize=False
    )
    return tf.reduce_mean(edit_distances)

class EditDistanceCallback(keras.callbacks.Callback):
    def __init__(self, pred_model):
        super().__init__()
        self.prediction_model = pred_model

    def on_epoch_end(self, epoch, logs=None):
        edit_distances = []

        for i in range(len(validation_images)):
            labels = validation_labels[i]
            predictions = self.prediction_model.predict(validation_images[i])
            edit_distances.append(calculate_edit_distance(labels, predictions).numpy())

        print(
            f"Mean edit distance for epoch {epoch + 1}: {np.mean(edit_distances):.4f}"
        )

"""
## Training

Now we are ready to kick off model training.
"""

epochs = 10  # To get good results this should be at least 50.

model = build_model()
prediction_model = keras.models.Model(
    model.get_layer(name="image").input, model.get_layer(name="dense2").output
)
edit_distance_callback = EditDistanceCallback(prediction_model)

# Train the model.
history = model.fit(
    train_ds,
    validation_data=validation_ds,
    epochs=epochs,
    callbacks=[edit_distance_callback],
)

"""
## Inference
"""

# A utility function to decode the output of the network.
def decode_batch_predictions(pred):
    input_len = np.ones(pred.shape[0]) * pred.shape[1]
    # Use greedy search. For complex tasks, you can use beam search.
    results = keras.backend.ctc_decode(pred, input_length=input_len, greedy=True)[0][0][
        :, :max_len
    ]
    # Iterate over the results and get back the text.
    output_text = []
    for res in results:
        res = tf.gather(res, tf.where(tf.math.not_equal(res, -1)))
        res = tf.strings.reduce_join(num_to_char(res)).numpy().decode("utf-8")
        output_text.append(res)
    return output_text

#  Let's check results on some test samples.
for batch in test_ds.take(1):
    batch_images = batch["image"]
    _, ax = plt.subplots(4, 4, figsize=(15, 8))

    preds = prediction_model.predict(batch_images)
    pred_texts = decode_batch_predictions(preds)

    for i in range(16):
        img = batch_images[i]
        img = tf.image.flip_left_right(img)
        img = tf.transpose(img, perm=[1, 0, 2])
        img = (img * 255.0).numpy().clip(0, 255).astype(np.uint8)
        img = img[:, :, 0]

        title = f"Prediction: {pred_texts[i]}"
        ax[i // 4, i % 4].imshow(img, cmap="gray")
        ax[i // 4, i % 4].set_title(title)
        ax[i // 4, i % 4].axis("off")

plt.show()

"""
To get better results the model should be trained for at least 50 epochs.
"""

"""
## Final remarks

* The `prediction_model` is fully compatible with TensorFlow Lite. If you are interested,
you can use it inside a mobile application. You may find
[this notebook](https://github.com/tulasiram58827/ocr_tflite/blob/main/colabs/captcha_ocr_tflite.ipynb)
to be useful in this regard.
* Not all the training examples are perfectly aligned as observed in this example. This
can hurt model performance for complex sequences. To this end, we can leverage
Spatial Transformer Networks ([Jaderberg et al.](https://arxiv.org/abs/1506.02025))
that can help the model learn affine transformations that maximize its performance.
"""


text:
import os
import os.path as osp
import sys
import time
import logging
import pathlib
import uuid
import shutil
import torch
import random
import numpy as np

class BaseArgs:
    def __init__(self, parser):
        parser.add_argument('--phase', type=str, default='train',
                            help='phase. Default: train')
        parser.add_argument('--seed', type=int, default=0)

        # datasets args
        parser.add_argument('--train_list', type=str, default='datasets/train_mirflickr.txt',
                            help='path to train list')
        parser.add_argument('--val_list', type=str, default='datasets/val_mirflickr.txt',
                            help='path to val list')
        parser.add_argument('--benchmark_path', type=str,
                            default='data/benchmark/urban100/urban100_noisy_lr_raw-srgb.pt',
                            help='path to val list')

        parser.add_argument('--patch_size', default=64, type=int,
                            help='width and height for a patch (default: 256)')
        parser.add_argument('--in_channels', default=3, type=int,
                            help='in_channels, RGB')
        parser.add_argument('--gt_channels', default=3, type=int,
                            help='gt_channels, RGB')
        parser.add_argument('--in_type', type=str, default='noisy_lr_raw',
                            help='the input image type: noisy_lr_raw, lr_raw, noisy_raw, raw, '
                                 'noisy_lr_linrgb, lr_linrgb, noisy_linrgb, linrgb, '
                                 'noisy_lr_rgb, lr_rgb, noisy_rgb, rgb'
                            )
        parser.add_argument('--mid_type', type=str, default='None',
                            help='the mid output image type: noisy_lr_raw, lr_raw, noisy_raw, raw, '
                                 'noisy_lr_linrgb, lr_linrgb, noisy_linrgb, linrgb, '
                                 'noisy_lr_rgb, lr_rgb, noisy_rgb, rgb, None'
                            )
        parser.add_argument('--out_type', type=str, default='linrgb',
                            help='the output image type: noisy_lr_raw, lr_raw, noisy_raw, raw, '
                                 'noisy_lr_linrgb, lr_linrgb, noisy_linrgb, linrgb, '
                                 'noisy_lr_rgb, lr_rgb, noisy_rgb, rgb'
                            )

        # noise
        # parser.add_argument('--denoise', action='store_true', help='denoise store_true, using shot and read noise')
        parser.add_argument('--read_noise', default=0.00, type=float, help='read_noise')
        parser.add_argument('--shot_noise', default=0.00, type=float, help='shot_noise')

        # train args
        parser.add_argument('--imgs_per_gpu', default=16, type=int,
                            help='batch size per GPU (default:16)')
        parser.add_argument('--n_gpus', default=1, type=int,
                            help='number of GPUs (default:1)')
        parser.add_argument('--max_epochs', default=500, type=int,
                            help='number of total epochs to run')
        parser.add_argument('--lr', default=1e-4, type=float,
                            help='initial learning rate')
        parser.add_argument('--lr_decay_step', default=50, type=int,
                            help='learning rate decay step')
        parser.add_argument('--gamma', default=0.5, type=float,
                            help='learning rate decay gamma')

        # logger parse
        parser.add_argument('--root_dir', type=str, default='log',
                            help='path for saving experiment files')
        parser.add_argument('--img_freq', default=10, type=int,
                            help='show images every xxx epochs(default: 10)')
        parser.add_argument('--print_freq', default=100, type=int,
                            help='show images every xxx iterations(default: 100)')
        # model args
        parser.add_argument('--model', default='tenet', type=str,
                            help='path to pretrained model (default: tenet)')
        parser.add_argument('--norm_type', default=None, type=str,
                            help='normalization_type(default: do not use BN or IN)')
        parser.add_argument('--block_type', default='res', type=str,
                            help='dm_block_type(default: res). res/dudb/rrdb')
        parser.add_argument('--act_type', default='relu', type=str,
                            help='activation layer {relu, prelu, leakyrelu}')
        parser.add_argument('--no_bias', action='store_false', dest='bias',
                            help='do not use bias of layer')
        parser.add_argument('--channels', default=64, type=int,
                            help='channels')
        parser.add_argument('--n_blocks', default=18, type=int,
                            help='number of basic blocks')
        parser.add_argument('--mid_out', action='store_true',
                            help='activate middle output supervision')
        parser.add_argument('--output_mid', action='store_true',
                            help='output the middle stage result')

        # for super-resolution
        parser.add_argument('--scale', default=2, type=int,
                            help='Scale of Super-resolution. Default: 2')
        parser.add_argument('--downsampler', default='bic', type=str,
                            help='downsampler of Super-resolution. Bicubic or average downsampling.  bic / avg')
        # loss args
        parser.add_argument('--mid_lambda', type=float, default=1.0, help='lamda for the middle stage supervision')
        parser.add_argument('--loss_on_srgb', action='store_true',
                            help='calculate the loss function values on sRGB')

        # test args
        parser.add_argument('--save_dir', type=str, default=None,
                            help='path to save the test result')
        parser.add_argument('--test_data', type=str, default='/home/wangy0k/Desktop/denoise/darmstadt/data/',
                            help='path to the test data (dnd dataset)')
        parser.add_argument('--pretrain', default='', type=str,
                            help='path to pretrained model(default: none)')
        parser.add_argument('--pretrain_dir', default='', type=str,
                            help='path to pretrained model(default: none)')
        parser.add_argument('--intermediate', type=bool, default=False,
                            help='ISP intermediate state')
        parser.add_argument('--pre_in_type', type=str, default='noisy_lr_raw',
                            help='the input image type: noisy_lr_raw, lr_raw, noisy_raw, raw, '
                                 'noisy_lr_linrgb, lr_linrgb, noisy_linrgb, linrgb, '
                                 'noisy_lr_rgb, lr_rgb, noisy_rgb, rgb'
                            )
        parser.add_argument('--pre_out_type', type=str, default='raw',
                            help='the output image type: noisy_lr_raw, lr_raw, noisy_raw, raw, '
                                 'noisy_lr_linrgb, lr_linrgb, noisy_linrgb, linrgb, '
                                 'noisy_lr_rgb, lr_rgb, noisy_rgb, rgb'
                            )
        parser.add_argument('--pre_model', default='tenet', type=str,
                            help='path to pretrained model (default: tenet)')

        args = parser.parse_args()

        args.dataset = args.train_list.split('_')[-1].split('.')[0]
        args.batch_size = args.imgs_per_gpu * args.n_gpus

        args.pre_jobname = '-'.join([args.pre_in_type, args.mid_type, args.pre_out_type])
        args.jobname = '-'.join([args.in_type, args.mid_type, args.out_type])

        args.mid_type = None if args.mid_type == 'None' else args.mid_type
        self.args = args

        # ===> generate log dir
        self._generate_exp_directory()
        if self.args.phase == 'train':
            self._configure_logger()
        self._print_args()
        self.set_seed(self.args.seed)
        self.args.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    def _generate_exp_directory(self):
        """
        Helper function to create checkpoint folder. We save
        model checkpoints using the provided model directory
        but we add a sub-folder for each separate experiment:
        """
        timestamp = time.strftime('%Y%m%d-%H%M%S')

        experiment_string = '_'.join([self.args.jobname, timestamp, str(uuid.uuid4())])

        if self.args.phase == 'train':
            self.args.exp_dir = osp.join(self.args.root_dir, experiment_string)
            self.args.ckpt_dir = osp.join(self.args.exp_dir, "checkpoint")
            self.args.code_dir = osp.join(self.args.exp_dir, "code")
            self.args.res_dir = osp.join(self.args.exp_dir, "result")
            pathlib.Path(self.args.exp_dir).mkdir(parents=True, exist_ok=True)
            pathlib.Path(self.args.ckpt_dir).mkdir(parents=True, exist_ok=True)
            pathlib.Path(self.args.res_dir).mkdir(parents=True, exist_ok=True)
            # ===> save scripts
            shutil.copytree('model', osp.join(self.args.code_dir, 'model'))
            shutil.copytree('TorchTools', osp.join(self.args.code_dir, 'TorchTools'))
        else:

            if not self.args.save_dir:
                self.args.save_dir = osp.dirname(self.args.pretrain)
            # self.args.save_dir = osp.join(self.args.save_dir, "result-{}".format(osp.basename(self.args.pretrain)))
            pathlib.Path(self.args.save_dir).mkdir(parents=True, exist_ok=True)

    def _configure_logger(self):
        """
        Configure logger on given level. Logging will occur on standard
        output and in a log file saved in model_dir.
        """
        self.args.loglevel = "info"
        numeric_level = getattr(logging, self.args.loglevel.upper(), None)
        if not isinstance(numeric_level, int):
            raise ValueError('Invalid log level: {}'.format(self.args.loglevelloglevel))

        log_format = logging.Formatter('%(asctime)s %(message)s')
        logger = logging.getLogger()
        logger.setLevel(numeric_level)

        file_handler = logging.FileHandler(osp.join(self.args.exp_dir,
                                                    '{}.log'.format(osp.basename(self.args.exp_dir))))
        file_handler.setFormatter(log_format)
        logger.addHandler(file_handler)

        file_handler = logging.StreamHandler(sys.stdout)
        file_handler.setFormatter(log_format)
        logger.addHandler(file_handler)
        logging.root = logger
        logging.info("save log, checkpoint and code to: {}".format(self.args.exp_dir))

    def _print_args(self):
        logging.info("==========       args      =============")
        for arg, content in self.args.__dict__.items():
            logging.info("{}: {}".format(arg, content))
        logging.info("==========     args END    =============")
        logging.info("\n")
        logging.info('===> Phase is {}.'.format(self.args.phase))

    @staticmethod
    def set_seed(seed=0):
        random.seed(seed)
        np.random.seed(seed)
        torch.manual_seed(seed)
        torch.cuda.manual_seed(seed)
        torch.cuda.manual_seed_all(seed)
        torch.backends.cudnn.deterministic = True
        torch.backends.cudnn.benchmark = False

ext: py

max_stars_repo_name: guochengqian/TENet

max_issues_repo_name: guochengqian/TENet

max_forks_repo_name: guochengqian/TENet

reason: import numpy


text:
import os
from argparse import ArgumentParser

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import pickle
from tensorboard.backend.event_processing.event_accumulator import EventAccumulator

from vis_paper_test import get_framework_name

seven_tab10_colors = [
    (0.12156862745098039, 0.4666666666666667, 0.7058823529411765),
    (1.0, 0.4980392156862745, 0.054901960784313725),
    (0.17254901960784313, 0.6274509803921569, 0.17254901960784313),
    (0.8392156862745098, 0.15294117647058825, 0.1568627450980392),
    (0.5803921568627451, 0.403921568627451, 0.7411764705882353),
    (0.5490196078431373, 0.33725490196078434, 0.29411764705882354),
    (0.8901960784313725, 0.4666666666666667, 0.7607843137254902),
    (0.4980392156862745, 0.4980392156862745, 0.4980392156862745),
    (0.7372549019607844, 0.7411764705882353, 0.13333333333333333),
    (0.09019607843137255, 0.7450980392156863, 0.8117647058823529),
]
plots = 2
palette = sns.color_palette(seven_tab10_colors[:4])

if plots == 2:
    first_col = [seven_tab10_colors[0]]
    seven_tab10_colors = first_col + seven_tab10_colors[-3:]
    palette = sns.color_palette(seven_tab10_colors)

sns.set(style="darkgrid", font_scale=1)
OUTPUT_DIR = "./output"

def get_scalars(
    tb_log,
    scalar_name,
    window_size=30,
):

    event_acc = EventAccumulator(tb_log)
    event_acc.Reload()

    try:
        _, time_steps, vals = zip(*event_acc.Scalars(scalar_name))
    except KeyError:
        print("Could not find scalar " + scalar_name)
        return None

    # convert time steps to episodes
    episodes = np.arange(1, len(time_steps) + 1)

    # the cumulative values must be divided by their respective episode length
    if "cum" in scalar_name:
        _, ep_lens_time_steps, ep_lens = zip(*event_acc.Scalars("rollout/ep_len_mean"))
        # access the episode lengths at the desired time steps (this will only make a difference if we access per object data)
        desired_ep_lens = []
        for i in range(len(time_steps)):
            time_steps = np.array(time_steps)
            ep_lens_time_steps = np.array(ep_lens_time_steps)
            index = np.where(time_steps[i] == ep_lens_time_steps)[0][0]
            desired_ep_lens.append(ep_lens[index])
        vals = np.array(vals) / np.array(desired_ep_lens)

    # smooth data with moving average filter
    vals = np.convolve(vals, np.ones(window_size), "valid") / window_size
    episodes = np.convolve(episodes, np.ones(window_size), "valid") / window_size

    # create pd dataframe
    data = {"episodes": episodes, scalar_name: vals}
    return pd.DataFrame(data)

def get_experiment_data(tb_log, args):

    event_acc = EventAccumulator(tb_log)
    event_acc.Reload()

    # the variable that you want to keep fixed
    # try:
    #     _, _, x = zip(*event_acc.Scalars(f"hparams/{args.keep_fixed}"))

    #     if x[0] != args.keep_fixed_value:
    #         print("none")
    #         return None

    # except Exception as e:
    #     print(e)
    #     return None

    df = pd.DataFrame()

    for s in args.scalar_names:
        df = df.append(get_scalars(tb_log, s[0]))

    # get some interesting hyperparameters
    des_hparams = ["reward_framework", "force_framework", "w_eps_torque", "w_delta", "gradient_steps", "learning_rate", "batch_size", "tau"]

    for hparam in des_hparams:
        try:
            _, _, x = zip(*event_acc.Scalars("hparams/" + hparam))
        except KeyError as e:
            print(e)
            continue
        if "framework" in hparam:
            force_framework = True if hparam == "force_framework" else False
            df[hparam] = get_framework_name(force_framework, x[0])
        else:
            df[hparam] = f"{x[0]:.5f}"

    # extract experiment id from log string
    id = tb_log.split("id")[1].split("_")[0]
    df["try_id"] = id
    df["tb_log"] = tb_log
    return df

def get_all_data(args, valid_tb_logs):
    print("Getting all data...")
    # get any directories
    all_dirs = [os.path.join(args.log_path, dir) for dir in os.listdir(args.log_path) if dir.endswith("_1")]

    # filter dirs for valid ones
    dirs = []
    for i in range(len(valid_tb_logs)):
        for j in range(len(all_dirs)):
            if all_dirs[j].__contains__(valid_tb_logs[i]):
                dirs.append(all_dirs[j])

    df = pd.DataFrame()

    m = 0
    for tb_log in dirs:
        m += 1
        print(f"({m}) - Getting " + tb_log)
        df = df.append(get_experiment_data(tb_log, args))
        # break

    # very infrequently we get data points with very high forces values, we treat them as outliers and remove them
    df_sum = df[df["episode/cum_sum_contact_forces"] <= 200]
    df = df[np.isnan(df["episode/cum_sum_contact_forces"])]
    df = df.append(df_sum)
    print(df)
    return df

def plot(args, df, title):
    hue_order = ["Full", "Normal", "Binary", "None"] if args.compare == "force_framework" else [r"$\epsilon$ and $\delta$", r"$\delta$", r"$\epsilon$", r"$\beta$"]
    num_frameworks = 4

    # all data should start at 15.5 episodes
    df = df[df["episodes"] >= 15.5]

    num_plots = len(args.scalar_names)
    fig = plt.figure(figsize=(10, 14.7))
    num_tries_per_exp = len(np.unique(df["tb_log"].values)) / num_frameworks
    print("Num tries per exp " + str(num_tries_per_exp))

    for i in range(num_plots):
        ax = fig.add_subplot(8, 3, i + 1)
        sns.lineplot(data=df, x="episodes", y=args.scalar_names[i][0], palette=palette, hue=args.compare, hue_order=hue_order, ax=ax)

        lines, labels = ax.get_legend_handles_labels()
        ax.get_legend().remove()
        ax.set_xlabel("Episodes")
        ax.set_xlim((0, 900))
        ax.xaxis.set_ticks(np.arange(0, 900, 250))
        ax.set_title("Plot (" + str(i + 1) + ") - All Objects")

        # a few metrics do not require setting of y ticks
        not_zero_to_one = ["rollout/ep_rew_mean", "episode/cum_num_contacts", "episode/cum_sum_contact_forces"]
        if args.scalar_names[i][0] not in not_zero_to_one:
            ax.yaxis.set_ticks(np.arange(0, 1.1, 0.5))

        if "box" in args.scalar_names[i][0]:
            ax.set_title("Plot (" + str(i + 1) + ") - Cuboids")
            ax.set_xlabel("Cuboid-Episodes")
            # todo remove
            ax.set_xlim((0, 300))
            ax.xaxis.set_ticks(np.arange(0, 290, 100))
        elif "cylinder" in args.scalar_names[i][0]:
            ax.set_title("Plot (" + str(i + 1) + ") - Cylinders")
            ax.set_xlabel("Cylinder-Episodes")
            # todo remove
            ax.set_xlim((0, 300))
            ax.xaxis.set_ticks(np.arange(0, 290, 100))
        elif "sphere" in args.scalar_names[i][0]:
            ax.set_title("Plot (" + str(i + 1) + ") - Spheres")
            ax.set_xlabel("Sphere-Episodes")
            # todo remove
            ax.set_xlim((0, 300))
            ax.xaxis.set_ticks(np.arange(0, 290, 100))
        ax.set_ylabel(args.scalar_names[i][1])
        if "sustained" in args.scalar_names[i][0]:
            ax.set_ylim((0, 1))

    fig.tight_layout(rect=[0, 0, 1, 0.96], pad=0.05, h_pad=1, w_pad=0.7)
    fig.legend(lines, labels, loc="upper center", ncol=4)
    fig.show()
    fig.savefig(f"{OUTPUT_DIR}/thesis_train_{args.prefix}_{args.compare}.png")
    fig.savefig(f"{OUTPUT_DIR}/thesis_train_{args.prefix}_{args.compare}.pdf")

if __name__ == "__main__":
    parser = ArgumentParser("Plots results of RL algorithm training.")
    parser.add_argument(
        "--log_path",
        type=str,
        default="/Users/koenig/Documents/master/semester_5/thesis/data/cluster_logs_sd6_14sep",
        help="Path to tensorboard log.",
    )
    parser.add_argument(
        "--prefix",
        type=str,
        default="23Aug_SmallTau25k_f",
        help="Prefix comment of your experiment.",
    )
    parser.add_argument(
        "--scalar_names",
        type=str,
        default="step/sustained_holding",
        help="Which metric to plot.",
    )
    parser.add_argument(
        "--compare",
        type=str,
        default="reward_framework",
        help="Which metric to compare.",
    )
    args = parser.parse_args()

    args.scalar_names = [
        ("step/sustained_holding", "Hold Success"),
        ("step/sustained_lifting", "Lift Success"),
        ("rollout/ep_rew_mean", "Episode Reward"),
        ("step/sustained_holding_box", "Hold Success"),
        ("step/sustained_holding_cylinder", "Hold Success"),
        ("step/sustained_holding_sphere", "Hold Success"),
        ("episode/cum_a_epsilon_force", r"$\epsilon_{f}$"),
        ("episode/cum_a_epsilon_torque", r"$\epsilon_{\tau}$"),
        ("episode/cum_num_contacts", "Num. Contacts"),
        ("episode/cum_a_delta_cur", r"$\delta_{cur}$"),
        ("episode/cum_a_delta_task", r"$\delta_{task}$"),
        ("episode/cum_sum_contact_forces", "Sum Forces in N"),
        ("episode/cum_a_epsilon_force_box", r"$\epsilon_{f}$"),
        ("episode/cum_a_epsilon_force_cylinder", r"$\epsilon_{f}$"),
        ("episode/cum_a_epsilon_force_sphere", r"$\epsilon_{f}$"),
        ("episode/cum_a_epsilon_torque_box", r"$\epsilon_{\tau}$"),
        ("episode/cum_a_epsilon_torque_cylinder", r"$\epsilon_{\tau}$"),
        ("episode/cum_a_epsilon_torque_sphere", r"$\epsilon_{\tau}$"),
        ("episode/cum_a_delta_cur_box", r"$\delta_{cur}$"),
        ("episode/cum_a_delta_cur_cylinder", r"$\delta_{cur}$"),
        ("episode/cum_a_delta_cur_sphere", r"$\delta_{cur}$"),
        ("episode/cum_a_delta_task_box", r"$\delta_{task}$"),
        ("episode/cum_a_delta_task_cylinder", r"$\delta_{task}$"),
        ("episode/cum_a_delta_task_sphere", r"$\delta_{task}$"),
    ]

    if plots == 1:
        args.compare = "reward_framework"
        frameworks = [r"$\epsilon$ and $\delta$", r"$\delta$", r"$\epsilon$", r"$\beta$"]
    elif plots == 2:
        args.compare = "force_framework"
        frameworks = ["Full", "Normal", "Binary", "None"]

    # we want to filter the frameworks that were successfully completeted
    done_frameworks_path = os.path.join(".", f"done_{args.compare}.pkl")
    with open(done_frameworks_path, "rb") as file:
        valid_tb_logs = pickle.load(file)

    title_path = os.path.join(".", f"title_{args.compare}.pkl")
    with open(title_path, "rb") as file:
        title = pickle.load(file)

    # get all data that we have a test result for
    df = get_all_data(args, valid_tb_logs)

    plot(args, df, title)

    print("done!")

    import pdb

    pdb.set_trace()


text:
import unittest
from unittest import TestCase

import numpy as np
import xarray as xr
import rasppy

# prepare the test data
lidar = xr.open_dataset('test_data.nc')
# get rid of silly byte strings that xarray created
lidar.coords['Component'].values = list(map(lambda x: x.decode(), lidar.coords['Component'].values))
lidar['wspeed2'] = lidar.rasp.estimate_wind()

class TestWinds(TestCase):
    def test_wind_estimate_is_close(self):
        self.assertTrue((lidar['Windspeed'] - lidar['wspeed2']).max().values < .002)

    def test_same_nans(self):
        wspeed1 = lidar['Windspeed'].isel(Time=range(4, lidar.dims['Time']))
        wspeed2 = lidar['wspeed2'].isel(Time=range(4, lidar.dims['Time']))
        self.assertTrue(np.all(np.equal(np.isnan(wspeed1), np.isnan(wspeed1))))

if __name__ == '__main__':
    unittest.main()

max_stars_repo_name: ASRCsoft/skykit

max_issues_repo_name: ASRCsoft/skykit

max_forks_repo_name: ASRCsoft/skykit


text:
import argparse
import pandas as pd
import numpy as np
from collections import defaultdict

import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'lib'))
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import common
import inputparser
import neutree
import util

def replace_supervar_with_variants(clusters, mutass):
  expanded = {}
  for cid in mutass.keys():
    expanded[cid] = []
    for svid in mutass[cid]:
      assert svid.startswith('S')
      svidx = int(svid[1:])
      expanded[cid] += clusters[svidx]
  return expanded

def load_tree(tid, resultfn):
  adjl = pd.read_hdf(resultfn, f'trees/{tid}/adjacency_list').to_numpy()
  parents, children = adjl[:,0], adjl[:,1]
  K = np.max(children) + 1
  adjm = np.eye(K)
  adjm[parents,children] = 1
  common.ensure_valid_tree(adjm)
  return adjm

def load_phi(tid, resultfn):
  phi = pd.read_hdf(resultfn, f'trees/{tid}/clade_freq').to_numpy().T
  return phi

def load_list(listfn):
  with open(listfn) as F:
    vals = [L.strip() for L in F.readlines()]
  return vals

def load_mutass(tid, resultfn, vidfn):
  # Assignments are variants to tree nodes.
  # Returns `mutass` dict, where `mutass[i]` is nodex index of variant `i`

  # Definitions:
  # `M` variants
  # `C` clusters
  # `N` nodes
  # (we should have `N = C`)

  # `varass`: `M`-length vector, where `varass[i]` is node index of variant `i`
  # `vids`: `M`-length vector, where `vids[i]` is VID of variant `i` (CITUP doesn't use VIDs, so this is my own mapping that their code never sees)
  varass = pd.read_hdf(resultfn, f'trees/{tid}/variant_assignment').to_numpy()
  vids = load_list(vidfn)
  assert len(varass) == len(vids)

  # `mutass`: dict, where `mutass[n]` is VIDs associated with node `n`
  mutass = defaultdict(list)
  for vid, nid in zip(vids, varass):
    mutass[nid].append(vid)
  return dict(mutass)

def load_mutass_using_clusters(tid, resultfn, vidfn, clustfn):
  # Assignments are variants to tree nodes.
  # Returns `mutass` dict, where `mutass[i]` is nodex index of variant `i`

  # Definitions:
  # `M` variants
  # `C` clusters
  # `N` nodes
  # (we should have `N = C`)

  # `clustass`: `C`-length vector, where `clustass[i]` is cluster index of variant `i`
  # `vids`: `M`-length vector, where `vids[i]` is VID of variant `i` (CITUP doesn't use VIDs, so this is my own mapping that their code never sees)
  clustass = [int(C) for C in load_list(clustfn)]
  vids = load_list(vidfn)
  assert len(clustass) == len(vids)

  clusters = defaultdict(list)
  for C, V in zip(clustass, vids):
    clusters[C].append(V)
  # If subsequent code accesses a nonexistent index in `clusters`, I want it to
  # throw an exception, so convert to regular dict.
  clusters = dict(clusters)

  # Assignments are clusters to tree nodes.
  # Returns `mutass`, which is dictionary giving tree nodes to VIDs.
  # `clust2node`: `C`-length vector, where `clust2node[c]` is nodex index of cluster `c`
  # `mutass`: dict, where `mutass[n]` is VIDs associated with node `n`
  clust2node = pd.read_hdf(resultfn, f'trees/{tid}/cluster_assignment').to_numpy()
  mutass = defaultdict(list)
  for C, N in enumerate(clust2node):
    # This mapping isn't guaranteed to be one-to-one -- sometimes we can have
    # multiple clusters assigned to a single node.
    mutass[N] += clusters[C]
  return dict(mutass)

def _extract_clustering(mutass, K):
  clustering = [list(mutass[C]) if C in mutass else [] for C in range(K)]
  return clustering

def _check_results(results):
  def _extract_members(clusters):
    return set([vid for C in clusters for vid in C])

  K, S = results[0]['phi'].shape
  members = _extract_members(results[0]['clusters'])

  for R in results:
    assert R['adjm'].shape == (K, K)
    assert R['phi'].shape == (K, S)
    assert len(R['clusters']) == K
    M = _extract_members(R['clusters'])
    assert M == members

def load_results(resultfn, vidfn, citup_clusters_fn, clusters, use_supervars):
  # NB:
  # * `clusters` are the Pairtree clusters, which we need only if we're using supervars
  # * `citup_clusters_fn` lists the assignment of variants to clusters, which
  #   we need only if CITUP used fixed clusters, which it does only when we're
  #   using the QIP rather than the iterative approximation mode in CITUP.

  tree_ids = pd.read_hdf(resultfn, 'results/tree_id').to_numpy()
  llh = pd.read_hdf(resultfn, 'results/likelihood').to_numpy()
  llh *= -1
  results = []

  for tid, tree_llh in zip(tree_ids, llh):
    adjm = load_tree(tid, resultfn)
    phi = load_phi(tid, resultfn)
    if citup_clusters_fn is None:
      mutass = load_mutass(tid, resultfn, vidfn)
    else:
      mutass = load_mutass_using_clusters(tid, resultfn, vidfn, citup_clusters_fn)

    K, S = phi.shape
    assert adjm.shape == (K, K)
    if False and len(mutass) != K - 1:
      # This condition seems common, so suppress the print.
      print('Nodes', set(range(1, K)) - set(mutass.keys()), 'have no assigned variants')

    if use_supervars:
      mutass = replace_supervar_with_variants(clusters, mutass)

    results.append({
      'adjm': adjm,
      'phi': phi,
      'clusters': _extract_clustering(mutass, K),
      'llh': tree_llh,
    })

  assert len(results) > 0
  _check_results(results)
  return results

def write_neutree(results, garbage, neutree_fn):
  adjms = [R['adjm'] for R in results]
  structs = [util.convert_adjmatrix_to_parents(A) for A in adjms]
  llhs = [R['llh'] for R in results]
  clusterings = [R['clusters'] for R in results]
  phis = [R['phi'] for R in results]
  N = len(structs)
  counts = np.ones(N)
  ntree = neutree.Neutree(
    structs = structs,
    phis = phis,
    counts = counts,
    logscores = llhs,
    clusterings = clusterings,
    garbage = garbage,
  )
  neutree.save(ntree, neutree_fn)

def main():
  parser = argparse.ArgumentParser(
    description='LOL HI THERE',
    formatter_class=argparse.ArgumentDefaultsHelpFormatter
  )
  parser.add_argument('--use-supervars', action='store_true')
  parser.add_argument('--citup-clusters')
  parser.add_argument('citup_result_fn')
  parser.add_argument('citup_vid_fn')
  parser.add_argument('pairtree_params_fn')
  parser.add_argument('neutree_fn')
  args = parser.parse_args()

  params = inputparser.load_params(args.pairtree_params_fn)
  results = load_results(args.citup_result_fn, args.citup_vid_fn, args.citup_clusters, params['clusters'], args.use_supervars)
  write_neutree(results, params['garbage'], args.neutree_fn)

if __name__ == '__main__':
  main()

max_stars_repo_name: J-Moravec/pairtree

max_issues_repo_name: J-Moravec/pairtree

max_forks_repo_name: J-Moravec/pairtree


text:
import sklearn.metrics
import numpy as np

def aurocScore(inData, outData):
	allData = np.concatenate((inData, outData))
	labels = np.concatenate((np.zeros(len(inData)), np.ones(len(outData))))
	fpr, tpr, thresholds = sklearn.metrics.roc_curve(labels, allData, pos_label = 0)
	return fpr, tpr, sklearn.metrics.auc(fpr, tpr)

def tprAtFpr(tpr, fpr, fprRate = 0.05):
	fprAdjust = np.abs(np.array(fpr)-fprRate)
	fprIdx = np.argmin(fprAdjust)
	tpratfpr = tpr[fprIdx]

	return tpratfpr, fpr[fprIdx]

def summarise_performance(inData, outData, fprRates = [], printRes = True, methodName = ''):
    results = {}

    fpr, tpr, auroc = aurocScore(inData, outData)
    results['auroc'] = auroc
    results['fpr'] = list(fpr)
    results['tpr'] = list(tpr)

    specPoints = []
    for fprRate in fprRates:
        tprRate = tprAtFpr(tpr, fpr, fprRate)
        specPoints += [tprRate]

        results[f'tpr at fprRate {fprRate}'] = tprRate

    if printRes:
        print(f'Results for Method: {methodName}')
        print(f'------ AUROC: {round(auroc, 3)}')
        for point in specPoints:
            fp = point[1]
            tp = point[0]
            print(f'------ TPR at {round((100.*fp), 1)}FPR: {round((100.*tp), 1)}')

    return results


text:
import itertools
import random

import vectorization_tools
from digit_input import Digit
from digit_mutator import DigitMutator
from utils import print_archive

import numpy as np
from deap import base, creator, tools
from deap.tools.emo import selNSGA2
from tensorflow import keras

import archive_manager
from individual import Individual
from properties import NGEN, IMG_SIZE, \
    POPSIZE, EXPECTED_LABEL, INITIALPOP, \
    ORIGINAL_SEEDS, RESEEDUPPERBOUND, GENERATE_ONE_ONLY

# Load the dataset.
mnist = keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# Fetch the starting seeds from file
with open(ORIGINAL_SEEDS) as f:
    starting_seeds = f.read().split(',')[:-1]

# DEAP framework setup.
toolbox = base.Toolbox()
# Define a bi-objective fitness function.
creator.create("FitnessMulti", base.Fitness, weights=(1.0, -1.0))
# Define the individual.
creator.create("Individual", Individual, fitness=creator.FitnessMulti)

def generate_digit(seed):
    seed_image = x_test[int(seed)]
    xml_desc = vectorization_tools.vectorize(seed_image)
    return Digit(xml_desc, EXPECTED_LABEL)

def generate_individual():
    Individual.COUNT += 1

    if INITIALPOP == 'random':
        # Choose randomly a file in the original dataset.
        seed = random.choice(starting_seeds)
        Individual.SEEDS.add(seed)
    elif INITIALPOP == 'seeded':
        # Choose sequentially the inputs from the seed list.
        # NOTE: number of seeds should be no less than the initial population
        assert (len(starting_seeds) == POPSIZE)
        seed = starting_seeds[Individual.COUNT - 1]
        Individual.SEEDS.add(seed)

    if not GENERATE_ONE_ONLY:
        digit1, digit2, distance_inputs = DigitMutator(generate_digit(seed)).generate()
    else:
        digit1 = generate_digit(seed)
        digit2 = digit1.clone()
        distance_inputs = DigitMutator(digit2).mutate()

    individual = creator.Individual(digit1, digit2)
    individual.distance = distance_inputs
    individual.seed = seed

    return individual

def reseed_individual(seeds):
    Individual.COUNT += 1
    # Chooses randomly the seed among the ones that are not covered by the archive
    if len(starting_seeds) > len(seeds):
        chosen_seed = random.sample(set(starting_seeds) - seeds, 1)[0]
    else:
        chosen_seed = random.choice(starting_seeds)

    if not GENERATE_ONE_ONLY:
        first_digit, second_digit, distance_inputs = DigitMutator(generate_digit(chosen_seed)).generate()
    else:
        digit1 = generate_digit(chosen_seed)
        digit2 = digit1.clone()
        distance_inputs = DigitMutator(digit2).mutate()

    individual = creator.Individual(first_digit, second_digit)
    individual.distance = distance_inputs
    individual.seed = chosen_seed
    return individual

# Evaluate an individual.
def evaluate_individual(individual, current_solution):
    individual.evaluate(current_solution)
    return individual.aggregate_ff, individual.misclass

def mutate_individual(individual):
    Individual.COUNT += 1
    # Select one of the two members of the individual.
    if random.getrandbits(1):
        distance_inputs = DigitMutator(individual.member1).mutate(reference=individual.member2)
    else:
        distance_inputs = DigitMutator(individual.member2).mutate(reference=individual.member1)
    individual.reset()
    individual.distance = distance_inputs

toolbox.register("individual", generate_individual)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("evaluate", evaluate_individual)
toolbox.register("select", selNSGA2)
toolbox.register("mutate", mutate_individual)

def main(rand_seed=None):
    random.seed(rand_seed)

    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("min", np.min, axis=0)
    stats.register("max", np.max, axis=0)
    stats.register("avg", np.mean, axis=0)
    stats.register("std", np.std, axis=0)
    logbook = tools.Logbook()
    logbook.header = "gen", "evals", "min", "max", "avg", "std"

    # Generate initial population.
    print("### Initializing population ....")
    population = toolbox.population(n=POPSIZE)

    # Evaluate the individuals with an invalid fitness.
    # Note: the fitnesses are all invalid before the first iteration since they have not been evaluated
    invalid_ind = [ind for ind in population]

    # fitnesses = toolbox.map(toolbox.evaluate, invalid_ind, itertools.repeat(population))
    # Note: the sparseness is calculated wrt the archive. It can be calculated wrt population+archive
    # Therefore, we pass to the evaluation method the current archive.
    fitnesses = toolbox.map(toolbox.evaluate, invalid_ind, itertools.repeat(archive.get_archive()))
    for ind, fit in zip(invalid_ind, fitnesses):
        ind.fitness.values = fit

    # Update archive with the individuals on the decision boundary.
    for ind in population:
        if ind.misclass < 0:
            archive.update_archive(ind)

    print("### Number of Individuals generated in the initial population: " + str(Individual.COUNT))

    # This is just to assign the crowding distance to the individuals (no actual selection is done).
    population = toolbox.select(population, len(population))

    record = stats.compile(population)
    logbook.record(gen=0, evals=len(invalid_ind), **record)
    print(logbook.stream)

    # Begin the generational process
    for gen in range(1, NGEN):
        # Vary the population.
        offspring = tools.selTournamentDCD(population, len(population))
        offspring = [toolbox.clone(ind) for ind in offspring]

        # Reseeding
        if len(archive.get_archive()) > 0:
            seed_range = random.randrange(1, RESEEDUPPERBOUND)
            candidate_seeds = archive.archived_seeds
            for i in range(seed_range):
                population[len(population) - i - 1] = reseed_individual(candidate_seeds)

        # Mutation.
        for ind1, ind2 in zip(offspring[::2], offspring[1::2]):
            toolbox.mutate(ind1)
            toolbox.mutate(ind2)
            del ind1.fitness.values, ind2.fitness.values

        # Evaluate the individuals
        # NOTE: all individuals in both population and offspring are evaluated to assign crowding distance.
        invalid_ind = [ind for ind in population + offspring]
        fitnesses = toolbox.map(toolbox.evaluate, invalid_ind, itertools.repeat(archive.get_archive()))

        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit

        for ind in population + offspring:
            if ind.fitness.values[1] < 0:
                archive.update_archive(ind)

        # Select the next generation population
        population = toolbox.select(population + offspring, POPSIZE)

        if gen % 300 == 0:
            archive.create_report(x_test, Individual.SEEDS, gen)

        # Update the statistics with the new population
        record = stats.compile(population)
        logbook.record(gen=gen, evals=len(invalid_ind), **record)
        print(logbook.stream)

    print(logbook.stream)

    return population

if __name__ == "__main__":
    archive = archive_manager.Archive()
    pop = main()

    print_archive(archive.get_archive())
    archive.create_report(x_test, Individual.SEEDS, 'final')
    print("GAME OVER")

max_stars_repo_name: TrackerSB/deepjanus

max_issues_repo_name: TrackerSB/deepjanus

max_forks_repo_name: TrackerSB/deepjanus


text:
from __future__ import division
from __future__ import print_function

import numpy as np
import scipy.sparse as sp
from itertools import product
from ..utility import preprocessing

np.random.seed(123)

class EdgeMinibatchIterator(object):
    """ This minibatch iterator iterates over batches of sampled edges or
    random pairs of co-occuring edges.
    assoc -- numpy array with target edges
    placeholders -- tensorflow placeholders object
    batch_size -- size of the minibatches
    """
    def __init__(self, adj_mats, feat, edge_types, batch_size=100, val_test_size=0.01):
        """ Creates a minibatch object given the whole dataset in the form of the
        adjacency and feature matrices. This constructor creates dictionaries with
        the data divided into minibatches of train, validation and test. Each dictionary
        contains the adjacency matrix entries' coordinates corresponding to datapoints.
        It also creates reference dictionaries to translate an edge type to an index.
        """
        self.adj_mats = adj_mats
        self.feat = feat
        self.edge_types = edge_types
        self.batch_size = batch_size
        self.val_test_size = val_test_size
        self.num_edge_types = sum(self.edge_types.values())

        self.iter = 0
        self.freebatch_edge_types= list(range(self.num_edge_types))
        self.batch_num = [0]*self.num_edge_types
        self.current_edge_type_idx = 0
        # Reference dictionaries
        self.edge_type2idx = {}
        self.idx2edge_type = {}
        r = 0
        for i, j in self.edge_types:
            for k in range(self.edge_types[i,j]):
                self.edge_type2idx[i, j, k] = r
                self.idx2edge_type[r] = i, j, k
                r += 1
        # Batch dictionaries initialization
        self.train_edges = {edge_type: [None]*n for edge_type, n in self.edge_types.items()}
        self.val_edges = {edge_type: [None]*n for edge_type, n in self.edge_types.items()}
        self.test_edges = {edge_type: [None]*n for edge_type, n in self.edge_types.items()}
        self.test_edges_false = {edge_type: [None]*n for edge_type, n in self.edge_types.items()}
        self.val_edges_false = {edge_type: [None]*n for edge_type, n in self.edge_types.items()}
        self.train_edges_false = {edge_type: [None]*n for edge_type, n in self.edge_types.items()}
        self.adj_train = {edge_type: [None]*n for edge_type, n in self.edge_types.items()}
        # Function to build test and val sets with val_test_size positive links
        for i, j in self.edge_types:
            for k in range(self.edge_types[i,j]):
                print("Minibatch edge type:", "(%d, %d, %d)" % (i, j, k))
                self.mask_test_edges((i, j), k)

                print("Train edges=", "%04d" % len(self.train_edges[i,j][k]))
                print("Val edges=", "%04d" % len(self.val_edges[i,j][k]))
                print("Test edges=", "%04d" % len(self.test_edges[i,j][k]))

    def preprocess_graph(self, adj):
        '''Normalize adj matrix to the form
        D^{-1/2}\bar{A}D^{-1/2} if is squared or
        D_r^{-1/2}AD_c^{-1/2} if is rectangular
        '''
        adj = sp.coo_matrix(adj)
        if adj.shape[0] == adj.shape[1]:
            adj_ = adj + sp.eye(adj.shape[0])
            rowsum = np.array(adj_.sum(1))
            degree_mat_inv_sqrt = sp.diags(np.power(rowsum, -0.5).flatten())
            adj_normalized = adj_.dot(degree_mat_inv_sqrt).transpose().dot(degree_mat_inv_sqrt).tocoo()
        else:
            rowsum = np.array(adj.sum(1))
            colsum = np.array(adj.sum(0))
            rowdegree_mat_inv = sp.diags(np.nan_to_num(np.power(rowsum, -0.5)).flatten())
            coldegree_mat_inv = sp.diags(np.nan_to_num(np.power(colsum, -0.5)).flatten())
            adj_normalized = rowdegree_mat_inv.dot(adj).dot(coldegree_mat_inv).tocoo()
        return preprocessing.sparse_to_tuple(adj_normalized)

    def _ismember(self, a, b):
        a = np.array(a)
        b = np.array(b)
        rows_close = np.all(a - b == 0, axis=1)
        return np.any(rows_close)

    def mask_test_edges(self, edge_type, type_idx):
        ''' Selects a fraction of the edges of a given adj matrix to be test and val edges
        given the fraction val_test_edges. Also selects an (equal) number of false edges
        from the zero entries of the matrix to be negative test and val edges.
        '''
        # Coordinates of non-zero elements in adj matrix (edge)
        edges_all, _, _ = preprocessing.sparse_to_tuple(self.adj_mats[edge_type][type_idx])
        # Number of test edges (% of all edges or 20)
        num_test = max(20, int(np.floor(edges_all.shape[0] * self.val_test_size)))
        # Number of val edges (% of all edges or 20)
        num_val = max(20, int(np.floor(edges_all.shape[0] * self.val_test_size)))
        # orders and indexes edges
        all_edge_idx = list(range(edges_all.shape[0]))
        np.random.shuffle(all_edge_idx)
        # Choose validation edges
        val_edge_idx = all_edge_idx[:num_val]
        val_edges = edges_all[val_edge_idx]
        # Choose test edges
        test_edge_idx = all_edge_idx[num_val:(num_val + num_test)]
        test_edges = edges_all[test_edge_idx]
        # Choose train edges as the remaining edges
        train_edges = np.delete(edges_all, np.hstack([test_edge_idx, val_edge_idx]), axis=0)
        # Choose false test edges randomly
        test_edges_false = []
        while len(test_edges_false) < len(test_edges):
            if len(test_edges_false) % 1000 == 0:
                print("Constructing test edges=", "%04d/%04d" %
                      (len(test_edges_false), len(test_edges)))
            idx_i = np.random.randint(0, self.adj_mats[edge_type][type_idx].shape[0])
            idx_j = np.random.randint(0, self.adj_mats[edge_type][type_idx].shape[1])
            if self._ismember([idx_i, idx_j], edges_all): # test that is not a true edge
                continue
            if test_edges_false: # test that is not already in false edges
                if self._ismember([idx_i, idx_j], test_edges_false):
                    continue
            test_edges_false.append([idx_i, idx_j])
        # Choose false validation edges randomly
        val_edges_false = []
        while len(val_edges_false) < len(val_edges):
            if len(val_edges_false) % 1000 == 0:
                print("Constructing val edges=", "%04d/%04d" %
                      (len(val_edges_false), len(val_edges)))
            idx_i = np.random.randint(0, self.adj_mats[edge_type][type_idx].shape[0])
            idx_j = np.random.randint(0, self.adj_mats[edge_type][type_idx].shape[1])
            if self._ismember([idx_i, idx_j], edges_all): # test that is not a true edge
                continue
            if val_edges_false: # test that is not already in false edges
                if self._ismember([idx_i, idx_j], val_edges_false) or \
                   self._ismember([idx_i, idx_j], test_edges_false):
                    continue
            val_edges_false.append([idx_i, idx_j])
        # Choose false train edges randomly
        train_edges_false = []
        for e in range(train_edges.shape[0]):
            if len(train_edges_false) % 1000 == 0:
                print("Constructing train edges=", "%04d/%04d" %
                      (len(train_edges_false), len(train_edges)))
            while len(train_edges_false) < e+1:
                idx_i = np.random.randint(0, self.adj_mats[edge_type][type_idx].shape[0])
                idx_j = train_edges[e,1]
                if self._ismember([idx_i, idx_j], edges_all): # test that is not a true edge
                    continue
                if train_edges_false: # test that is not already in false edges
                    if self._ismember([idx_i, idx_j], val_edges_false) or\
                       self._ismember([idx_i, idx_j], test_edges_false): # or\
                       #self._ismember([idx_i, idx_j], train_edges_false):
                        continue
                train_edges_false.append([idx_i, idx_j])
        # Re-build adj matrices with preprocessing
        data = np.ones(train_edges.shape[0])
        adj_train = sp.csr_matrix(
            (data, (train_edges[:, 0], train_edges[:, 1])),
            shape=self.adj_mats[edge_type][type_idx].shape)
        self.adj_train[edge_type][type_idx] = self.preprocess_graph(adj_train)
        self.train_edges_false[edge_type][type_idx] = train_edges_false
        self.train_edges[edge_type][type_idx] = train_edges
        self.val_edges[edge_type][type_idx] = val_edges
        self.val_edges_false[edge_type][type_idx] = np.array(val_edges_false)
        self.test_edges[edge_type][type_idx] = test_edges
        self.test_edges_false[edge_type][type_idx] = np.array(test_edges_false)

    def end(self):
        finished = len(self.freebatch_edge_types) == 0
        return finished

    def update_feed_dict(self, feed_dict, dropout, placeholders):
        """ Construct feed dictionary
        """
        feed_dict.update({
            placeholders['adj_mats_%d,%d,%d' % (i,j,k)]: self.adj_train[i,j][k]
            for i, j in self.edge_types for k in range(self.edge_types[i,j])})
        feed_dict.update({placeholders['feat_%d' % i]: self.feat[i] for i, _ in self.edge_types})
        feed_dict.update({placeholders['dropout']: dropout})

        return feed_dict
    ## MODIFICATION FOR NEGATIVE TRAINING ##
    def batch_feed_dict(self, batch_edges, neg_batch_edges, batch_edge_type, placeholders):
        """ Feed the tensorflow feed dictionary with the edges and indices taken as parameters
        """
        feed_dict = dict()
        feed_dict.update({placeholders['batch']: batch_edges})
        feed_dict.update({placeholders['neg_batch']: neg_batch_edges})
        feed_dict.update({placeholders['batch_edge_type_idx']: batch_edge_type})
        feed_dict.update({placeholders['batch_row_edge_type']: self.idx2edge_type[batch_edge_type][0]}) # 0 or 1, location of row in dictionary
        feed_dict.update({placeholders['batch_col_edge_type']: self.idx2edge_type[batch_edge_type][1]}) # 0 or 1, location of col in dictionary

        return feed_dict

    def next_minibatch_feed_dict(self, placeholders):
        """Select a random edge type and a batch of edges of the same type"""
        # 1. Select edge type assigning an index to it based on the value of self.iter
        while True:
            #print(self.iter)
            if self.iter % 4 == 0:
                # gene-gene relation
                self.current_edge_type_idx = self.edge_type2idx[0, 0, 0]
            elif self.iter % 4 == 1:
                # gene-drug relation
                self.current_edge_type_idx = self.edge_type2idx[0, 1, 0]
            elif self.iter % 4 == 2:
                # drug-gene relation
                self.current_edge_type_idx = self.edge_type2idx[1, 0, 0]
            else:
                # random side effect relation
                if len(self.freebatch_edge_types) > 0:
                    self.current_edge_type_idx = np.random.choice(self.freebatch_edge_types)
                else:
                    # If the training instances are over for that side effect, choose PPI
                    self.current_edge_type_idx = self.edge_type2idx[0, 0, 0]
                    self.iter = 0
            # Check if there are enough train instances left to fill a batch
            i, j, k = self.idx2edge_type[self.current_edge_type_idx]
            if self.batch_num[self.current_edge_type_idx] * self.batch_size \
                   <= len(self.train_edges[i,j][k]) - self.batch_size + 1:
                break
            else:
                # This seems to restart the batch for non-DDI edges if the batch has finished
                # Consecuence: these edges train until the DDI edges are finished
                if self.iter % 4 in [0, 1, 2]:
                    self.batch_num[self.current_edge_type_idx] = 0
                else:
                    self.freebatch_edge_types.remove(self.current_edge_type_idx)
        # 2. Update batch in placeholder with only the batch edges
        self.iter += 1
        start = self.batch_num[self.current_edge_type_idx] * self.batch_size
        self.batch_num[self.current_edge_type_idx] += 1
        batch_edges = self.train_edges[i,j][k][start: start + self.batch_size]
        ## MODIFICATION FOR NEGATIVE TRAINING ##
        neg_batch_edges = self.train_edges_false[i,j][k][start: start + self.batch_size]
        return self.batch_feed_dict(batch_edges, neg_batch_edges, self.current_edge_type_idx, placeholders)

    def num_training_batches(self, edge_type, type_idx):
        """ Returns the total number of different batches that can be possible formed
        with the number of edges in training given the edge type and the index.
        """
        return len(self.train_edges[edge_type][type_idx]) // self.batch_size + 1
    ## MODIFICATION FOR NEGATIVE VALIDATION ##
    def val_feed_dict(self, edge_type, type_idx, placeholders, size=None):
        """ Feed the tensorflow feed dictionary with validation edges instead of training
        edges given the edge type and the index. A size of the dataset (number of edges)
        can be passed as an optional parameter.
        """
        edge_list = self.val_edges[edge_type][type_idx]
        neg_edge_list = self.val_edges_false[edge_type][type_idx]
        if size is None:
            return self.batch_feed_dict(edge_list, neg_edge_list, edge_type, placeholders)
        else:
            ind = np.random.permutation(len(edge_list))
            val_edges = [edge_list[i] for i in ind[:min(size, len(ind))]]
            neg_val_edges = [neg_edge_list[i] for i in ind[:min(size, len(ind))]]
            return self.batch_feed_dict(val_edges, neg_val_edges, edge_type, placeholders)
        ## MODIFICATION FOR NEGATIVE TRAINING ##
    def shuffle(self):
        """ Re-shuffle the training set for all edge types.
            Also reset the batch number and the free batch availiable.
        """
        for edge_type in self.edge_types:
            for k in range(self.edge_types[edge_type]):
                self.train_edges[edge_type][k] = np.random.permutation(self.train_edges[edge_type][k])
                self.train_edges_false[edge_type][k] = np.random.permutation(self.train_edges_false[edge_type][k])
                self.batch_num[self.edge_type2idx[edge_type[0], edge_type[1], k]] = 0
        self.current_edge_type_idx = 0
        self.freebatch_edge_types = list(range(self.num_edge_types))
        self.freebatch_edge_types.remove(self.edge_type2idx[0, 0, 0])
        self.freebatch_edge_types.remove(self.edge_type2idx[0, 1, 0])
        self.freebatch_edge_types.remove(self.edge_type2idx[1, 0, 0])
        self.iter = 0

reason: import numpy,import scipy


text:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from numpy import array
from numpy import float64
from numpy import zeros

from compas.numerical import dr_numpy
from compas_fofin.loads import SelfweightCalculator

__all__ = ['apply_loads_numpy']

def apply_loads_numpy(mesh, safety_loads=1.0, safety_selfweight=1.0, kmax=10000, tol=0.01):
    """Apply loads to a materialised mesh.

    Parameters
    ----------
    mesh : compas_fofin.datastructures.Shell
        The data structure.
    safety_loads : float (1.0)
        Safety factor to be applied to the external loads.
        Default is ``1.0``.
    safety_selfweight : float (1.0)
        Safety factor to be applied to the selfweight.
        Default is ``1.0``.
    kmax : int (10000)
        Maximum number of iterations for the relaxation.
        Default is ``10000``.
    tol : float (0.01)
        Tolerance for residual forces.
        Default is ``0.01``.

    Returns
    -------
    None
        The function updates the input mesh and therefore does not return anything.

    """
    key_index = mesh.key_index()
    uv_index = {(u, v): index for index, (u, v) in enumerate(mesh.edges_where({'is_edge': True}))}

    fixed = [key_index[key] for key in mesh.vertices_where({'is_anchor': True})]
    xyz = array(mesh.vertices_attributes('xyz'), dtype=float64)
    edges = [(key_index[u], key_index[v]) for u, v in mesh.edges_where({'is_edge': True})]
    # v = len(xyz)
    e = len(edges)
    p = array(mesh.vertices_attributes(('px', 'py', 'pz')), dtype=float64)
    qpre = zeros((e, 1), dtype=float64)
    fpre = zeros((e, 1), dtype=float64)
    lpre = zeros((e, 1), dtype=float64)
    l0 = array([attr['l0'] for key, attr in mesh.edges_where({'is_edge': True}, True)], dtype=float64).reshape((-1, 1))
    E = array([attr['E'] * 1e+6 for key, attr in mesh.edges_where({'is_edge': True}, True)], dtype=float64).reshape((-1, 1))
    radius = array([attr['r'] for key, attr in mesh.edges_where({'is_edge': True}, True)], dtype=float64).reshape((-1, 1))

    p *= safety_loads

    density = mesh.attributes['density']
    if density:
        calculate_sw = SelfweightCalculator(mesh, density=density)
        sw = calculate_sw(xyz)
        p[:, 2] = - safety_selfweight * sw[:, 0]

    xyz, q, f, l, r = dr_numpy(xyz, edges, fixed, p, qpre, fpre, lpre, l0, E, radius, kmax=kmax, tol1=tol)

    for key, attr in mesh.vertices(True):
        index = key_index[key]
        attr['x'] = xyz[index, 0]
        attr['y'] = xyz[index, 1]
        attr['z'] = xyz[index, 2]
        attr['rx'] = r[index, 0]
        attr['ry'] = r[index, 1]
        attr['rz'] = r[index, 2]

    for key, attr in mesh.edges_where({'is_edge': True}, True):
        index = uv_index[key]
        attr['f'] = f[index, 0]
        attr['l'] = l[index, 0]

# ==============================================================================
# Main
# ==============================================================================

if __name__ == '__main__':
    pass

reason: from numpy


text:
#-------------------------------------
# Project: Learning to Compare: Relation Network for Few-Shot Learning
# Date: 2017.9.21
# Author: Flood Sung
# All Rights Reserved
#-------------------------------------

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from torch.optim.lr_scheduler import StepLR
import numpy as np
import os
import math
import argparse

from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
from torchvision.transforms import transforms

import eval_model
from datasets import VectorTargetDataset

parser = argparse.ArgumentParser(description="One Shot Visual Recognition")
parser.add_argument("-f","--feature_dim",type = int, default = 64)
parser.add_argument("-r","--relation_dim",type = int, default = 8)
parser.add_argument("-w","--class_num",type = int, default = 5)
parser.add_argument("-s","--sample_num_per_class",type = int, default = 1)
parser.add_argument("-b","--batch_num_per_class",type = int, default = 15)
parser.add_argument("-e","--episode",type = int, default= 500000)
parser.add_argument("-t","--test_episode", type = int, default = 600)
parser.add_argument("-l","--learning_rate", type = float, default = 0.001)
parser.add_argument("-g","--gpu",type=int, default=0)
parser.add_argument("-u","--hidden_unit",type=int,default=10)
args = parser.parse_args()

# Hyper Parameters
FEATURE_DIM = args.feature_dim
RELATION_DIM = args.relation_dim
CLASS_NUM = args.class_num
SAMPLE_NUM_PER_CLASS = 1
BATCH_NUM_PER_CLASS = args.batch_num_per_class
EPISODE = args.episode
TEST_EPISODE = args.test_episode
LEARNING_RATE = args.learning_rate
GPU = args.gpu
HIDDEN_UNIT = args.hidden_unit

PATH_DATASETS = os.environ.get("PATH_DATASETS", ".")
AVAIL_GPUS = min(1, torch.cuda.device_count())
BATCH_SIZE = 256 if AVAIL_GPUS else 64

def mean_confidence_interval(data, confidence=0.95):
    import scipy as sp
    import scipy.stats
    a = 1.0*np.array(data)
    n = len(a)
    m, se = np.mean(a), scipy.stats.sem(a)
    h = se * sp.stats.t._ppf((1+confidence)/2., n-1)
    return m,h

class CNNEncoder(nn.Module):
    """docstring for ClassName"""
    def __init__(self):
        super(CNNEncoder, self).__init__()
        self.flat = nn.Flatten()
        self.fc1 = nn.Sequential(
            nn.Linear(28 * 28, 128),
            nn.ReLU(),
        )
        self.fc2 = nn.Sequential(
            nn.Linear(128, 3),
            nn.ReLU(),
        )

    def forward(self,x):
        out = self.flat(x)
        out = self.fc1(out)
        out = self.fc2(out)
        return out

class RelationNetwork(nn.Module):
    """docstring for RelationNetwork"""
    def __init__(self,input_size):
        super(RelationNetwork, self).__init__()
        self.fc1 = nn.Linear(input_size * 2,1)

    def forward(self,x):
        out = self.fc1(x)
        out = F.sigmoid(out)

        return out

def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
        m.weight.data.normal_(0, math.sqrt(2. / n))
        if m.bias is not None:
            m.bias.data.zero_()
    elif classname.find('BatchNorm') != -1:
        m.weight.data.fill_(1)
        m.bias.data.zero_()
    elif classname.find('Linear') != -1:
        n = m.weight.size(1)
        m.weight.data.normal_(0, 0.01)
        m.bias.data = torch.ones(m.bias.data.size())

def main():
    # Step 1: init data folders
    print("init data folders")

    # Step 2: init neural networks
    print("init neural networks")

    feature_encoder = CNNEncoder()
    relation_network = RelationNetwork(3)

    #feature_encoder.apply(weights_init)
    #relation_network.apply(weights_init)

    feature_encoder.cuda(GPU)
    relation_network.cuda(GPU)

    feature_encoder_optim = torch.optim.Adam(feature_encoder.parameters(),lr=LEARNING_RATE)
    feature_encoder_scheduler = StepLR(feature_encoder_optim,step_size=100000,gamma=0.5)
    relation_network_optim = torch.optim.Adam(relation_network.parameters(),lr=LEARNING_RATE)
    relation_network_scheduler = StepLR(relation_network_optim,step_size=100000,gamma=0.5)

    # Step 3: build graph
    print("Training...")

    last_accuracy = 0.0

    for episode in range(EPISODE):

        feature_encoder_scheduler.step(episode)
        relation_network_scheduler.step(episode)

        # init dataset
        # sample_dataloader is to obtain previous samples for compare
        # batch_dataloader is to batch samples for training

        # Init DataLoader from MNIST Dataset
        train_ds = VectorTargetDataset(
            MNIST(os.getcwd(), train=True, download=True, transform=transforms.ToTensor()),
            dataset_seed=0,
            vector_width=2,
            gaussian_instead_of_uniform=True,
            scale=0.5,
        )  # MNIST(PATH_DATASETS, train=True, download=True, transform=transforms.ToTensor())
        half = len(train_ds) // 2
        train_1, train_2 = torch.utils.data.random_split(train_ds, [half, half])
        train_loader = DataLoader(train_1, batch_size=BATCH_SIZE, shuffle=True)
        train_loader2 = DataLoader(train_2, batch_size=BATCH_SIZE, shuffle=True)

        # sample datas
        samples, sample_labels = train_loader.__iter__().next()
        batches, batch_labels = train_loader2.__iter__().next()

        # calculate features
        sample_features = feature_encoder(samples.cuda(GPU)) # half x 32 ?
        batch_features = feature_encoder(batches.cuda(GPU)) # half x 32 ?

        # calculate relations
        # each batch sample link to every samples to calculate relations
        # to form a 100x128 matrix for relation network
        # (charlie) these 3 lines are just ZSL/FSL stuff, right?
        #sample_features_ext = sample_features.unsqueeze(0).repeat(BATCH_NUM_PER_CLASS*CLASS_NUM,1,1,1,1)
        #batch_features_ext = batch_features.unsqueeze(0).repeat(SAMPLE_NUM_PER_CLASS*CLASS_NUM,1,1,1,1)
        #batch_features_ext = torch.transpose(batch_features_ext,0,1)

        relation_pairs = torch.cat((sample_features,batch_features),-1)
        relations = relation_network(relation_pairs)

        # (charlie) todo get the vector labels here
        # for MNIST, cosine similarity is wonky, because all my targets are about in the same direction (noised_class, noised_class) ~ (1,1)
        # so here we will use a standard L2 norm
        def batch_distance(a, b):
            diff = a - b
            pow = diff ** 2
            dist = torch.sum(pow, dim=1)
            return dist.cuda(GPU)
        target_relations = batch_distance(sample_labels, batch_labels) #torch.dist(sample_labels, batch_labels, dim=1) # F.cosine_similarity(sample_labels, batch_labels)

        mse = nn.MSELoss().cuda(GPU)
        #one_hot_labels = Variable(torch.zeros(BATCH_NUM_PER_CLASS*CLASS_NUM, CLASS_NUM).scatter_(1, batch_labels.view(-1,1), 1)).cuda(GPU)
        loss = mse(relations, target_relations)

        # training

        feature_encoder.zero_grad()
        relation_network.zero_grad()

        loss.backward()

        torch.nn.utils.clip_grad_norm(feature_encoder.parameters(),0.5)
        torch.nn.utils.clip_grad_norm(relation_network.parameters(),0.5)

        feature_encoder_optim.step()
        relation_network_optim.step()

        if (episode+1)%100 == 0:
                print("episode:",episode+1,"loss",loss.item())

        if episode%5000 == 0:

            # test
            eval_ds = VectorTargetDataset(
                MNIST(os.getcwd(), train=False, download=True, transform=transforms.ToTensor()),
                dataset_seed=0,
                vector_width=2,
                gaussian_instead_of_uniform=True,
                scale=0.5
            )  # MNIST(PATH_DATASETS, train=True, download=True, transform=transforms.ToTensor())
            eval_model.main(feature_encoder, eval_ds, GPU)

if __name__ == '__main__':
    main()

max_stars_repo_name: Velythyl/pairwise-distance-loss-POC

max_issues_repo_name: Velythyl/pairwise-distance-loss-POC

max_forks_repo_name: Velythyl/pairwise-distance-loss-POC


text:
# Finds #invisible images for each news website along with its leaning.
import pandas as pd
import numpy as np
import statistics as stats

left = ["ndtv24x7","indianexpress","hindustantimes","punjabkesari","thehindu","anandabazar","scoopwhoop","ndtv","sandesh","dinamalar","mathrubhumi",
		"lokmat","greaterkashmir","scroll","siasat","andhrajyothy","kashmirlife","outlookindia","eenadu","huffingtonpost","thenewsminute","thewire",
		"youthkiawaaz","thehindubusinessline","risingkashmir","milligazette","mumbaimirror","thestatesman","telegraphindia","deshabhimani","newslaundry",
		"bangaloremirror","altnews","kashmirreader","countercurrents","ahmedabadmirror","punemirror","timesheadline","greatandhra"]

# RIGHT_TO_RIGHTCENTRE (38)
right = ["aajtak","intoday","jagran","bhaskar","zeenews","indiatvnews","abplive","amarujala","indiatimes","navbharattimes","patrika","news18","timesnownews","newsonair", "nic",
		 "newindianexpress","india","firstpost","republicworld","newslivetv","deccanchronicle","fakingnews","dnaindia","gujaratsamachar","dailyhunt",
		 "newdelhitimes","webdunia","moneycontrol","newsnation","newsnationtv","swarajyamag","aninews","dailyo","forbesindia","dailyexcelsior","oneindia","opindia",
		 "starofmysore","dailypioneer","ians"]

# CENTRE_AND_LEASTBIASED (28)
centre = ["timesofindia","indiatoday","news24","news24online","bbc","thequint","jansatta","economictimes","mid-day","dailythanthi","manoramaonline",
		  "livehindustan","financialexpress","cnbctv18","businesstoday","livemint","catchnews","businessinsider","deccanherald","theprint","wionews",
		  "ptinews","business-standard","tribuneindia","headlinesoftoday","nagpurtoday","asianage","freepressjournal"]

# N/A (20)
unknown = ["rvcj","thelogicalindian","brutindia","brut","thebetterindia","pinkvilla","topyaps","telanganatoday","wisden","statetimes","sentinelassam","assamtribune",
		   "socialsamosa","newstracklive","leagueofindia","prabhatkhabar","thesangaiexpress","news4masses","sinceindependence","5abnow","factchecker"]

def find_website_leaning(url):
    url = url.split('/')[2]
    url_list = url.split('.')
    if len(url_list) == 2:
        url = url_list[0]
    elif len(url_list) >= 3:
        url = url_list[1]

    if url in left:
        return 'left'
    elif url in right:
        return 'right'
    elif url in centre:
        return 'centre'
    elif url in unknown:
        return 'unknown'
    else:
        print('%s is not present in any leaning.' % url)
        return None

df = pd.read_csv('./inv_pixel_imgs_1x1.csv')

site_imgurl_dict = {}
size = len(df)

for i in range(size):
    row = df.iloc[i]
    if row['news_site'] not in site_imgurl_dict:
        site_imgurl_dict[row['news_site']] = 1
    else:
        site_imgurl_dict[row['news_site']] += 1

res = []
for k in site_imgurl_dict:
    leaning = find_website_leaning(k)
    if leaning:
        res.append([k, site_imgurl_dict[k], leaning])

df_res = pd.DataFrame(res, columns=['news_site', '#inv_imgs', 'leaning'])
df_res.sort_values(by=['#inv_imgs'], inplace=True, ascending=False)
df_res.to_csv('inv_px_site_dom.csv', index=False)

# df = pd.read_csv('inv_px_site_dom.csv')
#
# num_left = 0
# num_right = 0
# num_centre = 0
# num_unk = 0
# left_imgs = []
# right_imgs = []
# centre_imgs = []
# unk_imgs = []
#
# for i in range(len(df)):
#     row = df.iloc[i]
#     if row['leaning'] == 'left':
#         num_left += 1
#         left_imgs.append(row['#inv_imgs'])
#     elif row['leaning'] == 'right':
#         num_right += 1
#         right_imgs.append(row['#inv_imgs'])
#     elif row['leaning'] == 'centre':
#         num_centre += 1
#         centre_imgs.append(row['#inv_imgs'])
#     elif row['leaning'] == 'unknown':
#         num_unk += 1
#         unk_imgs.append(row['#inv_imgs'])
#     else:
#         print(row)
#
# print('No. of left sites:', num_left)
# print('Median imgs in left sites:', stats.median(left_imgs))
#
# print('No. of right sites:', num_right)
# print('Median imgs in right sites:', stats.median(right_imgs))
#
# print('No. of centre sites:', num_centre)
# print('Median imgs in centre sites:', stats.median(centre_imgs))
#
# print('No. of unknown sites:', num_unk)
# print('Median imgs in unknown sites:', stats.median(unk_imgs))

#RESULTS ####################################################
# No. of left sites: 35
# Median imgs in left sites: 12
# No. of right sites: 40
# Median imgs in right sites: 10.0
# No. of centre sites: 25
# Median imgs in centre sites: 15
# No. of unknown sites: 18
# Median imgs in unknown sites: 4.5

max_stars_repo_path: Invisible Pixels/inv_px_site_domains.py

max_issues_repo_path: Invisible Pixels/inv_px_site_domains.py

max_forks_repo_path: Invisible Pixels/inv_px_site_domains.py


text:
""" An implementation of the paper "A Neural Algorithm of Artistic Style"
by Gatys et al. in TensorFlow, based upon the assignment for the CS 20SI:
"TensorFlow for Deep Learning Research" created by Chip Huyen
(huyenn@stanford.edu).

For more details related to the convolution network implementation,
please read the assignment handout:
http://web.stanford.edu/class/cs20si/assignments/a2.pdf
"""
import time

import numpy as np
import tensorflow as tf

import vgg_model
import utils
import data_input

#Avoids innecesary warnings
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

#Parameters to manage experiments
STYLE = None
CONTENT = None
STYLE_IMAGE = None
CONTENT_IMAGE = None
IMAGE_HEIGHT = None
IMAGE_WIDTH = None
#Percentage of weight of the noise for intermixing with the content image
NOISE_RATIO = None

# Layers used for style features. You can change this.
STYLE_LAYERS = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1']
W = [0.5, 1.0, 1.5, 3.0, 4.0] # give more weights to deeper layers.

# Layer used for content features. You can change this.
CONTENT_LAYER = 'conv4_2'

ITERS = 10
# Learning rate of the algorithm, the smaller more precise but uses more resources for achieving it
LR = 2.0

#Weights to determine how much of the content/style image is used
CONTENT_WEIGHT = None
STYLE_WEIGHT = None

MEAN_PIXELS = np.array([123.68, 116.779, 103.939]).reshape((1,1,1,3))
""" MEAN_PIXELS is defined according to description on their github:
https://gist.github.com/ksimonyan/211839e770f7b538e2d8
'In the paper, the model is denoted as the configuration D trained with scale jittering.
The input images should be zero-centered by mean pixel (rather than mean image) subtraction.
Namely, the following BGR values should be subtracted: [103.939, 116.779, 123.68].'
"""

# VGG-19 parameters file
VGG_DOWNLOAD_LINK = 'http://www.vlfeat.org/matconvnet/models/imagenet-vgg-verydeep-19.mat'
VGG_MODEL = 'imagenet-vgg-verydeep-19.mat'
EXPECTED_BYTES = 534904783

def _setting_parameters():

    global STYLE, CONTENT, IMAGE_HEIGHT, IMAGE_WIDTH, NOISE_RATIO, ITERS, \
           CONTENT_WEIGHT, STYLE_WEIGHT, STYLE_IMAGE, CONTENT_IMAGE
    try:
        STYLE = data_input._choose_files("style")
        CONTENT = data_input._choose_files("content")
        IMAGE_HEIGHT, IMAGE_WIDTH = data_input._set_image_size()
        NOISE_RATIO = data_input._set_noise_ratio()
        ITERS = data_input._set_iterations()
        CONTENT_WEIGHT, STYLE_WEIGHT = data_input._set_weights()
        STYLE_IMAGE = 'styles/' + STYLE + '.jpg'
        CONTENT_IMAGE = 'content/' + CONTENT + '.jpg'

    except Exception as e:
            if e.args[0] == "CANCEL":
                print("Operation canceled")
            else:
                print(e)

def _create_content_loss(p, f):
    """ Calculate the loss between the feature representation of the
    content image and the generated image.

    Inputs:
        p, f are just P, F in the paper
        (read the assignment handout if you're confused)
        Note: we won't use the coefficient 0.5 as defined in the paper
        but the coefficient as defined in the assignment handout.
    Output:
        the content loss

    """
    return tf.reduce_sum((f - p) ** 2) / (4.0 * p.size)

def _gram_matrix(F, N, M):
    """ Create and return the gram matrix for tensor F
        Gram matrix explanation: https://en.wikipedia.org/wiki/Gramian_matrix
    """
    F = tf.reshape(F, (M, N))
    return tf.matmul(tf.transpose(F), F)

def _single_style_loss(a, g):
    """ Calculate the style loss at a certain layer
    Inputs:
        a is the feature representation of the real image
        g is the feature representation of the generated image
    Output:
        the style loss at a certain layer (which is E_l in the paper)
    """
    N = a.shape[3]  # number of filters
    M = a.shape[1] * a.shape[2]  # height times width of the feature map
    A = _gram_matrix(a, N, M)
    G = _gram_matrix(g, N, M)
    return tf.reduce_sum((G - A) ** 2 / ((2 * N * M) ** 2))

def _create_style_loss(A, model):
    """ Return the total style loss
    """
    n_layers = len(STYLE_LAYERS)
    E = [_single_style_loss(A[i], model[STYLE_LAYERS[i]]) for i in range(n_layers)]

    return sum([W[i] * E[i] for i in range(n_layers)])

def _create_losses(model, input_image, content_image, style_image):
    with tf.variable_scope('loss') as scope:
        with tf.Session() as sess:
            sess.run(input_image.assign(content_image)) # assign content image to the input variable
            p = sess.run(model[CONTENT_LAYER])
        content_loss = _create_content_loss(p, model[CONTENT_LAYER])

        with tf.Session() as sess:
            sess.run(input_image.assign(style_image))
            A = sess.run([model[layer_name] for layer_name in STYLE_LAYERS])
        style_loss = _create_style_loss(A, model)

        # Create total loss.
        total_loss = CONTENT_WEIGHT * content_loss + STYLE_WEIGHT * style_loss

    return content_loss, style_loss, total_loss

def _create_summary(model):
    """ Create summary ops necessary
    """
    with tf.name_scope('summaries'):
        tf.summary.scalar('content loss', model['content_loss'])
        tf.summary.scalar('style loss', model['style_loss'])
        tf.summary.scalar('total loss', model['total_loss'])
        tf.summary.histogram('histogram content loss', model['content_loss'])
        tf.summary.histogram('histogram style loss', model['style_loss'])
        tf.summary.histogram('histogram total loss', model['total_loss'])
        return tf.summary.merge_all()

def train(model, generated_image, initial_image):
    """ Train your model."""
    with tf.Session() as sess:
        saver = tf.train.Saver()
        #Initialize variables
        sess.run(tf.global_variables_initializer())
        sess.run(generated_image.assign(initial_image))
        ckpt = tf.train.get_checkpoint_state(os.path.dirname('checkpointsTransfer/checkpoint/'))
        if ckpt and ckpt.model_checkpoint_path:
            saver.restore(sess, ckpt.model_checkpoint_path)
        initial_step = model['global_step'].eval()

        start_time = time.time()

        skip_step = 1
        for index in range(initial_step, ITERS):
            if index >= 5 and index < 20:
                skip_step = 10
            elif index >= 20:
                skip_step = 20

            sess.run(model['optimizer'])
            if (index + 1) % skip_step == 0:
                #Generated image and loss
                gen_image, total_loss, summary = sess.run([generated_image, model['total_loss'],
                                                           model['summary_op']])
                elapsed_time = time.time() - start_time
                gen_image = gen_image + MEAN_PIXELS
                print('Step {}\n   Sum: {:5.1f}'.format(index + 1, np.sum(gen_image)))
                print('   Loss: {:5.1f}'.format(total_loss))
                print('   Time: {}'.format(elapsed_time))

                utils.eta(index, skip_step, elapsed_time, ITERS)

                start_time = time.time()
                filename = 'outputs/%d.png' % (index)
                utils.save_image(filename, gen_image)

                if (index + 1) % 20 == 0:
                    saver.save(sess, 'checkpointsTransfer/style_transfer/', index)

def main():
    _setting_parameters()
    with tf.device('/cpu:0'):   #Change to '/gpu:0' if having a GPU
        with tf.variable_scope('input') as scope:
            # use variable instead of placeholder because we're training the initial image to make it
            # look like both the content image and the style image
            input_image = tf.Variable(np.zeros([1, IMAGE_HEIGHT, IMAGE_WIDTH, 3]), dtype=tf.float32)

        #Downloads the pretrained model
        utils.download(VGG_DOWNLOAD_LINK, VGG_MODEL, EXPECTED_BYTES)
        model = vgg_model.load_vgg(VGG_MODEL, input_image)
        model['global_step'] = tf.Variable(0, dtype=tf.int32, trainable=False, name='global_step')

        content_image = utils.get_resized_image(CONTENT_IMAGE, IMAGE_HEIGHT, IMAGE_WIDTH)
        content_image = content_image - MEAN_PIXELS
        style_image = utils.get_resized_image(STYLE_IMAGE, IMAGE_HEIGHT, IMAGE_WIDTH)
        style_image = style_image - MEAN_PIXELS

        model['content_loss'], model['style_loss'], model['total_loss'] = _create_losses(model,
                                                        input_image, content_image, style_image)

        #Optimizer looking to reduce the total_loss of the model
        #TensorFlow optimizers: https://www.tensorflow.org/api_docs/python/tf/train
        model['optimizer'] = tf.train.AdamOptimizer(LR).minimize(model['total_loss'],
                                                                 global_step=model['global_step'])
        model['summary_op'] = _create_summary(model)

        initial_image = utils.generate_noise_image(content_image, IMAGE_HEIGHT, IMAGE_WIDTH, NOISE_RATIO)
        train(model, input_image, initial_image)
    #Showing the image one it is finished
    image_path = 'outputs/%d.png' % (ITERS-1)
    utils.show_image(image_path)

if __name__ == '__main__':
    main()