ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #16 : KT_AIVLE_SCHOOL : DX_4th : 딥러닝_언어지능
    KT_AIVLE_SCHOOL_DX_4th 2023. 10. 26. 01:14

    지난 15# 에서는 한기영 강사님과 함께 딥러닝의 전반적인 내용을 보았었다.

    ( #15   https://datawithu.tistory.com/26 )

     

    이번 딥러닝  시간에는 언어지능에 관련되어서   이숙번 강사님과 2일동안 배우게 되었다. 

     

     

    # 0 짧은 생각

    처음 드는 생각은 언어지능? 이 무엇을 말하 는 것인가 였다. 

    우리가 흔히 생각하는 언어는  예를 들면, 한국어, 영어, 일본어 등의 인간이 사용하는 것을 의미할테이다. 

    그렇다면 지능은 무엇인가?  해당 현상/상황/사건 등의 의미를 이해하고 학습하여 다른 활동에도 적용할 수 있는 지적 생산성을 말할것이다.

    그럼 이 두가지가 AI에 합쳐 언급되는 것이 바로 언어지능은 아닐까 생각했다.

    언어지능을 공부하다보면 필연적으로 자연어처리를 만나게 된다. , 여기서 자연어라는 것은 곧 인간의 언어를 의미한다.

    초창기(8월쯤)에 WordCloud를 통해서,  자주 언급되는 단어만 보는 것도 했었다. 

    이번 강의에서는 지난번 딥러닝에서 이해가 덜 되었던 부분들과 함께 언어를 분석하는 기법들을 배울 수 있어서 좋았다.


    1 딥러닝 모델 코드 비교해보기 : 

    • 코드를  여러 방식으로 짤 수있는 것을 배워서 좋았다.

    2. 영화 리뷰 감정 분석  :

    • 예전에 한번 해봤던 것인데, 새로운 데이터로 새로운 코드 방식을 사용해 볼 수 있었다.

    3.패션 MNIST :

    • 사실 이미지 분석은 아직 잘 머리에 안들어오는 것 같다.

    4.워드 클라우드 :

    • 언젠가 혼자서 다 암기하고 시도해보고 싶다

     


    1 딥러닝 모델 코드 비교해보기 

    코드를 보면, 사람마다의 습관이 있다.

    그리고 이건 문체와 비슷하다. 나도 가끔씩 수필&시를 쓰고 공모전도 지원하고 하는데,  사람마다 비슷한 구문, 어휘, 단어, 등등이 반복되는 경우가 많다.  코드를 짜는 것도 인간이 한다면 아무래도 특정한 패턴이 생길수밖에 없는것 같다. 그래서 지난 시간의 배웠던 코드와  이번 세션에 배운 코드의 차이점을 우선 알아보고자 한다.

    1) Sequential 모델에서 코드

    # 1. 세션 정리 = 리소스 아끼기
    from keras.backend import clear_session
    clear_session()
    
    #2. 모델 : Sequential 타입으로 
    from keras.models import Sequential
    from keras.layers import Dense
    
    #여러 layers/Dense 경우 => Hiden layer 추가 [ ] 리스트에 넣어서!!
    # 히든 레이어의 경우는 activation이 필요하다.
    nfeatures = x_train.shape[1] 
    model = Sequential( [ Dense( 아웃풋 노드수, input_shape=(nfeatures,), activation='relu' ),
    		Dense( 아웃풋 노드수, activation='relu' )
    		Dense(1) ] ))
    
    # 모델 : 요약하기 
    model.summary()
    
    ## 조절 가능한 파라미터: epochs(반복학 학습 횟수), learning_rate(학습율)
    # 모델 컴파일 
    from keras.optimizers import Adam 
    model.compile(optimizer=Adam(learning_rate=0.1), loss='mse')
    
    #모델 학습
    model.fit(x_train, y_train, epochs=10, validation_split=0.2)
    
    # 모델 예측
    y_pred = model.predict(x_val)
    
    # 모델 성능 평가
    print(f'RMSE  : {mean_squared_error(y_val,y_pred,squared=False)}')
    print(f'MAE   : {mean_absolute_error(y_val,y_pred)}')
    print(f'MAPE  : {mean_absolute_percentage_error(y_val,y_pred)}')

    2) Vanila 모델 

    이걸 왜 바닐라라고 하는지는 이해를 하지 못했지만,

    강사님은 이런 식으로 짜는 코드를 바닐라 모델이라고 부르는 것 같다.

    #라이브러리
    import pandas as pd
    import tensorflow as tf
    
    # 데이터
    독립 = 데이터[독립변수]
    종속 = 데이터[종속변수]
    
    # 모델 레이어 구성
    X = tf.keras.layers.Input(shape=[1])    # [1]독립변수가 1개 여서 1
    H = tf.keras.layers.SimpleRNN(8)(X)     # 히든 레이어
    Y = tf.keras.layers.Dense(1, activation='swish')(H)  # (1) 종속변수가 1개여서 1
    
    #모델선언
    model = tf.keras.models.Model(X,Y)
    # 모델 컴파일
    model.compile(loss='mse')
    # 모델 학습
    model.fit(독립, 종속, epochs=1000)

    3) 모델 코드-선언 비교해보기 

    # 방법1: sequential
    import tensorflow as tf
    model = tf.keras.Seqential([
        tf.keras.layers.Dense(3, activation='softmax')(X)
    ])
    
    
    # 방법2 : sequential
    from tensorflow.keras import Seqential
    from tensorflow.keras.layers import Dense
    model  = Seqential(Dense(3, input_shape=(4,), activation='softmax'))
    
    
    
    #방법3: vanilla
    X = tf.keras.Input(shape=[4])
    Y = tf.keras.layers.Dense(3, activation='softmax')(X)
    model = tf.keras.Model(X,Y)

    2. 영화 리뷰 감정 분석 

    이 세션에서는 Embedding을 배웠는데,  임배딩은 쉽게(?) 고차원-> 저차원 데이터 수치벡터화 시켜준다고 한다.

    1) DATA준비 & 전처리 

    • IMDB : 영화 리뷰 데이터 셋
    • keras.utils.pad_sequence는 자체적으로 쓸모있는 단어를 추출,
    • pad_sequences는 maxlen만큼 길이를 제한한다. 길이를 맞춰줘야한다. = 길이고정
       
    import  tensorflow as tf
    #IMDB
    (x_train, y_train),(x_test, y_test) = tf.keras.datasets.imdb.load_data()
    x_train = tf.keras.utils.pad_sequences(x_train, maxlen=20)
    x_test = tf.keras.utils.pad_sequences(x_test, maxlen=20)
    
    # 인덱스 부여
    word2index= tf.keras.datasets.imdb.get_word_index()
    index2word = { i : w  for w,i in word2index.items() }

    2) Vanilla RNN모델

    • 감정은 good or bad로 분류하기 때문에 이진분류룰 사용
    • 임베딩에서는 88585개의 단어를 28차원 공간에 하나로 만들기 (28은 임의로 선택한 숫자)
    import  tensorflow as tf
    X = tf.keras.Input(shape=[20])
    H = tf.keras.layers.Embedding(88585, 28)(X)
    H2 = tf.keras.layers.SimpleRNN(32)(H)
    Y = tf.keras.layers.Dense(1, activation='sigmoid')(H2)
    
    #모델 선언+컴파일
    model = tf.keras.Model(X,Y)
    model.compile(loss='binary_crossentropy', metrics='accuracy')
    
    #요약&학습
    model.summary()
    model.fit(x_train, y_train, epochs=10, validation_split=0.2)
    
    #평가  0부정. 1긍정
    model.evaluate(x_test, y_test)

    참고로 

    H2 = tf.keras.layers.SimpleRNN(32, return_sequences=True)(H)옵션을 주면 다중으로 가중치를 전달한다.

    3) 리뷰글 출력해보기

    decoded = " ".join(index2word[i] for i in x_train[1] )
    print(x_train[1][:10])
    print(decoded[:50])

    3. Fashion MNIST

    원래 mnist는 손글씨 숫자 이미지?? 맞추기 였는데 패션 엠니스트는 옷 이미지를 분류하는 것이다.

    1) DATA 준비

    import tensorflow as tf
    (x_train, y_train),(x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
    
    # 데이터에서 사진 한장 출력하기
    import matplotlib.pyplot as plt
    plt.imshow(x_train[1], cmap='gray')
    plt.show()
    
    #정답확인
    print(y_train[0])

    BatchNormalization  :

    • 딥러닝 모델 학습에 도움을 줌.. 표준정규화랑 같은 역할을 한다.

    2) 모델

    import tensorflow as tf
    
    X = tf.keras.Input(shape=[28, 28])
    H = tf.keras.layers.Flatten()(X)
    H = tf.keras.layers.Dense(64, activation='swish')(H)
    H = tf.keras.layers.BatchNormalization()(H)
    H = tf.keras.layers.Dense(32, activation='swish')(H)
    H = tf.keras.layers.BatchNormalization()(H)
    Y = tf.keras.layers.Dense(10, activation ='softmax')(H)
    
    #모델선언
    model = tf.keras.Model(X,Y)
    model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
    model.summary()
    
    #모델학습
    model.fit(x_train, y_train, validation_split=0.2, epochs=100, verbose=False)
    
    모델평가
    model.evaluate(x_test, y_test)

    3) Transformer model

    트랜스포머 모델은 처음 보았는데, 핫?하다고 하셨고 좋은 모델이 많이 만들어진다고도 강사님이 언급했던 기억이있다.

    그렇지만, 아직은 이해가 안가는 부분들도 있는데, 그럴때에는 그냥 암기하고 지식을 끼워넣다보면 어느순간 이해되기도 해서 그냥 외우기로 했다. 아니면 적어도 사용방법은 알아두기로 다짐했다 ㅜㅜ

     

    Attention Layer

    • 내가 가진 데이터 중에서 주목할 것들로 결과 만들기
    • layer여러개 쌓기 가능
    • attention의 핵심은 softmax가 이미 들어가 있다는것.
    # 모델링
    X = tf.keras.Input(shape=[20])
    H = tf.keras.layers.Embedding(88585, 28)(X)
    H = tf.keras.layers.SimpleRNN(32, return_sequences=True)(H)
    
    # Transformer::self-attentions
    H1 = tf.keras.layers.MultiHeadAttention(2, 32)(H, H)
    H = tf.keras.layers.BatchNormalization()(H + H1)
    
    # Transformer::feed-forward
    H1 = tf.keras.layers.Dense(32, activation='swish')(H)
    H = tf.keras.layers.BatchNormalization()(H + H1) #배치정규화와는 무관하게, 같은 엘리먼트와이즈 덧셈: 같은 위치의 것끼리 더해서 새로운 행렬표를 만듬
    
    H = tf.keras.layers.GlobalAveragePooling1D()(H)
    Y = tf.keras.layers.Dense(1, activation="sigmoid")(H)
    
    # 모델선언
    model = tf.keras.Model(X, Y)
    model.compile(loss="binary_crossentropy", metrics="accuracy")
    model.summary()
    
    #학습
    model.fit(x_train, y_train, validation_split=0.2, epochs=10)
    
    # 평가
    model.evaluate(x_test, y_test)

    4.워드 클라우드

    4-1 기존의 라이브러리를 사용하기 

    이건 기존에 해봤던 방법인데, 라이브러리를 사용하면 간단하게? 가장 많이 사용된 단어를 추출해서 이미지로 보여줄 수 있다. 

    1) 데이터 준비하기 

    #라이브러리
    from wordcloud import WordCloud
    #워드클라우드 생성
    wordcloud  = WordCloud(width=800, height=400, background_color='white')
    
    #폰트변경
    wordcloud.font_path = '/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf'
    
    #생성하기#이미지로 저장
    wordcloud.generate(' '.join(filtered_tokens1))
    wordcloud.to_file("wordcloud1.png")
    
    wordcloud.generate(' '.join(filtered_tokens2))
    wordcloud.to_file("wordcloud2.png")

    2) 화면에 출력하기

    # 화면에 나태내깅
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    # Colab 한글 폰트
    plt.rc('font', family='NanumBarunGothic')
    mpl.rc('axes', unicode_minus=False)
    
    #워드클라우드
    plt.axis('off')
    plt.imshow(wordcloud)
    plt.show()

    결과물은 이렇게 나온다...


    4-2 텍스트를 전처리해서 워드 클라우드 

    1.데이터 전처리 

    1-1) 데이터 준비

    연습용 텍스트 + 한글설정

    # 샘플 텍스트 데이터
    text1 = """Natural language processing (NLP) is a field
    of computer science, artificial intelligence,
    and computational linguistics concerned with
    the interactions between computers and human
    (natural) languages."""
    
    text2 = """자연어 처리(Natural Language Processing, NLP)는
    인간의 언어 현상을 컴퓨터와 같은 기계를 이용하여
    모사할 수 있도록 하는 인공 지능의 하위 분야 중 하나입니다."""
    #한글
    !pip install konlpy
    !sudo apt-get install -y fonts-nanum
    !sudo fc-cache -fv
    !rm ~/.cache/matplotlib -rf
    
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    # import matplotlib.font_manager as fm
    
    # Colab한글폰트
    plt.rc('font', family='NanumBarunGothic')
    
    # 유니코드 음수부호
    mpl.rc('axes', unicode_minus=False)

    1-2) 토큰화 

    = > 가장 작은 의미 단위로 분리하기

    영어

    import nltk
    
    # 말뭉치 다운로드
    nltk.download('punkt')
    
    # 텍스트 토큰화 (Tokenization)
    tokens1 = nltk.tokenize.word_tokenize(text1)

    한글

    from konlpy.tag import Okt
    
    # KoNLPy에서 Okt 형태소 분석기를 사용
    okt = Okt()
    
    # 텍스트 토큰화 (Tokenization)
    tokens2 = okt.morphs(text2)
    print(tokens2)

    1-3) 클렌징 및 정규화

    클렌징:  공백, 쉼표 등 의미없거나 필요없는 부분을 처리

    #Cleaning & Normalization
    #영어
    cleaned_tokens1 = [token.lower() for token in tokens1 if token.isalnum()]
    #한글
    cleaned_tokens2 = [token for token in tokens2 if token.isalnum()]

    정규화 : 토큰들을 조정 

    • 모든 단어를 소문자로 
    • 어간 추출/ 원형을 복원
    ## 영어 문장으로 함
    #어간 추출 Stemming
    stemmer1  = nltk.stem.PorterStemmer()
    stemmed_tokens1 = [stemmer1.stem(token) for token in cleaned_tokens1]
    
    #표제어 추출 -원형복원 Lemmatization
    nltk.download('wordnet')
    lemmatizer1 = nltk.stem.WordNetLemmatizer()
    lemmatized_tokens1 = [lemmatizer1.lemmatize(token) for token in cleaned_tokens1]

    1-4) 불용어 제거

    # 불용어 제거
    
    nltk.download('stopwords') #불용어 다운
    stop_words1 = set(nltk.corpus.stopwords.words('english')) #영어
    filtered_tokens1 = [token for token in lemmatized_tokens1 if token not in stop_words1]
    
    stop_words2 = set(["은", "는", "이", "가", "을", "를"]) #한글
    filtered_tokens2 = [token for token in cleaned_tokens2 if token not in stop_words2]

    2 워드클라우드 

    라이브러리 활용

    결국은 같은 이미지가 나오긴 했따 ㅎㅎㅎㅎㅎㅎ

    from wordcloud import WordCloud
    #워드클라우드 생성
    wordcloud  = WordCloud(width=800, height=400, background_color='white')
    
    #폰트변경
    wordcloud.font_path = '/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf'
    
    #파일 생성
    wordcloud.generate(' '.join(filtered_tokens1))
    wordcloud.to_file("wordcloud1.png")
    
    wordcloud.generate(' '.join(filtered_tokens2))
    wordcloud.to_file("wordcloud2.png")
    
    # 화면에 출력
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    # Colab 의 한글 폰트 설정
    plt.rc('font', family='NanumBarunGothic')
    mpl.rc('axes', unicode_minus=False)
    
    # 워드클라우드 출력
    plt.axis('off')
    plt.imshow(wordcloud)
    plt.show()

     

    결과물 

     


    미니 프로젝트를 끝나고 쓰는 글이어서 그런지, 생각보다 다시 보게  되었다.

    이후에 있을 딥러닝 언어/시각지능쪽 미니프로젝트는  실제로  워드클라우드 만들기 전단계인

    텍스트 전처리 과정이 꽤 .. 어려웠던 기억이 남는데, 

    역시 실전과 연습은 다르다는 것을... 또 느낀다. 

Designed by Tistory.