# encoding: utf-8

__author__ = '<NAME> <<EMAIL>>'
__date__ = '06/2012'

"""Module to convert frame representation as output by kinect recording
to angle and/or angle velocity histogram representations.
"""

import numpy as np
from scipy.cluster.vq import kmeans, whiten

from ..lib.transformations import (quaternion_multiply, quaternion_inverse,
                                   euler_from_quaternion)
from ..lib.utils import delayed_velocities, meta_map
from ..lib.vector_quantization import get_histos
from ..lib.kde2d import gaussian_kde_2d

# Note: frame names from ros kinect seems to denote left / right from
#   the observer point of view.

ANGLES = [
        ('left_shoulder', 'left_elbow'),
        ('left_elbow', 'left_hand'),
        ('torso', 'left_hip'),
        ('left_hip', 'left_knee'),
        ('left_knee', 'left_foot'),
        ('right_shoulder', 'right_elbow'),
        ('right_elbow', 'right_hand'),
        ('torso', 'right_hip'),
        ('right_hip', 'right_knee'),
        ('right_knee', 'right_foot'),
        ]

def angles_indices(marker_names):
    return [(marker_names.index(source), marker_names.index(dest))
            for source, dest in ANGLES]

def get_angles(sample, source_frame, dest_frame):
    """Compute rotation along three basis axis between two frames
    in the given sample.

    :param sample: array of translations and rotations (shape: (nb_frames, 7)
    :param source_frame, dest_frame: indices of source and dest frames
    """
    # All transformations are from the base frame, to get transformation from
    # one frame to the other, the first one needs to be inversed.
    # q = q1^{-1} * q2
    q = quaternion_multiply(quaternion_inverse(sample[source_frame, 3:]),
            sample[dest_frame, 3:])
    return euler_from_quaternion(q)

def get_angle_array(sample, angles_idx):
    angles = [get_angles(sample, s, d) for s, d in angles_idx]
    return np.hstack(angles)

def record_to_angle_array(record, angles_idx):
    return np.vstack([get_angle_array(sample, angles_idx)
        for sample in record])

def db_to_list_of_angle_arrays(db):
    angle_idx = angles_indices(db.marker_names)
    return [record_to_angle_array(r[0], angle_idx) for r in db.records]

def db_to_angles_and_vels(db, vel_delay=1, vel_padding='zeros'):
    angles = db_to_list_of_angle_arrays(db)
    vels = [delayed_velocities(vel_delay, angle, padding=vel_padding)
            for angle in angles]
    return angles, vels

def get_bounds(vels):
    min_vel = np.min(np.vstack(vels))
    max_vel = np.max(np.vstack(vels))
    return min_vel, max_vel

def filter_values(data, bounds):
    """Filter big values in data, according to given bounds.
    :param data: numpy array
    :param bounds: (min, max)
    """
    cut = lambda x: np.maximum(np.minimum(x, bounds[1]), bounds[0])
    return map(cut, data)

def db_to_binned_hist_matrix(db, vel_delay=1, vel_padding='zeros',
        nb_bins=16, bounds=None, vel_bounds=None, rel_h=.3, fft=True):
    """Compute the histogram matrix from the database, using binned histograms
    smoothed by a Gaussian kernel.

    :param db:
        the Database

    :param vel_delay, vel_padding:
        delayed velocity parameters

    :param nb_bins: int,
        number of bins (output dimension of histograms for a joint)

    :param bounds, vel_bounds: (min, max), couples of floats
        bounds on angle and velocities, if given, data
        is cut to fit in bounds, else they are computed from data.

    :param rel_h: float,
        relative width of the Gaussian smoother

    :param fft: bool,
        whether to use fft convolution (default)

    :return: (nb ex, nb features) matrix
    """
    angles, vels = db_to_angles_and_vels(db, vel_delay=1, vel_padding='zeros')
    # Angle bounds
    if bounds is None:
        bounds = get_bounds(angles)
    else:
        angles = filter_values(angles, bounds)
    # Velocity bounds
    if vel_bounds is None:
        vel_bounds = get_bounds(vels)
    else:
        vels = filter_values(vels, vel_bounds)
    # Histogram are specific to each angle and corresponding velocity
    # Compute Gaussian width from relative width for angles
    h = rel_h * (bounds[1] - bounds[0])
    # Compute gaussian width for velocities
    h_vel = rel_h * (vel_bounds[1] - vel_bounds[0])
    # For fair comparison with 1D hist and VQ
    nb_bins_sqrt = int(np.sqrt(nb_bins))
    to_gaussKDEs2 = lambda x: [  # x = (angles, vels)
            gaussian_kde_2d(
                np.hstack([x[0][:, dim][:, np.newaxis],
                    x[1][:, dim][:, np.newaxis]]),
                h, h_vel, nb_bins=nb_bins_sqrt,
                bounds=(np.array([bounds[0], vel_bounds[0]]),
                    np.array([bounds[1], vel_bounds[1]])),
                fft=fft)
            for dim in range(x[0].shape[1])]
    kdes = map(to_gaussKDEs2, zip(angles, vels))
    # Each kde is a triplet (x_grid, y_grid, bins)
    # Get and flatten histograms (second element of the couple)
    hist = meta_map(2, lambda  x: x[2].flatten())(kdes)
    data_matrix = np.vstack(map(np.hstack, hist))
    return data_matrix

def compact_examples(x):
    """Vertically stack list of array and returns stacked
    array and indices to un_compact it.
    """
    idx = [y.shape[0] for y in x]
    return np.vstack(x), list(np.cumsum(idx))

def un_compact_examples(v, idx):
    return [v[i:j, :]
            for i, j in zip([0] + idx[:-1], idx)]

def db_to_VQ_hist_matrix(db, vel_delay=1, vel_padding='zeros',
        nb_bins=16, bounds=None, vel_bounds=None, soft_vq=None):
    """Compute the histogram matrix from the database, using binned histograms
    smoothed by a Gaussian kernel.

    :param db:
        the Database

    :param vel_delay, vel_padding:
        delayed velocity parameters

    :param nb_bins: int,
        number of bins (output dimension of histograms for a joint)

    :param bounds, vel_bounds: (min, max), couples of floats
        bounds on angle and velocities, if given, data
        is cut to fit in bounds

    :param soft_vq:
        if not None (default) soft vector quantization parameter.
    """
    angles, vels = db_to_angles_and_vels(db, vel_delay=1, vel_padding='zeros')
    # Angle bounds
    if bounds is not None:
        angles = filter_values(angles, bounds)
    # Velocity bounds
    if vel_bounds is not None:
        vels = filter_values(vels, vel_bounds)
    # For each DOF and each example compute 2D angle-vel vects
    # angles / vels => [(time, dof) for each example]
    nb_dofs = angles[0].shape[1]
    nb_ex = len(angles)
    data = [[np.hstack([a[:, dof][:, np.newaxis],
                        v[:, dof][:, np.newaxis]])
             for a, v in zip(angles, vels)]
            for dof in range(nb_dofs)]
    compacted = map(compact_examples, data)
    # Whiten data for each dof
    all_data = [whiten(d) for d, _ in compacted]

    # Compute centroids for each DOF
    centro = [kmeans(d, nb_bins, iter=20)[0] for d in all_data]
    # Compute hitograms for each sample
    histos = [get_histos(d, c, soft=soft_vq)
              for d, c in zip(all_data, centro)]
    # Group and sum by example
    histos_by_ex = [un_compact_examples(h, c[1])
                    for h, c in zip(histos, compacted)]
    ex_histos = np.array([[h.sum(axis=0) for h in hs] for hs in histos_by_ex])
    # ex_histo is now (nb_dofs, nb_ex, nb_bins)
    Xdata = np.swapaxes(ex_histos, 0, 1).reshape((nb_ex, nb_bins * nb_dofs))
    Xdata /= Xdata.sum(axis=1)[:, np.newaxis]
    return Xdata


import os
import argparse
import numpy as np
import paddle.fluid as fluid
from scipy import sparse
import pdb

from utils import *
from layer import vmat, qe

parser = argparse.ArgumentParser(description='GNN_Reranking')
parser.add_argument('--data_path',
                    type=str,
                    default='../features/market_88_test.pkl',
                    help='path to dataset')
parser.add_argument('--k1',
                    type=int,
                    default=26,     # Market-1501
                    # default=60,   # Veri-776
                    help='parameter k1')
parser.add_argument('--k2',
                    type=int,
                    default=7,      # Market-1501
                    # default=10,   # Veri-776
                    help='parameter k2')

args = parser.parse_args()

def main():
    data = load_pickle(args.data_path)
    k1 = args.k1
    k2 = args.k2

    query_cam = data['query_cam']
    query_label = data['query_label']
    gallery_cam = data['gallery_cam']
    gallery_label = data['gallery_label']

    gallery_feature = data['gallery_f']
    query_feature = data['query_f']
    total_features = np.concatenate((query_feature,gallery_feature),axis=0)
    query_num = query_feature.shape[0]

    X_u = fluid.layers.data(name="all_fea",shape=[total_features.shape[0], total_features.shape[1]],dtype='float32')
    original_score = fluid.layers.matmul(X_u, X_u, transpose_x=False, transpose_y=True)

    _, initial_rank_k1 = fluid.layers.topk(original_score, k=k1)
    S, initial_rank_k2 = fluid.layers.topk(original_score, k=k2)

    initial_rank_k1_fp32 = fluid.layers.cast(initial_rank_k1, dtype='float32')
    initial_rank_k2_fp32 = fluid.layers.cast(initial_rank_k2, dtype='float32')

    # stage 1
    A = vmat(initial_rank_k1_fp32)
    S = S * S

    # stage 2
    if k2 != 1:
        for i in range(2):
            AT = fluid.layers.transpose(A, perm=[1,0])
            A = A + AT
            A = qe(A, initial_rank_k2_fp32, S)
            A_norm = fluid.layers.sqrt(fluid.layers.reduce_sum(fluid.layers.square(A), dim=1))
            A = fluid.layers.elementwise_div(A, A_norm, axis=0)

    score = fluid.layers.matmul(A, A, transpose_x=False, transpose_y=True)

    use_cuda = True
    place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
    exe = fluid.Executor(place)

    exe.run(fluid.default_startup_program())

    outs = exe.run(
        feed={'all_fea':total_features},
        fetch_list=[score])

    cosine_similarity = np.array(outs[0])
    indices = np.argsort(-cosine_similarity[:query_num, query_num:], axis=1)
    indices = indices.reshape(query_feature.shape[0], gallery_feature.shape[0])
    evaluate_ranking_list(indices, query_label, query_cam, gallery_label, gallery_cam)

if __name__ == '__main__':
    main()


<reponame>lanl/pyDRESCALk
#@author:  <NAME>,<NAME>
from scipy.stats import wilcoxon
from . import config
from .dist_clustering import *
from .pyDRESCAL import *
from .plot_results import *

class sample():
    """
    Generates perturbed version of data based on sampling distribution.

    Args:
        data (ndarray, sparse matrix): Array of which to find a perturbation.
        noise_var (float): The perturbation amount.
        method (str) : Method for sampling (uniform/poisson)
        seed (float),optional : Set seed for random data generation
    """

    @comm_timing()
    def __init__(self, data, noise_var, method, params,seed=None):
        self.np = params.np
        self.X = data
        self.noise_var = noise_var
        self.seed = seed
        if self.seed != None:
            self.np.random.seed(self.seed)
        self.method = method
        self.X_per = 0

    @comm_timing()
    def randM(self):
        """
        Multiplies each element of X by a uniform random number in (1-epsilon, 1+epsilon).
        """

        M = 2 * self.noise_var * self.np.random.random_sample(self.X.shape).astype(self.X.dtype) + self.noise_var
        M = M + 1
        self.X_per = self.np.multiply(self.X, M)

    @comm_timing()
    def poisson(self):
        """Resamples each element of a matrix from a Poisson distribution with the mean set by that element. Y_{i,j} = Poisson(X_{i,j}"""

        self.X_per = self.np.random.poisson(self.X).astype(self.X.dtype)

    @comm_timing()
    def fit(self):
        r"""
        Calls the sub routines to perform resampling on data

        Returns
        -------
        X_per : ndarry
           Perturbed version of data
        """

        if self.method == 'uniform':
            self.randM()
        elif self.method == 'poisson':
            self.poisson()
        return self.X_per

class pyDRESCALk():
    r"""
    Performs the distributed RESCAL decomposition with custom clustering for estimating hidden factors k

    Parameters:
        A_ij (ndarray) : Distributed Data
        factors (tuple), optional : Distributed factors W and H
        params (class): Class which comprises following attributes
        params.init (str) : RESCAL initialization(rand/nnsvd)
        params.comm1 (object): Global Communicator
        params.comm (object): Modified communicator object
        params.k (int) : Rank for decomposition
        params.m (int) : Global dimensions m
        params.n (int) : Global dimensions n
        params.p_r  (int): Cartesian grid row count
        params.p_c  (int): Cartesian grid column count
        params.row_comm (object) : Sub communicator along row
        params.col_comm (object) : Sub communicator along columns
        params.A_update (bool) : flag to set W update True/False
        params.norm (str): RESCAL norm to be minimized
        params.method(str): RESCAL optimization method
        params.eps (float) : Epsilon value
        params.verbose (bool) : Flag to enable/disable display results
        params.save_factors (bool) : Flag to enable/disable saving computed factors
        params.perturbations (int) : Number of Perturbations for clustering
        params.noise_var (float) : Set noise variance for perturbing the data
        params.sill_thr (float) : Set the sillhouette threshold for estimating K with p-test
        params.start_k (int) : Starting range for Feature search K
        params.end_k (int) : Ending range for Feature search K"""

    @comm_timing()
    def __init__(self, X_ijk, factors=None, params=None):
        self.X_ijk = X_ijk
        self.local_m, self.local_n, self.local_n = len(self.X_ijk),self.X_ijk[0].shape[0],self.X_ijk[0].shape[1]
        self.params = params
        self.np = self.params.np
        self.comm1 = self.params.comm1
        self.rank = self.comm1.rank
        self.p_r, self.p_c = self.params.p_r, self.params.p_c
        self.fpath = self.params.fpath
        self.fname = self.params.fname
        #self.fname = "Testrescalk"
        self.p = self.p_r * self.p_c
        if self.p_r != 1 and self.p_c != 1:
            self.topo = '2d'
        else:
            self.topo = '1d'
        self.sampling = var_init(self.params,'sampling',default='uniform')
        self.perturbations = var_init(self.params,'perturbations',default=10)
        self.noise_var = var_init(self.params,'noise_var',default=.03)
        self.Rall = 0
        self.Aall = 0
        self.recon_err = 0
        self.AvgR = 0
        self.AvgG = 0
        self.col_err = 0
        self.clusterSilhouetteCoefficients, self.avgSilhouetteCoefficients = 0, 0
        self.L_errDist = 0
        self.avgErr = 0
        self.start_k = self.params.start_k  # ['start_k']
        self.end_k = self.params.end_k  # ['end_k']
        self.step_k = var_init(self.params,'step_k',default=1)
        self.verbose = var_init(params,'verbose',default=True)

    @comm_timing()
    def fit(self):
        r"""
        Calls the sub routines to perform distributed RESCAL decomposition and then custom clustering to estimate k

        Returns
        -------
        nopt : int
           Estimated value of latent features
        """
        SILL_MIN = []
        SILL_AVG = []
        errRegres = []
        errRegresTol = []
        RECON = []
        RECON1 = []
        self.params.results_paths = self.params.results_path +self.params.fname + '/'
        if self.rank == 0:
            try: os.makedirs(self.params.results_paths)
            except: pass
        for self.k in range(self.start_k, self.end_k + 1,self.step_k):
            self.params.k = self.k
            self.pyrescalk_per_k()
            SILL_MIN.append(self.np.around(self.np.min(self.clusterSilhouetteCoefficients), 2))
            SILL_AVG.append(self.np.around(self.np.mean(self.clusterSilhouetteCoefficients), 2))
            errRegres.append([self.col_err])
            errRegresTol.append([self.recon_err])
            RECON.append(self.L_errDist)
            RECON1.append(self.avgErr)
        if self.rank==0:
            plot_results_paper(self.start_k, self.end_k,self.step_k, RECON, SILL_AVG, SILL_MIN, self.params.results_path, self.fname)

    @comm_timing()
    def pyrescalk_per_k(self):
        """Performs RESCAL decomposition and clustering for each k to estimate silhouette statistics"""
        self.params.results_paths = self.params.results_path+ str(self.k) + '/'
        if self.rank == 0:
            try: os.makedirs(self.params.results_paths)
            except: pass
        results = []
        if self.rank == 0: print('*************Computing for k=', self.k, '************')
        for i in range(self.perturbations):
            if self.rank == 0: print('Current perturbation =', i)
            self.params.perturbation = i
            data = sample(data=self.X_ijk, noise_var=self.noise_var, method=self.sampling,params=self.params, seed=self.rank*1000+i*100).fit()
            self.params.A_update = True
            results.append(pyDRESCAL(data, factors=None, params=self.params).fit())
        self.Aall = self.np.stack([results[i][0] for i in range(self.perturbations)],axis=-1)
        #self.Aall = self.Aall.reshape(self.Aall.shape[0], self.k, self.perturbations, order='F')      #n x k x perturbations
        self.Rall = self.np.stack([results[i][2] for i in range(self.perturbations)],axis=-1)
        #self.Rall = self.Rall.reshape(results[0][2].shape[0], self.k, self.Rall.shape[1], self.perturbations)    #m x k x k x perturbations
        self.recon_err = [results[i][3] for i in range(self.perturbations)]
        [processAvg, processSTD, self.Rall, self.clusterSilhouetteCoefficients, self.avgSilhouetteCoefficients,
                idx] = custom_clustering(self.Aall, self.Rall, self.params).fit()
        self.AvgR = self.np.median(self.Rall, axis=-1)
        self.AvgA = processAvg
        self.params.A_update = False
        regressH = pyDRESCAL(self.X_ijk, factors=[self.AvgA, self.AvgR], params=self.params)
        self.AvgA, self.AvgA_j, self.AvgR, self.L_errDist = regressH.fit()
        self.avgErr = np.mean(self.recon_err)
        cluster_stats = {'clusterSilhouetteCoefficients': self.clusterSilhouetteCoefficients,
                         'avgSilhouetteCoefficients': self.avgSilhouetteCoefficients, \
                          'avgErr': self.avgErr, 'recon_err': self.recon_err,'L_errDist':self.L_errDist}
        data_writer = data_write(self.params)
        data_writer.save_factors([self.AvgA, self.AvgR], reg=True)
        data_writer.save_cluster_results(cluster_stats)


<filename>bsuite/bsuite/models/agent_bootdqn.py<gh_stars>1-10
import dm_env
import numpy as np
import torch
import torch.nn.functional as functional
import torch.optim as optim
import typing
import wandb

from utils.memory import Experience, ReplayMemory, PrioritizedReplayMemory
from models.qnet_MCdrop import Dqn, DuelDQN, TwoHeadDqn

from scipy.optimize import minimize
from collections import namedtuple, deque, Counter

# from qnet import Dqn, DuelDQN

def get_iv_weights(variances):
    '''
    Returns Inverse Variance weights
    Params
    ======
        variances (numpy array): variance of the targets
    '''
    weights = 1/variances
    (weights)
    weights = weights/np.sum(weights)
    (weights)
    return weights

def compute_eff_bs(weights):
    # Compute original effective mini-batch size
    eff_bs = 1/np.sum(np.square(weights))
    #print(eff_bs)
    return eff_bs

def get_optimal_xi(variances, minimal_size, epsilon_start):
    minimal_size = min(variances.shape[0] - 1, minimal_size)
    if compute_eff_bs(get_iv_weights(variances)) >= minimal_size:
        return 0
    fn = lambda x: np.abs(compute_eff_bs(get_iv_weights(variances+np.abs(x))) - minimal_size)
    epsilon = minimize(fn, 0, method='Nelder-Mead', options={'fatol': 1.0, 'maxiter':100})
    xi = np.abs(epsilon.x[0])
    xi = 0 if xi is None else xi
    return xi

class BootstrapDQN:
    def __init__(self,
                 opt,
                 action_spec: dm_env.specs.DiscreteArray,
                 observation_spec: dm_env.specs.Array,
                 num_ensemble: int,
                 net_seed: int,
                 device: torch.device,
                 settings: dict) -> None:
        """
        Initializes the agent,  constructs the qnet and the q_target, initializes the optimizer and ReplayMemory.
        Args:
            action_spec(dm_env.specs.DiscreteArray): description of the action space of the environment
            observation_spec(dm_env.specs.Array): description of observations form the environment
            device(str): "gpu" or "cpu"
            settings(dict): dictionary with settings
        """
        self.device = device
        self.opt = opt
        self.num_ensemble = num_ensemble
        action_size = action_spec.num_values
        state_size = np.prod(observation_spec.shape)
        self.action_size = action_size
        self.state_size = state_size
        self.batch_size = settings['batch_size']
        self.noisy_nets = settings['qnet_settings']['noisy_nets']

        self.qnets, self.tnets, self.optims = [], [], []
        for i in range(num_ensemble):
            if settings["duelling_dqn"]:
                qnet = DuelDQN(state_size, action_size, settings['qnet_settings']).to(device)
                q_target = DuelDQN(state_size, action_size, settings['qnet_settings']).to(device)
            else:
                qnet = Dqn(state_size, action_size, settings['qnet_settings'], seed=opt.net_seed+i).to(device)
                q_target = Dqn(state_size, action_size, settings['qnet_settings'], seed=opt.net_seed+i).to(device)
                self.drop_porb = 0

            self.qnets.append(qnet)
            q_target.load_state_dict(qnet.state_dict())
            self.tnets.append(q_target)
            self.optims.append(optim.Adam(qnet.parameters(), lr=settings['lr']))

        self.epsilon = settings["epsilon_start"]
        self.decay = settings["epsilon_decay"]
        self.epsilon_min = settings["epsilon_min"]
        self.gamma = settings['gamma']

        self.start_optimization = settings["start_optimization"]
        self.update_qnet_every = settings["update_qnet_every"]
        self.update_target_every = settings["update_target_every"]
        self.number_steps = 0
        self.ddqn = settings["ddqn"]

        self.xi = settings["xi"]
        self.dynamic_xi = settings["dynamic_xi"]
        self.minimal_eff_bs_ratio = settings["minimal_eff_bs_ratio"]
        self.minimal_eff_bs = int(self.batch_size * self.minimal_eff_bs_ratio)
        self.mask_prob = settings["mask_prob"]

        self._rng = np.random.RandomState(net_seed)
        self._active_head = self._rng.randint(self.num_ensemble)
        # Initialize replay memory
        self.prioritized_replay = settings["prioritized_buffer"]
        if self.prioritized_replay:
            self.memory = PrioritizedReplayMemory(device, settings["buffer_size"], self.gamma, settings["n_steps"],
                                                  settings["alpha"], settings["beta0"], settings["beta_increment"])
        else:
            self.memory = ReplayMemory(device, settings["buffer_size"], self.gamma, settings["n_steps"])
        return

    def select_action(self, timestep: dm_env.TimeStep) -> int:
        """
        Returns an action following an epsilon-greedy policy.
        Args:
            timestep(dm_env.TimeStep): An observation from the environment

        Returns:
            int: The chosen action.
        """
        observation = np.array(timestep.observation).flatten()
        observation = torch.from_numpy(observation).float().to(self.device)
        self.number_steps += 1

        if not self.noisy_nets:
            self.update_epsilon()

        if np.random.rand() < self.epsilon:
            return np.random.choice(self.action_size)
        else:
            return int(self.qnets[self._active_head].get_max_action(observation))

    def greedy(self, Q_ensemble):
        mean_Q = np.mean(Q_ensemble, 0)
        # ------------------- action selection ------------------- #
        # if self.opt.select_action == "vote":
        actions = [np.argmax(Q) for Q in Q_ensemble]
        data = Counter(actions)
        action = data.most_common(1)[0][0]
        # elif self.opt.select_action == "mean":
        # action = np.argmax(mean_Q)

        return action

    def select_action_test(self, timestep: dm_env.TimeStep) -> int:
        """
        Returns an action following an epsilon-greedy policy.
        Args:
            timestep(dm_env.TimeStep): An observation from the environment

        Returns:
            int: The chosen action.
        """
        observation = np.array(timestep.observation).flatten()
        observation = torch.from_numpy(observation).float().to(self.device)
        # self.number_steps += 1

        with torch.no_grad():
            Q_ensemble = np.array([qnet(observation).cpu().data.numpy()
                               for qnet in self.qnets])

        return int(self.greedy(Q_ensemble))

    def update_epsilon(self) -> None:
        """
        Decays epsilon until self.epsilon_min
        Returns:
            None
        """
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.decay

    @staticmethod
    def calc_loss(q_observed: torch.Tensor,
                  q_target: torch.Tensor,
                  weights: torch.Tensor) -> typing.Tuple[torch.Tensor, np.float64]:
        """
        Returns the mean weighted MSE loss and the loss for each sample
        Args:
            q_observed(torch.Tensor): calculated q_value
            q_target(torch.Tensor):   target q-value
            weights: weights of the batch samples

        Returns:
            tuple(torch.Tensor, np.float64): mean squared error loss, loss for each indivdual sample
        """
        losses = functional.mse_loss(q_observed, q_target, reduction='none')
        loss = (weights * losses).sum()
        return loss, losses.cpu().detach().numpy() + 1e-8

    def update(self,
               step: dm_env.TimeStep,
               action: int,
               next_step: dm_env.TimeStep) -> None:
        """
        Adds experience to the replay memory, performs an optimization_step and updates the q_target neural network.
        Args:
            step(dm_env.TimeStep): Current observation from the environment
            action(int): The action that was performed by the agent.
            next_step(dm_env.TimeStep): Next observation from the environment
        Returns:
            None
        """

        logs = []
        observation = np.array(step.observation).flatten()
        next_observation = np.array(next_step.observation).flatten()
        done = next_step.last()

        if next_step.last():
          self._active_head = self._rng.randint(self.num_ensemble)

        exp = Experience(observation,
                         action,
                         next_step.reward,
                         next_step.discount,
                         next_observation,
                         0,
                         done,
                         self._rng.binomial(1, self.mask_prob, self.num_ensemble).astype(np.float32)
                         )
        self.memory.add(exp)

        if self.memory.number_samples() < self.start_optimization:
            return logs

        if self.number_steps % self.update_qnet_every == 0:
            s0, a0, n_step_reward, discount, s1, _, dones, indices, weights, masks = self.memory.sample_batch(self.batch_size)
            logs = self.optimization_step(s0, a0, n_step_reward, discount, s1, indices, weights, masks)

        if self.number_steps % self.update_target_every == 0:
            for i in range(self.num_ensemble):
                self.tnets[i].load_state_dict(self.qnets[i].state_dict())
        return logs

    def optimization_step(self,
                          s0: torch.Tensor,
                          a0: torch.Tensor,
                          n_step_reward: torch.Tensor,
                          discount: torch.Tensor,
                          s1: torch.Tensor,
                          indices: typing.Optional[torch.Tensor],
                          weights: typing.Optional[torch.Tensor],
                          masks: torch.Tensor) -> None:
        """
        Calculates the Bellmann update and updates the qnet.
        Args:
            s0(torch.Tensor): current state
            a0(torch.Tensor): current action
            n_step_reward(torch.Tensor): n-step reward
            discount(torch.Tensor): discount factor
            s1(torch.Tensor): next state
            indices(torch.Tensor): batch indices, needed for prioritized replay. Not used yet.
            weights(torch.Tensor): weights needed for prioritized replay

        Returns:
            None
        """

        with torch.no_grad():
            if self.noisy_nets:
                self.q_target.reset_noise()
                self.qnet.reset_noise()

            # Calculating the target values
            next_q_vals = torch.stack([self.tnets[i](s1) for i in range(self.num_ensemble)])
            next_actions = torch.stack([next_q_vals[i].max(1)[1] for i in range(self.num_ensemble)])
            # if self.ddqn:
            #     a1 = torch.argmax(self.qnet(s1), dim=1).unsqueeze(-1)
            #     next_q_val = next_q_vals.gather(1, a1).squeeze()
            # else:
            #     next_q_val = torch.max(next_q_vals, dim=2).values
            q_targets = torch.stack([n_step_reward.squeeze() + self.gamma * discount.squeeze() * torch.max(next_q_vals[i], dim=1).values\
                                        for i in range(self.num_ensemble)])
            # print(discount.size(), next_q_vals.size(), next_actions.size())
            q_target_var_all = (self.gamma**2) * (discount.repeat(1, self.action_size)**2) * next_q_vals.var(0)

        eff_batch_size_list, xi_list, loss_list = [], [], []
        for i in range(self.num_ensemble):
            # print(next_actions[i].size(), masks.size(), q_targets.size())
            q_target_var = q_target_var_all.gather(1, next_actions[i].unsqueeze(-1).long())[masks[:, i, 0]]
            # print(q_target_var.size())
            self.xi = get_optimal_xi(q_target_var.detach().cpu().numpy(
                ), self.minimal_eff_bs, self.xi) if self.dynamic_xi else self.xi
            weights = self.get_mse_weights(q_target_var)
            q_observed = self.qnets[i](s0).gather(1, a0.long()).squeeze()[masks[:, i, 0]]
            critic_loss, batch_loss = self.calc_loss(q_observed, q_targets[i][masks[:, i, 0]], weights.to(self.device))

            # Backpropagation of the gradients
            self.optims[i].zero_grad()
            critic_loss.backward()
            torch.nn.utils.clip_grad_norm_(self.qnets[i].parameters(), 5)
            self.optims[i].step()

            eff_batch_size_list.append(
                compute_eff_bs(weights.detach().cpu().numpy()))
            xi_list.append(self.xi)
            # loss_list.append(loss.item())

        # Update replay memory
        self.memory.update_priorities(indices, batch_loss)
        return q_target_var.detach().cpu().numpy(), weights.squeeze().detach().cpu().numpy(), np.mean(eff_batch_size_list), np.mean(xi_list)

    def train_log(self, var, weights, eff_batch_size, eps_list):
        wandb.log({"IV Weights(VAR)": np.var(weights), "IV Weights(Mean)": np.mean(weights),
            "IV Weights(Min)": np.min(weights), "IV Weights(Max)": np.max(weights), "IV Weights(Median)": np.median(weights)}, commit=False)
        wandb.log({"Variance(Q) (VAR)": np.var(var), "Variance(Q) (Mean)": np.mean(var),
            "Variance(Q) (Min)": np.min(var), "Variance(Q) (Max)": np.max(var), "Variance(Q) (Median)": np.median(var)}, commit=False)
        wandb.log(
            {"Avg Effective Batch Size / Episode": np.mean(eff_batch_size), "Avg Epsilon / Episode": np.mean(eps_list),
            "Max Epsilon / Episode": np.max(eps_list), "Median Epsilon / Episode": np.median(eps_list),
            "Min Epsilon / Episode": np.min(eps_list)}, commit=False)

    def get_mse_weights(self, variance):
        return torch.ones(variance.size()) / variance.size()[0]

class EnsembleDQN(BootstrapDQN):
    def __init__(self,
                 opt,
                 action_spec: dm_env.specs.DiscreteArray,
                 observation_spec: dm_env.specs.Array,
                 num_ensemble: int,
                 net_seed: int,
                 device: torch.device,
                 settings: dict) -> None:

        super().__init__(opt, action_spec, observation_spec, num_ensemble, net_seed, device, settings)

    def greedy(self, Q_ensemble):
        mean_Q = np.mean(Q_ensemble, 0)
        # ------------------- action selection ------------------- #
        # if self.opt.select_action == "vote":
        # actions = [np.argmax(Q) for Q in Q_ensemble]
        # data = Counter(actions)
        # action = data.most_common(1)[0][0]
        # elif self.opt.select_action == "mean":
        action = np.argmax(mean_Q)

        return action

    def select_action(self, timestep: dm_env.TimeStep) -> int:
        """
        Returns an action following an epsilon-greedy policy.
        Args:
            timestep(dm_env.TimeStep): An observation from the environment

        Returns:
            int: The chosen action.
        """
        observation = np.array(timestep.observation).flatten()
        observation = torch.from_numpy(observation).float().to(self.device)
        self.number_steps += 1

        for qnet in self.qnets:
            qnet.eval()

        with torch.no_grad():
            Q_ensemble = np.array([qnet(observation).cpu().data.numpy()
                               for qnet in self.qnets])

        if not self.noisy_nets:
            self.update_epsilon()

        if np.random.rand() < self.epsilon:
            return np.random.choice(self.action_size)
        else:
            return int(self.greedy(Q_ensemble))

    def select_action_test(self, timestep: dm_env.TimeStep) -> int:
        """
        Returns an action following an epsilon-greedy policy.
        Args:
            timestep(dm_env.TimeStep): An observation from the environment

        Returns:
            int: The chosen action.
        """
        observation = np.array(timestep.observation).flatten()
        observation = torch.from_numpy(observation).float().to(self.device)
        self.number_steps += 1

        for qnet in self.qnets:
            qnet.eval()

        with torch.no_grad():
            Q_ensemble = np.array([qnet(observation).cpu().data.numpy()
                               for qnet in self.qnets])

        return int(self.greedy(Q_ensemble))

class LakshmiBootDQN(BootstrapDQN):
    def __init__(self,
                 opt,
                 action_spec: dm_env.specs.DiscreteArray,
                 observation_spec: dm_env.specs.Array,
                 num_ensemble: int,
                 net_seed: int,
                 device: torch.device,
                 settings: dict) -> None:

        super().__init__(opt, action_spec, observation_spec, num_ensemble, net_seed, device, settings)

        self.qnets, self.tnets, self.optims = [], [], []
        for i in range(num_ensemble):
            if settings["duelling_dqn"]:
                qnet = DuelDQN(self.state_size, self.action_size, settings['qnet_settings']).to(device)
                q_target = DuelDQN(self.state_size, self.action_size, settings['qnet_settings']).to(device)
            else:
                qnet = TwoHeadDqn(self.state_size, self.action_size, settings['qnet_settings'], seed=opt.net_seed+i).to(device)
                q_target = TwoHeadDqn(self.state_size, self.action_size, settings['qnet_settings'], seed=opt.net_seed+i).to(device)
                self.drop_porb = 0

            self.qnets.append(qnet)
            q_target.load_state_dict(qnet.state_dict())
            self.tnets.append(q_target)
            self.optims.append(optim.Adam(qnet.parameters(), lr=settings['lr']))

    def optimization_step(self,
                          s0: torch.Tensor,
                          a0: torch.Tensor,
                          n_step_reward: torch.Tensor,
                          discount: torch.Tensor,
                          s1: torch.Tensor,
                          indices: typing.Optional[torch.Tensor],
                          weights: typing.Optional[torch.Tensor],
                          masks: torch.Tensor) -> None:
        """
        Calculates the Bellmann update and updates the qnet.
        Args:
            s0(torch.Tensor): current state
            a0(torch.Tensor): current action
            n_step_reward(torch.Tensor): n-step reward
            discount(torch.Tensor): discount factor
            s1(torch.Tensor): next state
            indices(torch.Tensor): batch indices, needed for prioritized replay. Not used yet.
            weights(torch.Tensor): weights needed for prioritized replay

        Returns:
            None
        """

        with torch.no_grad():
            if self.noisy_nets:
                self.q_target.reset_noise()
                self.qnet.reset_noise()

            # Calculating the target values
            next_q_vals_all = torch.stack([torch.stack(self.tnets[i](s1, is_training=True))
                                                         for i in range(self.num_ensemble)])
            next_q_vals, next_q_vals_std = next_q_vals_all[:,0], next_q_vals_all[:,1]
            next_actions = torch.stack([next_q_vals[i].max(1)[1] for i in range(self.num_ensemble)])
            # q_targets_all = torch.stack([n_step_reward.squeeze() + self.gamma * discount.squeeze() * next_q_vals[i]\
                                                                                # for i in range(self.num_ensemble)])
            # print(discount.size(), n_step_reward.size(), next_q_vals.size())
            q_targets_all = torch.stack([n_step_reward.repeat(1, self.action_size) + self.gamma * discount.repeat(1, self.action_size) * next_q_vals[i]\
                                                                                for i in range(self.num_ensemble)])
            q_targets = torch.stack([n_step_reward.squeeze() + self.gamma * discount.squeeze() * torch.max(next_q_vals[i], dim=1).values\
                                                                                for i in range(self.num_ensemble)])
            # print(discount.size(), next_q_vals.size(), next_actions.size())
            # q_target_var_all = (self.gamma**2) * (discount.repeat(1, self.action_size)**2) * next_q_vals.var(0)
            next_q_vals_std = (self.gamma**2) * torch.stack([next_q_vals_std[i].gather(1, next_actions[i].unsqueeze(-1).long()) for i in range(self.num_ensemble)])
            # print(next_q_vals.size(), next_q_vals_std.size(), q_targets.size())
            # print((next_q_vals_std**2 + q_targets**2 - q_targets.mean(0).unsqueeze(-1).repeat(self.num_ensemble,1,1)**2).mean(0).size())
            q_var_mixture = (discount.repeat(1, self.action_size)**2) * (next_q_vals_std**2 + q_targets_all**2 - q_targets_all.mean(0).unsqueeze(0).repeat(self.num_ensemble,1,1)**2).mean(0)

        eff_batch_size_list, xi_list, loss_list = [], [], []
        for i in range(self.num_ensemble):
            # print(next_actions[i].size(), masks.size(), q_targets.size())
            q_target_var = q_var_mixture.gather(1, next_actions[i].unsqueeze(-1).long())[masks[:, i, 0]]
            # print(q_target_var.size())
            self.xi = get_optimal_xi(q_target_var.detach().cpu().numpy(
                ), self.minimal_eff_bs, self.xi) if self.dynamic_xi else self.xi
            weights = self.get_mse_weights(q_target_var)
            q_observed, q_observed_std = self.qnets[i](s0, is_training=True)
            q_observed = q_observed.gather(1, a0.long()).squeeze()#[masks[:, i, 0]]
            q_observed_std = q_observed_std.gather(1, a0.long()).squeeze()#[masks[:,i,0]]

            y, mu, std = q_targets, q_observed, q_observed_std
            lossatt = torch.mean((y - mu)**2 / (2 * (std**2)) + (1/2) * torch.log((std**2)))

            critic_loss, batch_loss = self.calc_loss(q_observed[masks[:, i, 0]], q_targets[i][masks[:, i, 0]], weights.to(self.device))

            # Backpropagation of the gradients
            self.optims[i].zero_grad()
            critic_loss += self.opt.lossatt_weight * lossatt
            critic_loss.backward()
            torch.nn.utils.clip_grad_norm_(self.qnets[i].parameters(), 5)
            self.optims[i].step()

            eff_batch_size_list.append(
                compute_eff_bs(weights.detach().cpu().numpy()))
            xi_list.append(self.xi)
            # loss_list.append(loss.item())

        # Update replay memory
        self.memory.update_priorities(indices, batch_loss)
        return q_target_var.detach().cpu().numpy(), weights.squeeze().detach().cpu().numpy(), np.mean(eff_batch_size_list), np.mean(xi_list)

class IV_BootstrapDQN(BootstrapDQN):
    def __init__(self,
                 opt,
                 action_spec: dm_env.specs.DiscreteArray,
                 observation_spec: dm_env.specs.Array,
                 num_ensemble: int,
                 net_seed: int,
                 device: torch.device,
                 settings: dict) -> None:

        super().__init__(opt, action_spec, observation_spec, num_ensemble, net_seed, device, settings)

    def iv_weights(self, variance):
        weights = (1. / (variance+self.xi))
        weights /= weights.sum(0)
        return weights

    def get_mse_weights(self, variance):
        return self.iv_weights(variance)

class IV_DQN(EnsembleDQN):
    def __init__(self,
                 opt,
                 action_spec: dm_env.specs.DiscreteArray,
                 observation_spec: dm_env.specs.Array,
                 num_ensemble: int,
                 net_seed: int,
                 device: torch.device,
                 settings: dict) -> None:

        super().__init__(opt, action_spec, observation_spec, num_ensemble, net_seed, device, settings)

    def iv_weights(self, variance):
        weights = (1. / (variance+self.xi))
        weights /= weights.sum(0)
        return weights

    def get_mse_weights(self, variance):
        return self.iv_weights(variance)

class IV_LakshmiBootDQN(LakshmiBootDQN):
    def __init__(self,
                 opt,
                 action_spec: dm_env.specs.DiscreteArray,
                 observation_spec: dm_env.specs.Array,
                 num_ensemble: int,
                 net_seed: int,
                 device: torch.device,
                 settings: dict) -> None:

        super().__init__(opt, action_spec, observation_spec, num_ensemble, net_seed, device, settings)

    def iv_weights(self, variance):
        weights = (1. / (variance+self.xi))
        weights /= weights.sum(0)
        return weights

    def get_mse_weights(self, variance):
        return self.iv_weights(variance)

class SunriseDQN(BootstrapDQN):
    def __init__(self,
                 opt,
                 action_spec: dm_env.specs.DiscreteArray,
                 observation_spec: dm_env.specs.Array,
                 num_ensemble: int,
                 net_seed: int,
                 device: torch.device,
                 settings: dict) -> None:

        super().__init__(opt, action_spec, observation_spec, num_ensemble, net_seed, device, settings)
        self.opt = opt

    def sunrise_weights(self, variance):
        temp = self.opt.sunrise_temp
        weights = torch.sigmoid(-torch.sqrt(variance)*temp) + 0.5
        return weights

    def get_mse_weights(self, variance):
    	return self.sunrise_weights(variance)


<reponame>mengdong/mapr-streams-mxnet-face
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from symbol.resnet import *
from symbol.config import config
from symbol.processing import bbox_pred, clip_boxes, nms
import face_embedding
from mapr_streams_python import Consumer, KafkaError, Producer
import numpy as np
import cv2, os, json, time, sys, pickle
import mxnet as mx
import argparse, random, sklearn
import tensorflow as tf
from scipy import misc
from sklearn.decomposition import PCA
from time import sleep
from easydict import EasyDict as edict
from mtcnn_detector import MtcnnDetector
import face_image, face_preprocess
from flask import Flask, Response

app = Flask(__name__)

@app.route('/')
def index():
    return Response(kafkastream(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

def ch_dev(arg_params, aux_params, ctx):
    new_args = dict()
    new_auxs = dict()
    for k, v in arg_params.items():
        new_args[k] = v.as_in_context(ctx)
    for k, v in aux_params.items():
        new_auxs[k] = v.as_in_context(ctx)
    return new_args, new_auxs

def resize(im, target_size, max_size):
    """
    only resize input image to target size and return scale
    :param im: BGR image input by opencv
    :param target_size: one dimensional size (the short side)
    :param max_size: one dimensional max size (the long side)
    :return:
    """
    im_shape = im.shape
    im_size_min = np.min(im_shape[0:2])
    im_size_max = np.max(im_shape[0:2])
    im_scale = float(target_size) / float(im_size_min)
    if np.round(im_scale * im_size_max) > max_size:
        im_scale = float(max_size) / float(im_size_max)
    im = cv2.resize(im, None, None, fx=im_scale, fy=im_scale, interpolation=cv2.INTER_LINEAR)
    return im, im_scale

def get_face_embedding(filename, arg_params, aux_params, sym, model, ctx):
    img_orig = cv2.imread(filename)
    img_orig = cv2.cvtColor(img_orig, cv2.COLOR_BGR2RGB)
    img, scale = resize(img_orig.copy(), 600, 1000)
    im_info = np.array([[img.shape[0], img.shape[1], scale]], dtype=np.float32)  # (h, w, scale)
    img = np.swapaxes(img, 0, 2)
    img = np.swapaxes(img, 1, 2)  # change to (c, h, w) order
    img = img[np.newaxis, :]  # extend to (n, c, h, w)
    arg_params["data"] = mx.nd.array(img, ctx)
    arg_params["im_info"] = mx.nd.array(im_info, ctx)
    exe = sym.bind(ctx, arg_params, args_grad=None, grad_req="null", aux_states=aux_params)

    exe.forward(is_train=False)
    output_dict = {name: nd for name, nd in zip(sym.list_outputs(), exe.outputs)}
    rois = output_dict['rpn_rois_output'].asnumpy()[:, 1:]  # first column is index
    scores = output_dict['cls_prob_reshape_output'].asnumpy()[0]
    bbox_deltas = output_dict['bbox_pred_reshape_output'].asnumpy()[0]
    pred_boxes = bbox_pred(rois, bbox_deltas)
    pred_boxes = clip_boxes(pred_boxes, (im_info[0][0], im_info[0][1]))
    cls_boxes = pred_boxes[:, 4:8]
    cls_scores = scores[:, 1]
    keep = np.where(cls_scores >0.6)[0]
    cls_boxes = cls_boxes[keep, :]
    cls_scores = cls_scores[keep]
    dets = np.hstack((cls_boxes, cls_scores[:, np.newaxis])).astype(np.float32)
    keep = nms(dets.astype(np.float32), 0.3)
    dets = dets[keep, :]
    bbox = dets[0, :4]
    roundfunc = lambda t: int(round(t/scale))
    vfunc = np.vectorize(roundfunc)
    bbox = vfunc(bbox)
    f_vector, jpeg = model.get_feature(img_orig, bbox, None)
    fT = f_vector.T
    return fT

def kafkastream():
    if args.gpuid >= 0:
        ctx = mx.gpu(args.gpuid)
    else:
        ctx = mx.cpu()
    _, arg_params, aux_params = mx.model.load_checkpoint('mxnet-face-fr50', 0)
    arg_params, aux_params = ch_dev(arg_params, aux_params, ctx)
    sym = resnet_50(num_class=2)
    model = face_embedding.FaceModel(args.gpuid)

    f1T = get_face_embedding(args.filename, arg_params, aux_params, sym, model, ctx)

    c = Consumer({'group.id': args.groupid,
              'default.topic.config': {'auto.offset.reset': 'earliest', 'enable.auto.commit': 'false'}})
    c.subscribe([args.readstream+':'+args.readtopic])
    running = True
    p = Producer({'streams.producer.default.stream': args.writestream})

    while running:
        msg = c.poll(timeout=0)
        if msg is None: continue
        if not msg.error():
            pickle_vector = pickle.loads(msg.value())
            nparr = np.fromstring(pickle_vector[0], np.uint8)
            img_orig = cv2.imdecode(nparr, 1)

            bbox_vector = pickle_vector[1]
            print(len(bbox_vector))
            embedding_vector = pickle_vector[2]
            if len(embedding_vector) > 0:
                sim_vector = [np.dot(f, f1T) for f in embedding_vector]
                idx = sim_vector.index(max(sim_vector))
                bbox = bbox_vector[idx]
                sim = sim_vector[idx]
                if sim > args.threshold:
                    img = cv2.cvtColor(img_orig, cv2.COLOR_RGB2BGR)
                    cv2.rectangle(img, (int(round(bbox[0])), int(round(bbox[1]))),
                        (int(round(bbox[2])), int(round(bbox[3]))),  (0, 255, 0), 2)
                    ret, jpeg = cv2.imencode('.png', img)
                    bytecode = jpeg.tobytes()
                    time.sleep(args.timeout)
                    yield (b'--frame\r\n'
                        b'Content-Type: image/png\r\n\r\n' + bytecode + b'\r\n\r\n')
                    if args.writetostream:
                        p.produce(args.writetopic, jpeg.tostring())
                        print(args.writetopic)
        elif msg.error().code() != KafkaError._PARTITION_EOF:
            print(msg.error())
            running = False

    c.close()
    p.flush()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='mapr consumer settings')
    parser.add_argument('--groupid', default='dong001', help='mapr consumer to read from')
    parser.add_argument('--gpuid', default='-1', type=int, help='')
    parser.add_argument('--port', default='5013', type=int, help='')
    parser.add_argument('--threshold', default='0.3', type=float, help='')
    parser.add_argument('--readstream', default='/tmp/processedvideostream', help='')
    parser.add_argument('--writestream', default='/tmp/identifiedstream', help='')
    parser.add_argument('--timeout', default='0.3', type=float, help='')
    parser.add_argument('--writetostream', default='0', type=int, help='')
    parser.add_argument('--writetopic', default='sam', help='topic to write to')
    parser.add_argument('--readtopic', default='topic1', help='topic to write to')
    parser.add_argument('--filename', default='sam_.jpg', help='')
    args = parser.parse_args()
    app.run(host='0.0.0.0', port=args.port, debug=True)


# cifar10_svm.py

# Support Vector Machine (SVM)

import time
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn import model_selection
from scipy.io import loadmat

from sklearn.svm import SVC, LinearSVC
from sklearn.metrics import hinge_loss
from sklearn.metrics import classification_report, f1_score, accuracy_score, confusion_matrix

def run_svc(svc, title):
    # Fit model
    start = time.time()
    svc.fit(x_train, y_train)
    end = time.time()
    print("\nModel took %0.2f seconds to train"%(end - start))

    # Calculate predictions
    start = time.time()
    predicted = svc.predict(x_test)
    end = time.time()
    print("Model took %0.2f seconds to calculate predictions"%(end - start))

    # Output results
    print('\naccuracy', accuracy_score(y_test, predicted))
    print('\nSVM Results for ' + title)
    print('\nConfusion Matrix:')
    print(confusion_matrix(y_test, predicted))

    print('\nClassification Report:', classification_report(y_test, predicted))
    #print("Hinge loss", hinge_loss(y_test, predicted))

# Load datasets from file
npzfile = np.load('cifar10.npz')
print(npzfile.files)

x_train = npzfile['x_train']
x_test = npzfile['x_test']
y_train = npzfile['y_train']
y_test = npzfile['y_test']

# Standardize the columns
x_train = x_train / 255
x_test = x_test / 255

# The model cannot deal with 2D array so we have to convert to 1D array.
x_train_flat = np.empty(shape=[x_train.shape[0]] + [3072], dtype='float32')

for i in range(x_train.shape[0]):
    x_train_flat[i,:] = x_train[i,:,:].flatten()

# Flatten x_test array
x_test_flat = np.empty(shape=[x_test.shape[0]] + [3072], dtype='float32')
for i in range(x_test.shape[0]):
    x_test_flat[i,:] = x_test[i,:,:].flatten()

x_train = x_train_flat
x_test = x_test_flat
y_train = y_train.ravel()
y_test = y_test.ravel()

print('\n', type(x_train))
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)
print('y_train shape:', y_train.shape)
print('y_test shape:', y_test.shape)

# Linear
svc = SVC(kernel='linear', C=1)
run_svc(svc, 'Linear')

# Radial Basis Function (RBF)
svc = SVC(kernel='rbf', gamma=1, C=1)
run_svc(svc, 'Radial Basis Function (RBF)')

# Polynomial
svc = SVC(kernel='poly', degree=5, C=1)
run_svc(svc, 'Polynomial)')