전공공부/인공지능

Tensor manipulation -1

prefer_all 2022. 7. 26. 22:28

잘 정리되어 있음 https://wikidocs.net/52460

 

<목차>
1. Pytorch Tensor Shape
2. Numpy로 Tensor 만들기
3. Pytorch로 Tensor 만들기
- broadcasting
4. 기능
- 곱(multiplication)과 행렬 곱(matrix multiplication) 차이
- 평균(mean)  ***dim = 0, dim = 1
- 덧셈(sum)
- 최대(max)와 아그맥스(argmax)

 

1차원 벡터/ 2차원 행렬(matrix) / 3차원 텐서(Tensor) - 우리가 살고 있는 세상


Numpy로 Tensor 만들기

  • Numpy로 1차원 텐서인 벡터를 만들기
t = np.array([0., 1., 2., 3., 4., 5., 6.])
print('Rank of t: ', t.ndim) #몇 차원인지를 출력
print('Shape of t: ', t.shape)
'''
Rank of t:  1
Shape of t:  (7,)
'''
print('t[0] t[1] t[-1] = ', t[0], t[1], t[-1]) # 인덱스를 통한 원소 접근
#t[0] t[1] t[-1] =  0.0 1.0 6.0
print('t[2:5] t[4:-1]  = ', t[2:5], t[4:-1]) # [시작 번호 : 끝 번호]로 범위 지정을 통해 가져온다
#t[2:5] t[4:-1]  =  [2. 3. 4.] [4. 5.]

 

  • Numpy로 2차원 행렬 만들기
t = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.], [10., 11., 12.]])

Pytorch Tensor 선언하기

  • 1차원 텐서
import torch
t = torch.FloatTensor([0., 1., 2., 3., 4., 5., 6.])

print(t.dim())  # rank. 즉, 차원
print(t.shape)  # shape
print(t.size()) # shape
'''
1
torch.Size([7])
torch.Size([7])
'''

print(t[0], t[1], t[-1])  # 인덱스로 접근
print(t[2:5], t[4:-1])    # 슬라이싱
'''
tensor(0.) tensor(1.) tensor(6.)
tensor([2., 3., 4.]) tensor([4., 5.])
'''

 

  • 2차원 텐서
import torch
t = torch.FloatTensor([[1., 2., 3.],
                       [4., 5., 6.],
                       [7., 8., 9.],
                       [10., 11., 12.]
                      ])
print(t.dim())  # rank. 즉, 차원
print(t.shape)  # shape
print(t.size()) # shape
'''
2
torch.Size([4, 3])
torch.Size([4, 3])
'''

print(t[:, 1]) # 첫번째 차원을 전체 선택한 상황에서 두번째 차원의 첫번째 것만 가져온다.
print(t[:, 1].size()) # ↑ 위의 경우의 크기
'''
tensor([ 2.,  5.,  8., 11.])
torch.Size([4])
'''

print(t[:, :-1]) 
# 첫번째 차원을 전체 선택한 상황에서 
# 두번째 차원에서는 맨 마지막에서 첫번째를 제외하고 다 가져온다.
'''
tensor([[ 1.,  2.],
        [ 4.,  5.],
        [ 7.,  8.],
        [10., 11.]])
'''

 

  • Broadcasting

행렬의 덧셈, 뺄셈, 곱셈 등을 할 때 자동으로 크기를 맞춰서 연산을 수행하게 하는 기능

m1 = torch.FloatTensor([[1, 2]])
m2 = torch.FloatTensor([3]) # [3] -> [3, 3]
print(m1 + m2)
#tensor([[4., 5.]])
# 2 x 1 Vector + 1 x 2 Vector
m1 = torch.FloatTensor([[1, 2]])
m2 = torch.FloatTensor([[3], [4]])
print(m1 + m2)
'''
tensor([4., 5.],
       [5., 6.]])
       
이유:
[1, 2]
==> [[1, 2],
     [1, 2]]
[3]
[4]
==> [[3, 3],
     [4, 4]]
'''

행렬 곱셈(.matmul) <-> 원소 별 곱셈(.mul)

m1 = torch.FloatTensor([[1, 2], [3, 4]]) # 2x2
m2 = torch.FloatTensor([[1], [2]]) # 2x1
print(m1.matmul(m2)) # 2 x 1
'''
tensor([[ 5.],
        [11.]])
'''

print(m1 * m2) # 2 x 2
print(m1.mul(m2))
'''
tensor([[1., 2.],
        [6., 8.]])
'''


평균

t = torch.FloatTensor([1, 2])
print(t.mean()) #tensor(1.5000)
t = torch.FloatTensor([[1, 2], [3, 4]])
print(t.mean()) #tensor(2.5000)

print(t.mean(dim=0)) #tensor([2., 3.])
'''
<실제 연산 과정>
t.mean(dim=0)은 입력에서 첫번째 차원을 제거한다.

[[1., 2.],
 [3., 4.]]

1과 3의 평균을 구하고, 2와 4의 평균을 구한다.
결과 ==> [2., 3.]
'''
  • dim=0이라는 것은 첫번째 차원을 의미합니다. (행렬에서 첫번째 차원은 '행'을 의미)
  • 인자로 dim을 준다면 해당 차원을 제거한다는 의미임 (즉, 행렬에서 '열'만을 남기겠다는 의미)
  • 기존 행렬의 크기는 (2, 2)였지만 이를 수행하면 열의 차원만 보존되면서 (1, 2)가 됨

 

t = torch.FloatTensor([[1, 2], [3, 4]])
print(t.mean(dim=1)) #tensor([1.5000, 3.5000])

덧셈

t = torch.FloatTensor([[1, 2], [3, 4]])
print(t.sum(dim=0)) # 행을 제거 tensor([4., 6.])
print(t.sum(dim=1)) # 열을 제거 tensor([3., 7.])
print(t.sum(dim=-1)) # 열을 제거 tensor([3., 7.])

최대와 아그맥스

  • 최대(Max)는 원소의 최대값을 리턴하고, 아그맥스(ArgMax)는 최대값을 가진 인덱스를 리턴
t = torch.FloatTensor([[1, 2], [3, 4]])
print(t.max()) # Returns one value: max
#tensor(4.)

print(t.max(dim=0)) # Returns two values: max and argmax
#(tensor([3., 4.]), tensor([1, 1]))

print('Max: ', t.max(dim=0)[0]) #Max:  tensor([3., 4.])
print('Argmax: ', t.max(dim=0)[1]) #Argmax:  tensor([1, 1])