심층 신경망 디자이너를 사용하여 시계열을 전망하는 신경망 훈련시키기
이 예제에서는 심층 신경망 디자이너에서 장단기 기억(LSTM) 신경망을 훈련시켜 시계열 데이터를 전망하는 방법을 보여줍니다.
심층 신경망 디자이너에서 시퀀스 분류 및 회귀 작업을 위한 심층 신경망을 대화형 방식으로 만들고 훈련시킬 수 있습니다.
시퀀스의 미래 시간 스텝 값을 전망하려면 sequence-to-sequence 회귀 LSTM 신경망을 훈련시킵니다. 이 경우 응답 변수는 시간 스텝 하나만큼 값이 이동된 훈련 시퀀스입니다. 즉, LSTM 신경망은 입력 시퀀스의 시간 스텝마다 다음 시간 스텝의 값을 예측하도록 학습합니다.
이 예제에서는 데이터 세트 chickenpox_dataset
를 사용합니다. 이 예제에서는 이전 달의 건수를 바탕으로 수두 발생 건수를 전망하는 LSTM 신경망을 만들어 훈련시킵니다.
시퀀스 데이터 불러오기
예제 데이터를 불러옵니다. chickenpox_dataset
에는 달이 시간 스텝이고 발생 건수가 값인 단일 시계열이 들어 있습니다. 출력값은 셀형 배열로, 각 요소는 단일 시간 스텝입니다. 행 벡터가 되도록 데이터의 형태를 변경합니다.
data = chickenpox_dataset; data = [data{:}]; figure plot(data) xlabel("Month") ylabel("Cases") title("Monthly Cases of Chickenpox")
훈련 데이터와 테스트 데이터를 분할합니다. 시퀀스의 첫 90%에 대해 훈련을 수행하고 마지막 10%에 대해 테스트를 수행합니다.
numTimeStepsTrain = floor(0.9*numel(data))
numTimeStepsTrain = 448
dataTrain = data(1:numTimeStepsTrain+1); dataTest = data(numTimeStepsTrain+1:end);
데이터 표준화하기
더 적합한 피팅을 위해, 그리고 훈련의 발산을 방지하기 위해 평균 0, 분산 1이 되도록 훈련 데이터를 표준화합니다. 예측하려면 훈련 데이터와 같은 파라미터를 사용하여 테스트 데이터를 표준화해야 합니다.
mu = mean(dataTrain); sig = std(dataTrain); dataTrainStandardized = (dataTrain - mu) / sig;
예측 변수 및 응답 변수 준비하기
시퀀스의 미래 시간 스텝 값을 전망하려면 응답 변수 값을 시간 스텝 하나만큼 값이 이동된 훈련 시퀀스로 지정하십시오. 즉, LSTM 신경망은 입력 시퀀스의 시간 스텝마다 다음 시간 스텝의 값을 예측하도록 학습합니다. 예측 변수는 최종 시간 스텝이 없는 훈련 시퀀스입니다.
XTrain = dataTrainStandardized(1:end-1); YTrain = dataTrainStandardized(2:end);
심층 신경망 디자이너를 사용하여 신경망을 훈련시키려면 훈련 데이터를 datastore 객체로 변환하십시오. arrayDatastore
항목을 사용하여 훈련 데이터 예측 변수와 응답 변수를 ArrayDatastore
객체로 변환합니다. combine
항목을 사용하여 두 데이터저장소를 결합합니다.
adsXTrain = arrayDatastore(XTrain); adsYTrain = arrayDatastore(YTrain); cdsTrain = combine(adsXTrain,adsYTrain);
LSTM 신경망 아키텍처 정의하기
LSTM 신경망 아키텍처를 만들려면 심층 신경망 디자이너를 사용합니다. 심층 신경망 디자이너 앱을 사용하여 딥러닝 신경망을 구축, 시각화, 편집 및 훈련시킬 수 있습니다.
deepNetworkDesigner
심층 신경망 디자이너 시작 페이지에서 Sequence-to-Sequence에 커서를 올리고 열기를 클릭합니다. 이렇게 하면 sequence-to-sequence 분류 작업에 적합한 사전 작성된 신경망이 열립니다. 마지막 계층을 교체하여 분류 신경망을 회귀 신경망으로 변환할 수 있습니다.
소프트맥스 계층과 분류 계층을 삭제하고 회귀 계층으로 바꿉니다.
계층의 속성을 조정하여 수두 데이터 세트에 적합하도록 만듭니다. 이 데이터는 하나의 입력 특징과 하나의 출력 특징을 가집니다. sequenceInputLayer를 선택하고 InputSize를 1
로 설정합니다. fullyConnectedLayer를 선택하고 OutputSize를 1
로 설정합니다.
분석을 클릭하여 신경망을 확인합니다. 딥러닝 신경망 분석기에 보고되는 오류가 없으면 신경망이 훈련할 준비가 된 것입니다.
데이터 가져오기
훈련 데이터저장소를 가져오기 위해 데이터 탭을 선택하고 데이터 가져오기 > 사용자 지정 데이터 가져오기를 클릭합니다. 훈련 데이터로 cdsTrain
을 선택하고 검증 데이터로 None
을 선택합니다. 가져오기를 클릭합니다.
데이터 미리보기에는 각각 448개의 시간 스텝이 있는 단일 입력 시계열과 단일 응답 시계열이 표시됩니다.
훈련 옵션 지정하기
훈련 탭에서 훈련 옵션을 클릭합니다. 솔버를 adam
으로, InitialLearnRate를 0.005
로, MaxEpochs를 500
으로 설정합니다. 기울기가 한없이 증가하지 않도록 하려면 GradientThreshold를 1
로 설정하십시오.
훈련 옵션 설정에 대한 자세한 내용은 trainingOptions
항목을 참조하십시오.
신경망 훈련시키기
훈련을 클릭합니다.
심층 신경망 디자이너가 훈련 진행 상황을 보여주는 애니메이션 플롯을 표시합니다. 이 플롯은 미니 배치 손실과 정확도, 검증 손실과 정확도, 그리고 훈련 진행 상황에 대한 추가 정보를 보여줍니다.
훈련이 완료되면 훈련 탭에서 내보내기를 클릭하여 훈련된 신경망을 내보냅니다. 훈련된 신경망이 trainedNetwork_1
변수로 저장됩니다.
미래의 시간 스텝 전망하기
여러 개의 미래 시간 스텝을 전망하여 훈련된 신경망을 테스트합니다. predictAndUpdateState
함수를 사용하여 한 번에 하나씩 시간 스텝을 예측하고 각 예측에서 신경망 상태를 업데이트합니다. 각 예측에서 직전의 예측을 함수의 입력값으로 사용합니다.
훈련 데이터와 같은 파라미터를 사용하여 테스트 데이터를 표준화합니다.
dataTestStandardized = (dataTest - mu) / sig; XTest = dataTestStandardized(1:end-1); YTest = dataTest(2:end);
신경망 상태를 초기화하려면 먼저 훈련 데이터 XTrain
에서 예측합니다. 다음으로 훈련 응답 변수 YTrain(end)
의 마지막 시간 스텝을 사용하여 첫 번째 예측을 수행합니다. 루프를 사용해 나머지 예측을 순회하고 이전 예측을 predictAndUpdateState
에 입력합니다.
대규모의 데이터 모음, 긴 시퀀스 또는 큰 신경망의 경우에는 일반적으로 GPU에서의 예측이 CPU에서의 예측보다 연산 속도가 빠릅니다. 그 밖의 경우에는 일반적으로 CPU에서의 예측이 연산 속도가 빠릅니다. 단일 시간 스텝 예측에는 CPU를 사용하십시오. 예측에 CPU를 사용하려면 predictAndUpdateState
의 'ExecutionEnvironment'
옵션을 'cpu'
로 설정하십시오.
net = predictAndUpdateState(trainedNetwork_1,XTrain); [net,YPred] = predictAndUpdateState(net,YTrain(end)); numTimeStepsTest = numel(XTest); for i = 2:numTimeStepsTest [net,YPred(:,i)] = predictAndUpdateState(net,YPred(:,i-1),'ExecutionEnvironment','cpu'); end
앞에서 계산된 파라미터를 사용하여 예측을 표준화하기 이전으로 되돌립니다.
YPred = sig*YPred + mu;
훈련 진행 상황 플롯은 표준화된 데이터에서 계산된 RMSE(제곱평균제곱근 오차)를 보고합니다. 표준화 이전으로 되돌린 예측에서 RMSE를 계산합니다.
rmse = sqrt(mean((YPred-YTest).^2))
rmse = single
175.9693
전망된 값을 갖는 훈련 시계열을 플로팅합니다.
figure plot(dataTrain(1:end-1)) hold on idx = numTimeStepsTrain:(numTimeStepsTrain+numTimeStepsTest); plot(idx,[data(numTimeStepsTrain) YPred],'.-') hold off xlabel("Month") ylabel("Cases") title("Forecast") legend(["Observed" "Forecast"])
전망된 값을 테스트 데이터와 비교합니다.
figure subplot(2,1,1) plot(YTest) hold on plot(YPred,'.-') hold off legend(["Observed" "Forecast"]) ylabel("Cases") title("Forecast") subplot(2,1,2) stem(YPred - YTest) xlabel("Month") ylabel("Error") title("RMSE = " + rmse)
관측값으로 신경망 상태 업데이트
예측 간 시간 스텝의 실제 값을 사용할 수 있다면 예측값 대신 관측값으로 신경망 상태를 업데이트할 수 있습니다.
먼저 신경망 상태를 초기화합니다. 새 시퀀스에 대해 예측을 수행하려면 resetState
를 사용하여 신경망 상태를 재설정하십시오. 신경망 상태를 재설정하면 이전 예측이 새 데이터 예측에 영향을 미치지 않습니다. 신경망 상태를 재설정한 후 훈련 데이터에 대해 예측을 수행하여 신경망 상태를 초기화합니다.
net = resetState(net); net = predictAndUpdateState(net,XTrain);
각 시간 스텝에 대해 예측을 수행합니다. 각 예측마다 이전 시간 스텝의 관측값을 사용하여 다음 시간 스텝을 예측합니다. predictAndUpdateState
의 'ExecutionEnvironment'
옵션을 'cpu'
로 설정합니다.
YPred = []; numTimeStepsTest = numel(XTest); for i = 1:numTimeStepsTest [net,YPred(:,i)] = predictAndUpdateState(net,XTest(:,i),'ExecutionEnvironment','cpu'); end
앞에서 계산된 파라미터를 사용하여 예측을 표준화하기 이전으로 되돌립니다.
YPred = sig*YPred + mu;
RMSE(제곱평균제곱근 오차)를 계산합니다.
rmse = sqrt(mean((YPred-YTest).^2))
rmse = 119.5968
전망된 값을 테스트 데이터와 비교합니다.
figure subplot(2,1,1) plot(YTest) hold on plot(YPred,'.-') hold off legend(["Observed" "Predicted"]) ylabel("Cases") title("Forecast with Updates") subplot(2,1,2) stem(YPred - YTest) xlabel("Month") ylabel("Error") title("RMSE = " + rmse)
여기서 예측값이 아닌 관측값으로 신경망 상태를 업데이트하면 예측이 더 정확해집니다.