Main Content

신경망 훈련 개념

이 항목은 신경망 설계를 위한 워크플로에서 설명하는 설계 워크플로의 일부입니다.

이 항목에서는 두 가지 스타일의 훈련에 대해 설명합니다. 증분 훈련에서는 입력값이 신경망에 제공될 때마다 신경망의 가중치와 편향이 업데이트됩니다. 배치 훈련에서는 모든 입력값이 제공된 후에야 가중치와 편향이 업데이트됩니다. MATLAB® 환경에서는 배치 훈련 방법이 일반적으로 더 효율적이며 Deep Learning Toolbox™는 이러한 점을 강조하고 있습니다. 하지만 증분 훈련이 유용한 응용 분야도 일부 있기 때문에 이 패러다임 또한 구현되어 있습니다.

적응을 사용한 증분 훈련

증분 훈련은 적응 필터와 같이 동적 신경망에서 사용하는 것이 보다 일반적이긴 하지만 정적 신경망과 동적 신경망 양쪽에 모두 적용할 수 있습니다. 이 섹션에서는 정적 신경망과 동적 신경망 양쪽에서 증분 훈련이 수행되는 방법을 보여줍니다.

정적 신경망의 증분 훈련

첫 번째 예제에서 사용된 정적 신경망을 다시 살펴보겠습니다. 각 입력값이 입력된 후에 가중치와 편향이 업데이트되도록 정적 신경망을 증분 방식으로 훈련시키겠습니다. 이 경우 함수 adapt를 사용할 수 있으며, 입력값과 목표값은 시퀀스로 입력됩니다.

다음과 같은 선형 함수를 만들도록 신경망을 훈련시키려 한다고 가정하겠습니다.

t=2p1+p2

다음과 같은 이전 입력값에 대해

p1=[12],p2=[21],p3=[23],p4=[31]

목표값은 다음과 같습니다.

t1=[4],t2=[5],t3=[7],t4=[7]

증분 훈련에서는 다음과 같이 입력값과 목표값을 시퀀스로 제공합니다.

P = {[1;2] [2;1] [2;3] [3;1]};
T = {4 5 7 7};

먼저 초기 가중치와 편향을 0으로 두고 신경망을 설정합니다. 또한, 증분 훈련의 효과를 보이기 위해 초기 학습률을 0으로 설정합니다.

net = linearlayer(0,0);
net = configure(net,P,T);
net.IW{1,1} = [0 0];
net.b{1} = 0;

정적 신경망에서 동시 입력값을 사용한 시뮬레이션에서 정적 신경망의 경우 입력값이 동시 벡터로 구성된 행렬로 제공되든 순차 벡터로 구성된 셀형 배열로 제공되든 신경망의 시뮬레이션은 동일한 출력값을 생성한다고 설명하였습니다. 그러나 신경망을 훈련시킬 때는 그렇지 않습니다. adapt 함수를 사용할 때는 입력값이 순차 벡터로 구성된 셀형 배열로 제공되면 각 입력값이 제공될 때마다 가중치가 업데이트됩니다(증분 모드). 다음 섹션에서 설명하듯이, 입력값이 동시 벡터로 구성된 행렬로 제공될 경우 가중치는 모든 입력값이 입력된 후에야 업데이트됩니다(배치 모드).

이제 신경망을 증분 방식으로 훈련시킬 준비가 되었습니다.

[net,a,e,pf] = adapt(net,P,T);

학습률이 0이므로 신경망 출력값은 0으로 유지되고 가중치는 업데이트되지 않습니다. 오차는 목표값과 동일합니다.

a = [0]    [0]    [0]    [0]
e = [4]    [5]    [7]    [7]

이제 학습률을 0.1로 설정하면 각 입력값이 입력될 때마다 신경망이 어떻게 조정되는지 볼 수 있습니다.

net.inputWeights{1,1}.learnParam.lr = 0.1;
net.biases{1,1}.learnParam.lr = 0.1;
[net,a,e,pf] = adapt(net,P,T);
a = [0]    [2]    [6]    [5.8]
e = [4]    [3]    [1]    [1.2]

첫 번째 입력값이 입력되기 전까지는 업데이트가 이루어지지 않기 때문에 첫 번째 출력값은 학습률이 0이었을 때와 동일합니다. 두 번째 출력값의 경우 가중치가 업데이트되었기 때문에 달라집니다. 가중치는 각 오차가 계산됨에 따라 계속해서 수정됩니다. 신경망이 학습 능력이 있고 학습률이 올바르게 설정되었다면 오차는 결국 0을 향해 갑니다.

동적 신경망을 사용한 증분 훈련

동적 신경망을 증분 방식으로 훈련시킬 수도 있습니다. 실제로 이것이 가장 일반적인 경우입니다.

신경망을 증분 방식으로 훈련시키려면 입력값과 목표값을 셀형 배열의 요소로 입력하십시오. 초기 입력값 Pi가 있고 셀형 배열의 요소로 제공된 입력값 P와 목표값 T가 있습니다.

Pi = {1};
P = {2 3 4};
T = {3 5 7};

이전 예제에서 사용되었던 것처럼 입력값에서 하나의 지연을 갖는 선형 신경망을 가져옵니다. 가중치를 0으로 초기화하고 학습률을 0.1로 설정합니다.

net = linearlayer([0 1],0.1);
net = configure(net,P,T);
net.IW{1,1} = [0 0];
net.biasConnect = 0;

신경망이 현재 입력값과 이전 입력값을 더하여 현재 출력값을 만들도록 훈련시키려고 합니다. 입력값은 시퀀스의 첫 번째 항을 지연의 초기 조건으로 할당하는 점만 제외하면 이전 예제에서 사용한 입력값 시퀀스와 동일합니다. 이제 adapt를 사용하여 신경망을 순차적으로 훈련시킬 수 있습니다.

[net,a,e,pf] = adapt(net,P,T,Pi);
a = [0] [2.4] [7.98]
e = [3] [2.6] [-0.98]

첫 번째 출력값의 경우 가중치가 아직 업데이트되지 않았기 때문에 0입니다. 그 이후부터는 각 시간 스텝마다 가중치가 변경됩니다.

배치 훈련

모든 입력값과 목표값이 입력된 후에야 가중치와 편향이 업데이트되는 배치 훈련은 정적 신경망과 동적 신경망에 모두 적용할 수 있습니다. 이 섹션에서는 두 가지 유형의 신경망을 모두 다룹니다.

정적 신경망을 사용한 배치 훈련

배치 훈련은 adapt 또는 train을 사용하여 수행할 수 있습니다. 단, train은 보통 더 효율적인 훈련 알고리즘을 사용하므로 이것이 일반적으로 더 나은 옵션입니다. 보통 증분 훈련은 adapt를 사용하여 수행하고 배치 훈련은 train을 사용하여 수행합니다.

adapt를 사용하여 정적 신경망을 배치 훈련시킬 경우, 입력 벡터가 동시 벡터로 구성된 하나의 행렬에 배치되어야 합니다.

P = [1 2 2 3; 2 1 3 1];
T = [4 5 7 7];

이전 예제에서 사용한 정적 신경망으로 시작해 보겠습니다. 학습률은 0.01로 설정되어 있습니다.

net = linearlayer(0,0.01);
net = configure(net,P,T);
net.IW{1,1} = [0 0];
net.b{1} = 0;

adapt를 호출하면 trains(선형 신경망의 디폴트 적응 함수)와 learnwh(가중치 및 편향의 디폴트 학습 함수)가 호출됩니다. trains는 Widrow-Hoff 학습을 사용합니다.

[net,a,e,pf] = adapt(net,P,T);
a = 0 0 0 0
e = 4 5 7 7

신경망의 출력값이 모두 0인 것을 볼 수 있는데, 모든 훈련 세트가 입력되기 전까지는 가중치가 업데이트되지 않기 때문입니다. 가중치를 표시해 보면 다음과 같습니다.

net.IW{1,1}
  ans = 0.4900 0.4100
net.b{1}
  ans =
    0.2300

증분 업데이트에서 adapt를 한 번 통과한 후의 결과와 다른 결과입니다.

이번에는 train을 사용하여 동일한 배치 훈련을 수행합니다. Widrow-Hoff 규칙은 증분 모드와 배치 모드에서 모두 사용할 수 있으므로, adapt 또는 train으로 호출할 수 있습니다. (Levenberg-Marquardt와 같이 배치 모드에서만 사용할 수 있는 알고리즘이 몇 개 있는데, 이들 알고리즘은 train에 의해서만 호출할 수 있습니다.)

이 경우 입력 벡터는 동시 벡터로 구성된 행렬 또는 순차 벡터로 구성된 셀형 배열일 수 있습니다. 신경망이 정적이고 train은 항상 배치 모드에서 동작하므로 train은 시퀀스 벡터로 구성된 셀형 배열을 모두 동시 벡터로 구성된 행렬로 변환합니다. 동시 모드 연산이 MATLAB 코드에서 더 효율적으로 구현되어 있기 때문에 가능할 때마다 항상 동시 모드 연산이 사용됩니다.

P = [1 2 2 3; 2 1 3 1];
T = [4 5 7 7];

신경망은 동일한 방식으로 설정되어 있습니다.

net = linearlayer(0,0.01);
net = configure(net,P,T);
net.IW{1,1} = [0 0];
net.b{1} = 0;

이제 신경망을 훈련시킬 준비가 되었습니다. adapt의 통과 1회만 사용했기 때문에 Epoch 1회에 대해서만 훈련시킵니다. 선형 신경망의 디폴트 훈련 함수는 trainb이고, 가중치 및 편향의 디폴트 학습 함수는 learnwh입니다. 따라서 디폴트 적응 함수가 trains였던 이전 예제에서 adapt를 사용하여 얻은 것과 동일한 결과가 나와야 합니다.

net.trainParam.epochs = 1;
net = train(net,P,T);

훈련 Epoch 1회 후에 가중치를 표시해 보면 다음과 같습니다.

net.IW{1,1}
  ans = 0.4900 0.4100
net.b{1}
  ans =
    0.2300

adapt의 배치 모드 훈련과 동일한 결과입니다. 정적 신경망의 경우, adapt 함수는 입력 데이터의 형식에 따라 증분 훈련과 배치 훈련을 모두 구현할 수 있습니다. 데이터가 동시 벡터로 구성된 행렬로 입력되면 배치 훈련이 이루어집니다. 데이터가 시퀀스로 입력되면 증분 훈련이 이루어집니다. 반면에 train은 그렇지 않습니다. 이 경우에는 입력값의 형식과 관계없이 항상 배치 훈련을 수행합니다.

동적 신경망을 사용한 배치 훈련

정적 신경망을 훈련시키는 것은 비교적 간단합니다. train을 사용하면 신경망이 배치 모드로 훈련되고 입력값이 원래 시퀀스(셀형 배열의 요소)로 전달되었다 하더라도 동시 벡터(행렬의 열)로 변환됩니다. adapt를 사용하면 입력값의 형식에 따라 훈련 방법이 정해집니다. 입력값이 시퀀스로 전달되면 신경망이 증분 모드로 훈련됩니다. 입력값이 동시 벡터로 전달되면 배치 모드 훈련이 사용됩니다.

동적 신경망의 경우, 배치 모드 훈련은 보통 train으로만 수행됩니다. 특히 하나의 훈련 시퀀스만 존재하는 경우 더욱 그렇습니다. 이를 설명하기 위해 지연이 있는 선형 신경망을 다시 살펴보겠습니다. 훈련의 학습률은 0.02로 사용합니다. (경사하강법 알고리즘을 사용할 때는 보통 증분 훈련보다 배치 모드 훈련에서 더 작은 학습률을 사용합니다. 모든 개별 기울기가 합해진 후에 가중치에 대한 스텝 변경이 정해지기 때문입니다.)

net = linearlayer([0 1],0.02);
net.inputs{1}.size = 1;
net.layers{1}.dimensions = 1;
net.IW{1,1} = [0 0];
net.biasConnect = 0;
net.trainParam.epochs = 1;
Pi = {1};
P = {2 3 4};
T = {3 5 6};

앞에서 실시한 증분 훈련과 동일한 시퀀스를 사용하여 신경망을 훈련시키려고 합니다. 단, 이번에는 모든 입력값이 적용된 후에야 가중치를 업데이트할 것입니다(배치 모드). 입력값이 시퀀스이므로 신경망이 순차 모드로 시뮬레이션되지만 가중치는 배치 모드로 업데이트됩니다.

net = train(net,P,T,Pi);

훈련 Epoch 1회 후의 가중치는 다음과 같습니다.

net.IW{1,1}
ans = 0.9000    0.6200

이는 훈련 세트를 한 번 통과하는 동안 가중치가 세 번 업데이트되는 증분 훈련을 사용하여 얻은 가중치와 다릅니다. 배치 훈련에서는 가중치가 Epoch 1회에 한 번씩만 업데이트됩니다.

훈련 피드백

showWindow 파라미터를 사용하여 훈련 중에 훈련 창을 표시할 것인지 여부를 지정할 수 있습니다. 훈련 창은 기본적으로 표시됩니다. 그 밖에도 showCommandLineshow라는 2개의 파라미터로 훈련 중에 명령줄 출력이 생성되는지 여부와 명령줄 피드백 사이의 Epoch 횟수가 정해집니다. 예를 들어, 다음 코드는 훈련 창을 끄며, 이후 train을 사용하여 신경망이 훈련될 때 Epoch 35회마다 한 번씩 훈련 상태를 제공합니다.

net.trainParam.showWindow = false;
net.trainParam.showCommandLine = true;
net.trainParam.show= 35;

훈련 상태가 아예 표시되지 않도록 비활성화하는 것이 편리할 때도 있습니다. 이렇게 하려면 훈련 창과 명령줄 피드백을 모두 끄십시오.

net.trainParam.showWindow = false;
net.trainParam.showCommandLine = false;

훈련 창은 훈련을 진행하면 자동으로 표시됩니다.