comparison pylearn/sandbox/scan_inputs_groups.py @ 714:8d5d42274bd1

improved readability DAA_inputs_groups and scan_inputs_groups
author Xavier Glorot <glorotxa@iro.umontreal.ca>
date Fri, 22 May 2009 15:14:34 -0400
parents 0eae6d5315b5
children 573e3370d0fa
comparison
equal deleted inserted replaced
713:a268c5ea0db4 714:8d5d42274bd1
9 # (for exemple with multimodal data with sometimes entire modality missing). 9 # (for exemple with multimodal data with sometimes entire modality missing).
10 # The inputs will be represented with an index list and a theano.generic variable (which will be a list of matrices 10 # The inputs will be represented with an index list and a theano.generic variable (which will be a list of matrices
11 # (numpy array), each element will correspond to an available modality and the index list will indicate the weights 11 # (numpy array), each element will correspond to an available modality and the index list will indicate the weights
12 # associated to it). 12 # associated to it).
13 # Exemple of index list: [1, 0, -3] 13 # Exemple of index list: [1, 0, -3]
14 # *the 1 says that the first element of the input list will refer to the first element of the weights_list 14 # *the 1 says that the first element of the input list will refer to the first element of the weights_list
15 # (auxiliary target as input) 15 # (auxiliary target as input)
16 # if inputslist[i]>0 it refers to Weightslist[indexlist[i]-1] 16 # if inputslist[i]>0 it refers to Weightslist[indexlist[i]-1]
17 # *the 0 means that the second element of the input list will not be encoded neither decoded (it is remplaced by zeros) 17 # *the 0 means that the second element of the input list will not be encoded neither decoded (it is remplaced by zeros)
18 # this is not efficient, so in this case it is better to give: [1,-3] and [inputslist[0],inputslist[2]] 18 # this is not efficient, so in this case it is better to give: [1,-3] and [inputslist[0],inputslist[2]]
19 # but it allows us to deal with empty lists: give indexlist = numpy.asarray([.0]) 19 # but it allows us to deal with empty lists: give indexlist = numpy.asarray([.0])
20 # and inputlist=numpy.zeros((batchsize,1)) 20 # and inputlist=numpy.zeros((batchsize,1))
21 # *when an index is negative it means that the input will not be used for encoding but we will still reconstruct it 21 # *when an index is negative it means that the input will not be used for encoding but we will still reconstruct it
22 # (auxiliary target as output) 22 # (auxiliary target as output)
23 # if inputslist[i]<0 it refers to Weightslist[-indexlist[i]-1] 23 # if inputslist[i]<0 it refers to Weightslist[-indexlist[i]-1]
24 # 24 #
25 # An entire batch should have the same available inputs configuration. 25 # An entire batch should have the same available inputs configuration.
26 # 26 #
27 # Dense DAA Exemple:---------------------------------------------------------------------------- 27 # Dense DAA Exemple:----------------------------------------------------------------------------
28 # 28 #
44 #dec = sigmoid(scanbiasdec(vectin2,inputpart2,bdec) + scandotdec(vectin2, inputpart2,acthid,wdec)) 44 #dec = sigmoid(scanbiasdec(vectin2,inputpart2,bdec) + scandotdec(vectin2, inputpart2,acthid,wdec))
45 #cost = T.sum(T.sum(T.sqr( scaninput(vectin,inputpart) - rec ),1),0) 45 #cost = T.sum(T.sum(T.sqr( scaninput(vectin,inputpart) - rec ),1),0)
46 46
47 # Checking inputs in make_node methods---------------------- 47 # Checking inputs in make_node methods----------------------
48 def Checkidx_list(idx_list): 48 def Checkidx_list(idx_list):
49 idx_list = T.as_tensor_variable(idx_list) 49 idx_list = T.as_tensor_variable(idx_list)
50 nidx = idx_list.type.ndim 50 nidx = idx_list.type.ndim
51 if nidx != 1: raise TypeError('not vector', idx_list) 51 if nidx != 1: raise TypeError('not vector', idx_list)
52 return idx_list 52 return idx_list
53 53
54 def Checkhidd(hidd): 54 def Checkhidd(hidd):
55 hidd = T.as_tensor_variable(hidd) 55 hidd = T.as_tensor_variable(hidd)
56 nhidd = hidd.type.ndim 56 nhidd = hidd.type.ndim
57 if nhidd not in (1,2): raise TypeError('not matrix or vector', hidd) 57 if nhidd not in (1,2): raise TypeError('not matrix or vector', hidd)
58 return hidd 58 return hidd
59 59
60 def Checkweights_list(weights_list): 60 def Checkweights_list(weights_list):
61 weights_list = map(T.as_tensor_variable, weights_list) 61 weights_list = map(T.as_tensor_variable, weights_list)
62 for i in range(len(weights_list)): 62 for i in range(len(weights_list)):
63 nweights = weights_list[i].type.ndim 63 nweights = weights_list[i].type.ndim
64 if nweights not in (1,2): raise TypeError('not matrix or vector', weights_list[i]) 64 if nweights not in (1,2): raise TypeError('not matrix or vector', weights_list[i])
65 return weights_list 65 return weights_list
66 66
67 def Checkbias_list(bias_list): 67 def Checkbias_list(bias_list):
68 bias_list = map(T.as_tensor_variable, bias_list) 68 bias_list = map(T.as_tensor_variable, bias_list)
69 for i in range(len(bias_list)): 69 for i in range(len(bias_list)):
70 nbias = bias_list[i].type.ndim 70 nbias = bias_list[i].type.ndim
71 if nbias != 1: raise TypeError('not vector', bias_list[i]) 71 if nbias != 1: raise TypeError('not vector', bias_list[i])
72 return bias_list 72 return bias_list
73 73
74 # Encoding scan dot product------------------------------------ 74 # Encoding scan dot product------------------------------------
75 class ScanDotEnc(Op): 75 class ScanDotEnc(Op):
76 """This Op takes an index list (as tensor.ivector), a list of matrices representing 76 """This Op takes an index list (as tensor.ivector), a list of matrices representing
77 the available inputs (as theano.generic), and all the encoding weights tensor.dmatrix of the model. It will select the 77 the available inputs (as theano.generic), and all the encoding weights tensor.dmatrix of the model. It will select the
78 weights corresponding to the inputs (according to index list) and compute only the necessary dot products""" 78 weights corresponding to the inputs (according to index list) and compute only the necessary dot products"""
79 def __init__(self): 79 def __init__(self):
80 #Create Theano methods to do the dot products with blas or at least in C. 80 #Create Theano methods to do the dot products with blas or at least in C.
81 self.M=theano.Module() 81 self.M=theano.Module()
82 inputs = T.dmatrix('input') 82 inputs = T.dmatrix('input')
83 weights = T.dmatrix('weights') 83 weights = T.dmatrix('weights')
84 self.M.hid = T.dmatrix('hid') 84 self.M.hid = T.dmatrix('hid')
85 self.M.resultin = self.M.hid + T.dot(inputs,weights) 85 self.M.resultin = self.M.hid + T.dot(inputs,weights)
86 result = T.dot(inputs,weights) 86 result = T.dot(inputs,weights)
87 87
88 self.M.dotin = theano.Method([inputs,weights],None,{self.M.hid : self.M.resultin}) 88 self.M.dotin = theano.Method([inputs,weights],None,{self.M.hid : self.M.resultin})
89 self.M.dot = theano.Method([inputs,weights],result) 89 self.M.dot = theano.Method([inputs,weights],result)
90 self.m = self.M.make() 90 self.m = self.M.make()
91 91
92 def make_node(self, idx_list, inputs_list, weights_list): 92 def make_node(self, idx_list, inputs_list, weights_list):
93 idx_list = Checkidx_list(idx_list) 93 idx_list = Checkidx_list(idx_list)
94 weights_list = Checkweights_list(weights_list) 94 weights_list = Checkweights_list(weights_list)
95 return Apply(self, [idx_list] + [inputs_list] + weights_list, [T.dmatrix()]) 95 return Apply(self, [idx_list] + [inputs_list] + weights_list, [T.dmatrix()])
96 96
97 def perform(self, node, args, (hid,)): 97 def perform(self, node, args, (hid,)):
98 idx_list = args[0] 98 idx_list = args[0]
99 hidcalc = False 99 hidcalc = False
100 100
101 batchsize = (args[1][0].shape)[0] 101 batchsize = (args[1][0].shape)[0]
102 n_hid = (args[2].shape)[1] 102 n_hid = (args[2].shape)[1]
103 if len(idx_list) != len(args[1]) : 103 if len(idx_list) != len(args[1]) :
104 raise NotImplementedError('size of index different of inputs list size',idx_list) 104 raise NotImplementedError('size of index different of inputs list size',idx_list)
105 if max(idx_list) >= (len(args)-2)+1 : 105 if max(idx_list) >= (len(args)-2)+1 :
106 raise NotImplementedError('index superior to weight list length',idx_list) 106 raise NotImplementedError('index superior to weight list length',idx_list)
107 for i in range(len(args[1])): 107 for i in range(len(args[1])):
108 if (args[1][i].shape)[0] != batchsize: 108 if (args[1][i].shape)[0] != batchsize:
109 raise NotImplementedError('different batchsize in the inputs list',args[1][i].shape) 109 raise NotImplementedError('different batchsize in the inputs list',args[1][i].shape)
110 for i in range(len(args)-2): 110 for i in range(len(args)-2):
111 if (args[2+i].shape)[1] != n_hid: 111 if (args[2+i].shape)[1] != n_hid:
112 raise NotImplementedError('different length of hidden in the weights list',args[2+i].shape) 112 raise NotImplementedError('different length of hidden in the weights list',args[2+i].shape)
113 113
114 for i in range(len(idx_list)): 114 for i in range(len(idx_list)):
115 if idx_list[i]>0: 115 if idx_list[i]>0:
116 if hidcalc: 116 if hidcalc:
117 self.m.dotin(args[1][i],args[2+int(idx_list[i]-1)]) 117 self.m.dotin(args[1][i],args[2+int(idx_list[i]-1)])
118 else: 118 else:
119 self.m.hid = self.m.dot(args[1][i],args[2+int(idx_list[i]-1)]) 119 self.m.hid = self.m.dot(args[1][i],args[2+int(idx_list[i]-1)])
120 hidcalc = True 120 hidcalc = True
121 121
122 if not hidcalc: 122 if not hidcalc:
123 hid[0] = numpy.zeros([batchsize,n_hid]) 123 hid[0] = numpy.zeros([batchsize,n_hid])
124 else: 124 else:
125 hid[0] = self.m.hid 125 hid[0] = self.m.hid
126 126
127 127
128 def grad(self, args, gz): 128 def grad(self, args, gz):
129 gradi = ScanDotEncGrad()(args,gz) 129 gradi = ScanDotEncGrad()(args,gz)
130 if type(gradi) != list: 130 if type(gradi) != list:
131 return [None, None] + [gradi] 131 return [None, None] + [gradi]
132 else: 132 else:
133 return [None, None] + gradi 133 return [None, None] + gradi
134 134
135 def __hash__(self): 135 def __hash__(self):
136 return hash(ScanDotEnc)^58994 136 return hash(ScanDotEnc)^58994
137 137
138 def __str__(self): 138 def __str__(self):
139 return "ScanDotEnc" 139 return "ScanDotEnc"
140 140
141 scandotenc=ScanDotEnc() 141 scandotenc=ScanDotEnc()
142 142
143 class ScanDotEncGrad(Op): 143 class ScanDotEncGrad(Op):
144 """This Op computes the gradient wrt the weights for ScanDotEnc""" 144 """This Op computes the gradient wrt the weights for ScanDotEnc"""
145 def __init__(self): 145 def __init__(self):
146 #Create Theano methods to do the dot products with blas or at least in C. 146 #Create Theano methods to do the dot products with blas or at least in C.
147 self.M=theano.Module() 147 self.M=theano.Module()
148 input1 = T.dmatrix('input1') 148 input1 = T.dmatrix('input1')
149 self.M.g_out = T.dmatrix('g_out') 149 self.M.g_out = T.dmatrix('g_out')
150 result = T.dmatrix('result') 150 result = T.dmatrix('result')
151 input2=T.transpose(input1) 151 input2=T.transpose(input1)
152 self.M.resultin = result + T.dot(input2,self.M.g_out) 152 self.M.resultin = result + T.dot(input2,self.M.g_out)
153 self.M.result = T.dot(input2,self.M.g_out) 153 self.M.result = T.dot(input2,self.M.g_out)
154 154
155 self.M.dotin = theano.Method([input1,result],self.M.resultin) 155 self.M.dotin = theano.Method([input1,result],self.M.resultin)
156 self.M.dot = theano.Method([input1],self.M.result) 156 self.M.dot = theano.Method([input1],self.M.result)
157 self.m = self.M.make() 157 self.m = self.M.make()
158 158
159 def make_node(self, args, g_out): 159 def make_node(self, args, g_out):
160 idx_list = Checkidx_list(args[0]) 160 idx_list = Checkidx_list(args[0])
161 weights_list = Checkweights_list(args[2:]) 161 weights_list = Checkweights_list(args[2:])
162 return Apply(self, args + g_out, [T.dmatrix() for i in xrange(2,len(args))]) 162 return Apply(self, args + g_out, [T.dmatrix() for i in xrange(2,len(args))])
163 163
164 def perform(self, node, args, z): 164 def perform(self, node, args, z):
165 idx_list = args[0] 165 idx_list = args[0]
166 self.m.g_out = args[-1] 166 self.m.g_out = args[-1]
167 167
168 batchsize = (args[1][0].shape)[0] 168 batchsize = (args[1][0].shape)[0]
169 n_hid = (args[2].shape)[1] 169 n_hid = (args[2].shape)[1]
170 if len(idx_list) != len(args[1]) : 170 if len(idx_list) != len(args[1]) :
171 raise NotImplementedError('size of index different of inputs list size',idx_list) 171 raise NotImplementedError('size of index different of inputs list size',idx_list)
172 if max(idx_list) >= (len(args)-3)+1 : 172 if max(idx_list) >= (len(args)-3)+1 :
173 raise NotImplementedError('index superior to weight list length',idx_list) 173 raise NotImplementedError('index superior to weight list length',idx_list)
174 for i in range(len(args[1])): 174 for i in range(len(args[1])):
175 if (args[1][i].shape)[0] != batchsize: 175 if (args[1][i].shape)[0] != batchsize:
176 raise NotImplementedError('different batchsize in the inputs list',args[1][i].shape) 176 raise NotImplementedError('different batchsize in the inputs list',args[1][i].shape)
177 for i in range(len(args)-3): 177 for i in range(len(args)-3):
178 if (args[2+i].shape)[1] != n_hid: 178 if (args[2+i].shape)[1] != n_hid:
179 raise NotImplementedError('different length of hidden in the weights list',args[2+i].shape) 179 raise NotImplementedError('different length of hidden in the weights list',args[2+i].shape)
180 180
181 zcalc = [False for i in range(len(args)-3)] 181 zcalc = [False for i in range(len(args)-3)]
182 182
183 for i in range(len(idx_list)): 183 for i in range(len(idx_list)):
184 if idx_list[i]>0: 184 if idx_list[i]>0:
185 if zcalc[int(idx_list[i]-1)]: 185 if zcalc[int(idx_list[i]-1)]:
186 z[int(idx_list[i]-1)][0] = self.m.dotin(args[1][i],z[int(idx_list[i]-1)][0]) 186 z[int(idx_list[i]-1)][0] = self.m.dotin(args[1][i],z[int(idx_list[i]-1)][0])
187 else: 187 else:
188 z[int(idx_list[i]-1)][0] = self.m.dot(args[1][i]) 188 z[int(idx_list[i]-1)][0] = self.m.dot(args[1][i])
189 zcalc[int(idx_list[i]-1)] = True 189 zcalc[int(idx_list[i]-1)] = True
190 190
191 for i in range(len(args)-3): 191 for i in range(len(args)-3):
192 if not zcalc[i]: 192 if not zcalc[i]:
193 shp = args[2+i].shape 193 shp = args[2+i].shape
194 z[i][0] = numpy.zeros(shp) 194 z[i][0] = numpy.zeros(shp)
195 195
196 def __hash__(self): 196 def __hash__(self):
197 return hash(ScanDotEncGrad)^15684 197 return hash(ScanDotEncGrad)^15684
198 198
199 def __str__(self): 199 def __str__(self):
200 return "ScanDotEncGrad" 200 return "ScanDotEncGrad"
201 201
202 # Decoding scan dot product------------------------------------ 202 # Decoding scan dot product------------------------------------
203 class ScanDotDec(Op): 203 class ScanDotDec(Op):
204 """This Op takes an index list (as tensor.ivector), a list of matrices representing 204 """This Op takes an index list (as tensor.ivector), a list of matrices representing
205 the available inputs (as theano.generic), the hidden layer of the DAA (theano.dmatrix) 205 the available inputs (as theano.generic), the hidden layer of the DAA (theano.dmatrix)
206 and all the decoding weights tensor.dmatrix of the model. It will select the 206 and all the decoding weights tensor.dmatrix of the model. It will select the
207 weights corresponding to the available inputs (according to index list) and compute 207 weights corresponding to the available inputs (according to index list) and compute
208 only the necessary dot products. The outputs will be concatenated and will represent 208 only the necessary dot products. The outputs will be concatenated and will represent
209 the reconstruction of the different modality in the same order than the index list""" 209 the reconstruction of the different modality in the same order than the index list"""
210 def __init__(self): 210 def __init__(self):
211 #Create Theano methods to do the dot products with blas or at least in C. 211 #Create Theano methods to do the dot products with blas or at least in C.
212 self.M=theano.Module() 212 self.M=theano.Module()
213 weights = T.dmatrix('weights') 213 weights = T.dmatrix('weights')
214 self.M.hid = T.dmatrix('hid') 214 self.M.hid = T.dmatrix('hid')
215 oldval = T.dmatrix('oldval') 215 oldval = T.dmatrix('oldval')
216 resultin = oldval + T.dot(self.M.hid,weights) 216 resultin = oldval + T.dot(self.M.hid,weights)
217 result = T.dot(self.M.hid,weights) 217 result = T.dot(self.M.hid,weights)
218 218
219 self.M.dotin = theano.Method([weights,oldval],resultin) 219 self.M.dotin = theano.Method([weights,oldval],resultin)
220 self.M.dot = theano.Method([weights],result) 220 self.M.dot = theano.Method([weights],result)
221 self.m = self.M.make() 221 self.m = self.M.make()
222 222
223 def make_node(self, idx_list, input_list, hidd, weights_list): 223 def make_node(self, idx_list, input_list, hidd, weights_list):
224 idx_list = Checkidx_list(idx_list) 224 idx_list = Checkidx_list(idx_list)
225 hidd = Checkhidd(hidd) 225 hidd = Checkhidd(hidd)
226 weights_list = Checkweights_list(weights_list) 226 weights_list = Checkweights_list(weights_list)
227 return Apply(self, [idx_list] + [input_list] +[hidd] + weights_list,[T.dmatrix()]) 227 return Apply(self, [idx_list] + [input_list] +[hidd] + weights_list,[T.dmatrix()])
228 228
229 def perform(self, node, args, (z,)): 229 def perform(self, node, args, (z,)):
230 230
231 idx_list = abs(args[0]) 231 idx_list = abs(args[0])
232 self.m.hid = args[2] 232 self.m.hid = args[2]
233 233
234 batchsize = (self.m.hid.shape)[0] 234 batchsize = (self.m.hid.shape)[0]
235 n_hid = self.m.hid.shape[1] 235 n_hid = self.m.hid.shape[1]
236 if max(idx_list) >= len(args)-3+1 : 236 if max(idx_list) >= len(args)-3+1 :
237 raise NotImplementedError('index superior to weight list length',idx_list) 237 raise NotImplementedError('index superior to weight list length',idx_list)
238 if len(idx_list) != len(args[1]) : 238 if len(idx_list) != len(args[1]) :
239 raise NotImplementedError('size of index different of inputs list size',idx_list) 239 raise NotImplementedError('size of index different of inputs list size',idx_list)
240 for i in range(len(args)-3): 240 for i in range(len(args)-3):
241 if (args[3+i].shape)[0] != n_hid: 241 if (args[3+i].shape)[0] != n_hid:
242 raise NotImplementedError('different length of hidden in the weights list',args[3+i].shape) 242 raise NotImplementedError('different length of hidden in the weights list',args[3+i].shape)
243 243
244 zcalc = [False for i in idx_list] 244 zcalc = [False for i in idx_list]
245 z[0] = [None for i in idx_list] 245 z[0] = [None for i in idx_list]
246 246
247 for i in range(len(idx_list)): 247 for i in range(len(idx_list)):
248 if idx_list[i]>0: 248 if idx_list[i]>0:
249 if zcalc[i]: 249 if zcalc[i]:
250 z[0][i] = self.m.dotin(args[3+int(idx_list[i]-1)],z[0][i]) 250 z[0][i] = self.m.dotin(args[3+int(idx_list[i]-1)],z[0][i])
251 else: 251 else:
252 z[0][i] = self.m.dot(args[3+int(idx_list[i]-1)]) 252 z[0][i] = self.m.dot(args[3+int(idx_list[i]-1)])
253 zcalc[i] = True 253 zcalc[i] = True
254 254
255 for i in range(len(idx_list)): 255 for i in range(len(idx_list)):
256 if not zcalc[i]: 256 if not zcalc[i]:
257 shp = args[1][int(idx_list[i]-1)].shape 257 shp = args[1][int(idx_list[i]-1)].shape
258 z[0][i] = numpy.zeros((batchsize,shp[1])) 258 z[0][i] = numpy.zeros((batchsize,shp[1]))
259 259
260 z[0] = numpy.concatenate(z[0],1) 260 z[0] = numpy.concatenate(z[0],1)
261 261
262 def grad(self, args, gz): 262 def grad(self, args, gz):
263 gradi = ScanDotDecGrad()(args,gz) 263 gradi = ScanDotDecGrad()(args,gz)
264 if type(gradi) != list: 264 if type(gradi) != list:
265 return [None, None] + [gradi] 265 return [None, None] + [gradi]
266 else: 266 else:
267 return [None, None] + gradi 267 return [None, None] + gradi
268 268
269 def __hash__(self): 269 def __hash__(self):
270 return hash(ScanDotDec)^73568 270 return hash(ScanDotDec)^73568
271 271
272 def __str__(self): 272 def __str__(self):
273 return "ScanDotDec" 273 return "ScanDotDec"
274 274
275 scandotdec=ScanDotDec() 275 scandotdec=ScanDotDec()
276 276
277 class ScanDotDecGrad(Op): 277 class ScanDotDecGrad(Op):
278 """This Op computes the gradient wrt the weights for ScanDotDec""" 278 """This Op computes the gradient wrt the weights for ScanDotDec"""
279 def __init__(self): 279 def __init__(self):
280 self.M=theano.Module() 280 self.M=theano.Module()
281 gout = T.dmatrix('gout') 281 gout = T.dmatrix('gout')
282 self.M.hidt = T.dmatrix('hid') 282 self.M.hidt = T.dmatrix('hid')
283 oldval = T.dmatrix('oldval') 283 oldval = T.dmatrix('oldval')
284 resultin1 = oldval + T.dot(self.M.hidt,gout) 284 resultin1 = oldval + T.dot(self.M.hidt,gout)
285 result1 = T.dot(self.M.hidt,gout) 285 result1 = T.dot(self.M.hidt,gout)
286 weights = T.dmatrix('weights') 286 weights = T.dmatrix('weights')
287 weights2 = T.transpose(weights) 287 weights2 = T.transpose(weights)
288 resultin2 = oldval + T.dot(gout,weights2) 288 resultin2 = oldval + T.dot(gout,weights2)
289 result2 = T.dot(gout,weights2) 289 result2 = T.dot(gout,weights2)
290 290
291 self.M.dotin1 = theano.Method([gout,oldval],resultin1) 291 self.M.dotin1 = theano.Method([gout,oldval],resultin1)
292 self.M.dot1 = theano.Method([gout],result1) 292 self.M.dot1 = theano.Method([gout],result1)
293 self.M.dotin2 = theano.Method([gout,weights,oldval],resultin2) 293 self.M.dotin2 = theano.Method([gout,weights,oldval],resultin2)
294 self.M.dot2 = theano.Method([gout,weights],result2) 294 self.M.dot2 = theano.Method([gout,weights],result2)
295 self.m = self.M.make() 295 self.m = self.M.make()
296 296
297 297
298 def make_node(self, args, g_out): 298 def make_node(self, args, g_out):
299 idx_list = Checkidx_list(args[0]) 299 idx_list = Checkidx_list(args[0])
300 hidd = Checkhidd(args[2]) 300 hidd = Checkhidd(args[2])
301 weights_list = Checkweights_list(args[3:]) 301 weights_list = Checkweights_list(args[3:])
302 return Apply(self, args + g_out, [T.dmatrix() for i in xrange(2,len(args))]) 302 return Apply(self, args + g_out, [T.dmatrix() for i in xrange(2,len(args))])
303 303
304 def perform(self, node, args, z): 304 def perform(self, node, args, z):
305 idx_list = abs(args[0]) 305 idx_list = abs(args[0])
306 self.m.hidt = args[2].T 306 self.m.hidt = args[2].T
307 307
308 batchsize = (self.m.hidt.shape)[1] 308 batchsize = (self.m.hidt.shape)[1]
309 n_hid = self.m.hidt.shape[0] 309 n_hid = self.m.hidt.shape[0]
310 if max(idx_list) >= len(args)-4+1 : 310 if max(idx_list) >= len(args)-4+1 :
311 raise NotImplementedError('index superior to weight list length',idx_list) 311 raise NotImplementedError('index superior to weight list length',idx_list)
312 if len(idx_list) != len(args[1]) : 312 if len(idx_list) != len(args[1]) :
313 raise NotImplementedError('size of index different of inputs list size',idx_list) 313 raise NotImplementedError('size of index different of inputs list size',idx_list)
314 for i in range(len(args)-4): 314 for i in range(len(args)-4):
315 if (args[3+i].shape)[0] != n_hid: 315 if (args[3+i].shape)[0] != n_hid:
316 raise NotImplementedError('different length of hidden in the weights list',args[3+i].shape) 316 raise NotImplementedError('different length of hidden in the weights list',args[3+i].shape)
317 317
318 zidx=numpy.zeros((len(idx_list)+1)) 318 zidx=numpy.zeros((len(idx_list)+1))
319 319
320 for i in range(len(idx_list)): 320 for i in range(len(idx_list)):
321 if idx_list[i] == 0: 321 if idx_list[i] == 0:
322 zidx[i+1] = (args[1][i].shape)[1] 322 zidx[i+1] = (args[1][i].shape)[1]
323 else: 323 else:
324 zidx[i+1] = (args[3+idx_list[i]-1].shape)[1] 324 zidx[i+1] = (args[3+idx_list[i]-1].shape)[1]
325 325
326 zidx=zidx.cumsum() 326 zidx=zidx.cumsum()
327 hidcalc = False 327 hidcalc = False
328 zcalc = [False for i in range((len(args)-4))] 328 zcalc = [False for i in range((len(args)-4))]
329 329
330 for i in range(len(idx_list)): 330 for i in range(len(idx_list)):
331 if idx_list[i]>0: 331 if idx_list[i]>0:
332 if zcalc[int(idx_list[i])-1]: 332 if zcalc[int(idx_list[i])-1]:
333 z[int(idx_list[i])][0] = self.m.dotin1(args[-1][:,zidx[i]:zidx[i+1]],z[int(idx_list[i])][0]) 333 z[int(idx_list[i])][0] = self.m.dotin1(args[-1][:,zidx[i]:zidx[i+1]],z[int(idx_list[i])][0])
334 else: 334 else:
335 z[int(idx_list[i])][0] = self.m.dot1(args[-1][:,zidx[i]:zidx[i+1]]) 335 z[int(idx_list[i])][0] = self.m.dot1(args[-1][:,zidx[i]:zidx[i+1]])
336 zcalc[int(idx_list[i])-1] = True 336 zcalc[int(idx_list[i])-1] = True
337 if hidcalc: 337 if hidcalc:
338 z[0][0] = self.m.dotin2(args[-1][:,zidx[i]:zidx[i+1]],args[3+int(idx_list[i]-1)],z[0][0]) 338 z[0][0] = self.m.dotin2(args[-1][:,zidx[i]:zidx[i+1]],args[3+int(idx_list[i]-1)],z[0][0])
339 else: 339 else:
340 z[0][0] = self.m.dot2(args[-1][:,zidx[i]:zidx[i+1]],args[3+int(idx_list[i]-1)]) 340 z[0][0] = self.m.dot2(args[-1][:,zidx[i]:zidx[i+1]],args[3+int(idx_list[i]-1)])
341 hidcalc = True 341 hidcalc = True
342 342
343 if not hidcalc: 343 if not hidcalc:
344 z[0][0] = numpy.zeros((self.m.hidt.shape[1],self.m.hidt.shape[0])) 344 z[0][0] = numpy.zeros((self.m.hidt.shape[1],self.m.hidt.shape[0]))
345 345
346 for i in range((len(args)-4)): 346 for i in range((len(args)-4)):
347 if not zcalc[i]: 347 if not zcalc[i]:
348 shp = args[3+i].shape 348 shp = args[3+i].shape
349 z[i+1][0] = numpy.zeros(shp) 349 z[i+1][0] = numpy.zeros(shp)
350 350
351 351
352 def __hash__(self): 352 def __hash__(self):
353 return hash(ScanDotDecGrad)^87445 353 return hash(ScanDotDecGrad)^87445
354 354
355 def __str__(self): 355 def __str__(self):
356 return "ScanDotDecGrad" 356 return "ScanDotDecGrad"
357 357
358 # DAA input noise------------------------------------ 358 # DAA input noise------------------------------------
359 class ScanNoise(Op): 359 class ScanNoise(Op):
360 """This Op takes an index list (as tensor.ivector), a list of matrices representing 360 """This Op takes an index list (as tensor.ivector), a list of matrices representing
361 the available inputs (as theano.generic), a probability of individual bit masking and 361 the available inputs (as theano.generic), a probability of individual bit masking and
362 a probability of modality masking. It will return the inputs list with randoms zeros entry 362 a probability of modality masking. It will return the inputs list with randoms zeros entry
363 and the index list with some positive values changed to negative values (groups masking)""" 363 and the index list with some positive values changed to negative values (groups masking)"""
364 def __init__(self, seed = 1): 364 def __init__(self, seed = 1):
365 self.M=theano.Module() 365 self.M=theano.Module()
366 self.M.rand = T.RandomStreams(seed) 366 self.M.rand = T.RandomStreams(seed)
367 self.seed = seed 367 self.seed = seed
368 mat = T.matrix('mat') 368 mat = T.matrix('mat')
369 noise_level_bit = T.dscalar('noise_level_bit') 369 noise_level_bit = T.dscalar('noise_level_bit')
370 noise_level_group = T.dscalar('noise_level_group') 370 noise_level_group = T.dscalar('noise_level_group')
371 self.M.out1 = self.M.rand.binomial(T.shape(mat), 1, 1 - noise_level_bit) * mat 371 self.M.out1 = self.M.rand.binomial(T.shape(mat), 1, 1 - noise_level_bit) * mat
372 self.M.out2 = self.M.rand.binomial((1,1), 1, 1 - noise_level_group) 372 self.M.out2 = self.M.rand.binomial((1,1), 1, 1 - noise_level_group)
373 373
374 self.M.noisify_bit = theano.Method([mat,noise_level_bit],self.M.out1) 374 self.M.noisify_bit = theano.Method([mat,noise_level_bit],self.M.out1)
375 self.M.noisify_group_bool = theano.Method([noise_level_group],self.M.out2) 375 self.M.noisify_group_bool = theano.Method([noise_level_group],self.M.out2)
376 self.R = self.M.make() 376 self.R = self.M.make()
377 self.R.rand.initialize() 377 self.R.rand.initialize()
378 378
379 def make_node(self, idx_list, inputs_list, noise_level_bit, noise_level_group): 379 def make_node(self, idx_list, inputs_list, noise_level_bit, noise_level_group):
380 idx_list = Checkidx_list(idx_list) 380 idx_list = Checkidx_list(idx_list)
381 return Apply(self, [idx_list] + [inputs_list] + [noise_level_bit] + [noise_level_group],\ 381 return Apply(self, [idx_list] + [inputs_list] + [noise_level_bit] + [noise_level_group],\
382 [T.ivector(), theano.generic()]) 382 [T.ivector(), theano.generic()])
383 383
384 def perform(self, node, (idx_list,inputs_list,noise_level_bit,noise_level_group), (y,z)): 384 def perform(self, node, (idx_list,inputs_list,noise_level_bit,noise_level_group), (y,z)):
385 385
386 if len(idx_list) != len(inputs_list) : 386 if len(idx_list) != len(inputs_list) :
387 raise NotImplementedError('size of index different of inputs list size',idx_list) 387 raise NotImplementedError('size of index different of inputs list size',idx_list)
388 388
389 y[0] = numpy.asarray([-i if (i>0 and not(self.R.noisify_group_bool(noise_level_group))) else i for i in idx_list]) 389 y[0] = numpy.asarray([-i if (i>0 and not(self.R.noisify_group_bool(noise_level_group))) else i for i in idx_list])
390 z[0] = [(self.R.noisify_bit(inputs_list[i],noise_level_bit) if y[0][i]>0 else numpy.zeros((inputs_list[i].shape)))\ 390 z[0] = [(self.R.noisify_bit(inputs_list[i],noise_level_bit) if y[0][i]>0 else numpy.zeros((inputs_list[i].shape)))\
391 for i in range(len(inputs_list))] 391 for i in range(len(inputs_list))]
392 392
393 def grad(self,args,gz): 393 def grad(self,args,gz):
394 return [None,None,None,None] 394 return [None,None,None,None]
395 395
396 396
397 def __hash__(self): 397 def __hash__(self):
398 return hash(ScanNoise)^hash(self.seed)^hash(self.R.rand)^12254 398 return hash(ScanNoise)^hash(self.seed)^hash(self.R.rand)^12254
399 399
400 def __str__(self): 400 def __str__(self):
401 return "ScanNoise" 401 return "ScanNoise"
402 402
403 scannoise=ScanNoise() 403 scannoise=ScanNoise()
404 404
405 # Total input matrix construction------------------------------------ 405 # Total input matrix construction------------------------------------
406 class ScanInputs(Op): 406 class ScanInputs(Op):
407 """This Op takes an index list (as tensor.ivector) and a list of matrices representing 407 """This Op takes an index list (as tensor.ivector) and a list of matrices representing
408 the available inputs (as theano.generic). It will construct the appropriate tensor.dmatrix 408 the available inputs (as theano.generic). It will construct the appropriate tensor.dmatrix
409 to compare to the reconstruction obtained with ScanDotDec""" 409 to compare to the reconstruction obtained with ScanDotDec"""
410 def make_node(self, idx_list, inputs_list): 410 def make_node(self, idx_list, inputs_list):
411 idx_list = Checkidx_list(idx_list) 411 idx_list = Checkidx_list(idx_list)
412 return Apply(self, [idx_list] + [inputs_list],[T.dmatrix()]) 412 return Apply(self, [idx_list] + [inputs_list],[T.dmatrix()])
413 413
414 def perform(self, node, (idx_list, inputs_list), (z,)): 414 def perform(self, node, (idx_list, inputs_list), (z,)):
415 415
416 if len(idx_list) != len(inputs_list): 416 if len(idx_list) != len(inputs_list):
417 raise NotImplementedError('size of index different of inputs list size',idx_list) 417 raise NotImplementedError('size of index different of inputs list size',idx_list)
418 418
419 for i in range(len(idx_list)): 419 for i in range(len(idx_list)):
420 if idx_list[i] == 0: 420 if idx_list[i] == 0:
421 inputs_list[i] = 0 * inputs_list[i] 421 inputs_list[i] = 0 * inputs_list[i]
422 422
423 z[0] = numpy.concatenate(inputs_list,1) 423 z[0] = numpy.concatenate(inputs_list,1)
424 424
425 def grad(self,args,gz): 425 def grad(self,args,gz):
426 return [None,None] 426 return [None,None]
427 427
428 def __hash__(self): 428 def __hash__(self):
429 return hash(ScanInputs)^75902 429 return hash(ScanInputs)^75902
430 430
431 def __str__(self): 431 def __str__(self):
432 return "ScanInputs" 432 return "ScanInputs"
433 433
434 scaninputs=ScanInputs() 434 scaninputs=ScanInputs()
435 435
436 # Decoding bias vector construction------------------------------------ 436 # Decoding bias vector construction------------------------------------
437 class ScanBiasDec(Op): 437 class ScanBiasDec(Op):
438 """This Op takes an index list (as tensor.ivector), a list of matrices representing 438 """This Op takes an index list (as tensor.ivector), a list of matrices representing
439 the available inputs (as theano.generic) and the decoding bias tensor.dvector. 439 the available inputs (as theano.generic) and the decoding bias tensor.dvector.
440 It will construct the appropriate bias tensor.dvector 440 It will construct the appropriate bias tensor.dvector
441 to add to the reconstruction obtained with ScanDotDec""" 441 to add to the reconstruction obtained with ScanDotDec"""
442 def make_node(self, idx_list, input_list, bias_list): 442 def make_node(self, idx_list, input_list, bias_list):
443 idx_list = Checkidx_list(idx_list) 443 idx_list = Checkidx_list(idx_list)
444 bias_list = Checkbias_list(bias_list) 444 bias_list = Checkbias_list(bias_list)
445 return Apply(self, [idx_list] + [input_list] + bias_list, [T.dvector()]) 445 return Apply(self, [idx_list] + [input_list] + bias_list, [T.dvector()])
446 446
447 def perform(self, node, args, (z,)): 447 def perform(self, node, args, (z,)):
448 idx_list = abs(args[0]) 448 idx_list = abs(args[0])
449 449
450 if max(idx_list) >= (len(args)-2)+1 : 450 if max(idx_list) >= (len(args)-2)+1 :
451 raise NotImplementedError('index superior to bias list length',idx_list) 451 raise NotImplementedError('index superior to bias list length',idx_list)
452 if len(idx_list) != len(args[1]) : 452 if len(idx_list) != len(args[1]) :
453 raise NotImplementedError('size of index different of inputs list size',idx_list) 453 raise NotImplementedError('size of index different of inputs list size',idx_list)
454 z[0] = [args[idx_list[i]+1] if idx_list[i] != 0 else numpy.zeros(args[1][i].shape[1]) \ 454 z[0] = [args[idx_list[i]+1] if idx_list[i] != 0 else numpy.zeros(args[1][i].shape[1]) \
455 for i in range(len(idx_list))] 455 for i in range(len(idx_list))]
456 z[0] = numpy.concatenate(z[0],1) 456 z[0] = numpy.concatenate(z[0],1)
457 457
458 def __hash__(self): 458 def __hash__(self):
459 return hash(ScanBiasDec)^60056 459 return hash(ScanBiasDec)^60056
460 460
461 def grad(self,args,gz): 461 def grad(self,args,gz):
462 gradi = ScanBiasDecGrad()(args,gz) 462 gradi = ScanBiasDecGrad()(args,gz)
463 if type(gradi) != list: 463 if type(gradi) != list:
464 return [None, None] + [gradi] 464 return [None, None] + [gradi]
465 else: 465 else:
466 return [None, None] + gradi 466 return [None, None] + gradi
467 467
468 def __str__(self): 468 def __str__(self):
469 return "ScanBiasDec" 469 return "ScanBiasDec"
470 470
471 scanbiasdec=ScanBiasDec() 471 scanbiasdec=ScanBiasDec()
472 472
473 class ScanBiasDecGrad(Op): 473 class ScanBiasDecGrad(Op):
474 """This Op computes the gradient wrt the bias for ScanBiasDec""" 474 """This Op computes the gradient wrt the bias for ScanBiasDec"""
475 def make_node(self, args, g_out): 475 def make_node(self, args, g_out):
476 idx_list = Checkidx_list(args[0]) 476 idx_list = Checkidx_list(args[0])
477 bias_list = Checkbias_list(args[2:]) 477 bias_list = Checkbias_list(args[2:])
478 return Apply(self, args + g_out, [T.dvector() for i in range(len(args)-2)]) 478 return Apply(self, args + g_out, [T.dvector() for i in range(len(args)-2)])
479 479
480 def perform(self, node, args, z): 480 def perform(self, node, args, z):
481 idx_list = abs(args[0]) 481 idx_list = abs(args[0])
482 482
483 if max(idx_list) >= (len(args)-3)+1 : 483 if max(idx_list) >= (len(args)-3)+1 :
484 raise NotImplementedError('index superior to bias list length',idx_list) 484 raise NotImplementedError('index superior to bias list length',idx_list)
485 if len(idx_list) != len(args[1]) : 485 if len(idx_list) != len(args[1]) :
486 raise NotImplementedError('size of index different of inputs list size',idx_list) 486 raise NotImplementedError('size of index different of inputs list size',idx_list)
487 487
488 zidx=numpy.zeros((len(idx_list)+1)) 488 zidx=numpy.zeros((len(idx_list)+1))
489 for i in range(len(idx_list)): 489 for i in range(len(idx_list)):
490 if idx_list[i] == 0: 490 if idx_list[i] == 0:
491 zidx[i+1] = (args[1][i].shape)[1] 491 zidx[i+1] = (args[1][i].shape)[1]
492 else: 492 else:
493 zidx[i+1] = (args[2+idx_list[i]-1].size) 493 zidx[i+1] = (args[2+idx_list[i]-1].size)
494 zidx=zidx.cumsum() 494 zidx=zidx.cumsum()
495 zcalc = [False for i in range((len(args)-3))] 495 zcalc = [False for i in range((len(args)-3))]
496 496
497 for i in range(len(idx_list)): 497 for i in range(len(idx_list)):
498 if idx_list[i]>0: 498 if idx_list[i]>0:
499 if zcalc[int(idx_list[i])-1]: 499 if zcalc[int(idx_list[i])-1]:
500 z[int(idx_list[i])-1][0] += args[-1][zidx[i]:zidx[i+1]] 500 z[int(idx_list[i])-1][0] += args[-1][zidx[i]:zidx[i+1]]
501 else: 501 else:
502 z[int(idx_list[i])-1][0] = args[-1][zidx[i]:zidx[i+1]] 502 z[int(idx_list[i])-1][0] = args[-1][zidx[i]:zidx[i+1]]
503 zcalc[int(idx_list[i])-1] = True 503 zcalc[int(idx_list[i])-1] = True
504 504
505 for i in range((len(args)-3)): 505 for i in range((len(args)-3)):
506 if not zcalc[i]: 506 if not zcalc[i]:
507 shp = args[2+i].size 507 shp = args[2+i].size
508 z[i][0] = numpy.zeros(shp) 508 z[i][0] = numpy.zeros(shp)
509 509
510 510
511 def __hash__(self): 511 def __hash__(self):
512 return hash(ScanBiasDecGrad)^41256 512 return hash(ScanBiasDecGrad)^41256
513 513
514 def __str__(self): 514 def __str__(self):
515 return "ScanBiasDecGrad" 515 return "ScanBiasDecGrad"
516 516
517 # Mask construction------------------------------------ 517 # Mask construction------------------------------------
518 class ScanMask(Op): 518 class ScanMask(Op):
519 """This Op takes an index list (as tensor.ivector) and a list of weigths. 519 """This Op takes an index list (as tensor.ivector) and a list of weigths.
520 It will construct a list of T.iscalar representing the Mask 520 It will construct a list of T.iscalar representing the Mask
521 to do the correct regularisation on the weigths""" 521 to do the correct regularisation on the weigths"""
522 def __init__(self,encbool=True): 522 def __init__(self,encbool=True):
523 self.encbool = encbool 523 self.encbool = encbool
524 524
525 def make_node(self, idx_list, weights_list): 525 def make_node(self, idx_list, weights_list):
526 idx_list = Checkidx_list(idx_list) 526 idx_list = Checkidx_list(idx_list)
527 weights_list = Checkweights_list(weights_list) 527 weights_list = Checkweights_list(weights_list)
528 return Apply(self, [idx_list] + weights_list, [T.iscalar() for i in range(len(weights_list))]) 528 return Apply(self, [idx_list] + weights_list, [T.iscalar() for i in range(len(weights_list))])
529 529
530 def perform(self, node, args, z): 530 def perform(self, node, args, z):
531 if self.encbool: 531 if self.encbool:
532 idx_list = args[0] 532 idx_list = args[0]
533 dim = 1 533 dim = 1
534 else: 534 else:
535 idx_list = abs(args[0]) 535 idx_list = abs(args[0])
536 dim = 0 536 dim = 0
537 n_hid = args[1].shape[dim] 537 n_hid = args[1].shape[dim]
538 538
539 if max(idx_list) >= (len(args)-1)+1 : 539 if max(idx_list) >= (len(args)-1)+1 :
540 raise NotImplementedError('index superior to weights list length',idx_listdec) 540 raise NotImplementedError('index superior to weights list length',idx_listdec)
541 for i in range(len(args)-1): 541 for i in range(len(args)-1):
542 if args[1+i].shape[dim] != n_hid: 542 if args[1+i].shape[dim] != n_hid:
543 raise NotImplementedError('different length of hidden in the encoding weights list',args[1+i].shape) 543 raise NotImplementedError('different length of hidden in the encoding weights list',args[1+i].shape)
544 544
545 for i in range(len(args[1:])): 545 for i in range(len(args[1:])):
546 z[i][0] = numpy.asarray((idx_list == i+1).sum(),dtype='int32') 546 z[i][0] = numpy.asarray((idx_list == i+1).sum(),dtype='int32')
547 547
548 def __hash__(self): 548 def __hash__(self):
549 return hash(ScanMask)^hash(self.encbool)^11447 549 return hash(ScanMask)^hash(self.encbool)^11447
550 550
551 def grad(self,args,gz): 551 def grad(self,args,gz):
552 return [None] * len(args) 552 return [None] * len(args)
553 553
554 def __str__(self): 554 def __str__(self):
555 if self.encbool: 555 if self.encbool:
556 string = "Enc" 556 string = "Enc"
557 else: 557 else:
558 string = "Dec" 558 string = "Dec"
559 return "ScanMask" + string 559 return "ScanMask" + string
560 560
561 scanmaskenc=ScanMask(True) 561 scanmaskenc=ScanMask(True)
562 scanmaskdec=ScanMask(False) 562 scanmaskdec=ScanMask(False)