09-4. XOR 문제 keras로 풀어 Tensorboard로 확인 LAB

2020. 6. 13. 03:35AI/모두를 위한 딥러닝

이 포스트는 모두를 위한 딥러닝 - Tensor Flow를 정리한 내용을 담았습니다.
누구나 이해할 수 있는 수준으로 설명하고자 하였으며 LAB의 코드는 TF2.0에 맞추어 재작성되었습니다.

 

이번 포스트에서는 이때까지의 텐서플로우 코드의 출력을 텍스트로 보았다면, Tensorboard를 활용하여 그래프로 나타내고 데이터들을 그림으로 보는 방법에 대해 알아보겠습니다. TF2.0에서는 TF 1.X 버전의 코드를 지원하지 않는 것으로 보이므로 Tensorboard에 대한 설명은 모두를 위한 딥러닝 시즌1에서 확인해주시고 keras를 이용한 코드는 모두를 위한 딥러닝 시즌2의 5:30부터 확인해주시길 바랍니다. 아래의 코드는 모두를 위한 딥러닝 Github를 토대로 작성하였습니다.

 

그렇다면 먼저 Tensorboard에 대해 알아보겠습니다. 이전까지 우리는 주로 텐서플로우 코드를 print로 출력하여 값의 변화를 살펴보았습니다. 바로 직전 포스트의 XOR문제 또한 아래와 같이 print로 출력하여 Loss의 변화를 알아보았습니다. 이 방법은 수치적으로 값의 변화를 지켜볼 때는 유용하지만, 변화 추이만을 살펴보고 싶을 때는 숫자도 많아 한눈에 들어오지 않습니다.

print로 출력

따라서 이런 경우 우리는 아래와 같이 Tensorboard를 이용하여 그래프로 값의 변화를 한눈에 볼 수 있습니다.

다시 말하면 Tensorboard는 학습 과정을 시각화해서 볼 수 있습니다.

그래프 1.1. Tensorboard로 나타낸 그래프 예시

 

Tensorboard에 그래프를 그리는 과정은 물론 중요하지만, 이번 포스트에서는 TF2.X에 맞춰 Keras를 이용해 간단한 코드로 XOR문제를 시각화해서 보겠습니다. 먼저 아래는 코드 전문입니다.

코드 1.1 keras를 이용해 XOR문제를 Tensorboard에 표시

먼저 line 11 - 16를 보겠습니다. TF 2.X의 변경사항 중 하나로 keras API가 정식적으로 포함된 것으로, keras의 모델에 차례로 레이어를 쌓아 나가는 것을 볼 수 있습니다. Dense는 입력과 출력을 모두 연결해주는 레이어로, 전결합층(fully-connected layer)이라 합니다. 예를 들어 입력 뉴런이 3개, 출력 뉴런이 7개 있다면 Dense에서 연결선은 총 21개(3x7)입니다. 모든 연결선에는 가중치를 포함하고 있으며, 이 가중치는 뉴런 간 연결 강도를 의미합니다. 예를 들어 성별을 판단하는 문제에서 입력 뉴런에 염색체와 혈액형이 있다면, 출력 뉴런은 당연 성별이며 염색체는 가중치가 높을 것이지만 혈액형은 가중치가 비교적 낮을 것입니다.(사실 염색체로 성별을 판단할 수 있기 때문에 가중치가 가장 높지만, 설명을 위해 예를 들었습니다.) line 12를 예로 보겠습니다. Dense(10, input_dim=2, activation=tf.nn.sigmoid)에서 10은 출력 뉴런의 수, input_dim은 입력 뉴런의 수, activation은 활성화 함수를 의미합니다. 이외에도 주요 인자로 가중치를 균일 분포로 초기화할 것인지(uniform), 정규 분포(가우시안 분포, normal)로 초기화할 것인지를 선택하는 init도 있습니다. 지금은 XOR에 따라 1인지 0인지를 분류하는 이진 분류 문제이므로 출력 뉴런은 하나만 있으면 됩니다. 따라서 line 15를 보면 Dense 레이어의 첫 번째 인자가 1인 것을 확인할 수 있으며, 활성화 함수로는 모두 sigmoid를 사용하고 있습니다. 또한 입력층이 아닐 때는 이전층의 출력 뉴런 수를 자동으로 알 수 있기 때문에 input_dim을 지정하지 않아도 됩니다. 이러한 정보를 토대로 보면 line 12의 Dense 레이어는 입력 레이어, line 15의 Dense 레이어는 출력 레이어, 사이의 line 13 - 14의 Dense 레이어는 히든 레이어로 볼 수 있습니다. "09. XOR 문제 딥러닝으로 풀기"포스트에서의 풀이 과정과 비교하며 보면 더욱 이해가 쉬울 것입니다. 이제 line 19를 보겠습니다. 모델을 학습하기 전에. complie() 메서드를 활용하여 학습에 대한 설정을 해주는 과정입니다. optimizer는  이전의 코드들에서 최적화 부분에 많이 쓴 'sgd' 등의 최적화 함수를 설정하는 인자입니다. 이번에는 'adam'으로 설정했습니다. loss는 손실 함수를 설정하는 인자로, binary_crossentropy로 설정했습니다. 보통 결과가 0 또는 1의 형태이면서 sigmoid 함수를 사용할 때는 binary_crossentropy를, softmax 함수를 사용할 때는 결과 형태에 따라 categorial_crossentropy나 sparse_categorical_crossentropy를 사용합니다. metrics 인자는 모델의 성능을 평가하는 데 사용하는 지표 함수를 설정합니다. 이제 line 5에서 TensorBoard를 불러와 분석할 로그 파일을 저장할 위치 경로(log_dir'), 모델의 레이어에 대해 활성화와 가중치 히스토그램을 계산할 것인지에 대한 여부(histogram_freq, 다차원 텐서에서 필요합니다.), Tensorboard에서 그래프로 시각화할지에 대한 여부(write_graph), 이미지로 시각화할 모델의 가중치를 작성할지 여부(write_images)를 설정합니다. 이제 line 25에서 학습을 위해. fit()에 학습할 데이터를 넣고 반복 횟수(epochs)와 학습에 대한 통계를 구하는 함수(callbacks)를 정합니다. line 27과 29는 각각 모델의 구조를 요약한 것과 학습 후의 예측 레이블을 출력합니다. 위의 keras 메서드들에 대해 더 궁금하시다면, 링크의 사이트에서 참조해주시길 바랍니다.

이제 코드에 대해 모두 알아보았습니다. 다음 코드를 실행했을 때의 결과와 Tensorboard에서 확인하는 방법에 대해 알아보겠습니다. 먼저 코드 실행시 결과창입니다.

출력 1..1 학습 중일 때의 출력창
출력 1.2. 학습을 완료한 뒤 결과창

 위의 출력 1.1은 학습 중일 때 스크린샷한 결과창이며 아래의 출력 1.2는 학습을 완료한 뒤 스크린샷한 결과창입니다.  Epoch에 따라 loss가 줄어들고 binary_accuracy가 증가하는 것을 확인할 수 있습니다. 아래의 학습이 완료된 후의 결과를 보면, loss는 0.0087로 크게 줄고 binary_accuracy는 1.0000으로 정확한 결과를 보이는 것을 확인할 수 있습니다. 아래는 Dense 레이어의 구조를 요약한 모습과 예측 레이블을 출력합니다. XOR 모델에서 기대하는 결과로 학습되었음을 확인할 수 있습니다.

 이제 Tensorboard에서 확인해보겠습니다. 먼저 Tensorboard를 실행하기 위해 Anaconda Prompt를 실행합니다. 실행 이후 아래 그림과 같이 tensorflow 가상 환경으로 이동합니다.

코드 2.1. Anaconda Prompt에서 tensorflow 가상환경으로 이동

이제 아래 코드 2.2에서와 같이 학습이 완료된 파일의 위치를 알려주어 Tensorboard port값을 확인합니다. 파일이 저장된 위치는 특별하지 않으면 위와 같으나, 아래 코드로 실행되지 않는다면 직접 파일이 있는 경로를 찾아 지정해주면 됩니다. 참고로 상대 경로로 지정할 때./는 현재 폴더를, /는 루트를,../는 현재 위치의 상단 폴더를 의미합니다.

코드 2.2. tensorboard에 학습 완료된 파일 위치를 알려줌

이제 브라우저를 열고 port에 적힌대로 http://localhost:6006를 입력합니다. 참고로 tensorboard --logdir=./logs/ -port = 9999와 같이 기존에 다른 프로그램에서 디폴트 port값인 6006을 사용하고 있다면 port값을 변경할 수 있습니다. 이제 브라우저에서 Tensorboard를 열어 확인해보겠습니다.

그래프 2.1. 한번 학습한 뒤의 Tensorboard SCALARS

 

그래프 2.2. 여러번 학습한 뒤의 Tensorboard SCALARS

한번 학습한 뒤 Tensorboard를 열어 SCALARS에서 확인해보면 epoch에 따른 binary_accuracy의 변화와 loss의 변화를 그래프로 확인할 수 있습니다. 바로 위의 출력 1.1과 1.2에서 수치로 확인했을 때 보다 한눈에 들어오고, 바로 직전 포스트에서 의문이었던 급격히 loss가 줄어들고 accuracy가 늘어난 구간을 바로 알아볼 수 있습니다. 이처럼 SCALARS에서는 Epoch에 따른 loss와 metrics가 얼마나 변하는지를 보여줍니다. 물론 코드 작성에 따라 학습 속도 등의 다른 값들의 변화도 확인할 수 있습니다.

그래프 2.3. Tensorboard GRAPHS

 위는 모델을 시각화한 GRAPHS입니다. 위의 경우 입력 레이어 dense와 히든 레이어 dense 1,2 그리고 출력 레이어 dense3의 연산으로 metrics(binary_accuracy)와 loss가 구해지는 모델을 확인할 수 있습니다. 이외에도 코드 작성에 따라 시간에 따른 텐서의 분포와 다차원 텐서를 표현하는 DISTRIBUTIONS / HISTOGRAMS 등의 메뉴도 볼 수 있습니다.

 

이번 포스트에서는 keras 코드를 통해 XOR문제를 해결하고 이를 Tensorboard에서 시각적으로 확인해보았습니다. Github의 코드와는 조금 다른 부분이 있고 이를 하나하나 구글링을 통해 해결하다보니 시간이 꽤나 오래 걸렸지만 이제 우리는 시각적으로, 그래프로 모델의 결과를 확인할 수 있다는 큰 무기를 얻었습니다.