[DL] 실습 - RNN (단어 마지막 알파벳 예측)

Minjeong Kim·2026년 1월 7일

인공지능

목록 보기
35/50

📢 학습목표

  • RNN 학습 방법에 대해 알아보자
  • 시계열 데이터를 학습하여 예측하는 방법에 대해서 알아보자
  • keras 의 SimpleRNN() 활용해보자

분석 목적

Char -> 알파벳 한 글자 단위로 학습하기

  • 알파벳 4개의 글자가 들어가면 마지막 글자를 맞추는 모델을 만들어보자
  • 5개 단어 사용: hello, apple, happy, drink, house

code

  1. 단어 사전 만들기

    • 'h','e','l','o','a','p','y','d','r','i','n','k','u','s’ (14개)
      • 모델이 학습을 하기 위해서 현재 사용할 단어들의 묶음을 생성
      • 지금 사용할 단어들만 단어사전을 만들자!
    import numpy as np
    
    alpha_list = ['h','e','l','o','a','p','y','d','r','i','n','k','u','s']
    
    alpha_dic = {key:[] for key in alpha_list}
    tmp = [0 for i in range(len(alpha_list))]
    
    for i in range(len(alpha_list)):
      tmp2 = tmp.copy()
      tmp2[i] = 1
      alpha_dic[alpha_list[i]] = tmp2
    • alpha_dic
      {'h': [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'e': [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'l': [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'o': [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'a': [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'p': [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], 'y': [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], 'd': [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], 'r': [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 'i': [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 'n': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], 'k': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], 'u': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], 's': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]}
  2. 학습용 데이터, 정답 데이터 만들기

    # 학습용 데이터
    data = [['h','e','l','l'],['a','p','p','l'],['h','a','p','p'],['d','r','i','n'],['h','o','u','s']]
    
    X = []
    
    for i in range(len(data)):
      tmp = []
      for j in data[i]:
        tmp.append(alpha_dic[j])
      X.append(tmp)
    
    X = np.array(X)
    
    # 정답 데이터
    label = ['o','e','y','k','e']
    
    y = []
    
    for i in label:
      y.append(alpha_dic[i])
    
    y = np.array(y)
    • X
      # 크기 확인
      X.shape
      # (5,4,14) = (샘플 수, 순환 횟수, 특성 개수) -> 14개의 단어사전에 예측
      [[[1 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 1 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 1 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 1 0 0 0 0 0 0 0 0 0 0 0]]
      
       [[0 0 0 0 1 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 1 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 1 0 0 0 0 0 0 0 0]
        [0 0 1 0 0 0 0 0 0 0 0 0 0 0]]
      
       [[1 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 1 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 1 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 1 0 0 0 0 0 0 0 0]]
      
       [[0 0 0 0 0 0 0 1 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 1 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 1 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 1 0 0 0]]
      
       [[1 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 1 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 1 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 1]]]
    • y
      [[0 0 0 1 0 0 0 0 0 0 0 0 0 0]
       [0 1 0 0 0 0 0 0 0 0 0 0 0 0]
       [0 0 0 0 0 0 1 0 0 0 0 0 0 0]
       [0 0 0 0 0 0 0 0 0 0 0 1 0 0]
       [0 1 0 0 0 0 0 0 0 0 0 0 0 0]]
    • RNN 모델의 input_shape 예시 예) 시계열 데이터 예측
      • 6개월 전기 사용 요금을 입력으로 하여 다음 월의 전기 사용 요금을 예측
      • 총 7월, 8월, 9월 3개월의 예측을 진행함
      • 샘플 수: 3 (우리가 예측할 값들)
      • 순환 횟수: 6 (앞의 몇 개월치 데이터를 볼 것인지)
      • 특성 개수: 1 (사용 요금)
  3. RNN 모델링

    from tensorflow.keras import Sequential
    from tensorflow.keras.layers import Input, SimpleRNN, Dense
    
    rnn_model = Sequential()
    
    # Input layer
    rnn_model.add(Input(shape=(4,14)))
    
    # RNN
    rnn_model.add(SimpleRNN(units = 2)) # default activation = hyperbolic tangent(tanh) function
    
    # Output layer
    rnn_model.add(Dense(units=14,activation='softmax'))
    • 순환하기 때문에 층 1개만 쌓으면 됨!
    • SimpleRNN : 기본적인 RNN 구조를 구현하는 클래스
    • Dense : 순환 수 MLP 사용을 위하여 불러옴
    • output layer units = 14
      • 단어 사전에 있는 14개의 알파벳 중 1개를 예측
    • RNN 의 특성상 기억가중치를 학습에 활용 → 시계열 데이터 학습 가능
      • 유닛이 증가하면 다른 유닛의 기억가중치도 함께 학습
  4. 학습 방법 및 평가 방법 설계

    # 학습 방법 및 평가 방법 설계
    rnn_model.compile(loss= 'categorical_cross',
                      optimizer = 'Adam',
                      metrics=['accuracy']) 
    • loss 에 sparse 를 사용하지 않는 이유 이미 y 데이터가 우리가 출력하는 데이터와 차원이 맞으므로 sparse 사용하지 않음!
  5. 학습

    # 학습
    rnn_model.fit(X,y,epochs=1000)
  6. 예측

    • 기존 학습에 사용했던 단어 예측
      # 첫번째 샘플 hell 입력
      # 1개 데이터 입력을 위하여 3차원으로 변경
      # (sample 수, 순환 횟수, 특성 수)
      test = X[0].reshape(1,4,14)
      test.shape # (1,4,14)
      
      # 예측
      rnn_model.predict(test).argmax() # np.int64(3)
      
      # 정답 확인
      alpha_list[3] # 'o' 정답!
    • 새로운 단어(sunny) 예측
      # sunn -> y
      
      # input data 만들기
      tmp = []
      for j in ['s','u','n','n']:
        tmp.append(alpha_dic[j])
      test2 = np.array(tmp).reshape(1,4,14)
      test2.shape
      
      # 예측
      alpha_list[rnn_model.predict(test2).argmax()]
      

0개의 댓글