1. TensorFlow - CNN (Convolutional Neural Networks)

  • 개요
    • Fully connected
    • Foward nn
    • split & merge 를 진행하는 NN (CNN 의 기본 원리 - 입력을 여러개로 나누어 받는다.)
  • 고양이 실험
    • 그림을 보여주었을 때 동작되는 뉴런들이 각각 다르다.
    • 입력을 나누어 받는다.

  • Conv, LELU, POOL 등을 여러번 반복한 뒤, FC 를 적용


  • Convolution Layer (32*32*3 형태의 이미지 (RGB))  -> 결과(32*32*filter_depth)
    • 1. 5*5*3 filter 지정 - 여기서 filter 는 w라 하자.
    • 2. 5*5*3 filter는 하나의 값을 가져온다.
      • Wx+b  를 이용하여 한 값으로 만들어낸다.
      • ReLU(Wx+b) 함수를 이용하여 0 이상의 값으로 출력
      • W의 
    • 3. 옆으로 filter (w) 를 옆으로 넘기면서 전체 이미지를 훑는다.
      • 이렇게 하면 28 * 28 의 Activation Map 이 생긴다.
    • 4. 다른 W 값을 준 또 다른 filter 를 만들어서 동일하게 전체 이미지를 훑는다.
    • 5. 6개의 필터를 적용하면,
      • pad 적용을 안할 경우 28*28  이다.
  • W 의 개수?  (5*5*3*depth)

  • pad : activation Map이 input 과 동일한 크기를 유지하기 위해 주는 값
    • 테두리에 0으로된 padding 을 추가해주는 방법
    • 원본 input 데이터에 대한 손실 방지

  • Activation Map 크기 계산 (N - input size , F - filter size)
    • (N - F +(2 x pad size))  / stride

  • Stride : filter 가 이동되는 값의 단위
    • Stride 값이 클수록 output 크기가 작아진다.

  • 예시) 이미지에서 7 * 7 input 일 때 3*3 filter 가 있다면, 한번 훑는 것으로 몇개의 값을 가져올 수 있을까?
    • 한칸씩 움직일 때 (stride = 1)
      • 5*5
    • 두칸씩 움직일 때 (stride = 2)
      • 3*3
    • 공식 (N - input size , F - filter size)
      • (N-F)/stride +1
    • 사이즈가 줄어들었다..


  • 예시) 이미지에서 7 * 7 input 일 때 3*3 filter 가 있다면, 한번 훑는 것으로 몇개의 값을 가져올 수 있을까? (pad 는 1px 이다.)
    • pad 를 감싸게 되면 9*9로 이미지가 변한다.
      • 즉, 결과값은 같은 사이즈의 데이터가 나온다.
    • pad 를 추가하여 이미지 사이즈가 줄어드는 것을 방지.
    • 일반적으로는 output 의 사이즈가 동일하게 맞춰줄 수 있는 pad 값을 준다.

                






  • Pooling layer (Sampling)
    • 작게 resize 한 뒤, 다시 쌓는다.
    • filter 사이즈 내에서 하나의 샘플링 데이터를 추출하는것.
  • MAX POOLING
    • max pool  filter 가 2*2일 때, stride 가 2일때,
    • 가장 큰값을 필터에서 추출.

  • Fully connected 
    • 마지막 결과값은 Softmax 를 사용하여 처리.  (sigmoid)



다양한 활용의 예

  • LeNet-5
    • input 32*32
    • filter 5*5, stride 1
    • subsampling - 2*2, stride 2

  • C1 : Activation Map(28*28) *6 (Convolution 6 filters)
  • S2 : Activation Map(14*14) *6 (subsampling)
  • C3 : Activation Map(10*10) *10 (Convolution 10 filters)
  • S4 : Activation Map(5*5) *16 (subsampling)
  • C5 : 120 (Full connection)
  • F6 : 84 (Full connection)
  • output : 10 (Gaussian connections)

(N-F)/stride +1

  • AlexNet
    • 최초로 ReLU 사용, ensemble 을 이용하여 에러율을 줄임.
    • input 227*227*3 
    • First layer : filter size(11*11*3) *96 filters , stride 4
    • -> (55*55) * 96 filters  (버림)

                





  • ResNet 
    • AlexNet : 8layers,
    • VGG : 19layers,
    • ResNet : 152 layers

    • FastFoward 를 통해서 layer 가 많을수록 학습이 어려운 문제를 해결함.
  • 알파고








CNN
  • 주어진 이미지 벡터에 필터라는 것을 대어서 한개의 값을 뽑는데, 위치를 이동하면서 뽑기 때문에 결국 여러개의 값을 뽑아낸다.
  • 샘플링의 과정을 통해 데이터량을 축소시킨다.
    • 이 두 과정이 CNN


  1. Simple Convolution Layer (예제)
  • 조건
    • 3*3*1 image
    • 2*2*1 filter
    • stride : 1*1
  • Convolution 결과 예측
    • 2*2*1 의 데이터가 추출됨.
    • tensorflow 에서는 값이 알아서 추출되기 때문에 계산할 필요 없음.

  • 이미지를 만들어볼까요?
    • 이미지 생성 코드
sess = tf.InteractiveSession()
image = np.array([[[[1],[2],[3]],
                [[4],[5],[6]]],
                [[7],[8],[9]]]], dtype=np.float32)
print(image.shape)
# 결과값 : (1,3,3,1) - 사용할 이미지는 1개이며, 3*3의 이미지이며 컬러는 1개이다.

# imshow 라는 라이브러리를 사용하여 이미지를 생성한다.
pit.imshow(image.reshape(3,3), cmap='Greys')
  • 만들어진 이미지
                            


  • 이제 W (Filter) 를 정의해보자.
    • Filter 의 shape은 (2,2,1,1) - 2*2 사이즈에 한가지 컬러, 그리고 filter 개수가 1개이다.
    • 값 : [[[1.]],[[1.]]],      - !!!!값은 네개 다 같아야하는지??- 같아야되긴하는데...왜?
                                     [[1.]],[[1.]]]]  - shape = (2,2,1,1)  
                                        


  • 계산하면? (stride 는 1*1 이며 패딩은 없음)
    • 첫번째칸 1*1 + 2*1 + 4*1 + 5*1 = 12
    • 두번째칸 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
                            


  • 위 계산을 tensorFlow에서는..
# print("imag:\n", image)
print("image.shape", image.shape)
# 결과값 : image.shape (1, 3, 3, 1)

# 가장 depth 가 낮은 것은 필터 개수.
weight = tf.constant([[[[1.]],[[1.]]],
                      [[[1.]],[[1.]]]])
print("weight.shape", weight.shape)
# 결과값 : weight.shape (2, 2, 1, 1)

# tf.nn.conv2d 함수 하나로 Convolution 해결.
conv2d = tf.nn.conv2d(image, weight, strides=[1, 1, 1, 1], padding='VALID')

# tensorflow 실행
conv2d_img = conv2d.eval()

###### 결과값 확인 #######
print("conv2d_img.shape", conv2d_img.shape)
# 결과값 : conv2d_img.shape (1, 2, 2, 1)

#시각화 결과 출력
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')
 
                    
                


  • SAME Padding
    • VALID : padding 을 주지 않는다.
    • SAME : 원래 이미지와 똑같은 shape 를 원할 때 사용.
    • 소스코드
...
# tf.nn.conv2d 함수 하나로 Convolution 해결.
conv2d = tf.nn.conv2d(image, weight, strides=[1, 1, 1, 1], padding='SAME')
...

                


  • 필터를 여러개 쓸 경우.
    • 소스코드

...
# 필터가 3개.
weight = tf.constant([[[[1.,10.,-1.]],[[1.,10.,-1.]]],
                              [[[1.,10.,-1.]],[[1.,10.,-1.]]]])
...

                  




이 장은 이어서...
  • MAX POOLING
    • 소스코드
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='VALID')
print(pool.shape)
# 결과값 (1,1,1,1)
print(pool.eval())
# 결과값 [[[[4.]]]]
                 








출처 : https://docs.google.com/presentation/d/1h90rpyWiVlwkuCtMgTLfAVKIiqJrFunnKR7dqPNtI6I/edit#slide=id.g1ed3f9369e_0_449









'TensorFlow' 카테고리의 다른 글

TensorFlow - ReLU  (0) 2018.04.20
TensorFlow - XOR 문제 딥 러닝으로 풀기.  (0) 2018.03.26
TensorFlow - 딥러닝의 기본 개념  (0) 2018.03.26
TensorFlow - Softmax regression  (0) 2018.03.25
TensorFlow - Logistic regression  (0) 2018.03.25

+ Recent posts