본문 바로가기
딥러닝(Deep Learning)/D&A Deep Session

[D&A Deep Session] 1차시 - 2. Class & Tensor

by rahites 2022. 3. 14.

 

1. 클래스

: 똑같은 무언가를 만들어내는 설계 도면

 

객체 : 클래스로 만든 피조물로 객체마다 고유한 성격을 지닌다

 

인스턴스 : 클래스가 지시한대로 만든 값, 특정 객체가 어떤 클래스의 객체인지 관계 위주로 설명할 때 사용한다

 

메소드 : 클래스 안에 구현된 함수로 메소드의 첫 번째 매개변수(parameter)에는 호출한 객체가 자동으로 전달된다

 

객체 변수 : 객체에 생성되는 객체만의 변수를 의미하며 다른 객체들의 영향을 받지 않는다

 

생성자 : 객체가 생성되는 시점에 자동으로 호출되는 메소드를 의미한다, __init__이라고 설정하면 생성자로 인식한다

 

* 상속

: 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있게 만드는 것 ( class 클래스명(부모클래스) 로 생성 )

 

- super() : 부모 클래스의 속성 및 메소드를 자동으로 불러와 해당 클래스에서도 사용 가능하게 해주는 함수, 자식 클래스를 만들 때 super().__init__()을 입력하지 않으면 자식 클래스의 .__init__()에 의해 덮어쓰기 된다.

 

 

2. 텐서 ( Tensor )

: 데이터를 표현하는 단위로 numpy의 배열과 비슷한 다차원 배열을 의미한다.

 

스칼라 ( Scalar ) : 하나의 값을 표현할 때 1개의 수치로 표현 ( 상숫값 )

벡터 ( Vector ) : 하나의 값을 표현할 때 2개 이상의 수치로 표현 ( 1차원 )

행렬 ( Matrix ) : 2개 이상의 벡터 값을 통합해 구성된 값 ( 2차원 ) 

텐서 ( Tensor ) : 3차원 이상의 배열

 

* torch.tensor 명령을 통해 tensor를 생성할 수 있다. 또한 tensor끼리의 사칙연산도 수행할 수 있다.

# 스칼라 ( Scalar )
torch.tensor([1.])

# 벡터 ( Vector )
torch.tensor([1., 2., 3.]) 
# 벡터는 내적 연산또한 가능하다
torch.dot(vector1, vector2) # 행렬곱
torch.matmul(vector1, vector2) # matmul은 @로도 표현 가능
'''
1. matmul은 스칼라와 배열의 곱에서 오류 발생 ( 이때는 *를 사용해야함 )
2. dot, matmul은 3차원 이상의 다차원 배열에서 연산을 수행하는 방식이 다르다
   dot(a,b)는 a의 마지막 axis와 b의 마지막에서 두번째 axis 차원이 일치해야 dot이 가능하다.
   matmul(a,b)는 a의 마지막 두 axis 차원이 (n,k), b의 마지막 두 axis 차원이 (k, m)일 때,
   이 사이에서만 곱하여 (n, m) 차원이 되도록 반영한다.
'''

# 행렬 ( Matrix ) - 2개 이상의 벡터로 구성된 값
torch.tensor([[1., 2.], [3., 4.]])
# 행렬곱 연산은 matmul, mm을 사용한다
# mm은 matrix multiplication으로, [n, m] x [m,p] = [n,p] 를 구현

# 텐서 ( Tensor ) - 2차원 이상의 배열
torch.tensor([[[1., 2.], [3., 4.]], [[5., 6.], [7., 8.]]])
# matmul로 텐서곱 연산이 가능하다

 

# tensor의 종류                  

  CPU 텐서 GPU 텐서
32비트 부동 소수점  torch.FloatTensor torch.cuda.FloatTensor
64비트 부동 소수점 torch.DoubleTensor  torch.cuda.DoubleTensor
8비트 정수 ( 부호 없음 ) torch.ByteTensor torch.cuda.ByteTensor
8비트 정수 ( 부호 있음 ) torch.CharTensor torch.cuda.CharTensor
16비트 정수 ( 부호 있음 ) torch.ShortTensor torch.cuda.ShortTensor
32비트 정수 ( 부호 있음 ) torch.IntTensor torch.cuda.IntTensor
64비트 정수 ( 부호 있음 ) torch.LongTensor torch.cuda.LongTensor

 

# Pytorch - tensor 메소드

 

tensor.dim() : rank ( 차원 )

tensor.shape : 사이즈

tensor.size : 사이즈

tensor[숫자] : 인덱싱 ( 리스트와 같음 )

tensor[숫자:숫자] : 슬라이싱 ( 슬라이싱한 것만으로도 .shape가 가능하다 )

 

* Broadcasting

: tensor끼리 사칙연산을 수행할 때 더 작은 tensor를 큰 tensor의 크기에 맞춰 확장함 ( ex. 3 -> [[3,3]] )

 

tensor.mean() : tensor 원소들의 평균

tensor.mean(dim = 0) : dim=0이라는 것은 첫번째 차원을 의미하고 ( 행을 의미 ) 여기서 dim 인자를 주면 해당 차원을 제거하겠다는 의미이다. 즉, 열만 남기겠다는 의미이다.

t = torch.FloatTensor([1, 2])
print(t.mean())
# 1.5

t = torch.FloatTensor([[1, 2], [3, 4]])
print(t.mean())
# 2.5

print(t.mean(dim=0)) # 행의 차원을 제거 ( 기존 (2,2) -> (1,2)로 1,3의 평균, 2,4의 평균 )
# [2., 3.]

print(t.mean(dim=1)) # 열의 차원을 제거 ( 기존 (2,2) -> (2, 1)로 1,2의 평균, 3,4의 평균 )
# [1.5000, 3.5000]

# dim=-1은 마지막 차원을 제거한다는 의미로, 결국 열의 차원을 제거한다는 의미이다.
print(t.mean(dim=-1))
# [1.5000, 3.5000]

 

tensor.sum() : tensor의 합, 이 또한 dim을 주어 위와같이 계산할 수 있다.

 

tensor.max() : max 1개의 값 반환-> dim인자를 주면 argmax도 함께 반환한다.

# dim=0, 첫번째 차원을 제거한다는 의미
print(t.max(dim=0)) # (2,2) 행렬 -> (1,2) 행렬
# tensor([3., 4.]), tensor([1, 1])) -> (1,2) 행렬의 각각의 열의 최댓값, 최댓값 각각의 인덱스

 

tensor.argmax() : max값의 index 반환

 

tensor.view() : numpy의 reshape와 같은 역할로 원하는 크기로 shape를 바꿔준다

  • view는 기본적으로 변경 전과 변경 후의 텐서 안의 원소의 개수가 유지되어야 한다
  • Pytorch의 view는 사이즈가 -1로 설정되면 다른 차원으로부터 해당 값을 유추한다

tensor.squeeze() : 1차원으로 바꿔준다.

 

tensor.unsqueeze() : squeeze를 반대로 실행하여 ()안의 숫자에 맞는 차원을 추가한다 ( 0이면 첫번째 차원을 추가 ), view(1, -1)을 해주면 unsqueeze(0)을 한 것과 같은 효과를 낼 수 있다.

 

tensor.scatter_(dim, index, src) : dim은 인덱싱의 기준이 되는 축, index는 src 요소들이 흩어질 기준이 되는 인덱스 텐서, src는 텐서를 구성할 값을 의미한다 이 때 src가 하나의 실수이면 그 값으로만 채워진다.

 

tensor.float(), .long()... : Casting이라고 부르며 tensor의 type을 변환한다.

 

torch.cat(tensor1, tensor2) : Concatenation, 두 텐서를 연결한다, dim=숫자에 따른 차원을 늘린다. 

dim = 0 -> (2,2) 텐서 2개를 cat시 (4,2) # 아래로 붙임

dim = 1 -> (2,2) 텐서 2개를 cat시 (2,4) # 옆으로 붙임

 

torch.stack(tensor1, tensor2, tensor3) : Concatenate를 편리하게 이용하게 해준다. 생략시 dim = 0

print(torch.stack([x, y, z])) # 아래로 쌓기
print(torch.stack([x, y, z], dim=1)) # 옆으로 붙이기
# 같은 결과
print(torch.cat([x.unsqueeze(0), y.unsqueeze(0), z.unsqueeze(0)], dim=0))
print(torch.cat([x.unsqueeze(1), y.unsqueeze(1), z.unsqueeze(1)], dim=1))

torch.ones_like(x) : x와 똑같은 shape로 1텐서

torch.zeros_like(x) : x와 똑같은 shape로 0텐서

 

* 덮어쓰기 연산 ( in-place Operation )

tensor연산에서 연산 뒤에 _를 붙이면 실행 결과를 메모리에 새로 선언하지 않고 기존의 값을 덮어쓰기 한다.

ex) x.mul_(2.)를 하면 기존 x텐서에 2를 곱한 값이 x에 저장된다

 

 

 

 

< 참고자료 >

https://wikidocs.net/52846

 

03. 텐서 조작하기(Tensor Manipulation) 2

이어서 텐서를 조작하는 방법을 알아보겠습니다. ####4) 뷰(View) - 원소의 수를 유지하면서 텐서의 크기 변경. 매우 중요함!! 파이토치 텐서의 뷰(View)는 넘 ...

wikidocs.net

 

댓글