Tensor 셰이프, 스토리지 및 NumPy 차이점

System.Numerics.Tensors 패키지는 다차원 데이터용 Tensor<T>, TensorSpan<T>, 및 ReadOnlyTensorSpan<T>를 제공합니다. 텐서 셰이프는 논리적 차원을 설명하며, strides는 각 차원을 따라 연속된 위치 사이의 거리(요소 단위)를 설명합니다.

여기에 설명된 동작은 지원되는 대상 프레임워크 전반에서 패키지에 포함됩니다. 패키지를 업데이트하면 이전 .NET 버전을 대상으로 하는 앱에 영향을 줄 수 있습니다.

이러한 형식은 NumPy와 많은 규칙을 공유하지만 서로 대체할 수는 없습니다. 알고리즘을 이식할 때 다음과 같은 차이점을 고려하세요.

빈 셰이프 및 스칼라와 유사한 결과

backing data 없이 빈 셰이프([])에서 텐서를 만들 때 텐서는 셰이프 [0]를 가지며 요소가 없습니다. NumPy에서 셰이프 ()에는 랭크가 0이고 스칼라 요소가 하나 있습니다. 특히 np.empty(()) 초기화되지 않은 값을 갖는 스칼라를 할당합니다. "empty"가 요소가 없다는 의미는 아닙니다.

반면, 기존 데이터에 대해 텐서 범위 생성자의 길이를 생략하면 생성자는 제공된 배열 또는 범위에서 1차원 셰이프를 유추합니다.

셰이프가 [1, 1]인 텐서를 짜내면 결과의 셰이프는 [1]이며, NumPy의 rank-zero 셰이프 ()가 아닙니다. 두 결과 모두 하나의 요소를 포함하고 스칼라로 브로드캐스트할 수 있지만 차원 수를 검사하거나, 축을 선택하거나, 결과를 인덱싱하는 코드는 보존된 차원을 고려해야 합니다.

스트라이드를 생략하면 길이가 0인 차원이 포함된 모든 셰이프의 모든 차원에는 0개의 스트라이드가 있습니다. 해당 요소 수와 필요한 스토리지는 다른 차원 길이에 관계없이 0입니다. 음수 길이는 유효하지 않습니다. 명시적 스트라이드는 여전히 레이아웃 유효성 검사를 충족해야 합니다.

스트라이드 및 역방향 데이터

보폭은 음수가 아니어야 합니다. NumPy는 예를 들어 array[::-1]와 같은 음수 보폭을 사용하여 역순 뷰를 나타낼 수 있습니다.

첫 번째 축을 반대로 하려면 Tensor.ReverseDimension 차원으로 0를 호출합니다.

using System.Numerics.Tensors;

Tensor<int> source = Tensor.Create(new[] { 1, 2, 3, 4 }, new nint[] { 2, 2 });
Tensor<int> reversed = Tensor.ReverseDimension<int>(source.AsReadOnlyTensorSpan(), 0);

reversed의 논리적 요소는 [3, 4, 1, 2]입니다. 할당 오버로드는 새 텐서를 생성합니다. 원래 스토리지에 대한 음수 스트라이드 뷰가 아닙니다.

텐서 크기 조정

Tensor.Resize 및 Tensor.ResizeTo은 추가된 논리 요소를 default(T)으로 채웁니다. 예를 들어 int를 다섯 개 [1, 2] 요소로 늘리면 결과에는 [1, 2, 0, 0, 0]가 포함됩니다. NumPy의 np.resize는 대신 입력을 반복하고 [1, 2, 1, 2, 1]를 생성합니다.

대상이 더 작은 경우 작업은 대상의 논리적 요소 수 이후의 요소를 버립니다. 크기가 크면 대상에 요소 간에 간격이 있는 경우에도 나머지 논리 대상 요소가 초기화됩니다. 논리 대상 외부의 스토리지는 크기 조정 작업의 일부가 아닙니다.

Tensor.ResizeTo 및 기존 대상에 대한 연결은 둘 이상의 논리 요소를 포함하는 0-stride 차원을 거부합니다. 이러한 차원은 여러 출력 위치가 동일한 스토리지를 참조하게 하며 고유 출력 값을 보유할 수 없습니다. 싱글톤 차원의 0 보폭과 빈 대상은 이 충돌을 일으키지 않습니다.

겹치는 소스 및 대상

별도의 텐서 개체와 범위는 동일한 배열의 겹치는 영역을 참조할 수 있습니다. 지원되는 사례는 작업과 레이아웃 모두에 따라 달라집니다.

작업 겹침 지원
CopyTo 및 TryCopyTo 요소 개수가 같거나 보기가 정확히 동일한 밀집된 원본 및 대상입니다. 조밀한 복사본은 겹침에도 안전한 범위 복사를 사용합니다.
FlattenTo 및 TryFlattenTo 조밀한 원본 및 대상 스팬입니다.
출력 대상이 있는 요소별 연산 뷰에 반복되는 논리적 저장 위치가 없는 경우 입력과 출력은 동일한 시작 참조, 길이 및 보폭을 갖습니다. 각 입력은 독립적으로 확인됩니다.
Tensor.ResizeTo 고밀도 소스 및 대상입니다. 지원되지 않는 strided overlap은 거부됩니다.
동일한 보기로 되돌리기 밀집 보기는 제자리에서 되돌릴 수 있습니다. No-op 취소 거래도 지원됩니다.

기타 지원되지 않는 중첩 레이아웃은 작업이 출력을 쓰기 전에 ArgumentException 오류를 발생시킵니다. 조밀한 텐서만으로는 모든 작업에 대한 지원을 보장하지 않습니다. 예를 들어 이동된 조밀한 대상은 복사 작업에는 지원되지만 요소별 작업에는 지원되지 않습니다.

TryCopyTo 메서드와 TryFlattenTo 메서드는 대상이 너무 짧을 때 복사하지 않고 false를 반환합니다. TryCopyTo는 호환되지 않는 원본 및 대상 셰이프에 대해서도 false를 반환합니다. 대상 용량이 충분한 호환되는 셰이프의 경우에도 이러한 메서드는 지원되지 않는 겹침의 경우 여전히 예외를 발생시킬 수 있습니다. Try는 잘못된 레이아웃 예외를 억제하지 않습니다.

예를 들어 다음과 같은 스트라이드가 있는 소스와 밀집된 목적지는 겹칩니다.

int[] storage = { 1, 2, 3, 4, 5, 6 };
ReadOnlyTensorSpan<int> source = new(storage, new nint[] { 2, 2 }, new nint[] { 3, 1 });
TensorSpan<int> destination = new(storage, new nint[] { 2, 2 });

이 지원되지 않는 중첩 레이아웃에서 복사하려면 먼저 스냅샷을 독립 스토리지에 저장합니다.

int[] snapshot = new int[checked((int)source.FlattenedLength)];
source.FlattenTo(snapshot);
ReadOnlyTensorSpan<int> independentSource = new(snapshot, source.Lengths);
independentSource.CopyTo(destination);

스냅샷에 [1, 2, 4, 5]이 포함됩니다. 복사본은 원래 값을 읽기 전에 변경하지 않고 해당 요소를 대상에 씁니다.

대상 텐서를 받는 요소별 연산의 경우 출력을 쓰기 전에 겹치는 각 입력에 대해 별도의 결과 텐서 또는 스냅샷을 할당합니다. 반복된 스토리지 위치가 있는 브로드캐스트 대상의 경우 독립 출력 스토리지를 대신 사용합니다. 입력 스냅샷은 해당 대상이 서로 다른 값을 저장할 수 있도록 만들지 않습니다.

라이브러리는 임의 겹치는 레이아웃을 지원하기 위해 전체 텐서 스냅샷을 암시적으로 할당하지 않습니다. 겹치지 않는 스트라이드 복사는 임시 스토리지가 필요하지 않습니다.

또한, 다음을 참조하세요.