1. LeNet-5란?

LeNet-5은 1998년에 개발된 초기 CNN 구조로, 이후 딥러닝의 기반을 마련한 모델이라고 할 수 있다.

LeNet-5 구조


2. 각 Layer 살펴보기

(1) Input Layer (입력층) 

LeNet-5의 입력은 32x32 크기의 흑백 이미지이다. Input 이미지는 0과 1 사이의 값으로 정규화된다.

(2) C1 Layer (Convolution)

LeNet-5는 두 개의 Convolution Layer을 가지고 있는데, 첫 번째 Convolution layer는 6개의 5x5 크기의 필터를 사용한다. 합성곱 연산 결과 6장의 28x28 feature map을 얻게 된다. 활성화 함수는 sigmoid 함수를 사용한다.

(3) S2 Layer (Subsampling)

Convolution layer 이후 평균 풀링을 진행한다. 2x2 window와 stride 2를 사용하여 feature map이 반으로 줄어든다. 즉, 결과적으로 6장의 14x14 feature map을 얻게 된다.

(4) C3 Layer (Convolution)

두번째 Convolution layer는 첫 번째 합성곱 레이어와 유사한 구조를 가지고 있지만, feature map의 깊이가 6에서 16으로 증가한다. 이 층에서도 활성화 함수는 sigmoid 함수를 사용한다. 

(5) S4 Layer (Subsampling)

첫 번째 평균 풀링 layer와 마찬가지로 2x2 window와 stride 2를 사용하여 입력 이미지의 공간 해상도를 다시 줄입니다. 

(6) C5 Layer (Convolution)

16장의 5 x 5 특성맵을 120개의 5 x 5 x 16 사이즈의 필터와 합성곱 연산을 진행한다. 결과적으로 120개의 1 x 1 feature map이 나온다.

(7) F6 (Fully Connected Layer)

이제 입력 이미지는 Fully Connected Layer로 전달된다. 이 layer는 86개의 뉴런으로 구성되어 있으며, 이전 layer의 모든 feature map과 연결된다. Fully Connected Layer는 입력에 대한 weight 합과 bias을 계산하고, sigmoid 활성화 함수를 사용한다.

(8) Output Layer (출력층)

LeNet-5의 출력층은 10개의 뉴런으로 구성되어 있다. 이 레이어는 입력 이미지가 0부터 9까지의 숫자를 나타내는 확률 분포로 매핑되도록 설계되었다. 출력 뉴런 중 가장 높은 값을 가진 뉴런이 모델의 예측 결과로 사용되는 것이다.


3. Tensorflow 코드 구현하기

(1) 필요 라이브러리 가져오기

import numpy as np
import tensorflow as tf
import tensorflow.keras.datasets as ds

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D,MaxPooling2D,Flatten,Dropout,Dense
from tensorflow.keras.optimizers import Adam

(2) 데이터셋 전처리 

(x_train,y_train),(x_test,y_test)=ds.mnist.load_data()
x_train=x_train.reshape(60000,28,28,1) # 60000개의 데이터 -> 28x28x1 (grayscale)
x_test=x_test.reshape(10000,28,28,1) # 10000개의 데이터 -> 28x28x1 (grayscale)

x_train=x_train.astype(np.float32)/255.0 # 0~255의 픽셀 값 -> 0~1 사이의 값으로 정규화
x_test=x_test.astype(np.float32)/255.0

y_train=tf.keras.utils.to_categorical(y_train,10) # 0~9 값을 원핫 코드로 변환
y_test=tf.keras.utils.to_categorical(y_test,10)

(3) 층 쌓기

cnn=Sequential()
# C1 : 6개 5x5 filter, zero padding -> output_shape = (28, 28, 6)
cnn.add(Conv2D(6,(5,5),padding='same',activation='relu',input_shape=(28,28,1)))

# S2 : 2x2 filter, stride = 2 -> output_shape = (14, 14, 6)
cnn.add(MaxPooling2D(pool_size=(2,2),strides=2))

# C3 : 16개 5x5 filter, padding 안함 -> output_shape = (10, 10, 16)
cnn.add(Conv2D(16,(5,5),padding='valid',activation='relu'))

# S4  : 2x2 filter, stride = 2 -> output_shape = (5, 5, 16)
cnn.add(MaxPooling2D(pool_size=(2,2),strides=2))

# C5 : 120개 5x5 filter, padding 안함 -> output_shape = (1, 1, 120)
cnn.add(Conv2D(120,(5,5),padding='valid',activation='relu'))

# 120
cnn.add(Flatten())

# 120 -> 84
cnn.add(Dense(units=84,activation='relu'))

# 84 -> 10
cnn.add(Dense(units=10,activation='softmax'))

(4) 학습, 정확도 계산

cnn.compile(loss='categorical_crossentropy',optimizer=Adam(learning_rate=0.001),metrics=['accuracy'])
cnn.fit(x_train,y_train,batch_size=128,epochs=50,validation_data=(x_test,y_test),verbose=2)

res=cnn.evaluate(x_test,y_test,verbose=0)
print('accuracy=',res[1]*100)

 

반응형
SMALL

이번 포스팅에서는 딥러닝 모델의 연속 학습(Continual Learning)에 대하여 다뤄보고자 한다.

연속 학습(Continual Learning)이란?

인공지능의 연속학습(Continual Learning)이란 딥러닝 모델이 새로운 데이터를 기반으로 지속적으로 학습하는 방법을 말한다. 일반적인 딥러닝 모델은 큰 규모의 데이터셋으로 학습하고, 해당 데이터셋을 기반으로 일반화된 패턴을 학습한다. 그러나 실제 환경에서는 새로운 데이터가 지속적으로 발생하고, 이는 기존의 데이터와는 다를 가능성이 높다. 연속학습은 이러한 기존 딥러닝의 문제점을 보완하고자 새로운 데이터에 대해 지속적으로 학습하고, 학습한 지식을 점진적으로 확장해나간다. 

이 사진에서 보다시피 데이터는 연구의 방향이나 시장의 수요에 따라서 클래스가 분화된다. 클래스가 점차 분화되고 새로운 클래스가 등장함에 따라 새로운 데이터에 대해 지속적으로 학습할 수 있는 인공지능 모델이 필요해지게 된 것이다. 새로운 데이터가 나올 때마다 처음부터 다시 훈련시키는 것 보다는, 이미 학습된 모델에 새로운 데이터만 추가하는게 더 효율적이고 경제적이라고 할 수 있기 때문이다.

연속 학습의 가장 큰 문제점 : Catastrophic Forgetting

이 연속학습의 가장 큰 문제점은 바로 이 치명적 망각(Catastrophic Forgetting)이다. 이를 이해하기 위해서 다음 그림을 살펴보자.

split-MNIST의 task들

위 사진은 바로 대표적인 데이터셋 중 하나인 MNIST 데이터셋을 5개의 task로 나눈 것이다. 첫 번째 task1에서는 0과 1을 구분하도록 모델을 학습시킨다. 그 다음, 이 학습된 모델에 2와 3을 구분하도록 또 다시 학습시킨다. 이런 방식으로 앞에서 학습된 모델에 연속적으로 새로운 task를 훈련시키면 가장 큰 문제점은 앞에서 훈련되었던 내용을 잊어버린다는 것이다. 8과 9를 구분하는 마지막 task5를 훈련시키고 나면, 가장 처음에 훈련되었던 0과 1을 분류하는 task1은 정확도가 상당히 낮아진다. 즉, 점진적으로 모델을 학습해감에 따라 앞에서 학습되었던 내용을 점차 잊어버리는 것이다. 이를 연속학습에서는 치명적 망각(Catastrophic forgetting)이라고 부르며, 이를 해결하는 것이 연속학습의 핵심이라고 할 수 있다.

연속 학습의 대표적인 방법

연속 학습 방법은 크게 Replay method, Regularization-based method, Parameter isolation method로 분류할 수 있다. 

연속 학습의 대표적인 Method

1. Replay method

Replay 방법은 이전 작업의 데이터를 저장하고, 새로운 task에 대한 학습에서 이전 데이터를 다시 사용하는 방식이다. 이전 데이터를 다시 사용하는 방식은 버퍼에 일부 데이터를 저장(real data replay)하거나 생성모델을 통해 데이터를 생성(pseudo replay)하여 사용하는 방식이 있다. 이 방식은 연속학습의 문제점이었던 Catastrophic Forgetting을 어느 정도는 해결할 수 있으나 이전의 데이터를 메모리에 넣어 주어야 하기 때문에 많은 양의 메모리 공간이 요구된다는 점, 실제로 순차적 학습을 할 때 다시 과거 데이터에 접근할 수 있다는 보장이 없다는 점에서 여전히 문제점이 존재한다.

Generative Replay(2017)

대표적인 Replay 방식으로는 Generative Replay가 있다. Generative Replay는 새로운 task를 학습할 때 생성모델을 통해 데이터를 생성하여 이전 데이터를 다시 사용하는 방식을 택한다.

Generative Replay의 구조

Generative Replay는 Generator와 Solver의 구조를 가지고 있다. Generator는 이전에 학습했던 데이터를 재생산하고 Solver는 이 재생산된 데이터와 진짜 데이터를 이용해 분류하는 역할을 하도록 학습된다. 이런 구조 전체를 Scholar라고 하고 각 task마다 Scholar의 구조를 순차적으로 학습한다. 

2. Regularization-based method

다음으로는 Regularization-based 방식이 있다. 이 방식은 모델의 파라미터를 조절하여 이전 작업에 대한 지식을 보존하는 방식이다. 즉, 모델의 성능에 영향을 주는 활성화 함수(activation function), 옵티마이저 (Optimizer), 학습률 (Learning Rate) 등의 파라미터의 impact를 계산하여 이전 작업의 중요한 impact를 주는 파라미터는 이후의 학습에서도 보호하겠다는 것이다. 

LwF(Learning Without Forgetting, 2017)

Regularization-based method의 대표적인 모델로는 LwF(Learning Without Forgetting, 2017)가 있다. LwF는 각 stage의 학습을 시작하기 전에 현재 stage의 모든 데이터에 대해 이전 stage에서 학습이 완료된 모델의 feed-forward logit(LwF-logit)을 미리 계산하고, 각 데이터의 label과 LwF-logit을 이번 stage 학습에 활용한다. Label은 새로운 학습을 위해 사용되고, LwF-logit은 과거의 데이터를 보존하는데 사용된다.

위 그림은 다른 multi-task learning method(b, c, d)와 LwF(e)를 비교해놓은 그림이다. 이 그림에서는 각 부분의 색깔을 잘 확인할 필요가 있다. 주황색은 random initialize + train, 하늘색은 fine-tune, 흰색은 unchanged를 의미한다. 따라서 무엇이 학습되었는지, 학습이 되지 않았는지를 구분할 수 있다. 하나씩 살펴보자.

  • (b) Fine-tuning : 네트워크의 backbone과 새로운 task에 대하여 학습시키는 방식이다. 이 방식의 문제점은 이전에 학습된 파라미터(그림의 하얀색 부분)의 guidance 없이 공유된 파라미터들을 업데이트 시키기 때문에 이전에 학습된 task의 성능을 저하시킨다는 것이다. 
  • (c) Feature Extraction : Fine-tuning과는 달리, 사전 학습된 네트워크의 backbone을 다시 학습하는 대신에, 새로운 task에 더 많은 layer을 추가하고 이 branch만 학습한다. backbone과 공유된 파라미터를 업데이트 시키지 않기 때문에, 새로운 task의 특징을 잘 표현하기에 성능이 떨어지는 경우가 많다.
  • (d) Joint Training : 이 방식은 새로운 task를 위한 새로운 브랜치를 추가하고 전체 네트워크를 다시 학습한다. 다시 말해서, 모든 task의 데이터를 동시에 함께 사용하여 학습한다는 것이다. 정확성 측면에서는 가장 효율적인 방법으로 보일 수 있다. 하지만 더 많은 task가 추가되면 점점 더 학습하는 데 번거로울 수 있으며, 이전 작업의 학습 데이터를 사용할 수 없는 상황에서는 적절하지 않을 수 있다는 문제점이 있다. 
  • (e) LwF : LwF 방식은 새로운 task를 위하여 branch를 추가하지만, 새로운 task에 대한 학습을 진행할 때에는 이전 task의 데이터를 사용하지 않는다. 대신 Knowledge Distillation(지식 증류) 기법을 사용하는데, 지식 증류는 큰 규모의 미리 trained된 모델(선생님)로부터 작은 모델(학생)로 지식을 전달하는 기법이다. LwF에서는 이전 task에서 학습된 모델을 "선생님"으로 정의하고, 새로운 task를 위해 학습 중인 모델을 "학생"으로 정의한다.

3. Parameter isolation method

이 방식은 용어 그대로 task 간의 파라미터를 분리하여 각 task의 파라미터를 독립적으로 학습하는 방식이다. 이를 통하여 task 간의 간섭을 줄이고 각 task에 대한 성능을 개별적으로 관리할 수 있다.

PNN(Progressive Neural Network, 2016)

three column progressive network.

첫 번째 column은 task1, 두 번째 column은 task 2에 학습되었다. 세 번째 column은 마지막 task를 위하여 이전에 학습된 모든 특성에 접근할 수 있도록 추가된 column이다. 이 모델은 task가 늘어날 때마다 column을 추가한다. 이전의 column들은 새로운 데이터에 학습되지 않고 고정된다. 이렇게 되면 새로운 task가 추가되더라도 이전의 파라미터는 변경되지 않으며 독립적으로 학습된다는 것이 특징이다.

반응형
SMALL

아래 사이트(Machine Learning For Kids)에서 정말 간단하게 챗봇을 위한 인공지능 모델을 구축하고 사용해 볼 수 있다. 앱 인벤터를 이용하면 이 챗봇을 간단하게 앱으로도 구현해 볼 수 있다. 플랫폼과 파이썬을 사용하여 간단한 인공지능 챗봇을 구축해보고자 한다. 

 

Machine Learning for Kids

An educational tool for teaching kids about machine learning, by letting them train a computer to recognise text, pictures, numbers, or sounds, and make things with it in Scratch.

machinelearningforkids.co.uk

 

챗봇(ChatBot)이란?

우선, 챗봇이 무엇인지부터 알아보자. 챗봇은 ChatterBot의 약자로서, 말 그대로 이야기를 주고받는 로봇을 의미한다.

챗봇은 크게 트랜잭션 챗봇대화형 챗봇으로 나눌 수 있다.

  1. 트랜잭션 챗봇 : 하나의 기능을 수행하거나 자동화하는 데 주력하는 단일 용도의 챗봇을 말한다. 예를 들어 레스토랑이나 택배 회사, 은행 등에서 간단한 질문에 답하거나 업무를 수행할 때 사용된다. 
  2. 대화형 챗봇 : 보다 개인 맞춤화된 상호 작용에 사용되는 챗봇을 말한다. 트랜잭션 챗봇처럼 단일 용도로 사용되는 것이 아니라 사용자와 상호작용하며 마치 사람과 대화를 하듯 답변하도록 설계된다. 대표적으로 ChatGPT가 있을 것이다. 

챗봇 구현하기

이제 실제 챗봇을 구현하기 위한 모델을 위 플랫폼을 사용하여 구축해보자. 여기서는 호텔 안내 서비스 챗봇을 만들어 볼 예정이다.

1. 프로젝트 만들기

가장 먼저 머신러닝 프로젝트를 만들어야 한다. 우측에 있는 프로젝트 추가 버튼을 클릭한다.

그다음, 프로젝트의 세부사항을 입력한다. 여기서는 호텔 안내 챗봇을 만들어볼 것이기 때문에 프로젝트 이름은 "Hotel", 인식은 "텍스트", 언어는 "Korean"으로 선택하였다.

2. 훈련

프로젝트를 생성하면 다음과 같은 페이지가 나온다. 모델을 훈련시키기 위하여 가장 좌측에 있는 [훈련] 버튼을 클릭하자.

[훈련] 버튼을 클릭하면 다음과 같은 페이지가 나온다. 여기서 우측에 있는 [새로운 레이블 추가] 버튼을 누르고 자신의 챗봇에 맞는 질문 레이블을 추가하면 된다. 여기서는 호텔 안내 서비스이기 때문에 총 6개의 레이블(reservation, facility, location, service, price, checkinout)을 추가하였다. 

그다음, 각 질문 레이블에 맞는 데이터를 추가한다. 데이터는 고객이 질문할 만한 질문 데이터들을 입력해 주면 된다. 한 레이블당 약 7개 정도의 데이터를 추가하였다. 데이터는 당연히 많을수록 좋다. 

3. 학습 & 평가

이제 좌측 상단에 있는 [프로젝트로 돌아가기] 버튼을 누른 후, 학습&평가 버튼을 클릭하면 다음과 같은 화면이 나온다. 하단에 있는 [새로운 머신러닝 모델을 훈련시켜 보세요] 버튼을 클릭하자.

잘 학습이 완료되면 다음과 같은 페이지가 나온다. 모델이 잘 학습되었는지 간단하게 문자를 넣어 테스트도 해볼 수 있다.

간단하게 테스트를 진행해 본 결과는 다음과 같다. 인식된 레이블의 이름과 confidence 값이 함께 출력되는 것을 확인할 수 있다.

4. 만들기

이제 이 구축된 모델을 이용하여 챗봇을 만들어볼 것이다. 프로젝트로 돌아가서 만들기를 누르면 다음과 같은 화면이 나온다. 보다시피 스크래치나 파이썬, 앱 인벤터로 간단하게 챗봇을 만들 수 있다. 여기서는 파이썬을 이용해 볼 것이다. 

[파이썬] 버튼을 클릭하면 다음과 같은 화면이 나온다. 여러 방법이 소개되어 있는데, 코랩에 연결하여 사용하기 위해 우측에 있는 [내 컴퓨터에서 실행하도록 코드를 복사하세요.] 버튼을 클릭한다. 

그러면 다음과 같은 페이지가 나오고, 이 코드를 복사하여 그대로 코랩에 붙여 넣기 한다. 사진에서 빨간색 부분만 수정가능하다. 

각 질문 레이블에 맞는 답변을 다음과 같이 구성하였다.

while True:
    question = input("호텔에 대해서 궁금한 것을 저에게 물어보세요! 질문이 끝나시면 '나가기'를 입력해주세요.")

    if (question == "나가기") :
      break

    answer = classify(question)

    label = answer["class_name"]
    confidence = answer["confidence"]

    if confidence < 60 :
        print("제가 질문을 잘 이해하지 못했어요. 다시 질문해주세요.")

    elif (label == "reservation") : 
        print("호텔 예약과 관련된 정보는 저희 호텔 홈페이지에서 확인하실 수 있습니다.")
        print("답변 정확도 :", confidence)

    elif (label == "facility") :
        print("저희 호텔에는 헬스장, 수영장, 식당 등이 있습니다. 자세한 사항은 저희 호텔 홈페이지를 참고해주세요.")
        print("답변 정확도 :", confidence)

    elif (label == "location") :
        print("저희 호텔은 서울특별시 강남구에 위치해있습니다. 강남역 바로 앞에 위치해 있어 교통이 편리합니다.")
        print("답변 정확도 :", confidence)

    elif (label == "service") :
        print("저희 호텔은 전 객실 와이파이가 가능하며, 룸서비스 및 어메니티 서비스를 이용하실 수 있습니다.")
        print("답변 정확도 :", confidence)

    elif (label == "price") :
        print("호텔 객실 요금 정보는 저희 호텔 홈페이지에서 확인해주세요.")
        print("답변 정확도 :", confidence)

    elif (label == "checkinout") :
        print("체크인 시간은 오후 3시이며, 체크아웃 시간은 오후 12시입니다.")
        print("답변 정확도 :", confidence)

5. 실행결과

실행 결과는 다음과 같다.
  • 입력 : 호텔 예약을 하고 싶어요.
  • 출력 : 호텔 예약과 관련된 정보는 저희 호텔 홈페이지에서 확인하실 수 있습니다. / 답변 정확도 : 82
  • 입력 : 체크인은 언제부터 가능한가요.
  • 출력 : 체크인 시간은 오후 3시이며, 체크아웃 시간은 오후 12시입니다. / 답변 정확도 : 98
  • 입력 : 헬스장을 이용할 수 있나요.
  • 출력 : 제가 질문을 잘 이해하지 못했어요. 다시 질문해주세요. 

마치며..

Dialogflow로도 간단하게 챗봇을 구축할 수 있지만, 인공지능을 처음 배우는 학생들에게는 조금 난이도가 어려울 것 같아서 machine learning for kids 플랫폼을 사용하였다. 요즘 핫한 ChatGPT 정도의 챗봇을 만드는 것은 당연히 불가능하지만 난이도도 어렵지 않고 다양하게 활용이 가능해서 학생들이나 처음 인공지능을 공부하는 사람들에게는 한 번쯤 활용해 볼 만한 플랫폼인 것 같다. 

 

반응형
SMALL

드롭박스(Dropbox)는 전 세계 600,000개의 팀이 사용하고 있는 클라우드 스토리지 서비스이다.

사진 : 드롭박스

드롭박스는 지난 6월 22일 인공지능(AI) 기반 검색 도구 '드롭박스 대시(Dropbox Dash)'베타버전을 공개하였다. 드롭박스 대시는 인공지능을 기반으로 검색창 하나에 모든 툴, 콘텐츠, 앱을 연결해 주는 플랫폼이다. 이를 통하여 사용자는 다른 곳에 필요한 정보를 찾거나 정리 및 관리하는 시간을 줄일 수 있는 것이다. 

드롭박스 대시는 구글 웍스페이스, 마이크로소프트 아웃룩, 세일즈포스 등 주요 플랫폼을 위한 커넥터를 지원한다고 한다. 이에 따라 사용자는 자료 공유, 회의 참석, 파일 검색 업무 중 애플리케이션을 전환할 필요가 없게 되었다. 

사진 : 드롭박스(Dropbox)

드롭박스는 추후 생성 AI 또한 도입하여 저장된 자료를 기반으로 답변을 제공하거나 관련된 콘텐츠를 찾아주는 기능도 추가할 예정이라고 한다. 하나 아쉬운 점은 베타버전은 영어로만 제공된다는 점이다. 

반응형
SMALL

+ Recent posts