forked from TeamCohen/TensorLog
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlearnxcomp.py
More file actions
59 lines (51 loc) · 2.37 KB
/
Copy pathlearnxcomp.py
File metadata and controls
59 lines (51 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import theanoxcomp as X
import learn as L
import theano
import theano.tensor as TT
import funs
#from termios import XCASE
#theano.config.exception_verbosity='high'
class XLearner(object):
def __init__(self,tlprog,xc=None,compilerClass=X.DenseMatDenseMsgCrossCompiler):
if xc: self.xc = xc
else: self.xc = compilerClass(tlprog.db)
self.prog = tlprog
def predict(self,mode,X,pad=None):
"""Make predictions on a data matrix associated with the given mode."""
#if not pad: pad = opfunutil.Scratchpad()
result = self.xc.eval([X])[0]
return result
def crossEntropy(Y,P,perExample=False):
"""Compute cross entropy some predications relative to some labels."""
if perExample: return self.xc.dataLossFun([Y,P])
else: assert 'No per example xe yet' #return self.xe_all([Y,P])
def crossEntropyGrad(self,mode,X,Y,tracerArgs={},pad=None):
"""Compute the parameter gradient associated with softmax
normalization followed by a cross-entropy cost function. If a
scratchpad is passed in, then intermediate results of the
gradient computation will be saved on that scratchpad.
"""
#if not pad: pad = opfunutil.Scratchpad()
# More detail: in learning we use a softmax normalization
# followed immediately by a crossEntropy loss, which has a
# simple derivative when combined - see
# http://peterroelants.github.io/posts/neural_network_implementation_intermezzo02/
# So in doing backprop, you don't call backprop on the outer
# function, instead you compute the initial delta of P-Y, the
# derivative for the loss of the (softmax o crossEntropy)
# function, and it pass that delta down to the inner function
# for softMax
# do the prediction, saving intermediate outputs on the scratchpad
predictFun = self.prog.getPredictFunction(mode)
assert isinstance(predictFun,funs.SoftmaxFunction),'crossEntropyGrad specialized to work for softmax normalization'
#P = self.predict(mode,X,pad)
# compute gradient
#paramGrads = L.GradAccumulator()
#TODO assert rowSum(Y) = all ones - that's assumed here in
#initial delta of Y-P
#xc.fun.backprop(Y-P,paramGrads,pad)
paramGrads = self.xc.evalDataLossGrad(X,Y)
# the tracer function may output status, and may also write
# information to the counters in paramGrads
#self.tracer(self,paramGrads,Y,P,**tracerArgs)
return paramGrads