public static Vol Image_To_Vol(double[] img, int width, int hight, bool convert_grayscale) { var p = img; var w = width; var h = hight; double[] pv = new double[img.Length]; for (var i = 0; i < p.Length; i++) { pv[i] = (p[i] / 255.0 - 0.5); // normalize image pixels to [-0.5, 0.5] } var x = new Vol(w, h, 4, 0.0); x.W = pv; if (convert_grayscale) { var x1 = new Vol(w, h, 1, 0.0); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { x1.Set(i, j, 0, x.Get(i, j, 0)); } } x = x1; } return(x); }
public static Vol Augment(Vol V, int corp, int dx, int dy, bool fliplr) { //if (dx==0) //{ // dx = Util.Randi(0, V.SX - corp); //} //if (dy == 0) //{ // dy = Util.Randi(0, V.SY- corp); //} Vol W; if (corp != V.SX || dx != 0 || dy != 0) { W = new Vol(corp, corp, V.Depth, 0.0); for (int x = 0; x < corp; x++) { for (int y = 0; y < corp; y++) { if (x + dx < 0 || x + dx >= V.SX || y + dy < 0 || y + dy >= V.SY) { continue; } for (int d = 0; d < V.Depth; d++) { W.Set(x, y, d, V.Get(x + dx, y + dy, d)); } } } } else { W = V; } if (fliplr) { var W2 = W.CloneAndZero(); for (int x = 0; x < W.SX; x++) { for (int y = 0; y < W.SY; y++) { for (int d = 0; d < W.Depth; d++) { W2.Set(x, y, d, W.Get(W.SX - x - 1, y, d)); } } } W = W2; } return(W); }
public Vol Forward(Vol V, bool is_training) { this.Input = V; var tempOutput = new Vol(this.OutputWidth | 0, this.OutputHeight | 0, this.OutputDepth | 0, 0.0); var inputWidth = V.SX | 0; var inputHeight = V.SY | 0; var xy_stride = this.Stride | 0; for (int d = 0; d < this.OutputDepth; d++)//for each output depth aka filters { var f = this.Filters[d]; var x = -this.Pad | 0; var y = -this.Pad | 0; for (int ay = 0; ay < this.OutputHeight; y += xy_stride, ay++)// for each out height { x = -this.Pad | 0; for (var ax = 0; ax < this.OutputWidth; x += xy_stride, ax++) // for each out width { // xy_stride // convolve centered at this particular location var a = 0.0; for (var fy = 0; fy < f.SY; fy++) // for each element in the filter height { var oy = y + fy; // coordinates in the original input array coordinates for (var fx = 0; fx < f.SX; fx++) // for each element in the filter width { //x is current width element of the output //fx is the current width element of the filter var ox = x + fx; if (oy >= 0 && oy < inputHeight && ox >= 0 && ox < inputWidth) { for (var fd = 0; fd < f.Depth; fd++) // for each filter depth or input depth { // multiply filter pixel by image pixel and add (shared weight filter) // avoid function call overhead (x2) for efficiency, compromise modularity :( //filter (fx,fy,fd) * //input (ox,oy,fd) a += f.W[((f.SX * fy) + fx) * f.Depth + fd] * V.W[((inputWidth * oy) + ox) * V.Depth + fd]; } } } } a += this.Biases.W[d]; tempOutput.Set(ax, ay, d, a); } } } this.Output = tempOutput; return(this.Output); }
public Vol Forward(Vol V, bool is_training) { this.in_Act = V; var A = new Vol(this.OutputWidth, this.OutputHeight, this.OutputDepth, 0.0); var n = 0; // a counter for switches for (var d = 0; d < this.OutputDepth; d++) { var x = -this.Pad; var y = -this.Pad; for (var ax = 0; ax < this.OutputWidth; x += this.Stride, ax++) { y = -this.Pad; for (var ay = 0; ay < this.OutputHeight; y += this.Stride, ay++) { // convolve centered at this particular location double a = -99999; // hopefully small enough ;\ var winx = -1; var winy = -1; for (var fx = 0; fx < this.SX; fx++) { for (var fy = 0; fy < this.SY; fy++) { var oy = y + fy; var ox = x + fx; if (oy >= 0 && oy < V.SY && ox >= 0 && ox < V.SX) { var v = V.Get(ox, oy, d); // perform max pooling and store pointers to where // the max came from. This will speed up backprop // and can help make nice visualizations in future if (v > a) { a = v; winx = ox; winy = oy; } } } } this.Switchx[n] = winx; this.Switchy[n] = winy; n++; A.Set(ax, ay, d, a); } } } this.Output = A; return(this.Output); }
private void Conv(Vol V, bool is_training, Vol A) { var n = 0; // a counter for switches for (int d = 0; d < this.OutputDepth; d++) { for (var ax = 0; ax < this.OutputWidth; ax++) { var x = -this.Pad; x += (this.Stride * ax); for (var ay = 0; ay < this.OutputHeight; ay++) { var y = -this.Pad; y += (this.Stride * ay); // convolve centered at this particular location float a = -99999; // hopefully small enough ;\ var winx = -1; var winy = -1; for (var fx = 0; fx < this.KernelWidth; fx++) { for (var fy = 0; fy < this.KernelHeight; fy++) { var oy = y + fy; var ox = x + fx; if (oy >= 0 && oy < V.Height && ox >= 0 && ox < V.Width) { var v = V.Get(ox, oy, d); // perform max pooling and store pointers to where // the max came from. This will speed up backprop // and can help make nice visualizations in future if (v > a) { a = v; winx = ox; winy = oy; } } } } this.Switchx[n] = winx; this.Switchy[n] = winy; n++; A.Set(ax, ay, d, a); } } } //var source = Enumerable.Range(0, this.OutputDepth); //var pquery = from num in source.AsParallel() // select num; // pquery.ForAll((d) => ); }
private void LRNforWidth(Vol V, Vol A, double n2, int x) { for (var y = 0; y < V.SY; y++) { for (var i = 0; i < V.Depth; i++) { var ai = V.Get(x, y, i); // normalize in a window of size n var den = 0.0; for (var j = Math.Max(0, i - n2); j <= Math.Min(i + n2, V.Depth - 1); j++) { var aa = V.Get(x, y, (int)j); den += aa * aa; } den *= this.alpha / this.n; den += this.k; this.S_cache_.Set(x, y, i, den); // will be useful for backprop den = Math.Pow(den, this.beta); A.Set(x, y, i, ai / den); } } }
private void ConvOverRows(Vol V, Vol tempOutput, int inputWidth, int inputHeight, int xy_stride, int d, int ay) { var y = (-this.Pad | 0) + (xy_stride * ay); var f = this.Filters[d]; for (var ax = 0; ax < this.OutputWidth; ax++) // for each out width { var x = (-this.Pad | 0) + (xy_stride * ax); // convolve centered at this particular location var a = 0.0; for (var fy = 0; fy < f.Height; fy++) // for each element in the filter height { var oy = y + fy; // coordinates in the original input array coordinates for (var fx = 0; fx < f.Width; fx++) // for each element in the filter width { //x is current width element of the output //fx is the current width element of the filter var ox = x + fx; if (oy >= 0 && oy < inputHeight && ox >= 0 && ox < inputWidth) { for (var fd = 0; fd < f.Depth; fd++) // for each filter depth or input depth { // multiply filter pixel by image pixel and add (shared weight filter) // avoid function call overhead (x2) for efficiency, compromise modularity :( //filter (fx,fy,fd) * //input (ox,oy,fd) a += f.W[((f.Width * fy) + fx) * f.Depth + fd] * V.W[((inputWidth * oy) + ox) * V.Depth + fd]; } } } } a += this.Biases.W[d]; tempOutput.Set(ax, ay, d, (float)a); } }