💡 colab 에서 실습을 진행
from __future__ import print_function
import torch
torch.__version__
'1.7.1+cpu'
python 기반의 과학 연산 패키지
다음과 같은 경우에 사용
Torch 에서는 tensor
타입을 사용
📌 tensor
: numpy의 ndarray와 유사하며, 추가로 GPU를 사용한 연산 가속도 가능
초기화되지 않은 행렬 생성
torch.empty()
무작위로 초기화된 행렬 생성
torch.randn()
: 표준정규분포에서 값을 샘플링torch.rand()
: 0~1 사이의 값을 샘플링0 또는 1로 채워진 행렬 생성 (dtype=torch.float32)
torch.zeros()
: 0 으로 채워진 행렬 생성torch.ones()
: 1 로 채워진 행렬 생성데이터로부터 직접 tensor 생성
torch.tensor(data)
x = torch.tensor([5.5, 3])
print(x)
tensor([5.5000, 3.0000])
존재하는 tensor를 바탕으로 tensor 생성. 사용자로부터 제공된 새로운 값이 없으면 입력 tensor의 속성(예: dtype)을 재사용
x.new_ones()
torch.randn_like(x)
x = x.new_ones(5, 3, dtype=torch.double)
print(x)
x = torch.randn_like(x, dtype=torch.float)
print(x)
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[-2.0476, 1.1892, -0.9870],
[-0.4139, 0.3040, 0.5669],
[ 0.8405, -0.7245, -1.6147],
[ 0.4094, -0.7145, -1.6480],
[-1.4789, 2.0897, 1.9627]])
행렬의 크기
x.size()
or x.shape
print(x.size())
print(x.shape)
torch.Size([5, 3])
torch.Size([5, 3])
덧셈: 문법1 x + y
y = torch.rand(5, 3)
print(x)
print(y)
print(x + y)
tensor([[-0.8039, -0.0473, -0.2606],
[-0.6666, -0.2164, 1.5497],
[-0.0673, -0.6175, 1.4867],
[ 1.8226, -0.9508, 2.0158],
[ 1.1701, -1.5394, -0.1466]])
tensor([[0.5261, 0.0257, 0.2226],
[0.0479, 0.8267, 0.1479],
[0.4942, 0.8873, 0.1607],
[0.3858, 0.2859, 0.7855],
[0.3595, 0.9427, 0.4000]])
tensor([[-0.2778, -0.0216, -0.0379],
[-0.6187, 0.6103, 1.6975],
[ 0.4269, 0.2698, 1.6474],
[ 2.2084, -0.6649, 2.8013],
[ 1.5296, -0.5966, 0.2534]])
덧셈: 문법2 torch.add(x, y)
print(torch.add(x, y))
tensor([[-0.2778, -0.0216, -0.0379],
[-0.6187, 0.6103, 1.6975],
[ 0.4269, 0.2698, 1.6474],
[ 2.2084, -0.6649, 2.8013],
[ 1.5296, -0.5966, 0.2534]])
결과를 담을 tensor를 인자로 제공
result = torch.empty(5, 3)
print(result)
torch.add(x, y, out=result)
print(result)
tensor([[ 3.2141e-36, 0.0000e+00, 1.5975e-43],
[ 1.3873e-43, 1.4574e-43, 6.4460e-44],
[ 1.4153e-43, 1.5274e-43, 1.5695e-43],
[ 1.6255e-43, 1.6956e-43, 2.8013e+00],
[ 1.5296e+00, -5.9664e-01, 2.5340e-01]])
tensor([[-0.2778, -0.0216, -0.0379],
[-0.6187, 0.6103, 1.6975],
[ 0.4269, 0.2698, 1.6474],
[ 2.2084, -0.6649, 2.8013],
[ 1.5296, -0.5966, 0.2534]])
덧셈: 바꿔치기(In-place) 방식 y.add_(x)
# adds x to y
print(y)
y.add_(x)
print(y)
tensor([[0.5261, 0.0257, 0.2226],
[0.0479, 0.8267, 0.1479],
[0.4942, 0.8873, 0.1607],
[0.3858, 0.2859, 0.7855],
[0.3595, 0.9427, 0.4000]])
tensor([[-0.2778, -0.0216, -0.0379],
[-0.6187, 0.6103, 1.6975],
[ 0.4269, 0.2698, 1.6474],
[ 2.2084, -0.6649, 2.8013],
[ 1.5296, -0.5966, 0.2534]])
📌 바꿔치기(In-place) 방식으로 tensor의 값을 변경하는 연산은 '' 를 접미사로 갖는다. (예: x.copy(y), x.t_())
인덱싱 (Numpy와 동일)
print(x)
print(x[:, 1])
tensor([[-0.8039, -0.0473, -0.2606],
[-0.6666, -0.2164, 1.5497],
[-0.0673, -0.6175, 1.4867],
[ 1.8226, -0.9508, 2.0158],
[ 1.1701, -1.5394, -0.1466]])
tensor([-0.0473, -0.2164, -0.6175, -0.9508, -1.5394])
⭐ 크기변경 x.view()
-1 은 자동으로 계산하여 결정
x = torch.randn(4, 4)
print(x)
y = x.view(16)
z = y.view(-1, 2)
print(y)
print(z)
print(y.size(), z.size())
tensor([[ 1.5496, -0.3506, 1.2708, 0.3292],
[ 0.0165, 0.3230, -1.3762, -0.3285],
[ 1.2202, 1.2733, 0.6468, -1.5027],
[-0.0418, 0.6608, 0.4468, -0.0493]])
tensor([ 1.5496, -0.3506, 1.2708, 0.3292, 0.0165, 0.3230, -1.3762, -0.3285,
1.2202, 1.2733, 0.6468, -1.5027, -0.0418, 0.6608, 0.4468, -0.0493])
tensor([[ 1.5496, -0.3506],
[ 1.2708, 0.3292],
[ 0.0165, 0.3230],
[-1.3762, -0.3285],
[ 1.2202, 1.2733],
[ 0.6468, -1.5027],
[-0.0418, 0.6608],
[ 0.4468, -0.0493]])
torch.Size([16]) torch.Size([8, 2])
하나의 값만 존재할 경우 숫자 값 반환 x.item()
x = torch.randn(1)
print(x)
print(type(x), type(x.item()))
print(x.item())
tensor([1.1069])
<class 'torch.Tensor'> <class 'float'>
1.10688054561615
전치, 인덱싱, 슬라이싱, 수학계산, 선형대수, 난수 등과 같은
100가지 이상의 Tensor 연산은 🔗 에 설명되어 있다.
Torch의 Tensor를 Numpy 배열(array)로 변환하거나, 그 반대로 하는 것은 매우 쉽다.
CPU 상에서 Torch Tensor와 Numpy 배열은 ⭐저장 공간을 공유하기 때문에, 하나를 변경하면 다른 하나도 변경된다.
Torch Tensor를 Numpy 배열로 변환
a = torch.ones(5)
print(a)
tensor([1., 1., 1., 1., 1.])
b = a.numpy()
print(b)
[1. 1. 1. 1. 1.]
a.add_(1)
print(a)
print(b)
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]
개별로 선언 a.clone()
temp = a.clone()
temp_numpy = temp.numpy()
a.add_(1)
print(a)
print(temp_numpy)
tensor([3., 3., 3., 3., 3.])
[2. 2. 2. 2. 2.]
Numpy 배열을 Torch Tensor로 변환
import numpy as np
a = np.ones(5)
print(a)
[1. 1. 1. 1. 1.]
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
[2. 2. 2. 2. 2.]
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
💡 마찬가지로 Numpy(np) 배열을 변경하면 Torch Tensor의 값도 자동 변경된다!
Tensor를 다른 장치로 옮기기 x.to()
import torch
# 이 코드는 CUDA가 사용 가능한 환경에서만 실행합니다.
# ``torch.device`` 를 사용하여 tensor를 GPU 안팎으로 이동해보겠습니다.
x = torch.rand(4,4)
if torch.cuda.is_available():
device = "cuda:0" # torch.device("cuda:0") # CUDA 장치 객체(device object)로
y = torch.ones_like(x, device=device) # GPU 상에 직접적으로 tensor를 생성하거나
print(y)
x = x.to(device) # ``.to("cuda")`` 를 사용하면 됩니다.
z = x + y
print(z)
print(z.to("cpu", torch.double)) # ``.to`` 는 dtype도 함께 변경합니다!
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]], device='cuda:0')
tensor([[1.2859, 1.9080, 1.2066, 1.6184],
[1.7055, 1.7199, 1.2572, 1.0787],
[1.7547, 1.6160, 1.1335, 1.0379],
[1.0367, 1.5918, 1.3650, 1.8609]], device='cuda:0')
tensor([[1.2859, 1.9080, 1.2066, 1.6184],
[1.7055, 1.7199, 1.2572, 1.0787],
[1.7547, 1.6160, 1.1335, 1.0379],
[1.0367, 1.5918, 1.3650, 1.8609]], dtype=torch.float64)
Tensor를 다른 장치로 옮기기(간단하게) x.cuda()
x = x.cuda()
print(x)
tensor([[0.2859, 0.9080, 0.2066, 0.6184],
[0.7055, 0.7199, 0.2572, 0.0787],
[0.7547, 0.6160, 0.1335, 0.0379],
[0.0367, 0.5918, 0.3650, 0.8609]], device='cuda:0')
import tensorflow as tf
print(tf.__version__)
2.4.0
변수 생성 tf.Variable()
my_variable = tf.Variable(tf.zeros([1, 2, 3]))
my_variable
<tf.Variable 'Variable:0' shape=(1, 2, 3) dtype=float32, numpy=
array([[[0., 0., 0.],
[0., 0., 0.]]], dtype=float32)>
👉 모양이 [1, 2, 3]이고 값은 0으로 채워진 3차원 텐서가 변수로 생성
변수 사용
텐서플로 그래프에서 tf.Variable의 값을 사용하려면
이를 단순히 tf.Tensor로 취급하면 됨
v = tf.Variable(0.0)
print(v)
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>
w = v + 1 # w는 v값 기준으로 계산되는 tf.Tensor 입니다.
# 변수가 수식에 사용될 때, 변수는 자동적으로
# tf.Tensor로 변환되어 값을 표현합니다.
print(w)
tf.Tensor(1.0, shape=(), dtype=float32)
변수에 값 할당
값을 변수에 할당하려면 assign, assign_add 메소드와 tf.Variable 클래스에 있는 친구들(friends)을 사용
a = tf.Variable(0.0)
a.assign_add(1)
a.read_value() # 1.0
<tf.Tensor: shape=(), dtype=float32, numpy=1.0>
📌 tf.Tensor
객체의 랭크는 그 차원의 수
랭크 0 (스칼라)
mammal = tf.Variable("코끼리", tf.string)
ignition = tf.Variable(451, tf.int16)
floating = tf.Variable(3.14159265359, tf.float64)
its_complicated = tf.Variable(12.3 - 4.85j, tf.complex64)
print(mammal)
print(ignition)
print(floating)
print(its_complicated)
<tf.Variable 'Variable:0' shape=() dtype=string, numpy=b'\xec\xbd\x94\xeb\x81\xbc\xeb\xa6\xac'>
<tf.Variable 'Variable:0' shape=() dtype=int32, numpy=451>
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=3.1415927>
<tf.Variable 'Variable:0' shape=() dtype=complex128, numpy=(12.3-4.85j)>
랭크 1 (벡터)
mystr = tf.Variable(["안녕하세요"], tf.string)
cool_numbers = tf.Variable([3.14159, 2.71828], tf.float32)
first_primes = tf.Variable([2, 3, 5, 7, 11], tf.int32)
its_very_complicated = tf.Variable([12.3 - 4.85j, 7.5 - 6.23j], tf.complex64)
print(mystr)
print(cool_numbers)
print(first_primes)
print(its_very_complicated)
<tf.Variable 'Variable:0' shape=(1,) dtype=string, numpy=
array([b'\xec\x95\x88\xeb\x85\x95\xed\x95\x98\xec\x84\xb8\xec\x9a\x94'],
dtype=object)>
<tf.Variable 'Variable:0' shape=(2,) dtype=float32, numpy=array([3.14159, 2.71828], dtype=float32)>
<tf.Variable 'Variable:0' shape=(5,) dtype=int32, numpy=array([ 2, 3, 5, 7, 11], dtype=int32)>
<tf.Variable 'Variable:0' shape=(2,) dtype=complex128, numpy=array([12.3-4.85j, 7.5-6.23j])>
tf.rank(mystr)
<tf.Tensor: shape=(), dtype=int32, numpy=1>
랭크 2 (행렬)
mymat = tf.Variable([[7],[11]], tf.int16)
myxor = tf.Variable([[False, True],[True, False]], tf.bool)
linear_squares = tf.Variable([[4], [9], [16], [25]], tf.int32)
squarish_squares = tf.Variable([ [4, 9], [16, 25] ], tf.int32)
#tf.rank : 객체의 랭크 구하기
rank_of_squares = tf.rank(squarish_squares)
mymatC = tf.Variable([[7],[11]], tf.int32)
print(mymat)
print(rank_of_squares)
<tf.Variable 'Variable:0' shape=(2, 1) dtype=int32, numpy=
array([[ 7],
[11]], dtype=int32)>
tf.Tensor(2, shape=(), dtype=int32)
10개의 배치, 299개의 높이와 너비, 3개의 색상으로 생성
# 배치 x 높이 x 너비 x 색상
my_image = tf.zeros([10, 299, 299, 3])
# H*W = 299 * 299
tf.Tensor 객체의 랭크 구하기 tf.rank(x)
r = tf.rank(my_image)
print(r)
tf.Tensor(4, shape=(), dtype=int32)
tf.Tensor 원소 참조하기
my_vector = tf.Variable([1, 2, 3, 4], tf.int32)
print(tf.rank(my_vector))
my_scalar = my_vector[2]
print(my_scalar)
tf.Tensor(1, shape=(), dtype=int32)
tf.Tensor(3, shape=(), dtype=int32)
print(squarish_squares)
<tf.Variable 'Variable:0' shape=(2, 2) dtype=int32, numpy=
array([[ 4, 9],
[16, 25]], dtype=int32)>
my_scalar = squarish_squares[1, 0] # 2행 1열의 값
print(my_scalar)
tf.Tensor(16, shape=(), dtype=int32)
my_row_vector = squarish_squares[1]
print(my_row_vector)
tf.Tensor([16 25], shape=(2,), dtype=int32)
my_column_vector = squarish_squares[:, 1]
print(my_column_vector)
tf.Tensor([ 9 25], shape=(2,), dtype=int32)
tf.Tensor 객체 형태 얻기
zeros = tf.zeros(squarish_squares.shape) # squarish_squares.shape으로 새로운 텐서 생성
zeros
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[0., 0.],
[0., 0.]], dtype=float32)>
tf.Tensor 형태 변경
# 총 60개의 데이터 (3*4*5=60)
rank_three_tensor = tf.ones([3, 4, 5])
print(rank_three_tensor.shape)
print(rank_three_tensor)
print('=== matrix ===')
matrix = tf.reshape(rank_three_tensor, [6, 10]) # 기존 내용을 6x10 행렬로 형태 변경
print(matrix.shape)
print(matrix)
print('=== matrixB ===')
matrixB = tf.reshape(matrix, [3, -1]) # 기존 내용을 3x20 행렬로 형태 변경
print(matrixB.shape)
print(matrixB)
print('=== matrixAlt ===')
matrixAlt = tf.reshape(matrixB, [4, 3, -1]) # 기존 내용을 4x3x5 텐서로 형태 변경
print(matrixAlt.shape)
(3, 4, 5)
tf.Tensor(
[[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]], shape=(3, 4, 5), dtype=float32)
=== matrix ===
(6, 10)
tf.Tensor(
[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]], shape=(6, 10), dtype=float32)
=== matrixB ===
(3, 20)
tf.Tensor(
[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]], shape=(3, 20), dtype=float32)
=== matrixAlt ===
(4, 3, 5)
tf.Tensor(
[[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]], shape=(4, 3, 5), dtype=float32)