Development/AI

파이토치로 텐서 기본 조작하기 (Manipulating Tensor with PyTorch)

고고마코드 2021. 12. 18. 14:14
반응형

개발환경 : Google Colab

텐서를 만들기 전에 텐서 정보를 계속 확인하기 위해 사전 함수를 만든다.

#Tensor 상세 정보 확인
def desc(x):
  print("타입: {} / 크기: {}".format(x.type(), x.shape))
  print("값: {}\n".format(x))

텐서 만들기

기본

import torch
desc(torch.Tensor(2, 2))
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[1.2292e+09, 3.0907e-41],
        [8.5479e-44, 4.4842e-44]])
'''

파이썬 리스트로 만들기

import torch
a = [[1, 2, 3],
     [4, 5, 6]]
x = torch.Tensor(a)
desc(x)
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 3])
값: tensor([[1., 2., 3.],
        [4., 5., 6.]])
'''

넘파이 배열로 만들기

import torch
import numpy as np
numpy = np.random.rand(2, 2)
desc(torch.from_numpy(numpy))
'''
타입: torch.DoubleTensor / 크기: torch.Size([2, 2])
값: tensor([[0.5902, 0.7734],
        [0.8373, 0.1071]], dtype=torch.float64)
'''

랜덤하게 초기화한 텐서

import torch
desc(torch.rand(2, 2)) #[0, 1) 범위의 균등 분포에서 랜덤하게 초기화
desc(torch.randn(2, 2)) #표준 정규 분포
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[0.1150, 0.5218],
        [0.4766, 0.0377]])

타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[ 0.6931, -1.5548],
        [-0.1418, -0.3704]])
'''

메소드 활용

텐서를 특정값으로 채울 때 사용

zeros() : 0으로 채운다.

ones() : 1로 채운다.

fill_() : 지정한 값으로 채운다.

import torch
a = torch.zeros(2, 2) #0으로 채운다.
b = torch.ones(2, 2) #1로 채운다.
c = torch.Tensor(2, 2).fill_(5) #파라미터의 수로 채운다.
d = torch.Tensor(2, 2).fill_(8) 

desc(a)
desc(b)
desc(c)
desc(d)
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[0., 0.],
        [0., 0.]])

타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[1., 1.],
        [1., 1.]])

타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[5., 5.],
        [5., 5.]])

타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[8., 8.],
        [8., 8.]])
'''

unsqueeze() / squeeze()

지정된 위치에 차원을 추가 / 차원을 제거

import torch
x = torch.rand(2, 2)

desc(x)
desc(torch.unsqueeze(x, 0))
desc(torch.unsqueeze(x, 1))
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[0.5341, 0.7530],
        [0.3902, 0.5758]])

타입: torch.FloatTensor / 크기: torch.Size([1, 2, 2])
값: tensor([[[0.5341, 0.7530],
         [0.3902, 0.5758]]])

타입: torch.FloatTensor / 크기: torch.Size([2, 1, 2])
값: tensor([[[0.5341, 0.7530]],

        [[0.3902, 0.5758]]])
'''
import torch
x = torch.rand(2, 2)
desc(x)
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[0.9985, 0.4602],
        [0.6392, 0.0640]])
'''
x = torch.unsqueeze(x, 1)
desc(x)
desc(torch.squeeze(x, 1))
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 1, 2])
값: tensor([[[0.9985, 0.4602]],

        [[0.6392, 0.0640]]])

타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[0.9985, 0.4602],
        [0.6392, 0.0640]])
'''

uniform_()

특정 범위의 분포를 가지는 텐서

import torch
x = torch.FloatTensor(2, 5).uniform_(4, 6)
desc(x) 
'''
uniform_(4, 6) : 4~6 사이

타입: torch.FloatTensor / 크기: torch.Size([2, 5])
값: tensor([[4.8021, 4.1479, 4.7584, 5.4835, 5.5679],
        [5.3559, 5.4350, 4.7787, 5.9478, 5.3556]])
'''

normal_()

정규분포 텐서

import torch
desc(torch.rand(2, 2).normal_())
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[-0.2631, -0.2321],
        [ 0.4090,  0.7234]])
'''

add()

더하기 연산

import torch
x = torch.rand(2, 2).fill_(3)

desc(x)
desc(torch.add(x, x))
desc(x + x)
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[3., 3.],
        [3., 3.]])

타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[6., 6.],
        [6., 6.]])

타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[6., 6.],
        [6., 6.]])
'''

view()

기본 텐서의 동일한 데이터로 다른 모양의 텐서를 반환

import torch
x = torch.randn(2, 2)
desc(x)
desc(x.view(4))
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[-0.2181,  0.5708],
        [ 0.5501, -0.6792]])

타입: torch.FloatTensor / 크기: torch.Size([4])
값: tensor([-0.2181,  0.5708,  0.5501, -0.6792])
'''

sum()

텐서에서 입력한 차원의 모든 요소의 합을 합친다.

import torch
x = torch.rand(2, 2).uniform_(1, 2)
desc(x)
desc(torch.sum(x, 0))
desc(torch.sum(x, 1))
'''
타입: torch.FloatTensor / 크기: torch.Size([2, 2])
값: tensor([[1.2722, 1.8252],
        [1.2940, 1.9806]])

타입: torch.FloatTensor / 크기: torch.Size([2])
값: tensor([2.5662, 3.8058])

타입: torch.FloatTensor / 크기: torch.Size([2])
값: tensor([3.0974, 3.2746])
'''

transpose()

텐서의 내부 차원 간 데이터 변경

import torch
x = torch.rand(10, 20, 30, 40)
print(x.shape)
'''torch.Size([10, 20, 30, 40])'''

print(torch.transpose(x, 0, 1).shape)
print(torch.transpose(x, 2, 3).shape)
print(torch.transpose(x, 1, 2).shape)
'''
torch.Size([20, 10, 30, 40])
torch.Size([10, 20, 40, 30])
torch.Size([10, 30, 20, 40])
'''

인덱싱, 슬라이싱

기본

import torch
x = torch.arange(6).view(2, 3)
print(x)
'''
tensor([[0, 1, 2],
        [3, 4, 5]])
'''

print(x[:1, :2])
print(x[:2, :3])
'''
tensor([[0, 1]])
tensor([[0, 1, 2],
        [3, 4, 5]])
'''

print(x[0, 1])
print(x[1, 2])
'''
tensor(1)
tensor(5)
'''

복잡한 인덱싱 (1)

import torch
x = torch.arange(6).view(2, 3)
indices = torch.LongTensor([0, 2])

desc(x)
'''
타입: torch.LongTensor / 크기: torch.Size([2, 3])
값: tensor([[0, 1, 2],
        [3, 4, 5]])
'''
desc(torch.index_select(x, 0, torch.LongTensor([0, 0])))
desc(torch.index_select(x, 0, torch.LongTensor([1, 1])))
'''
타입: torch.LongTensor / 크기: torch.Size([2, 3])
값: tensor([[0, 1, 2],
        [0, 1, 2]])

타입: torch.LongTensor / 크기: torch.Size([2, 3])
값: tensor([[3, 4, 5],
        [3, 4, 5]])
'''

desc(torch.index_select(x, 1, torch.LongTensor([0, 1])))
desc(torch.index_select(x, 1, torch.LongTensor([0, 2])))
'''
타입: torch.LongTensor / 크기: torch.Size([2, 2])
값: tensor([[0, 1],
        [3, 4]])

타입: torch.LongTensor / 크기: torch.Size([2, 2])
값: tensor([[0, 2],
        [3, 5]])
'''

복잡한 인덱싱 (2)

import torch
x = torch.arange(6).view(2, 3)
print(x)
'''
tensor([[0, 1, 2],
        [3, 4, 5]])
'''
print(x[torch.LongTensor([0, 0]), torch.LongTensor([0, 0])])
print(x[torch.LongTensor([0, 0]), torch.LongTensor([0, 1])])
print(x[torch.LongTensor([0, 0]), torch.LongTensor([0, 2])])
'''
tensor([0, 0])
tensor([0, 1])
tensor([0, 2])
'''

print(x[torch.LongTensor([1, 0]), torch.LongTensor([0, 0])])
print(x[torch.LongTensor([1, 0]), torch.LongTensor([0, 1])])
print(x[torch.LongTensor([1, 0]), torch.LongTensor([2, 2])])
'''
tensor([3, 0])
tensor([3, 1])
tensor([5, 2])
'''

expand()

텐서 복사

import torch
x = torch.rand(3, 1)
print(x)
'''
tensor([[0.8069],
        [0.9352],
        [0.6312]])
'''

print(x.expand(3, 2))
print(x.expand(3, 4))
'''
tensor([[0.8069, 0.8069],
        [0.9352, 0.9352],
        [0.6312, 0.6312]])
tensor([[0.8069, 0.8069, 0.8069, 0.8069],
        [0.9352, 0.9352, 0.9352, 0.9352],
        [0.6312, 0.6312, 0.6312, 0.6312]])
'''

mm()

행렬 곱셈

import torch
a = torch.arange(6).view(2, 3)
b = torch.LongTensor(3, 2).fill_(3)

print(a)
print(b)
print(torch.mm(a, b))
'''
tensor([[0, 1, 2],
        [3, 4, 5]])
tensor([[3, 3],
        [3, 3],
        [3, 3]])
tensor([[ 9,  9],
        [36, 36]])
'''

bmm()

배치행렬 곱셈

import torch
a = torch.rand(2,1,2)
b = torch.rand(2,2,1)

print(a)
print(b)
print(torch.bmm(a, b))
'''
tensor([[[0.7077, 0.2738]],

        [[0.3667, 0.9299]]])
tensor([[[0.1659],
         [0.0979]],

        [[0.9319],
         [0.0933]]])
tensor([[[0.1442]],

        [[0.4285]]])
'''

requires_grad=True

그레이디언를 기록하는 부가 연산 활성화

import torch
a = torch.ones(2, 2, requires_grad=True)
print(a)
'''
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)
'''

b = a + 2
print(b)
print(a.grad is None)
'''
tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)
True
'''

b[0, :] = 5
c = b.mean() #텐서 평균값
print(b)
print(c)
'''
tensor([[5., 5.],
        [3., 3.]], grad_fn=<CopySlices>)
tensor(4., grad_fn=<MeanBackward0>)
'''

c.backward() #역방향 계산(정방향 계산에 참여한 텐서에 대한 그레이디언트값을 계산)
print(a.grad is None)
'''False'''

CUDA 텐서 만들기

torch.cuda.is_available() : CUDA 텐서의 사용 여부를 확인

import torch
print(torch.cuda.is_available())
'''
True
CUDA 텐서 사용 불가능 하면 False
'''

cuda 텐서 사용

'''
device() 종류
cpu, cuda, xpu, mkldnn, opengl, opencl, ideep, hip, 
ve, ort, mlc, xla, lazy, vulkan, meta, hpu
'''
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)
#cuda

x = torch.rand(2, 2).to(device)
print(x)
'''
tensor([[0.0848, 0.5855],
        [0.3222, 0.7351]], device='cuda:0')
'''

공식 매뉴얼

  1. torch.Tensor — PyTorch 1.10.0 documentation

반응형