1. 강의 내용
torch.nn.Module
- 딥러닝을 구성하는 layer의 base class
- input,output,Forward,Backward 정의
- 학습의 대상이 되는 parameter(tensor) 정의
nn.Parameter
- Tensor 객체의 상속 객체
- nn.Module 내에 attribute가 될 때는 required_grad = True로 지정되어 학습 대상이 되는 Tensor
Backward
- Layer에 있는 Parameter들의 미분 수행
- Forward의 결과값(model의 output=예측치)과 실제값 간의 차이(loss)에 대해 미분 수행
- 해당 값으로 parameter 업데이트
Datasets & DataLoaders
Dataset 클래스
- 데이터 입력 형태를 정의하는 클래스
- Image, Text,Audio 등에 따른 다른 입력 정의
- 데이터셋에 대한 표준화된 처리방법 제공
- 최근 HuggingFace 등 표준화된 라이브러리 사용
DataLoader 클래스
- Data의 Batch를 생성해주는 클래스
- 학습직전 데이터의 변환을 책임
- Tensor로 변환 + Batch 처리
2. 필수과제 1번 Custom Model 제작
torch.Tensor
- 클래스
- int 입력시 float로 변환
- torch 데이터 입력시 입력받은 데이터의 메모리 공간 사용 (원래 데이터 바꾸면 새로운 데이터도 바뀜)
- list, numpy 데이터 입력 시 복사하여 새롭게 torch.Tensor 만든 후 사용
torch.tensor
- 함수
- int 입력시 그대로 int
- 입력 받은 데이터를 새로운 메모리 공간으로 복사 후 사용 (원래 데이터 바꿔도 영향 없음)
사칙연산
- torch.add
- torch.sub
- torch.mul
- torch.div
인덱싱
- torch.index_select(input, dim, index)
import torch
A = torch.Tensor([[1,2],[3,4]])
# 1,3 뽑기
#1
torch.index_select(A,1,torch.tensor([0])).view(-1)
#2
A[:,0]
#torch.Tensor([1, 3])
2D tensor에서 대각선 요소 가져오기
- torch.gather(input,dim,index)
import torch
A = torch.tensor([[1,2],[3,4]])
torch.gather(A,1,torch.tensor([[0],[1]])).view(-1)
3D tensor에서 대각선 요소 가져오기
import torch
A = torch.tensor([[[1,2],[3,4]],[[5,6],[7,8]]])
torch.gather(A,2,torch.tensor([[[0],[1]],[[0],[1]]])).view(2,2)
#torch.Tensor([[1, 4], [5, 8]])
임의의 크기 3D tensor에서 대각선 요소 모으기
import torch
def get_diag_element(A):
C,H,W = A.size()
diag_size = min(H,W) # 대각선은 둘 중 짧은 길이 만큼만 가능
# diag_size 만큼 행별로 하나씩 -> C 수만큼
gather_index = torch.arange(diag_size).view(diag_size,-1).expand(C,diag_size,1)
output = torch.gather(A,2,gather_index)
output = output.view(C,diag_size)
return output
Tensors - Creation Ops
- torch.from_numpy : numpy array 를 tensor로
- torch.zeros : 지정한 크기만큼 0으로 채운 tensor
- torch.zeros_like : 같은 크기의 tensor 0으로 채우기
Tensors - Indexing, Slicing, Joining, Mutating Ops
- torch.chunk(input,chunks,dim)
- torch.swapdims(input,dim0,dim1) (torch.transpose())
- torch.Tensor.scatter_(dim,index,src,reduce=None)
src의 숫자들을 index에 scatter
Random Sampling
- torch.randn(size)
- torch.randperm(n)
random permutation of integers from 0 to n - 1.
- torch.poisson(input,generator=None)
Returns a tensor of the same size as input with each element sampled from a Poisson distribution with rate parameter given by the corresponding element in input
Math Operations - Pointwise Ops
- torch.log1p(input)
natural logarithm of (1 + input)
- torch.rad2deg(input)
converted from angles in radians to degrees.
- torch.clamp(input,min,max)
Clamps all elements in input into the range [ min, max ]
Math Operations - Reduction Ops
- torch.prod(input)
product of all elements
- torch.count_nonzero(input,dim=None)
>>> x = torch.zeros(3,3)
>>> x[torch.randn(3,3) > 0.5] = 1
>>> x
tensor([[0., 1., 1.],
[0., 0., 0.],
[0., 0., 1.]])
>>> torch.count_nonzero(x)
tensor(3)
>>> torch.count_nonzero(x, dim=0)
tensor([0, 1, 2]) # 순서 상관없이 dim 별로 count nonzero
- torch.argmax(input)
max값의 index
>>> a = torch.randn(4, 4)
>>> a
tensor([[ 1.3398, 0.2663, -0.2686, 0.2450],
[-0.7401, -0.8805, -0.3402, -1.1936],
[ 0.4907, -1.3948, -1.0691, -0.3132],
[-1.6092, 0.5419, -0.2993, 0.3195]])
>>> torch.argmax(a)
tensor(0)
>>> a = torch.randn(4, 4)
>>> a
tensor([[-0.8995, 1.0854, -1.3916, -0.2326],
[ 1.5765, -1.6868, -0.6414, 0.6763],
[ 1.6658, 0.4947, 0.9403, 1.5973],
[ 0.5412, 0.4130, 0.1965, -0.8740]])
>>> torch.argmax(a)
tensor(8) # 순서대로 index 부여해서 가장 큰 숫자의 index 리턴
>>> a = torch.randn(4, 4)
>>> a
tensor([[ 1.3398, 0.2663, -0.2686, 0.2450],
[-0.7401, -0.8805, -0.3402, -1.1936],
[ 0.4907, -1.3948, -1.0691, -0.3132],
[-1.6092, 0.5419, -0.2993, 0.3195]])
>>> torch.argmax(a, dim=1)
tensor([ 0, 2, 0, 1])
Math Operations - Comparison Ops
- torch.allclose(input,other,atol,rtol,equal_nan)
- input (Tensor) – first tensor to compare
- other (Tensor) – second tensor to compare
- atol (float, optional) – absolute tolerance. Default: 1e-08
- rtol (float, optional) – relative tolerance. Default: 1e-05
- equal_nan (bool, optional) – if True, then two NaN s will be considered equal. Default: False
>>> torch.allclose(torch.tensor([10000., 1e-07]), torch.tensor([10000.1, 1e-08]))
False
>>> torch.allclose(torch.tensor([10000., 1e-08]), torch.tensor([10000.1, 1e-09]))
True
>>> torch.allclose(torch.tensor([1.0, float('nan')]), torch.tensor([1.0, float('nan')]))
False
>>> torch.allclose(torch.tensor([1.0, float('nan')]), torch.tensor([1.0, float('nan')]), equal_nan=True)
True
- torch.argsort(input,dim=-1,descending=False)
>>> a = torch.randn(4, 4)
>>> a
tensor([[ 0.0785, 1.5267, -0.8521, 0.4065],
[ 0.1598, 0.0788, -0.0745, -1.2700],
[ 1.2208, 1.0722, -0.7064, 1.2564],
[ 0.0669, -0.2318, -0.8229, -0.9280]])
>>> torch.argsort(a, dim=1)
tensor([[2, 0, 3, 1],
[3, 2, 1, 0],
[2, 1, 0, 3],
[3, 2, 1, 0]])
- torch.topk(input,k,dim=None,largest=True,sorted=True)
- input (Tensor) – the input tensor.
- k (int) – the k in “top-k”
- dim (int, optional) – the dimension to sort along
- largest (bool, optional) – controls whether to return largest or smallest elements
- sorted (bool, optional) – controls whether to return the elements in sorted order
>>> x = torch.arange(1., 6.)
>>> x
tensor([ 1., 2., 3., 4., 5.])
>>> torch.topk(x, 3)
torch.return_types.topk(values=tensor([5., 4., 3.]), indices=tensor([4, 3, 2]))
Math Operations - other operations
- torch.triu(input, diagonal)
upper triangular part of a matrix
>>> b = torch.randn(4, 6)
>>> b
tensor([[ 0.5876, -0.0794, -1.8373, 0.6654, 0.2604, 1.5235],
[-0.2447, 0.9556, -1.2919, 1.3378, -0.1768, -1.0857],
[ 0.4333, 0.3146, 0.6576, -1.0432, 0.9348, -0.4410],
[-0.9888, 1.0679, -1.3337, -1.6556, 0.4798, 0.2830]])
>>> torch.triu(b, diagonal=1)
tensor([[ 0.0000, -0.0794, -1.8373, 0.6654, 0.2604, 1.5235],
[ 0.0000, 0.0000, -1.2919, 1.3378, -0.1768, -1.0857],
[ 0.0000, 0.0000, 0.0000, -1.0432, 0.9348, -0.4410],
[ 0.0000, 0.0000, 0.0000, 0.0000, 0.4798, 0.2830]])
>>> torch.triu(b, diagonal=-1)
tensor([[ 0.5876, -0.0794, -1.8373, 0.6654, 0.2604, 1.5235],
[-0.2447, 0.9556, -1.2919, 1.3378, -0.1768, -1.0857],
[ 0.0000, 0.3146, 0.6576, -1.0432, 0.9348, -0.4410],
[ 0.0000, 0.0000, -1.3337, -1.6556, 0.4798, 0.2830]])
- torch.einsum(equation,operands)
# batch matrix multiplication
>>> As = torch.randn(3,2,5)
>>> Bs = torch.randn(3,5,4)
>>> torch.einsum('bij,bjk->bik', As, Bs)
tensor([[[-1.0564, -1.5904, 3.2023, 3.1271],
[-1.6706, -0.8097, -0.8025, -2.1183]],
[[ 4.2239, 0.3107, -0.5756, -0.2354],
[-1.4558, -0.3460, 1.5087, -0.8530]],
[[ 2.8153, 1.8787, -4.3839, -1.2112],
[ 0.3728, -2.1131, 0.0921, 0.8305]]])
- torch.bucketsize(input,boundaries,right = False)
input의 원소들이 boundaries의 어떤 원소 사이에 있는지
boundaries는 단조 증가하는 시퀀스
right 가 False 이면 right에 ==
right이 True 이면 left에 ==
>>> boundaries = torch.tensor([1, 3, 5, 7, 9])
>>> boundaries
tensor([1, 3, 5, 7, 9])
>>> v = torch.tensor([[3, 6, 9], [3, 6, 9]])
>>> v
tensor([[3, 6, 9],
[3, 6, 9]])
>>> torch.bucketize(v, boundaries)
tensor([[1, 3, 4],
[1, 3, 4]])
>>> torch.bucketize(v, boundaries, right=True)
tensor([[2, 3, 5],
[2, 3, 5]])
Math Operations - BLAS and LAPACK Operations
BLAS : Basic Linear Algebra Subprograms
LAPACK : Linear Algebra PACKage
- torch.addmm(input,mat1,mat2)
input + mat1 * mat2
- torch.matrix_rank(input,tol,symmetric)
numerical rank of a 2-D tensor
>>> a = torch.eye(10)
>>> torch.matrix_rank(a)
tensor(10)
>>> b = torch.eye(10)
>>> b[0, 0] = 0
>>> torch.matrix_rank(b)
tensor(9)
- torch.qr(
Computes the QR decomposition of a matrix
QR 분해는 실수 행렬을 직교 행렬과 상삼각 행렬의 곱으로 나타내는 행렬 분해
>>> a = torch.tensor([[12., -51, 4], [6, 167, -68], [-4, 24, -41]])
>>> q, r = torch.qr(a)
>>> q
tensor([[-0.8571, 0.3943, 0.3314],
[-0.4286, -0.9029, -0.0343],
[ 0.2857, -0.1714, 0.9429]])
>>> r
tensor([[ -14.0000, -21.0000, 14.0000],
[ 0.0000, -175.0000, 70.0000],
[ 0.0000, 0.0000, -35.0000]])
>>> torch.mm(q, r).round()
tensor([[ 12., -51., 4.],
[ 6., 167., -68.],
[ -4., 24., -41.]])
>>> torch.mm(q.t(), q).round()
tensor([[ 1., 0., 0.],
[ 0., 1., -0.],
[ 0., -0., 1.]])
>>> a = torch.randn(3, 4, 5)
>>> q, r = torch.qr(a, some=False)
>>> torch.allclose(torch.matmul(q, r), a)
True
torch.nn (Linear Layers)
>>> m = nn.Linear(20, 30)
>>> input = torch.randn(128, 20)
>>> output = m(input)
>>> print(output.size())
torch.Size([128, 30])
torch.nn.Identity
>>> m = nn.Identity(54, unused_argument1=0.1, unused_argument2=False)
>>> input = torch.randn(128, 20)
>>> output = m(input)
>>> print(output.size())
torch.Size([128, 20])
torch.nn.LazyLinear
- 출력값만 지정
- 입력값의 크기는 첫 forward 진행할 때 자동으로 지정
입력값의 크기 변화에 맞추어 유연하게 대응
hook
- 프로그램의 실행 로직을 분석 및 추가 기능
- package를 사용할 때 custom 코드를 package 중간중간에 실행
- tensor에는 backward hook만
- nn.Module에 등록하는 모든 hook은 __dict__ 이용하여 한번에 확인 가능
- Module:
register_full_backward_hook
register_forward_pre_hook
register_forward_hook
- Tensor (backward만 가능)
register_hook
apply
- 구현되어 있는 모델에 custom 함수 적용할 때 사용
- 가중치 초기화,..등
import torch
from torch import nn
def init_weights(m):
if type(m) == nn.Linear:
m.weight.fill_(1.0)
print(m.weight)
net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
net.apply(init_weights)
맨 위 module에 적용하면 하위 module에 모두 적용
'Boostcamp AI Tech > [week 1-5] LEVEL 1' 카테고리의 다른 글
[Week 3 - Day 4 ] Pytorch (0) | 2021.08.20 |
---|---|
[Week 3 - Day 3 ] Pytorch (0) | 2021.08.20 |
[Week 3 - Day 1] Pytorch (0) | 2021.08.17 |
[Week 2 - Day 5] DL Basic - Generative Models (0) | 2021.08.13 |
[Week 3 - Day 4] DL Basic - RNN, Transformer (0) | 2021.08.12 |