Beispiel #1
0
func (wm *writtenMemory) backwardWErase() {
	n := wm.N
	m := len(wm.TopVal) / n

	mgrad := make([]float64, n*m)
	mGradG := blas64.General{Rows: n, Cols: m, Stride: m, Data: mgrad}
	hEraseGrad := blas64.Vector{Inc: 1, Data: make([]float64, m)}
	for i, weights := range wm.Ws {
		erase := wm.erase[i]
		add := wm.add[i]
		eraseV := blas64.Vector{Inc: 1, Data: erase}
		addV := blas64.Vector{Inc: 1, Data: add}
		weightsVal := blas64.Vector{Inc: 1, Data: weights.TopVal}

		for j := range mgrad {
			mgrad[j] = 0
		}
		blas64.Ger(1, weightsVal, eraseV, mGradG)
		wm.div1MWE(mgrad)
		floats.Mul(mgrad, wm.TopGrad)

		weightsV := blas64.Vector{Inc: 1, Data: weights.TopGrad}
		blas64.Gemv(blas.NoTrans, -1, mGradG, eraseV, 1, weightsV)
		blas64.Gemv(blas.NoTrans, 1, blas64.General{Rows: n, Cols: m, Stride: m, Data: wm.TopGrad}, addV, 1, weightsV)

		hErase := wm.Heads[i].EraseGrad()
		for j := range hEraseGrad.Data {
			hEraseGrad.Data[j] = 0
		}
		blas64.Gemv(blas.Trans, -1, mGradG, weightsVal, 1, hEraseGrad)
		for j, e := range erase {
			hErase[j] += hEraseGrad.Data[j] * e * (1 - e)
		}
	}
}
Beispiel #2
0
func fitnessRMSE(ind, targ *imgut.Image) float64 {
	// Images to vector
	dataInd := imgut.ToSlice(ind)
	dataTarg := imgut.ToSlice(targ)
	// (root mean square) error
	floats.Sub(dataInd, dataTarg)
	// (root mean) square error
	floats.Mul(dataInd, dataInd)
	// (root) mean square error
	totErr := floats.Sum(dataInd)
	return math.Sqrt(totErr / float64(len(dataInd)))
}
Beispiel #3
0
func MakeFitLinScale(targetImage *imgut.Image) func(*imgut.Image) float64 {
	// Pre-compute image to slice of floats
	dataTarg := imgut.ToSlice(targetImage)
	// Pre-compute average
	avgt := floats.Sum(dataTarg) / float64(len(dataTarg))
	return func(indImage *imgut.Image) float64 {
		// Images to vector
		dataInd := imgut.ToSlice(indImage)
		// Compute average pixels
		avgy := floats.Sum(dataInd) / float64(len(dataInd))
		// Difference y - avgy
		y_avgy := make([]float64, len(dataInd))
		copy(y_avgy, dataInd)
		floats.AddConst(-avgy, y_avgy)
		// Difference t - avgt
		t_avgt := make([]float64, len(dataTarg))
		copy(t_avgt, dataTarg)
		floats.AddConst(-avgt, t_avgt)
		// Multuplication (t - avgt)(y - avgy)
		floats.Mul(t_avgt, y_avgy)
		// Summation
		numerator := floats.Sum(t_avgt)
		// Square (y - avgy)^2
		floats.Mul(y_avgy, y_avgy)
		denomin := floats.Sum(y_avgy)
		// Compute b-value
		b := numerator / denomin
		// Compute a-value
		a := avgt - b*avgy

		// Compute now the scaled RMSE, using y' = a + b*y
		floats.Scale(b, dataInd)      // b*y
		floats.AddConst(a, dataInd)   // a + b*y
		floats.Sub(dataInd, dataTarg) // (a + b * y - t)
		floats.Mul(dataInd, dataInd)  // (a + b * y - t)^2
		total := floats.Sum(dataInd)  // Sum(...)
		return math.Sqrt(total / float64(len(dataInd)))
	}
}
Beispiel #4
0
func MakeFitMSE(targetImage *imgut.Image) func(*imgut.Image) float64 {
	dataTarg := imgut.ToSliceChans(targetImage, "R")
	return func(indImage *imgut.Image) float64 {
		// Get data
		dataImg := imgut.ToSliceChans(indImage, "R")
		// Difference (X - Y)
		floats.Sub(dataImg, dataTarg)
		// Squared (X - Y)^2
		floats.Mul(dataImg, dataImg)
		// Summation
		return floats.Sum(dataImg) / float64(len(dataImg))
	}
}
Beispiel #5
0
// CovarianceMatrix calculates a covariance matrix (also known as a
// variance-covariance matrix) from a matrix of data, using a two-pass
// algorithm.
//
// The weights must have length equal to the number of rows in
// input data matrix x. If cov is nil, then a new matrix with appropriate size will
// be constructed. If cov is not nil, it should have the same number of columns as the
// input data matrix x, and it will be used as the destination for the covariance
// data. Weights must not be negative.
func CovarianceMatrix(cov *mat64.SymDense, x mat64.Matrix, weights []float64) *mat64.SymDense {
	// This is the matrix version of the two-pass algorithm. It doesn't use the
	// additional floating point error correction that the Covariance function uses
	// to reduce the impact of rounding during centering.

	r, c := x.Dims()

	if cov == nil {
		cov = mat64.NewSymDense(c, nil)
	} else if n := cov.Symmetric(); n != c {
		panic(matrix.ErrShape)
	}

	var xt mat64.Dense
	xt.Clone(x.T())
	// Subtract the mean of each of the columns.
	for i := 0; i < c; i++ {
		v := xt.RawRowView(i)
		// This will panic with ErrShape if len(weights) != len(v), so
		// we don't have to check the size later.
		mean := Mean(v, weights)
		floats.AddConst(-mean, v)
	}

	if weights == nil {
		// Calculate the normalization factor
		// scaled by the sample size.
		cov.SymOuterK(1/(float64(r)-1), &xt)
		return cov
	}

	// Multiply by the sqrt of the weights, so that multiplication is symmetric.
	sqrtwts := make([]float64, r)
	for i, w := range weights {
		if w < 0 {
			panic("stat: negative covariance matrix weights")
		}
		sqrtwts[i] = math.Sqrt(w)
	}
	// Weight the rows.
	for i := 0; i < c; i++ {
		v := xt.RawRowView(i)
		floats.Mul(v, sqrtwts)
	}

	// Calculate the normalization factor
	// scaled by the weighted sample size.
	cov.SymOuterK(1/(floats.Sum(weights)-1), &xt)
	return cov
}
Beispiel #6
0
func newWrittenMemory(ws []*refocus, heads []*Head, mtm1 *writtenMemory) *writtenMemory {
	n := mtm1.N
	m := len(mtm1.TopVal) / n
	wm := writtenMemory{
		Ws:    ws,
		Heads: heads,
		Mtm1:  mtm1,

		N:       mtm1.N,
		TopVal:  make([]float64, len(mtm1.TopVal)),
		TopGrad: make([]float64, len(mtm1.TopVal)),

		erase:    makeTensor2(len(heads), m),
		add:      makeTensor2(len(heads), m),
		erasures: make([]float64, len(mtm1.TopVal)),
	}
	for i, h := range wm.Heads {
		erase := wm.erase[i]
		add := wm.add[i]
		addVec := h.AddVal()
		for j, e := range h.EraseVal() {
			erase[j] = Sigmoid(e)
			add[j] = Sigmoid(addVec[j])
		}
	}

	copy(wm.erasures, mtm1.TopVal)
	we := make([]float64, n*m)
	weG := blas64.General{Rows: n, Cols: m, Stride: m, Data: we}
	for k, ws := range wm.Ws {
		weights := blas64.Vector{Inc: 1, Data: ws.TopVal}
		erase := blas64.Vector{Inc: 1, Data: wm.erase[k]}
		for i := range we {
			we[i] = 1
		}
		blas64.Ger(-1, weights, erase, weG)
		floats.Mul(wm.erasures, we)
	}

	copy(wm.TopVal, wm.erasures)
	topG := blas64.General{Rows: n, Cols: m, Stride: m, Data: wm.TopVal}
	for k, ws := range wm.Ws {
		weights := blas64.Vector{Inc: 1, Data: ws.TopVal}
		add := blas64.Vector{Inc: 1, Data: wm.add[k]}
		blas64.Ger(1, weights, add, topG)
	}

	return &wm
}
Beispiel #7
0
// CovarianceMatrix calculates a covariance matrix (also known as a
// variance-covariance matrix) from a matrix of data, using a two-pass
// algorithm. The matrix returned will be symmetric and square.
//
// The weights wts should have the length equal to the number of rows in
// input data matrix x. If c is nil, then a new matrix with appropriate size will
// be constructed.  If c is not nil, it should be a square matrix with the same
// number of columns as the input data matrix x, and it will be used as the receiver
// for the covariance data.  Weights cannot be negative.
func CovarianceMatrix(cov *mat64.Dense, x mat64.Matrix, wts []float64) *mat64.Dense {
	// This is the matrix version of the two-pass algorithm. It doesn't use the
	// additional floating point error correction that the Covariance function uses
	// to reduce the impact of rounding during centering.

	// TODO(jonlawlor): indicate that the resulting matrix is symmetric, and change
	// the returned type from a *mat.Dense to a *mat.Symmetric.

	r, c := x.Dims()

	if cov == nil {
		cov = mat64.NewDense(c, c, nil)
	} else if covr, covc := cov.Dims(); covr != covc || covc != c {
		panic(mat64.ErrShape)
	}

	var xt mat64.Dense
	xt.TCopy(x)
	// Subtract the mean of each of the columns.
	for i := 0; i < c; i++ {
		v := xt.RawRowView(i)
		// This will panic with ErrShape if len(wts) != len(v), so
		// we don't have to check the size later.
		mean := Mean(v, wts)
		floats.AddConst(-mean, v)
	}

	var n float64
	if wts == nil {

		n = float64(r)

		cov.MulTrans(&xt, false, &xt, true)

		// Scale by the sample size.
		cov.Scale(1/(n-1), cov)
		return cov
	}

	// Multiply by the sqrt of the weights, so that multiplication is symmetric.
	sqrtwts := make([]float64, r)
	for i, w := range wts {
		if w < 0 {
			panic("stat: negative covariance matrix weights")
		}
		sqrtwts[i] = math.Sqrt(w)
	}
	// Weight the rows.
	for i := 0; i < c; i++ {
		v := xt.RawRowView(i)
		floats.Mul(v, sqrtwts)
	}

	// Calculate the normalization factor.
	n = floats.Sum(wts)
	cov.MulTrans(&xt, false, &xt, true)

	// Scale by the sample size.
	cov.Scale(1/(n-1), cov)
	return cov
}