text:
# -*- coding: utf-8 -*-
#
# Markov Logic Networks
#
# (C) 2006-2011 by Dominik Jain (jain@cs.tum.edu)
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from pracmln.mln.learning.common import SoftEvidenceLearner, DiscriminativeLearner
from pracmln.mln.learning.common import AbstractLearner
import numpy
from numpy.ma.core import exp
from pracmln.mln.util import fsum
from pracmln.mln.mrfvars import SoftMutexVariable

# TODO Note: when counting diffs (PLL), the assumption is made that no formula contains two atoms that are in the same block

class PLL(AbstractLearner):

    def __init__(self, mln, mrf, pmbMethod="old", diffMethod="blocking", **params):
        '''
        pmbMethod: 'excl' or 'old'
            concerns the calculation of the probability of a ground atom assignment given the ground atom's Markov blanket
            If set to 'old', consider only the two assignments of the ground atom x (i.e. add the weights of any ground
            formulas within which x appears for both cases and then use the appriopriate fraction).
            If set to 'excl', consider mutual exclusiveness and exhaustiveness by looking at all the assignments of the
            block that x is in (and all the formulas that are affected by any of the atoms in the block). We obtain an exp. sum of
            weights for each block assignment and consider the fraction of those block assignments where x has a given value.

        diffMethod: "blocking" or "simple"
            This applies to parameter learning with pseudo-likelihood, where, for each ground atom x, the difference in the number
            of true groundings of a formula is computed for the case where x's truth value is flipped and where x's truth value
            remains the same (as indicated by the training db).
            If set to 'blocking', then we not only consider the effects of flipping x itself but also flips of any
            ground atoms with which x appears together in a block, because flipping them may (or may not) affect the truth
            value of x and thus the truth of ground formulas within which x appears.
        '''
        AbstractLearner.__init__(self, mln, mrf, **params)
        self.pmbMethod = pmbMethod
        self.diffMethod = diffMethod
        if len(filter(lambda b: isinstance(b, SoftMutexVariable), self.mrf.variables)) > 0:
            raise Exception('%s cannot handle soft-functional constraints' % self.__class__.__name__)

    def getAtomProbMB(self, atom):
        '''
        determines the probability of the given ground atom (string) given its Markov blanket
        (the MLN must have been provided with evidence using combineDB)
        '''
        idxGndAtom = self.mrf.gndAtoms[atom].idx
        weights = self._weights()
        return self._getAtomProbMB(idxGndAtom, weights)

    def _getAtomProbMB(self, idxGndAtom, wt, relevantGroundFormulas=None):
        '''
        gets the probability of the ground atom with index idxGndAtom when given its Markov blanket (evidence set)
        using the specified weight vector
        '''
        #old_tv = self._getEvidence(idxGndAtom)
        # check if the ground atom is in a block
        block = None
        if idxGndAtom in self.mrf.gndBlockLookup and self.pmbMethod != 'old':
            blockname = self.mrf.gndBlockLookup[idxGndAtom]
            block = self.mrf.gndBlocks[blockname]   # list of gnd atom indices that are in the block
            sums = [0 for i in range(len(block))]   # init sum of weights for each possible assignment of block
                                                    # sums[i] = sum of weights for assignment where the block[i] is set to true
            idxBlockMainGA = block.index(idxGndAtom)
            # find out which one of the ground atoms in the block is true
            idxGATrueone = -1
            for i in block:
                if self.mrf._getEvidence(i):
                    if idxGATrueone != -1: raise Exception("More than one true ground atom in block %s!" % blockname)
                    idxGATrueone = i
            if idxGATrueone == -1: raise Exception("No true gnd atom in block!" % blockname)
            mainAtomIsTrueone = idxGATrueone == idxGndAtom
        else: # not in block
            wts_inverted = 0
            wts_regular = 0
            wr, wi = [], []
        # determine the set of ground formulas to consider
        checkRelevance = False
        if relevantGroundFormulas == None:
            try:
                relevantGroundFormulas = self.atomRelevantGFs[idxGndAtom]
            except:
                relevantGroundFormulas = self.mrf.gndFormulas
                checkRelevance = True
        # check the ground formulas
        #print self.gndAtomsByIdx[idxGndAtom]
        if self.pmbMethod == 'old' or block == None: # old method (only consider formulas that contain the ground atom)
            for gf in relevantGroundFormulas:
                if checkRelevance:
                    if not gf.containsGndAtom(idxGndAtom):
                        continue
                # gnd atom maintains regular truth value
                prob1 = self._getTruthDegreeGivenEvidence(gf)
                #print "gf: ", str(gf), " index: ", gf.idxFormula, ", wt size:", len(wt), " formula size:", len(self.formulas)
                if prob1 > 0:
                    wts_regular += wt[gf.idxFormula] * prob1
                    wr.append(wt[gf.idxFormula] * prob1)
                # flipped truth value
                #self._setTemporaryEvidence(idxGndAtom, not old_tv)
                self._setInvertedEvidence(idxGndAtom)
                #if self._isTrueGndFormulaGivenEvidence(gf):
                #    wts_inverted += wt[gf.idxFormula]
                #    wi.append(wt[gf.idxFormula])
                prob2 = self._getTruthDegreeGivenEvidence(gf)
                if prob2 > 0:
                    wts_inverted += wt[gf.idxFormula] * prob2
                    wi.append(wt[gf.idxFormula] * prob2)
                #self._removeTemporaryEvidence()
                #print "  F%d %f %s %f -> %f" % (gf.idxFormula, wt[gf.idxFormula], str(gf), prob1, prob2)
                self._setInvertedEvidence(idxGndAtom)
            #print "  %s %s" % (wts_regular, wts_inverted)
            return exp(wts_regular) / (exp(wts_regular) + exp(wts_inverted))
        elif self.pmbMethod == 'excl' or self.pmbMethod == 'excl2': # new method (consider all the formulas that contain one of the ground atoms in the same block as the ground atom)
            for gf in relevantGroundFormulas: # !!! here the relevant ground formulas may not be sufficient!!!! they are different than in the other case
                # check if one of the ground atoms in the block appears in the ground formula
                if checkRelevance:
                    gfRelevant = False
                    for i in block:
                        if gf.containsGndAtom(i):
                            gfRelevant = True
                            break
                    if not gfRelevant: continue
                # make each one of the ground atoms in the block true once
                idxSum = 0
                for i in block:
                    # set the i-th variable in the block to true
                    if i != idxGATrueone:
                        self.mrf._setTemporaryEvidence(i, True)
                        self.mrf._setTemporaryEvidence(idxGATrueone, False)
                    # is the formula true?
                    if self.mrf._isTrueGndFormulaGivenEvidence(gf):
                        sums[idxSum] += wt[gf.idxFormula]
                    # restore truth values
                    self.mrf._removeTemporaryEvidence()
                    idxSum += 1
            expsums = map(exp, sums)
            if self.pmbMethod == 'excl':
                if mainAtomIsTrueone:
                    return expsums[idxBlockMainGA] / sum(expsums)
                else:
                    s = sum(expsums)
                    return (s - expsums[idxBlockMainGA]) / s
            elif self.pmbMethod == 'excl2':
                if mainAtomIsTrueone:
                    return expsums[idxBlockMainGA] / sum(expsums)
                else:
                    idxBlockTrueone = block.index(idxGATrueone)
                    return expsums[idxBlockTrueone] / (expsums[idxBlockTrueone] + expsums[idxBlockMainGA])
        else:
            raise Exception("Unknown pmbMethod '%s'" % self.pmbMethod)

    def _setInvertedEvidence(self, idxGndAtom):
        old_tv = self.mrf._getEvidence(idxGndAtom)
        self.mrf._setEvidence(idxGndAtom, 1 - old_tv)

    # prints the probability of each ground atom truth assignment given its Markov blanket
    def printAtomProbsMB(self):
        gndAtoms = self.mrf.gndAtoms.keys()
        gndAtoms.sort()
        values = []
        for gndAtom in gndAtoms:
            v = self.getAtomProbMB(gndAtom)
            print "%s=%s  %f" % (gndAtom, str(self.mrf._getEvidence(self.mrf.gndAtoms[gndAtom].idx)), v)
            values.append(v)
        pll = fsum(map(log, values))
        print "PLL = %f" % pll

    def _calculateAtomProbsMB(self, wt):
        if ('wtsLastAtomProbMBComputation' not in dir(self)) or self.wtsLastAtomProbMBComputation != list(wt):
            print "recomputing atom probabilities...",
            self.atomProbsMB = [self._getAtomProbMB(i, wt) for i in range(len(self.mrf.gndAtomsByIdx))]
            self.atomProbsMB = map(lambda x: x if x > 0 else 1e-10, self.atomProbsMB)
            self.wtsLastAtomProbMBComputation = list(wt)
            print "done."

    def _f(self, wt, **params):
        self._calculateAtomProbsMB(wt)
        #print self.atomProbsMB
        probs = map(lambda x: x if x > 0 else 1e-10, self.atomProbsMB) # prevent 0 probs
        pll = fsum(map(log, probs))
        print "pseudo-log-likelihood:", pll
        return pll

    def _addToDiff(self, idxFormula, idxGndAtom, diff):
        key = (idxFormula, idxGndAtom)
        cur = self.diffs.get(key, 0)
        self.diffs[key] = cur + diff

    def _computeDiffs(self):
        self.diffs = {}
        for gndFormula in self.mrf.gndFormulas:
            for idxGndAtom in gndFormula.idxGroundAtoms():
                cnt1, cnt2 = 0, 0
                # check if formula is true if gnd atom maintains its truth value
                cnt1 = self.mrf._isTrueGndFormulaGivenEvidence(gndFormula)
                # check if formula is true if gnd atom's truth value is inversed
                old_tv = self.mrf._getEvidence(idxGndAtom)
                self.mrf._setTemporaryEvidence(idxGndAtom, 1 - old_tv)
                cnt2 = self.mrf._isTrueGndFormulaGivenEvidence(gndFormula)
                self.mrf._removeTemporaryEvidence()
                # save difference
                diff = cnt2 - cnt1
                if diff != 0:
                    self._addToDiff(gndFormula.idxFormula, idxGndAtom, diff)
                    # if the gnd atom is in a block with other variables, then these other variables can also
                    # cause a change in the number of true groundings of this formula:
                    # let's say there are k gnd atoms in the block and one of the k items appears in gndFormula, say item x.
                    # if gnd atom x is true, then a change to any of the other k-1 items will flip x.
                    # if gnd atom x is false, then there is a chance of 1/(k-1) that x is flipped
                    if self.diffMethod == 'blocking':
                        if idxGndAtom in self.mrf.gndBlockLookup:
                            blockname = self.mrf.gndBlockLookup[idxGndAtom]
                            block = self.mrf.gndBlocks[blockname] # list of gnd atom indices that are in the block
                            for i in block:
                                if i not in gndFormula.idxGroundAtoms(): # for each ground atom in the block besides the one we are just processing (which occurs in the ground formula)
                                    if old_tv:
                                        self._addToDiff(gndFormula.idxFormula, i, diff)
                                    else:
                                        self._addToDiff(gndFormula.idxFormula, i, diff / (len(block) - 1))

    def _grad(self, wt, **params):
        grad = numpy.zeros(len(self.mln.formulas), numpy.float64)
        fullWt = wt
        self._calculateAtomProbsMB(fullWt)
        for (idxFormula, idxGndAtom), diff in self.diffs.iteritems():
            v = diff * (self.atomProbsMB[idxGndAtom] - 1)
            grad[idxFormula] += v
        return grad

    def _getAtomRelevantGroundFormulas(self):
        if self.pmbMethod == 'old':
            self.atomRelevantGFs = self.mrf.gndAtomOccurrencesInGFs
        else:
            raise Exception("Not implemented")

    def _prepareOpt(self):
        print "computing differences..."
        self._computeDiffs()
        print "  %d differences recorded" % len(self.diffs)
        print "determining relevant formulas for each ground atom..."
        self._getAtomRelevantGroundFormulas()

class PLL_ISE(SoftEvidenceLearner, PLL):

    def __init__(self, mln, **params):
        SoftEvidenceLearner.__init__(self, mln, **params)
        PLL.__init__(self, mln, **params)

    def _computeDiffs(self):
        self.diffs = {}
        for gndFormula in self.mrf.gndFormulas:
            cnt1 = self._getTruthDegreeGivenEvidence(gndFormula)
            for idxGndAtom in gndFormula.idxGroundAtoms():
                # check if formula is true if gnd atom's truth value is inversed
                cnt2 = 0
                # check if it really is a soft evidence:
                s = strFormula(self.mrf.gndAtomsByIdx[idxGndAtom])
                isSoftEvidence = False
                for se in self.mrf.softEvidence:
                    if se["expr"] == s:
                        isSoftEvidence = True
                        old_tv = se["p"]
                        break

                if isSoftEvidence:
                    self.mrf._setSoftEvidence(self.mln.gndAtomsByIdx[idxGndAtom], 1 - old_tv)
                    cnt2 = self._getTruthDegreeGivenEvidence(gndFormula)
                    self.mrf._setSoftEvidence(self.mln.gndAtomsByIdx[idxGndAtom], old_tv)
                else:
                    old_tv = self.mrf._getEvidence(idxGndAtom)
                    self.mrf._setTemporaryEvidence(idxGndAtom, not old_tv)
                    if self.mrf._isTrueGndFormulaGivenEvidence(gndFormula): cnt2 = 1
                    self.mrf._removeTemporaryEvidence()

                # save difference
                diff = cnt2 - cnt1
                if diff != 0:
                    self._addToDiff(gndFormula.idxFormula, idxGndAtom, diff)

    def _setInvertedEvidence(self, idxGndAtom):
        s = strFormula(self.mrf.gndAtomsByIdx[idxGndAtom])
        isSoftEvidence = False
        for se in self.mrf.softEvidence:
            if se["expr"] == s:
                isSoftEvidence = True
                old_tv = se["p"]
                break
        if isSoftEvidence:
            self.mrf._setSoftEvidence(self.mrf.gndAtomsByIdx[idxGndAtom], 1 - old_tv)
        else:
            old_tv = self.mrf._getEvidence(idxGndAtom)
            self.mrf._setEvidence(idxGndAtom, not old_tv)

    def _prepareOpt(self):
        if self.pmbMethod != 'old': raise Exception("Only PMB (probability given Markov blanket) method 'old' supported by PLL_ISE")

        # set all soft evidence values to true
        #for se in self.softEvidence:
        #    self._setEvidence(self.mln.gndAtoms[se["expr"]].idx, True)

        PLL._prepareOpt(self)

    def _f(self, wt, **params):

        pll = PLL._f(self, wt)

        if self.gaussianPriorSigma != None:
            #add gaussian means:
            for weight in wt:
                pll += gaussianZeroMean(weight, self.gaussianPriorSigma)

        print "pseudo-log-likelihood:", pll
        return pll

    def _grad(self, wt, **params):
        grad = PLL._grad(self, wt)

        if self.gaussianPriorSigma != None:
            #add gaussian means:
            for i, weight in enumerate(wt):
                grad[i] += gradGaussianZeroMean(weight, self.gaussianPriorSigma)

        return grad

class DPLL_ISE(PLL_ISE):
    ''' discriminative PLL_ISE with independent soft evidence for atLocation '''

    def __init__(self, mln, **params):
        DPLL.__init__(mln, **params)
        PLL_ISE.__init__(mln, **params)
        # manually inherit methods from DPLL
        self._f = DPLL._f
        self._grad = DPLL._grad
        self._isQueryPredicate = DPLL._isQueryPredicate


text:
# coding:utf-8
import os
import json
import numpy as np
import glob
import shutil
from labelme import utils

from sklearn.model_selection import train_test_split

np.random.seed(41)

classname_to_id = {'BowenPress_1': 1, 'BowenPress_2': 2, 'FTchinese': 3, 'Formosa TV News network': 4, 'RFA': 5,
                   'apollo': 6, 'bbc_1': 7, 'cnn_1': 8, 'creaders_0': 9, 'creaders_1': 10, 'creaders_2': 11,
                   'cti_0': 12, 'cti_2': 13, 'epoch_1': 14, 'epoch_2': 15, 'global_videw_1': 16, 'global_videw_2': 17,
                   'jgzs_1': 18, 'jgzs_2': 19, 'mjhp_0': 20, 'mjhp_1': 21, 'mjhp_2': 22, 'ntd_0': 23, 'ntd_1': 24,
                   'ntd_2': 25, 'voa_0': 26, 'zyzg_0': 27, 'zyzg_2': 28}

class Lableme2CoCo:

    def __init__(self):
        self.images = []
        self.annotations = []
        self.categories = []
        self.img_id = 0
        self.ann_id = 0

    def save_coco_json(self, instance, save_path):
        json.dump(instance, open(save_path, 'w', encoding='utf-8'), ensure_ascii=False, indent=1)  # indent=2 更加美观显示

    def to_coco(self, json_path_list):
        self._init_categories()
        for json_path in json_path_list:
            obj = self.read_jsonfile(json_path)
            # self.images.append(self._image(obj, json_path))
            self.images.append(self._image_no_data(obj, json_path))
            shapes = obj['shapes']
            for shape in shapes:
                annotation = self._annotation(shape)
                self.annotations.append(annotation)
                self.ann_id += 1
            self.img_id += 1
        instance = {}
        instance['info'] = 'spytensor created'
        instance['license'] = ['license']
        instance['images'] = self.images
        instance['annotations'] = self.annotations
        instance['categories'] = self.categories
        return instance

    def _init_categories(self):
        for k, v in classname_to_id.items():
            category = {}
            category['id'] = v
            category['name'] = k
            self.categories.append(category)

    def _image(self, obj, path):
        image = {}
        img_x = utils.img_b64_to_arr(obj['imageData'])
        h, w = img_x.shape[:-1]
        image['height'] = h
        image['width'] = w
        image['id'] = self.img_id
        image['file_name'] = os.path.basename(path).replace(".json", ".jpg")
        return image

    def _image_no_data(self, obj, path):
        image = {}
        image['height'] = obj['imageHeight']
        image['width'] = obj['imageWidth']
        image['id'] = self.img_id
        image['file_name'] = os.path.basename(path).replace(".json", ".jpg")
        return image

    def _annotation(self, shape):
        label = shape['label']
        points = shape['points']
        annotation = {}
        annotation['id'] = self.ann_id
        annotation['image_id'] = self.img_id
        annotation['category_id'] = int(classname_to_id[label])
        annotation['segmentation'] = self._get_segmentation(points)
        annotation['bbox'] = self._get_box(points)
        annotation['iscrowd'] = 0
        annotation['area'] = 1.0
        return annotation

    def read_jsonfile(self, path):
        with open(path, "r", encoding='utf-8') as f:
            return json.load(f)

    def _get_box(self, points):
        min_x = min_y = np.inf
        max_x = max_y = 0
        for x, y in points:
            min_x = min(min_x, x)
            min_y = min(min_y, y)
            max_x = max(max_x, x)
            max_y = max(max_y, y)
        return [min_x, min_y, max_x - min_x, max_y - min_y]

    def _get_segmentation(self, points):
        x1 = points[0][0]
        y1 = points[0][1]
        x2 = points[1][0]
        y2 = points[1][1]
        seg = [list(np.asarray([[x1, y1], [x2, y1], [x2, y2], [x1, y2]]).flatten())]
        # seg = [np.asarray(points).flatten().tolist()]
        return seg

if __name__ == '__main__':
    labelme_path = "/mnt/data/logo/training/"
    saved_coco_path = "/home/lintao/docker_share/logo_coco/logo/"
    if not os.path.exists("%sannotations/" % saved_coco_path):
        os.makedirs("%sannotations/" % saved_coco_path)
    if not os.path.exists("%simages/train2017/" % saved_coco_path):
        os.makedirs("%simages/train2017" % saved_coco_path)
    if not os.path.exists("%simages/val2017/" % saved_coco_path):
        os.makedirs("%simages/val2017" % saved_coco_path)

    json_list_path = glob.glob(labelme_path + "*/*.json")

    train_path, val_path = train_test_split(json_list_path, test_size=0.12)
    print("train_n:", len(train_path), 'val_n:', len(val_path))

    l2c_train = Lableme2CoCo()
    train_instance = l2c_train.to_coco(train_path)
    l2c_train.save_coco_json(train_instance, '%sannotations/instances_train2017.json' % saved_coco_path)
    # for file in train_path:
    #     shutil.copy(file.replace("json", "jpg"), "%simages/train2017/" % saved_coco_path)
    # for file in val_path:
    #     shutil.copy(file.replace("json", "jpg"), "%simages/val2017/" % saved_coco_path)

    l2c_val = Lableme2CoCo()
    val_instance = l2c_val.to_coco(val_path)
    l2c_val.save_coco_json(val_instance, '%sannotations/instances_val2017.json' % saved_coco_path)

ext: py

reason: import numpy


text:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@author: Henning Lange (helange@uw.edu)
"""

import torch

from torch import nn
from torch import optim

import numpy as np
from scipy.ndimage import gaussian_filter

class koopman(nn.Module):

    r'''

    model_obj: an object that specifies the function f and how to optimize
               it. The object needs to implement numerous function. See
               below for some examples.

    sample_num: number of samples from temporally local loss used to
                reconstruct the global error surface.

    batch_size: Number of temporal snapshots processed by SGD at a time
                default = 32
                type: int

    parallel_batch_size: Number of temporaly local losses sampled in parallel.
                         This number should be as high as possible but low enough
                         to not cause memory issues.
                         default = 1000
                         type: int

    device: The device on which the computations are carried out.
            Example: cpu, cuda:0, or list of GPUs for multi-GPU usage, i.e. ['cuda:0', 'cuda:1']
            default = 'cpu'

    '''

    def __init__(self, model_obj, sample_num = 12, **kwargs):

        super(koopman, self).__init__()
        self.num_freq = model_obj.num_freq

        if 'device' in kwargs:
            self.device = kwargs['device']
            if type(kwargs['device']) == list:
                self.device = kwargs['device'][0]
                multi_gpu = True
            else:
                multi_gpu = False
        else:
            self.device = 'cpu'
            multi_gpu = False

        #Inital guesses for frequencies
        if self.num_freq == 1:
            self.omegas = torch.tensor([0.2], device = self.device)
        else:
            self.omegas = torch.linspace(0.01,0.5,self.num_freq, device = self.device)

        self.multi_gpu = multi_gpu

        self.parallel_batch_size = kwargs['parallel_batch_size'] if 'parallel_batch_size' in kwargs else 1000
        self.batch_size = kwargs['batch_size'] if 'batch_size' in kwargs else 32

        model_obj = model_obj.to(self.device)
        self.model_obj = nn.DataParallel(model_obj, device_ids= kwargs['device']) if multi_gpu else model_obj

        self.sample_num = sample_num

    def sample_error(self, xt, which):
        '''

        sample_error computes all temporally local losses within the first
        period, i.e. between [0,2pi/t]

        Parameters
        ----------
        xt : TYPE numpy.array
            Temporal data whose first dimension is time.
        i : TYPE int
            Index of the entry of omega

        Returns
        -------
        TYPE numpy.array
            Matrix that contains temporally local losses between [0,2pi/t]
            dimensions: [T, sample_num]

        '''

        num_samples = self.sample_num
        omega = self.omegas

        if type(xt) == np.ndarray:
            xt = torch.tensor(xt, device = self.device)

        t = torch.arange(xt.shape[0], device=self.device)+1

        errors = []
        batch = self.parallel_batch_size
        pi_block = torch.zeros((num_samples, len(omega)), device=self.device)
        pi_block[:, which] = torch.arange(0,num_samples)*np.pi*2/num_samples

        for i in range(int(np.ceil(xt.shape[0]/batch))):
            t_batch = t[i*batch:(i+1)*batch][:,None]
            wt = t_batch*omega[None]
            wt[:, which] = 0
            wt = wt[:,None] + pi_block[None]
            k = torch.cat([torch.cos(wt), torch.sin(wt)], -1)
            loss = self.model_obj(k, xt[i*batch:(i+1)*batch, None]).cpu().detach().numpy()
            errors.append(loss)

        if self.device.startswith('cuda'):
            torch.cuda.empty_cache()

        return np.concatenate(errors, axis=0)

    def reconstruct(self, errors, use_heuristic = True):

        e_fft = np.fft.fft(errors)
        E_ft = np.zeros(errors.shape[0]*self.sample_num, dtype=np.complex64)

        for t in range(1,e_fft.shape[0]+1):
            E_ft[np.arange(self.sample_num//2)*t] += e_fft[t-1,:self.sample_num//2]

        E_ft = np.concatenate([E_ft, np.conj(np.flip(E_ft, -1))])[:-1]
        E = np.real(np.fft.ifft(E_ft))

        if use_heuristic:
            E = -np.abs(E-np.median(E))
            #E = gaussian_filter(E, 5)

        return E, E_ft

    def fft(self, xt, i, verbose=False):
        '''

        fft first samples all temporaly local losses within the first period
        and then reconstructs the global error surface w.r.t. omega_i
        Parameters
        ----------
        xt : TYPE numpy.array
            Temporal data whose first dimension is time.
        i : TYPE int
            Index of the entry of omega
        verbose : TYPE boolean, optional
            DESCRIPTION. The default is False.
        Returns
        -------
        E : TYPE numpy.array
            Global loss surface in time domain.
        E_ft : TYPE
            Global loss surface in frequency domain.
        '''

        E, E_ft = self.reconstruct(self.sample_error(xt, i))
        omegas = np.linspace(0,1,len(E))

        idxs = np.argsort(E[:len(E_ft)//2])

        omegas_actual = self.omegas.cpu().detach().numpy()
        omegas_actual[i] = -1
        found = False

        j=0
        while not found:
            # The if statement avoids non-unique entries in omega and that the
            # frequencies are 0 (should be handle by bias term)
            if idxs[j]>1 and np.all(np.abs(2*np.pi/omegas_actual - 1/omegas[idxs[j]])>1):
                found = True
                if verbose:
                    print('Setting ',i,'to',1/omegas[idxs[j]])
                self.omegas[i] = torch.from_numpy(np.array([omegas[idxs[j]]]))
                self.omegas[i] *= 2*np.pi

            j+=1

        return E, E_ft

    def sgd(self, xt, verbose=False):
        '''

        sgd performs a single epoch of stochastic gradient descent on parameters
        of f (Theta) and frequencies omega

        Parameters
        ----------
        xt : TYPE numpy.array
            Temporal data whose first dimension is time.
        verbose : TYPE boolean, optional
            The default is False.

        Returns
        -------
        TYPE float
            Loss.

        '''

        batch_size = self.batch_size

        T = xt.shape[0]

        omega = nn.Parameter(self.omegas)

        opt = optim.SGD(self.model_obj.parameters(), lr=3e-3)
        opt_omega = optim.SGD([omega], lr=1e-7/T)

        T = xt.shape[0]
        t = torch.arange(T, device=self.device)

        losses = []

        for i in range(len(t)//batch_size):

            ts = t[i*batch_size:(i+1)*batch_size]
            o = torch.unsqueeze(omega, 0)
            ts_ = torch.unsqueeze(ts,-1).type(torch.get_default_dtype()) + 1

            xt_t = torch.tensor(xt[ts.cpu().numpy(),:], device=self.device)

            wt = ts_*o

            k = torch.cat([torch.cos(wt), torch.sin(wt)], -1)
            loss = torch.mean(self.model_obj(k, xt_t))

            opt.zero_grad()
            opt_omega.zero_grad()

            loss.backward()

            opt.step()
            opt_omega.step()

            losses.append(loss.cpu().detach().numpy())

        if verbose:
            print('Setting to', 2*np.pi/omega)

        self.omegas = omega.data

        return np.mean(losses)

    def fit(self, xt, iterations = 10, interval = 5, cutoff = np.inf, verbose=False):
        '''
        Given a dataset, this function alternatingly optimizes omega and
        parameters of f. Specifically, the algorithm performs interval many
        epochs, then updates all entries in omega. This process is repeated
        until iterations-many epochs have been performed

        Parameters
        ----------
        xt : TYPE numpy.array
            Temporal data whose first dimension is time.
        iterations : TYPE int, optional
            Total number of SGD epochs. The default is 10.
        interval : TYPE, optional
            The interval at which omegas are updated, i.e. if
            interval is 5, then omegas are updated every 5 epochs. The default is 5.
        verbose : TYPE boolean, optional
            DESCRIPTION. The default is False.

        Returns
        -------
        None.

        '''

        assert(len(xt.shape) > 1), 'Input data needs to be at least 2D'
        losses = []
        for i in range(iterations):

            if i%interval == 0 and i < cutoff:
                for k in range(self.num_freq):
                    self.fft(xt, k, verbose=verbose)

            if verbose:
                print('Iteration ',i)
                print(2*np.pi/self.omegas)

            l = self.sgd(xt, verbose=verbose)
            if verbose:
                print('Loss: ',l)
            losses.append(l)

        return losses

    def predict(self, T):
        '''
        Predicts the data from 1 to T.

        Parameters
        ----------
        T : TYPE int
            Prediction horizon

        Returns
        -------
        TYPE numpy.array
            xhat from 0 to T.

        '''

        t = torch.arange(T, device=self.device)+1
        ts_ = torch.unsqueeze(t,-1).type(torch.get_default_dtype())

        o = torch.unsqueeze(self.omegas, 0)
        k = torch.cat([torch.cos(ts_*o), torch.sin(ts_*o)], -1)

        if self.multi_gpu:
            mu = self.model_obj.module.decode(k)
        else:
            mu = self.model_obj.decode(k)

        return mu.cpu().detach().numpy()

class model_object(nn.Module):

    def __init__(self, num_freq):
        super(model_object, self).__init__()
        self.num_freq = num_freq

    def forward(self, y, x):
        '''
        Forward computes the error.

        Input:
            y: temporal snapshots of the linear system
                type: torch.tensor
                dimensions: [T, (batch,) num_frequencies ]

            x: data set
                type: torch.tensor
                dimensions: [T, ...]
        '''

        raise NotImplementedError()

    def decode(self, y):
        '''
        Evaluates f at temporal snapshots y

        Input:
            y: temporal snapshots of the linear system
                type: torch.tensor
                dimensions: [T, (batch,) num_frequencies ]

            x: data set
                type: torch.tensor
                dimensions: [T, ...]
        '''
        raise NotImplementedError()

class fully_connected_mse(model_object):

    def __init__(self, x_dim, num_freqs, n):
        super(fully_connected_mse, self).__init__(num_freqs)

        self.l1 = nn.Linear(2*num_freqs, n)
        self.l2 = nn.Linear(n,32)
        self.l3 = nn.Linear(32,x_dim)

    def decode(self, x):
        o1 = nn.Tanh()(self.l1(x))
        o2 = nn.Tanh()(self.l2(o1))
        o3 = self.l3(o2)

        return o3

    def forward(self, y, x):
        xhat = self.decode(y)
        return torch.mean((xhat-x)**2, dim=-1)

reason: import numpy,from scipy


text:
"""
Module to run tests on SciImgStack class
Requires files in Development suite
"""
import os

import pytest
import glob
import numpy as np

from pypeit.tests.tstutils import dev_suite_required, cooked_required
from pypeit.tests.tstutils import load_kast_blue_masters
from pypeit.spectrographs.util import load_spectrograph
from pypeit.images import buildimage
from pypeit.images import rawimage
from pypeit.images import pypeitimage
from pypeit.core import procimg
from pypeit import flatfield

def data_path(filename):
    data_dir = os.path.join(os.path.dirname(__file__), 'files')
    return os.path.join(data_dir, filename)

kast_blue = load_spectrograph('shane_kast_blue')
kast_par = kast_blue.default_pypeit_par()
keck_nires = load_spectrograph('keck_nires')

@pytest.fixture
@dev_suite_required
def shane_kast_blue_sci_files():
    return [os.path.join(os.getenv('PYPEIT_DEV'), 'RAW_DATA', 'shane_kast_blue', '600_4310_d55',
                         ifile) for ifile in ['b27.fits.gz', 'b28.fits.gz']]

@pytest.fixture
@dev_suite_required
def nires_sci_files():
    return [os.path.join(os.getenv('PYPEIT_DEV'), 'RAW_DATA', 'keck_nires', 'NIRES', ifile)
            for ifile in ['s180604_0089.fits.gz', 's180604_0092.fits.gz']]

@pytest.fixture
@dev_suite_required
def nires_bg_files():
    return [os.path.join(os.getenv('PYPEIT_DEV'), 'RAW_DATA', 'keck_nires', 'NIRES', ifile)
            for ifile in ['s180604_0090.fits.gz', 's180604_0091.fits.gz']]

@cooked_required
def test_instantiate_from_one(shane_kast_blue_sci_files):
    """
    Run on a single science frame
    """
    #
    det = 1
    # Load calibrations
    pixelflat = load_kast_blue_masters(pixflat=True)[0]
    bpm = kast_blue.empty_bpm(shane_kast_blue_sci_files[0], det)
    # Process steps -- Set in PypeItPar
    frame_par = kast_par['scienceframe']
    frame_par['process']['use_illumflat'] = False
    frame_par['process']['use_biasimage'] = False
    # Load
    rawImage = rawimage.RawImage(shane_kast_blue_sci_files[0], kast_blue, det)
    flatImages = flatfield.FlatImages(pixelflat_norm=pixelflat)
    pypeItImage = rawImage.process(frame_par['process'], flatimages=flatImages)

@cooked_required
def test_from_list(shane_kast_blue_sci_files):
    """
    Run on two frames
    """
    det = 1
    # Load calibrations
    pixelflat = load_kast_blue_masters(pixflat=True)[0]
    bpm = kast_blue.empty_bpm(shane_kast_blue_sci_files[0], det)
    # Do it
    flatImages = flatfield.FlatImages(pixelflat_norm=pixelflat)
    kast_par['scienceframe']['process']['use_illumflat'] = False
    kast_par['scienceframe']['process']['use_biasimage'] = False
    sciImg = buildimage.buildimage_fromlist(kast_blue, det, kast_par['scienceframe'],
                                            shane_kast_blue_sci_files, bpm=bpm,
                                            bias=None, flatimages=flatImages)
    # Test
    assert isinstance(sciImg, pypeitimage.PypeItImage)

@dev_suite_required
def test_proc_diff(nires_sci_files, nires_bg_files):
    """
    Run on near-IR frames
    """
    # Setup
    det = 1
    bpm = np.zeros((2048,1024), dtype=int)
    pixelflat = np.ones(bpm.shape, dtype=float)
    nires_par = keck_nires.default_pypeit_par()

    # Sci image
    flatImages = flatfield.FlatImages(pixelflat_norm=pixelflat)
    nires_par['scienceframe']['process']['use_illumflat'] = False
    nires_par['scienceframe']['process']['use_specillum'] = False
    sciImg = buildimage.buildimage_fromlist(keck_nires, det, nires_par['scienceframe'],
                                            nires_sci_files, bias=None, bpm=bpm,
                                            flatimages=flatImages)
    # Bg image
    bgImg = buildimage.buildimage_fromlist(keck_nires, det, nires_par['scienceframe'],
                                           nires_bg_files, bias=None, bpm=bpm,
                                           flatimages=flatImages)
    # Difference
    sciImg = sciImg.sub(bgImg, nires_par['scienceframe']['process'])
    # Test
    assert isinstance(sciImg, pypeitimage.PypeItImage)

max_stars_repo_name: brackham/PypeIt

max_issues_repo_name: brackham/PypeIt

max_forks_repo_name: brackham/PypeIt


text:
import numpy as np
import networkx as nx

from blockworld.towers.simple_tower import SimpleTower
from blockworld.blocks.simple_block import SimpleBlock
from blockworld.blocks.base_block import BaseBlock

class EmptyTower(SimpleTower):

    """
    Empty instance of a `Tower`.

    Used for a base tower in `builders.Builder`

    Attributes:
        base_dimensions (tuple(float)): The dimensions of the base.
        blocks (`nx.Graph`(`Block`)): A graph with only one element, the base.
    """

    def __init__(self, base_dims):
        self.base_dimensions = base_dims

    # Properties #

    @property
    def base(self):
        return self.blocks[0]['block']

    @property
    def base_dimensions(self):
        return self.base.dimensions

    @base_dimensions.setter
    def base_dimensions(self, ds):
        g = nx.DiGraph()
        base = BaseBlock(ds)
        g.add_node(0, block = base)
        self._graph = g

    @property
    def height(self):
        return self.base.mat[0, 2]

    # Methods #
    # def levels(self, block_ids = None):
    #     """
    #     Returns surface maps valid for block placement.
    #     """
    #     data = [(self.base.mat[0,2], [(0, self.base)])]
    #     return ([self.base], data)

max_stars_repo_name: belledon/blockworld

max_issues_repo_name: belledon/blockworld

max_forks_repo_name: belledon/blockworld

reason: import numpy,import networkx


text:
import cv2
import logging
import numpy as np
from typing import List, Union, Tuple, Dict

from mot.utils.config import Config
from mot.structures import Tracklet
from mot.utils.io import ImagesCapture
from mot.utils.hcc import hierarchical_cluster
from mot.tracker import build_tracker, Tracker, TrackerState

def _sample_tracklet_features(tracklet: Tracklet, n_feature_samples: int):
    recent_detections = tracklet.detection_history[-len(tracklet.feature_history):]
    p = np.array([detection.score for _, detection in recent_detections])

    all_recent_features = np.stack([feature[1]['openreid'] for feature in tracklet.feature_history])

    clusterIDs = hierarchical_cluster(all_recent_features, n_feature_samples, linkage_method='average',
                                      criterion='maxclust')
    tracklet_features = []
    for clusterID in np.unique(clusterIDs):
        inds = np.where(clusterIDs == clusterID)[0]
        feature = np.sum((all_recent_features[inds].T * (p[inds] / np.sum(p[inds]))).T, axis=0, keepdims=True)
        tracklet_features.append(feature)

    tracklet_features = np.vstack(tracklet_features)
    print('Shrinking target #{}\'s {} features into {}'.format(tracklet.id, len(M), len(tracklet_features)))
    return tracklet_features

class Identity:
    def __init__(self, globalID: int, camID: int, localID: int, tracklet: Tracklet, n_feature_samples: int = 8,
                 max_cluster_distance: float = 0.1):
        self.globalID: int = globalID
        self.end_time: int = tracklet.detection_history[-1][0]
        self.tracklets: Dict[Tuple[int, int], Tracklet] = {(camID, localID): tracklet}
        self.max_cluster_distance = max_cluster_distance
        self.n_feature_samples: int = n_feature_samples

        recent_detections = tracklet.detection_history[-len(tracklet.feature_history):]
        detecton_scores = np.array([detection.score for _, detection in recent_detections])
        best_ind = int(np.argmax(detecton_scores))
        self.images: Dict[int, np.ndarray] = {camID: tracklet.feature_history[best_ind][1]['patch'].copy()}

        if tracklet.sample_features is None:
            tracklet.update_sample_features()
        self.features = tracklet.sample_features

        del tracklet.feature_history
        del tracklet.feature

    def merge(self, others: List):
        for other in others:
            for k, v in other.tracklet_dict.items():
                self.tracklets[k] = v
                self.end_time = max(self.end_time, v.detection_history[-1][0])
        return self

    def add_tracklet(self, tracklet: Tracklet, camID: int):
        tracklet.globalID = self.globalID
        self.tracklets[(camID, tracklet.id)] = tracklet
        self.end_time = max(self.end_time, tracklet.last_active_frame_num)
        if tracklet.id not in self.images:
            recent_detections = tracklet.detection_history[-len(tracklet.feature_history):]
            detecton_scores = np.array([detection.score for _, detection in recent_detections])
            best_ind = int(np.argmax(detecton_scores))
            self.images[camID] = tracklet.feature_history[best_ind][1]['patch'].copy()

    def is_active(self):
        for _, tracklet in self.tracklets.items():
            if not tracklet.is_finished():
                return True
        return False

class MCTracker:
    # Infinite distance between local tracklets.
    INF = 1

    def __init__(self, stracker_config: Config, captures: Dict[int, Union[ImagesCapture, cv2.VideoCapture]],
                 cluster_freq: int = 60, max_ttl: int = 6000, max_local_overlap: int = 10,
                 max_reid_distance: float = 0.25, max_cluster_distance: float = 0.1, n_feature_samples: int = 8):
        # Single camera tracker for all cameras.
        self.stracker: Tracker = build_tracker(stracker_config)
        # Tracker states for switching.
        self.stracker_states: Dict[int, TrackerState] = {camID: TrackerState() for camID, _ in captures.items()}
        # Corresponding captures (ImagesCapture or cv2.VideoCapture objects).
        self.captures: Dict[int, Union[ImagesCapture, cv2.VideoCapture]] = captures
        # Global tracklet pool. globalID => Identity.
        self.identity_pool: Dict[int, Identity] = {}
        # Global ID for allocation
        self.max_id: int = 0
        # Global frame number.
        self.frame_num: int = 0
        # Frequency to perform global clustering.
        self.cluster_freq: int = cluster_freq
        # Maximum time-to-live of any tracklet.
        self.max_ttl: int = max_ttl
        # Maximum local overlap time.
        self.max_local_overlap = max_local_overlap
        # Re-identification distance threshold.
        self.max_reid_distance = max_reid_distance
        # Local clustering distance threshold.
        self.max_cluster_distance = max_cluster_distance
        # Number of feature samples for each new identity
        self.n_feature_samples = n_feature_samples
        # Feature gallery (instead of image gallery)
        self.feature_gallery = np.ndarray((0, 256), dtype=np.float)
        # Corresponding IDs for each line of feature gallery
        self.id_gallery = np.ndarray((0,), dtype=np.int)
        # Logger
        self.logger: logging.Logger = logging.getLogger('MTMCT')

    def tick(self):
        self.frame_num += 1
        for camID, cap in self.captures.items():

            ret, frame = cap.read()
            if not ret:
                return False
            self.stracker.state = self.stracker_states[camID]
            self.stracker.tick(frame)

        self.update_identity_pool()
        if self.frame_num % self.cluster_freq == 0:
            # self.update_tracklet_features()
            self.query_identities()
        return True

    def update_identity_pool(self):
        """
        Update identities with new tracklets added, or initiate new identities with single-cam tracklets.
        """
        for camID, stracker_state in self.stracker_states.items():
            while len(stracker_state.tracklets_finished) > 0:
                tracklet = stracker_state.tracklets_finished.pop()
                if tracklet.globalID >= 0:
                    # Tracklet has been re-identified
                    identity = self.identity_pool[tracklet.globalID]

                    # Update Identity features using this tracklet with randomly chosen features
                    # recent_detections = tracklet.detection_history[-len(tracklet.feature_history):]
                    # p = np.array([detection.score for _, detection in recent_detections])
                    # p = p / np.sum(p)
                    # inds = np.random.choice(range(len(tracklet.feature_history)), self.n_feature_samples, replace=False,
                    #                         p=p)
                    # new_features = np.stack([tracklet.feature_history[ind][1]['openreid'].copy() for ind in inds])

                    # New update method: Shrink the feature history size by HCC
                    if tracklet.sample_features is None:
                        tracklet.update_sample_features()
                    identity.features = np.vstack((identity.features, tracklet.sample_features))

                else:
                    # Tracklet hasn't been re-identified yet, start a new identity
                    if tracklet.time_lived >= self.n_feature_samples:
                        self.max_id += 1
                        tracklet.globalID = self.max_id
                        self.identity_pool[self.max_id] = Identity(self.max_id, camID, tracklet.id, tracklet,
                                                                   n_feature_samples=self.n_feature_samples)
                        self.logger.info('Initiating global ID #{} from tracklet (cam = {}, localID = {})'.format(
                            self.max_id, camID, tracklet.id
                        ))

    # def update_gallery_features(self):
    #     """
    #     Update feature gallery and corresponding features for queries.
    #     """
    #     if len(self.identity_pool) == 0:
    #         return
    #     features, globalIDs = [], []
    #     for globalID, identity in self.identity_pool.items():
    #         features.append(identity.features)
    #         globalIDs.extend([globalID] * len(identity.features))
    #     self.feature_gallery = np.vstack(features)
    #     self.id_gallery = np.array(globalIDs)
    #     assert len(self.feature_gallery) == len(self.id_gallery)

    def clear_inactive_identities(self):
        """
        Clear old identities.
        """
        globalIDs = list(self.identity_pool.keys())
        end_times = np.array([(self.frame_num if identity.is_active() else identity.end_time) for _, identity in
                              self.identity_pool.items()])
        inds_to_clear = np.where(self.frame_num - end_times > self.max_ttl)[0]
        inds_to_clear = np.sort(inds_to_clear)[::-1]
        identities = []
        for ind in inds_to_clear:
            globalID = globalIDs[int(ind)]
            identities.append((globalID, self.identity_pool.pop(globalID)))
        return identities

    def terminate(self):
        for camID, state in self.stracker_states.items():
            self.stracker.state = state
            self.stracker.terminate()
        self.update_identity_pool()
        # self.update_gallery_features()
        self.query_identities(query_all=True)

    def query_identities(self, query_all: bool = False):
        if len(self.identity_pool) == 0:
            return
        camIDs = []
        tracklets = []
        M = []
        # Build up query features
        for i, (camID, state) in enumerate(self.stracker_states.items()):
            for tracklet in state.tracklets_active:
                # Only consider tracklets that are long enough
                if tracklet.globalID == -1 and (query_all or len(tracklet.feature_history) >= self.n_feature_samples):
                    camIDs.append(camID)
                    tracklets.append(tracklet)

                    # Sample features from feature history
                    if tracklet.sample_features is None:
                        tracklet.update_sample_features()
                    tracklet_features = tracklet.sample_features

                    dists = []
                    for j, (globalID, identity) in enumerate(self.identity_pool.items()):
                        dists.append(np.average(1 - np.matmul(tracklet_features, identity.features.T).reshape(-1)))
                        for key, other in identity.tracklet_dict.items():
                            # No long overlap allowed
                            if tracklet.time_overlap(other) > self.max_local_overlap:
                                dists[-1] = 1
                                break
                    M.append(dists)

        # Perform greedy matching
        M = np.array(M)
        flattened = np.reshape(M, (-1))
        inds = list(np.argsort(flattened))
        row_ind, col_ind = [], []
        for ind in inds:
            if flattened[ind] > self.max_reid_distance:
                break
            row, col = ind // len(self.identity_pool), ind % len(self.identity_pool)
            if row not in row_ind and col not in col_ind:
                row_ind.append(row)
                col_ind.append(col)

        # Merge tracklets into identities
        globalIDs = list(self.identity_pool.keys())
        for row, col in zip(row_ind, col_ind):
            identity = self.identity_pool[globalIDs[col]]
            self.logger.info(
                'Local tracklet (cam = {}, localID = {}) matches global ID {} (distance = {})'.format(camIDs[row],
                                                                                tracklets[
                                                                                row].id,
                                                                                identity.globalID,
                                                                                M[row][col]))
            identity.add_tracklet(tracklets[row], camIDs[row])

    def _time_overlap(self, period1: Tuple[int, int], period2: Tuple[int, int]):
        overlap = min(period2[1], period1[1]) - max(period2[0], period1[0])
        return overlap if overlap > 0 else 0

    def _cosine_distance(self, vector1, vector2):
        return 1 - np.dot(vector1, vector2) / ((np.linalg.norm(vector1) * np.linalg.norm(vector2)) + 1e-16)

    def _identity_distance(self, identity1: Identity, identity2: Identity):
        for (cam1, localID1), tracklet1 in identity1.tracklets.items():
            for (cam2, localID2), tracklet2 in identity2.tracklets.items():
                if cam1 == cam2 and self._time_overlap(
                        (tracklet1.detection_history[0][0], tracklet1.detection_history[-1][0]),
                        (tracklet2.detection_history[0][0], tracklet2.detection_history[-1][0])
                ) > self.max_local_overlap:
                    return self.INF

        features1 = [tracklet.feature['openreid'] for (_, _), tracklet in identity1.tracklets.items()]
        features2 = [tracklet.feature['openreid'] for (_, _), tracklet in identity2.tracklets.items()]
        return max(
            [max([self._cosine_distance(feature1, feature2) for feature2 in features2]) for feature1 in features1])


text:
# Once for All: Train One Network and Specialize it for Efficient Deployment
# Han Cai, Chuang Gan, Tianzhe Wang, Zhekai Zhang, Song Han
# International Conference on Learning Representations (ICLR), 2020.

import time
import copy
import torch
import torch.nn as nn
import random
import numpy as np
import thop
from ofa.model_zoo import ofa_net
from ofa.imagenet_codebase.networks.proxyless_nets import MobileInvertedResidualBlock
from ofa.imagenet_codebase.modules.layers import *

__all__ = ['FLOPsTable']

def rm_bn_from_net(net):
	for m in net.modules():
		if isinstance(m, nn.BatchNorm2d) or isinstance(m, nn.BatchNorm1d):
			m.forward = lambda x: x

class FLOPsTable:
	def __init__(self, pred_type='flops', device='cuda:0', multiplier=1.2, batch_size=64, load_efficiency_table=None):
		assert pred_type in ['flops', 'latency']
		self.multiplier = multiplier
		self.pred_type = pred_type
		self.device = device
		self.batch_size = batch_size
		self.efficiency_dict = {}
		if load_efficiency_table is not None:
			self.efficiency_dict = np.load(load_efficiency_table, allow_pickle=True).item()
		else:
			self.build_lut(batch_size)

	@torch.no_grad()
	def measure_single_layer_latency(self, layer: nn.Module, input_size: tuple, warmup_steps=10, measure_steps=50):
		total_time = 0
		inputs = torch.randn(*input_size, device=self.device)
		layer.eval()
		rm_bn_from_net(layer)
		network = layer.to(self.device)
		torch.cuda.synchronize()
		for i in range(warmup_steps):
			network(inputs)
		torch.cuda.synchronize()

		torch.cuda.synchronize()
		st = time.time()
		for i in range(measure_steps):
			network(inputs)
		torch.cuda.synchronize()
		ed = time.time()
		total_time += ed - st

		latency = total_time / measure_steps * 1000

		return latency

	@torch.no_grad()
	def measure_single_layer_flops(self, layer: nn.Module, input_size: tuple):
		inputs = torch.randn(*input_size, device=self.device)
		network = layer.to(self.device)
		layer.eval()
		rm_bn_from_net(layer)
		flops, params = thop.profile(network, (inputs,), verbose=False)
		return flops / 1e6

	def build_lut(self, batch_size=1, resolutions=[160, 176, 192, 208, 224]):
		for resolution in resolutions:
			self.build_single_lut(batch_size, resolution)

		np.save('local_lut.npy', self.efficiency_dict)

	def build_single_lut(self, batch_size=1, base_resolution=224):
		print('Building the %s lookup table (resolution=%d)...' % (self.pred_type, base_resolution))
		# block, input_size, in_channels, out_channels, expand_ratio, kernel_size, stride, act, se
		configurations = [
			(ConvLayer, base_resolution, 3, 16, 3, 2, 'relu'),
			(MobileInvertedResidualBlock, base_resolution // 2, 16, 16, [1], [3, 5, 7], 1, 'relu', False),
			(MobileInvertedResidualBlock, base_resolution // 2, 16, 24, [3, 4, 6], [3, 5, 7], 2, 'relu', False),
			(MobileInvertedResidualBlock, base_resolution // 4, 24, 24, [3, 4, 6], [3, 5, 7], 1, 'relu', False),
			(MobileInvertedResidualBlock, base_resolution // 4, 24, 24, [3, 4, 6], [3, 5, 7], 1, 'relu', False),
			(MobileInvertedResidualBlock, base_resolution // 4, 24, 24, [3, 4, 6], [3, 5, 7], 1, 'relu', False),
			(MobileInvertedResidualBlock, base_resolution // 4, 24, 40, [3, 4, 6], [3, 5, 7], 2, 'relu', True),
			(MobileInvertedResidualBlock, base_resolution // 8, 40, 40, [3, 4, 6], [3, 5, 7], 1, 'relu', True),
			(MobileInvertedResidualBlock, base_resolution // 8, 40, 40, [3, 4, 6], [3, 5, 7], 1, 'relu', True),
			(MobileInvertedResidualBlock, base_resolution // 8, 40, 40, [3, 4, 6], [3, 5, 7], 1, 'relu', True),
			(MobileInvertedResidualBlock, base_resolution // 8, 40, 80, [3, 4, 6], [3, 5, 7], 2, 'h_swish', False),
			(MobileInvertedResidualBlock, base_resolution // 16, 80, 80, [3, 4, 6], [3, 5, 7], 1, 'h_swish', False),
			(MobileInvertedResidualBlock, base_resolution // 16, 80, 80, [3, 4, 6], [3, 5, 7], 1, 'h_swish', False),
			(MobileInvertedResidualBlock, base_resolution // 16, 80, 80, [3, 4, 6], [3, 5, 7], 1, 'h_swish', False),
			(MobileInvertedResidualBlock, base_resolution // 16, 80, 112, [3, 4, 6], [3, 5, 7], 1, 'h_swish', True),
			(MobileInvertedResidualBlock, base_resolution // 16, 112, 112, [3, 4, 6], [3, 5, 7], 1, 'h_swish', True),
			(MobileInvertedResidualBlock, base_resolution // 16, 112, 112, [3, 4, 6], [3, 5, 7], 1, 'h_swish', True),
			(MobileInvertedResidualBlock, base_resolution // 16, 112, 112, [3, 4, 6], [3, 5, 7], 1, 'h_swish', True),
			(MobileInvertedResidualBlock, base_resolution // 16, 112, 160, [3, 4, 6], [3, 5, 7], 2, 'h_swish', True),
			(MobileInvertedResidualBlock, base_resolution // 32, 160, 160, [3, 4, 6], [3, 5, 7], 1, 'h_swish', True),
			(MobileInvertedResidualBlock, base_resolution // 32, 160, 160, [3, 4, 6], [3, 5, 7], 1, 'h_swish', True),
			(MobileInvertedResidualBlock, base_resolution // 32, 160, 160, [3, 4, 6], [3, 5, 7], 1, 'h_swish', True),
			(ConvLayer, base_resolution // 32, 160, 960, 1, 1, 'h_swish'),
			(ConvLayer, 1, 960, 1280, 1, 1, 'h_swish'),
			(LinearLayer, 1, 1280, 1000, 1, 1),
		]

		efficiency_dict = {
			'mobile_inverted_blocks': [],
			'other_blocks': {}
		}

		for layer_idx in range(len(configurations)):
			config = configurations[layer_idx]
			op_type = config[0]
			if op_type == MobileInvertedResidualBlock:
				_, input_size, in_channels, out_channels, expand_list, ks_list, stride, act, se = config
				in_channels = int(round(in_channels * self.multiplier))
				out_channels = int(round(out_channels * self.multiplier))
				template_config = {
					'name': MobileInvertedResidualBlock.__name__,
					'mobile_inverted_conv': {
						'name': MBInvertedConvLayer.__name__,
						'in_channels': in_channels,
						'out_channels': out_channels,
						'kernel_size': kernel_size,
						'stride': stride,
						'expand_ratio': 0,
						# 'mid_channels': None,
						'act_func': act,
						'use_se': se,
					},
					'shortcut': {
						'name': IdentityLayer.__name__,
						'in_channels': in_channels,
						'out_channels': out_channels,
					} if (in_channels == out_channels and stride == 1) else None
				}
				sub_dict = {}
				for ks in ks_list:
					for e in expand_list:
						build_config = copy.deepcopy(template_config)
						build_config['mobile_inverted_conv']['expand_ratio'] = e
						build_config['mobile_inverted_conv']['kernel_size'] = ks

						layer = MobileInvertedResidualBlock.build_from_config(build_config)
						input_shape = (batch_size, in_channels, input_size, input_size)

						if self.pred_type == 'flops':
							measure_result = self.measure_single_layer_flops(layer, input_shape) / batch_size
						elif self.pred_type == 'latency':
							measure_result = self.measure_single_layer_latency(layer, input_shape)

						sub_dict[(ks, e)] = measure_result

				efficiency_dict['mobile_inverted_blocks'].append(sub_dict)

			elif op_type == ConvLayer:
				_, input_size, in_channels, out_channels, kernel_size, stride, activation = config
				in_channels = int(round(in_channels * self.multiplier))
				out_channels = int(round(out_channels * self.multiplier))
				build_config = {
					# 'name': ConvLayer.__name__,
					'in_channels': in_channels,
					'out_channels': out_channels,
					'kernel_size': kernel_size,
					'stride': stride,
					'dilation': 1,
					'groups': 1,
					'bias': False,
					'use_bn': True,
					'has_shuffle': False,
					'act_func': activation,
				}
				layer = ConvLayer.build_from_config(build_config)
				input_shape = (batch_size, in_channels, input_size, input_size)

				if self.pred_type == 'flops':
					measure_result = self.measure_single_layer_flops(layer, input_shape) / batch_size
				elif self.pred_type == 'latency':
					measure_result = self.measure_single_layer_latency(layer, input_shape)

				efficiency_dict['other_blocks'][layer_idx] = measure_result

			elif op_type == LinearLayer:
				_, input_size, in_channels, out_channels, kernel_size, stride = config
				in_channels = int(round(in_channels * self.multiplier))
				out_channels = int(round(out_channels * self.multiplier))
				build_config = {
					# 'name': LinearLayer.__name__,
					'in_features': in_channels,
					'out_features': out_channels
				}
				layer = LinearLayer.build_from_config(build_config)
				input_shape = (batch_size, in_channels)

				if self.pred_type == 'flops':
					measure_result = self.measure_single_layer_flops(layer, input_shape) / batch_size
				elif self.pred_type == 'latency':
					measure_result = self.measure_single_layer_latency(layer, input_shape)

				efficiency_dict['other_blocks'][layer_idx] = measure_result

			else:
				raise NotImplementedError

		self.efficiency_dict[base_resolution] = efficiency_dict
		print('Built the %s lookup table (resolution=%d)!' % (self.pred_type, base_resolution))
		return efficiency_dict

	def predict_efficiency(self, sample):
		input_size = sample.get('r', [224])
		input_size = input_size[0]
		assert 'ks' in sample and 'e' in sample and 'd' in sample
		assert len(sample['ks']) == len(sample['e']) and len(sample['ks']) == 20
		assert len(sample['d']) == 5
		total_stats = 0.
		for i in range(20):
			stage = i // 4
			depth_max = sample['d'][stage]
			depth = i % 4 + 1
			if depth > depth_max:
				continue
			ks, e = sample['ks'][i], sample['e'][i]
			total_stats += self.efficiency_dict[input_size]['mobile_inverted_blocks'][i + 1][(ks, e)]

		for key in self.efficiency_dict[input_size]['other_blocks']:
			total_stats += self.efficiency_dict[input_size]['other_blocks'][key]

		total_stats += self.efficiency_dict[input_size]['mobile_inverted_blocks'][0][(3, 1)]
		return total_stats

max_stars_repo_name: gatech-sysml/CompOFA


text:
import csv
import datetime
import h5py
import keras
import numpy as np
import os
import pandas as pd
import sys
import tensorflow as tf
import time

import localmodule

# Define constants.
data_dir = localmodule.get_data_dir()
dataset_name = localmodule.get_dataset_name()
folds = localmodule.fold_units()
models_dir = localmodule.get_models_dir()
n_input_hops = 104
bg_duration = 1800

# Read command-line arguments.
args = sys.argv[1:]
aug_kind_str = args[0]
test_unit_str = args[1]
trial_str = args[2]
predict_unit_str = args[3]

# Retrieve fold such that unit_str is in the test set.
fold = [f for f in folds if test_unit_str in f[0]][0]
test_units = fold[0]
training_units = fold[1]
validation_units = fold[2]

# Print header.
start_time = int(time.time())
print(str(datetime.datetime.now()) + " Start.")
print("Using NTT-like convnet for binary classification in " +
    dataset_name + " clips with PCEN input. ")
print("Training set: " + ", ".join(training_units) + ".")
print("Validation set: " + ", ".join(validation_units) + ".")
print("Test set: " + ", ".join(test_units) + ".")
print("")
print('h5py version: {:s}'.format(h5py.__version__))
print('keras version: {:s}'.format(keras.__version__))
print('numpy version: {:s}'.format(np.__version__))
print('tensorflow version: {:s}'.format(tf.__version__))
print("")

# Load model.
model_name = "pcen-ntt-convnet"
if not aug_kind_str == "none":
    model_name = "_".join([model_name, "aug-" + aug_kind_str])
model_dir = os.path.join(models_dir, model_name)
unit_dir = os.path.join(model_dir, test_unit_str)
trial_dir = os.path.join(unit_dir, trial_str)
network_name = "_".join(
    [dataset_name, model_name, test_unit_str, trial_str, "network"])
network_path = os.path.join(trial_dir, network_name + ".hdf5")
model = keras.models.load_model(network_path)

# Open PCEN container with h5py.
aug_str = "original"
pcen_dir = os.path.join(data_dir, "_".join([dataset_name, "clip-pcen"]))
original_pcen_dir = os.path.join(pcen_dir, aug_str)
hdf5_name = "_".join([dataset_name, aug_str, predict_unit_str])
hdf5_path = os.path.join(original_pcen_dir, hdf5_name + ".hdf5")
pcen_container = h5py.File(hdf5_path, "r")
pcen_group = pcen_container["pcen"]
keys = list(pcen_group.keys())

# Open background container with h5py.
bg_name = "_".join(
    [dataset_name, "clip-pcen-backgrounds"])
bg_dir = os.path.join(data_dir, bg_name)
T_str = "T-" + str(bg_duration).zfill(4)
T_dir = os.path.join(bg_dir, T_str)
bg_name = "_".join(
    [dataset_name, "clip-backgrounds",
     predict_unit_str, T_str + ".hdf5"])
bg_path = os.path.join(T_dir, bg_name)
bg_container = h5py.File(bg_path, "r")
bg_group = bg_container["pcen_background"]

# Create HDF5 container for predictions.
clip_predictions_name = "_".join([
    dataset_name,
    model_name,
    "test-" + test_unit_str,
    "predict-" + predict_unit_str,
    "clip-predictions"
])

# Create CSV file.
prediction_name = "_".join([dataset_name, model_name,
    "test-" + test_unit_str, trial_str, "predict-" + predict_unit_str,
    "clip-predictions"])
prediction_path = os.path.join(trial_dir, prediction_name + ".csv")
csv_file = open(prediction_path, 'w')
csv_writer = csv.writer(csv_file, delimiter=',')

# Create CSV header.
csv_header = ["Dataset", "Test unit", "Prediction unit", "Timestamp",
    "Key", "Predicted probability"]
csv_writer.writerow(csv_header)

# Loop over keys.
for key in keys:
    # Load logmelspec.
    X_pcen = pcen_group[key]

    # Trim logmelspec in time to required number of hops.
    X_width = X_pcen.shape[1]
    first_col = int((X_width-n_input_hops) / 2)
    last_col = int((X_width+n_input_hops) / 2)
    X_pcen = X_pcen[:, first_col:last_col]

    # Add trailing singleton dimension for Keras interoperability.
    X_pcen = X_pcen[np.newaxis, :, :, np.newaxis]

    # Define key for background container.
    bg_key = "_".join(key.split("_")[:-1])

    # Load background.
    X_bg = bg_group[bg_key].value.T
    X_bg = X_bg[np.newaxis, :, :]

    # Predict.
    predicted_probability = model.predict(
        {"spec_input": X_pcen, "bg_input": X_bg})[0, 0]

    # Store prediction as DataFrame row.
    key_split = key.split("_")
    timestamp_str = key_split[1]
    freq_str = key_split[2]
    ground_truth_str = key_split[3]
    aug_str = key_split[4]
    predicted_probability_str = "{:.16f}".format(predicted_probability)
    row = [dataset_name, test_unit_str, predict_unit_str, timestamp_str,
         freq_str, aug_str, key, ground_truth_str, predicted_probability_str]
    csv_writer.writerow(row)

# Close HDF5 containers.
pcen_container.close()

# Close CSV file.
csv_file.close()

# Print elapsed time.
print(str(datetime.datetime.now()) + " Finish.")
elapsed_time = time.time() - int(start_time)
elapsed_hours = int(elapsed_time / (60 * 60))
elapsed_minutes = int((elapsed_time % (60 * 60)) / 60)
elapsed_seconds = elapsed_time % 60.
elapsed_str = "{:>02}:{:>02}:{:>05.2f}".format(elapsed_hours,
                                               elapsed_minutes,
                                               elapsed_seconds)
print("Total elapsed time: " + elapsed_str + ".")


text:
import re, os, sys
from functools import reduce
from itertools import combinations as comb, permutations as perm, combinations_with_replacement as combr
from operator import itemgetter
from pprint import pprint
from math import *
from collections import defaultdict
import networkx as nx
import numpy as np

def dprint(d):
    pprint(dict(d))
def lmap(*args, **kwargs):
    return list(map(*args, **kwargs))
def lmapi(*args, **kwargs):
    return list(map(int, *args, **kwargs))
def enum(*args, **kwargs):
    return enumerate(*args, **kwargs)
def prod(l):
    return reduce(lambda a,b: a*b, l, 1)

def shift(orig, shifted, sx, sy):
    dx, dy = orig.shape
    sign = -1 if (sx < 0 or sy < 0) else 1
    if sign == 1:
        #print("pos", sx,sy,dx,dy)
        print( shifted[sx:,sy:][:dx,:dy] )
        return shifted[sx:,sy:][:dx,:dy] > orig
    else:
        if sx == 0: sx = dx
        if sy == 0: sy = dy
        print("neg", sx,sy,dx,dy)
        print( shifted[-sx:,-sy:][-dx:,-dy:] )
        return shifted[-sx:,-sy:][-dx:,-dy:] > orig

def basin_size(g, sink):
    ht = g.nodes(data="ht")
    basin = {sink}
    tree = nx.bfs_tree(g, sink)
    queue = [sink]
    visited = set()
    while queue:
        cur = queue.pop()
        basin.add(cur)
        visited.add(cur)
        #print("cur", cur, queue, ht[cur], list(tree.successors(cur)))
        for c in g.neighbors(cur):
            if c in visited: continue
            if ht[c] != 9:
                queue.append(c)
    #print("for sink", sink, "\tbasin", [ht[b] for b in basin], basin)
    return len(basin)

def solve(input_fname):
    heights = []
    with open(input_fname) as ifile:
        for line in ifile:
            heights.append(lmapi(line.strip()))
    hts = np.array(heights)
    phts = np.pad(hts, 1, constant_values=42)
    shfts = dict()
    dx, dy = hts.shape
    shfts["l"] = phts[ :,1:][:dx,:dy]
    shfts["r"] = phts[1:,1:][-dx:,:dy]
    shfts["u"] = phts[1:, :][:dx,:dy]
    shfts["d"] = phts[1:,1:][:dx,-dy:]
    #print(shfts)
    lows = reduce(lambda a,b: a & b, (s > hts for s in shfts.values()))
    #print(lows)

    lowhts = hts[lows]+1

    sinks = [(x,y) for x in range(dx) for y in range(dy) if lows[x,y]]
    g = nx.Graph()
    g.add_nodes_from(((x,y),{"ht":hts[x,y]}) for x in range(dx) for y in range(dy))

    for x in range(dx):
        for y in range(dy):
            if (x-1,y) in g: g.add_edge((x-1,y),(x,y))
            if (x,y-1) in g: g.add_edge((x,y-1),(x,y))
            if (x+1,y) in g: g.add_edge((x+1,y),(x,y))
            if (x,y+1) in g: g.add_edge((x,y+1),(x,y))

    print(sinks)
    print(g)

    sizes = []
    for sink in sinks:
        b = basin_size(g, sink)
        sizes.append(b)

    print(sizes)
    return prod(sorted(sizes, reverse=True)[:3])

    #return sum(lowhts)


text:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

import re
import requests
import shutil
import time
import os

from uuid import uuid4
from pathlib import Path

from .settings import VERBOSITY, SAMPLE_LABELS_URL, SAMPLE_IMAGES_URL

def fancy_print(to_print, verbosity=0):
    if VERBOSITY >= verbosity:
        print(to_print)

def append_image_data_chunk(image_frame: pd.DataFrame, file_to_append: str):
    # this function load a parquet data chunk and 'add' it to image_frame
    to_add = pd.read_parquet(file_to_append, engine="pyarrow")
    return pd.concat([image_frame, to_add.T], axis=0)

def load_and_combine_dataset(dataset_path: str, nums: [int]):
    # i wanted to make sure the memory for each image data files are released after the combined dataframe is built
    images = pd.DataFrame()
    # just in case where base_path has /
    if dataset_path[-1] == "/":
        dataset_path = dataset_path[:-1]

    for num in nums:
        images = append_image_data_chunk(images, f"{dataset_path}/dataset_{num}.parquet")

    labels = pd.concat([pd.read_csv(f"{dataset_path}/dataset_labels_{each}.csv",index_col=0) for each in nums], axis=0, ignore_index=True)

    return images, labels

def string_contains(__str: str, __words: list):
    # catching empty captioned images here
    if not __str:
        return []

    # i think using the regex module is better than my own half assed implementation
    __output = []
    for each_word in __words:
        result = re.findall(each_word, __str)
        if result.__len__() != 0:
            __output.append(each_word)
    return __output

def plot_image_batch(shared_id=None,batch_images=None):
    # plot out images for manual inspection
    grid_size = int(np.floor(np.sqrt(batch_images.shape[0]))) + 1
    fig, axs = plt.subplots(grid_size, grid_size, figsize=(6,6))  # <= note that axs is a ndarray shape grid,grid with subplots inside

    fig.suptitle(f"found {batch_images.shape[0]} images for id {shared_id}")
    print(f"identifying for id {shared_id}")

    # plot each image and i in subplot
    for i in range(batch_images.shape[0]):
        axs[i // grid_size, i % grid_size].imshow(batch_images[i])
        axs[i // grid_size, i % grid_size].set_title(f"{i}")

    plt.show()
    plt.close()
    time.sleep(0.5)  # <= this is here to stop image plot from being shown after text input

def download_sample_dataset(image_url=SAMPLE_IMAGES_URL, label_url=SAMPLE_LABELS_URL):
    # download and save to disk
    target_dir = "./data/sample"
    image_path = download_to_path(target_path=Path(target_dir + "/dataset_0.parquet"),target_url=image_url)
    label_path = download_to_path(target_path=Path(target_dir + "/dataset_labels_0.parquet"),target_url=label_url)
    # return path of dataset directory
    return target_dir

# getting files from hosted storage
def download_to_path(target_url, target_path, human_name="file"):
    if isinstance(target_path, str):
        target_path = Path(target_path)

    # ensure weights exist:
    if os.path.isfile(target_path):
        return fancy_print(f"existing file found at {target_path}, download skipped")
    else:
        fancy_print(f"downloading {human_name} from {target_url}")

    # ensure we have a dir to put downloaded file
    os.makedirs(target_path.parent, exist_ok=True)

    # do request
    with requests.get(target_url, stream=True) as r:
        with open(target_path, "wb") as file:
            shutil.copyfileobj(r.raw, file)

    fancy_print(f"saved {human_name} to {target_path}")
    return target_path

def new_short_id():
    return str(uuid4())[-12:]


text:
#!/usr/bin/env python
#-*- coding: utf-8 -*-

# Author: QuYingqi
# mail: cookiequ17@hotmail.com
# Created Time: 2017-12-12
import sys, os
import pickle
import numpy as np
import random
import torch
from torch.autograd import Variable
sys.path.append('../vocab')
sys.path.append('../tools')
import virtuoso
from args import get_args
args = get_args()

def create_seq_ranking_data(qa_data, word_vocab, rel_sep_vocab, rel_vocab, save_path):
    seqs = []
    seq_len = []
    pos_rel1 = []
    pos_rel2 = []
    neg_rel1 = []
    neg_rel2 = []
    pos_rel = []
    neg_rel = []
    pos_rel_len = []
    neg_rel_len = []
    batch_index = -1    # the index of sequence batches
    seq_index = 0       # sequence index within each batch
    pad_index = word_vocab.lookup(word_vocab.pad_token)

    rel_max_len = args.rel_maxlen

    data_list = pickle.load(open(qa_data, 'rb'))

    def get_separated_rel_id(relation):
        rel = relation.split('.')
        rel1 = '.'.join(rel[:-1])
        rel2 = rel[-1]
        rel_word = []
        rel[0] = rel[0][3:]
        for i in rel:
            rel_word.extend(i.split('_'))

        rel1_id = rel_sep_vocab[0].convert_to_index([rel1])[0]
        rel2_id = rel_sep_vocab[1].convert_to_index([rel2])[0]
        rel_id = word_vocab.convert_to_index(rel_word)
        return rel1_id, rel2_id, rel_id

    for data in data_list:
        tokens = data.question_pattern.split()
        can_rels = []
        if hasattr(data, 'cand_sub') and data.subject in data.cand_sub:
            can_rels = data.cand_rel
        else:
            can_subs = virtuoso.str_query_id(data.text_subject)
            for sub in can_subs:
                can_rels.extend(virtuoso.id_query_out_rel(sub))
            can_rels = list(set(can_rels))
        if data.relation in can_rels:
            can_rels.remove(data.relation)
        for i in range(len(can_rels), args.neg_size):
            tmp = random.randint(2, len(rel_vocab)-1)
            while(tmp in can_rels):
                tmp = random.randint(2, len(rel_vocab)-1)
            can_rels.append(rel_vocab.index2word[tmp])
        can_rels = random.sample(can_rels, args.neg_size)

        if seq_index % args.batch_size == 0:
            seq_index = 0
            batch_index += 1
            seqs.append(torch.LongTensor(args.batch_size, len(tokens)).fill_(pad_index))
            seq_len.append(torch.LongTensor(args.batch_size).fill_(1))
            pos_rel1.append(torch.LongTensor(args.batch_size).fill_(pad_index))
            pos_rel2.append(torch.LongTensor(args.batch_size).fill_(pad_index))
            neg_rel1.append(torch.LongTensor(args.neg_size, args.batch_size).fill_(pad_index))
            neg_rel2.append(torch.LongTensor(args.neg_size, args.batch_size).fill_(pad_index))
            pos_rel.append(torch.LongTensor(args.batch_size, rel_max_len).fill_(pad_index))
            pos_rel_len.append(torch.Tensor(args.batch_size).fill_(1))
            neg_rel.append(torch.LongTensor(args.neg_size, args.batch_size, rel_max_len).fill_(pad_index))
            neg_rel_len.append(torch.Tensor(args.neg_size, args.batch_size).fill_(1))
            print('batch: %d' %batch_index)

        seqs[batch_index][seq_index, 0:len(tokens)] = torch.LongTensor(word_vocab.convert_to_index(tokens))
        seq_len[batch_index][seq_index] = len(tokens)

        pos1, pos2, pos = get_separated_rel_id(data.relation)
        pos_rel1[batch_index][seq_index] = pos1
        pos_rel2[batch_index][seq_index] = pos2
        pos_rel[batch_index][seq_index, 0:len(pos)] = torch.LongTensor(pos)
        pos_rel_len[batch_index][seq_index] = len(pos)

        for j, can_rel in enumerate(can_rels):
            neg1, neg2, neg = get_separated_rel_id(can_rel)
            if not neg1 or not neg2:
                continue
            neg_rel1[batch_index][j,seq_index] = neg1
            neg_rel2[batch_index][j,seq_index] = neg2
            neg_rel[batch_index][j,seq_index, 0:len(neg)] = torch.LongTensor(neg)
            neg_rel_len[batch_index][j,seq_index] = len(neg)

        seq_index += 1

    torch.save((seqs, seq_len, pos_rel1, pos_rel2, neg_rel1, neg_rel2, pos_rel, pos_rel_len, neg_rel, neg_rel_len), save_path)

class SeqRankingLoader():
    def __init__(self, infile, device=-1):
        self.seqs, self.seq_len, self.pos_rel1, self.pos_rel2, self.neg_rel1, self.neg_rel2, self.pos_rel, self.pos_rel_len, self.neg_rel, self.neg_rel_len = torch.load(infile)
        self.batch_size = self.seqs[0].size(0)
        self.batch_num = len(self.seqs)

        if device >=0:
            for i in range(self.batch_num):
                self.seqs[i] = self.seqs[i].cuda(device)
                self.pos_rel1[i] = self.pos_rel1[i].cuda(device)
                self.pos_rel2[i] = self.pos_rel2[i].cuda(device)
                self.neg_rel1[i] = self.neg_rel1[i].cuda(device)
                self.neg_rel2[i] = self.neg_rel2[i].cuda(device)
                self.pos_rel[i] = self.pos_rel[i].cuda(device)
                self.neg_rel[i] = self.neg_rel[i].cuda(device)

    def next_batch(self, shuffle = True):
        if shuffle:
            indices = torch.randperm(self.batch_num)
        else:
            indices = range(self.batch_num)
        for i in indices:
            yield Variable(self.seqs[i]), self.seq_len[i], Variable(self.pos_rel1[i]), \
            Variable(self.pos_rel2[i]), Variable(self.neg_rel1[i]), Variable(self.neg_rel2[i]), \
            Variable(self.pos_rel[i]), self.pos_rel_len[i], Variable(self.neg_rel[i]),\
            self.neg_rel_len[i]

class CandidateRankingLoader():
    def __init__(self, qa_pattern_file, word_vocab, rel_sep_vocab, device=-1):
        self.qa_pattern = pickle.load(open(qa_pattern_file, 'rb'))
        self.batch_num = len(self.qa_pattern)
        self.word_vocab = word_vocab
        self.rel_sep_vocab = rel_sep_vocab
        self.pad_index = word_vocab.lookup(word_vocab.pad_token)
        self.device = device

    def get_separated_rel_id(self, relation):
        rel = relation.split('.')
        rel1 = '.'.join(rel[:-1])
        rel2 = rel[-1]
        rel_word = []
        rel[0] = rel[0][3:]
        for i in rel:
            rel_word.extend(i.split('_'))

        rel1_id = self.rel_sep_vocab[0].convert_to_index([rel1])[0]
        rel2_id = self.rel_sep_vocab[1].convert_to_index([rel2])[0]
        rel_id = self.word_vocab.convert_to_index(rel_word)
        return rel1_id, rel2_id, rel_id

    def next_question(self):
        for data in self.qa_pattern:
            if not hasattr(data, 'cand_rel'):
                self.batch_num -= 1
                continue

            tokens = data.question_pattern.split()
            seqs = torch.LongTensor(self.word_vocab.convert_to_index(tokens)).unsqueeze(0)
            seq_len = torch.LongTensor([len(tokens)])

            pos1, pos2, pos = self.get_separated_rel_id(data.relation)
            pos_rel1 = torch.LongTensor([pos1])
            pos_rel2 = torch.LongTensor([pos2])
            pos_rel = torch.LongTensor(args.rel_maxlen).fill_(self.pad_index)
            pos_rel[0:len(pos)] = torch.LongTensor(pos)
            pos_rel = pos_rel.unsqueeze(0)
            pos_len = torch.LongTensor([len(pos)])

            neg_rel1 = torch.LongTensor(len(data.cand_rel))
            neg_rel2 = torch.LongTensor(len(data.cand_rel))
            neg_rel = torch.LongTensor(len(data.cand_rel), args.rel_maxlen).fill_(self.pad_index)
            neg_len = torch.LongTensor(len(data.cand_rel))
            for idx, rel in enumerate(data.cand_rel):
                neg1, neg2, neg = self.get_separated_rel_id(rel)
                neg_rel1[idx] = neg1
                neg_rel2[idx] = neg2
                neg_rel[idx, 0:len(neg)] = torch.LongTensor(neg)
                neg_len[idx] = len(neg)
            neg_rel1.unsqueeze_(1)
            neg_rel2.unsqueeze_(1)
            neg_rel.unsqueeze_(1)

            if self.device>=0:
                seqs, pos_rel1, pos_rel2, neg_rel1, neg_rel2, pos_rel, neg_rel = \
                seqs.cuda(self.device), pos_rel1.cuda(self.device), pos_rel2.cuda(self.device), \
                neg_rel1.cuda(self.device), neg_rel2.cuda(self.device), pos_rel.cuda(self.device), \
                neg_rel.cuda(self.device)
            yield Variable(seqs), seq_len, Variable(pos_rel1), Variable(pos_rel2), Variable(neg_rel1), Variable(neg_rel2), Variable(pos_rel), pos_len, Variable(neg_rel), neg_len, data

if __name__ == '__main__':
    word_vocab = torch.load(args.vocab_file)
    rel_sep_vocab = torch.load(args.rel_vocab_file)
    rel_vocab = torch.load('../vocab/vocab.rel.pt')

    qa_data_path = '../entity_detection/results/QAData.label.%s.pkl'
    if not os.path.exists('data'):
        os.mkdir('data')

    create_seq_ranking_data(qa_data_path % 'valid', word_vocab, rel_sep_vocab, rel_vocab, args.valid_file)
    create_seq_ranking_data(qa_data_path % 'test', word_vocab, rel_sep_vocab, rel_vocab, args.test_file)
    create_seq_ranking_data(qa_data_path % 'train', word_vocab, rel_sep_vocab, rel_vocab, args.train_file)

max_issues_repo_name: chanshunli/kbqa-ar-smcnn

max_forks_repo_name: chanshunli/kbqa-ar-smcnn


text:
import numpy as np
import pdb
import matplotlib.pyplot as plt

def scatter_data_points(data):
    for dxd in data:
        for xxd,yxd in data[dxd]:
            plt.scatter(xxd,yxd,c=dxd,s=100)

def draw_pt_connections(point,data):
    # Connections from point to all of the points from data
    for xxd,yxd in data:
        plt.plot([point[0],xxd],[point[1],yxd], c='r', linewidth=1)
        plt.pause(0.01)

max_stars_repo_name: asbird/K-Nearest-Neighbours

max_issues_repo_name: asbird/K-Nearest-Neighbours

max_forks_repo_name: asbird/K-Nearest-Neighbours


text:
"""
This module include the cost-sensitive logistic regression method.
"""

# Authors: Alejandro Correa Bahnsen <al.bahnsen@gmail.com>
# License: BSD 3 clause

import numpy as np
import math
from scipy.optimize import minimize
from sklearn.base import BaseEstimator
# from sklearn.linear_model.logistic import _intercept_dot
from pyea import GeneticAlgorithmOptimizer
from ..metrics import cost_loss

# Not in sklearn 0.15, is in 0.16-git
#TODO: replace once sklearn 0.16 is release
# The one in sklearn 0.16 return yz instead of z, therefore,
# the impact on the code should be addressed before making the change.
def _intercept_dot(w, X):
    """Computes y * np.dot(X, w).

    It takes into consideration if the intercept should be fit or not.

    Parameters
    ----------
    w : ndarray, shape (n_features,) or (n_features + 1,)
        Coefficient vector.

    X : {array-like, sparse matrix}, shape (n_samples, n_features)
        Training data.

    """
    c = 0.
    if w.size == X.shape[1] + 1:
        c = w[-1]
        w = w[:-1]

    z = np.dot(X, w) + c
    return w, c, z

def _sigmoid(z):
    """ Private function that calculate the sigmoid function """
    return 1 / (1 + np.exp(-z))

def _logistic_cost_loss_i(w, X, y, cost_mat, alpha):
    n_samples = X.shape[0]
    w, c, z = _intercept_dot(w, X)
    y_prob = _sigmoid(z)

    out = cost_loss(y, y_prob, cost_mat) / n_samples
    out += .5 * alpha * np.dot(w, w)
    return out

def _logistic_cost_loss(w, X, y, cost_mat, alpha):
    """Computes the logistic loss.

    Parameters
    ----------
    w : array-like, shape (n_w, n_features,) or (n_w, n_features + 1,)
        Coefficient vector or matrix of coefficient.

    X : array-like, shape (n_samples, n_features)
        Training data.

    y : ndarray, shape (n_samples,)
        Array of labels.

    cost_mat : array-like of shape = [n_samples, 4]
        Cost matrix of the classification problem
        Where the columns represents the costs of: false positives, false negatives,
        true positives and true negatives, for each example.

    alpha : float
        Regularization parameter. alpha is equal to 1 / C.

    Returns
    -------
    out : float
        Logistic loss.
    """

    if w.shape[0] == w.size:
        # Only evaluating one w
        return _logistic_cost_loss_i(w, X, y, cost_mat, alpha)

    else:
        # Evaluating a set of w
        n_w = w.shape[0]
        out = np.zeros(n_w)

        for i in range(n_w):
            out[i] = _logistic_cost_loss_i(w[i], X, y, cost_mat, alpha)

        return out

class CostSensitiveLogisticRegression(BaseEstimator):
    """A example-dependent cost-sensitive Logistic Regression classifier.

    Parameters
    ----------

    C : float, optional (default=1.0)
        Inverse of regularization strength; must be a positive float.
        Like in support vector machines, smaller values specify stronger
        regularization.

    fit_intercept : bool, default: True
        Specifies if a constant (a.k.a. bias or intercept) should be
        added the decision function.

    max_iter : int
        Useful only for the ga and bfgs solvers. Maximum number of
        iterations taken for the solvers to converge.

    random_state : int seed, RandomState instance, or None (default)
        The seed of the pseudo random number generator to use when
        shuffling the data.

    solver : {'ga', 'bfgs'}
        Algorithm to use in the optimization problem.

    tol : float, optional
        Tolerance for stopping criteria.

    verbose : int, optional (default=0)
        Controls the verbosity of the optimization process.

    Attributes
    ----------
    `coef_` : array, shape (n_classes, n_features)
        Coefficient of the features in the decision function.

    `intercept_` : array, shape (n_classes,)
        Intercept (a.k.a. bias) added to the decision function.
        If `fit_intercept` is set to False, the intercept is set to zero.

    See also
    --------
    sklearn.tree.DecisionTreeClassifier

    References
    ----------

    .. [1] A. Correa Bahnsen, D.Aouada, B, Ottersten,
           `"Example-Dependent Cost-Sensitive Logistic Regression for Credit Scoring" <http://albahnsen.com/files/Example-Dependent%20Cost-Sensitive%20Logistic%20Regression%20for%20Credit%20Scoring_publish.pdf>`__,
           in Proceedings of the International Conference on Machine Learning and Applications,
           , 2014.

    Examples
    --------
    >>> from sklearn.linear_model import LogisticRegression
    >>> from sklearn.cross_validation import train_test_split
    >>> from costcla.datasets import load_creditscoring2
    >>> from costcla.models import CostSensitiveLogisticRegression
    >>> from costcla.metrics import savings_score
    >>> data = load_creditscoring2()
    >>> sets = train_test_split(data.data, data.target, data.cost_mat, test_size=0.33, random_state=0)
    >>> X_train, X_test, y_train, y_test, cost_mat_train, cost_mat_test = sets
    >>> y_pred_test_lr = LogisticRegression(random_state=0).fit(X_train, y_train).predict(X_test)
    >>> f = CostSensitiveLogisticRegression()
    >>> f.fit(X_train, y_train, cost_mat_train)
    >>> y_pred_test_cslr = f.predict(X_test)
    >>> # Savings using Logistic Regression
    >>> print(savings_score(y_test, y_pred_test_lr, cost_mat_test))
    0.00283419465107
    >>> # Savings using Cost Sensitive Logistic Regression
    >>> print(savings_score(y_test, y_pred_test_cslr, cost_mat_test))
    0.142872237978
    """
    def __init__(self,
                 C=1.0,
                 fit_intercept=True,
                 max_iter=100,
                 random_state=None,
                 solver='ga',
                 tol=1e-4,
                 verbose=0):

        self.C = C
        self.fit_intercept = fit_intercept
        self.max_iter = max_iter
        self.random_state = random_state
        self.solver = solver
        self.tol = tol
        self.coef_ = None
        self.intercept_ = 0.
        self.verbose = verbose

    def fit(self, X, y, cost_mat):
        """ Build a example-dependent cost-sensitive logistic regression from the training set (X, y, cost_mat)

        Parameters
        ----------
        X : array-like of shape = [n_samples, n_features]
            The input samples.

        y : array indicator matrix
            Ground truth (correct) labels.

        cost_mat : array-like of shape = [n_samples, 4]
            Cost matrix of the classification problem
            Where the columns represents the costs of: false positives, false negatives,
            true positives and true negatives, for each example.

        Returns
        -------
        self : object
            Returns self.
        """

        #TODO: Check input

        n_features = X.shape[1]
        if self.fit_intercept:
            w0 = np.zeros(n_features + 1)
        else:
            w0 = np.zeros(n_features)

        if self.solver == 'ga':
            #TODO: add n_jobs
            res = GeneticAlgorithmOptimizer(_logistic_cost_loss,
                                            w0.shape[0],
                                            iters=self.max_iter,
                                            type_='cont',
                                            n_chromosomes=100,
                                            per_mutations=0.25,
                                            n_elite=10,
                                            fargs=(X, y, cost_mat, 1. / self.C),
                                            range_=(-5, 5),
                                            n_jobs=1,
                                            verbose=self.verbose)
            res.fit()

        elif self.solver == 'bfgs':

            if self.verbose > 0:
                disp = True
            else:
                disp = False

            res = minimize(_logistic_cost_loss,
                           w0,
                           method='BFGS',
                           args=(X, y, cost_mat, 1. / self.C),
                           tol=self.tol,
                           options={'maxiter': self.max_iter, 'disp': disp})

        if self.fit_intercept:
            self.coef_ = res.x[:-1]
            self.intercept_ = res.x[-1]
        else:
            self.coef_ = res.x

    def predict_proba(self, X):
        """Probability estimates.

        The returned estimates.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        T : array-like, shape = [n_samples, 2]
            Returns the probability of the sample for each class in the model.
        """
        y_prob = np.zeros((X.shape[0], 2))
        y_prob[:, 1] = _sigmoid(np.dot(X, self.coef_) + self.intercept_)
        y_prob[:, 0] = 1 - y_prob[:, 1]
        return y_prob

    def predict(self, X, cut_point=0.5):
        """Predicted class.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        T : array-like, shape = [n_samples]
            Returns the prediction of the sample..
        """
        return np.floor(self.predict_proba(X)[:, 1] + (1 - cut_point))

max_stars_repo_name: eldrin/CostSensitiveClassification