Pytorch - Tensor
정의
다차원 배열을 의미하며, Numpy에서의 Array와 유사하다.
연산 속도를 극대화하기 위해 GPU연산을 지원한다.
이 때 그래픽카드가 없으면 CPU모드로 설치할 수 있는데, 이런 경우 GPU연산은 지원되지 않지만, 더 많은 딥러닝 연산 함수가 지원되는 tensor객체를 사용하기 위해 파이토치를 사용하기도 한다.
x = torch.zeros(5, 3)
print(x)
print(x.shape)
"""
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]) 행렬의 원소를 0으로 하고 출력한다
torch.Size([5, 3]) 5행 3열 크기의 행렬
"""
2차원 텐서 뿐만 아니라 3차원 N차원까지 존재하며, torch.Size([a,b,c,d,e.....])로 텐서의 크기를 표현한다.
a = torch.rand(1000, 100000) # 1000 * 100000 크기 행렬을 0~1사이의 값으로 채운다.
b = torch.rand(1000, 100000)
# GPU가 사용가능한지 확인
if torch.cuda.is_available():
# cuda() 함수를 통해 gpu tensor로 변환
a = a.cuda()
b = b.cuda()
GPU를 사용해 빠른 연산을 수행할 수 있다.
기본 함수
텐서로 활용할 수 있는 함수들에 대해 알아보자.
tensor = torch.FloatTensor([[1., 2., 3.],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
])
tensor.dim() # tensor의 차원 확인. 2차원.
tensor.size() # tensor의 shape 확인. 4,3 크기의 행렬
tensor[:, 1] # 2번째 열만 취함 (0부터 시작하니까) tensor([ 2., 5., 8., 11.]) 반환
tensor[:, 1].size() # shape 확인. 크기는 4이다.
텐서끼리 연산을 수행할 수 있다.
t1 = torch.Tensor([[3, 3]])
t2 = torch.Tensor([[2, 1]])
t1 + t2 # tensor([[5., 4.]]) 출력됨
###
t1 = torch.Tensor([[1, 2]])
t2 = torch.Tensor([3]) # [3] -> [3, 3] 스칼라를 벡터의 크기만큼 늘려서 연산한다.
t1 + t2 # tensor([[4., 5.]])
###
t1 = torch.Tensor([[1, 2]]) # (1 x 2) -> (2 x 2)
t2 = torch.Tensor([[3], [4]]) # (2 x 1) -> (2 x 2) 크기가 다른 벡터끼리도 크기를 맞춰서 연산한다.
t1 + t2 # tensor([[4., 5.],[5., 6.]])
곱셈에 대해서는 행렬곱과 원소별 곱을 모두 수행할 수 있다.
t1 = torch.FloatTensor([[1, 2], [3, 4]])
t2 = torch.FloatTensor([[1], [2]])
t1.matmul(t2) # 행렬 곱셈. 5,11
t1 * t2 # 행렬의 원소별 곱셈. [1,2]; [6,8] 크기는 알아서 맞춰진다.
t1.mul(t2) # 행렬의 원소별 곱셈. 같은 동작을 수행한다.
t = torch.FloatTensor([[1, 2], [3, 4]])
print(t.sum()) # 단순히 원소 전체의 덧셈을 수행. 10
print(t.sum(dim=0)) # 열 끼리 덧셈을 진행. 4,6
print(t.sum(dim=1)) # 행 끼리 덧셈을 진행. 3,7
print(t.sum(dim=-1)) # 마지막 차원을 제거하면서 덧셈 수행 --> 여기서는 열 제거. 3,7
print(t.mean()) # 단순히 원소 전체의 평균을 계산. 2.5
print(t.mean(dim=0)) # 열 끼리 평균 계산 2, 3
print(t.mean(dim=1)) # 행 끼리 평균 계산 1.5, 3.5
print(t.mean(dim=-1)) # 마지막 차원을 제거하면서 평균 계산 --> 여기서는 열 제거 1.5, 3.5
print(t.max()) # 단순히 원소 전체의 최대값 반환
print(t.max(dim=0)) # 열에 대해 최대값 반환
print(t.max(dim=1)) # 행에 대해 최대값 반환
print(t.max(dim=-1)) # 마지막 차원을 제거하면서 최대값 반환 --> 여기서는 열 제거
print(t.argmax()) # 단순히 원소 전체의 최대값의 인덱스 반환
print(t.argmax(dim=0)) # 열에 대해 최대값의 인덱스 반환
print(t.argmax(dim=1)) # 행에 대해 최대값의 인덱스 반환
print(t.argmax(dim=-1)) # 마지막 차원을 제거하면서 최대값의 인덱스 반환 --> 여기서는 열 제거
차원 변경 함수
먼저 텐서의 차원에 대해 확실하게 이해하고 가자.
1차원에서는 크기가 (열)로 주어진다.
tensor = torch.FloatTensor([1,1,1,1,1,1,1])
# 7
2차원에서는 크기가 (행, 열)로 주어진다.
tensor = torch.FloatTensor([[1,1,1,1,1],[1,1,1,1,1]])
# 2,5
3차원에서는 크기가 (개수, 행, 열)로 주어진다.
tensor = torch.FloatTensor([[[0, 1, 2],
[3, 4, 5]],
[[6, 7, 8],
[9, 10, 11]]])
# 2,2,3
view함수를 사용해서 원소의 수를 유지하면서 텐서의 크기를 변경할 수 있다.
tensor = torch.FloatTensor([[[0, 1, 2],
[3, 4, 5]],
[[6, 7, 8],
[9, 10, 11]]])
viewed_tensor = tensor.view([-1, 3]) # 4,3
viewed_tensor2 = tensor.view([-1, 1, 3]) # 4,1,3
여기서 -1을 크기에 지정하는 건 파이토치에게 알아서 크기를 설정하라는 것으로 이해하면 된다.
변경 전과 변경 후의 원소 수는 같다는 점에 집중하자.
squeeze함수를 이용해서 원소의 개수가 한 개인 차원을 지울 수 있다.
tensor = torch.FloatTensor([[0], [1], [2]])
squeezed_tensor = tensor.squeeze() # 크기 3
unsqueeze함수를 사용하면 원소의 개수가 한 개인 차원을 추가할 수 있다.
tensor = torch.FloatTensor([0, 1, 2])
unsqueezed_tensor = tensor.unsqueeze(0) # 0번째에 차원을 추가함
#tensor([[0., 1., 2.]])
원래 크기가 3인 텐서를 크기가 (1,3)인 텐서로 바꿨다.
이 때 차원을 추가하는 개념이기 때문에, 원소가 추가되지는 않는다. (이해하기)
차원을 건너뛰어서 추가할 수는 없다.
타입 캐스팅
텐서에서도 타입이 존재한다.
텐서를 선언할 때 별도로 타입을 지정해주지 않을 경우 텐서에서의 원소의 타입에 따라 텐서의 타입이 결정된다.
long_tensor = torch.LongTensor([1, 2, 3, 4])
long_tensor.type() # 'torch.LongTensor'
.float() 처럼 타입에 해당하는 함수를 사용해 텐서의 타입을 변환할 수 있다.
병합
cat함수를 사용해 두 텐서를 연결할 수 있으며, 이 때 방향 또한 함께 설정할 수 있다.
x = torch.Tensor([[1, 2], [3, 4]])
y = torch.Tensor([[5, 6], [7, 8]])
concat_tensor1 = torch.cat([x, y], dim=0) # 첫 번째 차원에 연결
concat_tensor2 = torch.cat([x, y], dim=1) # 두 번째 차원에 연결
stack함수를 사용해 두 텐서를 연결할 수 있다.
x = torch.FloatTensor([1, 4])
y = torch.FloatTensor([2, 5])
z = torch.FloatTensor([3, 6])
stacked_tensor1 = torch.stack([x, y, z]) # 첫 번째 차원에 쌓기
#tensor([[1., 4.],
[2., 5.],
[3., 6.]])
stacked_tensor2 = torch.stack([x, y, z], dim=1) # 두 번째 차원에 쌓기
#tensor([[1., 2., 3.],
[4., 5., 6.]])
파이토치의 DataLoader를 사용하면 배치 크기(행)만큼 데이터를 전달할 수 있어 GPU를 활용해 데이터를 병렬로 처리하는데 도움을 준다.
'Machine Learning > AI Introduction' 카테고리의 다른 글
Pytorch Lightning (0) | 2022.03.26 |
---|---|
Pytorch / Tensorflow - 차원 (0) | 2022.03.18 |
정리 (0) | 2021.12.13 |
Machine Learning - RNN (0) | 2021.12.05 |
Deep Learning - CNN (0) | 2021.12.05 |
댓글
이 글 공유하기
다른 글
-
Pytorch Lightning
Pytorch Lightning
2022.03.26 -
Pytorch / Tensorflow - 차원
Pytorch / Tensorflow - 차원
2022.03.18 -
정리
정리
2021.12.13 -
Machine Learning - RNN
Machine Learning - RNN
2021.12.05