public static Tuple <Array <Real>, Array <int> > NewDownSample_MaxPooling2d(Array <Real> arr, int pool_h, int pool_w, bool ignoreBorder = true) { int x_h = arr.Shape[0]; int x_w = arr.Shape[1]; int out_h = x_h / pool_h; int out_w = x_w / pool_w; if (ignoreBorder == false) { if (((x_h ^ pool_h) >= 0) && (x_h % pool_h != 0)) { out_h++; } if (((x_w ^ pool_w) >= 0) && (x_w % pool_w != 0)) { out_w++; } } int arr_y_max = 0; int arr_x_max = 0; var poolout = NN.Array(new Real[out_h, out_w]); var switches = NN.Array(new int[out_h, out_w, 2]); for (int y_out = 0; y_out < out_h; y_out++) { int y = y_out * pool_h; int y_min = y; int y_max = Math.Min(y + pool_h, x_h); for (int x_out = 0; x_out < out_w; x_out++) { int x = x_out * pool_w; int x_min = x; int x_max = Math.Min(x + pool_w, x_w); var value = Real.NegativeInfinity; for (int arr_y = y_min; arr_y < y_max; arr_y++) { for (int arr_x = x_min; arr_x < x_max; arr_x++) { var new_value = arr.Item[arr_y, arr_x]; if (new_value > value) { value = new_value; arr_y_max = arr_y; arr_x_max = arr_x; } } } switches[y_out, x_out, 0] = arr_y_max; switches[y_out, x_out, 1] = arr_x_max; poolout[y_out, x_out] = value; } } return(Tuple.Create(poolout, switches)); }
public static Array <Real> new_Unpooling(Array <Real> delta, Array <int> switches, int pool_h, int pool_w, bool ignoreBorder = true) { var sh = new int[2]; var unpooled = NN.Array(new Real[switches.Shape[0] * pool_h, switches.Shape[1] * pool_w]); for (int y = 0; y < delta.Shape[0]; y++) { for (int x = 0; x < delta.Shape[1]; x++) { unpooled[(int)switches[y, x, 0], (int)switches[y, x, 1]] = (Real)delta[y, x]; } } return(unpooled); }