|
NumSharp의 훌륭한 새로운 배열 슬라이싱 기능 덕분에 .NET 커뮤니티는 강력한 오픈 소스 머신러닝 플랫폼을 갖추는 데 한 걸음 더 다가섰습니다. 파이썬이 머신러닝 언어인 이유 중 하나는 NumPy, TensorFlow 같은 훌륭한 라이브러리가 있기 때문입니다. 하지만 C# 개발자들은 머신러닝과 데이터 과학을 위한 강력한 오픈 소스 라이브러리가 매우 필요합니다. SciSharp STACK 조직의 NumPy C# 포트인 NumSharp는 최근 슬라이싱 기능을 완전히 구현하여 N차원 배열의 임의의 부분집합을 원시 데이터의 효율적인 뷰로 생성할 수 있게 하며 큰 진전을 이루었습니다. 이로 인해 C#을 머신러닝과 TensorFlow.NET 함께 활용하는 데 유용한 도구가 됩니다.
뭐가 그렇게 대단한 일이야?
NumPy를 사용해보지 않았다면, 슬라이싱이 얼마나 훌륭한지 잘 모를 수도 있습니다. 파이썬 배열은 다음과 같이 일련의 요소를 인덱싱하여 배열의 슬라이스를 반환할 수 있게 해줍니다: a[start:stop:step]. 하지만 NumPy의 복잡한 배열 구현 덕분에야 슬라이싱이 진정으로 강력한 데이터 조작 기법이 되어, 기계 학습이나 데이터 과학이 없으면 상상할 수 없습니다. 다행히도, 머신러닝을 위해 파이썬으로 전환하고 싶지 않거나 원하지 않는 분들(저도 파이썬을 만들었어요)을 위해 NumSharp가 이 기능을 .NET 세계에 가져다줍니다. NumSharp의 개발자 중 한 명으로서, C#의 샘플 코드 스니펫을 활용한 중요한 슬라이싱 사용 사례를 소개해 드렸습니다. 언어 문법 차이로 인해 C#에서는 Python과 같은 방식으로 인덱싱을 할 수 없다는 점에 유의하세요. 하지만 슬라이스 정의에 Python 문법을 유지하기로 결정해서, C#에서 슬라이스를 인덱싱하는 데 문자열을 사용했습니다. 이 예시를 확인하시면 NumSharp가 NumPy와 얼마나 비슷한지 알 수 있습니다.
Python/NumPy에서 매트릭스에서 열을 잘라내세요C#과 NumSharp로 작성하면 코드가 거의 동일합니다. 슬라이스는 인덱서의 매개변수로 문자열을 사용하여 약간 다르게 인덱싱된다는 점에 유의하세요.
C#/NumSharp에서 행렬에서 열을 잘라내기보시다시피, NumSharp 팀은 코드를 파이썬과 최대한 비슷하게 만들기 위해 많은 노력을 기울였습니다. 이 점이 매우 중요합니다. 왜냐하면 NumPy에 의존하는 기존 Python 코드를 이제 쉽게 C#으로 이식할 수 있기 때문입니다.
사용 사례: 동일한 데이터를 여러 뷰로 활용하기
기본 데이터의 로컬 부분(즉, 큰 이미지의 작은 조각들)만 함수 간에 복사 없이 전달할 수 있는 것은 특히 대규모 데이터 세트의 런타임 성능에 매우 중요합니다. 슬라이스는 로컬 좌표를 사용해 인덱스화되므로, 알고리즘이 데이터의 전역 구조를 알 필요가 없어, 불필요한 중복을 피하고 최대 성능을 보장합니다.
사용 사례: 희소 뷰와 재귀 슬라이싱
슬라이스 범위의 시작과 끝을 넘어서는 단계를 지정하여 배열의 희소 뷰를 만들 수 있습니다. 제가 알기로는 C# 8.0에서 새로운 배열 슬라이스 구문을 적용해도 이런 기능은 없습니다. 이 기능은 인터리브드 데이터를 다룰 때 매우 중요합니다. 연속 데이터를 처리하도록 알고리즘을 설계하고, 연속 데이터 소스를 모방하는 희소 슬라이스를 제공함으로써 알고리즘의 복잡성을 최소화할 수 있습니다.
슬라이싱은 더 세팅할 수 있는데, 이는 고차원 데이터를 다룰 때 매우 중요한 기능입니다. 이것은 재귀적으로 슬라이싱하여 데이터의 차원을 줄일 수 있어 알고리즘의 복잡도를 줄이는 데도 도움이 됩니다.
사용 사례: 고차원 데이터를 효율적으로 처리하기
데이터 배열을 볼륨으로 생각하고 그 부분들을 다루고 싶다면, 엄청난 좌표 변환 계산을 하지 않고도 작업할 수 있다면 .reshape()가 도움이 될 것입니다. 모든 배열은 .reshape() 형태로, 원본 데이터의 뷰입니다. 뷰에 요소를 반복, 읽기, 쓰면 원시 데이터 배열에 접근할 수 있습니다. NumSharp는 적절한 인덱스 변환을 투명하게 수행해 주기 때문에, 상대 좌표로 슬라이스를 인덱싱할 수 있습니다.
사용 사례: 추가 비용 없이 요소 순서를 반전시킬 수 있습니다
음수 단계를 사용하는 슬라이스는 실제로는 슬라이스의 순서를 반대로 하는 것입니다. 이 기술의 장점은 IEnumerable()과 마찬가지로 데이터를 복사하거나 열거할 필요가 없다는 점입니다. 차이점은 뷰(연산 a["::-1"]의 결과)가 데이터를 역순으로 표시하며, 열거하지 않고도 그 역순 순서로 인덱싱할 수 있다는 점입니다.
사용 사례: 치수를 줄여 복잡성을 줄이기
고차원 데이터를 다룰 때는 그 데이터의 알고리즘도 매우 복잡해질 수 있습니다. 사용에서는 어떤 고차원 부피든 출력할 수 있습니다. ToString()의 NumSharp 메서드 NDArray를 사용했을 때, ND 볼륨을 체계적이고 재귀적으로 (N-1)D 볼륨으로 나누어 알고리즘이 얼마나 단순하고 아름답게 변했는지 느꼈습니다. 이 분할 및 정복 방식은 NumSharp의 인덱스 기호를 사용해 범위 기호를 절단하여 저차원 하위 부피를 반환합니다. 범위 기호 vs. 인덱스 기호범위 심볼 ["start:stop:step"]은 동일한 크기의 부피 내 하위 범위에 접근할 수 있게 해줍니다. 그래서 2D 행렬의 한 열만 잘라내더라도, 한 열만 있는 2D 행렬이 됩니다. 여기 이를 보여주는 짧은 C# 코드 조각이 있습니다:
범위 기호를 사용해 열을 슬라이스합니다
인덱스 기호는 N차원 부모 부피의 지정된 위치에 (N-1) 차원 슬라이스를 제공합니다. 인덱스 기호를 사용해 2D 행렬에서 열을 오려내면 1차원 벡터가 됩니다:
인덱스 기호를 이용한 열을 슬라이스
한눈에 차이를 못 보셨다면, 위에 나란히 설명한 두 슬라이스 정의, ange[":,2:3"] 대 index[":,2"]를 나란히 소개하는데, 이 두 가지가 결과에 큰 영향을 미칩니다. 새로운 슬라이스 심볼에 대한 자세한 참고 자료는 NumSharp 위키에서 확인할 수 있습니다.
참고: <T>어레이슬라이스
N차원 뷰의 슬라이싱을 구현하면서 .NET의 다른 많은 영역에도 흥미로울 수 있을 것 같아 SliceAndDice라는 독립 실행형 라이브러리로 분해했습니다. 이 도구는 어떤 C# 데이터 구조(예: or)도 ArraySlice를 인덱싱할 수 있는 가벼운 래퍼이며<T>, 다른 복잡한 수치 계산 없이도 동일한 리모델링, 슬라이싱, 뷰잉 메커니즘을 사용할 수 있게 해줍니다. 몇 백 줄의 코드만 있으면 훌륭한 절단 기능을 구현할 수 있습니다! T[]IList<T>
랩어라운드
NumSharp도 최근 동일한 슬라이싱 및 뷰잉 메커니즘을 갖추었으며, 이는 NumPy가 파이썬 머신러닝 생태계에서 가장 중요한 라이브러리 중 하나임을 분명히 보여줍니다. SciSharp STACK은 소수의 숙련된 개발자들로 구성된 오픈 소스 조직으로, 동일한 기능을 .NET 세계에 가져오기 위해 매우 열심히 노력해왔습니다. NumSharp의 최신 개선 사항은 이를 달성하는 데 중요한 초석입니다. 원문 언어:하이퍼링크 로그인이 보입니다.
|