save the world

4주차 본문

Deep Learning Diary

4주차

함안조씨 2018. 2. 6. 17:20

<2018.02.06. 화>

Model Output Check
학습모델의 최종결과인 l5를 확인하기위해 l5를 numpy.array로 받았는데 몇번의 iteration 후 모든 픽셀의 값이 0으로 나왔다. 원인을 찾기위해 weight 값 (커널)을 확인하려고 tensorboard를 사용했다
(아래문단).

Tensorboard: Weight Histogram 
텐서보드에서 첫번째 레이어의 weight값이 한번 학습했을 때 아주 크게 변하는 것을 확인하고 이를 장기적인 측면에서 확인하고자 텐서보드를 사용하여 그래프로 보고싶었다. weight값을 텐서보드로 넘기기 위해서 모든 weight값을 저장하기위해 tf.summary.histogram("w1_summ", w1) 명령어를 사용하고 실행하였더니  InvalidArgumentError: Nan in summary histogram for: 이런 에러메세지가 발생하였다. python에서 Nan은 Not a number 로서 "숫자가 아니다"라는 의미를 가지며 숫자가 아니기 때문에 histogram에 등록되지 않았던것이다. 문제를 해결하기위해 googling 한 결과(https://github.com/tflearn/tflearn/issues/304) learning rate를 낮춘다면 문제를 해결할 수 있다고 하여 step_size를 0.5에서 0.01로 내림으로써 문제를 해결하였다.

Tensorboard: checking(looking) hidden layer output


Hidden layer의 output을 보기위해서 _, l1_out = sess.run([train_op, l1]) 을 수행하면 오류가 난다. l1이라는 변수가 없기 때문인 것 같다. 그래서 l1 = tf.placeholder('float', [None, 14, 14, 32]) 로 선언후 sess.run([train_op, l1])을 수행하면 l1의 히든레이어 결과가 l1_out에 numpy.array 값으로 저장된다.

Python dimension switch
tensorflow 사용중 weight의 dimension이 3(행)x3(열)x1(흑백색깔차원)x32(커널수)인 경우가 있었는데 weight를 
보기위해 디버깅모드에 들어가 봤더니 [0][0][:][:]식의 값만 나오는 것이었다. 3x3 의 이미지인 [:][:][0][0]으로 보고싶어서 w[:][:][0][0]를 해 보았으나 전혀 변동이 없어서 np.swapaxes()라는 것을 사용했다.
w = np.swapaxes(w, 0, 2) 명령후 w의 dimension은 1x3(열)x3(행)x32(커널수)
w = np.swapaxes(w, 1, 3) 명령후 w의 dimension은 1x32(커널수)x3(행)x3(열)
으로 바뀌면서 디버깅모드에서도 3x3의 매트릭스 값을 확인 할 수 있었다.
※Tensorflow 에서는 tf.transpose() 함수가 np.swapaxes()와 동일한 작동을 함.

현재까지 python code

69~71번째 줄은 Blurred image가 만들어지기위해 convolution을 수행하다 보니 0~255사이의 값을 가지던 픽셀값들이 0~255범위를 넘어서게되므로 이를 0~255 사이의 값으로 normalize 시키기 위해 추가한 코드이다. normalize를 위해 blurred image의 min, max 값을 이용하여 0~255사이의 정수로 나타냈다. (소수점이하는 버림)
또 다른 normalize 방법으로는 scikit-learn 라이브러리에 포함된 함수를 사용하여 편하게 해결할 수 있다. 아래의 코드는 normalize 뿐만 아니라 다른 편리한 preprocessing 함수들이 예제로 나와있다.
출처: 
http://iostream.tistory.com/111

120번째 줄부터 123번째 줄은 tensorflow를 sess.run 시키고 난 뒤 tensor의 결과를 numpy.arrary로 받아내기 위한 코드이다.
125~158번째 줄 까지는 numpy.array의 차원을 바꿔 debuging 할 때 이미지를 픽셀단위의 값으로 직접 보기위해 차원의 순서를 바꿔준 명령어이다. 기존 차원은 (batchSize, Row, Colum, Channel) 이었으나 그냥 디버깅하면 Colum, Channel 만 보여주기 때문에 이를 
(batchSize, Channel, Row, Colum)로 바꿔 픽셀별 값을 직접 확인하였다.
162~168까지는 layer의 convolution이 제대로 동작하고 있는지 확인하기위한 코드이다. 블러이미지 B와 w1o의 convolution 결과를 sum으로 출력해준다.

Convolution 결과분석
Convolution이 제대로 되고있는지 확인하기위해 모든 레이어의 output을 numpy.array로 출력하여 convolution이 제대로 동작하는 것을 확인했으나 convolution의 결과 값이 0이 되도록 Weight가 학습되어 ReLu를 지나면서 모든 픽셀값이 0으로 수렴하므로 학습이 되지 않는(코드에는 문제가 없으나) 것으로 결정지어 Network 구조를 Fully Convolution Network에서 VGGNet으로 바꾸기로 하였다. VGGNet이 Regression문제에 높은 성능을 보이기 때문이다.
개인적인 견해로는 현재까지의 코드가 하나의 픽셀 값이 softmax를 통하여 나오는 것이 아닌 MSE 를 Loss로 삼아 나온 결과이기 때문에 softmax를 이용하여 결과가 나오도록 한다면 가능성이 있다고 생각된다.

'Deep Learning Diary' 카테고리의 다른 글

7주차  (0) 2018.03.02
6주차  (0) 2018.02.19
3주차  (0) 2018.01.31
2주차  (0) 2018.01.22
1주차  (0) 2018.01.18