Obviously, there is a lot from the previous chapter that we can reuse:
- The range normalization function (pixelWeight) and its isometric counterpart (reversePixelWeight)
- prepareX and prepareY
- The visualize function
For convenience sake, here they are again:
func pixelWeight(px byte) float64 { retVal := (float64(px) / 255 * 0.999) + 0.001 if retVal == 1.0 { return 0.999 } return retVal}func reversePixelWeight(px float64) byte { return byte(((px - 0.001) / 0.999) * 255)}func prepareX(M []RawImage) (retVal tensor.Tensor) { rows := len(M) cols := len(M[0]) b := make([]float64, 0, rows*cols) for i := 0; i < rows; i++ { for j := 0; j < len(M[i]); j++ { b = append(b, pixelWeight(M[i][j])) } } return tensor.New(tensor.WithShape(rows, ...