Post

텐서 생성 및 연산

텐서 생성 및 연산

Tensor

텐서(Tensor)는 matrix을 표현하는 자료형으로, NumPy의 Array와 동일하게 multidimensional matrix를 표현하는 것이다. 다만, tensor는 array보다 gpu 사용, 자동 미분 등의 기능이 추가된 것이라고 생각하면 된다. 이때, Pandas의 dataframe과 동일하지 않나 생각을 할 수 있으나, pandas의 dataframe은 multidimensional matrix를 표현하는 것이 아닌, 2-dimensional table, 일종의 spreadsheet로 단순한 table 형태의 자료형이라고 생각하면 된다.

구분 Pytorch Tensor NumPy Array Pandas Dataframe
Dimension Multidimension Multidimension 2-dimension
GPU 가속 O X X
자동미분 O X X
Data Type Number Number Number, Char etc.
1
2
3
4
5
6
7
8
import numpy as np
import torch

a = [1, 2, 3]
B = [[1, 2, 3], [4, 5, 6]]

a_t = torch.tensor(a)
B_t = torch.tensor(B)

이 경우, a는 다음과 같이 출력이 되며, 행렬료 표현하면 (1)과 같다.

1
a_t

tensor([1, 2, 3])

\[\mathbf{a}_t=\begin{pmatrix}1&2&3\end{pmatrix}\tag{1}\]

2-dimensional matrix를 만들어보면 다음과 같이 할 수 있다.

1
B_t
tensor([[1, 2, 3],  
        [4, 5, 6]])
\[\mathbf{B}_t=\begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}\tag{2}\]

Tensor 생성

영행렬 생성

직접 차원 설정해서 생성
1
2
O_t = torch.zeros(2, 3)
O_t
tensor([[0., 0., 0.],
        [0., 0., 0.]])
\[\mathbf{O}_t=\begin{pmatrix}0&0&0\\0&0&0\\\end{pmatrix}\tag{3}\]
다른 tensor 속성 불러와서 생성
1
2
O_t = torch.zeros_like(B_t_T)
O_t
 tensor([[0, 0],
       [0, 0],
       [0, 0]])
\[\mathbf{O}_t=\begin{pmatrix}0&0\\0&0\\0&0\\\end{pmatrix}\tag{4}\]

원소가 모두 1인 행렬 생성

직접 차원 설정해서 생성
1
2
J_t = torch.ones(2, 3)
J_t
tensor([[1., 1., 1.],
        [1., 1., 1.]])
\[\mathbf{J}_t=\begin{pmatrix}1&1&1\\1&1&1\\\end{pmatrix}\tag{5}\]
다른 tensor 속성 불러와서 생성
1
2
J_t = torch.ones_like(B_t_T)
J_t
tensor([[1, 1],
        [1, 1],
        [1, 1]])

\(\mathbf{J}_t=\begin{pmatrix}1&1\\1&1\\1&1\\\end{pmatrix}\tag{6}\)

랜덤 상수 행렬 생성

직접 차원 설정해서 생성
1
2
C_t = torch.rand(2, 3)
C_t
tensor([[0.1483, 0.6737, 0.5585],
        [0.4265, 0.9422, 0.9804]])
\[\mathbf{C}_t=\begin{pmatrix}0.1483&0.6737&0.5585\\0.4265&0.9422&0.9804\\\end{pmatrix}\tag{7}\]
다른 tensor 속성 불러와서 생성

아래와 같은 경우 에러가 발생하게 된다. _like method는 자료형을 따로 설정하지 않는다면 다른 tensor에서 속성(차원, 자료형)을 그대로 가져와서 만들게 되는데 불러온 다른 tensor는 자료형이 long, 즉 정수형이다. 그런데 앞에서 봤듯이 .rand() method는 float 형태로 만들기에 자료형이 달라 생성을 할 수 없다. 이러한 경우, 별도로 자료형을 설정해줘야 한다.

1
2
C_t = torch.rand_like(B_t_T)
C_t
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[28], line 1
----> 1 C_t = torch.rand_like(B_t_T)

RuntimeError: "check_uniform_bounds" not implemented for 'Long'

아래와 같이 명시적으로 자료형을 설정해준 경우, 제대로 출력된다.

1
2
C_t = torch.rand_like(B_t_T, dtype=torch.float)
C_t
tensor([[0.1342, 0.1410],
       [0.5062, 0.1640],
       [0.8247, 0.4431]])
\[\mathbf{C}_t=\begin{pmatrix}0.1342&0.1410\\0.5062&0.1640\\0.8247&0.4431\\\end{pmatrix}\tag{8}\]

Tensor 차원 변수 설정 후 생성하기

Tensor는 multidimenion을 지원하기에, 단순 2 dimension (1, 2)와 같이 생성할 수도 있으나, 더 많은 dimension (1, 2, 3, 4, …)을 생성할 수도 있다.

1
2
3
shape = (3, 2, 1)
O_t = torch.zeros(shape)
O_t
tensor([[[0.],
        [0.]],

       [[0.],
        [0.]],

       [[0.],
        [0.]]])
\[\mathbf{O}_{t}=\begin{pmatrix}\begin{pmatrix}0\\0\\\end{pmatrix}&\begin{pmatrix}0\\0\\\end{pmatrix}&\begin{pmatrix}0\\0\\\end{pmatrix}\end{pmatrix}\tag{9}\]

전치 행렬

1
2
B_t_T = B_t.T
B_t_T
tensor([[1, 4],
        [2, 5],
        [3, 6]])
\[\mathbf{B}_t^T=\begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}^T=\begin{pmatrix}1&4\\2&5\\3&6\\\end{pmatrix}\tag{2}\]

Tensor 기본 연산

행렬의 합

1
2
C_t = B_t+B_t
C_t
 tensor([[ 2,  4,  6],
       [ 8, 10, 12]])
1
2
C_t = B_t.add(B_t)
C_t
 tensor([[ 2,  4,  6],
       [ 8, 10, 12]])
1
2
torch.add(B_t, B_t, out=C_t)
C_t
 tensor([[ 2,  4,  6],
       [ 8, 10, 12]])
\[\mathbf{B}_t+\mathbf{B}_t=\begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}+\begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}=\begin{pmatrix}2&4&6\\8&10&12\\\end{pmatrix}\]

행렬의 차

1
2
3
J_t = torch.ones_like(B_t)
C_t = B_t-J_t
C_t
tensor([[0, 1, 2],
       [3, 4, 5]])
\[\mathbf{B}_t-\mathbf{J}_t=\begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}-\begin{pmatrix}1&1&1\\1&1&1\\\end{pmatrix}=\begin{pmatrix}0&1&2\\3&4&5\\\end{pmatrix}\]

행렬의 곱

1
2
B_t_2 = B_t @ B_t.T
B_t_2
tensor([[14, 32],
       [32, 77]])
1
2
torch.matmul(B_t, B_t.T, out=B_t_2)
B_t_2
tensor([[14, 32],
       [32, 77]])
1
2
B_t_2 = B_t.matmul(B_t.T)
B_t_2
tensor([[14, 32],
       [32, 77]])
\[\begin{align} \mathbf{B}_t^2 &= \begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}\begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}^T \tag{10}\\ &= \begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}\begin{pmatrix}1&4\\2&5\\3&6\\\end{pmatrix} \tag{11}\\ &= \begin{pmatrix}14&32\\32&77\\\end{pmatrix} \tag{12} \end{align}\]

모든 elements의 합

하나의 tensor 안에 있는 모든 element의 합은 다음과 같이 구할 수 있다.

1
B_t.sum()

tensor(21) \(\mathbf{B}_t=\begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}\tag{13}\) \(1+2+3+4+5+6=21\tag{14}\)

Tensor 합치기

기존 차원으로 합치기

torch.cat()는 tenser를 기존 차원을 바탕으로 합치는 것이다. 행렬로 예를 들면 아래와 같이 행렬이 있을 때, 행을 추가하거나 열을 추가하는 것이다. \(\mathbf{A}_t=\begin{pmatrix}1&2&3\end{pmatrix}\tag{13}\) \(\mathbf{B}_t=\begin{pmatrix}1&2&3\\4&5&6\\\end{pmatrix}\tag{14}\) \(\mathbf{C}_t=\begin{pmatrix}1&2&3\\1&2&3\\4&5&6\\\end{pmatrix}\tag{15}\)

그런데 아래의 코드를 보면, 위와 같이 되지 않고, 오류가 나는 것을 확인할 수 있다. 그 이유는 기존에 정의한 a_t가 1차원의 vector이기 때문이다. torch.cat()를 사용하기 위해서는 tensor의 dimension이 동일해야 한다. 따라서 1행만 있는 matrix 형태의 tensor를 만들어주어야 한다.

1
C_t = torch.cat([a_t, B_t], dim=0)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[90], line 1
----> 1 C_t = torch.cat([a_t, B_t])

RuntimeError: Tensors must have same number of dimensions: got 1 and 2

1행만 있는 matrix 형태의 tensor를 새롭게 정의하여 torch.cat()를 사용하니 의도한 대로 잘 되는 것을 확인할 수 있다. 당연하겠지만, 두 tensor를 합칠 때, 합치는 부분의 dimension, 즉 행 또는 열의 수는 동일해야 한다.

1
2
3
A = [[1, 2, 3]]
A_t = torch.tensor(A)
C_t = torch.cat([A_t, B_t], dim=0)
tensor([[1, 2, 3],
       [1, 2, 3],
       [4, 5, 6]])
새로운 차원으로 합치기

torch.stack()은 방금 살펴본 torch.cat()와는 달리, 새로운 차원으로 합치게 된다. 이떄, 새로운 dimension으로 합치게 되기에 합치는 tensor들의 dimension이 동일해야 한다.

1
2
C_t = torch.stack([B_t, B_t], dim=0)
C_t
tensor([[[1, 2, 3],
        [4, 5, 6]],

       [[1, 2, 3],
        [4, 5, 6]]])
Tensor 나누기
1

Tensor dimension 바꾸기

1

Tensor dimension 축소하기

1

기타

Tensor 속성 확인

Dimension 확인
1
B_t.shape

torch.Size([2, 3])

자료형 확인
1
B_t.dtype

torch.int64

저장 위치 확인
1
B_t.device

device(type=’cpu’)

Tensor 저장 위치 변경

GPU(CUDA)로 변경
1
2
B_t = B_t.cuda()
B_t.device

device(type=’cuda’, index=0)

CPU로 변경
1
2
B_t = B_t.cpu()
B_t.device

device(type=’cpu’)

This post is licensed under CC BY 4.0 by the author.