func (s *LogSoftmaxLayer) ApplyR(v autofunc.RVector, in autofunc.RResult) autofunc.RResult { return autofunc.PoolR(in, func(in autofunc.RResult) autofunc.RResult { // See comment in Apply() for details on how this works. maxIdx := maxVecIdx(in.Output()) maxValue := autofunc.SliceR(in, maxIdx, maxIdx+1) exponents := autofunc.AddFirstR(in, autofunc.ScaleR(maxValue, -1)) expSum := autofunc.SumAllR(autofunc.Exp{}.ApplyR(v, exponents)) expLog := autofunc.Log{}.ApplyR(v, expSum) denomLog := autofunc.AddR(expLog, maxValue) return autofunc.AddFirstR(in, autofunc.ScaleR(denomLog, -1)) }) }
func (l *lstmGate) BatchR(rv autofunc.RVector, in autofunc.RResult, n int) autofunc.RResult { if l.Peephole == nil { return l.Activation.ApplyR(rv, l.Dense.BatchR(rv, in, n)) } return autofunc.PoolR(in, func(in autofunc.RResult) autofunc.RResult { vecSize := len(in.Output()) / n var weightedInputs []autofunc.RResult var peepholed []autofunc.RResult peephole := autofunc.NewRVariable(l.Peephole, rv) for i := 0; i < n; i++ { start := vecSize * i weightedEnd := start + vecSize - len(l.Peephole.Vector) weightedInputs = append(weightedInputs, autofunc.SliceR(in, start, weightedEnd)) peepholeMe := autofunc.SliceR(in, weightedEnd, (i+1)*vecSize) peepholed = append(peepholed, autofunc.MulR(peephole, peepholeMe)) } weighted := l.Dense.BatchR(rv, autofunc.ConcatR(weightedInputs...), n) joinedPeep := autofunc.ConcatR(peepholed...) return l.Activation.ApplyR(rv, autofunc.AddR(joinedPeep, weighted)) }) }