Package dimer :: Package nnet :: Module monitor
[hide private]
[frames] | no frames]

Source Code for Module dimer.nnet.monitor

  1   
  2  import logging 
  3  from operator import attrgetter, concat 
  4  from collections import namedtuple 
  5   
  6  import numpy as np 
  7  import pandas as pd 
  8   
  9  from .. import archive 
 10   
 11  log = logging.getLogger(__name__) 
12 13 -class Monitor( object ):
14 """ abstract class keep track of a set of parameters in the model or the 15 learning process""" 16 17 ftype_frm = {int : "%d", float : "%.6f", str : "%s"} 18 fzero = {int : 0, float : 0.0, str : "NA"} 19 20 @property
21 - def csv(self, sep=","):
22 return sep.join( [self.ftype_frm[t] for t in self._ftypes] ) % self
23 24 @classmethod
25 - def _empty(cls):
26 return tuple.__new__(cls, [cls.fzero[t] for t in cls._ftypes])
27 28 @property
29 - def report(self):
30 return self._report_frm.format(**self._asdict())
31 32 @classmethod
33 - def _has_changed(cls, what, patience, data, summ_f, cmp_f):
34 """compares a summary of the last `patience` values defined by the `what` field 35 with the `patience`-1 value""" 36 37 38 if len(data) < patience + 1: 39 raise ValueError("not enough history (%d) for this patience (%d)" % (len(data), patience)) 40 41 what_f = attrgetter(what) 42 43 ##extract the values defined by `what` from the last patience epochs 44 patience_best = summ_f(map(what_f, data[-patience:])) 45 ##extract the value just before the last `patience` items 46 history_mark = what_f(data[-patience-1]) 47 48 assert type(patience_best) == type(history_mark) 49 log.debug("%f, [%f]" % (history_mark, patience_best)) 50 51 return cmp_f(patience_best, history_mark)
52 53 @classmethod
54 - def rel_diff(cls, init, final):
55 "(final-init)/max(final, init)" 56 57 M = float( max(final, init) ) 58 if M: 59 return (final-init)/M 60 return 0.
61 62 @classmethod
63 - def is_min_up(cls, what, memory, data):
64 return cls._has_changed(what, memory, data, min, lambda summarized, mark: summarized > mark)
65 66 @classmethod
67 - def is_min_down(cls, what, memory, data):
68 return cls._has_changed(what, memory, data, min, lambda summarized, mark: summarized < mark)
69 70 @classmethod
71 - def is_min_still(cls, what, memory, data):
72 return cls._has_changed(what, memory, data, min, lambda summarized, mark: summarized == mark)
73 74 @classmethod
75 - def is_max_up(cls, what, memory, data):
76 return cls._has_changed(what, memory, data, max, lambda summarized, mark: summarized > mark)
77 78 @classmethod
79 - def is_max_down(cls, what, memory, data):
80 return cls._has_changed(what, memory, data, max, lambda summarized, mark: summarized < mark)
81 82 @classmethod
83 - def is_max_still(cls, what, memory, data):
84 return cls._has_changed(what, memory, data, max, lambda summarized, mark: summarized == mark)
85 86 @classmethod
87 - def _dump(cls, path, data):
88 with open(path, 'w') as fd: 89 log.info("saving %s log to %s ..." % (str(cls), fd.name)) 90 fd.write(",".join( cls._fields )+"\n") 91 map(lambda r: fd.write("%s\n" % r.csv), data)
92 93 @classmethod
94 - def _archive_dump(cls, path, train_run_name, data):
95 cls_name = str(cls).split(".")[-1][:-2] 96 key = "%s/%s/%s" % (archive.basename(path), train_run_name, cls_name) 97 obj = pd.DataFrame.from_records(data, columns=cls._fields) 98 99 archive.save_object( archive.archname(path), key, obj )
100
101 102 -class DaeLearnMonitor(Monitor, namedtuple("learnmonitor", "epoch lrate traincost validcost")):
103 _ftypes = (int, float, float, float) 104 _report_frm = ("Epoch {epoch} / lrate: {lrate:.6f}\n\t" 105 "Cost: {traincost:.6f} / {validcost:.6f} \n\t") 106 107 @classmethod
108 - def _from_fs(cls, ds, mtr, epoch, cost_f):
109 train_batches = ds.train_batches 110 valid_batches = ds.valid_batches 111 112 ct = np.array( map(cost_f, train_batches) ).mean() 113 cv = np.array( map(cost_f, valid_batches) ).mean() 114 115 return cls._make( [epoch, mtr.lr, ct, cv] )
116
117 118 -class LearnMonitor(Monitor, namedtuple("learnmonitor", "epoch lrate traincost trainCE trainMC validcost validCE validMC") ):
119 """learning stats""" 120 121 _ftypes = (int, float, 122 float, float, 123 float, float, 124 float, float) 125 _report_frm = ("Epoch {epoch} / lrate: {lrate:.6f}\n\t" 126 "Cost: {traincost:.6f} / {validcost:.6f} \n\t" 127 "Cross entropy: {trainCE:.6f} / {validCE:.6f} \n\t" 128 "Missclass.: {trainMC:.2%} / {validMC:.2%}") 129 130 @classmethod
131 - def _from_fs(cls, ds, mtr, epoch, cost_f, ce_f, mcl_f):
132 train_batches = ds.train_batches 133 valid_batches = ds.valid_batches 134 135 train_s = ds.batch_size * len(ds.train_batches) 136 valid_s = ds.batch_size * len(ds.valid_batches) 137 a = [np.mean(np.array(map(cost_f, train_batches))), 138 np.mean(np.array(map(ce_f, train_batches))), 139 sum(map(mcl_f, train_batches)) / float(train_s), 140 141 np.mean(np.array(map(cost_f, valid_batches))), 142 np.mean(np.array(map(ce_f, valid_batches))), 143 sum(map(mcl_f, valid_batches)) / float(valid_s)] 144 145 return cls._make( [epoch, mtr.lr] + a )
146
147 -class RegrLearnMonitor(Monitor, namedtuple("learnmonitor", "epoch lrate traincost validcost") ):
148 """learning stats for a linear regression """ 149 150 _ftypes = (int, float, float, float) 151 _report_frm = ("Epoch {epoch} / lrate: {lrate:.6f}\n\t" 152 "Cost: {traincost:.6f} / {validcost:.6f}") 153 154 @classmethod
155 - def _from_fs(cls, ds, mtr, epoch, cost_f, train_batches, valid_batches):
156 a = [np.mean(np.array(map(cost_f, train_batches))), 157 np.mean(np.array(map(cost_f, valid_batches)))] 158 return cls._make( [epoch, mtr.lr] + a )
159
160 161 -class WeightMonitor( Monitor, namedtuple("w_monitor", "epoch layer wshp wmin wmean wmedian wsd wmax bshp bmin bmean bmedian bsd bmax") ):
162 """weight and activity information on the network""" 163 164 _ftypes = (int, int, 165 str, float, float, float, float, float, 166 str, float, float, float, float, float) 167 _report_frm = ("{epoch:d} {layer:d} " 168 "W({wshp:s}): {wmin:.6f} {wmean:.6f} {wmedian:.6f} {wsd:.6f} {wmax:.6f}\n\t" 169 "B({bshp:s}): {bmin:.6f} {bmean:.6f} {bmedian:.6f} {bsd:.6f} {bmax:.6f}") 170 171 @classmethod
172 - def _from_model(cls, epoch, l, model):
173 def stat_record(a): 174 return map(lambda f: f(a), (np.min, np.mean, np.median, np.std, np.max))
175 176 def shape_str(a): 177 return str(np.prod(a.shape))
178 179 w_lst = model[l].get_weights() 180 w_shapes = map(shape_str, w_lst) 181 w_stats = map(stat_record, w_lst) 182 w_rec = map(lambda (a,b): [a] + b, zip(w_shapes, w_stats)) 183 184 return cls._make( [epoch, l] + reduce(concat, w_rec) ) 185 186 187 if __name__ == "__main__": 188 for C in (WeightMonitor, LearnMonitor): 189 assert len(C._ftypes) == len(C._fields), "%s) C._ftypes %d != C._fields = %d" % (str(C), len(C._ftypes) , len(C._fields)) 190