string PaddingInBytes(string value, PadType type, int byteCount) { Encoding enc = Encoding.GetEncoding("Shift_JIS"); if (byteCount < enc.GetByteCount(value)) { // valueが既定のバイト数を超えている場合は、切り落とし value = value.Substring(0, byteCount); } switch (type) { case PadType.Char: // 文字列の場合 左寄せ+空白埋め return(value.PadRight(byteCount - (enc.GetByteCount(value) - value.Length))); case PadType.Number: // 数値の場合 右寄せ+0埋め return(value.PadLeft(byteCount, ' ')); default: // 上記以外は全部空白 return(value.PadLeft(byteCount)); } }
internal void HitByPad(PadType padType, Vector3 forceDir, Vector3 impulse) { if (isPlayer) { forceDir *= 1.1f; } if (padType == PadType.Persistant) { AddImpulse(GameSettings.instance.data.percistantPadJumpImpulse * forceDir); } else if (padType == PadType.Bottom) { AddImpulse(impulse); } else if (padType == PadType.Destructable) { AddImpulse(GameSettings.instance.data.destructablePadJumpImpulse * forceDir); } else if (padType == PadType.Finish) { anim.SetLayerWeight(1, 0); anim.SetTrigger("victory"); } }
/// <summary> /// Padding the specified str. /// </summary> /// <returns>The result string.</returns> /// <param name="str">String to be padded.</param> /// <param name="length">Total Length.</param> /// <param name="padStr">Padding string, default is " ".</param> /// <param name="type">Pad Type,padleft ,padright or padboth.</param> public static string Pad(this string str, int length, string padStr = null, PadType type = PadType.Left) { if (str.Length >= length) { return(str); } int needPading = length - str.Length; int leftPadding = 0, rightPadding = 0; switch (type) { case PadType.Left: leftPadding = needPading; break; case PadType.Right: rightPadding = needPading; break; case PadType.Both: leftPadding = Convert.ToInt32(Math.Floor(needPading / 2f)); rightPadding = Convert.ToInt32(Math.Ceiling(needPading / 2f)); break; } padStr = padStr == null || padStr.Length <= 0 ? " " : padStr; return(Repeat(padStr, leftPadding / padStr.Length + 1).Substring(0, leftPadding) + str + Repeat(padStr, rightPadding / padStr.Length + 1).Substring(0, rightPadding)); }
public static Conv2DInfo computePool2DInfo(int[] inShape, int[] filterSize, int[] strides, PadType pad, roundingMode roundingMode, ConvDataFormat dataFormat = ConvDataFormat.channelsLast, Nullable <int> padValue = null) { var filterHeight = filterSize[0]; var filterWidth = filterSize[1]; int[] filterShape; if (dataFormat == ConvDataFormat.channelsLast) { filterShape = new int[] { filterHeight, filterWidth, inShape[3], inShape[3] }; } else if (dataFormat == ConvDataFormat.channelsFirst) { filterShape = new int[] { filterHeight, filterWidth, inShape[1], inShape[1] }; } else { throw new Exception("Unknown dataFormat"); } var dilations = 1; return(computeConv2DInfo( inShape, filterShape, strides, new int[] { dilations }, pad, roundingMode, false, dataFormat, padValue)); }
/// <summary> /// Computes a 1D convolution over the input x. /// </summary> /// <param name="x">The input tensor, of Rank 3 or Rank 2, of shape /// "[batch, width, inChannels]". If Rank 2, batch of 1 is assumed.</param> /// <param name="filter">The filter, Rank 3, of shape /// "[filterWidth, inDepth, outDepth]".</param> /// <param name="stride">The number of entries by which the filter is moved right at /// each step.</param> /// <param name="pad">The type of padding algorithm. /// - "same" and stride 1: output will be of same size as input, /// regardless of filter size. /// - "valid": output will be smaller than input if filter is larger /// than 1x1. /// - For more info, see this guide: /// [https://www.tensorflow.org/api_guides/python/nn#Convolution]( /// https://www.tensorflow.org/api_guides/python/nn#Convolution) /// </param> /// <param name="dilation">The dilation rate in which we sample input values in /// atrous convolution. Defaults to "1". If it is greater than 1, then /// stride must be "1".</param> /// <param name="dimRoundingMode">The rounding mode used when computing output /// dimensions if pad is a number. If none is provided, it will not round /// and error if the output is of fractional size.</param> /// <param name="padvalue">the value of pad if pad is number</param> /// <returns></returns> public static Tensor conv1d(this Tensor x, Tensor filter, int stride, PadType pad, int dilation = 1, roundingMode dimRoundingMode = roundingMode.none, Nullable <int> padvalue = null) { var input3D = x; var reshapedTo3D = false; if (x.Rank == 2) { reshapedTo3D = true; input3D = x.as3D(1, x.Shape[0], x.Shape[1]); } var filter4D = filter.as4D(1, filter.Shape[0], filter.Shape[1], filter.Shape[2]); var input4D = input3D.as4D(input3D.Shape[0], 1, input3D.Shape[1], input3D.Shape[2]); int[] strides = new int[] { 1, stride }; int[] dilations = new int[] { 1, dilation }; var res = conv2d( input4D, filter4D, strides, pad, dilations, dimRoundingMode, padvalue); if (reshapedTo3D) { return(res.as2D(res.Shape[2], res.Shape[3])); } return(res.as3D(res.Shape[0], res.Shape[2], res.Shape[3])); }
public Padding(int count, PadType padType) { padTypes = Enumerable.Repeat(padType, count).ToArray(); splitPattern = DEFAULT_SPLIT_PATTERN; columnSeparator = " "; text = ""; sizes = new int[0]; }
/// <summary> /// Computes the 2D max pooling of an image. /// </summary> /// <param name="x">The input tensor, of rank 4 or rank 3 of shape /// `[batch, height, width, inChannels]`. If rank 3, batch of 1 is assumed</param> /// <param name="filterSize">The filter size, a tuple `[filterHeight, filterWidth]`.</param> /// <param name="strides">The strides of the pooling: `[strideHeight, strideWidth]`.</param> /// <param name="pad"> The type of padding algorithm. /// - `same` and stride 1: output will be of same size as input, /// regardless of filter size. /// - `valid`: output will be smaller than input if filter is larger /// than 1x1. /// - For more info, see this guide: /// [https://www.tensorflow.org/api_guides/python/nn#Convolution]( /// https://www.tensorflow.org/api_guides/python/nn#Convolution)</param> /// <param name="dimRoundingMode">The rounding mode used when computing output /// dimensions if pad is a number. If none is provided, it will not round /// and error if the output is of fractional size.</param> /// <param name="padvalue"></param> /// <returns></returns> public static Tensor maxPool(this Tensor x, int[] filterSize, int[] strides, PadType pad, roundingMode dimRoundingMode = roundingMode.none, Nullable <int> padvalue = null) { Tensor x4D = null; var reshapedTo4D = false; if (x.Rank == 3) { reshapedTo4D = true; x4D = x.as4D(1, x.Shape[0], x.Shape[1], x.Shape[2]); } else { x4D = x as Tensor; } var convInfo = Util.computePool2DInfo( x4D.Shape, filterSize, strides, pad, dimRoundingMode, ConvDataFormat.channelsLast, padvalue); Func <Tensor, List <Tensor>, NamedGradientMap> grad = (Tensor dy, List <Tensor> s) => { NamedGradientMap g = new NamedGradientMap(); g.gradient = new Dictionary <string, Func <Tensor> >(); g.gradient.Add("x", () => { var y4D = s[0]; return(maxPoolBackprop(dy, x4D, y4D, filterSize, strides, pad, dimRoundingMode, padvalue)); }); return(g); }; Engine e = ENV.engine; ForwardFunc f = (IBackend bk, Func <Tensor, Tensor> saved) => { return(saved(bk.maxPool(x4D, convInfo))); }; var inputs = new Dictionary <string, Tensor>(); inputs.Add("x", x4D); var res = e.runKernel(f, inputs, grad); if (reshapedTo4D) { return(res.as3D(res.Shape[1], res.Shape[2], res.Shape[3])); } return(res); }
static Tensor depthwiseConv2dDerInput(int[] xShape, Tensor dy, Tensor filter, int[] strides, PadType pad, roundingMode dimRoundingMode, Nullable <int> padValue = null) { int[] xShape4D = xShape; Tensor dy4D = null; var reshapedTo4D = false; if (dy.Rank == 3) { reshapedTo4D = true; dy4D = dy.as4D(1, dy.Shape[0], dy.Shape[1], dy.Shape[2]); xShape4D = new int[] { 1, xShape[0], xShape[1], xShape[2] }; } else { dy4D = dy as Tensor; } var inDepth = xShape4D[3]; var outDepth = dy4D.Shape[3]; var dilations = 1; var convInfo = Util.computeConv2DInfo( xShape4D, filter.Shape, strides, new int[] { dilations, dilations }, pad, dimRoundingMode, false, ConvDataFormat.channelsLast, padValue); Engine e = ENV.engine; ForwardFunc f = (IBackend bk, Func <Tensor, Tensor> saved) => { return(bk.depthwiseConv2DDerInput(dy4D, filter, convInfo)); }; var inputs = new Dictionary <string, Tensor>(); inputs.Add("dy4D", dy4D); var res = e.runKernel(f, inputs); if (reshapedTo4D) { return(res.as3D(res.Shape[1], res.Shape[2], res.Shape[3])); } return(res); }
/// <summary> /// Computes the backprop of a max pool. /// </summary> /// <param name="dy">The dy error, of rank 4 or rank 3 of shape /// [batchSize, height, width, channels]. If rank 3, batch of 1 is assumed.</param> /// <param name="input">The original input image, of rank 4, of shape /// [batchSize, height, width, channels].</param> /// <param name="output ">The original output image, of rank 4, of shape /// [batchSize, outHeight, outWidth, channels].</param> /// <param name="filterSize">The filter size, a tuple [filterHeight, filterWidth].</param> /// <param name="strides">The strides of the pooling: [strideHeight, strideWidth].</param> /// <param name="pad">A string from: 'same', 'valid'. The type of padding algorithm used in the forward prop of the op.</param> /// <param name="dimRoundingMode">A string from: 'ceil', 'round', 'floor'. The /// rounding mode used when computing output dimensions if pad is a /// number. If none is provided, it will not round and error if the output /// is of fractional size.</param> /// <param name="padvalue"></param> /// <returns></returns> private static Tensor maxPoolBackprop(Tensor dy, Tensor input, Tensor output, int[] filterSize, int[] strides, PadType pad, roundingMode dimRoundingMode, int?padvalue) { var convInfo = Util.computePool2DInfo( input.Shape, filterSize, strides, pad, dimRoundingMode, ConvDataFormat.channelsLast, padvalue); Engine e = ENV.engine; ForwardFunc f = (IBackend bk, Func <Tensor, Tensor> saved) => { return(bk.maxPoolBackprop(dy, input, output, convInfo)); }; var inputs = new Dictionary <string, Tensor>(); inputs.Add("dy", dy); inputs.Add("input", input); var res = e.runKernel(f, inputs); return(res); }
/// <summary> /// Computes the backprop of an avg pool. /// </summary> /// <param name="dy">The dy error, of rank 4 or rank 3 of shape /// [batchSize, height, width, channels]. If rank 3, batch of 1 is assumed</param> /// <param name="input">The input image, of rank 4 or rank 3 of shape /// [batchSize, height, width, channels]. If rank 3, batch of 1 is assumed</param> /// <param name="filterSize">The filter size, a tuple [filterHeight, filterWidth].</param> /// <param name="strides">The strides of the pooling: [strideHeight, strideWidth].</param> /// <param name="pad"> A string from: 'same', 'valid'. The type of padding algorithm used in the forward prop of the op.</param> /// <param name="padvalue"></param> /// <returns></returns> private static Tensor avgPoolBackprop(Tensor dy, Tensor input, int[] filterSize, int[] strides, PadType pad, int?padvalue) { Tensor input4D = null; Tensor dy4D = null; var reshapedTo4D = false; if (input.Rank == 3) { reshapedTo4D = true; input4D = input.as4D(1, input.Shape[0], input.Shape[1], input.Shape[2]); dy4D = dy.as4D(1, dy.Shape[0], dy.Shape[1], dy.Shape[2]); } else { input4D = input as Tensor; dy4D = dy as Tensor; } var convInfo = Util.computePool2DInfo( input4D.Shape, filterSize, strides, pad, roundingMode.none, ConvDataFormat.channelsLast, padvalue); Engine e = ENV.engine; ForwardFunc f = (IBackend bk, Func <Tensor, Tensor> saved) => { return(bk.avgPoolBackprop(dy4D, input4D, convInfo)); }; var inputs = new Dictionary <string, Tensor>(); inputs.Add("dy4D", dy4D); inputs.Add("input4D", input4D); var res = e.runKernel(f, inputs); if (reshapedTo4D) { return(res.as3D(res.Shape[1], res.Shape[2], res.Shape[3])); } return(res); }
static Tensor depthwiseConv2dDerFilter(this Tensor x, Tensor dy, int[] filterShape, int[] strides, PadType pad, roundingMode dimRoundingMode = roundingMode.none, Nullable <int> padValue = null) { Tensor x4D = null; if (x.Rank == 3) { x4D = x.as4D(1, x.Shape[0], x.Shape[1], x.Shape[2]); } else { x4D = x as Tensor; } Tensor dy4D = null; if (dy.Rank == 3) { dy4D = dy.as4D(1, dy.Shape[0], dy.Shape[1], dy.Shape[2]); } else { dy4D = dy as Tensor; } var dilations = 1; var convInfo = Util.computeConv2DInfo( x4D.Shape, filterShape, strides, new int[] { dilations, dilations }, pad, dimRoundingMode, false, ConvDataFormat.channelsLast, padValue); Engine e = ENV.engine; ForwardFunc f = (IBackend bk, Func <Tensor, Tensor> saved) => { return(bk.depthwiseConv2DDerFilter(x4D, dy4D, convInfo)); }; var inputs = new Dictionary <string, Tensor>(); inputs.Add("x4D", x4D); inputs.Add("dy4D", dy4D); return(e.runKernel(f, inputs)); }
string PaddingInBytes(string value, PadType type, int byteCount) { Encoding enc = Encoding.GetEncoding("Shift_JIS"); if (byteCount < enc.GetByteCount(value)) { // valueが既定のバイト数を超えている場合は、切り落とし value = value.Substring(0, byteCount); } switch (type) { case PadType.Char: // 文字列の場合 左寄せ+空白埋め return value.PadRight(byteCount - (enc.GetByteCount(value) - value.Length)); case PadType.Number: // 数値の場合 右寄せ+0埋め return value.PadLeft(byteCount, ' '); default: // 上記以外は全部空白 return value.PadLeft(byteCount); } }
/// <summary>Returns a new instance of the appropriate class of an object based on its object ID.</summary> /// <param name="objectID">The object ID of the new object.</param> public static GeneralObject GetNewObjectInstance(PadType objectID) => GetNewObjectInstance((int)objectID);
/// <summary>Creates a new instance of the <seealso cref="ObjectIDAttribute"/> attribute.</summary> /// <param name="objectID">The object ID of the <seealso cref="Pad"/>.</param> public ObjectIDAttribute(PadType objectID) : this((int)objectID) { }
public static string Pad(string text, PadType type, int maximumLength, char paddingCharacter = ' ') => type switch {
/// <summary> /// 2-D convolution with separable filters. /// /// Performs a depthwise convolution that acts separately on channels followed /// by a pointwise convolution that mixes channels. Note that this is /// separability between dimensions [1, 2] and 3, not spatial separability /// between dimensions 1 and 2. /// /// See /// [https://www.tensorflow.org/api_docs/python/tf/nn/separable_conv2d]( /// https://www.tensorflow.org/api_docs/python/tf/nn/separable_conv2d) /// for more details. /// </summary> /// <param name="x">The input tensor, of rank 4 or rank 3, of shape /// `[batch, height, width, inChannels]`. If rank 3, batch of 1 is /// assumed.</param> /// <param name="depthwiseFilter">The depthwise filter tensor, rank 4, of shape /// `[filterHeight, filterWidth, inChannels, channelMultiplier]`. This is /// the filter used in the first step.</param> /// <param name="pointwiseFilter">The pointwise filter tensor, rank 4, of shape /// `[1, 1, inChannels * channelMultiplier, outChannels]`. This is /// the filter used in the second step.</param> /// <param name="strides">The strides of the convolution: `[strideHeight, /// strideWidth]`. If strides is a single number, then `strideHeight == /// strideWidth`.</param> /// <param name="pad"> The type of padding algorithm. /// - `same` and stride 1: output will be of same size as input, /// regardless of filter size. /// - `valid`: output will be smaller than input if filter is larger /// than 1x1. /// - For more info, see this guide: /// [https://www.tensorflow.org/api_guides/python/nn#Convolution]( /// https://www.tensorflow.org/api_guides/python/nn#Convolution)</param> /// <param name="dilation">The dilation rates: `[dilationHeight, dilationWidth]` /// in which we sample input values across the height and width dimensions /// in atrous convolution. Defaults to `[1, 1]`. If `rate` is a single /// number, then `dilationHeight == dilationWidth`. If it is greater than /// 1, then all values of `strides` must be 1.</param> /// <param name="padvalue">the value of pad if pad is number</param> /// <returns></returns> public static Tensor separableConv2d(this Tensor x, Tensor depthwiseFilter, Tensor pointwiseFilter, int[] strides, PadType pad , int[] dilation, Nullable <int> padvalue = null) { var x4D = x; var reshapedTo4D = false; if (x.Rank == 3) { reshapedTo4D = true; x4D = x.as4D(1, x.Shape[0], x.Shape[1], x.Shape[2]); } Util.assert( x4D.Rank == 4, "Error in separableConv2d: input must be Rank 4, but got " + "Rank ${x4D.Rank}."); Util.assert( depthwiseFilter.Rank == 4, "Error in separableConv2d: depthwise filter must be Rank 4, but got " + "Rank ${depthwiseFilter.Rank}."); Util.assert( pointwiseFilter.Rank == 4, "Error in separableConv2d: pointwise filter must be Rank 4, but got " + "Rank ${depthwiseFilter.Rank}."); Util.assert( pointwiseFilter.Shape[0] == 1, "Error in separableConv2d: the first dimension of pointwise filter " + " must be 1, but got ${pointwiseFilter.shape[0]}."); Util.assert( pointwiseFilter.Shape[1] == 1, "Error in separableConv2d: the second dimension of pointwise filter " + " must be 1, but got ${pointwiseFilter.shape[1]}."); var inChannels = depthwiseFilter.Shape[2]; var channelMultiplier = depthwiseFilter.Shape[3]; Util.assert( pointwiseFilter.Shape[2] == inChannels * channelMultiplier, "Error in separableConv2d: the third dimension of pointwise filter " + "must be ${inChannels * channelMultiplier}, " + "but got ${pointwiseFilter.shape[2]}."); var depthwise = depthwiseConv2d( x4D, depthwiseFilter, strides, pad, dilation, roundingMode.none, padvalue); var pointwiseStride = 1; var res = conv2d( depthwise, pointwiseFilter, new int[] { pointwiseStride, pointwiseStride }, PadType.valid); if (reshapedTo4D) { return(res.as3D(res.Shape[1], res.Shape[2], res.Shape[3])); } return(res); }
public static Conv2DInfo computeConv2DInfo(int[] inShape, int[] filterShape, int[] strides, int[] dilations, PadType pad, roundingMode roundingMode = roundingMode.none, bool depthwise = false, ConvDataFormat dataFormat = ConvDataFormat.channelsLast, Nullable <int> padValue = null) { var batchSize = -1; var inHeight = -1; var inWidth = -1; var inChannels = -1; if (dataFormat == ConvDataFormat.channelsLast) { batchSize = inShape[0]; inHeight = inShape[1]; inWidth = inShape[2]; inChannels = inShape[3]; } else { batchSize = inShape[0]; inChannels = inShape[1]; inHeight = inShape[2]; inWidth = inShape[3]; } var filterHeight = filterShape[0]; var filterWidth = filterShape[1]; var filterChannels = filterShape[3]; var strideHeight = strides[0]; var strideWidth = strides[1]; var dilationHeight = dilations[0]; int dilationWidth = 0; if (dilations.Length > 1) { dilationWidth = dilations[1]; } else { dilationWidth = dilations[0]; } var effectiveFilterHeight = getEffectiveFilterSize(filterHeight, dilationHeight); var effectiveFilterWidth = getEffectiveFilterSize(filterWidth, dilationWidth); var d = getPadAndOutInfo( pad, inHeight, inWidth, strideHeight, strideWidth, effectiveFilterHeight, effectiveFilterWidth, roundingMode, padValue); var padInfo = d.Item1; var outHeight = d.Item2; var outWidth = d.Item3; var outChannels = depthwise ? filterChannels * inChannels : filterChannels; int[] outShape = null; if (dataFormat == ConvDataFormat.channelsFirst) { outShape = new int[] { batchSize, outChannels, outHeight, outWidth }; } else if (dataFormat == ConvDataFormat.channelsLast) { outShape = new int[] { batchSize, outHeight, outWidth, outChannels }; } return(new Conv2DInfo() { batchSize = batchSize, dataFormat = dataFormat, inHeight = inHeight, inWidth = inWidth, inChannels = inChannels, outHeight = outHeight, outWidth = outWidth, outChannels = outChannels, padInfo = padInfo, strideHeight = strideHeight, strideWidth = strideWidth, filterHeight = filterHeight, filterWidth = filterWidth, dilationHeight = dilationHeight, dilationWidth = dilationWidth, inShape = inShape, outShape = outShape, filterShape = filterShape }); }
/// <summary> /// Computes the transposed 2D convolution of an image, also known as a /// deconvolution. /// </summary> /// <param name="x">The input image, of Rank 4 or Rank 3, of shape /// "[batch, height, width, inDepth]". If Rank 3, batch of 1 is assumed.</param> /// <param name="filter">The filter, Rank 4, of shape /// "[filterHeight, filterWidth, outDepth, inDepth]". /// "inDepth" must match "inDepth" in "x".</param> /// <param name="outputShape">outputShape Output shape, of Rank 4 or Rank 3: /// "[batch, height, width, outDepth]". If Rank 3, batch of 1 is assumed.</param> /// <param name="strides">The strides of the original convolution: /// "[strideHeight, strideWidth]".</param> /// <param name="pad">The type of padding algorithm used in the non-transpose version /// of the op.</param> /// <param name="dimRoundingMode">The rounding mode used when computing output /// dimensions if pad is a number. If none is provided, it will not round /// and error if the output is of fractional size.</param> /// <param name="padvalue">the value of pad if pad is number</param> /// <returns></returns> public static Tensor conv2dTranspose(this Tensor x, Tensor filter, int[] outputShape, int[] strides, PadType pad, roundingMode dimRoundingMode = roundingMode.none, Nullable <int> padvalue = null) { return(conv2dDerInput( outputShape, x, filter, strides, pad, dimRoundingMode, padvalue)); }
/// <summary> /// Fill the string with the new length. /// </summary> /// <param name="length">The new string length. If the value is less than the original length of the string, no action is taken.</param> /// <param name="str">The string to be filled.</param> /// <param name="padStr">A string to be used for padding. The default is blank.</param> /// <param name="type"> /// Fill in which side of the string. /// <para><see cref="PadType.Both"/>Fill both sides of the string. If not even, get extra padding on the right side.</para> /// <para><see cref="PadType.Left"/>Fill the left side of the string.</para> /// <para><see cref="PadType.Right"/>Fill the right side of the string.</para> /// </param> /// <returns>Returns filled string.</returns> public static string Pad(int length, string str = null, string padStr = null, PadType type = PadType.Right) { str = str ?? string.Empty; var needlePadding = length - str.Length; if (needlePadding <= 0) { return(str); } int rightPadding; var leftPadding = rightPadding = 0; if (type == PadType.Both) { leftPadding = needlePadding >> 1; rightPadding = (needlePadding >> 1) + (needlePadding % 2 == 0 ? 0 : 1); } else if (type == PadType.Right) { rightPadding = needlePadding; } else { leftPadding = needlePadding; } padStr = padStr ?? Space; padStr = padStr.Length <= 0 ? Space : padStr; var leftPadCount = (leftPadding / padStr.Length) + (leftPadding % padStr.Length == 0 ? 0 : 1); var rightPadCount = (rightPadding / padStr.Length) + (rightPadding % padStr.Length == 0 ? 0 : 1); return(Repeat(padStr, leftPadCount).Substring(0, leftPadding) + str + Repeat(padStr, rightPadCount).Substring(0, rightPadding)); }
public MetaData(PadType padType) { MaxLength = 0; PadType = padType; }
public static Tuple <PadInfo, int, int> getPadAndOutInfo(PadType pad, int inHeight, int inWidth, int strideHeight, int strideWidth, int filterHeight, int filterWidth, roundingMode roundingMode = roundingMode.none, Nullable <int> padValue = null) { var padInfo = new PadInfo(); var outHeight = 0; var outWidth = 0; if (pad == PadType.number) { padInfo.bottom = padValue.Value; padInfo.left = padValue.Value; padInfo.right = padValue.Value; padInfo.top = padValue.Value; var outShape = computeOutputShape3D( new int[] { inHeight, inWidth, 1 }, filterHeight, 1, strideHeight, padValue, roundingMode); outHeight = outShape[0]; outWidth = outShape[1]; padInfo.alongh = padValue.Value; padInfo.alongw = padValue.Value; } else if (pad == PadType.valid) { padInfo.bottom = 0; padInfo.left = 0; padInfo.right = 0; padInfo.top = 0; outHeight = (int)Math.Ceiling((inHeight - filterHeight + 1d) / strideHeight); outWidth = (int)Math.Ceiling((inWidth - filterWidth + 1d) / strideWidth); padInfo.alongh = 0; padInfo.alongw = 0; } else if (pad == PadType.same) { outHeight = (int)Math.Ceiling(inHeight / (float)strideHeight); outWidth = (int)Math.Ceiling(inWidth / (float)strideWidth); var padAlongHeight = (outHeight - 1) * strideHeight + filterHeight - inHeight; var padAlongWidth = (outWidth - 1) * strideWidth + filterWidth - inWidth; var top = (int)Math.Floor(padAlongHeight / 2f); var bottom = (int)padAlongHeight - top; var left = (int)Math.Floor(padAlongWidth / 2f); var right = (int)padAlongWidth - left; padInfo.bottom = bottom; padInfo.left = left; padInfo.right = right; padInfo.top = top; padInfo.alongh = padAlongHeight; padInfo.alongw = padAlongWidth; } else { throw new Exception("Unknown padding parameter"); } return(new Tuple <PadInfo, int, int>(padInfo, outHeight, outWidth)); }
/// <summary> /// Depthwise 2D convolution. /// * Given a 4D "input" array and a "filter" array of shape /// "[filterHeight, filterWidth, inChannels, channelMultiplier]" containing /// "inChannels" convolutional filters of depth 1, this op applies a /// different filter to each input channel (expanding from 1 channel to /// "channelMultiplier" channels for each), then concatenates the results /// together. The output has "inChannels * channelMultiplier" channels. /// /// See /// [https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d]( /// https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d) /// for more details. /// </summary> /// <param name="input">The input tensor, of Rank 4 or Rank 3, of shape /// "[batch, height, width, inChannels]". If Rank 3, batch of 1 is assumed.</param> /// <param name="filter">The filter tensor, Rank 4, of shape /// "[filterHeight, filterWidth, inChannels, channelMultiplier]"</param> /// <param name="strides">The strides of the convolution: "[strideHeight, /// strideWidth]". If strides is a single number, then "strideHeight == /// strideWidth".</param> /// <param name="pad">The type of padding algorithm. /// - "same" and stride 1: output will be of same size as input, /// regardless of filter size. /// - "valid": output will be smaller than input if filter is larger /// than 1x1. /// - For more info, see this guide: /// [https://www.tensorflow.org/api_guides/python/nn#Convolution]( /// https://www.tensorflow.org/api_guides/python/nn#Convolution)</param> /// <param name="dilations">The dilation rates: "[dilationHeight, dilationWidth]" /// in which we sample input values across the height and width dimensions /// in atrous convolution. Defaults to "[1, 1]". If "rate" is a single /// number, then "dilationHeight == dilationWidth". If it is greater than /// 1, then all values of "strides" must be 1.</param> /// <param name="dimRoundingMode">The rounding mode used when computing output /// dimensions if pad is a number. If none is provided, it will not round /// and error if the output is of fractional size.</param> /// <param name="padvalue">the value of pad if pad is number</param> /// <returns></returns> public static Tensor depthwiseConv2d(this Tensor input, Tensor filter, int[] strides, PadType pad, int[] dilations = null, roundingMode dimRoundingMode = roundingMode.none, Nullable <int> padvalue = null) { if (dilations == null) { dilations = new int[] { 1, 1 }; } Tensor input4D = null; var reshapedTo4D = false; if (input.Rank == 3) { reshapedTo4D = true; input4D = input.as4D(1, input.Shape[0], input.Shape[1], input.Shape[2]); } else { input4D = input as Tensor; } var convInfo = Util.computeConv2DInfo( input4D.Shape, filter.Shape, strides, dilations, pad, dimRoundingMode, true /* depthwise */, ConvDataFormat.channelsLast, padvalue); Func <Tensor, List <Tensor>, NamedGradientMap> grad = (Tensor dy, List <Tensor> s) => { NamedGradientMap g = new NamedGradientMap(); g.gradient = new Dictionary <string, Func <Tensor> >(); g.gradient.Add("input4D", () => { var resg = depthwiseConv2dDerInput(input4D.Shape, dy, filter, strides, pad, dimRoundingMode, padvalue); if (reshapedTo4D) { resg = resg.as3D(resg.Shape[1], resg.Shape[2], resg.Shape[3]); } return(resg); }); g.gradient.Add("filter", () => { return(depthwiseConv2dDerFilter(input4D, dy, filter.Shape, strides, pad, dimRoundingMode, padvalue)); }); return(g); }; Engine e = ENV.engine; ForwardFunc f = (IBackend bk, Func <Tensor, Tensor> saved) => { return(bk.depthwiseConv2D(input4D, filter, convInfo)); }; var inputs = new Dictionary <string, Tensor>(); inputs.Add("input4D", input4D); inputs.Add("filter", filter); var res = e.runKernel(f, inputs, grad); if (reshapedTo4D) { return(res.as3D(res.Shape[1], res.Shape[2], res.Shape[3])); } return(res); }
public static int[,] Filter_int(int[,] arr, int[,] filter, PadType padType) { int width = arr.GetLength(1); int height = arr.GetLength(0); int[,] temp; PadMyArray <int> padArr = new PadMyArray <int>(); int[,] result = new int[height, width]; int[,] toConv = new int[filter.GetLength(0), filter.GetLength(1)]; if (arr.Length < filter.Length) { Console.WriteLine("Cannot filter image, less than filter window. Returned array with zeros. Method: filter_int"); return(result); } int padsizeR, padsizeC = 0; if (filter.GetLength(0) % 2 == 0) { padsizeR = filter.GetLength(0) / 2; } else { padsizeR = (filter.GetLength(0) - 1) / 2; } if (filter.GetLength(1) % 2 == 0) { padsizeC = filter.GetLength(1) / 2; } else { padsizeC = (filter.GetLength(1) - 1) / 2; } temp = padArr.PadArray(arr, padsizeR, padsizeC, padType, Direction.both); //filtering //obtain part of image array and convolution with filter window try { for (int i = 1; i <= height; i++) { for (int j = 1; j <= width; j++) { for (int m = 0; m < filter.GetLength(0); m++) { for (int n = 0; n < filter.GetLength(1); n++) { toConv[m, n] = temp[i + m - 1, j + n - 1]; } } //such size coz array mult by elements, and we take part same size as filter window int[,] convolution = new int[filter.GetLength(0), filter.GetLength(1)]; convolution = toConv.ArrayMultElements(filter); //get elemt after filter if (convolution.Cast <int>().Sum() < 0) { result[i - 1, j - 1] = 0; } else if (convolution.Cast <int>().Sum() > 255) { result[i - 1, j - 1] = 255; } else { result[i - 1, j - 1] = convolution.Cast <int>().Sum(); } //result[i - 1, j - 1] = convolution.Cast<int>().Sum(); //get elemt after filter } } } catch (Exception e) { Console.WriteLine("Problem in filter, most likely OutOfRangeException, here message:\n" + e.Message); } return(result); }
public void AddColumn(string text, PadType padType) { overriddenPadTypes[getKey()] = padType; columns.Add(text); }