ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [pytorch] nn.Embedding 알아보기
    AI-ML 2024. 3. 8. 22:42
    728x90
    반응형

    - 목차

     

    키워드.

    • - Embedding
    • - Latent

     

    들어가며.

    pytorch 의 Embedding Layer 는 Input Tensor 를 다차원으로 확장시켜주는 기능을 수행합니다.

    예를 들어, 입력값이 1 인 경우에 5차원으로 확장시켜주는 Embedding Layer 에 의해서

    [-0.8088,  0.6665, -0.0974, -0.1083,  0.2192] 와 같은 형식으로 변형될 수 있죠.

    1 -> Embedding -> [-0.8088,  0.6665, -0.0974, -0.1083,  0.2192]

     

    이러한 Embedding Layer 는 크게 2가지 동작을 수행합니다.

    첫번째로 제공되는 기능은 Input Data 를 Latent Vector 인코딩할 수 있습니다.

    즉, Categorical 한 제한된 범위의 데이터는 Embedding Layer 를 통해서 인코딩됩니다.

    예를 들어, "apple", "banana", "candy" 와 같은 입력 데이터가 존재한다고 가정하겠습니다.

    그리고 각 입력 데이터는 0, 1, 2 로 Label Encoding 이 된 이후에 아래와 같이 다차원의 결과물로 인코딩됩니다.

    apple -> 0  --> [-0.8088,  0.6665, -0.0974, -0.1083,  0.2192]
    banana -> 1 --> [-0.3139,  1.3455,  0.3946, -1.6869,  0.2589]
    candy -> 2  --> [-0.5057,  0.3863,  0.4789,  1.3578,  1.2840]

     

    이러한 방식으로 하나의 값이 다차원으로 분해되는 것을 Latent Feature, Latent Vector 와 같이 부르며,

    잠재적인 차원으로 확장할 수 있게 됩니다.

     

    두번째 특징은 차원을 한 차례 확장할 수 있습니다.

    위 예시에서 확인하였듯이, Scalar Value 는 1-Dimensional Vector 로 확장이 됩니다.

    그리고 Vector 는 Matrix 로 확장되며, N 차원의 입력값은 N+1 차원의 값으로 출력됩니다.

    아래와 같이 차원의 확장의 의미도 존재합니다.

    Input : [[0],[1],[2]]
    
    Output :
    [
        [[-1.2975, -0.4792, -0.1931, -0.4409,  0.5042]],
        [[ 0.2923, -3.0725,  0.4268,  1.5539, -0.3350]],
        [[-0.5267, -0.6775, -0.2996,  0.4482,  0.3179]]
    ]

     

    즉, Embedding Layer 는 크게 잠재적인 feature 들을 생성하며, 그 과정에서 차원이 확장되는 기능을 제공하게 됩니다.

     

    nn.Embedding 사용해보기.

    이제 본격적으로 pytorch 의 Embedding Layer 에 대해서 자세히 알아보겠습니다.

    간단한 활용법은 아래와 같습니다.

    임의의 Input Tensor 를 생성합니다.

    그리고 Input Tensor 는 생성된 Embedding 모듈에 입력시켜줍니다.

    그럼 Embedding 된 Output Tensor 를 확인할 수 있습니다.

    import torch 
    import torch.nn as nn
    
    input_tensor = torch.tensor(1)
    # tensor(1)
    
    embed = nn.Embedding(3, 5)
    print(embed.weight)
    # tensor([[-1.2975, -0.4792, -0.1931, -0.4409,  0.5042],
    #         [ 0.2923, -3.0725,  0.4268,  1.5539, -0.3350],
    #         [-0.5267, -0.6775, -0.2996,  0.4482,  0.3179]], requires_grad=True)
    
    output_tensor = embed(input_tensor)
    # tensor([ 0.2923, -3.0725,  0.4268,  1.5539, -0.3350],
    #       grad_fn=<EmbeddingBackward0>)

     

    num_embeddings.

    nn.Embedding 모듈은 num_embeddings 인자를 취합니다.

    num_embeddings 는 인코딩할 대상의 모든 가지수를 의미합니다.

    일반적으로 과일의 종류나 도시의 이름과 같이 범주형 데이터가 Embedding 의 대상 데이터가 되구요.

    이러한 총 범주의 케이스들이 num_embeddings 의 값이 됩니다.

    아래와 같이 num_embeddings 인자의 값이 3으로 설정된다면, 0, 1, 2 의 입력 값을 취할 수 있게 됩니다.

    nn.Embedding(num_embeddings=3, embedding_dim=5)

     

    예를 들어보겠습니다.

    아래와 같이 0, 1, 2 의 값을 가지는 0 차원의 Input Tensor 를 Embedding 에 적용합니다.

    각 Input Tensor 는 5개의 Dimension 을 가지는 Output Tensor 로 출력됩니다.

    import torch 
    import torch.nn as nn
    embedding = nn.Embedding(num_embeddings=3, embedding_dim=5)
    print(embedding(  torch.tensor(0)  ))
    print(embedding(  torch.tensor(1)  ))
    print(embedding(  torch.tensor(2)  ))
    tensor([-0.3355,  0.6567, -1.5640,  0.0710,  0.4330],
           grad_fn=<EmbeddingBackward0>)
    tensor([-0.8927,  1.0581, -0.3941,  0.3343,  0.5579],
           grad_fn=<EmbeddingBackward0>)
    tensor([-0.1961, -0.9640, -0.8966,  2.7573,  0.5928],
           grad_fn=<EmbeddingBackward0>)

     

     

    만약 num_embeddings 보다 큰 값이 Input Tensor 로 입력된다면,( Unseen Data )

    IndexError 가 발생하게 됩니다.

    IndexError: index out of range in self

     

    embedding_dim.

    embedding_dim 은 Output Tensor 의 Dimension 을 지정합니다.

    아래 예시와 같이 embedding_dim 을 5 로 설정하게 되면, Output Tensor 는 5 Dimension 을 가지게 됩니다.

    import torch 
    import torch.nn as nn
    embedding = nn.Embedding(num_embeddings=3, embedding_dim=5)
    print(embedding(  torch.tensor(0)  ))
    tensor([-0.9814, -1.3657, -0.1319,  0.0218, -0.6831],
           grad_fn=<EmbeddingBackward0>)

     

     

    _weight.

    Embedding 모듈은 weight 을 매뉴얼하게 설정 가능합니다.

    weight 를 설정하는 방식은 아래와 같구요.

    weight_tensor 를 생성하여, nn.Embedding 모듈의 _weight 인자로 설정할 수 있습니다.

    import torch 
    import torch.nn as nn
    weight_tensor = torch.tensor([
        [1.,2.,3.,4.,5.],
        [6.,7.,8.,9.,10.],
        [11.,12.,13.,14.,15.]
    ])
    embedding = nn.Embedding(num_embeddings=3, embedding_dim=5, _weight=weight_tensor)
    embedding.weight
    tensor([[ 1.,  2.,  3.,  4.,  5.],
            [ 6.,  7.,  8.,  9., 10.],
            [11., 12., 13., 14., 15.]], requires_grad=True)

     

    그럼 nn.Embedding 의 Weight 가 의미하는 바가 무엇일까요 ?

    아래와 같이 0 이라는 Input Tensor 를 Embedding Layer 에 통과시킵니다.

    그럼 출력되는 결과는 [1., 2., 3., 4., 5.] 가 됩니다.

    즉, Weight 에 설정된 값이 곧 Input Tensor 가 변형될 결과가 됩니다.

    input_tensor = torch.tensor([0])
    output_tensor = embedding( input_tensor )
    output_tensor
    tensor([[1., 2., 3., 4., 5.]], grad_fn=<EmbeddingBackward0>)
    input_tensor = torch.tensor([1])
    output_tensor = embedding( input_tensor )
    output_tensor
    tensor([[ 6.,  7.,  8.,  9., 10.]], grad_fn=<EmbeddingBackward0>)

     

     

    반응형
Designed by Tistory.