Main Content

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

1차원 컨벌루션을 사용한 시퀀스 분류

이 예제에서는 1차원 컨벌루션 신경망을 사용하여 시퀀스 데이터를 분류하는 방법을 보여줍니다.

시퀀스 데이터를 분류하도록 심층 신경망을 훈련시키기 위해 1차원 컨벌루션 신경망을 사용할 수 있습니다. 1차원 컨벌루션 계층은 1차원 입력값에 슬라이딩 컨벌루션 필터를 적용하여 특징을 학습합니다. 컨벌루션 계층은 한 번의 연산으로 입력을 처리할 수 있기 때문에 1차원 컨벌루션 계층을 사용하는 것이 순환 계층을 사용하는 것보다 더 빠를 수 있습니다. 반면에 순환 계층은 입력값의 시간 스텝마다 반복해야 합니다. 그러나 순환 계층은 시간 스텝 간의 장기적인 종속성을 학습할 수 있기 때문에 신경망 아키텍처와 필터 크기가 어떤지에 따라 1차원 컨벌루션 계층이 순환 계층보다 성능이 떨어질 수도 있습니다.

이 예제에서는 [1]과 [2]에서 설명한 Japanese Vowels 데이터 세트를 사용합니다. 이 예제에서는 연속해서 발화된 2개의 일본어 모음을 나타내는 시계열 데이터를 주고 화자를 인식하도록 1차원 컨벌루션 신경망을 훈련시킵니다. 훈련 데이터는 화자 9명의 시계열 데이터를 포함합니다. 각 시퀀스는 12개의 특징을 가지며 길이가 서로 다릅니다. 데이터 세트는 270개의 훈련 관측값과 370개의 테스트 관측값을 포함합니다.

시퀀스 데이터 불러오기

WaveformData.mat에서 예제 데이터를 불러옵니다. 이 데이터는 시퀀스로 구성된 numObservations×1 셀형 배열이며, 여기서 numObservations는 시퀀스 개수입니다. 각 시퀀스는 numChannels×-numTimeSteps 숫자형 배열이며, 여기서 numChannels는 시퀀스의 채널 개수이고 numTimeSteps는 시퀀스의 시간 스텝 개수이며 파형 유형으로 레이블이 지정됩니다.

load WaveformData

시퀀스 중 일부를 플롯으로 시각화합니다.

numChannels = size(data{1},1);

idx = [3 4 5 12];
figure
tiledlayout(2,2)
for i = 1:4
    nexttile
    stackedplot(data{idx(i)}',DisplayLabels="Channel "+string(1:numChannels))
    
    xlabel("Time Step")
    title("Class: " + string(labels(idx(i))))
end

검증과 테스트를 위해 데이터를 남겨 둡니다. 데이터의 80%가 포함된 훈련 세트, 데이터의 10%가 포함된 검증 세트, 데이터의 나머지 10%가 포함된 테스트 세트로 데이터를 분할합니다. 데이터를 분할하려면 이 예제에 지원 파일로 첨부된 trainingPartitions 함수를 사용합니다. 이 파일에 액세스하려면 이 예제를 라이브 스크립트로 여십시오.

numObservations = numel(data);
[idxTrain,idxValidation,idxTest] = trainingPartitions(numObservations, [0.8 0.1 0.1]);
XTrain = data(idxTrain);
TTrain = labels(idxTrain);

XValidation = data(idxValidation);
TValidation = labels(idxValidation);

XTest = data(idxTest);
TTest = labels(idxTest);

1차원 컨벌루션 신경망 아키텍처 정의하기

1차원 컨벌루션 신경망 아키텍처를 정의합니다.

  • 입력 데이터의 특징 개수로 입력 크기를 지정합니다.

  • 두 블록의 1차원 컨벌루션 계층, ReLU 계층, 계층 정규화 계층을 지정합니다. 여기서 컨벌루션 계층의 필터 크기는 5입니다. 첫 번째 컨벌루션 계층과 두 번째 컨벌루션 계층에 대해 각각 32개 필터와 64개 필터를 지정합니다. 이 두 컨벌루션 계층의 출력값의 길이가 동일하도록 입력값의 왼쪽을 채웁니다(인과적(causal) 채우기).

  • 컨벌루션 계층의 출력값을 단일 벡터로 줄이기 위해 1차원 전역 평균값 풀링 계층을 사용합니다.

  • 출력값을 확률로 구성된 벡터에 매핑하기 위해, 출력 크기가 클래스 개수와 일치하는 완전 연결 계층을 지정하고 그 뒤에 소프트맥스 계층과 분류 계층을 지정합니다.

filterSize = 5;
numFilters = 32;

numFeatures = size(XTrain{1},1);
numClasses = numel(categories(TTrain));

layers = [ ...
    sequenceInputLayer(numFeatures)
    convolution1dLayer(filterSize,numFilters,Padding="causal")
    reluLayer
    layerNormalizationLayer
    convolution1dLayer(filterSize,2*numFilters,Padding="causal")
    reluLayer
    layerNormalizationLayer
    globalAveragePooling1dLayer
    fullyConnectedLayer(numClasses)
    softmaxLayer
    classificationLayer];

훈련 옵션 지정하기

다음과 같이 훈련 옵션을 지정합니다.

  • Adam 최적화 함수를 사용하여 학습률 0.01로 Epoch 60회만큼 훈련시킵니다.

  • 시퀀스의 왼쪽을 채웁니다.

  • 검증 데이터를 사용하여 신경망을 검증합니다.

  • 훈련 진행 상황을 플롯에서 모니터링하고 세부 정보가 출력되지 않도록 합니다.

miniBatchSize = 27;

options = trainingOptions("adam", ...
    MaxEpochs=60, ...
    InitialLearnRate=0.01, ...
    SequencePaddingDirection="left", ...
    ValidationData={XValidation,TValidation}, ...
    Plots="training-progress", ...
    Verbose=0);

신경망 훈련시키기

trainNetwork 함수를 사용하여 지정된 훈련 옵션으로 신경망을 훈련시킵니다.

net = trainNetwork(XTrain,TTrain,layers,options);

신경망 테스트하기

훈련에 사용된 것과 동일한 시퀀스 채우기 옵션을 사용하여 테스트 데이터를 분류합니다.

YTest = classify(net,XTest, ...
    SequencePaddingDirection="left");

예측의 분류 정확도를 계산합니다.

acc = mean(YTest == TTest)
acc = 0.8400

예측값을 혼동행렬로 시각화합니다.

figure
confusionchart(TTest,YTest)

참고 항목

| | | | | | |

관련 항목