본문 바로가기

카테고리 없음

[deepLearning]CNN filter의 number, filter의 size

알아볼것

  • self.conv1 = layers.Conv2D(32, kernel_size=5, activation=tf.nn.relu) 에서 계수들이 의미하는 바
  • convolution layer를 지날때 마다 텐서의 크기가 어떻게 바뀌는지

계수들의 의미

kernel_size=5

5는 filter의 한변의 크기를 의미하며 filter는 kernel, window등이라고도 불린다.

가운데 보라색이 필터

원래 그림에서 이미지 사이즈는 7*7 이었는데 3*3인 필터랑 컨볼루션 하면 (7+1)-3 = 5사이즈의 이미지가 된다.

32 : number of filter

32는 filter의 개수를 의미한다. 위의 그림에서 보라색 filter 같은게 32개가 있다고 보면된다.

LeCun논문의 CNN구조

위의 그림에서 INPUT 이미지를 컨볼루션 하면 28*28의 이미지가 6개 나오는데 filter를 6개를 컨볼루션 해줘서 그렇다.

filter 종류들

예전 영상처리에는 저 filter들을 직접 만들어서 활용했다.

(첫번째 필터를 컨볼루션 해주면 대각선 성분의 이미지가 추출된다.)

CNN에서는 저 filter이 정해진게 아니라 학습을 통해 만들어 지게 되는 것이다.

 

class ConvNet(Model):
    def __init__(self):
        super(ConvNet, self).__init__()
        self.conv1 = layers.Conv2D(32, kernel_size=5, activation=tf.nn.relu)
        self.maxpool1 = layers.MaxPool2D(2, strides=2)
        self.conv2 = layers.Conv2D(64, kernel_size=3, activation=tf.nn.relu)
        self.maxpool2 = layers.MaxPool2D(2, strides=2)
        self.flatten = layers.Flatten()
        self.fc1 = layers.Dense(1024)
        self.dropout = layers.Dropout(rate = 0.5)
        self.out = layers.Dense(num_classes)

위처럼 CNN을 구성하고 각 단계별 shape을 구해보자.

Mnist이미지를 traindata로 사용했으므로 입력이미지는 28*28이다.

 

입력이미지: 28*28

conv1이후: 24*24 (28+1-5)

maxpoo1이후: 12*12 (2*2마다 한개씩 최대값을 취해준다)

conv2이후: 10*10 (12+1-3)

maxpool2이후: 5*5

의 shape을 가진다.

print(x)한 결과

max와 conv는 4차원 텐서가 출력이 되는데

128은 train data의 한 batch 사이즈이며 맨뒤의 32와 64 는 각각 filter의 개수가 된다.(##개수는 좀더 설명 필요)

 

from __future__  import  absolute_import, division, print_function

import tensorflow as tf
from tensorflow .keras import Model, layers
import numpy as np

num_classes = 10
learning_rate = 0.001
training_steps = 200
batch_size = 128
display_step = 10

conv1_filters = 32
conv2_filters = 64
fc1_units = 1024

from tensorflow.keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = np.array(x_train, np.float32), np.array(x_test, np.float32)
x_train, x_test = x_train / 255., x_test / 255.

train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_data = train_data.repeat().shuffle(5000).batch(batch_size).prefetch(1)

class ConvNet(Model):
    def __init__(self):
        super(ConvNet, self).__init__()
        self.conv1 = layers.Conv2D(32, kernel_size=5, activation=tf.nn.relu)
        self.maxpool1 = layers.MaxPool2D(2, strides=2)
        self.conv2 = layers.Conv2D(64, kernel_size=3, activation=tf.nn.relu)
        self.maxpool2 = layers.MaxPool2D(2, strides=2)
        self.flatten = layers.Flatten()
        self.fc1 = layers.Dense(1024)
        self.dropout = layers.Dropout(rate = 0.5)
        self.out = layers.Dense(num_classes)

    def call(self, x, is_training = False):
        x = tf.reshape(x, [-1, 28, 28, 1])
        x = self.conv1(x)
        #print("conv1", x.shape)
        x = self.maxpool1(x)
        #print("maxpool1", x.shape)
        x = self.conv2(x)
        #print("conv2", x.shape)
        x = self.maxpool2(x)
        #print("maxpool2",x.shape)
        x = self.flatten(x)
        x = self.fc1(x)
        x = self.dropout(x, training=is_training)
        x = self.out(x)
        if not is_training:
            x=tf.nn.softmax(x)
        return x
conv_net = ConvNet()

def cross_entropy_loss(x,y):
    y = tf.cast(y, tf.int64)
    loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels =y, logits =x)
    return tf.reduce_mean(loss)

def accuracy(y_pred, y_true):
    correct_prediciton = tf.equal(tf.argmax(y_pred, 1), tf.cast(y_true, tf.int64))
    return tf.reduce_mean(tf.cast(correct_prediciton, tf.float32), axis=-1)
optimizer = tf.optimizers.Adam(learning_rate)
def run_optimization(x, y):
    with tf.GradientTape() as g:
        pred = conv_net(x, is_training =True)
        loss = cross_entropy_loss(pred, y)
    trainable_variables = conv_net.trainable_variables
    gradients = g.gradient(loss, trainable_variables)

    optimizer.apply_gradients(zip(gradients, trainable_variables))

# Run training for the given number of steps.
for step, (batch_x, batch_y) in enumerate(train_data.take(training_steps), 1):
    # Run the optimization to update W and b values.
    run_optimization(batch_x, batch_y)
    if step % display_step == 0:
        pred = conv_net(batch_x)
        loss = cross_entropy_loss(pred, batch_y)
        acc = accuracy(pred, batch_y)
        print("step: %i, loss: %f, accuracy: %f" % (step, loss, acc))

pred = conv_net(x_test)
print("Test Accuracy: %f" % accuracy(pred, y_test))
import matplotlib.pyplot as plt
n_images = 5
test_images = x_test[:n_images]
predictions = conv_net(test_images)

# Display image and model prediction.
for i in range(n_images):
    plt.imshow(np.reshape(test_images[i], [28, 28]), cmap='gray')
    plt.show()
    print("Model prediction: %i" % np.argmax(predictions.numpy()[i]))

참고사진