본문 바로가기

업무/Matlab

Deep Learning Onramp

딥러닝은 머신러닝의 한 기법으로 심층 신경망 (계층이 많은 심경망)을 사용하여 예측을 수행

딥러닝의 목표는 종단간 학습을 하는 것

즉 영상을 바로 입력값으로 받고 특징과 분류를 영상으로부터 직접 학습

 

본 과정에서는 MATLAB에서 심층 신경망을 사용하여 영상을 인식하는 방법을 중점적으로 다룸

1. 사전 훈련된 신경망 사용하기

이번 섹션에서는 이미 만들어진 심층 신경망을 사용하여 아래 12개의 영상을 분류하는 방법 알아봄

1.1 교육 예제 - 여러 개의 영상에서 사물 식별하기

 

imread 함수를 사용하여 GIF, JPEG, PNG처럼 표준 파일 형식으로 저장된 영상 가져올 수 있음

 

1.2 예측하기

1.2.1 영상 분류하기

1.2.1.1 googlenet

이 함수를 사용하면 미리 정의된 심층 신경망인 "GoogleNet"의 복사본을 MATLAB 작업 공간에 만들 수 있음

 

1.2.1.2 classify

이 함수를 사용하면 영상에 대한 예측 수행 가능

pred = classify(net, img)

 

1.2.2 사전 훈련된 신경망 가져오기

시용 가능한 사전 훈련된 신경망을 살펴보려면 심층 신경망 디자인을 열자

또한 애드온 기능에서 ONNX(Open Neural Network Exchange)와 같은 오픈 소스 형식을 사용하여 

저장된 신경망을 가져오는 기능도 추가할 수 있음

즉 GitHub에서 제공하는 다른 사전 훈련된 신경망을 가져올 수 있음

 

 

1.3 CNN 아키텍처

1.3.1 CNN내의 계층

CNN은 성능이 뛰어나 널리 사용되며 2차원 구조의 입력 데이터를 활용하는 응용 사례에 맞게 설계됨 (ex. 영상)

CNN 계층은 종류가 다양하고 계층마다 세부적인 차이가 있지만 대부분의 CNN 신경망은 입력된 영상을

일련의 특징으로 변환하고 그 특징을 기반으로 마지막 몇 개 계층에서 분류를 수행

 

신경망은 어떻게 분류를 수행하냐?

신경망의 아키텍처라 할 수 있는 계층의 유형과 크기, 순서는 설계자가 정함

하지만 계층에는 자체 파라미터가 다양하게 존재하는데 이를 가중치라고 함

가중치는 데이터가 계층을 통과할 때 계층이 어떻게 동작하는지 결정함

가중치의 값은 레이블 데이터에 대해 신경망을 훈련시켜 결정됨

1.3.2 신경망 계층 검토하기

1.3.2.1 신경망 계층 확인

deepnet.Layers

 

1.3.2.2 개별 계층 확인

layer3 = ly(3)

 

1.3.2.3 InputSIze

입력 계층에서 중요한 속성은 InputSize로 신경망이 요구하는 입력 영상의 크기(차원)를 나타냅니다.

insz =inlayer.InputSize

 

1.4 예측 결과 살펴보기

 

1.4.1.1 classify

이 함수는 신경망이 가장 높은 점수를 할당하는 클래스를 첫 번째 출력값으로 반환

모든 클래스에 대한 예측 점수를 구하려면 classify 함수의 두번째 출력값을 요청하면 됨

[pred, scrs] = classify(net, img)

 

1.4.1.2 bar

예측 점수가 할당된 벡터를 사용하여 신경망의 분류 결과를 살펴볼 수 있음

bar(scrs) -> 예측 점수의 막대차트 만들기

 

1.4.1.3 유의미한 결과 분류

scores 변수 내 각 요소 값이 0.01보다 클 때 논리 값 1을 갖는 논리형 배열 highscores를 만들자

 

highscore = scores > 0.01

 

1.4.1.4 유의미한 결과의 그래프화

논리형 인덱싱을 사용하여 임계값 0.01보다 큰 예측 점수들만 나타내는 막대 차트 만들기

 

bar(scores(higjscores))

 

1.4.1.5 막대 그래프에 label 

xticklabels(categorynames(highscores))

2. 영상 데이터 세트 관리하기 

2.1 영상 데이터저장소

2.1.1 데이터저장소란?

딥러닝 수행 시 수많은 데이터들을 가지고 작업하므로 일일이 파일을 불러오기 보다는

데이터 저장소를 사용함

데이터 저장소는 MATLAB 변수로 데이터 소스에 대한 참조 역할을 함

MATLAB은 데이터저장소를 만들 때 파일을 확인하고 데이터에 대한 일부 기본 메타 정보(이름, 형식 등)을 저장함

하지만 데이터를 가져오지는 않음

사용자는 나중에 필요할 때 데이터를 가져올 수 있음

MATLAB의 CNN은 영상 데이터저장소와 원활하게 작동함

신경망은 영상을 모아 둔 세트의 예측을 수행할 수 있는데, 이떄 데이터저장소를 제공함

메모리 관리도 걱정할 필요 없음 -> 매트랩에서 알아서 관리해줌

2.1.2 데이터저장소 만들기

2.1.2.1 imageDatastore

이 함수를 사용하여 데이터저장소를 만들 수 있음

폴더 또는 파일 이름을 함수의 입력값으로 지정

 

ds = imageDatastore("foo*.png")

 

2.1.2.2 데이터저장소에 저장된 메타 정보

데이터저장소의 속성은 데이터 파일에 대한 메타정보를 포함

 

fname = imds.Files -> imds라는 이름의 데이터저장소에서 Files 속성을 fname에 저장

 

2.1.2.3 데이터 저장소에서 데이터 가져오기

- read : 영상을 한번에 하나씩 가져옴

- readimage : 하나의 특정 영상을 가져옴

  I = readimage(ds,n) -> 데이터저장소 ds의 n번째 영상을 I라는 배열로 가져옴

- readall : 모든 영상을 하나의 셀형 배열로 가져옴

 

2.1.2.4 classify

classify와 같은 CNN함수에서 개별 영상 대신 영상 데이터저장소를 입력값으로 사용 가능

결과는 데이터저장소에 포함된 각 영상당 하나씩 예측된 클래스로 구성된 배열

preds = classify(net, imds)
-> classify 함수는 GoogLeNet (net 변수)를 통해 12개의 영상의 분류 수행
 
2.1.2.5 12개의 영상 중 점수가 가장 높은 부분 가져오기
 
[preds, scores] = classify(net, imds)
max(scores,[],2)

 
bar(max(scores,[],2))
xticklabels(preds)
xtickangle(60)
ylabel("Score of Prediction")
 

2.2 입력값으로 사용할 영상 준비하기

2.2.1 사용할 영상 준비하기

기존 신경망에서 영상을 사용하려면 해당 신경망의 예상 입력 크기와 일치해야 함

이 크기는 신경망에 따라 다르지만 대부분의 사전 훈련됭 신경망에는 220 * 220 * 3 영상이 필요

 

하지만 대부분의 우리가 가져오는 영상은 크기가 다 다름

이에 자르기, 크기 조정, 회색조에서 컬러로 변환 등의 전처리가 필요

2.2.2 입력 영상 조정하기

2.2.2.1 영상 크기 확인

size 함수를 사용하여 영상의 크기 확인

 

2.2.2.2 신경망의 계층이 요구하는 영상 크기 확인

신경망의 입력 계층은 신경망이 요구하는 영상 크기를 지정

 

expectedSize = inputLayer.InputSize

------------------------------------------------------------ 

net = googlenet
layer1 = net.Layers(1)

 
insz = layer1.InputSize
 
2.2.2.3 영상 크기 조정
요구되는 입력 크기에 맞게 imresize 함수를 사용하여 영상의 크기 조정 가능
 
img = imresize(img, [numrows numcols])
 

2.3 데이터저장소의 영상 처리하기

2.3.1 영상 전처리 과정

컨벌루션 신경망을 사용하여 영상을 분류하려면 각 영상의 크기가 해당 신경망의 입력 계층이 요구하는 크기과 같아야 함

일반적으로 영상을 분류하기에 앞서 간단한 전처리 작업이 필요

전처리 작업을 각 영상마다 일일이 할 수 있지만, 전체 데이터 세트의 메타 정보를 가지고 있는 데이터 저장소를 사용하여

전처리를 수행하는 것이 더 효율적

2.3.2 데이터저장소의 영상 크기 조정하기

2.3.2.1 augementedImageDatastore

이 함수는 영상 데이터 세트 전체에 대한 전처리를 간단하게 수행 가능

 

auds = augementedImageDatastore([r c], imds)

 

2.3.2.2 영상 분류

증대 영상 데이터저장소를 classify 함수에 대한 입력값으로 사용 가능

각 영상은 분류되기 전에 데이터저장소를 만들 때 지정한 방법을 사용하여 전처리됨

 

preds = classify(net, auds)

 

2.3.3 데이터저장소를 사용하여 색 전처리하기

2.3.3.1 montage

이 함수를 사용하면 모든 영상 표시 가능 

montage(imds)

 

2.3.3.2 회색조 -> 컬러 영상

증대 영상 데이터저장소를 만들 때 ColorPreprocessing 옵션을 설정하여 회색조 영상을 3차원 배열로 변환 가능

 

auds = augmentedImageDatastore([n m], imds, "ColorPreprocessing", "gray2rgb")

-> 회색조 영상을 세번 복제하여 3차원 배열 생성

2.4 하위 폴더를 사용하여 데이터저장소 만들기

기본적으로 imageDatastrore는 지정된 폴더 내에서 영상 파일을 찾음

"IncludeSubfolders" 옵션을 사용하면 지정된 폴더의 하위 폴더 내에서도 영상을 찾을 수 있음

 

flwrds = imageDatastore("Flowers", "InculudeSubfolders", true)

resizeds = augmentedImageDatastore([224 224], flwrds)

preds = classify(net, resizeds)

3. 전이 학습 수행하기 

3.1 전이 학습이란?

3.1.1 전이 학습이란?

사전 훈련된 신경망을 가져와 수정한 후 새 데이터에 대해 다시 훈련시키는 과정

전이 학습은 많은 딥러닝 문제를 효과적으로 처리 가능

3.2 전이 학습에 필요한 구성요소

3.2.1 전이 학습에 필요한 구성요소

- 훈련시킬 신경망 : 전이학습의 핵심은 사전 훈련된 신경망에서 출발해 이를 수정하여 원하는 신경망을 얻는 것

- 훈련에 사용할 데이터 : 이미 올바른 레이블이 있는 예제 영상 필요 (지도 학습)

- 훈련 옵션 세트 지정 : 훈련 과정에서 적용되는 반복적 알고리즘을 통해

                                     신경망은 훈련 영상을 올바르게 인식하는 능력을 키우게 됨

이 알고리즘은 여러 파라미터를 사용하여 미세 조정 가능하지만 대부분 디폴트로 해도 됨

 

이 3가지 요소를 trainNetwork 함수에 전달하고 출력값 반환하기 기다리면 됨

3.2.2 일반적인 전이 학습 과정

3.3 훈련 데이터 준비하기

3.3.1 데이터저장소의 영상에 레이블 지정하기

신경망을 훈련시킬 때 훈련 영상에 대한 올바른 레이블을 제공해야 함

따라서 훈련에 필요한 레이블을 제공하는 데 폴더의 이름을 사용할 수 있음

 

"LabelSource" 옵션을 지정하여 데이터저장소가 폴더 이름으로부터 레이블을 자동으로 결정할 수 있음

 

3.3.2 훈련 및 테스트를 위해 데이터 분할하기

신경망이 쓸모 있으려면 훈련할 때 사용한 영상이 아니라 새 영상에 그 신겸망을 적용할 수 있어야 함

따라서 훈련용으로 준비한 데이터 중 일부를 테스트용으로 남겨놓음

이번 섹션에서는 splitEachLabel 함수를 통해 폴더 내 영상을 2개의 별도 데이터저장소로 나눌 예정

 

3.3.2.1 splitEachLabel

이 함수를 사용하여 데이터저장소의 영상들을 2개의 개별 데이터저장소로 나눌 수 있음

[ds1, ds2] = splitEachLabel(imds, p) -> p의 값은 0~1사이 값

 

[flwrTrain, flwrTest] = splitEachLabel(flwrds, 0.8, "randomized") -> "randmoized" 옵션을 통해 파일들을 무작위로 섞어 분리 가능
 
[flwrTrain, flwrTest] = splitEachLabel(flwrds, 500) -> 비례적으로 분할되는게 아닌 특정 개수만큼 분할
 

3.3.3 증대 훈련 데이터

augmentedImageDatasrore 함수는 출력 영상 크기와 imageDatastore를 입력값으로 받음

반환되는 출력값을 trainNetwork 함수에 대한 훈련 데이터 입력값으로 사용 가능

영상의 크기가 조정되지만 사용자가 선택적 입력값을 사용하여 전처리 동작 제어 가능

 

imageDataAugmenter 함수를 사용하여 여러가지 변환을 설정할 수 있음

이러한 변환을 사용하여 증대 훈련 세트를 만들 수 있음

설정한 다음에는 imageDataAugmenter 변수를 augmentedImageDatastore 함수에 선택적 입력값으로 전달 가능

 

3.4 신경망 계층 수정하기

3.4.1 심층 신경망 디자이너

심층 신경망 디자이너를 사용하여 사전 훈련된 신경망을 탐색하거나 신경망을 처음부터 새로 만들 수 있음

(애드 온 탐색기)

전이 학습을 수행하는 경우 가장 중요한 계층은 입력 및 출력 계층임

전이 학습의 경우 아래 캡쳐본이 가리키는 두 계층은 바꿔야 함

계층 라이브러리에서 새로 바꿀 계층을 찾아 놓아야 함

그런 다음 새로운 계층의 출력크기를 데이터 세트의 개수와 일치시켜야 함

새 아키텍처를 훈련시키기 전에 이 아키텍처가 유효한지 확인 필요

툴 스크립트에서 Analyze 클릭 -> 오류 확인 및 디버깅 -> 전이 학습에 사용

3.4.2 사전 훈련된 신경망의 계층 수정하기

GoogLeNet으로 전이 학습을 수행하려면 신경망을 심층 신경망 디자이너로 가져오면 됨

시작 페이지의 옵션에서 사전 훈련된 신경망을 선택할 수 있음

 

신경망 선택 후 툴 스크립트의 탐색 섹션을 사용하여 아키텍처의 다른 섹션 확대 가능

Ctrl + 스크롤 휠을 사용하여 마우스로 확대 또는 축소 가능

 

꽃을 분류하도록 아키텍처를 사용자 지정하려면 먼저 완전 연결 계층을 대체해야 함

완전 연결 계층에는 지정된 수의 뉴런이 필요

각 출력 클래스에 하나의 뉴런이 있어야 함

 

완전 연결 계층을 추가하려면 계층 라이브러리의 컨벌루션 및 완전 연결 섹션을 찾고,

원하는 계층을 클릭해 끌어서 놓으면 캔버스에 추가 됨

 

계층을 대체하려면 기존 계층을 삭제한 다음 새 계층에 연결을 추가

연결을 추가하려면 한 계층의 출력을 클릭한 다음 다른 계층의 입력으로 끌어서 놓음

 

신경망의 마지막 계층을 클릭함

속성 창의 OutputSize는 1000

방금 만든 완전 연결 계층의 OutputSize는 5

이 불일치로 인해 완전 연결 계층에서 분류 계층으로 정보가 전달될 때 문제 발생할 수 있음

이 문제를 해결하려면 출력 계층을 새로운 빈 계층으로 대체해야 함

 

출력 섹션 아래에서 선택해 새 classificationLayer를 만드세요

기존 분류 계층을 새 계층으로 대체하세요

 

3.5 훈련 옵션 설정하기

3.5.1 trainingOptions

이 함수를 사용하면 선택한 훈련 알고리즘에 쓸 수 있은 옵션 확인할 수 있음

 

opts = trainingOptions("sgdm")

-> 훈련 알고리즘 "모멘텀을 사용한 확률적 경사하강법"에 대한 디폴트 옵션을 포함하는 변수 opts 만듬

 

3.5.2 학습률 변경

처음에는 대부분의 옵션을 디폴트 값으로 유지하고 훈련을 수행

하지만, 전이 학습을 수행할 때는 일반적으로 InitialLearnRate를 디폴트 값인 0.01보다 작은 값으로 설정하는 것이 좋음

 

학습률은 알고리즘이 얼마나 과감하게 신경망 가중치를 변경하는지를 제어

전이 학습의 목표는 기존 신경망을 미세하게 조정하는 것이므로 일반적으로 처음부터 새로 훈련시킬 때보다

덜 과감하게 가중치를 변경하는 것이 좋음

 

3.5.2.1 traingOptions의 InitialLearnRate 옵션

trainingOptions 함수에 이름-값 쌍을 사용해 원하는 개수만큼 선택적으로 설정을 지정 가능

 

opts = trainingOptions("sgdm", "InitialLearnRate", 0.001)

3.6 신경망 훈련시키기

3.6.1 훈련 수행하기

전이 학습을 수행하려면 3가지 요소 필요

- 신경망을 나타내는 계층

- 훈련 영상을 저장할 데이터 저장소

- 훈련 알고리즘의 설정을 담을 변수

 

이 3요소를 신경망 훈련 함수에 제공하고 실핻되도록 설정하면 됨

작업이 완료되면 새로 훈련된 신경망의 계층은 입력 신경망과 동일하지만 가중치가 업데이트된 상태

정확도는 신경망이 올바르게 분류하는 훈련 영상의 비율 (훈련 중 증가해야 함)

손실은 신경망이 완벽한 예측과 얼마나 차이가 있는지를 훈련 영상 세트 전체에 대해 측정한 값(훈련 중 감소해야 함)

3.6.2 미니 배치

각 반복마다 "미니 배치"라고 하는 훈련 영상의 서브셋이 가중치를 업데이트하는 데 사용됨

반복마다 각기 다른 미니 배치 사용

훈련 알고리즘이 전체 훈련 세트를 반복해서 학습하는 횟수를 Epoch라고 함

 

Epoch의 최대 수와 미니 배치의 크기는 훈련 알고리즘 옵션에서 설정 가능

3.6.3 GPU 사용하기

GPU(그래픽스 처리 장치)는 딥러닝에 필요한 많은 계산 작업의 속도를 크게 높일 수 있음 (GPU가 없으면 CPU에서 훈련 수행 가능)

딥러닝을 본격적으로 활용할 생각이면 관련 계산을 지원하는 GPU가 장착된 컴퓨터에서 신경망을 훈련시키는 것이 좋음

- 적절한 GPU 및 Parallel Computing Toolbox가 설치된 경우 trainNetwork 함수가 GPU에서 자동으로 훈련을 수행하므로

  특별한 코딩 작업 필요 X

- 그렇지 않은 경우 CPU에서 대신 훈련 수행, 이는 필요한 하드웨어 및 소프트웨어를 구매하기 전에 잠시 딥러닝 실험 가능

 

3.6.4 전이 학습 예제 스크립트

load pathToImages
flower_ds = imageDatastore(pathToImages,"IncludeSubfolders",true,"LabelSource","foldernames");
[trainImgs,testImgs] = splitEachLabel(flower_ds,0.6);
resizeTrainImgs = augmentedImageDatastore([224 224],trainImgs);
resizeTestImgs = augmentedImageDatastore([224 224],testImgs);
numClasses = numel(categories(flower_ds.Labels));

 
load untrainedNetwork
opts = trainingOptions("sgdm","InitialLearnRate",0.001,"MaxEpochs",1,"VerboseFrequency",2, "Plots", "training-progress")
[flowernet,info] = trainNetwork(resizeTrainImgs,lgraph,opts)

 

3.7 성능 평가하기

3.7.1 훈련 및 테스트 성능 평가하기

변수 info는 훈련에 대한 정보를 담은 구조체

TrainingLoss, TrainingAccuracy 필드는 훈련 데이터에 대한 매번의 반복에서 얻은 신경망의 성능 기록을 담고 있음

 

load pathToImages
load trainedFlowerNetwork flowernet info

 
plot(info.TrainingLoss) -> Loss 값 플로팅

 
dsflowers = imageDatastore(pathToImages,"IncludeSubfolders",true,"LabelSource","foldernames");
[trainImgs,testImgs] = splitEachLabel(dsflowers,0.99);
resizeTestImgs = augmentedImageDatastore([224 224],testImgs);

 
flwrPreds = classify(flowernet, resizeTestImgs) 
 
신경망 훈련의 목표는 손실함수를 최소화하는 것
 

3.7.2 테스트 성능 살펴보기

3.7.2.1 nnz

논리 비교와 이 함수를 사용하여 두 배열 간의 서로 일치하는 요소의 개수 파악 가능

(예측된 분류 클래스와 실제 분류 클래스 비교)

 

numCorrect = nnz(flwrPreds == flwrActual)
 
 
3.7.2.2 올바르게 분류된 테스트 영상의 비율 구하기
 
fracCorrect = numCorrect / numel(flwrActual) -> numel : 배열에 포함된 요소의 개수 반환

 

3.7.2.3 클래스별 성능

 
3.7.2.4 confusionchart 
이 함수는 예측된 분류 클래스에 대한 혼동행렬 계산하여 표시
혼동행렬의(j,k) 요소는 신경망이 k 클래스라고 예측한 영상 중 실제로는 j클래스인 영상의 수
대각선 요소는 정분류, 그 외는 오분류를 나타냄

 

3.7.3 성능 개선하기

성능이 만족스럽지 못하다면 일반적으로 옵션부터 변경해보자

학습률과 모멘텀, 이 두 파라미터는 훈련 알고리즘이 가중치를 업데이트하는 방식에 영향을 미치는 주요 파라미터

 

경사하강법 알고리즘은 현재 위치 주변의 몇 군데 지점에서 지상으로부터 계곡의 높이를 확인하고

이를 사용하여 경사 또는 경사가 가파른 방향을 파악하는 알고리즘

그런 후 해당 방향으로 1 step 나아가면 새로운 위치에 대한 새로운 가중치 값 얻을 수 있음

이 step의 크기를 학습률이라 함

가중치가 너무 커져서 신경망이 아주 형편없는 결과를 보이면 먼저 학습률을 10으로 나눈 후 다시 시도

 

모멘텀을 사용한 경사하강법은 처음에는 경사의 방향을 따라 그대로 내려가지만 다음 스탭에서 경상 방향이 바뀌는 경우

새로운 경사 방향으로 방향을 완전히 바꾸지는 않음 대신 그 방향으로 좀 더 향하게 됨

3.8 전이 학습 요약

 

 

4. 결론

4.1 추가 학습 자료

4.1.1 딥러닝 응용 사례

다양한 유형의 계층에 대한 몇 가지 배경이론과 이러한 계층 유형이 수행하는 작업 파악 필요

매트랩 홈페이지에서 딥러닝 응용 사례를 구축하는데 도움이 되는 추가 학습 자료 얻을 수 있음

 

'업무 > Matlab' 카테고리의 다른 글

Reinforcement Learning Onramp  (1) 2024.10.23
Computer Vision Onramp  (0) 2024.09.18
Machine Learning Onramp  (0) 2024.06.30
Signal Processing Onramp  (0) 2024.06.30
Image Processing Onramp  (0) 2024.06.24