가장 쉬운 CNN (convolutional neural network) 예제 by 바죠

가장 쉬운 CNN (convolutional neural network) 예제

이미지 인식에서 압도적 성능을 발휘한 네트워크 모델이 CNN이다. 딥러닝의 시작을 알리는 알고리듬들 중 하나이다.
인공 신경망 발전의 역사에서 아주 중요한 의미를 가진다.  
특별히, 엄청난 양의 입력 데이터에 비해서, 결과는 숫자 하나가 되는 상황이 전형적인 CNN의 적용 범위이다.
즉, 이미지 파일처럼 많은 데이터가 들어가지만, 결과는 아주 간단한 것이다.
입력의 크기, 출력의 크기, 필터의 크기에 주의함으로써 데이터의 흐름을 이해할 수 있다.
입출력에서 데이터 크기의 엄청난 비대칭이 있을 때 사용한다.
텍스트 입력의 경우도 마찬가지이다. 엄청난 텍스트를 입력하고 요구하는 것이 Yes, No 둘 중 하나일 경우, 1차원 CNN은 아주 유용한 것이다. 전체적인 맥락을 찾아내는 데 유리한 것이 CNN이기 때문이다.

CNN의 우수한 성능의 물리적 배경에는 무엇이 있을까?
객체의 전반적인 이동에 대한 객체 특성 추출의 불변성(invariance)을 들 수 있다.
부분의 변화가 중요한 것이 아니고 전반적인 형태를 알아차리는 것이 중요할 때, 1, 2, 3차원에서 동일한 아이디어로 사용할 수 있다. 나무를 보는 것이 아니라 숲을 보고자 할 때 사용하는 알고리듬이다. 단순한 내적이 아니고 필터를 사용하는 내적이라고 볼 수도 있다.
대량의 입력 데이터가 들어오지만 최종적인 결과는 아주 간단한 것이다.
입출력의 심각한 비대칭이 존재한다. 긴 문장에서 문장이 내포하는 내용이 1이거나 0인것으로 분류하는 경우, 전형적인 CNN 방식이 필요한 경우이다.

딥러닝의 화려한 시작을 알리는 인공 신경망, 그것이 바로 CNN의 성공이다. 2012년이 딥러닝의 원년이다.

dropout:



------------------------------------------------------------------------------------------------------------------------
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, pooling
from keras.utils import np_utils
from keras.datasets import mnist
np.random.seed(123)                          # for reproducibility
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print(X_train.shape)
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)
print(X_train.shape)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
Y_train = np_utils.to_categorical(y_train, 10)
Y_test = np_utils.to_categorical(y_test, 10)
model = Sequential()
model.add(Conv2D(32, 3, 3, activation='relu', input_shape=(28,28, 1)))
print(model.output_shape)
model.add(Conv2D(32, 3, 3, activation='relu'))
model.add(pooling.MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, Y_train, batch_size=32, nb_epoch=10, verbose=1)
score = model.evaluate(X_test, Y_test, verbose=0)
print(model.metrics_names)
print(score)

60000/60000 [==============================] - 54s 906us/step - loss: 0.2094 - acc: 0.9362
Epoch 2/10
60000/60000 [==============================] - 53s 882us/step - loss: 0.0870 - acc: 0.9733
Epoch 3/10
60000/60000 [==============================] - 53s 883us/step - loss: 0.0664 - acc: 0.9805
Epoch 4/10
60000/60000 [==============================] - 53s 882us/step - loss: 0.0574 - acc: 0.9825
Epoch 5/10
60000/60000 [==============================] - 53s 882us/step - loss: 0.0475 - acc: 0.9849
Epoch 6/10
60000/60000 [==============================] - 53s 882us/step - loss: 0.0411 - acc: 0.9870
Epoch 7/10
60000/60000 [==============================] - 53s 881us/step - loss: 0.0371 - acc: 0.9875
Epoch 8/10
60000/60000 [==============================] - 53s 877us/step - loss: 0.0356 - acc: 0.9885
Epoch 9/10
60000/60000 [==============================] - 53s 879us/step - loss: 0.0321 - acc: 0.9898
Epoch 10/10
60000/60000 [==============================] - 53s 879us/step - loss: 0.0292 - acc: 0.9909
['loss', 'acc']
[0.0262326498150338, 0.9917]

------------------------------------------------------------------------------------------------------------------------
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
# Model / data parameters
num_classes = 10
input_shape = (28, 28, 1)

# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
# Make sure images have shape (28, 28, 1)
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")


# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
model = keras.Sequential(
    [
        keras.Input(shape=input_shape),
        layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
        layers.MaxPooling2D(pool_size=(2, 2)),
        layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
        layers.MaxPooling2D(pool_size=(2, 2)),
        layers.Flatten(),
        layers.Dropout(0.5),
        layers.Dense(num_classes, activation="softmax"),
    ]
)

model.summary()
batch_size = 128
epochs = 15

model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
------------------------------------------------------------------------------------------------------------------------
커널의 매개변수가 "가중치"에 해당한다. 커널은 유사도를 측정하는 것으로 받아들이면 된다.

"편향"도 존재한다.
편향은 가중치 요소들에 대해서 모두 다 적용된다.

입력데이터 주위를 둘러싸면서 0으로 채우는 작업을 "패딩"이라고 한다.  출력의 크기를 조절하기 위해서 사용한다.

스트라이드의 크기를 키우면 출력의 크기는 작아진다.

커널을 적용하는 간격을 조절하는 것이 스트라이드이다.

입력데이터의 채널 수 == 필터의 채널 수

풀링, 최대 풀링, 평균 풀링, 학습할 매개변수가 없다.
채널의 수가 변하지 않는다.
입력변화에도 작은 영향을 받는다.


마찬가지로 pooled feature도 정의할 수 있다.
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------
if True:
    print("Saving model...")
    train_dataset = tf.data.Dataset.from_tensor_slices(X_train).batch(BATCH_SIZE)
    test_dataset = tf.data.Dataset.from_tensor_slices(X_test).batch(BATCH_SIZE)
    input_shape_set=False
    if not input_shape_set:
        # Note: Why set input shape manually and why here:
        # 1. If I do not set input shape manually: ValueError: Model <main.CVAE object at 0x7f1cac2e7c50> cannot be saved because the input shapes have not been set. Usually, input shapes are automatically determined from calling .fit() or .predict(). To manually set the shapes, call model._set_inputs(inputs).
        # 2. If I set input shape manually BEFORE the first actual train step, I get: RuntimeError: Attempting to capture an EagerTensor without building a function.
        model._set_inputs(train_dataset.__iter__().next())
        input_shape_set = True
        # Note: Why choose tf format: model.save('my_model.h5') will return NotImplementedError: 
        # Saving the model to HDF5 format requires the model to be a Functional model or a Sequential model. 
        # It does not work for subclassed models, because such models are defined via the body of a Python method, 
        # which isn't safely serializable. 
        # Consider saving to the Tensorflow SavedModel format (by setting save_format="tf") or using save_weights.
        model.save('my_model_tf', save_format='tf' , overwrite=True, include_optimizer=True)        
------------------------------------------------------------------------------------------------------------------------






핑백

덧글

댓글 입력 영역

최근 포토로그



MathJax