반응형

ViT 배경 설명

  • ViT는 2021 ICLR에 나온, Google Brain의 논문이다.
  • NLP 분야에서 광범위하게 사용되고 있던, Transformer를 computer vision 분야에 적용해 좋은 성능을 보여주었다. 

 

Abstact

  • Transformer가 NLP 분야에서는 standard로 자리 잡았지만, computer vision 분야에서 활용은 아직 한계가 있다.
  • vision 분야에서는 attention은 attention은 CNN과 함께 적용되거나, 그 요소를 바꾸는 데 사용하는 등, 전체적인 구조는 그대로이다.
  • 이 논문에서는 CNN구조의 중심이 불필요하고, image patches를 sequence 형태로 pure transformer에 바로 적용하는 것이 image classification에서 잘 working한다는 것을 보여준다.
  • 많은 양의 pre-trained 데이터로 학습하고, 적은 양의 image recognition benchmark들로 실험했을 때, Vision Transformer(ViT)는 SOTA CNN 구조보다 학습에 적은 연산 cost를 사용하면서 좋은 성능을 낸다.

 

Introduction

[배경]

  •  NLP 분야에서는 Transformer를 선두로 한, Self-attention-based 구조를 채택해서, 매우 좋은 성능을 보이고 있다.
  • Computer vision에서는 CNN 구조가 아직 대세이다. CNN 구조와 self-attention 구조를 연결하려고 노력하거나, conviolution을 대체하는 등 여러 연구들도 있었다.
  • 특히, convolution을 대체하는 연구는 이론적으로는 효율적이지만, 현재(그 당시) hardware accelerator 구조로는 적용이 어려웠다. 따라서, large-scale image recognition에서는 classic resnet 구조가 아직 SOTA였다.

[소개]

  • 이 논문에서는 standard Transformer를 거의 변경없이, 이미지에 적용한다. 이를 위해, image를 patch로 나누고, 이 patch들을 linear embeddings sequence 형태로 transformer에 넣는다. (image patche들은 NLP의 token처럼 다뤄진다.)
  • 모델은 image classification을 supervised learning으로 학습한다. 
  • ImageNet 같은 mid-sized 데이터셋에서 이 모델은 비슷한 크기의 resnet보다 몇 % 정도 낮은 수준의 정확도를 보인다. 
  • 이 결과는 기대에 밑돌아, Transformer가 inductive biases(추상적 일반화)가 CNN에 비해 떨어진다고 생각할 수 있다. 
  • 하지만, 대용량 dataset에서 실험했을 때, 상황은 바뀐다.
  • ViT는 충분한 pre-trained 데이터가 있을 때, 매우 좋은 성능을 보인다. 

 

Method

  • 모델 디자인은 original Transformer를 최대한 비슷하게 따랐다. (구현이 되어 있기에 바로 적용할 수 있어서)

[ViT]

  • Transformer는 1D 데이터를 처리하는데, 이미지는 2D이다. 이미지(HXWXC)를 다루기 위해, Image를 2D patches(PXPXC) 개로 나누었다. 
  • Transformer는 각 layer에서 constant latent vector size D를 유지하는데, 이를 위해, patch들을 학습 가능한 linear projection을 통해, D dimension 화하였다. 그리고, 이 결과를 patch embeddings라고 부른다.
  • BERT의 class token 처럼, patch embedding의 앞에 learnable embedding을 붙인다. 이것은 Transformer encoder의 output이 이미지 representation(y)이 될 수 있도록 사용된다. 
  • pre-training과 fine-tuning 단계에서 모두, Transformer encoder의 ouput이 classification의 head로 이용된다. 
  • classification head는 pre-training 단에서는 one hidden layer의 MLP로, fine-trurning 단계에서는 하나의 linear layer로 구성된다. 
  • Position embeddings는 patch embeddings에 더해져, 공간 정보를 제공한다.
  • ViT에서는 학습 가능한 1D position embeddings를 사용했는데, 2D의 position embedding이 성능에 딱히 영향이 없는 것 같아서 그랬다고 한다.
  • Transformer encoder는 multiheaded self-attention의 대체 layer들과 MLP block으로 구성되어있다.
  • Layernorm은 각 block 전에 적용되어 있고, 모든 block 끝에는 residual connection이 존재한다.
  • MLP는 GELU 함수를 사용한 2개의 latyer로 구성되어 있다. 

 
[Inductive bias]

  • ViT는 image specific inductive bias가 CNN에 비해 덜하다.
  • CNN에서는 지역 정보, 2D neighborhood 정보, translation 등분산성(골고루 보고 처리한다.)이 각 layer에 담긴다.
  • ViT에서는 MLP layer에서만 translation 등분산성과 지역 정보를 보고,  self-attention layer들에서는 전체적으로 본다. 
  • 2D neighborhood 정보는 드물게 사용된다. model의 시작에 이미지를 cutting 하고, fine-tuning 때는 position emeddings를 다른 resolution으로 처리하기 때문이다. 또한, initinalization 시에 embedding에는 정보가 없기 때문에, patch의 2D 위치와 patch 간의 공간 관계에 대해 처음부터 스스로 학습해야 한다. 

[Hybrid Architecture]

  • raw image patches의 대안으로, CNN의 feature 형태로 input sequence를 구성할 수 있다. hybrid model에서는 patch embedding을 CNN feature map으로부터 뽑는다.
  • 어떤 케이스에서는 1X1이 될 수 있는데, 이 것은 input sequence가 spatial dimension 정보를 flatten 한 케이스이다.
  • classification input embedding과 postion embeddings들은 아래처럼 더해진다. 

 
[Fine-turning and Higher resolution]

  • 기본적으로 ViT를 large dataset에서 pre-train 하였고, 적은 데이터셋에서 fine-tune 하였다.
  • 이를 위해, pre-trained prediction head를 지우고, zero-initialized D X K layer를 넣었다. (K는 classification class 개수)
  •  pre-trained 보디, fine-tune 때 높은 해상도의 이미지를 사용하는 것이 유리하다.
  • 고해상도 이미지를 넣을 때, patch size는 동일하게 유지한다. (sequence length만 늘어난다.)
  • ViT는 임의의 sequence length를 다룰 수 있지만, 그러면 pre-training 된 position embedding은 더 이상 의미가 없다. 
  • 이때는 pre-trained position embedding에 original image에서의 위치에 따라, 2D interpolation을 통해 처리했다. 

 

Experiments

  • Resnet, ViT, hybrid model을 실험했다. 
  • 각 모델의 데이터 필요도를 확인하기 위해, 다양한 사이즈에서 pre-train을 하였고, 다양한 benchmark에서 실험했다.
  • pre-training의 연산 cost를 생각했을 때, ViT는 매우 순조롭게, 적은 양의 연산 cost 만으로 SOTA recognition benchmark에 도달했다. 

[Setup]

  • Dataset : ILSVRC-2012 ImageNet 데이터셋(1000 classes, 1.3M images), superset ImageNet-21k(21k classes, 14M images), JFT(18k classes, 303M high resolution images)을 사용했다. benchmark로는 ImageNet의 original validation labels와 cleaned-up Real labels, CIFAR-10/100, Oxford-IIIT Pets, Oxford Flowers-102를 사용했다. 
  • Model Variants : ViT의 configuration는 BERT를 기반으로 했다. patch size가 작아질 수 록 연산은 expensive 해진다. (token이 많다고 생각하면 됨) CNN의 baseline으로는 ResNet을 사용했지만, Batch Normalizaation layer를 Group Normalization으로 대체했다.

[SOTA와 비교]

  • 특정 모델에서 ImageNet의 SOTA인 NoisyStudent보다 좋은 성능을 보여준다. 

 

Conclusion

  • image recognition에 Transformer를 사용해 보았다.
  • 과거 computer vision에서의 self-attention 구조와 다르게, image-specific inductive biases를 구조에 넣지 않았다. 
  • 대신에, 이미지를 patch들의 sequence로 다뤄, NLP처럼 처리했다. 
  • scalable 하고, large dataset에서 pre-training 했을 때, 잘 working 하여, ViT는 pre-trained에 많은 cost를 쓰지 않고도, SOTA image classification에 버금가는 성능을 보여주었다. 
  • 아직, 나아갈 길이 많다. (detection이나 segmentation 적용 등)

 

Reference

Dosovitskiy, Alexey, et al. "140 Thomas Unterthiner, Mostafa Dehghani, Matthias Minderer, Georg Heigold, Sylvain Gelly, 141 Jakob Uszkoreit, and Neil Houlsby. An image is worth 16x16 words: Transformers for image 142 recognition at scale." ICLR 3 (2021): 143.
 

총평

  • NLP 분야에서 혁신을 이뤄낸, transformer를 vision 분야에 도입하여 성능을 낸 게, 지금 시점에서는 당연해 보이지만, 이 도입을 위해 얼마나 고민하고, 실험했을지 싶다.
  • NLP처럼 transformer를 시작으로, GPT, BERT 등으로 이어지는 거대 모델의 흐름이 vision에도 적용될 것인지 살펴봐야겠다.
반응형

💬 한국어 텍스트 데이터 전처리

  • 텍스트 데이터는 보통 그 자체로 사용하기보다, 의미의 단위로 나눠서 활용 여부나 사이 연관 관계를 찾는다.
  • 저번 장에서 확인한 대로, 데이터셋의 텍스트 데이터는 한국어 문장으로 구성되어 있다.
  • 학습할 때마다 한국어 형태소 분리를 실행해도 되지만, 시간이 너무 많이 걸려서, 텍스트 데이터를 전처리 해놓기로 한다. 

한국어 텍스트 데이터 전처리 방법

  • 텍스트 데이터의 전처리 단계는 다음과 같다.
1. 텍스트 데이터를 형태소 단위로 분리한다.
2. 분리된 데이터 중, 불용어를 제거한다. (Optional)
3. 동의어를 mapping 할 수 있다면, 동의어를 mapping한다. (Optional)
4. word dictionary를 생성
5. word를 정수 인코딩한다.

1. 한국어 형태소 분리 (Tokenization)

  • 한국어의 경우에는 영어와 달리, 의미의 단위가 띄어쓰기와 정확히 일치하지 않는다.
  • 과거부터 한국어 형태소 분리가 연구되어 여러 방법들이 존재한다.
  • 파이썬은 "konlpy" 라이브러리에서 다양한 형태소 분석기를 제공한다. (자세한 내용은 https://konlpy.org/ko/latest/index.html 참조)
  • konlpy에서는 다양한 형태소 분석기를 제공해 주지만, 그중 "Okt"(Twitter에서 개발한 오픈소스 한국어 처리기)를 사용하여 한국어 형태소 분리 처리를 하기로 한다. (선택한 이유는 속도 때문이다.)
처리 전 처리 후
"아버지가 방에 들어가신다."  ["아버지","가","방","에","들어가신다","."]

2. 불용어 처리

  • 불용어(Stopword)는 분석에 필요하지 않거나, 분석 결과에 영향을 미치는 단어를 말한다. (예시: 은,는,이,가)
  • 자연어 처리에서는 불용어 제거가 매우 중요하다. 불용어는 실제 분석에는 이용되지 않지만, 일반적으로 문장에서 등장하는 빈도수가 높아져서, 해당 단어들이 중요한 단어로 인식될 수가 있다. 
  • 또한, 불용어 제거는 전처리 과정에서 처리할 텍스트 데이터의 양이 줄어서 처리 속도 향상을 위해 꼭 필요하다. 
  • 다만, 불용어는 분석의 목적에 따라 달라지는 상대적인 개념이기 때문에, 분석에 영향을 미치지 않는 단어만 넣도록 한다. 예를 들어, 일반적으로 '?'는 Elastic Search 등의 텍스트 검색을 위한 처리에서 불용어 처리가 될 수 있지만, 우리가 다루고자 하는 비윤리적 텍스트 검출에서는 상대를 비꼬는 문장을 찾을 수 있는 중요한 단서가 되기도 한다. 
  • 일반적으로 특수문자는 문장에서 제거한 후에, 한국어 형태소 분리하지만, 해당 Task에서는 특수문자가 분류에 많이 사용될 것으로 생각되어서, 실제 사용되지 않을 것으로 보이는 특수문자만 불용어로 처리하였다.  
불용어 예시 : 

stopwords = ['','','','','','','','','','','으로','','하다','!','?','<','>','(',')','[',']','|','#','.']

3. 동의어 처리

  • 동의어 처리는 일반적으로 텍스트 검색 기능에서 유사한 단어를 찾기 위해 자주 사용된다. 
  • 비윤리적 텍스트 문장 검출 데이터셋에서는 일반적인 단어를 특수문자나 축약어로 표현해 놓은 데이터가 많다. (예시: ㅇㅋ, Ok, 오키, 옿키)
  • 좋은 성능의 검출 모델을 만들기 위해서 동의어 처리도 매우 중요할 것으로 생각되지만, 현실적으로 공수가 너무 많이 소요되어, 별도의 동의어 처리는 하지 않았다. 

4. Word Dictionary 생성 

  • 학습 데이터셋을 형태소 분리하고, 불용어와 동의어 처리까지 처리한 후, 학습 데이터를 기반으로 워드 딕셔너리를 생성한다.
  • 실사용 시, Word Dictionary에 포함되지 않는 단어가 등장했을 경우에는 모델은 해당 단어에 대한 정보를 사용할 수 없다. (자연어 처리 시, 다양하고 풍부한 학습 데이터가 필요한 이유이기도 하다.) 
  • 각 단어에 대한 고유의 번호를 지정한다. 
  • 모든 단어를 사용하는 것이 다양성 측면에서는 좋겠지만, 속도나 성능을 고려하면, word dictionary의 크기를 무작정 늘리는 것은 좋지 않다. (일반적으로 최대 단어 개수를 지정한다. )
  • 정수 인코딩과 모델 테스트 시 빠른 사용을 위해, 인덱싱(key: 숫자, value: word)과 역인덱싱(key: word, value: 숫자)을 모두 진행해 놓는 것이 좋다.  
문장 형태소 분리 Word Dictionary 인덱싱
"아버지가 방에 들어가신다." ["아버지","가","방","에","들어가신다","."]  {<unk>:0,<pad>:1,"아버지":2, "방":3, "들어가신다":4} {'0':<unk>,'1':<pad>,'2': "아버지", '3':"방", '4':"들어가신다"}

5. 텍스트의 Word를 정수 인코딩

  • 모델의 학습을 위해, 텍스트를 정수로 인코딩해주는 작업이 필요하다. 
  • Word Dictionary를 기반으로 학습 데이터의 각 단어들을 정수로 변환한다.
  • Word Dictionary에 포함되지 않은 불용어 등은 "<unk>"라는 wildcard로 치환한다. 이를 통해, 모델이 입력받는 word 데이터의 종류는 Word Dictionary에 존재하는 단어 개수로 제한된다. 
  • 정수 인코딩을 진행하면, 문장마다의 인코딩 벡터의 길이는 전부 다르다. 학습을 위해 데이터를 정형화하는 편이 좋기 때문에, 인코딩 벡터의 끝부분에 "<pad>"값을 넣어, 벡터의 길이를 모두 같게 만들어준다. 
처리 전 처리 후
"아버지가 방에 들어가신다."  2,0,3,0,4,0,1,1,1,1

 

데이터 전처리 코드 구현

  • 전처리 과정을 사전에 진행해 놓기 위한, 코드를 구현하였다. 다만, 학습과 테스트 시 코드 통일성을 위해, 정수 인코딩 부분은 모델 데이터셋 정의 과정에 넣었다. (테스트 데이터도 정수 인코딩은 진행해야 하기 때문에, Dataset 구성 파트에서 설명 예정)
  • 자연어 Dataset 처리를 용이하게 하기 위해, "torchtext"라는 pytorch에서 제공해 주는 자연어 처리용 패키지를 사용하였다. (하지만, pytorch는 데이터셋의 종류에 따른 전처리를 모두 통일하기 위해 현재는 torch를 사용하도록 권장하고 있다. )
  • Okt가 빠르긴 하지만, 처리 데이터가 많기 때문에 전처리에 시간이 많이 소요된다. 
  • 데이터 전처리 단계를 대략적으로 구성하였지만, 실사용에서는 불용어 지정이나 어느 종류의 형태소 분석기를 사용할 것인지, word dictionary를 어떻게 구성할 것인지 등이 성능을 결정하는 매우 중요한 단계이다. 
from konlpy.tag import *
from torchtext import data 
import json

import pandas as pd

tokenizer = Okt()
stopwords = ['의','가','에','들','는','잘','걍','과','도','를','으로','한','하다','!','?','<','>','(',')','[',']','|','#','.']

# 텍스트 전처리 함수
def norm_morphs(x):
    x = tokenizer.normalize(x) # 텍스트 Normalization
    x = tokenizer.morphs(x) # 형태소 분리
    x = [word for word in x if not word in stopwords] #불용어 처리
    return x


if __name__ =='__main__':
    # 데이터셋 위치 지정
    data_dir = r"..\korean_language\data"

    # ID: 문서의 번호, TEXT: 문장 데이터(전처리 함수를 지정할 수 있음), LABEL: 윤리성 유무를 나타내는 LABEL 
    ID = data.Field(sequential=False, use_vocab=False)
    TEXT = data.Field(sequential=True, use_vocab=True, tokenize = norm_morphs, batch_first=True, tokenizer_language='ko')
    LABEL = data.Field(sequential=False, use_vocab=False, is_target=True)

    # Torch Text의 splits를 이용해서, 데이터를 한번에 불러올 수 있다. 
    train_data, test_data = data.TabularDataset.splits(path=data_dir, train='train', test='test', format='tsv', fields=[('id',ID), ('label',LABEL),('temp1',None),('temp2',None),('temp3',None),('text',TEXT)], skip_header=True)

    # word dictionary를 만듬 (최대 크기와, 최소 빈도수를 지정)
    TEXT.build_vocab(train_data, min_freq=2, max_size=100000)

    # word dictionary를 저장
    with open('./dictionary.json','w') as f:
        json.dump(TEXT.vocab.stoi, f, ensure_ascii=False, indent=4)

    # Index dictionary를 저장 
    index_dict = {v: k for k, v in TEXT.vocab.stoi.items()}
    with open('./index_dictionary.json','w') as f:
        json.dump(index_dict, f, ensure_ascii=False, indent=4)


    id_list = []
    text_list = []
    label_list = []
    df = pd.DataFrame()

    for id, data_dict in enumerate(train_data):
        id_list.append(id)
        text_list.append('|'.join(data_dict.text))
        label_list.append(data_dict.label)

    df['id'] = id_list
    df['text'] = text_list
    df['label'] = label_list
    df.to_csv('train.csv', index=False,sep = '#')

    id_list = []
    text_list = []
    label_list = []
    df = pd.DataFrame()

    for id, data_dict in enumerate(test_data):
        id_list.append(id)
        text_list.append('|'.join(data_dict.text))
        label_list.append(data_dict.label)

    df['id'] = id_list
    df['text'] = text_list
    df['label'] = label_list

    df.to_csv('test.csv', index=False,sep = '#')


    print("Train Data :",len(train_data))
    print("Test Data :",len(test_data))

 

전처리를 진행하였으니, Dataset을 정의하고, 모델을 만들어볼 차례이다!

반응형

AI가 연구의 영역에서 실용 영역으로 침투하기 시작하면서, AI로 구성된 서비스를 어떻게 잘 제공할 것인지에 대한 수요가 높아지고 있다. 특히, chat-gpt로 AI 영역에서 엔지니어링의 중요성이 대두된 만큼, AI 서비스의 수집부터, 제공까지의 워크플로우를 어떻게 관리할 것인지에 대한 관심이 높아졌다. Kubeflow는 이런 상황 속에서 등장하고 발전했다. (처음 등장한 지는 조금 오래됐다 - 2018년)


ML workflow 란?

  • Kubeflow를 알기 위해서는 ML workflow를 이해할 필요가 있다. ML workflow는 머신러닝 알고리즘을 개발하고, 이를 통해 만든 서비스를 배포하기까지의 일련의 과정들을 모두 포함한다. (사실, 머신러닝 & 딥러닝을 구분해야하지만, 해당 글에서는 머신러닝으로 줄여서 이야기한다.)
  •  일반적으로 ML workflow는 다음과 같은 단계로 나뉜다. 
    1. 데이터 수집 : DB or Online 등에서 데이터를 수집한다.
    2. 데이터 검증 : 수집한 데이터를 검증한다.
    3. 데이터 전처리 : 수집한 데이터에서 노이즈 제거 & 결측치 대체 & 스케일링, Normalization & Augmentation 등을 수행한다.
    4. 모델 학습 : 머신러닝 알고리즘을 선택하고, 전처리된 데이터를 사용하여 모델을 학습한다. 
    5. 배포 : 모델을 실제 운영 환경에 배포하고 사용한다.

 

Kubeflow 란?

  • Kubeflow의 시작은 구글에서 머신러닝에 사용되는 리소스를 효율적으로 관리하기 위해, Tensorflow Extended(TFX)을 사용하면서 처음으로 시작되었다. 후에 여러 개발자들이 모여서, 오픈소스 프로젝트로 공개되었다. 
  • Kubeflow는 이름에서 알 수 있듯, Kubernetes에서 동작하는 ML 워크플로우 툴이다. Kubernetes는 머신러닝 Job에 굉장히 적합한 플랫폼인데, 이유는 다음과 같다.  
    • 머신러닝의 학습 및 배포에는 다른 서비스에 비해, 리소스 자원의 활용이 크다. 따라서, 리소스를 어떻게 잘 컨트롤하여, 학습하고 배포할 것인지가 중요하다. → Kubernetes의 유연성 컨트롤
    • 머신러닝 & 딥러닝은 환경 구축이 H/W나 OS, 라이브러리 버전 등에 따라 다 다르다. (머신러닝, 딥러닝 학습을 해본 사람들이면, 환경 구축에 정말 많은 시간이 소요된다는 것을 알 수 있을 것이다.) Kubernetes의 장점인 확장성 & 유연성
  • Kubeflow는 그 자체가 새로운 서비스라기보다는, Kubernetes 플랫폼 위에서 동작하기 위한, ML workflow에 필요한 여러 오픈소스 툴들을 모아놓은 것이다.
  • 내가 생각하는 Kubeflow의 가장 큰 장점은, 서비스 구성 및 엔지니어링등에 상대적으로 약한 AI researcher들의 부담을 줄여주는 것이라고 생각한다. (운영단에 제공하는 서비스가 아니라면, Kubeflow의 필요성은 조금 약하다고 생각한다. 다만, Kubernetes 환경에서 모델을 학습하는 경우에는 쓰지 않을 이유가 없다.)

 

Kubeflow의 구조

  • 아래 그림은 Kuberflow 홈페이지에 있는 Kuberflow 아키텍처에 대한 Conceptual Overview이다. 
  • 맨 아래, 어떤 플랫폼에서든 Kubernetes를 활용할 수 있다는 것을 강조하고, 그 위에 Kubeflow가 올라가 있다는 것을 보여준다.
  • 즉, Kubernetes 환경 위에서 여러 ML workflow component 들을 묶어서, Kubeflow로 제공해 주고, 그 위에 Pytorch나 Tensorflow등 다양한 언어를 활용해서 Kubeflow를 운영할 수 있다는 것을 강조하고 있다.
  • 그림의 우측에 Istio(트래픽 관리, 보안 등), Argo(워크플로우 관리), Prometheus(모니터링), Spartakus(사용자 데이터 수집) 등을 함께 활용하여, 운영 환경의 안정성을 높일 수 있다는 것을 보여준다.

Kubeflow 아키텍쳐 (출처 : https://www.kubeflow.org/docs/started/architecture/)

 
 

Kubeflow의 Component

  • Kubeflow는 여러 ML workflow 툴들의 집합이라고 위에서 소개했다. 어떤 것이 있는지 알아보자.
  • 우선, ML workflow를 크게 2개로 분류할 수 있다. 알맞는 모델을 찾기 위한 실험 단계와, 선택된 모델을 가지고 서비스를 운영하는 단계이다.
  • 실험 단계에서는 다음과 같은 Component 들을 제공한다.
    • Jupyter Notebook : Kubernetes 위에서 Jupyter Notebook을 사용해서, 모델을 개발 & 실험해볼 수 있게 해준다. 
    • Fairing : 모델의 생성 & 학습 & 배포등을 Kubernetes Cluster로 쉽게 요청할 수 있게 해준다. (즉, 모델을 Docker Image 형태로 Kubernetes에 뿌려준다.)
    • Katlib : 하이퍼파라미터 최적화 & 뉴럴 아키텍쳐 탐색을 지원함. (각기 다른, 하이퍼파라미터와 아키텍쳐를 설정해서, 원하는 결과가 나올때까지 실험해 볼 수 있음)
  • 운영 단계에서는 다음과 같은 Component들을 제한다.
    • Pipelines : ML workflow(수집 & 검증 & 전처리 & 학습 & 배포)를 end-to-end로 만들어 주는 툴 (Argo를 사용한다.)
    • Metadata : Kubeflow Pipelines에서 실행되는 ML workflow에 대한 metadata를 관리하는 서비스
    • KFServing : Kubernetes 위에서 머신러닝 서빙(Serving)을 위해 사용하는 툴
    • TensorRT : 미리 학습된 모델의 정확도를 유지하면서, Inference 속도를 최적화해주는 툴
    • Pytorch : 파이토치
    • TFServing : Tensorflow 모델의 서빙(Serving)을 위해 사용하는 툴
    • Seldon : 머신러닝 모델의 배포 및 관리를 위한 툴
    • Tensorboard : 머신러닝 모델 디버깅 & 시각화 툴

Kubeflow의 Component들 (출처: https://www.kubeflow.org/docs/started/architecture/)

 

Kubeflow의 UI

  • Kubeflow는 Command 명령어로 구동 가능하다. 하지만, Command 명령어로 Kubeflow 내에 있는 기능을 각각 사용할 것이라면, Kubeflow를 사용하는 의미(통합성 & 편의성 등...)가 덜하다고 생각한다.
  • Kubeflow의 UI는 편하면서, 불편하다. 메뉴에 있는 각 Component들을 각각 사용하기에는 편한데, 그 사이에 어떠한 연관성이 있는지 등등은 드러나지 않는다. (어느 메뉴들은 같이 사용해야하고, 어느 메뉴는 독립적이고...)
  • Kuberflow는 "Central Dashboard"라는 UI를 통해, 각 component를 쉽게 접근 할 수 있도록 해준다.  
    • Home: Home이다. 
    • Notebook Servers: Jupyter Notebook 서버를 사용할 수 있게 해준다. 
    • TensorBoards: Tensorboard를 쉽게 사용 할 수 있게해준다.
    • Models: 배포된 KFServing 모델들을 관리한다.
    • Volumes: Cluster의 저장소를 관리한다.
    • Experiments (AutoML): Katlib(하이퍼파라미터 튜닝 등)을 사용할 수 있게 해준다. 
    • Experiments (KFP): 실험용 Kuberflow Pipeline(KFP)을 사용할 수 있게 해준다. 
    • Pipelines: end-to-end Kuberflow Pipeline(KFP)을 사용할 수 있게 해준다. 
    • Runs: Kuberflow Pipeline(KFP)의 실행을 관리한다.
    • Recurring Runs: Kuberflow Pipeline(KFP)의 반복적 실행을 관리한다. 
    • Artifacts: Metadata를 확인 할 수 있게 해준다. 

Kubeflow Central Dashboard (출처 : https://www.kubeflow.org/docs/components/central-dash/overview/)

 


Kubeflow를 보면서, 느낀 것은 아직은 ML workflow의 end-to-end를 책임지기에는 역부족이지만, 앞으로 발전해 간다면 정말 유용하게 사용될 것 같다. 아무래도, 각 Component가 독립적으로 개발되어서, Component 간에 연결이 완벽하지 않다는 느낌을 자주 받았다. Component 간의 연결성이나, kubeflow 자체의 서비스 등을 제공한다면 더 좋을 것 같다. 우선, 다음 장부터 Kubeflow를 설치해 보기로 한다.  

반응형

💬 비윤리적 텍스트 검출 데이터셋 분석

  • 지난 장에서, '텍스트 윤리검증 데이터'의 train, validation, test 데이터의 양과 형태에 대해서 확인해보았다.
  • 이번 장에서는, 텍스트 데이터를 조금 더 자세하게 분석해보기로 한다.
  • 텍스트 데이터를 분석하는 것은 추후 불용어나, 텍스트 정수 인코딩에서 빈도수 제한을 거는 등에 활용되어, 더 좋은 모델을 만드는데 사용될 수 있다.

  • 텍스트의 윤리검증 기준은 사람마다 다르다. 데이터셋을 구성한 명확한 기준을 알 수 없기에, 우선 데이터셋으로 구성된 비윤리적 텍스트들에는 어떠한 공통점이 있는지 확인해보면 좋을 것이다.

 

data_dir = r"{설치위치}\data\val"
df = pd.read_csv(data_dir, sep='\t', header=None)
df_true = df[df[1]==True]

우선, validation 데이터 파일을 다시 불러온다.(train 데이터의 텍스트를 분석하는 것이 더 좋겠지만, 너무 양이 많아서 오래 걸린다.

 

from konlpy.tag import Hannanum

word_parser = Hannanum()

text_list = list(df_true[5].values)
word_list = []

for text in text_list:
    word_list += word_parser.morphs(text)

 

"Hannanum"이라는 한국어 형태소 분석기를 통해, 데이터셋에 존재하는 text들을 parsing할 것이다. 형태소 분석을 하는 이유는, 형태소 단위로 의미있는 형용사나 명사를 추출하기 위함이다. 

위의 코드에서 "비윤리적" 텍스트들을 형태소 단위로 parsing하여 "word_list"에 넣어주었다. 

 

"word_list"에는 "비윤리적" 텍스트들이 list 형태로 들어가있다. 그중 여러 텍스트들에서 공통되는 단어들은 중복으로 들어가 있을 것이다. 우리는 어느 단어가 많이 등장하는지를 확인하기 위해, "Counter" 함수를 사용할 것이다.

 

from collections import Counter

c = Counter(word_list)
c_dict = dict(c)
c_dict = sorted(c_dict.items(), reverse=True, key=lambda item: item[1])

"word_list"를 "Counter" 함수를 통해 각 단어의 빈도수를 구했고, "sorted" 함수를 통해, 빈도수대로 정렬하였다.

 

비윤리적 텍스트 데이터 단어 빈도수

 

빈도수를 확인해보면, '이','하','는' 등등 "비윤리적" 텍스트들의 특징이라기보다는 한국어 텍스트 데이터들에서 공통으로 찾아볼 수 있는 단어들이 많이 등장하는 것을 볼 수 있다.

 

보통 검색엔진 등에서는 index 구성 시, stopword(불용어)라는 단계를 추가하여 이러한 데이터들을 제거하는데, 우리는 아직 데이터 분석 단계니, 해당 과정을 거치지 않는다. 

 

한 글자로는공통되는 단어가 직관적으로 파악되지 않아, 2글자 이상의 글자만 다시 확인해본다.  

 

word_list = [word for word in word_list if len(word)>1]

c = Counter(word_list)
c_dict = dict(c)
c_dict = sorted(c_dict.items(), 
                              reverse=True, 
                              key=lambda item: item[1])

2글자 이상에서 다시 확인해보니, 의미 있는 단어들이나, 이해가는 단어들이 등장하기 시작하였다. 

 

마찬가지로, 3글자 이상도 추출해본다. 

한 눈에 봐도, 비윤리적으로 보이는 단어들도 다수 등장한다.

 

해당 과정을 반복하면, 단어의 길이가 길수록 빈도수는 적지만, 단어 그 자체로 좋지 않은 의미를 담고 있는 단어들이 많다는 것을 확인 할 수 있다.

 

추후에 word를 정수로 인코딩하는 과정이 들어가는데, word_list에 존재하는 frequency에 따라 해당 단어를 정수로 encoding 할 것인지, 모르는 단어로 놔둘 것인지 설정할 수 있다.

 

이 단계에서 encoding 단계에서 매우 낮은 frequency 기준을 잡아야겠다는 생각을 할 수 있다.

 

 

사실, 이 단계에서 끝내도 되지만, 이왕한 김에 빈도를 wordcloud로 확인해보기로한다. 

 

from wordcloud import WordCloud
import matplotlib.pyplot as plt

wc = WordCloud(font_path='malgun', width=400, height=400, scale=2.0, max_font_size=250)
gen = wc.generate_from_frequencies(c)
plt.figure()
plt.imshow(gen)

 

 

2글자 이상의 데이터를 wordcloud 한 결과는 다음과 같다. (2글자까지는 그나마, 모자이크가 필요없다.)

 

윤리적 데이터에 대해서도 wordcloud를 만들어본다. 

내가 평소에 많이하는 '아니', '어서', '진짜' 같은 단어 들이 많다. 

 

데이터들을 직접 살펴보면서 분석의 방향을 잡은 것은 다음과 같다.

1. 윤리적 기준이 사람마다 달라서 단순 단어의 유무로 판단하는 것은 문제가 있다. (문맥을 파악해야할 것 같다.)
2. 글자 하나가 있냐 없냐에 따라, 의미가 완전히 달라져서 불용어를 최대한 조심해서 사용해야할 것 같다.
3. 긴 단어일수록, 데이터셋 내에서 빈도수는 적지만, 그 단어 하나가 판정에 powerful한 역할을 할 것 같다.
4. 데이터셋의 비윤리적 텍스트와 윤리적 텍스트의 양에 어느 정도 차이가 있다.  (Class Imbalance가 일어날 정도는 아닌 것 같은데, 추후 확장을 생각했을 때 고려해야한다.)
5. 윤리적/비윤리적 데이터의 소스가 비슷해서 그런지 서로 겹치는 단어들이 너무 많다. 추후 확장성을 생각한다면 윤리적 데이터를 추가적으로 더해서 학습해야할 것 같다. 
6. 형태소 분석에 시간이 꽤나 오래 걸려서, 미리 전처리를 해놔야겠다. 

 

지금까지 데이터를 분석해보았다. 다음 장부터, 본격적으로 데이터 모델을 만들고 처리하는 과정을 담도록 하겠다.

반응형

💬 자연어처리(NLP) 모델 만들기


💎 배경

  • 요즘 ChatGPT가 대세다. 석사 과정때는 이미지 처리 중심으로 연구를 진행했어서, 자연어처리에 관련해서 공부를 해보고 싶다는 생각이 들어 자연어처리의 초기 모델부터 현재 ChatGPT까지 흐름을 직접 코드를 짜보면서 이해해보고자 한다.

데이터셋 준비

  • 기본적으로 딥러닝 모델을 만들때, 가장 중요한 것은 “어떤 데이터를 처리하고자 하는가?”이다. 이왕 공부하는 김에 재밌는 데이터를 처리하고 싶어서, 자연어 처리에 필요한 데이터를 뒤져보았다.
  • 내가 선택한 데이터는 한국지능정보사회진흥원에서 운영하는 “AI Hub”에서 다운로드 받을 수 있는 “_텍스트 윤리검증 데이터_”이다. (내국인은 로그인 후, 다운 받을 수 있다)

  • 해당 데이터는 인터넷 상에서 윤리적인 데이터와 비윤리적인 데이터를 구분하기 위해 구축된 데이터로 451,110 문장을 대상으로 하였다고한다.
  • 구축 및 갱신 년도가 나름 최근이여서, 데이터셋을 확인해보았을때, 현재 인터넷에서 난무하는 밈들이나 악플들을 담고 있다. (심신이 약하면 데이터셋을 직접 눈으로 확인안하는 것을 추천한다... 정말 나쁜 글들이 많다.)
  • 해당 데이터를 선택한 이유는 다음과 같다.

① 데이터 및 만들고자 하는 모델이 흥미롭다. (실제로 필요하다고 생각이 들기도하고, 최신 데이터라 그런지 고전 데이터셋 특유의 정적인 맛이 덜해서 좋았다.)
② 데이터가 무겁지 않다.
③ 풀고자 하는 문제가 명확하다. (윤리 VS 비윤리)
④ 참과 거짓 간의 기준이 모호하다
→ 윤리와 비윤리의 정의는 사람마다 기준이 다르기 때문에 그 경계선이 모호하다. 예를들어, "이거 진짜 골때린다"라는 문장이 있을때, 이 문장은 윤리적일까 비윤리적일까? 이렇게 Class간 모호한 기준이 있는 데이터들은 오히려 학습 모델과 학습 방법에 따른 효과를 더 드라마틱하게 확인 가능하고, 추후 개선 아이디어도 만들기 좋다.

 

  • 데이터셋 설치 방법은 다음과 같다.

1. Raw 데이터를 다운 받는다. 

Raw 데이터 다운로드

 

2. 아래로 내려서, 데이터에 대한 전체적인 소개를 읽어본 후, 아래의 AI 샘플코드를 받는다.

(윤리 검증 이진 분류 학습용으로 전처리된 데이터를 포함)

전처리된 데이터 다운로드

 

데이터에 대한 상세한 설명은 다음 장에 진행하도록한다...

 

개발 환경 셋팅

  • Anaconda 환경에서 가상환경을 신규로 구축한 뒤, pypi를 이용하여 몇개의 라이브러리를 설치해준다.
pip install torch   
pip install torchtext==0.6.0
pip install konlpy
pip install pandas
  • torch : 딥러닝 도구 pytorch (CUDA 환경인 경우 홈페이지 설치 추천합니다)
  • torchtext : 자연어처리 분야에서 torch 활용을 쉽게 할 수 있도록 만들어진 라이브러리, 추후 데이터 loader 작성 시 쉽게 활용하기 위해 설치함. torchtext는 버전 0.6.0을 추천함. (이유는 추후에 별도로 설명할 계획)
  • konlpy : 한국어 정보처리를 위한 파이썬 라이브러리, 추후 한국어 형태소 분석에 필요한 모듈들을 사용할 계획임.
  • pandas : 데이터를 분석 조작하기 위해, 쉽게 만들어진 파이썬 라이브러리, 데이터 전처리 과정을 용이하게 진행하기 위해 활용할 계획임.

데이터와 개발 환경 셋팅이 모두 마무리되었다면, 다음 장에서 데이터 전처리를 해보자!

+ Recent posts