Instructions to use OneclickAI/CNN_test_Model with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use OneclickAI/CNN_test_Model with Keras:
# Available backend options are: "jax", "torch", "tensorflow". import os os.environ["KERAS_BACKEND"] = "jax" import keras model = keras.saving.load_model("hf://OneclickAI/CNN_test_Model") - Notebooks
- Google Colab
- Kaggle
dd
Browse files
README.md
DELETED
|
@@ -1,226 +0,0 @@
|
|
| 1 |
-
---
|
| 2 |
-
license: apache-2.0
|
| 3 |
-
---
|
| 4 |
-
|
| 5 |
-
안녕하세요 Oneclick AI 입니다!!
|
| 6 |
-
오늘은, CNN 모델에 대해서 깊게 알아보는 시간을 가져볼까 합니다.
|
| 7 |
-
|
| 8 |
-
딥러닝에 이미지 데이터를 사용할 수 있게 된 이유가 바로 CNN의 합성곱 신경망 (Convolutional Neural Network, CNN) 덕분인데요, 오늘은 이 신경망이 어떻게 작동하는지, CNN은 어떻게 사진 속의 고양이와 개를 구분할 수 있는지 알아봅시다.
|
| 9 |
-
|
| 10 |
-
---
|
| 11 |
-
|
| 12 |
-
## 목차
|
| 13 |
-
1. CNN 핵심 원리 파악하기
|
| 14 |
-
- 왜 이미지에 CNN을 사용할까?
|
| 15 |
-
- CNN의 핵심 : 지역 수용 영역과 파라미터 공유
|
| 16 |
-
- CNN의 주요 구성 요소
|
| 17 |
-
2. 아키텍처를 통한 내부 코드 들여다 보기
|
| 18 |
-
- keras로 구현한 CNN 모델 아키텍쳐
|
| 19 |
-
- model.summary()로 구조 확인하기
|
| 20 |
-
3. 직접 CNN 구현해 보기
|
| 21 |
-
- 1단계 : 데이터 로드 및 전처리
|
| 22 |
-
- 2단계 : 모델 컴파일
|
| 23 |
-
- 3단계 : 모델 학습 및 평가
|
| 24 |
-
- 4단계 : 학습된 모델 저장하기
|
| 25 |
-
- 5단계 : 모델 사용하기
|
| 26 |
-
4. 나만의 CNN 모델 만들어보기
|
| 27 |
-
- 하이퍼파라미터 튜닝
|
| 28 |
-
- 모델 구조 변경하기
|
| 29 |
-
- 전이학습으로 성능 극대화 하기
|
| 30 |
-
|
| 31 |
-
---
|
| 32 |
-
|
| 33 |
-
## 1. CNN 핵심원리 파악하기
|
| 34 |
-
들어가기 앞서, CNN 이 어떤 원리로 이미지를 이해하는지 먼저 살펴보겠습니다.
|
| 35 |
-
|
| 36 |
-
**왜 이미지에 CNN을 사용할까??**
|
| 37 |
-
단순한 신경망(Fully Connected Layer)에 이미지를 입력하려면, 2차원인 이미지를 1차원의 긴 데이터로 펼치는 데이터 전처리 과정이 꼭 필요합니다.
|
| 38 |
-
이 과정에서 픽셀 간의 공간적인 정보가 전부 파괴됩니다.
|
| 39 |
-
이는 어떤 픽셀이 서로 이웃해 있는지 알 수 없어져서 눈이 코 옆에 있다는 위치정보 같은 내용이 가라저 버린다는 의미 입니다.
|
| 40 |
-
CNN은 이런 문제를 해결하기 위해 인간의 시신경 구조를 모방하여 설계되었습니다.
|
| 41 |
-
|
| 42 |
-
**CNN의 핵심 아이디어**
|
| 43 |
-
이것이 바로 지역적 수용영역과 파라미터 공유 입니다.
|
| 44 |
-
- 지역적 수용 영역(Local Receptive Fields)
|
| 45 |
-
신경망의 각 뉴런이 이미지 전체가 아닌, 작은 일부에만 연결됩니다.
|
| 46 |
-
이는 전체 픽셀에 대해서가 아닌 예시를 들면 3 * 3 픽셀에만 적용되는 방식인데요, 이를 통해 모델은 이미지의 전체 맥락보다 선, 모서리, 질감과 같은 지역적인 패턴을 먼저 학습하게 됩니다.
|
| 47 |
-
|
| 48 |
-
- 파라미터 공유(Parameter Sharing)
|
| 49 |
-
CNN은 이미지 전체를 필터를 통해서 스캔하는 느낌으로 학습합니다.
|
| 50 |
-
따라서, 한번 이미지의 특징을 학습하면, 이미지의 모든 위치에서 해당 특징을 감지할 수 있습니다.
|
| 51 |
-
이를 통해서 학습할 파라미터 수를 많이 줄일 수 있습니다.
|
| 52 |
-
|
| 53 |
-
**CNN의 주요 구성 요소**
|
| 54 |
-
앞선 아이디어를 바탕으로, CNN은 다음 3가지의 계층을 조합해서 만듭니다.
|
| 55 |
-
- 합성곱 계층 (Convolutional Layer)
|
| 56 |
-
학습 가능한 필터를 사용해서 이미지의 특징을 추출해 냅니다.
|
| 57 |
-
edge, corner 등을 추출하여 얻는 결과물을 특징 맵(Feature Map) 이라고 합니다.
|
| 58 |
-
|
| 59 |
-
- 풀링 계층 (Pooling Layer)
|
| 60 |
-
앞서 만든 맵의 크기를 줄이는 요약단계 입니다.
|
| 61 |
-
최대 풀링(Max Pooling)은 특정 영역헤서 가장 중요한 특징(가장 큰 값)만 남겨 계산량을 줄이고, 모델이 특징의 미세한 위치 변화에 덜 민감해 하도록 만듭니다.
|
| 62 |
-
|
| 63 |
-
- 완전 연결 계층 (Dense Layer)
|
| 64 |
-
추출된 특징들을 종합하여 최종적으로 이미지가 어떤 클래스에 속하는지 분류하는 역할을 합니다.
|
| 65 |
-
|
| 66 |
-
---
|
| 67 |
-
|
| 68 |
-
## 2. 아키텍처를 통한 내부 코드 들여다 보기
|
| 69 |
-
이제, 앞서 설명한 내용을 바탕으로, 실제 TensorFlow Keras 코드를 통해서 어떻게 작동하는지 실감해 봅시다.
|
| 70 |
-
다음은, Keras로 구현한 CNN 모델 아키텍쳐 입니다.
|
| 71 |
-
```python
|
| 72 |
-
import tensorflow as tf
|
| 73 |
-
from tensorflow import keras
|
| 74 |
-
|
| 75 |
-
# 모델 아키텍처 정의
|
| 76 |
-
model = keras.Sequential([
|
| 77 |
-
# Input: (28, 28, 1) 이미지
|
| 78 |
-
# 첫 번째 Conv-Pool 블록
|
| 79 |
-
keras.layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=(28, 28, 1)),
|
| 80 |
-
keras.layers.MaxPooling2D(pool_size=(2, 2)),
|
| 81 |
-
|
| 82 |
-
# 두 번째 Conv-Pool 블록
|
| 83 |
-
keras.layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
|
| 84 |
-
keras.layers.MaxPooling2D(pool_size=(2, 2)),
|
| 85 |
-
|
| 86 |
-
# 분류기(Classifier)
|
| 87 |
-
keras.layers.Flatten(),
|
| 88 |
-
keras.layers.Dropout(0.5),
|
| 89 |
-
keras.layers.Dense(10, activation="softmax"),
|
| 90 |
-
])
|
| 91 |
-
```
|
| 92 |
-
이제, 앞서 설명했던 이론이 이 코드에 어떻게 녹아있는지 알아봅시다.
|
| 93 |
-
|
| 94 |
-
- **합성곱 계층(Conv2D)**
|
| 95 |
-
```python
|
| 96 |
-
keras.layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=(28, 28, 1))
|
| 97 |
-
```
|
| 98 |
-
이 코드를 통해서, 합성곱 계층을 형성, 다음 아이디어를 구현합니다.
|
| 99 |
-
1. 지역 수용영역
|
| 100 |
-
```kernel_size(3, 3)```을 통해서 이미지 전체가 아닌 3 * 3 크기의 작은 영역만 보도록 만듭니다.
|
| 101 |
-
이렇게, 지역적 수용영역을 만듭니다
|
| 102 |
-
|
| 103 |
-
2. 파라미터 공유
|
| 104 |
-
```Conv2D``` 계층은 32개의 필터를 생성합니다.
|
| 105 |
-
3 * 3필터는 고유한 파라미터(가중치)세트를 가지며, 이 필터 하나가 이미지 전체를 스캔합니다.
|
| 106 |
-
만약, 파라미터 공유가 없다면, 각 3 * 3 위치마다 별도의 파라미터를 사용해야 하므로 크기가 엄청 커집니다.
|
| 107 |
-
하지만, 파라미터 공유 덕분에, 이 경우에서 ```(3 * 3 * 1 +1) * 32 = 320``` 개의 파라미터 만으로 이미지 전체의 특징을 추출할 수 있습니다.
|
| 108 |
-
|
| 109 |
-
- **풀링 계층(MaxPooling2D)**
|
| 110 |
-
```python
|
| 111 |
-
keras.layers.MaxPooling2D(pool_size=(2, 2))
|
| 112 |
-
```
|
| 113 |
-
앞선 합성곱 계층이 생성한 특징맵을 2* 2 크기의 영역으로 나누고, 각 영역에서 가장 큰 값만 남기라는 의미입니다.
|
| 114 |
-
이를 통해 맵 크기가 절반으로 줄어드는 **다운 샘플링**이 일어나고, 계사 ㄴ효율성이 높아져 모델 학습이 더 가벼워 집니다.
|
| 115 |
-
|
| 116 |
-
- **완전 연결 계층(Dense Layer)**
|
| 117 |
-
```python
|
| 118 |
-
keras.layers.Flatten()
|
| 119 |
-
keras.layers.Dense(10, activation="softmax")
|
| 120 |
-
```
|
| 121 |
-
최종 분류기 이며, 완전연결계층 입니다.
|
| 122 |
-
1. ```keras.layers.Flatten()```
|
| 123 |
-
완전연결계층은 1차원 백터를 입력으로 받기 때문에, Flastten 계층이 먼저 들어와 2차원 형태의 특징 맵을 한 줄로 펼쳐줍니다.
|
| 124 |
-
|
| 125 |
-
2. ```keras.layers.Dense(10, activation="softmax")```
|
| 126 |
-
이 코드가 완전연결계층이며, 보통 Dense Layer 라고 부릅니다.
|
| 127 |
-
특징백터를 입력받아 10개의 클래스 중 어느 클래스에 할당할지 최종적으로 결정합니다.
|
| 128 |
-
```activation="softmax"```는 각 클래스에 대한 예측값을 0 과 1 사이의 확률값으로 하게 하여 모든 확률의 합이 `이 되도록 만들어 줍니다.
|
| 129 |
-
|
| 130 |
-
---
|
| 131 |
-
|
| 132 |
-
## 3. 직접 CNN 구현해 보기
|
| 133 |
-
이제, 직접 CNN 학습 코드를 단계별로 구현해 봅시다.
|
| 134 |
-
|
| 135 |
-
**1단계. 데이터 로드 및 전처리**
|
| 136 |
-
모델이 학습할 데이터를 가져와 줍니다.
|
| 137 |
-
이번엔, 쉽게 불러올 수 있는 MNIST 손글씨 숫자 데이터셋을 가져와 적절한 형태로 전처리 하겠습니다.
|
| 138 |
-
|
| 139 |
-
```python
|
| 140 |
-
import numpy as np
|
| 141 |
-
import tensorflow as tf
|
| 142 |
-
from tensorflow import keras
|
| 143 |
-
from keras import layers
|
| 144 |
-
|
| 145 |
-
# Keras 라이브러리를 통해 MNIST 데이터셋을 손쉽게 불러옵니다.
|
| 146 |
-
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
|
| 147 |
-
|
| 148 |
-
# 정규화: 픽셀 값의 범위를 0~255에서 0~1 사이로 조정하여 학습 안정성 및 속도를 높입니다.
|
| 149 |
-
x_train = x_train.astype("float32") / 255.0
|
| 150 |
-
x_test = x_test.astype("float32") / 255.0
|
| 151 |
-
|
| 152 |
-
# 채널 차원 추가: 흑백 이미지(채널 1)의 차원을 명시적으로 추가합니다.
|
| 153 |
-
x_train = np.expand_dims(x_train, -1)
|
| 154 |
-
x_test = np.expand_dims(x_test, -1)
|
| 155 |
-
|
| 156 |
-
# 레이블 원-핫 인코딩: 숫자 '5'를 [0,0,0,0,0,1,0,0,0,0] 형태의 벡터로 변환합니다.
|
| 157 |
-
num_classes = 10
|
| 158 |
-
y_train = keras.utils.to_categorical(y_train, num_classes)
|
| 159 |
-
y_test = keras.utils.to_categorical(y_test, num_classes)
|
| 160 |
-
```
|
| 161 |
-
|
| 162 |
-
**2단계. 모델 컴파일**
|
| 163 |
-
모델 아키텍쳐를 정의하고 모델을 어떻게 학습시킬지에 대해 정합니다.
|
| 164 |
-
```python
|
| 165 |
-
model = keras.Sequential([
|
| 166 |
-
keras.Input(shape=(28, 28, 1)), # 입력 레이어
|
| 167 |
-
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
|
| 168 |
-
layers.MaxPooling2D(pool_size=(2, 2)),
|
| 169 |
-
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
|
| 170 |
-
layers.MaxPooling2D(pool_size=(2, 2)),
|
| 171 |
-
layers.Flatten(),
|
| 172 |
-
layers.Dropout(0.5),
|
| 173 |
-
layers.Dense(num_classes, activation="softmax")
|
| 174 |
-
])
|
| 175 |
-
|
| 176 |
-
model.compile(
|
| 177 |
-
# 손실 함수(Loss Function): 모델의 예측이 정답과 얼마나 다른지 측정합니다.
|
| 178 |
-
loss="categorical_crossentropy",
|
| 179 |
-
# 옵티마이저(Optimizer): 손실을 최소화하기 위해 모델의 가중치를 업데이트하는 방법입니다.
|
| 180 |
-
optimizer="adam",
|
| 181 |
-
# 평가지표(Metrics): 훈련 과정을 모니터링할 지표로, 정확도를 사용합니다.
|
| 182 |
-
metrics=["accuracy"]
|
| 183 |
-
)
|
| 184 |
-
```
|
| 185 |
-
|
| 186 |
-
**3단계. 모델 학습 및 평가**
|
| 187 |
-
```model.fit()```함수를 통해서 학습을 시작하고, 학습이 끝난 후 ```model.evaluate()```로 최종 성능을 확인합니다.
|
| 188 |
-
```python
|
| 189 |
-
batch_size = 128
|
| 190 |
-
epochs = 15
|
| 191 |
-
|
| 192 |
-
# 모델 학습 실행
|
| 193 |
-
history = model.fit(
|
| 194 |
-
x_train, y_train,
|
| 195 |
-
batch_size=batch_size,
|
| 196 |
-
epochs=epochs,
|
| 197 |
-
validation_data=(x_test, y_test)
|
| 198 |
-
)
|
| 199 |
-
|
| 200 |
-
# 학습 완료 후 최종 성능 평가
|
| 201 |
-
score = model.evaluate(x_test, y_test, verbose=0)
|
| 202 |
-
print(f"\nTest loss: {score[0]:.4f}")
|
| 203 |
-
print(f"Test accuracy: {score[1]:.4f}")
|
| 204 |
-
```
|
| 205 |
-
|
| 206 |
-
**4단계. 학습된 모델 저장하기**
|
| 207 |
-
모델을 저장하고, 불러올 수 있도록 합니다.
|
| 208 |
-
```python
|
| 209 |
-
# 모델의 구조, ��중치, 학습 설정을 모두 '.keras' 파일 하나에 저장합니다.
|
| 210 |
-
model.save("my_keras_model.keras")
|
| 211 |
-
print("\nModel saved to my_keras_model.keras")
|
| 212 |
-
```
|
| 213 |
-
|
| 214 |
-
위 단계를 전부 수행한 모델이 지금 이 허깅페이스 라이브러리에 들어있는 모델입니다. 이어서, 모델을 사용해 볼 떄, 위 코드를은 직접 실행하지 말고, 다음 코드를 실행시켜 주세요!
|
| 215 |
-
만일, 위 코드를 통해 직접 딥러닝을 시켭고 싶으시다면, Files의
|
| 216 |
-
train.py를 실행시켜 주세요!
|
| 217 |
-
|
| 218 |
-
**5단계. 모델 사용해 보기**
|
| 219 |
-
앞선 단계들을 거쳐 완성한 모델이 이 허깅페이스 페이지에 올라가 있습니다.
|
| 220 |
-
이제, 이 허깅페이스 페이지의 모델을 불러와서, 직접 사용해 보겠습니다.
|
| 221 |
-
Files의 test.py를 실행시켜 보세요!!
|
| 222 |
-
직접 준비한 숫자 손글씨를 모델에 입력으로 넣으면, 그 숫자가 어떤 숫자인지 맞춰줄 겁니다!!
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
## 4. 나만의 CNN 모델 만들기
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|