Пример #1
0
        private static NdArray <Real> LocalSum(NdArray <Real> input, int axis)
        {
            int[] resultShape = new int[input.Shape.Length - 1];

            for (int i = 0, j = 0; i < input.Shape.Length; i++)
            {
                if (i != axis)
                {
                    resultShape[j++] = input.Shape[i];
                }
            }

            NdArray <Real> result = new NdArray <Real>(resultShape, input.BatchCount);

            for (int i = 0; i < input.Length; i++)
            {
                List <int> index = new List <int>(input.GetDimensionsIndex(i));
                index.RemoveAt(axis);
                int localIndex = result.GetLocalIndex(0, index.ToArray());

                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    result.Data[batchCount * result.Length + localIndex] += input.Data[batchCount * input.Length + i];
                    if (input.Grad != null)
                    {
                        result.Grad[batchCount * result.Length + localIndex] += input.Grad[batchCount * input.Length + i];
                    }
                }
            }

            return(result);
        }
Пример #2
0
        private static NdArray Sum(NdArray a, int axis)
        {
            int[] resultShape = new int[a.Shape.Length - 1];

            for (int i = 0, j = 0; i < a.Shape.Length; i++)
            {
                if (i != axis)
                {
                    resultShape[j++] = a.Shape[i];
                }
            }

            NdArray result = new NdArray(resultShape, a.BatchCount);

            for (int i = 0; i < a.Length; i++)
            {
                List <int> index = new List <int>(a.GetDimensionsIndex(i));
                index.RemoveAt(axis);
                int localIndex = result.GetLocalIndex(0, index.ToArray());

                for (int batchCount = 0; batchCount < a.BatchCount; batchCount++)
                {
                    result.Data[batchCount * result.Length + localIndex] += a.Data[batchCount * a.Length + i];
                    result.Grad[batchCount * result.Length + localIndex] += a.Grad[batchCount * a.Length + i];
                }
            }

            return(result);
        }
Пример #3
0
        public static NdArray Transpose(NdArray input, params int[] dimensions)
        {
#if DEBUG
            if (input.Shape.Length != dimensions.Length)
            {
                throw new Exception("次元数がマッチしていません");
            }

            for (int i = 0; i < dimensions.Length; i++)
            {
                //自身の中にダブりがないか
                for (int j = i + 1; j < dimensions.Length; j++)
                {
                    if (dimensions[i] == dimensions[j])
                    {
                        throw new Exception("指定された要素がダブっています");
                    }
                }
                //範囲チェック
                if (dimensions[i] >= input.Shape.Length || dimensions[i] < 0)
                {
                    throw new Exception("指定された要素が範囲を超えています");
                }
            }
#endif
            int[] transposedDimensions = new int[input.Shape.Length];

            for (int j = 0; j < input.Shape.Length; j++)
            {
                transposedDimensions[j] = input.Shape[dimensions[j]];
            }

            NdArray resultMatrix = new NdArray(transposedDimensions);

            for (int b = 0; b < input.BatchCount; b++)
            {
                for (int i = 0; i < input.Length; i++)
                {
                    int[] indecies        = input.GetDimensionsIndex(i);
                    int[] transposedIndex = new int[input.Shape.Length];

                    for (int j = 0; j < input.Shape.Length; j++)
                    {
                        transposedIndex[j] = indecies[dimensions[j]];
                    }

                    resultMatrix.Data[resultMatrix.GetLocalIndex(b, transposedIndex)] = input.Data[input.GetLocalIndex(b, indecies)];
                }
            }

            return(resultMatrix);
        }
Пример #4
0
        public static NdArray Concatenate(NdArray a, NdArray b, int axis)
        {
            int[] shapeList = a.Shape.ToArray();
            shapeList[axis] += b.Shape[axis];

#if DEBUG
            for (int i = 0; i < a.Shape.Length; i++)
            {
                if (i != axis && a.Shape[i] != b.Shape[i])
                {
                    throw new Exception("配列の大きさがマッチしていません");
                }
            }

            if (a.BatchCount != b.BatchCount)
            {
                throw new Exception("バッチの大きさがマッチしていません");
            }
#endif

            NdArray result = new NdArray(shapeList, a.BatchCount);

            for (int batchCount = 0; batchCount < a.BatchCount; batchCount++)
            {
                int aInputBatchoffset = batchCount * a.Length;
                int bInputBatchoffset = batchCount * b.Length;

                for (int i = 0; i < a.Length; i++)
                {
                    int resultindex = result.GetLocalIndex(batchCount, a.GetDimensionsIndex(i));

                    result.Data[resultindex] = a.Data[i + aInputBatchoffset];
                    result.Grad[resultindex] = a.Grad[i + aInputBatchoffset];
                }

                for (int i = 0; i < b.Length; i++)
                {
                    int[] tmpIndex = b.GetDimensionsIndex(i);
                    tmpIndex[axis] += a.Shape[axis];

                    int resultIndex = result.GetLocalIndex(batchCount, tmpIndex);

                    result.Data[resultIndex] = b.Data[i + bInputBatchoffset];
                    result.Grad[resultIndex] = b.Grad[i + bInputBatchoffset];
                }
            }

            return(result);
        }
Пример #5
0
        NdArray ForwardCpu(NdArray val)
        {
            int[] resultShape;

            if (val.Shape.Length > this.Shape.Length)
            {
                //入力の方が大きい
                resultShape = val.Shape.ToArray();
                int offset = val.Shape.Length - this.Shape.Length;

                for (int i = offset; i < resultShape.Length; i++)
                {
                    if (resultShape[i] == 1)
                    {
                        resultShape[i] = this.Shape[i - offset];
                    }
#if DEBUG
                    else if (this.Shape[i - offset] != 1 && resultShape[i] != this.Shape[i - offset])
                    {
                        throw new Exception("変換不可能な組み合わせです");
                    }
#endif
                }
            }
            else
            {
                //指定の方が大きい
                resultShape = this.Shape.ToArray();
                int offset = this.Shape.Length - val.Shape.Length;

                for (int i = offset; i < resultShape.Length; i++)
                {
                    if (resultShape[i] == 1)
                    {
                        resultShape[i] = val.Shape[i - offset];
                    }
#if DEBUG
                    else if (val.Shape[i - offset] != 1 && resultShape[i] != val.Shape[i - offset])
                    {
                        throw new Exception("変換不可能な組み合わせです");
                    }
#endif
                }
            }

            NdArray result      = new NdArray(resultShape, val.BatchCount, this);
            int     indexOffset = result.Shape.Length - val.Shape.Length;

            for (int batchCount = 0; batchCount < result.BatchCount; batchCount++)
            {
                for (int i = 0; i < result.Length; i++)
                {
                    int[] baseIndex = result.GetDimensionsIndex(i);

                    int tmpIndexLastIndex = val.Shape.Length - 1;
                    int valIndex          = batchCount * val.Length;
                    int rankoffset        = 1;

                    for (int j = 0; j < val.Shape.Length; j++)
                    {
                        if (val.Shape[tmpIndexLastIndex] > 1)
                        {
                            valIndex += baseIndex[tmpIndexLastIndex + indexOffset] * rankoffset;
                        }

                        rankoffset *= val.Shape[tmpIndexLastIndex--];
                    }

                    result.Data[batchCount * result.Length + i] = val.Data[valIndex];
                }
            }

            return(result);
        }