ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 패스트캠퍼스 환급챌린지 40일차 미션 (3월 11일) : 딥러닝·인공지능 Signature 초격차 패키지 Online. 강의 후기
    패스트캠퍼스 챌린지 2024. 3. 11. 12:14

     

    벌써 환급챌린지의 2/3이다...

    못할 줄 알았는데 꾸역꾸역 어케 또 하게 된다.

    자!!!!!!!!!!

    오늘은

     

    CH09-02. VAE 실습

    &

    Chapter10. 감정분석모델 구현을 통한 자연어 처리 실습

    CH10-01. 주요코드미리보기(1)

     

     

     

    CH09-02. VAE 실습

    지난 시간에 주요 코드 미리보기를 하다가 부족한 부분에 대해 다시 조금 더 설명해주신다.

     

    # Step4. SetNetwork Sturcture(구조)

    class VAE(nn.Module):
      def __init__(self, latent_dim):
        super(VAE, self).__init__()
        self.flatten = nn.Flatten()
        self.encoder = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 256),
            nn.RELU()
        )
        self.fc_mu = nn.Linear(256, latent_dim)
        self.fc_var = nn.Linear(256, latent_dim)
        self.decoder = nn.Sequential(
            nn.Lienear(latent_dim, 256),
            nn.ReLU(),
            nn.Lienar(256, 512),
            nn.ReLU(),
            nn.Linear(512, 28*28),
            nn.Sigmoid()
        )

        def encode(self, x):
          result = self.encoder(x)
          mu = self.fc_mu(result)
          var = self.fc_vat(result)
          return mu, var

        def decode(self, z):
          result = self.decoder(z)
          return result

        def reparameterize(self, mu, var):
          std = torch.exp(var / 2)
          eps = torch.randn_like(std)
          return mu+eps*std

        def forward(self, x):
          x = self.flatten(x)
          mu, var = self.encoder(x)
          z = self.reparameterize(mu, var)
          out = self.decode(z)
          return out, mu, var

     

    자 여기서, 인코드 코드부터 먼저 살펴보자.

     

        def encode(self, x):
          result = self.encoder(x)
          mu = self.fc_mu(result)
          var = self.fc_vat(result)
          return mu, var

     

    인코드는? 우리가 정했던 X는 2차원 형태로서 플래튼을 통과후(1차원의 상태)의 상태로 입력을 받았다.

     

    인코드라고 선언한 부분(풀리커넥티드레이어)를 통과시키고, fc_mu로 / fc_var 각각의 커넥티드로 통과시킨  다음,

     

    이 인코드를 통과한 리절트에 대해 풀리 커넥티드 레이어를 별도로 설계하는 형태로 인코드를 구현한다.

     

     

    이미지에서 보이는 것처럼 x가 1차원  형태로 플래튼 되어 저 사각박스안에 들어가게 되고, 

    박스 안에서 mu/var로 나뉘어지게 됨을 알 수 있다.

     

    즉, 뮤와 바가 각각 출력이 된다는 점!이 핵심.

     

        def reparameterize(self, mu, var):
          std = torch.exp(var / 2)
          eps = torch.randn_like(std)
          return mu+eps*std

     

    그 다음이 이 리파라미터라이즈인데,

     

    뷰와 바를 사용하여 동일한 확률분포를 가지지만,  다양한 형태의 잠재백터를 가지기 위해(이전에도 설명했듯이

    잠재백터가 다양해야 산출하는 아웃풋도 다양해진다.)

     

    리 파라미터라이즈를 만든 것이다. 

     

    std 배리에이션을 만들고, randn_like에 이 std를 넣어 eps 즉, 우리가 계속 얘기하던 입실론을 만든다.

     

    그래서 위에 보는 것처럼 입실론과 std가 먼저 곱해지고, 여기에 뮤를 더하면 우리가 원하는 z를 구할 수 있다.

     

    Z는 디코더로 들어가는 아이!

     

     

    모델을 다 만들었다면?

    "학습을 시킬 차례입니다."

     

     

    모델을 설정하고 인자를 10으로 설정하였다. ▶ VAE 설정하는데  잠재벡터 10개를 사용하라.

     

    10개의 차원을 입력을 받는게 보이지? 그게 10 넣은 값이 반영 된 것이다.

     

    # Step6. Model Compile
    def loss_function(recon_x, x, mu, var):
        recon_loss = F.binary_cross_entropy(recon_x, x.view(-1, 28*28), reduction='sum')
        kl_loss = -0.5 * torch.sum(1 + var - mu.pow(2) - var.exp())
      # recon_loss의 역할은 x와 아웃풋으로 나온 x'의 차이를 최소화 할 수 있도록 학습 시키기 위한로스 값임.
      # kl_loss는 원본 데이터(x)에 대한 확률밀도 함수와 추정한 approximate한 확률밀도 함수 간 차이를 구하는 형태의 로스값
    optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE)

     

    모델 컴파일러에서 로스를 정의하는데,

    recon_loss와 kl_loss 2가지를 두어 계산한다.

     

    결국 위의 주석달아 놓은 것처럼 2가지의 로스를 최소화하는 방향으로 학습을 수행해나간다.

     

    #Step7. set train loop

    def train(train_loader, model, loss_fn, optimizer):
        model.train()

        for batch, (X, y) in enumerate(train_loader):
            X, y = X.to(DEVICE), y.to(DEVICE)
            decoded, mu, var= model(X)

            # 손실계산
            loss = loss_fn(decoded, X, mu, var)

            # 역전파
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        # 결과 시각화
        origin_data = X[:5].view(-1, 28*28).type(torch.FloatTensor)/255.
        decoded_data = decoded[:5].view(-1, 28*28).type(torch.FloatTensor)/255.
     
        f, axs = plt.subplots(2, 5, figsize=(5, 2))    
        for i in range(5):
            img = np.reshape(origin_data.data.numpy()[i],(28, 28))
            axs[0][i].imshow(img, cmap='gray')
            axs[0][i].set_xticks(())
            axs[0][i].set_yticks(())

        for i in range(5):
            img = np.reshape(decoded_data.to("cpu").data.numpy()[i], (28, 28))
            axs[1][i].imshow(img, cmap='gray')
            axs[1][i].set_xticks(())
            axs[1][i].set_yticks(())
        plt.show()

     

    학습은 이전에 사용했던 동일한 로직이고,

     

    새로운게 decoded, mu, var = model(X) 이부분이다.

     

    모델을 통과시키고 나면 3가지가 나오는데

     

        def forward(self, x):
          x = self.flatten(x)
          mu, var = self.encoder(x)
          z = self.reparameterize(mu, var)
          out = self.decode(z)
          return out, mu, var

     

     

    output만 가지고 x랑 비교해서 로스를 구하는게 아니고, 확률분포를 가지고 확률밀도 함수간 차이를 최소화 하기 위해

    뮤값이랑 바 값이 필요하기 때문에 3개를 내뱉는 것이다.

     

    for i in range(EPOCH):
        print(f"Epoch {i+1} \n------------------------")
        train(train_loader, model, loss_function, optimizer)

     

    이제 내뱉으면, 

     

     

    위에가 원본이미지고, 밑이 잠재백터를 통해 내뱉은 아웃풋, 새롭게 생성된 이미지이다.

     

     

     

    CH10-01. 감정분석모델 구현을 통한 자연어처리실습 주요코드미리보기(1)

    이번시간에 알아볼 내용은 IMDB 클래시파이어 파일입니다.

    아이엠디비 뮤비 어널러시스 리뷰고 자연어처리를 살펴보자.

     

     

     

     

    RNN의 유형은 일전에도 살펴봤듯이 여러가지 종류가 있다.

    우리가 지금 알아볼려고 하는 것은 영화 리뷰 데이터를 분석하여 긍/부정을 판단하는 것이기 때문에,

     

    입력으로 들어가는 데이터는 리뷰 즉 다양한 텍스트로 이루어져 있기 때문에 many가 될 것이고,

    아웃풋은 긍/부 이진분류로 하나의 노드만 필요하기 때문에 

    many to one이 되는 것이다.

     

    자 그러면 모델의 구조를 미리 보자!

     

    #모델 구조 미리보기
    LSTMClassifier(
      (embedding): Embedding(121301, 256)
      (lstm): LSTM(256, 512, num_layers=2, batch_first=True, dropout=0.25)
      (dropout): Dropout(p=0.3, inplace=False)
      (fc): Linear(in_features=512, out_features=1, bias=True)
      (sigmoid): Sigmoid()
    )

     

    LSTM 클래시파이어 라는 이름의 클래스를 만들 것이고,

     

    embedding 레이엇, LSTM, 리니어 레이어를 사용하여 신경망을 만들 것이다.

     

    입력 출력으로 몇개의 노드가 생성되느냐...

     

    12만개의 입력을 받아서 256개의 차원으로 임베딩한 벡터를 만들 것이고,

     

    LSTM 은 256개를 512개, linear는 최종 1개로 만든다.

     

    LSTM 클래스가 받는 인자들에 대해서 알아보즈아.

     

    인풋사이즈: 말 그대로 몇개의 데이터가 입력으로 들어가냐

    히든사이즈: 은닉층의 사이즈다. 

     

     

    위의 이미지에서 보이는 것처럼 히든 사이즈가 1개층이냐 2개층이냐에 따라 이 리커런트 연산이 수행되는 횟수를 말한다.

     

    넘레이어즈: 몇개의 층을 쌓아서 레이어를 만드나

    드롭아웃: 노드를 일부 끊을 것인가 아닐가 정하는 것

    batch_First: 입력으로 주는 데이터의 구조가 배치가 가장 앞에 있을 때에는 배치퍼스트 인자를 트루로 설정,

                        아니면 시퀀스의 길이가 가장 먼저 입력되어 이해한다. 나중에 알아 볼 것.

     

    bidirectional: 양방향 연산을 할 것인지. (위의 그림에서 화살표가 양쪽으로)

     

    입력과 아웃풋이 어떤식으로 들어오고 나가느냐.

     

    여기부턴 다음 시간에 알아보도록 하즈아.

     

     

     

     

     

    40일차 끝.

     

     

     

    본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

    https://bit.ly/48sS29N

Designed by Tistory.