--24.PyTorch 사용.ipynb--
import numpy as np
import torch
torch.version
https://pytorch.org/docs/stable/torch.html#tensors
np.arange(9)
tensor = torch.arange(9)
tensor
type(tensor) # torch.Tensor객체
tensor.shape
tensor.numpy()
tensor.reshape(3,3)
randoms = torch.rand((3,3)) # [0,1) 범위의 난수를 (3,3) 크기로 생성
randoms
randoms.dtype
zeros = torch.zeros((3,3))
zeros
zeros.shape
zeros.size() # <- numpy와 다른 결과!!
ones = torch.ones((3,3))
ones
torch.zeros_like(ones) # input가 동일한 shape를 가진 zeros를 만듬.
tensor
tensor * 3 # broadcast도 가능!
tensor = tensor.reshape((3,3))
tensor
tensor + tensor
torch.add(tensor, 10)
https://pytorch.org/docs/stable/tensor_view.html#tensor-views
range_nums = torch.arange(9).reshape(3, 3)
range_nums
range_nums.view(-1) # -1 은 차원 추론, (3,3) => (9,)
range_nums.view(-1, 9)
tensor
tensor[1]
tensor[1, 1]
tensor[1:]
tensor[1:, 1:]
PyTorch에서 특정 디바이스에 '컴파일'된다는 것은 모델이 실행될 디바이스(CPU 또는 GPU)에 최적화된 코드를 생성하여, 해당 디바이스의 자원을 효율적으로 활용하고, 전체 연산 성능을 향상시키는 것을 의미.
이 개념은 주로 PyTorch의 torch.compile 기능과 관련이 있다. PyTorch의 torch.compile은 JIT(Just-In-Time) 컴파일러를 사용하여 모델을 실행 시점에 최적화합니다
arr = np.array([1, 1, 1])
arr
arr_torch = torch.from_numpy(arr)
arr_torch
arr_torch.dtype
torch.cuda.is_available()
device = 'cuda' if torch.cuda.is_available() else 'cpu'
device
arr_torch.to(device)
'기울기'를 주어 학습이 되게 하는 것
x = torch.ones(2,2, requires_grad=True) # 기울기 계산 해야한다고 컴퓨터에게 알려주는것.
x
x.grad # 학습기울기, 처음에는 없다.
x = torch.tensor(2.0, requires_grad=True)
x
x.grad
y = x ** 2
y.backward()
x.grad
y.grad_fn # funtion 확인 가능
x.requires_grad
(x ** 2).requires_grad
with torch.no_grad() :
print((x ** 2).requires_grad)
# no_grad() 이면 기울기를 구하지 않게 됩니다.
# 따라서 batch, normalization dropout 들이 작동 안함
# 작동 속도는 train mode 일때보다 test mode 가 더 빠르겠죠.
from torchvision import datasets, transforms
PyTorch는 DataLoader()를 사용하여 model에 입력
batch_size = 32
test_batch_size = 32
base_path = r'./'
train_loader = torch.utils.data.DataLoader(
# MNIST 예제 데이터
dataset = datasets.MNIST(
base_path, # 저장할 디렉토리
train = True, # 학습용
download = True, # 없으면 다운로드!
transform = transforms.Compose([ # 데이터 로딩시 필요한 변환 (transform) 나열.
transforms.ToTensor(), # 데이터 다운 받은 뒤 Tensor로 받아옴.
transforms.Normalize(mean = (0.5,), std = (0.5,)), # Nomalize(mean,std)
# 평균 0.5, 표준편차 0.5로 스케일링하여 로딩
# channel 이 한개라서 1개값만 명시. (RGB 처럼 3개의 채널이면 다름.)
])
),
batch_size = batch_size,
shuffle = True,
)
import os
os.listdir(base_path)
test_loader = torch.utils.data.DataLoader(
dataset = datasets.MNIST(
base_path,
train = False, # 학습모드로 사용하는 데이터가 아니니까 False
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)) # test 데이터로 train과 마찬가지로 스케일링
]),
),
batch_size = test_batch_size,
shuffle = True,
)
DataLoader 에서는 batch 단위로 뽑혀져 나온다
type(train_loader) # DataLoader 객체 <= iterable 하다.(for문을 돌릴 수 있다.)
images, labels = next(iter(train_loader)) # 첫번째 batch 추출
images.shape, labels.shape
images[0].shape
torch_image = torch.squeeze(images[0])
torch_image.shape
image = torch_image.numpy()
image.shape
label = labels[0].numpy()
print(label)
label.shape
np.min(image), np.max(image)
import matplotlib.pyplot as plt
plt.title(label)
plt.imshow(image, 'gray')
plt.show()
train_loader = torch.utils.data.DataLoader(
# MNIST 예제 데이터
dataset = datasets.MNIST(
base_path,
train = True,
download = True,
transform = transforms.Compose([
transforms.ToTensor(),
# 직전 예제에서는 normalize 했지만, 이번 예제에서는 '모델학습'이 목적이 아니라 생략.
])
),
batch_size = 1, # 이번 단원의 목적이 이미지 '하나하나'를 Layer에 넣어서 확인 해보기 위함.
# shuffle도 안함.
)
image, label = next(iter(train_loader))
image.shape, label.shape
plt.imshow(image[0, 0, :, :], 'gray')
plt.title(label[0])
plt.show()
import torch.nn as nn # nn 레이어
import torch.nn.functional as F # F 레이어
device
https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html?highlight=conv2d#torch.nn.Conv2d
nn.Conv2d(in_channels = 1, out_channels = 20, kernel_size = 5, stride = 1)
layer_conv1 = nn.Conv2d(1, 20, 5, 1).to(torch.device(device))
layer_conv1
weight = layer_conv1.weight
weight.shape
weight
weight = weight.detach().numpy()
weight
weight.shape
plt.imshow(weight[0, 0, :, :])
plt.colorbar()
plt.show()
output_data = layer_conv1(image) # image를 layer에 통과시켜 본다.
output_data.shape
output_data # (Tensor 객체, grad_fn) <- 튜플
output_data.data # 위에서 데이터만 추출
output_data = output_data.data
output_data.data.numpy() # output_data 자체는 튜플 객체임. 그래서 .data 붙혀서 Tensor객체만 남김
output = output_data.cpu().numpy()
output
image_arr = image.numpy()
image_arr.shape
plt.figure(figsize=(15,30))
plt.subplot(131)
plt.title("Input")
plt.imshow(np.squeeze(image_arr), 'gray')
plt.subplot(132)
plt.title('Weight')
plt.imshow(weight[0, 0, :, :])
plt.subplot(133)
plt.title('Output')
plt.imshow(output[0, 0, :, :], 'gray')
plt.show()
image.shape
pool = F.max_pool2d(input=image, kernel_size=2, stride=2)
pool.shape
pool_arr = pool.numpy()
pool_arr
plt.figure(figsize=(10, 15))
plt.subplot(121)
plt.title("Input")
plt.imshow(np.squeeze(image), 'gray')
plt.subplot(122)
plt.title('Output')
plt.imshow(np.squeeze(pool_arr), 'gray')
plt.show()
image.shape
flatten = image.view(1, 28 * 28) # batch size는 유지해주어야 한다.
flatten.shape
lin = nn.Linear(in_features=784, out_features=10)(flatten)
lin.shape
lin
lin.detach().numpy()
plt.imshow(lin.detach().numpy(), 'jet')
plt.show()
lin.shape
with torch.no_grad() :
flatten = image.view(1, 28 * 28)
lin = nn.Linear(784, 10)(flatten)
softmax = F.softmax(lin, dim = 1) # lin이 (1, 10)이기 때문에 뒤에 있는 차원을 softmax 해야한다. (dim = 1)
softmax
np.sum(softmax.numpy())
np.argmax(softmax)