CS🏅/해체 분석기📝

[Einops] 차원관리의 새로운 차원

Dobby98 2023. 10. 17. 23:21

Deeplearning code를 작성하다 보면 항상 tensor의 차원을 관리하는 것에서 어려움을 마주친다.

물론 Pytorch나 Numpy를 활용해서 차원을 관리할 수 있지만 

문제는 `직관적`이지 않다는 것이다.

 

실제로 4차원 이상부터는 사람이 상상하기 힘들다..

 

이렇게 어려운 차원관리를 효율적으로 할 수 있는 라이브러리가 있다.

바로 `Einops`이다.

이 라이브러리를 처음 발견한 코드는 ViT를 Pytorch로 구현한 코드였다

처음 이 코드를 보았을때, 기존 Python의 문법에서 본적이 없는 하이퍼 파라미터의 형태를 갖고 있어서 조금은 혼란스러웠다.

        out = torch.matmul(attn, v)
        out = rearrange(out, 'b h n d -> b n (h d)')
        return self.to_out(out)

(위 코드에서 rearrange가 einops 라이브러리의 메소드 중 하나이다,

코드 출처 : https://github.com/lucidrains/vit-pytorch/blob/main/vit_pytorch/vit.py)

 

위 코드에서 알 수 있듯이 'b n (h d) -> b h n d'라는 걸 보고 처음에는 당황을 했지만 해당 라이브러리에 대해서 알아보고

DOC을 읽었을 때 직관적으로 이해할 수 있었다

 

바로  [b h n d] 차원을  [b n (h d)]의 형태로 변경하는 것이다

여기서 pytorch의 차원 표기법을 생각해보면 

 3차원인 경우 tensor가 위와 같이 표현된다

즉, 위 코드의 예시를 적용하면, 4차원 -> 이는 배치사이즈를 의미하기 때문에 

[1, 1, 3, 3] -> [1, 3, 3]이 된다

여기서 (h d)는 괄호 안에 있는 차원을 곱해서 하나의 차원으로 만들어준다.

 

이렇듯 차원을 복잡하게 조작하고 관리해야하는 모델의 경우 torch와 numpy를 활용할때 어려움을 느낄 수 있다

따라서 einops를 활용해준다면 간단하게 표현식 같은 방법을 활용해 직관적으로 차원을 관리해 줄 수 있다.

 


einops의 튜토리얼은 아래 블로그와 공식 doc에 잘 정리가 되어 있어서 넘어가겠습니다!!

관심 있으신 분안 아래 블로그 주소와 doc 링크를 활용해주세요!!

 

einops 튜토리얼

In [1]: %config Completer.use_jedi = False import numpy as np from utils import display_np_arrays_as_images fundamentals: reordering, composition and decomposition of axes operations: rerrange, reduce, repeat In [2]: display_np_arrays_as_images() In [3]: i

data-analysis-science.tistory.com

 

 

Einops tutorial, part 1: basics - Einops

# pixelate: first downscale by averaging, then upscale back using the same pattern averaged = reduce(ims, 'b (h h2) (w w2) c -> b h w c', 'mean', h2=6, w2=8) repeat(averaged, 'b h w c -> (h h2) (b w w2) c', h2=6, w2=8) # pixelate: first downscale by averag

einops.rocks

 

실습 코드는 아래 링크 참고

 

einops

실습코드

bottlenose-oak-2e3.notion.site


대표 기능들 살펴 보기 - 자세한 내용은 튜토리얼에 이미지로 나와있습니다.

 

asnumpy - Einops

Convert a tensor of an imperative framework (i.e. numpy/cupy/torch/jax/etc.) to numpy.ndarray Parameters: Name Type Description Default tensor tensor of any known imperative framework required Returns: Type Description Any numpy.ndarray, converted to numpy

einops.rocks

rearrange : 차원 재배열 메소드

#3차원 이미지 (224, 124, 3)가 있다면 'h w c -> h w c' 등의 표현식으로 차원 순서를 재배열 할 수 있다
rearrange(images, 'h w c -> w h c')
# 변경 후 : (124, 224 ,3)

#4차원의 이미지 (3, 224, 124, 3)가 있다면 이를 ()를 활용하여서 차원끼리 묶어 줄 수 있다 , 'b h w c ->(h b) w c'
rearrange(images,  'b h w c ->(h b) w c')
# 변경 후 : (672, 124, 3)

#임시 값을 활용하여서 정렬해줄 수도 있다
rearrange(images, 'b (h1 h) (w1 w) c -> (b h1 w1) h w c', h1=2, w1=2)
# 변경 후 : (12, 62, 112, 3)

reduce : 배열에 대한 복잡한 축소 연산을 수행

#4차원의 이미지 (3, 224, 224, 3)으로 구성된 이미지가 있다면 
##-이는 4장의 이미지가 하나의 배열로 있는것

##reduce를 활용하여하나의 이미지로 축소할 수 있다
reduce(ims, 'b h w c -> h w c', 'mean')

위와 같은 경우

아래의 이미지가 

이렇게 변화한다

이는 torch에서 0차원의 mean을 구하는 것과 같다

ims.mean(axis=0)

 

'mean' 말고도 'min', 'max' , 'sum'과 같은 여러 기준을 설정해줄 수 있다

repeat : 배열에 대한 복제 연산을 수행

#3차원의 이미지 (224, 224, 3) 이 있다면  아래와 같이 repeat를 활용해 반복연산 가능
repeat(img[0], 'h w c -> h (repeat w) c', repeat=3)

#해당 경우 가로로 3번 반복된다

#repeat 파라미터 지정없이 바로 정수로 지정이 가능하다
#아래 코드는 위와 같은 결과를 만든다
repeat(img[0], 'h w c -> h (3 w) c')

repeat(img[0], 'h w c -> (2 h) (2 w) c')
#이런 경우 가로 2개, 세로 2개로 반복된다

#또한 괄호 안에 들어가는 순서에 따라서 반복되는 대상이 변화한다
repeat(img[0], 'h w c -> h (w 3) c') #1번

repeat(img[0], 'h w c -> h (3 w) c') #2번

1번(왼), 2번(오)