티스토리 뷰

ConvNet은 이미지와 텍스트 분류 외에도 여러가지 분야에서 좋은 성능을 발휘한다.

이것의 과정을 크게 3가지로 나눠볼 수 있다.

1. convolution이라는 과정을 통해 filtering 하여 여러가지 convolution layer로 값을 뽑아내는 방법

2. 대이터량이 너무 많아지니 작게 subsampling을 한다.

3. 나눠진 값들(특징들이 추출된 값들)을 최종적으로 일반적인 (forward NN, FC)를 통해서 분류나 회귀를 한다.

 

CNN이 특히 이미지에 대해서 잘 동작을 하는데, 한국 아산대학교 컨테스트에서 CNN을 이용해 CT images 결과를 내어 수상하기도 했었다.

 

 

전에 블로그에 올렸었던 풀링 과정이다. convolution하는 과정과 sampling하는 과정이 Tensorflow에서는 어떻게 쓰이는지 확인해보자. 

 

다음을 구현해보자.

 

 

 

 

 

 

텐서플로우 실습을 하기 위해 먼저 이미지를 만들자.

In [1]:
%matplotlib inline
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
 

1부터 9까지의 숫자로 이루어진 matrix를 시각화 해보자.

In [3]:
sess = tf.InteractiveSession()
image = np.array([[[[1],[2],[3]],
                   [[4],[5],[6]], 
                   [[7],[8],[9]]]], dtype=np.float32)
print(image.shape)
plt.imshow(image.reshape(3,3), cmap='Greys')
 
(1, 3, 3, 1)
Out[3]:
<matplotlib.image.AxesImage at 0x1286ce35400>
 
 

1 filter (2,2,1,1) with padding: VALID

weight.shape = 1 filter (2 , 2 , 1, 1)
2x2, 색깔(1 = shape의 마지막에 있는 1과 같다), 필터개수(1)을 의미한다.

image

필터를 올려놓고 서로 마주보는 숫자끼리 곱해서 하나의 값을 뽑아낸다.

In [3]:
# print("imag:\n", image)
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')
 
image.shape (1, 3, 3, 1)
weight.shape (2, 2, 1, 1)
conv2d_img.shape (1, 2, 2, 1)
[[ 12.  16.]
 [ 24.  28.]]
 
 

1 filter (2,2,1,1) with padding:SAME

image
 

same을 사용하여 입력과 출력의 크기를 같도록 padding함

In [4]:
# print("imag:\n", image)
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')
 
image.shape (1, 3, 3, 1)
weight.shape (2, 2, 1, 1)
conv2d_img.shape (1, 3, 3, 1)
[[ 12.  16.   9.]
 [ 24.  28.  15.]
 [ 15.  17.   9.]]
 
 

3 filters (2,2,1,3)

 

필터를 여러개 쓰기 위해서는 필터의 개수를 의미하는 weight.shape=(a,b,c,d)중 d의 값을 늘려주면 된다. 필터를 d개 쓰면 d개의 img가 나온다.

In [5]:
# print("imag:\n", image)
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')
 
image.shape (1, 3, 3, 1)
weight.shape (2, 2, 1, 3)
conv2d_img.shape (1, 3, 3, 3)
[[ 12.  16.   9.]
 [ 24.  28.  15.]
 [ 15.  17.   9.]]
[[ 120.  160.   90.]
 [ 240.  280.  150.]
 [ 150.  170.   90.]]
[[-12. -16.  -9.]
 [-24. -28. -15.]
 [-15. -17.  -9.]]
 
 

MAX POOLING

imageimage
 

데이터를 subsampling한다고 생각하면 된다. 위와 같이 주어진 이미지가 있을 때 그것에 대해서 kernelsize( ,weight-size,filter-size, )를 정해주고 stride(,1,1, )가 얼마인지 정해주고 패딩을 어떻게 할지만 정해주면 알아서 뽑아준다.
pooling중에 max풀링이 cnn과 동작을 잘해서 많이 사용한다. 위 이미지를 가지고 maxpooling을 하면 똑같은 이미지가 나온다.

In [6]:
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)
print(pool.eval())
 
(1, 1, 1, 1)
[[[[ 4.]]]]
 

SAME: Zero paddings

image
In [7]:
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())
 
(1, 2, 2, 1)
[[[[ 4.]
   [ 3.]]

  [[ 2.]
   [ 1.]]]]
 

실전 img에서는 어떻게 적용되는지 확인해보자.

 

MNIST Convolution layer

In [8]:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# Check out https://www.tensorflow.org/get_started/mnist/beginners for
# more information about the mnist dataset
 
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
In [9]:
img = mnist.train.images[0].reshape(28,28)
plt.imshow(img, cmap='gray')
Out[9]:
<matplotlib.image.AxesImage at 0x1152b2048>
 
In [10]:
sess = tf.InteractiveSession()

img = img.reshape(-1,28,28,1) # 여러개 img들의 28x28의 컬러1가지이다.
W1 = tf.Variable(tf.random_normal([3, 3, 1, 5], stddev=0.01)) # 3x3 , 컬러1, filter5개
conv2d = tf.nn.conv2d(img, W1, strides=[1, 2, 2, 1], padding='SAME') 
# 옆으로 아래로 2칸씩 움직이겠다. stride가 1x1일때는 입력과 출력이 같지만, 2x2일때는 반으로 줄어들게 된다.(출력은 14x14)

print(conv2d)
sess.run(tf.global_variables_initializer())
conv2d_img = conv2d.eval()
conv2d_img = np.swapaxes(conv2d_img, 0, 3)
for i, one_img in enumerate(conv2d_img):
    plt.subplot(1,5,i+1), plt.imshow(one_img.reshape(14,14), cmap='gray')
 
Tensor("Conv2D_3:0", shape=(1, 14, 14, 5), dtype=float32)
 
 

조금씩 다른 이미지가 5개가 출력됐다. weight가 random이므로 서로 다른 색이고, filter가 5개 이므로 이미지가 5개 나왔다.

 

MNIST Max pooling

In [11]:
pool = tf.nn.max_pool(conv2d, ksize=[1, 2, 2, 1], strides=[
                        1, 2, 2, 1], padding='SAME')
# conv2d는 앞에서 출력된 img, kersize는 2x2 , padding은 same이지만 stride가 2x2이므로 출력은 7x7
print(pool)
sess.run(tf.global_variables_initializer())
pool_img = pool.eval()
pool_img = np.swapaxes(pool_img, 0, 3)
for i, one_img in enumerate(pool_img):
    plt.subplot(1,5,i+1), plt.imshow(one_img.reshape(7, 7), cmap='gray')
 
Tensor("MaxPool_2:0", shape=(1, 7, 7, 5), dtype=float32)
 

'beginner > 파이썬 딥러닝 기초' 카테고리의 다른 글

Class, tf.layers, Ensemble (MNIST 99.5%)  (0) 2019.05.13
TensorFlow로 MNIST 99% 구현하기  (0) 2019.05.13
ConvNet의 활용  (0) 2019.05.12
ConvNet Max Pooling  (0) 2019.05.12
ConvNet의 conv 레이어 만들기  (0) 2019.05.12
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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 26 27 28
29 30 31
글 보관함