Browse Source

proper test for flow

luis 7 years ago
parent
commit
93ee4798e6
4 changed files with 103 additions and 17 deletions
  1. 44 9
      go/src/demos/cmd/noui/flow.go
  2. 39 4
      go/src/demos/ops/ml/gonumops.go
  3. 3 3
      go/src/flow/flow_test.go
  4. 17 1
      go/src/flow/operation.go

+ 44 - 9
go/src/demos/cmd/noui/flow.go

@@ -28,6 +28,7 @@ func main() {
 	// Load minst somehow 28x28 784
 	// Load minst somehow 28x28 784
 	nSample := 1
 	nSample := 1
 
 
+	learningRate := float64(1.0)
 	// Load minst into floats array
 	// Load minst into floats array
 
 
 	// Make a matrix from the weights variable
 	// Make a matrix from the weights variable
@@ -42,23 +43,57 @@ func main() {
 	inp := f.Op("matNew", 2, 1, f.In(0))
 	inp := f.Op("matNew", 2, 1, f.In(0))
 
 
 	// Layer1 weights
 	// Layer1 weights
-	w1 := f.Op("matNew", 5, 2, f.Var("w1", f.Op("normFloat", 5*2)))
+	w1 := f.Op("matNew", 3, 2, f.Var("w1", f.Op("normFloat", 3*2)))
+	// Layour 1 result
+	l1res := f.Op("matSigmoid", f.Op("matMul", w1, inp))
 
 
-	l1op := f.Op("matSigmoid", f.Op("matMul", w1, inp))
+	// weights 2
+	w2 := f.Op("matNew", 2, 3, f.Var("w2", f.Op("normFloat", 2*3)))
 
 
-	// 5 inputs 2 output
-	w2 := f.Op("matNew", 2, 5, f.Var("w2", f.Op("normFloat", 2*5)))
+	// Layour 2 result
+	l2res := f.Op("matSigmoid", f.Op("matMul", w2, l1res))
 
 
-	// Previous layer result
-	l2op := f.Op("matSigmoid", f.Op("matMul", w2, l1op))
+	// Network output
+	netRes := l2res
+
+	//////////////////////
+	// Create trainer ops
+	/////////
+	// Backpropagation
+
+	log.Println("Grab error from output layer")
+	errOp := f.Op("matSub", inp, netRes)
+	log.Println(errOp.Process(sample))
+
+	log.Println("Calculate deltas")
+	deltaOp := f.Op("matMulElem", f.Op("matSigmoidD", l2res), errOp)
+	log.Println(deltaOp.Process(sample))
+
+	log.Println("Multiplying the following matrixes")
+	log.Println(l2res.Process(sample))
+	log.Println(deltaOp.Process(sample))
+	log.Println("Calculate changes to apply to hidden layer")
+	outChangesOp := f.Op("matMul", l2res, deltaOp)
+	log.Println(outChangesOp.Process(sample))
+
+	outChangesOp = f.Op("matScale", outChangesOp, learningRate)
+
+	train1 := f.SetVar("w2", f.Op("matAdd", outChangesOp, w1))
+	// Set Var w1
+	//
+	log.Println("Training 1")
+	log.Println(train1.Process(sample))
+
+	log.Println("deltaOutputLayer")
+	log.Println(deltaOp.Process(sample))
 
 
 	// Do we need this?
 	// Do we need this?
-	netOp := f.Op("toFloatArr", l2op)
+	//netOp := f.Op("toFloatArr", l2op)
 
 
-	netResI, _ := netOp.Process(sample)
+	/*netResI, _ := netOp.Process(sample)
 	res := netResI.([]float64)
 	res := netResI.([]float64)
 	log.Println("Network result:", res)
 	log.Println("Network result:", res)
-	log.Println("Loss", res[0]-sample[0], res[1]-sample[1])
+	log.Println("Error", sample[0]-res[0], sample[1]-res[1])*/
 	// Back propagation
 	// Back propagation
 
 
 	//log.Println(layerRes.Process(samples[0]))
 	//log.Println(layerRes.Process(samples[0]))

+ 39 - 4
go/src/demos/ops/ml/gonumops.go

@@ -21,7 +21,12 @@ func New() *registry.R {
 		r.Add(matNew).Inputs("rows", "columns", "data"),
 		r.Add(matNew).Inputs("rows", "columns", "data"),
 		r.Add(
 		r.Add(
 			normFloat,
 			normFloat,
+			matNewRand,
+			matAdd,
+			matSub,
 			matMul,
 			matMul,
+			matMulElem,
+			matScale,
 			matTranspose,
 			matTranspose,
 			matSigmoid,
 			matSigmoid,
 			matSigmoidD,
 			matSigmoidD,
@@ -45,17 +50,47 @@ func normFloat(n int) []float64 {
 func matNew(r, c int, data []float64) Matrix {
 func matNew(r, c int, data []float64) Matrix {
 	return mat.NewDense(r, c, data)
 	return mat.NewDense(r, c, data)
 }
 }
+func matNewRand(r, c int) Matrix {
+	data := normFloat(r * c)
+
+	return mat.NewDense(r, c, data)
+
+}
+
+func matAdd(a Matrix, b Matrix) Matrix {
+	var r mat.Dense
+	r.Add(a, b)
+	return &r
+}
+func matSub(a, b Matrix) Matrix {
+	var r mat.Dense
+	r.Sub(a, b)
+	return &r
+}
 
 
 func matMul(a Matrix, b Matrix) Matrix {
 func matMul(a Matrix, b Matrix) Matrix {
-	var c mat.Dense
-	c.Mul(a, b)
-	return &c
+	var r mat.Dense
+	r.Mul(a, b)
+	return &r
+}
+func matMulElem(a, b Matrix) Matrix {
+	var r mat.Dense
+	r.MulElem(a, b)
+	return &r
+}
+
+// Scalar per element multiplication
+func matScale(a Matrix, f float64) Matrix {
+	var r mat.Dense
+	r.Scale(f, a)
+	return &r
 }
 }
 
 
 func matTranspose(a Matrix) Matrix {
 func matTranspose(a Matrix) Matrix {
 	return a.T()
 	return a.T()
 }
 }
 
 
+// sigmoid Activator
 func matSigmoid(a Matrix) Matrix {
 func matSigmoid(a Matrix) Matrix {
 	// Should be a vector perhaps
 	// Should be a vector perhaps
 	r, c := a.Dims()
 	r, c := a.Dims()
@@ -78,6 +113,7 @@ func matSigmoidD(a Matrix) Matrix {
 	}
 	}
 	return ret
 	return ret
 }
 }
+
 func toFloatArr(a Matrix) []float64 {
 func toFloatArr(a Matrix) []float64 {
 	r, c := a.Dims()
 	r, c := a.Dims()
 	ret := make([]float64, r*c)
 	ret := make([]float64, r*c)
@@ -87,7 +123,6 @@ func toFloatArr(a Matrix) []float64 {
 		}
 		}
 	}
 	}
 	return ret
 	return ret
-
 }
 }
 
 
 func activator(v float64) float64 {
 func activator(v float64) float64 {

+ 3 - 3
go/src/flow/flow_test.go

@@ -4,7 +4,6 @@ import (
 	"bytes"
 	"bytes"
 	"encoding/json"
 	"encoding/json"
 	"testing"
 	"testing"
-	"time"
 
 
 	"flow"
 	"flow"
 
 
@@ -148,7 +147,8 @@ func TestCache(t *testing.T) {
 	}
 	}
 }
 }
 
 
-func TestHandler(t *testing.T) {
+// XXX: Create proper test
+/*func TestHandler(t *testing.T) {
 	f, op := prepareComplex()
 	f, op := prepareComplex()
 	f.Hook(flow.Hook{
 	f.Hook(flow.Hook{
 		Wait:   func(op flow.Operation, triggerTime time.Time) { t.Logf("[%s] Wait", op) },
 		Wait:   func(op flow.Operation, triggerTime time.Time) { t.Logf("[%s] Wait", op) },
@@ -157,7 +157,7 @@ func TestHandler(t *testing.T) {
 		Error:  func(op flow.Operation, triggerTime time.Time, err error) { t.Logf("[%s] Error %v", op, err) },
 		Error:  func(op flow.Operation, triggerTime time.Time, err error) { t.Logf("[%s] Error %v", op, err) },
 	})
 	})
 	op.Process()
 	op.Process()
-}
+}*/
 
 
 func TestLocalRegistry(t *testing.T) {
 func TestLocalRegistry(t *testing.T) {
 	a := assert.A(t)
 	a := assert.A(t)

+ 17 - 1
go/src/flow/operation.go

@@ -114,9 +114,25 @@ func (f *Flow) Var(name string, initial Data) Operation {
 		}
 		}
 		return val, nil
 		return val, nil
 	}
 	}
-
 	return op
 	return op
+}
 
 
+// SetVar a variable from operation/constant
+func (f *Flow) SetVar(name string, data Data) Operation {
+	inputs := f.makeInputs(data)
+	op := f.newOperation("setvar", inputs)
+	op.name = fmt.Sprintf("(setvar)<%s>", name)
+	op.executor = func(sess *Session, ginputs ...Data) (Data, error) {
+		f.hooks.wait(op)
+		res, err := sess.RunList(op.inputs, ginputs...)
+		if err != nil {
+			return nil, err
+		}
+		f.Data[name] = res[0]
+		return res[0], nil
+	}
+
+	return op
 }
 }
 
 
 // Op operation from registry
 // Op operation from registry