protected override NdArray NeedPreviousForwardCpu(NdArray x) { int outputHeight = (int)Math.Floor((x.Shape[1] - this._kHeight + this._padY * 2.0) / this._strideY) + 1; int outputWidth = (int)Math.Floor((x.Shape[2] - this._kWidth + this._padX * 2.0) / this._strideX) + 1; Real[] y = new Real[x.BatchCount * this.OutputCount * outputHeight * outputWidth]; for (int batchCounter = 0; batchCounter < x.BatchCount; batchCounter++) { int yBatchOffset = batchCounter * this.OutputCount * outputHeight * outputWidth; int xBatchOffset = batchCounter * x.Length; for (int och = 0; och < this.OutputCount; och++) { int kOchOffset = och * this.InputCount * this._kHeight * this._kWidth; int yChOffset = yBatchOffset + och * outputHeight * outputWidth; for (int oy = 0; oy < outputHeight * this._strideY; oy += this._strideY) { int iyStart = oy - this._padY < 0 ? 0 : oy - this._padY; int iyLimit = this._kHeight + oy - this._padY < x.Shape[1] ? this._kHeight + oy - this._padY : x.Shape[1]; for (int ox = 0; ox < outputWidth * this._strideX; ox += this._strideX) { int ixStart = ox - this._padX < 0 ? 0 : ox - this._padX; int ixLimit = this._kWidth + ox - this._padX < x.Shape[2] ? this._kWidth + ox - this._padX : x.Shape[2]; int yIndex = yChOffset + oy / this._strideY * outputWidth + ox / this._strideX; for (int ich = 0; ich < this.InputCount; ich++) { int kIchOffset = kOchOffset + ich * this._kHeight * this._kWidth; int xChOffset = xBatchOffset + ich * x.Shape[1] * x.Shape[2]; for (int iy = iyStart; iy < iyLimit; iy++) { for (int ix = ixStart; ix < ixLimit; ix++) { int wIndex = kIchOffset + (iy - oy + this._padY) * this._kWidth + ix - ox + this._padX; int xIndex = xChOffset + iy * x.Shape[2] + ix; y[yIndex] += x.Data[xIndex] * this.Weight.Data[wIndex]; } } } } } } } if (this.Activator != null && !NoBias) { for (int batchCounter = 0; batchCounter < x.BatchCount; batchCounter++) { int resultIndex = batchCounter * this.OutputCount * outputHeight * outputWidth; for (int och = 0; och < this.OutputCount; och++) { for (int location = 0; location < outputHeight * outputWidth; location++) { y[resultIndex] += this.Bias.Data[och]; y[resultIndex] = this.Activator.ForwardActivate(y[resultIndex]); resultIndex++; } } } } else if (!NoBias) { for (int batchCounter = 0; batchCounter < x.BatchCount; batchCounter++) { int resultIndex = batchCounter * this.OutputCount * outputHeight * outputWidth; for (int och = 0; och < this.OutputCount; och++) { for (int location = 0; location < outputHeight * outputWidth; location++) { y[resultIndex] += this.Bias.Data[och]; resultIndex++; } } } } else if (this.Activator != null) { for (int i = 0; i < y.Length; i++) { y[i] = this.Activator.ForwardActivate(y[i]); } } return(NdArray.Convert(y, new[] { this.OutputCount, outputHeight, outputWidth }, x.BatchCount, this)); }
protected override NdArray NeedPreviousForwardCpu(NdArray input) { int outputHeight = (input.Shape[1] - 1) * this._strideY + this._kHeight - this._padY * 2; int outputWidth = (input.Shape[2] - 1) * this._strideX + this._kWidth - this._padX * 2; Real[] result = new Real[input.BatchCount * this.OutputCount * outputWidth * outputHeight]; int outSizeOffset = outputWidth * outputHeight; int inputSizeOffset = input.Shape[1] * input.Shape[2]; int kSizeOffset = this.Weight.Shape[2] * this.Weight.Shape[3]; for (int batchCount = 0; batchCount < input.BatchCount; batchCount++) { for (int och = 0; och < this.OutputCount; och++) { for (int oy = this._padY; oy < outputHeight + this._padY; oy++) { int iyLimit = oy / this._strideY + 1 < input.Shape[1] ? oy / this._strideY + 1 : input.Shape[1]; int iyStart = oy - this.Weight.Shape[2] < 0 ? 0 : (oy - this.Weight.Shape[2]) / this._strideY + 1; for (int ox = this._padX; ox < outputWidth + this._padX; ox++) { int ixLimit = ox / this._strideX + 1 < input.Shape[2] ? ox / this._strideX + 1 : input.Shape[2]; int ixStart = ox - this.Weight.Shape[3] < 0 ? 0 : (ox - this.Weight.Shape[3]) / this._strideX + 1; int outputIndex = batchCount * this.OutputCount * outSizeOffset + och * outSizeOffset + (oy - this._padY) * outputWidth + ox - this._padX; for (int ich = 0; ich < input.Shape[0]; ich++) { int inputIndexOffset = batchCount * input.Length + ich * inputSizeOffset; int kernelIndexOffset = ich * this.Weight.Shape[1] * kSizeOffset + och * kSizeOffset; for (int iy = iyStart; iy < iyLimit; iy++) { for (int ix = ixStart; ix < ixLimit; ix++) { int inputIndex = inputIndexOffset + iy * input.Shape[2] + ix; int kernelIndex = kernelIndexOffset + (oy - iy * this._strideY) * this.Weight.Shape[3] + (ox - ix * this._strideX); result[outputIndex] += input.Data[inputIndex] * this.Weight.Data[kernelIndex]; } } } } } } } if (this.Activator != null && !NoBias) { for (int batchCount = 0; batchCount < input.BatchCount; batchCount++) { for (int och = 0; och < this.OutputCount; och++) { for (int oy = this._padY; oy < outputHeight + this._padY; oy++) { for (int ox = this._padX; ox < outputWidth + this._padX; ox++) { int outputIndex = batchCount * this.OutputCount * outSizeOffset + och * outSizeOffset + (oy - this._padY) * outputWidth + ox - this._padX; result[outputIndex] += this.Bias.Data[och]; result[outputIndex] = this.Activator.ForwardActivate(result[outputIndex]); } } } } } else if (!NoBias) { for (int batchCount = 0; batchCount < input.BatchCount; batchCount++) { for (int och = 0; och < this.OutputCount; och++) { for (int oy = this._padY; oy < outputHeight + this._padY; oy++) { for (int ox = this._padX; ox < outputWidth + this._padX; ox++) { int outputIndex = batchCount * this.OutputCount * outSizeOffset + och * outSizeOffset + (oy - this._padY) * outputWidth + ox - this._padX; result[outputIndex] += this.Bias.Data[och]; } } } } } else if (this.Activator != null) { for (int batchCount = 0; batchCount < input.BatchCount; batchCount++) { for (int och = 0; och < this.OutputCount; och++) { for (int oy = this._padY; oy < outputHeight + this._padY; oy++) { for (int ox = this._padX; ox < outputWidth + this._padX; ox++) { int outputIndex = batchCount * this.OutputCount * outSizeOffset + och * outSizeOffset + (oy - this._padY) * outputWidth + ox - this._padX; result[outputIndex] = this.Activator.ForwardActivate(result[outputIndex]); } } } } } return(NdArray.Convert(result, new[] { this.OutputCount, outputHeight, outputWidth }, input.BatchCount, this)); }
public override NdArray SingleInputForward(NdArray x) { if (Finetune) { N++; Decay = 1 - 1 / N; } int dataSize = x.Length / ChannelSize; //計算用パラメータの取得 if (this.Train) { //メンバのMeanとVarianceを設定する this.Variance = new Real[this.ChannelSize]; this.Mean = new Real[this.ChannelSize]; for (int i = 0; i < this.ChannelSize; i++) { for (int b = 0; b < x.BatchCount; b++) { for (int location = 0; location < dataSize; location++) { this.Mean[i] += x.Data[b * x.Length + i * dataSize + location]; } } this.Mean[i] /= x.BatchCount * dataSize; for (int b = 0; b < x.BatchCount; b++) { for (int location = 0; location < dataSize; location++) { this.Variance[i] += (x.Data[b * x.Length + i * dataSize + location] - this.Mean[i]) * (x.Data[b * x.Length + i * dataSize + location] - this.Mean[i]); } } this.Variance[i] /= x.BatchCount * dataSize; } } else { this.Mean = this.AvgMean.Data; this.Variance = this.AvgVar.Data; } this.Std = new Real[this.ChannelSize]; for (int i = 0; i < this.Std.Length; i++) { this.Std[i] = Math.Sqrt(this.Variance[i] + this.Eps); } //結果を計算 this.Xhat = new Real[x.Data.Length]; Real[] y = new Real[x.Data.Length]; for (int i = 0; i < this.ChannelSize; i++) { for (int b = 0; b < x.BatchCount; b++) { for (int location = 0; location < dataSize; location++) { int index = b * x.Length + i * dataSize + location; this.Xhat[index] = (x.Data[index] - this.Mean[i]) / this.Std[i]; y[index] = this.Gamma.Data[i] * this.Xhat[index] + this.Beta.Data[i]; } } } //パラメータを更新 if (this.Train) { Real adjust = x.BatchCount / Math.Max(x.BatchCount - 1.0, 1.0); // unbiased estimation for (int i = 0; i < this.AvgMean.Data.Length; i++) { this.AvgMean.Data[i] *= this.Decay; this.Mean[i] *= 1 - this.Decay; // reuse buffer as a temporary this.AvgMean.Data[i] += this.Mean[i]; this.AvgVar.Data[i] *= this.Decay; this.Variance[i] *= (1 - this.Decay) * adjust; // reuse buffer as a temporary this.AvgVar.Data[i] += this.Variance[i]; } } return(NdArray.Convert(y, x.Shape, x.BatchCount, this)); }
protected override NdArray NeedPreviousForwardCpu(NdArray input) { int outputHeight = (int)Math.Floor((input.Shape[1] - this._kHeight + this._padY * 2.0) / this._strideY) + 1; int outputWidth = (int)Math.Floor((input.Shape[2] - this._kWidth + this._padX * 2.0) / this._strideX) + 1; Real[] result = new Real[this.OutputCount * outputHeight * outputWidth * input.BatchCount]; for (int batchCounter = 0; batchCounter < input.BatchCount; batchCounter++) { int resultIndex = batchCounter * this.OutputCount * outputHeight * outputWidth; for (int och = 0; och < this.OutputCount; och++) { //Wインデックス用 int outChOffset = och * this.InputCount * this._kHeight * this._kWidth; for (int oy = 0; oy < outputHeight * this._strideY; oy += this._strideY) { int kyStartIndex = oy - this._padY < 0 ? 0 : oy - this._padY; int kyLimit = this._kHeight + oy - this._padY < input.Shape[1] ? this._kHeight + oy - this._padY : input.Shape[1]; for (int ox = 0; ox < outputWidth * this._strideX; ox += this._strideX) { int kxStartIndex = ox - this._padX < 0 ? 0 : ox - this._padX; int kxLimit = this._kWidth + ox - this._padX < input.Shape[2] ? this._kWidth + ox - this._padX : input.Shape[2]; for (int ich = 0; ich < this.InputCount; ich++) { //Wインデックス用 int inChOffset = ich * this._kHeight * this._kWidth; //inputインデックス用 int inputOffset = ich * input.Shape[1] * input.Shape[2]; for (int ky = kyStartIndex; ky < kyLimit; ky++) { for (int kx = kxStartIndex; kx < kxLimit; kx++) { int wIndex = outChOffset + inChOffset + (ky - oy + this._padY) * this._kWidth + kx - ox + this._padX; int inputIndex = inputOffset + ky * input.Shape[2] + kx + batchCounter * input.Length; result[resultIndex] += input.Data[inputIndex] * this.Weight.Data[wIndex]; } } } resultIndex++; } } } } if (this.Activator != null && !NoBias) { for (int batchCounter = 0; batchCounter < input.BatchCount; batchCounter++) { int resultIndex = batchCounter * this.OutputCount * outputHeight * outputWidth; for (int och = 0; och < this.OutputCount; och++) { for (int location = 0; location < outputHeight * outputWidth; location++) { result[resultIndex] += this.Bias.Data[och]; result[resultIndex] = this.Activator.ForwardActivate(result[resultIndex]); resultIndex++; } } } } else if (!NoBias) { for (int batchCounter = 0; batchCounter < input.BatchCount; batchCounter++) { int resultIndex = batchCounter * this.OutputCount * outputHeight * outputWidth; for (int och = 0; och < this.OutputCount; och++) { for (int location = 0; location < outputHeight * outputWidth; location++) { result[resultIndex] += this.Bias.Data[och]; resultIndex++; } } } } else if (this.Activator != null) { for (int batchCounter = 0; batchCounter < input.BatchCount; batchCounter++) { int resultIndex = batchCounter * this.OutputCount * outputHeight * outputWidth; for (int och = 0; och < this.OutputCount; och++) { for (int location = 0; location < outputHeight * outputWidth; location++) { result[resultIndex] = this.Activator.ForwardActivate(result[resultIndex]); resultIndex++; } } } } return(NdArray.Convert(result, new[] { this.OutputCount, outputHeight, outputWidth }, input.BatchCount, this)); }
public static NdArray <Real> SingleInputForward(NdArray <Real> x, bool train, NdArray <Real> gamma, NdArray <Real> beta, NdArray <Real> avgMean, NdArray <Real> avgVar, ref Real n, bool finetune, ref Real decay, Real Eps, out Real[] std, out Real[] xhat, int channelSize, IFunction <Real> batchNorm) { Real[] Mean; Real[] Variance; if (finetune) { n++; decay = 1 - 1 / n; } int dataSize = x.Length / channelSize; //計算用パラメータの取得 if (train) { //メンバのMeanとVarianceを設定する Variance = new Real[channelSize]; Mean = new Real[channelSize]; for (int i = 0; i < channelSize; i++) { for (int b = 0; b < x.BatchCount; b++) { for (int location = 0; location < dataSize; location++) { Mean[i] += x.Data[b * x.Length + i * dataSize + location]; } } Mean[i] /= x.BatchCount * dataSize; for (int b = 0; b < x.BatchCount; b++) { for (int location = 0; location < dataSize; location++) { Variance[i] += (x.Data[b * x.Length + i * dataSize + location] - Mean[i]) * (x.Data[b * x.Length + i * dataSize + location] - Mean[i]); } } Variance[i] /= x.BatchCount * dataSize; } } else { Mean = avgMean.Data; Variance = avgVar.Data; } std = new Real[channelSize]; for (int i = 0; i < std.Length; i++) { std[i] = Math.Sqrt(Variance[i] + Eps); } //結果を計算 xhat = new Real[x.Data.Length]; Real[] y = new Real[x.Data.Length]; for (int b = 0; b < x.BatchCount; b++) { for (int i = 0; i < channelSize; i++) { for (int location = 0; location < dataSize; location++) { int index = b * x.Length + i * dataSize + location; xhat[index] = (x.Data[index] - Mean[i]) / std[i]; y[index] = gamma.Data[i] * xhat[index] + beta.Data[i]; } } } //パラメータを更新 if (train) { Real adjust = x.BatchCount / Math.Max(x.BatchCount - 1, 1.0f); // unbiased estimation for (int i = 0; i < avgMean.Data.Length; i++) { avgMean.Data[i] *= decay; Mean[i] *= 1 - decay; // reuse buffer as a temporary avgMean.Data[i] += Mean[i]; avgVar.Data[i] *= decay; Variance[i] *= (1 - decay) * adjust; // reuse buffer as a temporary avgVar.Data[i] += Variance[i]; } } return(NdArray.Convert(y, x.Shape, x.BatchCount, batchNorm)); }
private TestDataSet <T> GetRandomData(int batchCount, Func <int> getIndexFunc) { T[] data = new T[NdArray.ShapeToLength(Shape) * batchCount]; int[] label = new int[batchCount]; for (int i = 0; i < batchCount; i++) { int index = getIndexFunc(); T[] labeledData = Get(index); Array.Copy(labeledData, 0, data, i * labeledData.Length, labeledData.Length); label[i] = DataLabel[index]; } TestDataSet <T> result = new TestDataSet <T>(NdArray.Convert(data, Shape, batchCount), NdArray.Convert(label, new[] { 1 }, batchCount)); return(result); }
//全データを読み込む public TestDataSet <T> GetAllDataSet() { int batchCount = Data.Length; T[] data = new T[NdArray.ShapeToLength(Shape) * Data.Length]; for (int i = 0; i < batchCount; i++) { T[] labeledData = Get(i); Array.Copy(labeledData, 0, data, i * labeledData.Length, labeledData.Length); } TestDataSet <T> result = new TestDataSet <T>(NdArray.Convert(data, Shape, batchCount), NdArray.Convert(DataLabel, new[] { 1 }, batchCount)); return(result); }