<s> '''<STR_LIT>''' <EOL> import climate <EOL> import numpy as np <EOL> import theano . tensor as TT <EOL> from . import util <EOL> logging = climate . get_logger ( __name__ ) <EOL> class Loss ( util . Registrar ( str ( '<STR_LIT>' ) , ( ) , { } ) ) : <EOL> r'''<STR_LIT>''' <EOL> def __init__ ( self , target , weight = <NUM_LIT:1.> , weighted = False , output_name = '<STR_LIT>' ) : <EOL> self . weight = weight <EOL> self . _target = ( util . FLOAT_CONTAINERS [ target ] ( '<STR_LIT:target>' ) <EOL> if isinstance ( target , int ) else target ) <EOL> self . _weights = None <EOL> if weighted : <EOL> self . _weights = util . FLOAT_CONTAINERS [ self . _target . ndim ] ( '<STR_LIT>' ) <EOL> self . output_name = output_name <EOL> if '<STR_LIT::>' not in self . output_name : <EOL> self . output_name += '<STR_LIT>' <EOL> @ property <EOL> def variables ( self ) : <EOL> '''<STR_LIT>''' <EOL> result = [ self . _target ] <EOL> if self . _weights is not None : <EOL> result . append ( self . _weights ) <EOL> return result <EOL> def log ( self ) : <EOL> '''<STR_LIT>''' <EOL> logging . info ( '<STR_LIT>' , <EOL> self . weight , self . __class__ . __name__ , self . output_name ) <EOL> def __call__ ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> raise NotImplementedError <EOL> class MeanSquaredError ( Loss ) : <EOL> r'''<STR_LIT>''' <EOL> __extra_registration_keys__ = [ '<STR_LIT>' ] <EOL> def __call__ ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> err = outputs [ self . output_name ] - self . _target <EOL> if self . _weights is not None : <EOL> return ( self . _weights * err * err ) . sum ( ) / self . _weights . sum ( ) <EOL> return ( err * err ) . mean ( ) <EOL> class MeanAbsoluteError ( Loss ) : <EOL> r'''<STR_LIT>''' <EOL> __extra_registration_keys__ = [ '<STR_LIT>' ] <EOL> def __call__ ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> err = outputs [ self . output_name ] - self . _target <EOL> if self . _weights is not None : <EOL> return abs ( self . _weights * err ) . sum ( ) / self . _weights . sum ( ) <EOL> return abs ( err ) . mean ( ) <EOL> class GaussianLogLikelihood ( Loss ) : <EOL> r'''<STR_LIT>''' <EOL> __extra_registration_keys__ = [ '<STR_LIT>' ] <EOL> def __init__ ( self , mean_name = '<STR_LIT>' , covar_name = '<STR_LIT>' , covar_eps = <NUM_LIT> , ** kwargs ) : <EOL> self . mean_name = mean_name <EOL> if '<STR_LIT::>' not in self . mean_name : <EOL> self . mean_name += '<STR_LIT>' <EOL> self . covar_name = covar_name <EOL> if '<STR_LIT::>' not in self . covar_name : <EOL> self . covar_name += '<STR_LIT>' <EOL> self . covar_eps = covar_eps <EOL> super ( GaussianLogLikelihood , self ) . __init__ ( ** kwargs ) <EOL> def log ( self ) : <EOL> '''<STR_LIT>''' <EOL> logging . info ( '<STR_LIT>' , <EOL> self . weight , self . __class__ . __name__ , <EOL> self . mean_name , self . covar_name ) <EOL> def __call__ ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> mean = outputs [ self . mean_name ] <EOL> covar = outputs [ self . covar_name ] <EOL> prec = <NUM_LIT:1> / ( abs ( covar ) + self . covar_eps ) <EOL> eta = mean * prec <EOL> logpi = TT . cast ( mean . shape [ - <NUM_LIT:1> ] * np . log ( <NUM_LIT:2> * np . pi ) , '<STR_LIT>' ) <EOL> logdet = TT . log ( prec . sum ( axis = - <NUM_LIT:1> ) ) <EOL> const = logpi - logdet + ( eta * prec * eta ) . sum ( axis = - <NUM_LIT:1> ) <EOL> squared = ( self . _target * prec * self . _target ) . sum ( axis = - <NUM_LIT:1> ) <EOL> nll = <NUM_LIT:0.5> * ( const + squared ) - ( eta * self . _target ) . sum ( axis = - <NUM_LIT:1> ) <EOL> return nll . mean ( ) <EOL> class MaximumMeanDiscrepancy ( Loss ) : <EOL> r'''<STR_LIT>''' <EOL> __extra_registration_keys__ = [ '<STR_LIT>' ] <EOL> @ staticmethod <EOL> def gaussian ( bw ) : <EOL> def kernel ( x , y ) : <EOL> r = x . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' , * tuple ( range ( <NUM_LIT:1> , x . ndim ) ) ) <EOL> return TT . exp ( TT . sqr ( r - y ) . sum ( axis = - <NUM_LIT:1> ) / - bw ) <EOL> return kernel <EOL> def __init__ ( self , kernel = <NUM_LIT:1> , ** kwargs ) : <EOL> super ( MaximumMeanDiscrepancy , self ) . __init__ ( ** kwargs ) <EOL> if isinstance ( kernel , ( int , float ) ) : <EOL> kernel = MaximumMeanDiscrepancy . gaussian ( kernel ) <EOL> self . kernel = kernel <EOL> def __call__ ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> output = outputs [ self . output_name ] <EOL> xx = self . kernel ( self . _target , self . _target ) <EOL> xy = self . kernel ( self . _target , output ) <EOL> yy = self . kernel ( output , output ) <EOL> return xx . mean ( ) - <NUM_LIT:2> * xy . mean ( ) + yy . mean ( ) <EOL> class KullbackLeiblerDivergence ( Loss ) : <EOL> r'''<STR_LIT>''' <EOL> __extra_registration_keys__ = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __call__ ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> output = outputs [ self . output_name ] <EOL> eps = <NUM_LIT> <EOL> t = TT . clip ( self . _target , eps , <NUM_LIT:1> - eps ) <EOL> kl = t * TT . log ( t / TT . clip ( output , eps , <NUM_LIT:1> - eps ) ) <EOL> if self . _weights is not None : <EOL> return abs ( self . _weights * kl ) . sum ( ) / self . _weights . sum ( ) <EOL> return abs ( kl ) . mean ( ) <EOL> class CrossEntropy ( Loss ) : <EOL> r'''<STR_LIT>''' <EOL> __extra_registration_keys__ = [ '<STR_LIT>' ] <EOL> def __init__ ( self , target , weight = <NUM_LIT:1.> , weighted = False , output_name = '<STR_LIT>' ) : <EOL> super ( CrossEntropy , self ) . __init__ ( <EOL> target , weight = weight , weighted = weighted , output_name = output_name ) <EOL> self . _target = util . INT_CONTAINERS [ target ] ( '<STR_LIT:target>' ) <EOL> def __call__ ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> output = outputs [ self . output_name ] <EOL> k = output . shape [ - <NUM_LIT:1> ] <EOL> n = TT . prod ( output . shape ) // k <EOL> prob = output . reshape ( ( n , k ) ) [ TT . arange ( n ) , self . _target . reshape ( ( n , ) ) ] <EOL> nlp = - TT . log ( TT . clip ( prob , <NUM_LIT> , <NUM_LIT:1> ) ) <EOL> if self . _weights is not None : <EOL> return ( self . _weights . reshape ( ( n , ) ) * nlp ) . sum ( ) / self . _weights . sum ( ) <EOL> return nlp . mean ( ) <EOL> def accuracy ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> output = outputs [ self . output_name ] <EOL> predict = TT . argmax ( output , axis = - <NUM_LIT:1> ) <EOL> correct = TT . eq ( predict , self . _target ) <EOL> acc = correct . mean ( ) <EOL> if self . _weights is not None : <EOL> acc = ( self . _weights * correct ) . sum ( ) / self . _weights . sum ( ) <EOL> return acc <EOL> class Hinge ( CrossEntropy ) : <EOL> r'''<STR_LIT>''' <EOL> __extra_registration_keys__ = [ ] <EOL> def __call__ ( self , outputs ) : <EOL> '''<STR_LIT>''' <EOL> output = outputs [ self . output_name ] <EOL> k = output . shape [ - <NUM_LIT:1> ] <EOL> n = TT . prod ( output . shape ) // k <EOL> output = output . reshape ( ( n , k ) ) <EOL> true = output [ TT . arange ( n ) , self . _target . reshape ( ( n , ) ) ] <EOL> err = TT . maximum ( <NUM_LIT:0> , ( output - true [ : , None ] ) . max ( axis = - <NUM_LIT:1> ) ) <EOL> if self . _weights is not None : <EOL> return ( self . _weights . reshape ( ( n , ) ) * err ) . sum ( ) / self . _weights . sum ( ) <EOL> return err . mean ( ) </s>
