PyTorch 2 : Tensor
1. 텐서(Tensor)
텐서(Tensor)는 데이터를 다차원 배열로 일반화한 것입니다. 수학적으로는 스칼라, 벡터, 행렬을 고차원으로 확장한 개념으로 볼 수 있으며, 딥러닝에서는 이러한 텐서를 사용하여 복잡한 데이터 구조를 효율적으로 처리합니다.
예를 들어, 0차원 텐서는 단일 숫자(스칼라)를, 1차원 텐서는 숫자 배열(벡터)을, 2차원 텐서는 숫자의 2차원 배열(행렬)을 나타내며, 이를 더 확장하여 이미지 데이터(3차원 텐서)나 비디오 데이터(4차원 텐서) 등을 처리할 수 있습니다.
※ 텐서의 중요성
텐서는 딥러닝 모델에서 데이터를 표현하고 처리하는 핵심적인 구성 요소입니다. 모든 딥러닝 연산은 텐서를 사용하여 수행되며, 이는 복잡한 데이터 구조를 효율적으로 다루고 다루기 위해 필수적입니다. 텐서를 사용함으로써 다음과 같은 이점을 얻을 수 있습니다:
- 다차원 데이터 처리: 텐서를 사용하면 이미지, 비디오, 텍스트 등 다양한 형태의 고차원 데이터를 쉽게 처리할 수 있습니다.
- 벡터화 연산: 텐서를 통한 벡터화 연산은 계산 효율성을 높이고 코드의 간결성을 유지합니다.
- GPU 가속: 대부분의 딥러닝 프레임워크는 텐서 연산을 GPU에서 실행할 수 있게 지원하며, 이는 대규모 데이터의 처리 속도를 크게 향상시킵니다.
2. 차원(Dimension)과 형태(Shape)
차원(Dimension)
차원은 텐서가 가지는 축(axis)의 수를 의미합니다. 차원의 수는 텐서 데이터의 복잡성을 나타내며, 이는 텐서가 얼마나 많은 수준의 중첩된 배열 구조를 가지고 있는지를 나타냅니다.
- 0차원 텐서: 스칼라(단일 숫자)
- 1차원 텐서: 벡터(숫자의 배열)
- 2차원 텐서: 행렬(숫자의 2차원 배열)
형태(Shape)
형태는 각 차원에서 텐서가 얼마나 많은 요소를 가지고 있는지를 나타내는 튜플입니다. 형태는 텐서의 구체적인 크기와 구조를 정의합니다.
예를 들어, [3, 4] 형태의 2차원 텐서는 3개의 행과 4개의 열을 가진 행렬을 의미합니다. [2, 3, 4] 형태의 3차원 텐서는 2개의 3x4 행렬을 쌓아 놓은 구조를 가지고 있습니다.
텐서의 형태는 데이터를 조작하고, 모델을 설계할 때 중요한 역할을 합니다. 예를 들어, 신경망의 입력 레이어는 입력 데이터의 형태에 따라 설계되어야 하며, 연산을 수행할 때 텐서의 형태가 올바르게 맞춰져 있어야 합니다.
3. 텐서 생성
텐서 생성
- torch.zeros 지정된 크기로 모든 요소가 0인 텐서를 생성합니다. 이는 가중치 초기화나 임시 텐서 생성 시 유용하게 사용됩니다.
- torch.ones 지정된 크기의 텐서를 생성하고 모든 요소를 1로 채웁니다. 이는 종종 특정 연산에서의 기본값 설정이나, 마스킹 연산에서 사용됩니다.
- torch.full 지정된 크기로 모든 요소를 사용자가 지정한 값으로 채운 텐서를 생성합니다. 이는 특정 값으로 초기화된 텐서가 필요할 때 사용됩니다.
- torch.eye 단위 행렬(identity matrix)을 생성합니다. 주 대각선 요소가 모두 1이고 나머지 요소는 0인 정사각 행렬을 반환합니다.
- torch.arange 시작값과 끝값, 그리고 선택적인 단계(step) 값을 받아 이 범위 내에서 일정한 간격의 요소를 가진 1차원 텐서를 생성합니다.
- torch.linspace 시작값과 끝값을 받고, 지정된 개수만큼의 요소를 두 값 사이를 균등하게 배치한 1차원 텐서를 생성합니다.
텐서 생성(2) - 랜덤 데이터
- torch.rand 주어진 크기의 텐서를 생성하고, 모든 요소를 0과 1 사이의 균일 분포(uniform distribution)에서 랜덤하게 채웁니다. 이는 일반적으로 모델의 가중치 초기화에 사용됩니다.
- torch.randn 주어진 크기의 텐서를 생성하고, 모든 요소를 평균 0과 표준편차 1을 가진 정규 분포(normal distribution)에서 랜덤하게 채웁니다. 이 함수는 가중치 초기화나 노이즈 추가 등에 유용하게 사용됩니다.
- torch.randint 지정된 범위 내에서 랜덤한 정수를 생성하여 텐서를 초기화합니다. 이 함수는 정수 값을 가진 텐서가 필요할 때, 예를 들어 인덱스를 랜덤하게 생성할 때 유용합니다.
- torch.randperm 0부터 n-1까지의 정수를 랜덤하게 섞어서 반환합니다. 이는 데이터셋을 셔플링할 때 주로 사용됩니다.
4. 텐서의 형태 변환
텐서의 형태 변경 (1) - reshape
reshape() 함수는 텐서의 형태를 변경하는 데 사용됩니다. 이 함수는 원본 텐서의 데이터를 유지하면서 새로운 형태의 텐서를 반환합니다.
reshape()는 주어진 새로운 형태가 원본 텐서의 총 원소 수와 일치할 때 사용할 수 있습니다. 이는 데이터의 차원을 재구성하거나, 특정 연산에 적합한 형태로 텐서를 조정할 필요가 있을 때 매우 유용합니다.
만약 변경하려는 형태가 원본 텐서와 메모리 데이터의 효율화면, PyTorch는 가능한 한 원본 데이터를 공유하고자 시도합니다. 그러나, 만약 원본 텐서의 메모리 레이아웃이 연속적이지 않아서 직접적인 형태 변환이 불가능할 경우에는 reshape()은 먼저 텐서를 복사하여 메모리에서 연속적인 데이터 블록을 생성한 후 새로운 형태를 반환합니다. 이는 추가적인 메모리 사용과 계산 비용을 발생시킬 수 있습니다.
예를 들어, 아래 그림과 같이 2x3 형태의 텐서를 6x1 형태로 변경할 수 있습니다.
텐서의 형태 변경 (2) - view
view() 함수는 원본 텐서의 데이터를 공유하는 새로운 형태의 텐서를 반환합니다. 이는 데이터의 실제 메모리 레이아웃을 변경하지 않으며, 원치 텐서에 대한 새로운 인덱싱 뷰를 제공합니다.
만약 원본 텐서가 메모리상에서 연속적이지 않은 경우, view() 함수는 오류를 발생시킵니다. 이런 상황에서는 reshape() 함수를 사용하거나, contiguous() 메소드를 호출한 후 view()를 사용해야 합니다.
차원 축소 - squeeze
squeeze 함수는 텐서에서 크기가 1인 차원을 찾아서 그 차원을 제거합니다. 이는 데이터의 형태를 바꾸지 않으면서 텐서를 효율적으로 만들어 줍니다.
예를 들어, 만약 입력이 [1, 10, 1, 50] 크기의 텐서를 가지고 있다면, squeeze를 사용한 후에는 [10, 50] 크기의 텐서로 줄어들게 됩니다.
차원 확장 - unsqueeze
squeeze가 불필요한 공간을 제거한다면, unsqueeze는 상자에 조금 더 공간을 추가하는 것과 같습니다. 파이토치에서는 특정 위치에 새로운 차원을 추가할 수 있도록 unsqueeze를 제공합니다. 이는 특정 연산을 수행하기 위해 텐서를 적절히 변형하는 데 유용합니다.
예를 들어, [10, 50] 크기의 텐서에 unsqueeze를 사용하여 첫 번째 위치에 차원을 추가하면, [1, 10, 50]의 크기를 가진 텐서가 됩니다.
텐서의 차원 교환 (1) - transpose
transpose 함수는 책장을 정리하다가 책들을 가로로 놓은 것을 세로로 바꾸고 싶을 때와 비슷한 일을 합니다. 즉, 텐서의 두 차원을 서로 바꾸는 역할을 합니다. 이는 행렬의 형태를 바꾸는 것과 유사하며, 데이터를 다른 방식으로 해석하고 싶을 때 매우 유용합니다.
예를 들어, [10, 50] 크기의 텐서에 대해 첫 번째 차원과 두 번째 차원을 transpose하면 [50, 10] 크기의 텐서를 얻게 됩니다.
텐서의 차원 교환 (2) - permute
permute 함수는 여러분이 방의 가구를 재배치하여 완전히 새로운 공간을 만들고 싶을 때와 비슷한 역할을 합니다. 이 함수는 텐서의 차원을 재배열할 수 있게 해줍니다. permute는 여러 차원을 원하는 방식으로 바꾸고 싶을 때 사용됩니다.
예를 들어, [10, 20, 30] 크기의 텐서가 있을 때, permute를 사용하여 차원의 순서를 [2, 0, 1]로 바꾸면 [30, 10, 20] 크기의 새로운 형태의 텐서를 얻게 됩니다.
5. 텐서의 결합과 분할
텐서 결합 (1) - cat
cat 함수는 'concatenate(연결)'의 줄임말입니다. 마치 손을 잡고 줄을 서는 것처럼, cat 함수는 여러 텐서를 지정된 차원을 따라 하나로 연결합니다. 이를 통해 크기가 더 큰 새로운 텐서를 생성할 수 있습니다. cat은 여러 데이터 조각을 하나로 모으고 싶을 때 매우 유용합니다.
예를 들어, [2, 2] 및 [2, 3] 크기의 두 텐서를 1번째 차원(열)을 따라 연결하면, [2, 5] 크기의 텐서가 만들어집니다.
텐서 결합 (2) - stack
stack 함수는 책을 쌓아 올리듯이, 여러 텐서를 새로운 차원을 추가하여 쌓아 올립니다. 이는 cat과 다르게, 모든 텐서에 대해 새로운 차원이 생기므로, 텐서들은 그 크기가 동일해야만 합니다. stack은 데이터를 구조적으로 정리하고 싶을 때 유용합니다.
예를 들어, 세 개의 [2, 2] 크기의 텐서를 stack으로 쌓으면, [3, 2, 2] 크기의 텐서가 됩니다.
텐서 분할 (1) - chunk
chunk 함수는 큰 텐서를 여러 개의 작은 텐서로 나누는 데 사용됩니다. 마치 큰 케이크를 여러 조각으로 나누어 친구들과 나누어 먹는 것과 비슷합니다. 이 함수는 두 개의 인자를 받습니다. 하나는 몇 개의 조각으로 나눌 것인지, 다른 하나는 어느 차원을 따라 나눌 것인지를 지정합니다.
예를 들어, [10] 크기의 텐서를 3개의 조각으로 나누면, 각각 [4], [3], [3] 크기의 텐서 3개를 얻게 됩니다. chunk는 데이터를 작은 단위로 나누어 처리하고 싶을 때 매우 유리합니다.
텐서 분할 (2) - split
split 함수는 chunk와 유사하지만, 조각의 크기를 더 세밀하게 지정할 수 있습니다. 즉, 각 조각에 몇 개의 요소를 포함할지 직접 결정할 수 있습니다.
만약 입력이 [10] 크기의 텐서를 각각 4개와 6개의 요소를 포함하는 두 조각으로 나누고 싶다면, split 함수를 사용하여 이를 수행할 수 있습니다. 반면에 chunk는 여러분의 필요에 따라 균등하게 나눌 수 있습니다.
5. 텐서 인덱싱과 슬라이싱
텐서 인덱싱
텐서 인덱싱은 마치 책장에서 원하는 책을 찾아내는 것과 유사합니다. 여러분이 특정 요소에 접근하고 싶을 때 사용하는 방법입니다. 파이토치에서는 대괄호([])를 사용하여 텐서의 특정 위치에 있는 데이터에 접근할 수 있습니다.
예를 들어, tensor[1, 2]는 텐서의 두 번째 행과 세 번째 열에 있는 요소를 의미합니다. 이 방법을 사용하면, 텐서 내의 한 개 또는 여러 개의 특정 요소를 선택할 수 있습니다.
텐서 슬라이싱
텐서 슬라이싱은 케이크를 여러 조각으로 나누어 친구들과 나누어 먹는 것과 비슷합니다. 즉, 텐서의 일부를 선택적으로 접근하고 싶을 때 사용하는 방법입니다. 파이토치에서는 콜론(:)을 사용하여 시작 인덱스, 끝 인덱스, 그리고 스텝 크기를 지정함으로써 텐서의 특정 범위를 선택할 수 있습니다.
예를 들어, tensor[:, 1:4]는 텐서의 모든 행과 두 번째 열부터 네 번째 열까지의 범위를 의미합니다. 이 방법을 통해 원하는 부분 텐서를 쉽게 얻을 수 있습니다.
조건부 인덱싱
조건부 인덱싱은 여러분이 특정 조건을 만족하는 요소만 선택하고 싶을 때 사용합니다. 마치 여러분이 과일을 고를 때, 달콤한 과일만 고르는 것과 비슷하다고 할 수 있습니다. 파이토치에서는 불리언(Boolean) 텐서를 사용하여 이를 수행할 수 있습니다.
예를 들어, tensor[tensor > 5]는 텐서 내에서 5보다 큰 모든 요소를 선택합니다. 이 방법은 데이터를 필터링하거나 조건에 따라 특정 데이터를 추출하고 싶을 때 유용합니다.
6. 고급 인덱싱 기법
gather
gather 함수는 텐서 내의 데이터를 인덱스에 따라 모으는 연산입니다. 이 함수는 다차원 인덱스를 사용하여 주어진 차원의 텐서의 요소를 선택적으로 추출합니다. gather는 주로 복잡한 데이터 추출 작업이나, 특정 조건에 맞는 데이터를 선택할 때 유용합니다.
예를 들어, [10, 20, 30], [40, 50, 60] 형태는 2x3 크기의 텐서를 나타냅니다. 여기에서 [0, 0, 1], [1, 2, 0] 이라는 인덱스를 지정하면, 첫 번째 행의 첫 번째 열과 두 번째 행의 두 번째 열, 첫 번째 행의 세 번째 열을 선택합니다. 따라서 결과는 [10, 50, 30]이 됩니다.
masked_select
masked_select 함수는 불리언 마스크를 사용하여 텐서에서 요소를 선택합니다. 이 함수는 주어진 마스크에 따라 True에 해당하는 위치의 요소만을 선택하여 텐서를 반환합니다.
예를 들어, [10, 20, 30] 형태의 텐서에서 [True, False, True]라는 마스크를 사용하면, 10과 30만 선택된 [10, 30] 텐서를 얻을 수 있습니다. 이 방법은 데이터를 필터링하거나 특정 조건을 만족하는 요소를 추출할 때 유용합니다.
정수 배열을 사용한 인덱싱
복잡한 데이터 선택 요구사항을 충족하기 위해 사용됩니다. 이 방식은 정수 배열 또는 불리언 배열을 사용하여 텐서의 특정 요소들을 선택할 수 있게 해줍니다.
예를 들어, rows = torch.tensor([0, 2])는 첫 번째 행과 세 번째 행을 선택한다는 의미입니다. cols = torch.tensor([1, 3])는 첫 번째와 세 번째 열을 선택합니다. 최종적으로, result = tensor[rows, cols]는 텐서의 특정 행과 열의 요소들로 구성된 결과를 반환합니다.
이 방식은 원본 텐서의 구조와는 독립적으로 작동합니다.
7. 텐서와 넘파이 간의 변환
넘파이 배열을 텐서로 변환
torch.from_numpy 함수는 NumPy 배열을 PyTorch 텐서로 변환합니다. 이 함수는 메모리를 공유하기 때문에, 변환된 텐서를 변경하면 원본 NumPy 배열도 변경됩니다. 이는 데이터 복사를 피하고 효율성을 높이기 위한 것입니다.
텐서를 넘파이 배열로 변환
tensor.numpy() 메서드는 PyTorch 텐서를 NumPy 배열로 변환합니다. 이 변환 역시 메모리를 공유하기 때문에, 변환된 배열을 변경하면 원본 텐서도 변경됩니다. 이 메서드는 PyTorch 텐서에 대해 빠르게 호출됩니다.
데이터 공유의 중요성
torch.from_numpy와 tensor.numpy() 모두 원본 데이터와 변환된 데이터 사이에서 메모리를 공유합니다. 이는 데이터 복사가 없어도 되므로 성능상의 이점을 가집니다. 하지만 이런 이유로 변환된 데이터와 원본 데이터를 동시에 수정하지 않도록 주의할 필요가 있습니다. 이 점을 유의하여 사용하면 데이터 복사 없이 효율적으로 메모리를 관리할 수 있지만, 명시적으로 복사(copy) 연산을 수행해야 할 때도 있습니다.
8. 텐서 복제
텐서 복제 - clone
clone 함수는 파이토치(PyTorch)에서 텐서의 데이터를 복사하여 새로운 텐서를 생성하는 데 사용됩니다. 이 함수는 원본 텐서의 데이터를 완전히 복제하여 새로운 메모리 위치에 저장합니다.
결과적으로, clone으로 생성된 텐서는 원본 텐서와 데이터는 같지만, 서로 독립적인 메모리를 가집니다. 따라서, clone된 텐서를 수정해도 원본 텐서에는 영향을 주지 않습니다.
사용 용도
- 데이터의 안전한 복제: 텐서의 데이터를 수정하고자 할 때, 원본 데이터를 보존하면서 실행하고 싶을 때 유용합니다.
- 계산 그래프의 독립성: clone은 기본적으로 복제된 텐서에 대한 새로운 계산 그래프를 생성합니다. 이는 자동 미분에 영향을 줄 수 있는 연산에서 특히 중요할 수 있습니다.
9. 기본 연산
덧셈과 뺄셈
텐서의 덧셈과 뺄셈 연산은 두 텐서의 동일 위치에 있는 요소들끼리 연산을 수행합니다.
예를 들어, 두 개의 2x2 텐서 tensor_a와 tensor_b가 각각 [1, 2], [3, 4]와 [5, 6], [7, 8]의 값을 갖는 경우, 이들의 연산은 아래와 같이 계산됩니다.
- 덧셈 결과: 각 요소를 더한 결과값은 [6, 8], [10, 12]로 얻습니다. 이는 tensor_a의 각 요소 + tensor_b의 각 요소를 더하여 계산한 결과입니다.
- 뺄셈 결과: tensor_a에서 tensor_b를 뺀 결과값인 [-4, -4], [-4, -4]를 얻습니다. 이는 tensor_a의 각 요소 - tensor_b의 각 요소를 빼서 계산한 결과입니다.
곱셈과 나눗셈
요소별 곱셈과 나눗셈 연산도 마찬가지로 각 텐서의 동일한 위치에 있는 요소끼리 수행합니다.
예를 들어, tensor_a와 tensor_b가 각각 [2, 3], [4, 5]와 [5, 6], [7, 8]의 값을 갖는 경우, 연산 결과는 다음과 같습니다.
- 요소별 곱셈 결과: 각 요소의 곱한 결과값 [10, 18], [28, 40]을 얻습니다.
브로드캐스팅
브로드캐스팅을 통해 서로 다른 모양(shape)을 가진 텐서를 간에도 수학 연산을 수행할 수 있게 됩니다. 이는 더 작은 텐서가 큰 텐서의 모양에 맞게 자동으로 확장(확대)되어 연산이 가능하게 만듭니다.
브로드캐스팅이 작동하는 방법은 다음과 같은 규칙을 따릅니다:
- 차원의 크기가 같거나, 하나의 차원이 1인 경우에만 브로드캐스팅이 가능합니다.
예를 들어, (5, 4) 모양의 텐서와 (1, 4) 모양의 텐서는 브로드캐스팅이 가능합니다. 여기서 (1, 4) 모양의 텐서는 첫 번째 차원을 기준으로 5회 반복되어 (5, 4) 모양으로 확장됩니다. - 작은 텐서의 차원 수가 클 경우, 더 작은 차원을 가진 텐서의 앞에 1을 추가하여 동일한 차원을 만듭니다.
예를 들어, (3, 4)와 (4,) 모양의 텐서가 있을 때, 작은 텐서는 (1, 4)로 간주됩니다. 그 후, 앞의 첫 번째 차원 방향으로 브로드캐스팅이 수행됩니다. - 브로드캐스팅은 각 차원을 따라 반복함으로써 더 큰 모양의 텐서에 맞춰 연산을 수행합니다.
하지만 실제 데이터 복사가 일어나지 않으며, 연산을 효율적으로 만들기 위한 가상의 확장으로 생각할 수 있습니다.
10. 비교 연산
동등 비교
동등 비교는 두 텐서 간의 요소별 동등성을 비교하는 데 사용하는 것입니다.
동등비교를 위해 == 또는 torch.eq()를 사용합니다. 이 함수는 두 텐서의 동일한 위치에 있는 요소가 같은지 여부를 검사하며, 결과를 불리언(Boolean) 텐서로 반환합니다. 즉, 두 요소가 같으면 True, 다르면 False 값을 갖습니다.
torch.eq() 함수의 사용법은 매우 간단합니다. 두 텐서 a와 b가 주어졌을 때, torch.eq(a, b)를 호출하여 두 텐서 간의 요소별 동등 비교를 수행할 수 있습니다.
대소 비교
파이토치(PyTorch)에서 텐서 간의 대소 비교는 각 요소의 값을 비교하여 해당 조건이 참인지 거짓인지 판단하는 연산입니다.
대소 비교에는 아래와 같은 함수를 이용합니다:
- torch.gt(a, b): a가 b보다 큰 경우 True를 반환합니다. (greater than)
- torch.lt(a, b): a가 b보다 작은 경우 True를 반환합니다. (less than)
- torch.ge(a, b): a가 b보다 크거나 같은 경우 True를 반환합니다. (greater than or equal to)
- torch.le(a, b): a가 b보다 작거나 같은 경우 True를 반환합니다. (less than or equal to)
11. 축소 연산
최대값과 최소값 구하기
- 최대값: 텐서 내의 최대값을 구하기 위해 torch.max() 함수를 사용합니다. 이 함수는 텐서 전체의 최대값을 반환할 수도 있고, 특정 차원을 기준으로 각 부분의 최대값과 그 위치(indices)를 반환할 수도 있습니다.
- 최소값: 텐서 내의 최소값을 구하기 위해 torch.min() 함수를 사용합니다. 마찬가지로, 텐서 전체의 최소값을 반환하거나, 특정 차원에서의 최소값과 위치를 반환할 수 있습니다.
함수에 dim 매개변수를 지정함으로써, 특정 차원을 기준으로 한 최대값과 최소값을 계산할 수 있습니다.
합계
텐서 전체 요소의 합계를 구하기 위해 torch.sum() 함수를 사용합니다. 이 함수는 텐서 내 모든 요소의 합을 반환합니다.
torch.sum() 함수에 dim 매개변수를 지정함으로써, 특정 차원을 기준으로 한 합계를 구할 수 있습니다. 예를 들어, 행 또는 열 방향의 합계를 구할 수 있습니다.
평균/중앙값/최빈값
- 평균: 데이터 집합의 총합을 데이터의 개수로 나눈 값입니다.
torch.mean() 함수를 사용하여 텐서의 평균을 구할 수 있습니다. 이 함수는 특정 차원을 기준으로 정렬하여 작동하며, 정수 타입 텐서의 평균을 구하려면 타입 변환을 해야 합니다. - 중앙값: 데이터들이 크기 순으로 나열될 때 중앙에 위치하는 값입니다.
torch.median() 함수를 사용하여 텐서의 중앙값을 구할 수 있습니다. - 최빈값: 데이터 집합에서 가장 자주 등장하는 값을 의미합니다.
torch.mode() 함수를 사용하여 텐서의 최빈값과 그 인덱스를 구할 수 있습니다.
분산/표준편차
분산(Variance)과 표준편차(Standard Deviation)는 데이터의 분포가 평균으로부터 얼마나 떨어져 있는지를 나타내는 중요한 통계량입니다. 이들은 데이터의 변동성을 측정하는 데 사용되며, 데이터가 평균값을 중심으로 얼마나 퍼져 있는지의 정도를 나타냅니다.
- 분산:
데이터의 평균 간의 차이의 제곱의 평균입니다.
파이토치에서 torch.var() 함수를 사용하여 텐서의 분산을 구할 수 있습니다.
분산은 데이터가 평균으로부터 얼마나 멀리 떨어져 있는지의 평균적인 제곱 값을 제공합니다. - 표준편차:
분산의 제곱근으로, 데이터의 분포가 평균으로부터 얼마나 퍼져 있는지를 나타내는 값입니다.
torch.std() 함수를 사용하여 텐서의 표준편차를 구할 수 있습니다.
표준편차는 분산보다 단위를 동일하게 하므로 데이터의 측정이나 이해가 더 쉽습니다.
12. 논리 연산
AND 연산
AND 연산은 두 텐서의 동일한 위치에 있는 요소들끼리 비교하여, 둘 다 True인 경우에만 결과로 True를 반환합니다. 반면에 둘 중 하나라도 True가 아닌 경우에는 False를 반환합니다.
이를 위해 & 또는 torch.logical_and() 함수가 사용됩니다.
OR 연산
OR 연산은 두 텐서의 동일한 위치에 있는 요소들 중 하나라도 True일 경우 결과로 True를 반환합니다. 반면, 요소들 모두 False일 경우 False를 반환합니다.
이를 위해 | 또는 torch.logical_or() 함수가 사용됩니다.
Not 연산
Not 연산은 주어진 불리언 텐서의 각 요소에 대해 True는 False로, False는 True로 반전시킵니다.
이를 위해 ~ 또는 torch.logical_not() 함수가 사용됩니다.
13. 수학 연산
지수/로그/제곱근
파이토치(PyTorch)에서는 수학적 연산을 위한 다양한 함수를 제공합니다. 이 중 지수, 로그, 제곱근 연산은 데이터 전처리, 특성 변환, 수치 계산 등 다양한 상황에서 널리 사용됩니다. 각 연산의 기본적인 사용 방법을 살펴봅니다.
- 지수 연산: 주어진 텐서의 각 요소에 대해 e의 x 제곱을 적용합니다.
torch.exp(input) 함수를 사용합니다. - 로그 연산: 주어진 텐서의 각 요소에 대해 밑이 e인 자연로그를 적용합니다.
torch.log(input) 함수를 사용합니다. 로그 연산은 값의 스케일을 조정할 때 유용하게 사용됩니다. - 제곱근 연산: 주어진 텐서의 각 요소에 대해 제곱근을 계산합니다.
torch.sqrt(input) 함수를 사용합니다. 제곱근 연산은 분산, 표준편차 계산 등에 활용됩니다.
제곱/절대값/역수/음수
- 제곱 연산: 텐서의 각 요소를 제곱합니다.
torch.pow(input, exponent) 함수를 사용하며, exponent에 2를 지정할 수 있습니다. 또는 input ** 2 형태로도 가능합니다. - 절대값 연산: 텐서의 각 요소에 대해 절대값을 계산합니다.
torch.abs(input) 함수를 사용합니다. - 역수 연산: 텐서의 각 요소에 대해 역수(1을 요소값으로 나눈 값)를 계산합니다.
torch.reciprocal(input) 함수를 사용합니다. - 음수 연산: 텐서의 각 요소에 대해 음수를 계산합니다.
torch.neg(input) 또는 -input을 사용합니다.
삼각함수
- 사인(sin): 주어진 각도(라디안 단위)의 사인 값을 계산합니다.
torch.sin(input) 함수를 사용합니다. - 코사인(cos): 주어진 각도(라디안 단위)의 코사인 값을 계산합니다.
torch.cos(input) 함수를 사용합니다. - 탄젠트(tan): 주어진 각도(라디안 단위)의 탄젠트 값을 계산합니다.torch.tan(input) 함수를 사용합니다.