[Pytorch]텐서의 정의
카테고리: Pytorch
Pytorch Framework
1. Pytorch 개요
- PyTorch는 기계 학습 프레임워크(framework) 중 하나다.
- PyTorch의 텐서(tensor)는 NumPy 배열과 매우 유사하다.
- PyTorch를 사용하면, GPU 연동을 통해 효율적으로 딥러닝 모델을 학습할 수 있다.
2. Tensor(텐서)
1) 텐서의 정의
- 데이터 표현을 위한 기본 구조로 텐서(tensor)를 사용
- 텐서는 데이터를 담기위한 컨테이너(container)로서 일반적으로 수치형 데이터를 저장
- 넘파이(NumPy)의 ndarray와 유사
- GPU를 사용한 연산 가속 가능
import torch
print(torch.__virsion__)
data = [
[1,2],
[3,4]
]
x = torch.tensor(data) ## 텐서로 데이터 저장
print(x.is_cuda)
x = x.cuda() ## GPU로 옮기기
print(x.is_cuda)
x = x.cpu() ## CPU로 옮기기기
print(x.is_cuda)
1.13.1+cu116
False
True
False
# GPU 장치의 텐서
a = torch.tensor([
[1,2],
[3,4]
]).cuda()
# CPU 장치의 텐서
b = torch.tensor([
[5,6],
[7,8]
])
# print(torch.matmul(a,b)) # 오류 발생
print(torch.matmul(a.cpu(), b))
tensor([[19, 22],
[43, 50]])
2) 텐서 초기화와 데이터 타입
텐서는 여러가지 방법으로 초기화할 수 있다.
- Ex)
- 데이터로부터 직접(directly) 생성하기
- 데이터로부터 직접 텐서를 생성할 수 있습니다.
- 데이터의 자료형(data type)은 자동으로 유추한다
- 데이터로부터 직접(directly) 생성하기
데이터로부터 직접(directly) 생성
리스트를 이용
data = [[1,2],[3,4]]
x_data = torch.tensor(data)
print(x_data)
tensor([[1, 2],
[3, 4]])
초기화되지 않은 센서
초기화되지 않은 값인데 왜 특정 값이 있나?
초기화가되지 않았으니깐, 메모리를 잡긴 잡더라도, 메모리에서 기존에 사용하던 값들을 그냥 그대로 가져온 것일 뿐임
# 실행마다 달라짐. 정말 아무 의미없는 값들로 채워짐. 쓰레기 값들
x = torch.empty(4,2)
print(x)
실행 1
tensor([[0., 0.],
[0., 0.],
[0., 0.],
[0., 0.]])
실행 2
tensor([[-1.0367e+05, 4.5691e-41],
[-1.0367e+05, 4.5691e-41],
[ 4.4842e-44, 0.0000e+00],
[ 8.9683e-44, 0.0000e+00]])
무작위(random)로 초기화 되는 텐서
x = torch.rand(4,2)
print(x)
tensor([[0.1168, 0.2962],
[0.0421, 0.7551],
[0.9146, 0.1689],
[0.3916, 0.7220]])
dtype이 long, 0으로 채워진 텐서
x = torch.zeros(4,2, dtype = torch.long) ## (4,2)의 원소가 0으로 채워진 행렬렬
print(x)
tensor([[0, 0],
[0, 0],
[0, 0],
[0, 0]])
Numpy 배열로부터 생성하기
import numpy as np
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
print(x_np)
print('-----------------')
print(x_np.shape)
print('-----------------')
print(x_np.dtype)
tensor([[1, 2],
[3, 4]])
----------------------
torch.Size([2, 2])
----------------------
torch.int64
다른 텐서로부터 생성
x_ones = torch.ones_like(x_data) # x_data의 속성을 유지, x_data와 사이즈 동일, but 성분은 모두 1
print(f"Ones Tensor: \n {x_ones} \n")
x_rand = torch.rand_like(x_data, dtype=torch.float) # x_data의 속성을 덮어씀
print(f"Random Tensor: \n {x_rand} \n")
Ones Tensor:
tensor([[1, 1],
[1, 1]])
Random Tensor:
tensor([[0.1945, 0.8921],
[0.1632, 0.8592]])
기타
x = torch.tensor([3,2.3]) # 값을 직접 지정해줌
print(x)
tensor([3.0000, 2.3000])
x = x.new_ones(2,4,dtype = torch.double)
print(x)
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.]], dtype=torch.float64)
x = torch.randn_like(x, dtype = torch.float) ## like는 data의 shape을 그대로 가져와서 값을 채워넣겠다.
print(x)
## 위에서 x를 2,4 행렬로 잡았으니 like에 의해 2x4행렬로 나옴
tensor([[-0.2537, 1.3063, 1.4733, -0.9004],
[-1.2198, -0.5154, 0.5316, 2.5383]])
shape = (2, 3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)
print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
Random Tensor:
tensor([[0.8067, 0.4252, 0.0554],
[0.0625, 0.1938, 0.8126]])
Ones Tensor:
tensor([[1., 1., 1.],
[1., 1., 1.]])
Zeros Tensor:
tensor([[0., 0., 0.],
[0., 0., 0.]])
x = torch.tensor([
[5, 7],
[1, 2]
])
# x와 같은 모양과 자료형을 가지지만, 값이 1인 텐서 생성
x_ones = torch.ones_like(x)
print(x_ones)
# x와 같은 모양을 가지되, 자료형은 float으로 덮어쓰고, 값은 랜덤으로 채우기
x_rand = torch.rand_like(x, dtype=torch.float32) # uniform distribution [0, 1)
print(x_rand)
tensor([[1, 1],
[1, 1]])
tensor([[0.4862, 0.9064],
[0.0512, 0.1819]])
3) 텐서의 속성
- 텐서의 기본 속성으로는 다음과 같은 것들이 있다.
- 모양(shape)
- 자료형(data type)
- 저장된 장치
텐서의 크기(shape)
x = torch.rand(4,2)
print(x)
print('-------------------------------')
print(x.shape)
tensor([[0.4579, 0.8034],
[0.8778, 0.9338],
[0.5151, 0.0725],
[0.6880, 0.8795]])
-------------------------------
torch.Size([4, 2])
텐서의 자료형
x = torch.rand(4,2)
print("Data Type: ", x.dtype)
Data Type: torch.float32
저장된 장치
x = torch. rand(4,2)
print("x.Device: ", x.device)
print("-----------------------")
y = torch. rand(4,2).cuda()
print("y.Device: ", y.device)
x.Device: cpu
-----------------------
y.Device: cuda:0
텐서 만들기 정리
torch.empty(x, y)
= x * y 사이즈의 요소들의 값이 초기화 되지 않은 행렬 반환torch.rand(x, y)
: x * y 사이즈의 요소들이 0 ~ 1 사이의 랜덤한 값으로 초기화 된 행렬 반환.torch.randn(x, y)
: x * y 사이즈의 요소들이 정규분포 그래프 상의 랜덤한 값으로 초기화 된 행렬 반환.torch.zeros(x, y, dtype=type)
: x * y 사이즈의 요소들이 0으로 초기화 된 행렬 반환, 요소들은 type에 맞게 초기화 된다.torch.ones(x, y, dtype=type)
: x * y 사이즈의 요소들이 1으로 초기화 된 행렬 반환, 요소들은 type에 맞게 초기화 된다.torch.tensor(iterable)
: iterable한 객체를 Tensor 객체로 변환한다.torch.zeros_like(tensor, dtype=type)
: 파라미터로 들어 간 Tensor 객체의 사이즈과 똑같은 행렬을 반환하며, 요소들은 0으로 초기화 되어 있다.torch.ones_like(tensor, dtype=type)
: 파라미터로 들어 간 Tensor 객체의 사이즈과 똑같은 행렬을 반환하며, 요소들은 1으로 초기화 되어 있다.torch.randn_like(tensor, dtype=type)
: 파라미터로 들어 간 Tensor 객체의 사이즈과 똑같은 행렬을 반환하며, 요소들은 정규분포 그래프 상의 랜덤한 값으로 초기화 되어 있다.
empty_tensor = torch.empty(3, 3) # 3 * 3의 빈 행렬 생성
rand_tensor = torch.rand(3, 3) # 3 * 3의 요소들이 0 ~ 1의 랜덤 값으로 초기화된 행렬 생성
randn_tensor = torch.randn(3, 3, dtype=torch.double) # 3 * 3의 요소들이 정규분포 그래프 값으로 초기화된 행렬 생성
zero_tensor = torch.zeros(3, 3, dtype=torch.long) # 3 * 3의 요소들이 0으로 초기화된 행렬 생성
one_tensor = torch.ones(3, 3, dtype=torch.double) # 3 * 3의 요소들이 1으로 초기화된 행렬 생성
iterable_tensor = torch.tensor([1, 2, 3]) # list 객체를 Tensor 객체로 변환
zeros_like_tensor = torch.zeros_like(iterable_tensor, dtype=torch.double) # iterable_tensor와 사이즈가 같은, 요소들이 0으로 초기화된 행렬 생성
ones_like_tensor = torch.ones_like(iterable_tensor, dtype=torch.double) # iterable_tensor와 사이즈가 같은, 요소들이 1으로 초기화된 행렬 생성
randn_like_tensor = torch.randn_like(iterable_tensor, dtype=torch.double) # iterable_tensor와 사이즈가 같은, 요소들이 정규분포 그래프 값으로 초기화된 행렬 생성
print('1: ' , empty_tensor)
print('2: ', rand_tensor)
print('3: ', randn_tensor)
print('4: ', zero_tensor)
print('5: ', one_tensor)
print('6: ', iterable_tensor)
print('7: ', zeros_like_tensor)
print('8: ', ones_like_tensor)
print('9: ', randn_like_tensor)
1: tensor([[2.1707e-18, 7.0952e+22, 1.7748e+28],
[1.8176e+31, 7.2708e+31, 5.0778e+31],
[3.2608e-12, 1.7728e+28, 7.0367e+22]])
2: tensor([[0.2648, 0.6304, 0.1789],
[0.5173, 0.1238, 0.4457],
[0.8282, 0.7767, 0.2907]])
3: tensor([[ 0.8707, -0.7935, 1.2842],
[ 0.6186, -0.5729, 0.0480],
[-1.8895, -1.5841, 0.6177]], dtype=torch.float64)
4: tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
5: tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
6: tensor([1, 2, 3])
7: tensor([0., 0., 0.], dtype=torch.float64)
8: tensor([1., 1., 1.], dtype=torch.float64)
9: tensor([0.0225, 0.7263, 0.2575], dtype=torch.float64)
4) 텐서의 연산
덧셈
# 덧셈 1
a = torch.rand(4,2)
b = torch.rand(4,2)
print(a+b)
tensor([[1.0959, 0.9410],
[0.1206, 0.9975],
[1.1056, 1.2427],
[0.8267, 1.1264]])
# 덧셈 2
print(torch.add(a,b))
tensor([[1.0959, 0.9410],
[0.1206, 0.9975],
[1.1056, 1.2427],
[0.8267, 1.1264]])
# 덧셈 3
# 결과 텐서를 인자로 제공
result = torch.empty(4,2)
torch.add(a,b, out = result)
print(result)
tensor([[1.0959, 0.9410],
[0.1206, 0.9975],
[1.1056, 1.2427],
[0.8267, 1.1264]])
# 덧셈 4
# in-place 방식
# - in-place방식으로 텐서의 값을 변경하는 연산 뒤에는 _''가 붙음
# - `x.copy_(y), x.t_()`
print(a)
print(b)
print('-----------------------------------')
b.add_(a)
print(b)
tensor([[0.5433, 0.2835],
[0.0649, 0.0631],
[0.5512, 0.6149],
[0.3727, 0.4714]])
tensor([[0.5527, 0.6575],
[0.0556, 0.9343],
[0.5544, 0.6278],
[0.4540, 0.6549]])
-----------------------------------
tensor([[1.0959, 0.9410],
[0.1206, 0.9975],
[1.1056, 1.2427],
[0.8267, 1.1264]])
그 외의 연산
torch.sub
: 뺄셈torch.mul
: 곱셈 ## Element-Wisetorch.div
: 나눗셈 ## Element-Wisetorch.mm
: 내적(dot product), 행렬곱torch.matmul
: 행렬곱
# 같은 크기를 가진 두 갸의 텐서에 대하여 사칙연산 가능
# 기본적으로 요소별(element-wise) 연산
a = torch.tensor([
[1,2],
[3,4]
])
b = torch.tensor([
[5,6],
[7,8]
])
print(a+b)
print(a-b)
print(a*b)
print(a/b)
tensor([[ 6, 8],
[10, 12]])
tensor([[-4, -4],
[-4, -4]])
tensor([[ 5, 12],
[21, 32]])
tensor([[0.2000, 0.3333],
[0.4286, 0.5000]])
행렬 곱(matrix multiplicatio) 수행
a = torch.tensor([
[1,2],
[3,4],
])
b = torch.tensor([
[5,6],
[7,8]
])
print(a.matmul(b))
print(torch.matmul(a,b))
tensor([[19, 22],
[43, 50]])
tensor([[19, 22],
[43, 50]])
텐서의 평균 함수
텐서의 요소들의 평균을 계산
a = torch.Tensor([ # torch.tensor와 torch.Tensor는 다르다.
[1,2,3,4], # torch.tensor: (Python function, in torch.tensor) 즉 이거는 그냥 함수
[5,6,7,8] # torch.Tensor: (Python class, in torch.tensor) 즉 이거는 클래스임
])
print(a)
print(a.mean()) # 전체 원소에 대한 평균
print(a.mean(dim = 0)) # 각 열에 대하여 평균
print(a.mean(dim = 1)) # 각 행에 대하여 평균
tensor([[1., 2., 3., 4.],
[5., 6., 7., 8.]])
tensor(4.5000)
tensor([3., 4., 5., 6.])
tensor([2.5000, 6.5000])
텐서의 합계 함수
요소들의 합을 계산
a = torch.Tensor([
[1,2,3,4,],
[5,6,7,8]
])
print(a)
print(a.sum()) # 전체 원소에 대한 합계
print(a.sum(dim = 0)) # 각 열에 대하여 합계 계산
print(a.sum(dim = 1)) # 각 행에 대하여 합계 계산
tensor([[1., 2., 3., 4.],
[5., 6., 7., 8.]])
tensor(36.)
tensor([ 6., 8., 10., 12.])
tensor([10., 26.])
텐서의 최대 함수
max() 함수는 원소의 최댓값을 반환한다.
argmax() 함수는 가장 큰 원소(최댓값)의 인덱스를 반환한다.
a = torch.Tensor([
[1,2,3,4],
[5,6,7,8]
])
print(a)
print(a.max()) # 전체 원소에 대한 최댓값
print(a.max(dim = 0)) # 각 열에 대하여 최댓값 계산
print(a.max(dim = 1)) # 각 행에 대하여 최댓값 계산
print()
print(a.argmax()) # 전체 원소에 대한 최댓값의 인덱스
print(a.argmax(dim = 0)) # 각 열에 대하여 최댓값의 인덱스
print(a.argmax(dim = 1)) # 각 행에 대하여 최댓값의 인덱스
tensor([[1., 2., 3., 4.],
[5., 6., 7., 8.]])
tensor(8.)
torch.return_types.max(
values=tensor([5., 6., 7., 8.]),
indices=tensor([1, 1, 1, 1]))
torch.return_types.max(
values=tensor([4., 8.]),
indices=tensor([3, 3]))
tensor(7)
tensor([1, 1, 1, 1])
tensor([3, 3])
Reference
Youtube-파이토치 기초(이수안 컴퓨터 연구소)
패스트 캠퍼스
댓글 남기기