hi there,
I've stumbled on this piece of code from reddit:
I've tried to see what it would look like with Gonum:
it's not always super pretty (especially the part that updates the weights row/row).
and, it's even slower than the original (initially b/c of the `mat.Dense.RowView` that I've modified to reuse a `mat.VecDense`+`RowViewOf`, and now it's slow b/c of interface-checks in `mat.Dot` https://github.com/sbinet-staging/goAdaline/blob/9b8316625f4170edc195b4e3cd5bb6ca6bb13f8c/main.go#L50)
see:
```
$> time ./goAdaline-ref -cycles=1000
Test error:
0.017159516933323248
Weights:
[0.629646421847802 0.5111203968481454 0.21903157034908186 -0.24872268718943477 0.113694617824979 0.03994836902175236 0.09902375643857968 0.5027786680714972 -0.015058660602257478]
real 0m0.080s
user 0m0.077s
sys 0m0.003s
$> time ./goAdaline-gonum -cycles=1000
Test error:
0.01715951693332323
Weights:
[0.6296464218478025 0.5111203968481459 0.21903157034908222 -0.2487226871894338 0.11369461782497912 0.03994836902175287 0.09902375643858036 0.5027786680714972 -0.015058660602259038]
real 0m0.278s
user 0m0.276s
sys 0m0.003s
```
here is a `pprof` output:
```
$> go tool pprof ./cpu.prof
File: goAdaline-gonum
Type: cpu
Time: Oct 3, 2017 at 9:29am (CEST)
Duration: 400.60ms, Total samples = 260ms (64.90%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top50
Showing nodes accounting for 260ms, 100% of 260ms total
flat flat% sum% cum cum%
100ms 38.46% 38.46% 260ms 100% main.main /home/binet/tmp/go/src/github.com/Plorenzo/goAdaline/main.go
30ms 11.54% 50.00% 30ms 11.54% gonum.org/v1/gonum/mat.(*VecDense).At /home/binet/tmp/go/src/gonum.org/v1/gonum/mat/index_no_bound_checks.go
30ms 11.54% 61.54% 40ms 15.38% gonum.org/v1/gonum/mat.(*VecDense).RowViewOf /home/binet/tmp/go/src/gonum.org/v1/gonum/mat/vector.go
20ms 7.69% 69.23% 20ms 7.69% gonum.org/v1/gonum/blas/gonum.Implementation.Ddot /home/binet/tmp/go/src/gonum.org/v1/gonum/blas/gonum/level1double_ddot.go
10ms 3.85% 73.08% 30ms 11.54% gonum.org/v1/gonum/blas/gonum.(*Implementation).Ddot <autogenerated>
10ms 3.85% 76.92% 10ms 3.85% gonum.org/v1/gonum/internal/asm/f64.DotUnitary /home/binet/tmp/go/src/gonum.org/v1/gonum/internal/asm/f64/dot_amd64.s
10ms 3.85% 80.77% 10ms 3.85% gonum.org/v1/gonum/mat.(*Dense).At /home/binet/tmp/go/src/gonum.org/v1/gonum/mat/index_no_bound_checks.go
10ms 3.85% 84.62% 10ms 3.85% gonum.org/v1/gonum/mat.(*Dense).RawMatrix /home/binet/tmp/go/src/gonum.org/v1/gonum/mat/dense.go
10ms 3.85% 88.46% 10ms 3.85% gonum.org/v1/gonum/mat.(*VecDense).RawVector /home/binet/tmp/go/src/gonum.org/v1/gonum/mat/vector.go
10ms 3.85% 92.31% 20ms 7.69% gonum.org/v1/gonum/mat.Sum /home/binet/tmp/go/src/gonum.org/v1/gonum/mat/matrix.go
10ms 3.85% 96.15% 20ms 7.69% runtime.assertI2I2 /usr/lib/go/src/runtime/iface.go
10ms 3.85% 100% 10ms 3.85% runtime.getitab /usr/lib/go/src/runtime/iface.go
0 0% 100% 30ms 11.54% gonum.org/v1/gonum/blas/blas64.Dot /home/binet/tmp/go/src/gonum.org/v1/gonum/blas/blas64/blas64.go
0 0% 100% 10ms 3.85% gonum.org/v1/gonum/blas/blas64.Gemv /home/binet/tmp/go/src/gonum.org/v1/gonum/blas/blas64/blas64.go
0 0% 100% 10ms 3.85% gonum.org/v1/gonum/blas/gonum.(*Implementation).Dgemv <autogenerated>
0 0% 100% 10ms 3.85% gonum.org/v1/gonum/blas/gonum.Implementation.Dgemv /home/binet/tmp/go/src/gonum.org/v1/gonum/blas/gonum/level2double.go
0 0% 100% 10ms 3.85% gonum.org/v1/gonum/mat.(*VecDense).MulVec /home/binet/tmp/go/src/gonum.org/v1/gonum/mat/vector.go
0 0% 100% 60ms 23.08% gonum.org/v1/gonum/mat.Dot /home/binet/tmp/go/src/gonum.org/v1/gonum/mat/matrix.go
0 0% 100% 30ms 11.54% main.computeError /home/binet/tmp/go/src/github.com/Plorenzo/goAdaline/main.go
0 0% 100% 260ms 100% runtime.main /usr/lib/go/src/runtime/proc.go
(pprof)
(pprof) list main
Total: 260ms
ROUTINE ======================== main.computeError in /home/binet/tmp/go/src/github.com/Plorenzo/goAdaline/main.go
0 30ms (flat, cum) 11.54% of Total
. . 198:}
. . 199:
. . 200:func computeError(data *mat.Dense, expected, weights *mat.VecDense) float64 {
. . 201:
. . 202: var errs mat.VecDense
. 10ms 203: errs.MulVec(data, weights)
. . 204: errs.SubVec(expected, &errs)
. . 205: errs.MulElemVec(&errs, &errs)
. . 206:
. 20ms 207: return mat.Sum(&errs) / float64(errs.Len())
. . 208:}
ROUTINE ======================== main.main in /home/binet/tmp/go/src/github.com/Plorenzo/goAdaline/main.go
100ms 260ms (flat, cum) 100% of Total
. . 56: var errorsTrain []float64
. . 57: var errorsValidate []float64
. . 58: var errorsTest float64
. . 59:
. . 60: // Learning
10ms 10ms 61: for cycle := 0; cycle < *cycles; cycle++ {
. . 62: var row mat.VecDense
. . 63: for i := 0; i < nrows; i++ {
. 40ms 64: row.RowViewOf(data, i)
. . 65: // Calculate estimate
. 60ms 66: estimate := mat.Dot(&row, weights)
. . 67: // Update weights (range passes values as a copy)
. . 68: raw := weights.RawVector().Data
20ms 20ms 69: for x := range raw {
70ms 100ms 70: raw[x] += *learningRate * (expectedY.At(i, 0) - estimate) * data.At(i, x)
. . 71: }
. . 72: }
. . 73:
. . 74: // Compute cycle train error
. 30ms 75: errorsTrain = append(errorsTrain, computeError(data, expectedY, weights))
. . 76: errorsValidate = append(errorsValidate, computeError(validateData, valExpectedY, weights))
. . 77: }
. . 78:
. . 79: errorsTest = computeError(testData, testExpectedY, weights)
. . 80:
```
not sure whether there is any Gonum-based more performant way to do this...
--
You received this message because you are subscribed to the Google Groups "gonum-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gonum-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Thanks Dan.I'll check how this translates performance wise.
To unsubscribe from this group and stop receiving emails from it, send an email to gonum-dev+...@googlegroups.com.
Can you pull the `f64/gemv` branch and run it with that?
To unsubscribe from this group and stop receiving emails from it, send an email to gonum-dev+unsubscribe@googlegroups.com.