Deep Learning study

Convolutional Neural Network(CNN) Basic 본문

AI/Deep learning 을 위한 지식

Convolutional Neural Network(CNN) Basic

HwaniL.choi 2018. 1. 6. 22:54
반응형


아직은 강의를 보고 따라서 해보고 내용을이해하는 정도이므로 이론에 관한 내용들은 좀 더 익숙해지고 잘해진다면 머신러닝의 처음내용부터 차근차근 써 보아야겠다. 


어쨌든 오늘 해볼것은 CNN의 부분적인 내용들(?) 이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
 
sess = tf.InteractiveSession()
image = np.array([[[[1],[2],[3]],
                 [[4],[5],[6]],
                 [[7],[8],[9]]]], dtype = np.float32)
 
print("image.shape", image.shape)
weight = tf.constant([[[[1.]],[[1.]]],
                      [[[1.]],[[1.]]]])
 
print("weight.shape", weight.shape)
 
conv2d = tf.nn.conv2d(image,weight,strides=[1,1,1,1], padding = 'VALID')
conv2d_img = conv2d.eval()
print("conv2d_img.shape", conv2d_img.shape)
conv2d_img = np.swapaxes(conv2d_img,0,3)
 
for i, one_img in enumerate(conv2d_img) :
    print(one_img.reshape(2,2))
    plt.subplot(1,2,i+1),plt.imshow(one_img.reshape(2,2),cmap = 'gray')
plt.show()






cs


먼저 CNN에서 사용할 이미지를 간단하게 array로 만들어보았다. 


그 이미지(image)의 shape은 (1,3,3,1)이다. 의미하는 바는 3*3*1의 이미지 라는 뜻이다. 3*3은 2D이미지의 크기이고, 1은 color를 의미한다. (RGB색상을 표현하는 칼라이미지라면 3이 되겠다)


이제 필터(filter)를 설정할것인데 강의에서처럼 간단하게 2*2 필터를 쓸것이다. 그것을 weight로 두고 conv2d를 실행할 것이다. 


conv2d 함수의 parameter로는 이미지와, weight(앞서말한 필터), 그리고 strides, padding 이다.

stride는 필터를 적용시킬때 얼마만큼씩 움질일것인지를 정하는 것이고, padding은 conv layer를 거치면서 image가 작아지는것을 방지하기위해 image의 테두리에 0으로 채워넣는것을 말한다. (이 내용들은 나중에 이론에관해 쓸때 좀더 자세하게 공부해서 채워넣어야 겠다.)


그뒤로 eval()함수를 통해 conv2d를 실행시킨다.


그밑의 작업들은 matplotlib을 통해 화면에 출력시켜보기위한 작업이라고 하신다..일단은 CNN과 관련 없는것같으니 몰라도 될것 같다.



실행 결과들 이다.


conv를 거친 3*3 이미지가 2*2 가 되었고 그결과값으로 [[12 , 16], [24,28]]  이 되었다. 

이유는 필터를 적용시켰기 때문인데 과정을 잠깐 살펴보자면 


 1

 2

 3

 4

 5

 6

 7

 8

 9

이렇게 생겨먹은 image에 



 1

 1

 1

이렇게 생긴 필터(filter)를 수평방향, 수직방향 차례대로 적용을 시켜 계산을 해보면,


 1

 2

 3

 5

 6

 7

 8

 9


1*1 + 2*1 + 4*1 + 5*1 = 12


 1

 2

 3

 4

 5

 6

 7

 8

 9


2*1 + 3*1 + 5*1 + 6*1 = 16


(이하 그림생략..)

4*1 + 5*1 + 7*1 + 8*1 = 24

5*1 + 6*1 + 8*1 + 9*1 = 28

이된다. 따라서 위에 출력결과에 있는 값이 되는것이다.



이번엔 padding 값을 SAME으로 두어서 실행을 해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
 
sess = tf.InteractiveSession()
image = np.array([[[[1],[2],[3]],
                 [[4],[5],[6]],
                 [[7],[8],[9]]]], dtype = np.float32)
 
print("image.shape", image.shape)
weight = tf.constant([[[[1.]],[[1.]]],
                      [[[1.]],[[1.]]]])
 
print("weight.shape", weight.shape)
 
conv2d = tf.nn.conv2d(image,weight,strides=[1,1,1,1], padding = 'SAME')
conv2d_img = conv2d.eval()
print("conv2d_img.shape", conv2d_img.shape)
conv2d_img = np.swapaxes(conv2d_img,0,3)
 
for i, one_img in enumerate(conv2d_img) :
    print(one_img.reshape(3,3))
    plt.subplot(1,2,i+1),plt.imshow(one_img.reshape(3,3),cmap = 'gray')
plt.show()
cs


나머지는 다 똑같고 conv2d에서 padding 값을 'SAME'으로 주고,  reshape설정을 (3,3)으로 해주었다. 

왜냐하면 padding을 SAME으로 설정해주게 되면 필터를 거쳐도 원래 이미지와 같은 크기로 만들어 주기 때문에 원래 이미지와 크기를 같게 설정해 주어야 한다. 


실행 결과이다. 


어떻게 이렇게 되냐고 하면 padding을 해서 원래 image의 테두리에 0 이 추가되었기 때문이다. 


 1

 2

 3

 4

 5

 6

 0

 7

 8

 9

 0

 0

 0

 0

 0

이런식으로 들어가게 된다. 그래서 다시 위에서처럼 필터(filter)를 적용시켜주면 위의 결과값이 나오게 된다.



지금까지는 필터를 1개만 썼지만 이번에는 필터를 여러개를 써보도록 하자 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
 
sess = tf.InteractiveSession()
image = np.array([[[[1],[2],[3]],
                 [[4],[5],[6]],
                 [[7],[8],[9]]]], dtype = np.float32)
 
print("image.shape", image.shape)
weight = tf.constant([[[[1.,10.,-1.]],[[1.,10.,-1.]]],
                      [[[1.,10.,-1.]],[[1.,10.,-1.]]]])
 
print("weight.shape", weight.shape)
 
conv2d = tf.nn.conv2d(image,weight,strides=[1,1,1,1], padding = 'SAME')
conv2d_img = conv2d.eval()
print("conv2d_img.shape", conv2d_img.shape)
conv2d_img = np.swapaxes(conv2d_img,0,3)
 
for i, one_img in enumerate(conv2d_img) :
    print(one_img.reshape(3,3))
    plt.subplot(1,3,i+1),plt.imshow(one_img.reshape(3,3),cmap = 'gray')
plt.show()
cs


weight 부분을 바꾸어주고 나머지는 거의 그대로다.


결과값을 보도록 하자 


서로다를 세개의 필터를 사용했으므로 서로다른 결과값들이나오고, 그 모양새도 다르다.(실제 CNN에서는 훨씬 더 많은 필터들을 사용하여 서로다른 결과들로 인해 학습을 잘 시킬 수 있는것 같다.!)


다음으로는 POOL에대해 알아보도록 하자


1
2
3
4
5
6
7
8
9
10
11
12
13
import tensorflow as tf
import numpy as np
import matplotlib as plt
 
sess = tf.InteractiveSession()
image = np.array([[[[4],[3]],
                   [[2],[1]]]], dtype = np.float32)
 
pool = tf.nn.max_pool(image, ksize=[1,2,2,1], strides=[1,1,1,1], padding = 'SAME')
 
print(pool.shape)
print(pool.eval())Colored by Color Scripter


cs

결과값이다, 차례대로 pool.shape, pool.eval()값들이다.



pool은 원래는 이미지가 수많은 픽셀들로 이루어져 있기때문에 , 그중에 부분들만 추려내는듯한 작업이다.


그중에 max_pool이라는 것을 가장 많이 쓴다고한다. max_pool은 지역적인 부분에서 가장 두드러지는 한 부분만을 추려내는 작업이다. 


예시를 직관적으로 나타내어 보았다.

(padding을 했기때문에 0이 들어가게 된다)


 4

 0

 2

 0

 0

pool의 크기가 2*2*1이므로 초록색 색깔영역에 해당한다.

 max_pool 이므로 가장 큰값을 골라 4를 추출하게 된다.


 2

 0


마찬가지로 여기서는 3을 뽑아내게 되고 ,, 다음에 2, 다음엔 1이 된다. 

따라서 위에 보이는것과 같은 출력값이 나오게 된다.


 

반응형
Comments