<s> from collections import OrderedDict <EOL> import logging <EOL> from picklable_itertools . extras import equizip <EOL> import theano <EOL> from theano import tensor <EOL> from blocks . utils import dict_subset <EOL> from blocks . monitoring . aggregation import ( _DataIndependent , Mean , <EOL> TakeLast , MonitoredQuantity ) <EOL> from blocks . graph import ComputationGraph <EOL> from blocks . utils import reraise_as <EOL> logger = logging . getLogger ( __name__ ) <EOL> class MonitoredQuantityBuffer ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , quantities ) : <EOL> self . quantities = quantities <EOL> requires = [ ] <EOL> for quantity in quantities : <EOL> requires += quantity . requires <EOL> self . requires = list ( set ( requires ) ) <EOL> self . _initialized = False <EOL> self . quantity_names = [ q . name for q in self . quantities ] <EOL> self . _computation_graph = ComputationGraph ( self . requires ) <EOL> self . inputs = self . _computation_graph . inputs <EOL> def initialize_quantities ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _initialized = True <EOL> for quantity in self . quantities : <EOL> quantity . initialize ( ) <EOL> def get_aggregated_values ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _initialized : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> ret_vals = [ q . get_aggregated_value ( ) for q in self . quantities ] <EOL> return dict ( zip ( self . quantity_names , ret_vals ) ) <EOL> def aggregate_quantities ( self , numerical_values ) : <EOL> """<STR_LIT>""" <EOL> if not self . _initialized : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> for quantity in self . quantities : <EOL> quantity . aggregate ( <EOL> * [ numerical_values [ self . requires . index ( requirement ) ] <EOL> for requirement in quantity . requires ] ) <EOL> class AggregationBuffer ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , variables , use_take_last = False ) : <EOL> self . variables = variables <EOL> self . use_take_last = use_take_last <EOL> self . variable_names = [ v . name for v in self . variables ] <EOL> if len ( set ( self . variable_names ) ) < len ( self . variables ) : <EOL> duplicates = [ ] <EOL> for vname in set ( self . variable_names ) : <EOL> if self . variable_names . count ( vname ) > <NUM_LIT:1> : <EOL> duplicates . append ( vname ) <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" . format ( '<STR_LIT:U+002CU+0020>' . join ( duplicates ) ) ) <EOL> self . _computation_graph = ComputationGraph ( self . variables ) <EOL> self . inputs = self . _computation_graph . inputs <EOL> self . _initialized = False <EOL> self . _create_aggregators ( ) <EOL> self . _compile ( ) <EOL> def _create_aggregators ( self ) : <EOL> """<STR_LIT>""" <EOL> self . initialization_updates = [ ] <EOL> self . accumulation_updates = [ ] <EOL> self . readout_variables = OrderedDict ( ) <EOL> for v in self . variables : <EOL> logger . debug ( '<STR_LIT>' , v . name ) <EOL> if not hasattr ( v . tag , '<STR_LIT>' ) : <EOL> if not self . _computation_graph . has_inputs ( v ) : <EOL> scheme = ( TakeLast if self . use_take_last <EOL> else _DataIndependent ) <EOL> logger . debug ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , scheme . __name__ , v . name ) <EOL> v . tag . aggregation_scheme = scheme ( v ) <EOL> else : <EOL> logger . debug ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , v . name ) <EOL> v . tag . aggregation_scheme = Mean ( v , <NUM_LIT:1.0> ) <EOL> aggregator = v . tag . aggregation_scheme . get_aggregator ( ) <EOL> self . initialization_updates . extend ( <EOL> aggregator . initialization_updates ) <EOL> self . accumulation_updates . extend ( aggregator . accumulation_updates ) <EOL> self . readout_variables [ v . name ] = aggregator . readout_variable <EOL> def _compile ( self ) : <EOL> """<STR_LIT>""" <EOL> logger . debug ( "<STR_LIT>" ) <EOL> if self . initialization_updates : <EOL> self . _initialize_fun = theano . function ( <EOL> [ ] , [ ] , updates = self . initialization_updates ) <EOL> else : <EOL> self . _initialize_fun = None <EOL> self . _readout_fun = theano . function ( <EOL> [ ] , [ tensor . as_tensor_variable ( v ) <EOL> for v in self . readout_variables . values ( ) ] ) <EOL> logger . debug ( "<STR_LIT>" ) <EOL> def initialize_aggregators ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _initialized = True <EOL> if self . _initialize_fun is not None : <EOL> self . _initialize_fun ( ) <EOL> def get_aggregated_values ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _initialized : <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> ret_vals = self . _readout_fun ( ) <EOL> return OrderedDict ( equizip ( self . variable_names , ret_vals ) ) <EOL> class DatasetEvaluator ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , variables , updates = None ) : <EOL> theano_variables = [ ] <EOL> monitored_quantities = [ ] <EOL> for variable in variables : <EOL> if isinstance ( variable , MonitoredQuantity ) : <EOL> monitored_quantities . append ( variable ) <EOL> else : <EOL> theano_variables . append ( variable ) <EOL> self . theano_variables = theano_variables <EOL> self . monitored_quantities = monitored_quantities <EOL> variable_names = [ v . name for v in variables ] <EOL> if len ( set ( variable_names ) ) < len ( variables ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . theano_buffer = AggregationBuffer ( theano_variables ) <EOL> self . monitored_quantities_buffer = MonitoredQuantityBuffer ( <EOL> monitored_quantities ) <EOL> self . updates = updates <EOL> self . _compile ( ) <EOL> def _compile ( self ) : <EOL> """<STR_LIT>""" <EOL> inputs = [ ] <EOL> outputs = [ ] <EOL> updates = None <EOL> if self . theano_buffer . accumulation_updates : <EOL> updates = OrderedDict ( ) <EOL> updates . update ( self . theano_buffer . accumulation_updates ) <EOL> inputs += self . theano_buffer . inputs <EOL> if self . updates : <EOL> if updates is None : <EOL> updates = self . updates <EOL> else : <EOL> updates . update ( self . updates ) <EOL> inputs += self . monitored_quantities_buffer . inputs <EOL> outputs = self . monitored_quantities_buffer . requires <EOL> if inputs != [ ] : <EOL> self . unique_inputs = list ( set ( inputs ) ) <EOL> self . _aggregate_fun = theano . function ( self . unique_inputs , <EOL> outputs , <EOL> updates = updates ) <EOL> else : <EOL> self . _aggregate_fun = None <EOL> def initialize_aggregators ( self ) : <EOL> self . theano_buffer . initialize_aggregators ( ) <EOL> self . monitored_quantities_buffer . initialize_quantities ( ) <EOL> def process_batch ( self , batch ) : <EOL> try : <EOL> input_names = [ v . name for v in self . unique_inputs ] <EOL> batch = dict_subset ( batch , input_names ) <EOL> except KeyError : <EOL> reraise_as ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( input_names ) ) <EOL> if self . _aggregate_fun is not None : <EOL> numerical_values = self . _aggregate_fun ( ** batch ) <EOL> self . monitored_quantities_buffer . aggregate_quantities ( <EOL> numerical_values ) <EOL> def get_aggregated_values ( self ) : <EOL> values = self . theano_buffer . get_aggregated_values ( ) <EOL> values . update ( <EOL> self . monitored_quantities_buffer . get_aggregated_values ( ) ) <EOL> return values <EOL> def evaluate ( self , data_stream ) : <EOL> """<STR_LIT>""" <EOL> self . initialize_aggregators ( ) <EOL> if self . _aggregate_fun is not None : <EOL> for batch in data_stream . get_epoch_iterator ( as_dict = True ) : <EOL> self . process_batch ( batch ) <EOL> else : <EOL> logger . debug ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> return self . get_aggregated_values ( ) </s>
