반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

https://d2l.ai/chapter_recurrent-neural-networks/rnn-concise.html

 

9.6. Concise Implementation of Recurrent Neural Networks — Dive into Deep Learning 1.0.0-beta0 documentation

 

d2l.ai

 

9.6. Concise Implementation of Recurrent Neural Networks

 

Like most of our from-scratch implementations, Section 9.5 was designed to provide insight into how each component works. But when you’re using RNNs every day or writing production code, you will want to rely more on libraries that cut down on both implementation time (by supplying library code for common models and functions) and computation time (by optimizing the heck out of these library implementations). This section will show you how to implement the same language model more efficiently using the high-level API provided by your deep learning framework. We begin, as before, by loading The Time Machine dataset.

 

대부분의 초기 구현과 마찬가지로 섹션 9.5는 각 구성 요소의 작동 방식에 대한 통찰력을 제공하도록 설계되었습니다. 그러나 매일 RNN을 사용하거나 프로덕션 코드를 작성할 때 구현 시간(공통 모델 및 함수에 대한 라이브러리 코드 제공)과 계산 시간(최적화를 통해)을 모두 줄이는 라이브러리에 더 의존하고 싶을 것입니다. 이러한 라이브러리 구현). 이 섹션에서는 딥 러닝 프레임워크에서 제공하는 고급 API를 사용하여 동일한 언어 모델을 보다 효율적으로 구현하는 방법을 보여줍니다. 이전과 마찬가지로 Time Machine 데이터 세트를 로드하여 시작합니다.

 

import torch
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2l

 

9.6.1. Defining the Model

 

We define the following class using the RNN implemented by high-level APIs.

 

상위 수준 API에 의해 구현된 RNN을 사용하여 다음 클래스를 정의합니다.

 

class RNN(d2l.Module):  #@save
    """The RNN model implemented with high-level APIs."""
    def __init__(self, num_inputs, num_hiddens):
        super().__init__()
        self.save_hyperparameters()
        self.rnn = nn.RNN(num_inputs, num_hiddens)

    def forward(self, inputs, H=None):
        return self.rnn(inputs, H)

위 코드는 고수준 API를 사용하여 구현된 RNN(순환 신경망) 모델을 나타냅니다.

  • num_inputs: 입력 특성의 개수입니다.
  • num_hiddens: 은닉 상태의 차원 수입니다.

이 클래스의 __init__ 메서드는 다음과 같이 작동합니다:

  1. num_inputs와 num_hiddens를 저장하고 부모 클래스인 d2l.Module의 생성자를 호출합니다.
  2. nn.RNN을 사용하여 RNN 레이어를 생성합니다. 이 RNN 레이어는 입력의 크기가 num_inputs이고, 은닉 상태의 크기가 num_hiddens인 순환 신경망 레이어입니다.

forward 메서드는 다음과 같이 작동합니다:

  1. inputs: 입력 데이터입니다. 시계열 데이터의 시간 스텝에 따른 특성들로 이루어진 3D 텐서입니다.
  2. H: 초기 은닉 상태입니다. 기본값은 None이며, 필요한 경우 입력될 수 있습니다.
  3. self.rnn을 통해 입력 데이터와 초기 은닉 상태를 RNN 레이어에 전달하여 순방향 계산을 수행합니다. 이 결과는 순방향 계산의 출력과 마지막 시간 스텝에서의 은닉 상태로 구성된 튜플로 반환됩니다.

이 코드는 고수준 API를 사용하여 간단한 RNN 모델을 구현하고 있습니다. RNN 모델은 순차 데이터를 처리하고 은닉 상태를 업데이트하는 데 사용될 수 있습니다.

 

https://pytorch.org/docs/stable/generated/torch.nn.RNN.html

 

RNN — PyTorch 2.0 documentation

Shortcuts

pytorch.org

torch.nn.RNN 클래스는 PyTorch에서 제공하는 순환 신경망(RNN) 레이어를 나타내는 클래스입니다. RNN은 시퀀스 데이터를 처리하는데 사용되며, 이전 단계의 출력이 다음 단계의 입력으로 사용되는 재귀 구조를 가집니다.

torch.nn.RNN 클래스는 다양한 매개변수를 통해 RNN 레이어의 동작을 구성할 수 있습니다. 주요 매개변수와 해당 역할은 다음과 같습니다:

  • input_size: 입력 특성의 크기입니다.
  • hidden_size: 은닉 상태의 크기입니다. RNN 레이어의 출력 및 은닉 상태의 크기가 됩니다.
  • num_layers: RNN의 층 수입니다. 디폴트 값은 1이며, 여러 층으로 쌓아 복잡한 모델을 만들 수 있습니다.
  • nonlinearity: 활성화 함수를 지정합니다. 디폴트는 'tanh'이며, 다른 옵션으로는 'relu' 등이 있습니다.
  • bias: 편향(bias)을 사용할지 여부를 결정합니다.
  • batch_first: True로 설정하면 입력 데이터의 shape를 (batch_size, seq_length, input_size)로 사용합니다.
  • dropout: 드롭아웃을 적용할 비율입니다.
  • bidirectional: 양방향 RNN을 사용할지 여부를 결정합니다.

이러한 매개변수를 설정하여 torch.nn.RNN 클래스로 RNN 레이어를 생성할 수 있으며, 이후 입력 데이터를 이 레이어에 전달하여 시퀀스 데이터의 처리를 수행할 수 있습니다.

 

 

Inheriting from the RNNLMScratch class in Section 9.5, the following RNNLM class defines a complete RNN-based language model. Note that we need to create a separate fully connected output layer.

 

섹션 9.5의 RNNLMcratch 클래스에서 상속받은 다음 RNNLM 클래스는 완전한 RNN 기반 언어 모델을 정의합니다. 별도의 완전히 연결된 출력 계층을 만들어야 합니다.

 

class RNNLM(d2l.RNNLMScratch):  #@save
    """The RNN-based language model implemented with high-level APIs."""
    def init_params(self):
        self.linear = nn.LazyLinear(self.vocab_size)

    def output_layer(self, hiddens):
        return self.linear(hiddens).swapaxes(0, 1)

위 코드는 고수준 API를 사용하여 구현된 RNN 기반의 언어 모델인 RNNLM 클래스를 정의하고 있습니다.

이 클래스는 d2l.RNNLMScratch 클래스를 상속받습니다. RNNLMScratch 클래스는 이전 대화에서 고수준 API를 사용하여 구현된 RNN 언어 모델의 기본 구현을 포함하고 있습니다.

RNNLM 클래스의 init_params 메서드는 다음과 같이 작동합니다:

  1. nn.LazyLinear를 사용하여 선형 레이어를 생성합니다. 이 레이어의 출력 크기는 어휘 크기(vocab_size)로 설정됩니다.

output_layer 메서드는 다음과 같이 작동합니다:

  1. hiddens: RNN의 은닉 상태입니다. 각 시간 스텝마다의 은닉 상태들로 구성된 텐서입니다.
  2. self.linear 레이어를 통해 은닉 상태를 선형 변환하여 언어 모델의 출력을 생성합니다. 출력 텐서의 크기는 (num_steps, batch_size, vocab_size)로 되며, 시간 스텝을 따라 텐서의 차원이 바뀌도록 swapaxes(0, 1) 메서드를 사용하여 차원을 바꿔줍니다.

이를 통해 RNNLM 클래스는 고수준 API를 사용하여 RNNLMScratch 클래스의 구현을 더 간결하고 편리하게 나타내고 있습니다.

 

 

9.6.2. Training and Predicting

 

Before training the model, let’s make a prediction with a model initialized with random weights. Given that we have not trained the network, it will generate nonsensical predictions.

 

모델을 훈련시키기 전에 임의의 가중치로 초기화된 모델로 예측을 해봅시다. 우리가 네트워크를 훈련시키지 않았다면 무의미한 예측을 생성할 것입니다.

 

data = d2l.TimeMachine(batch_size=1024, num_steps=32)
rnn = RNN(num_inputs=len(data.vocab), num_hiddens=32)
model = RNNLM(rnn, vocab_size=len(data.vocab), lr=1)
model.predict('it has', 20, data.vocab)

위 코드는 고수준 API를 사용하여 구현된 RNN 기반의 언어 모델인 RNNLM 클래스를 활용하여 예측하는 과정을 보여줍니다.

  1. d2l.TimeMachine 클래스를 사용하여 데이터를 로드합니다. 이 데이터는 언어 모델 학습에 사용되는 텍스트 데이터입니다.
  2. RNN 클래스를 인스턴스화하여 RNN 모델을 생성합니다. 이 클래스는 고수준 API를 사용하여 RNN 레이어를 포함하고 있습니다.
  3. RNNLM 클래스를 인스턴스화하여 언어 모델을 생성합니다. 이 클래스는 RNN 클래스를 기반으로 하며, 모델의 출력 레이어로 nn.LazyLinear 레이어를 사용하여 언어 모델의 예측을 수행합니다.
  4. model.predict 메서드를 사용하여 주어진 입력 문자열('it has')에 대한 모델의 예측을 생성합니다. 이 메서드는 주어진 입력 문자열 다음에 오는 문자들을 모델을 사용하여 예측합니다. 마지막 인자로는 어휘 사전(data.vocab)을 전달하여 예측된 정수값을 문자로 변환합니다.

이를 통해 고수준 API를 사용하여 구현된 RNN 언어 모델을 활용하여 주어진 입력에 대한 다음 문자 예측을 수행하는 과정을 보여줍니다.

 

'it hasgggggggggggggggggggg'

 

Next, we train our model, leveraging the high-level API.

 

다음으로 상위 수준 API를 활용하여 모델을 교육합니다.

 

trainer = d2l.Trainer(max_epochs=100, gradient_clip_val=1, num_gpus=1)
trainer.fit(model, data)

위 코드는 d2l.Trainer를 사용하여 모델을 학습하는 과정을 보여줍니다.

  1. d2l.Trainer 클래스를 인스턴스화하여 트레이너를 생성합니다. 이 클래스는 모델 학습에 관련된 설정을 지정할 수 있는 기능을 제공합니다. 여기서 max_epochs는 최대 에포크 수를, gradient_clip_val은 그래디언트 클리핑을 수행할 임계값을, num_gpus는 사용할 GPU 수를 나타냅니다.
  2. trainer.fit 메서드를 사용하여 모델을 학습합니다. 첫 번째 인자로는 학습할 모델(model)을, 두 번째 인자로는 학습 데이터(data)를 전달합니다. 이 메서드는 지정한 최대 에포크 수(max_epochs) 동안 모델을 학습시킵니다. 학습 중에는 그래디언트 클리핑이 적용될 수 있습니다(gradient_clip_val에 지정한 임계값을 넘어서지 않도록 그래디언트를 조정).

이를 통해 d2l.Trainer를 사용하여 모델을 학습하는 방법을 보여줍니다.

 

 

Compared with Section 9.5, this model achieves comparable perplexity, but runs faster due to the optimized implementations. As before, we can generate predicted tokens following the specified prefix string.

 

섹션 9.5와 비교하여 이 모델은 비슷한 복잡성을 달성하지만 최적화된 구현으로 인해 더 빠르게 실행됩니다. 이전과 마찬가지로 지정된 접두사 문자열 다음에 예측 토큰을 생성할 수 있습니다.

 

model.predict('it has', 20, data.vocab, d2l.try_gpu())

위 코드는 RNNLM 모델을 사용하여 텍스트를 생성하는 예시를 보여줍니다.

  1. model.predict 메서드를 호출하여 텍스트를 생성합니다. 이 메서드는 생성하려는 텍스트의 시작 점인 prefix, 생성할 텍스트의 길이인 num_preds, 사용할 어휘 사전인 vocab, 그리고 어떤 디바이스(GPU 또는 CPU)에서 연산을 수행할지를 나타내는 device를 인자로 받습니다.
  2. 이 메서드는 outputs라는 리스트를 생성하고, 먼저 prefix의 첫 번째 단어를 outputs에 추가합니다. 그런 다음 생성된 텍스트의 길이인 num_preds만큼 반복문을 수행합니다.
  3. 각 반복에서 현재까지 생성된 텍스트를 바탕으로 다음 단어를 생성하고 outputs에 추가합니다. 이를 위해 현재 단어에 해당하는 인덱스를 X로 변환하고, 모델에 입력으로 넣어서 다음 단어를 예측합니다.
  4. 이렇게 생성된 텍스트의 인덱스를 outputs에 추가합니다.
  5. 모든 반복이 끝나면 outputs 리스트에 저장된 인덱스들을 어휘 사전을 이용해 실제 단어로 변환하여 결합하여 생성된 텍스트를 반환합니다.

즉, model.predict 메서드는 주어진 접두어(prefix)와 모델을 사용하여 주어진 길이(num_preds)만큼의 텍스트를 생성하는 기능을 수행합니다.

'it has and the time trave '

 

9.6.3. Summary

High-level APIs in deep learning frameworks provide implementations of standard RNNs. These libraries help you to avoid wasting time reimplementing standard models. Moreover, framework implementations are often highly optimized, leading to significant (computational) performance gains as compared to implementations from scratch.

 

딥 러닝 프레임워크의 고급 API는 표준 RNN 구현을 제공합니다. 이러한 라이브러리는 표준 모델을 다시 구현하는 데 시간을 낭비하지 않도록 도와줍니다. 또한 프레임워크 구현은 종종 고도로 최적화되어 처음부터 구현하는 것과 비교할 때 상당한 (계산) 성능 향상을 가져옵니다.

 

RNN High-Level API에 대해서...

 

In the context of deep learning frameworks like PyTorch, a high-level API for Recurrent Neural Networks (RNNs) refers to a set of pre-built and easy-to-use functions, classes, and modules that abstract away the low-level details of creating and training RNN models. This high-level API simplifies the process of working with RNNs by providing ready-to-use components, reducing the need for manual implementation and allowing practitioners to focus more on designing and experimenting with models.

 

딥 러닝 프레임워크인 PyTorch에서의 고수준 API란 사전에 구축된 함수, 클래스, 모듈 세트를 의미합니다. 이러한 API는 재귀 신경망(RNN) 모델을 생성하고 훈련시키는 저수준 세부 사항을 추상화하여 제공합니다. 이 고수준 API는 RNN 작업을 간단하게 만들어주며, 수동으로 구현할 필요성을 줄여주어 모델 디자인 및 실험에 집중할 수 있도록 도와줍니다.

 

The high-level API for RNNs often includes the following features:

고수준 RNN API는 일반적으로 다음과 같은 기능을 포함합니다:

 

  1. Pre-built RNN Layers: High-level APIs provide pre-built RNN layer classes with configurable parameters, such as the number of hidden units, number of layers, dropout rates, and more. These classes encapsulate the underlying complexity of RNN cell creation and management.

    미리 구축된 RNN 레이어: 고수준 API는 설정 가능한 매개변수(숨겨진 유닛 수, 레이어 수, 드롭아웃 비율 등)를 가진 미리 구축된 RNN 레이어 클래스를 제공합니다. 이러한 클래스는 RNN 셀 생성 및 관리의 기본 복잡성을 캡슐화합니다.

  2. Sequence Handling: They offer convenient functions for dealing with sequences, such as padding, packing, and unpacking sequences, making it easier to work with variable-length inputs.

    시퀀스 처리: 시퀀스(열) 처리와 관련된 편리한 기능을 제공하여 패딩, 언패킹 등의 작업을 간편하게 처리할 수 있도록 합니다. 이는 가변 길이 입력과 작업하는 데 도움이 됩니다.

  3. Bidirectional RNNs: Many high-level APIs support bidirectional RNNs out of the box, allowing the model to capture information from both past and future time steps.

    양방향 RNN: 많은 고수준 API가 양방향 RNN을 지원하며, 이로 인해 모델이 과거 및 미래 시간 단계의 정보를 모두 캡처할 수 있습니다.

  4. Batch First: They often allow you to specify whether the input data should have the batch dimension as the first dimension, simplifying the handling of batched data.

    배치 우선: 입력 데이터의 배치 차원을 첫 번째 차원으로 설정할 수 있도록 허용하여 배치 데이터 처리를 간편하게 할 수 있도록 합니다.

  5. Model Building: High-level APIs offer simple ways to construct complex models using RNN layers. They typically allow for stacking multiple layers, adding other types of layers, and creating custom architectures.

    모델 구축: 고수준 API는 RNN 레이어를 사용하여 복잡한 모델을 간단하게 구성하는 방법을 제공합니다. 여러 레이어를 쌓거나 다른 유형의 레이어를 추가하고 사용자 정의 아키텍처를 만드는 것이 일반적입니다.

  6. Training Loop: These APIs often provide training loops that abstract away the gradient calculation, optimization steps, and loss calculation, making the training process more streamlined.

    훈련 루프: 이러한 API는 경사 계산, 최적화 단계 및 손실 계산 등의 세부 사항을 추상화하는 훈련 루프를 제공하여 훈련 과정을 더 간단하게 만들어줍니다.

  7. Model Saving and Loading: High-level APIs provide methods for saving and loading trained models, which is crucial for model deployment and further experimentation.

    모델 저장 및 불러오기: 고수준 API는 훈련된 모델을 저장하고 불러오는 방법을 제공하여 모델 배포 및 추가 실험에 필요한 기능을 제공합니다.

Examples of high-level APIs for RNNs in PyTorch include nn.RNN, nn.LSTM, and nn.GRU modules. These modules encapsulate the functionality of RNN cells and provide a simpler interface for building and training RNN-based models.

PyTorch에서의 고수준 RNN API 예시로는 nn.RNN, nn.LSTM, nn.GRU 모듈이 있습니다. 이러한 모듈은 RNN 셀의 기능을 캡슐화하고 구축 및 훈련하기 위한 더 간단한 인터페이스를 제공합니다.

9.6.4. Exercises

  1. Can you make the RNN model overfit using the high-level APIs?
  2. Implement the autoregressive model of Section 9.1 using an RNN.
반응형