annotate pylearn/algorithms/exponential_mean.py @ 678:790c5e44906c

small correction to exponential_mean
author James Bergstra <bergstrj@iro.umontreal.ca>
date Thu, 02 Apr 2009 17:57:51 -0400
parents 273d782b5a20
children e69249897f89
rev   line source
677
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
1 """Modules for maintaining statistics based on exponential decay"""
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
2 __docformat__ = "restructuredtext en"
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
3
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
4 import copy
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
5 import numpy
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
6 import theano
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
7 import theano.tensor
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
8
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
9 class ExponentialMean(theano.Module):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
10 """Maintain an exponentially-decaying estimate of the mean
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
11
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
12 This module computes the exact mean of the first `max_denom` values of `x`.
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
13 After the first `max_denom` values, it tracks the mean using the formula:
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
14
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
15 :math:`self.curval = (1.0 - (1.0/max_denom)) * self.old_curval + (1.0/max_denom) * x`
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
16
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
17 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
18
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
19 max_denom = None
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
20 """The average will be updated as if the current estimated average was estimated from at
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
21 most `max_denom-1` values."""
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
22
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
23 ival = None
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
24 """The initial value for the estimated average."""
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
25
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
26 def __init__(self, x, max_denom, ival):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
27 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
28 :param x: track the mean of this Variable
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
29
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
30 :param max_denom: see `self.max_denom`
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
31
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
32 :param ival: This should be a tensor of zeros with a shape that matches `x`'s runtime
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
33 value.
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
34
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
35 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
36 super(ExponentialMean, self).__init__()
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
37
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
38 self.max_denom = max_denom
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
39 self.ival = ival
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
40
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
41 if len(ival.shape) == 0:
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
42 x_type = theano.tensor.dscalar
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
43 elif len(ival.shape) == 1:
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
44 x_type = theano.tensor.dvector
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
45 elif len(ival.shape) == 2:
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
46 x_type = theano.tensor.dmatrix
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
47 else:
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
48 #TODO: x_type = theano.tensor.TensorType(...)
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
49 raise NotImplementedError()
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
50
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
51 self.old_curval = (x_type())
678
790c5e44906c small correction to exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents: 677
diff changeset
52 # TODO: making this an lscalar caused different optimizations, followed by integer
790c5e44906c small correction to exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents: 677
diff changeset
53 # division somewhere were i wanted float division.... and the wrong answer.
790c5e44906c small correction to exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents: 677
diff changeset
54 self.denom = (theano.tensor.dscalar())
677
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
55
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
56 alpha = 1.0 / self.denom
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
57 self.curval = (1.0 - alpha) * self.old_curval + alpha * x
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
58
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
59 def updates(self):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
60 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
61 :returns: the symbolic updates necessary to refresh the mean estimate
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
62 :rtype: dict Variable -> Variable
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
63 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
64 return {
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
65 self.old_curval: self.curval,
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
66 self.denom: theano.tensor.smallest(self.denom + 1, self.max_denom)
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
67 }
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
68
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
69 def _instance_initialize(self, obj):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
70 obj.denom = 1
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
71 obj.old_curval = copy.copy(self.ival)
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
72
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
73 def exp_mean(x, x_shape, max_denom=100):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
74 """Return an `ExponentialMean` to track a Variable `x` with given shape
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
75
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
76 :type x: Variable
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
77 :type x_shape: tuple
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
78 :type max_denom: int
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
79
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
80 :rtype: ExponentialMean instance
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
81 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
82 return ExponentialMean(x,
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
83 max_denom=max_denom,
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
84 ival=numpy.zeros(x_shape))
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
85
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
86 def exp_mean_sqr(x, x_shape, max_denom=100):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
87 """Return an `ExponentialMean` to track a Variable `x`'s square with given shape
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
88
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
89 :type x: Variable
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
90 :type x_shape: tuple
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
91 :type max_denom: int
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
92
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
93 :rtype: ExponentialMean instance
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
94 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
95 return ExponentialMean(x**2,
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
96 max_denom=max_denom,
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
97 ival=numpy.zeros(x_shape))
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
98
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
99 class exp_var(theano.Module):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
100 """Module with interface similar to `ExponentialMean` for tracking elementwise variance
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
101
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
102 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
103
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
104 mean = None
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
105 """`ExponentialMean`: current estimate of mean of `x` """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
106
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
107 mean_sqr = None
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
108 """`ExponentialMean`: current estimate of mean sqr of `x` """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
109
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
110 curval = None
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
111 """Variable: Current estimate of the variance of `x` """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
112
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
113 def __init__(self, x, x_shape, max_denom=100):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
114 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
115 :param x: track the variance of this Variable
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
116
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
117 :param max_denom: see `self.max_denom`
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
118
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
119 :param ival: This should be a tensor of zeros with a shape that matches `x`'s runtime
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
120 value.
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
121
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
122 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
123 super(exp_var,self).__init__()
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
124
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
125 self.mean = exp_mean(x, x_shape, max_denom)
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
126 self.mean_sqr = exp_mean_sqr(x, x_shape, max_denom)
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
127
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
128 self.curval = self.mean_sqr.curval - self.mean.curval**2
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
129
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
130 def updates(self):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
131 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
132 :returns: the symbolic updates necessary to refresh the variance estimate
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
133 :rtype: dict Variable -> Variable
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
134 """
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
135 rval = {}
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
136 rval.update(self.mean.updates())
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
137 rval.update(self.mean_sqr.updates())
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
138 return rval
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
139
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
140 def _instance_initialize(self, obj):
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
141 obj.mean.initialize()
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
142 obj.mean_sqr.initialize()
273d782b5a20 added exponential_mean
James Bergstra <bergstrj@iro.umontreal.ca>
parents:
diff changeset
143