파이토치에서 텐서는 넘파이의 ndarray를 조작하는 것과 유사하게 동작한다.
텐서 생성 및 변환
import torch
torch.tensor([[1., -1], [1.,-1]]) # 2차원 텐서 생성
torch.tensor([[1., -1], [1.,-1]], device = "cuda:0") # GPU에 텐서 생성
torch.tensor([[1., -1], [1.,-1]], dtype=torch.int32) # dtype을 이용해 텐서 생성
실행 결과
tensor([[ 1., -1.],
[ 1., -1.]])
tensor([[ 1., -1.],
[ 1., -1.]], device='cuda:0')
tensor([[ 1, -1],
[ 1, -1]], dtype=torch.int32)
첫번째는 그냥 텐서 생성, 두번째는 GPU에 텐서 생성, 세번째는 타입을 정해서 텐서를 생성하였다.
x = torch.rand(2,3)
print(x)
난수값으로 구성된 2×3 텐서 생성
x = torch.randn(2,3)
print(x)
정규분포 난수값으로 구성된 2×3 텐서 생성
torch.randint(0,10,size=(2,3))
0~9까지의 정수형 난수값으로 구성된 2×3 텐서 생성
torch.zeros(2,3)
torch.ones(2,3)
각각 0과 1으로 구성된 2×3 텐서 생성
tmp = torch.rand(2, 3)
torch.zeros_like(tmp)
torch.ones_like(tmp)
각각 tmp랑 같은 차원(형상)의 0, 1으로 구성된 텐서 생성
tmp = torch.tensor([[1., -1], [1.,-1]])
tmp.type()
type(tmp)
텐서의 타입 얻기
tmp = torch.tensor([[1., -1], [1.,-1]])
# 텐서를 numpy로 변환
print(tmp.numpy())
print(type(tmp.numpy()))
x = np.array([1, 2, 3])
torch.from_numpy(x)
텐서를 ndarray로 변환하고 싶으면 numpy() 사용. numpy에서 텐서로 변환하고 싶으면 from_numpy사용
tmp = torch.tensor([[1., -1], [1.,-1]], device = "cuda:0")
print(tmp.to("cpu"))
GPU에 생성한 tensor를 cpu로 변환
텐서 연산
v = torch.tensor([1, 2, 3])
w = torch.tensor([4, 5, 6])
텐서 뺄셈
v - w
tensor([-3, -3, -3])
텐서 덧셈
v + w # torch.add(v, w)도 같은 연산
tensor([5, 7, 9])
텐서 곱셈
v * w # torch.mul(v,w)도 같은 연산
tensor([ 4, 10, 18])
텐서의 곱 계산
torch.dot(v,w)
tensor(32)
텐서의 내적
x1 = torch.FloatTensor([[1,2,3],[4,5,6]])
x2 = torch.FloatTensor([[1,2,3],[4,5,6],[7,8,9]])
torch.mm(x1,x2)
tensor([[30., 36., 42.],
[66., 81., 96.]])
행렬곱
x1 = torch.FloatTensor([
[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]],
])
x2 = torch.FloatTensor([
[[1,2,3],[4,5,6],[7,8,9]],
[[1,2,3],[4,5,6],[7,8,9]],
])
torch.bmm(x1,x2)
tensor([[[30., 36., 42.],
[66., 81., 96.]],
[[30., 36., 42.],
[66., 81., 96.]]])
배치 행렬곱 연산
텐서 나눗셈
w / v # torch.div(w,v)도 같은 연산
tensor([4.0000, 2.5000, 2.0000])
텐서 제곱
w**2
torch.pow(w, 2)
tensor([16, 25, 36])
텐서 2개 결합하기
x = torch.FloatTensor([[1,2,3],[4,5,6]])
y = torch.FloatTensor([[-1,-2,-3],[-4,-5,-6]])
z1 = torch.cat([x,y], dim=0)
print(z1)
'''
tensor([[ 1., 2., 3.],
[ 4., 5., 6.],
[-1., -2., -3.],
[-4., -5., -6.]])
'''
z2 = torch.cat([x,y], dim=1)
print(z2)
'''
tensor([[ 1., 2., 3., -1., -2., -3.],
[ 4., 5., 6., -4., -5., -6.]])
'''
z3 = torch.stack([x, y])
print(z3)
'''
tensor([[[ 1., 2., 3.],
[ 4., 5., 6.]],
[[-1., -2., -3.],
[-4., -5., -6.]]])
'''
cat과 stack 둘 다 텐서 2개를 연결해주는 연산. cat은 주어진 텐서의 고유 shape에 맞추어서 병합. stack은 새로운 차원으로 확장하여 텐서 시퀀스를 병합.
텐서의 전치
x1 = torch.tensor([[1,2,3],[4,5,6],[7,8,9]])
print(x1)
x2 = x1.t()
print(x2)
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
tensor([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
텐서 분해
tmp = torch.FloatTensor([
[ 1., 2., 3.],
[ 4., 5., 6.],
[7., 8., 9.],
[10., 11., 12.]
])
x, y = torch.chunk(tmp, 2, dim=0)
print(x, y, sep= '\n')
'''
tensor([[1., 2., 3.],
[4., 5., 6.]])
tensor([[ 7., 8., 9.],
[10., 11., 12.]])
'''
x, y, z = torch.chunk(tmp, 3, dim=1)
print(x, y, z, sep= '\n')
'''
tensor([[ 1.],
[ 4.],
[ 7.],
[10.]])
tensor([[ 2.],
[ 5.],
[ 8.],
[11.]])
tensor([[ 3.],
[ 6.],
[ 9.],
[12.]])
'''
x, y = torch.split(tmp, 2, dim=1)
print(x, y, sep= '\n')
'''
tensor([[ 1., 2.],
[ 4., 5.],
[ 7., 8.],
[10., 11.]])
tensor([[ 3.],
[ 6.],
[ 9.],
[12.]])
'''
chunk의 경우 n개의 그룹을 만드는 것이고, split의 경우 n개의 데이터가 있는 그룹을 만드는 것