일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- tensorflow
- 다익스트라
- 미래는_현재와_과거로
- dfs
- 너비 우선 탐색
- 이분 탐색
- DP
- 분할 정복
- 알고리즘
- 조합론
- dropout
- 자바스크립트
- pytorch
- object detection
- 문자열
- c++
- 크루스칼
- 가끔은 말로
- 백트래킹
- 가끔은_말로
- BFS
- Overfitting
- lazy propagation
- 세그먼트 트리
- back propagation
- 회고록
- NEXT
- 플로이드 와샬
- 우선 순위 큐
- 2023
- Today
- Total
Doby's Lab
Cat & Dog Binary Classification Project 본문
Cat & Dog Binary Classification Project
도비(Doby) 2022. 12. 12. 23:49✔️ Contents
- Intro
- Purpose
- Tool
- Step 1: Get Data
- Step 2: Path to Image
- Step 3: Modeling
- Outro
✔️ Intro
12월이 되고 해를 마무리 짓는 시기가 되면서 올해 부족했던 것들을 찾는 시간을 가졌었습니다. 인공지능에 대한 이론과 간단한 기초 실습을 공부해봤던 8월 말부터 9월 말까지 2개월 후 남은 건 기초뿐이라 느꼈습니다. 그리고, 11월쯤 Kaggle에서 곧바로 하고 싶던 인공지능을 공부하기에는 다른 분들의 Notebook 코드가 하나도 이해되지 않았었습니다. 그래서 스스로를 판단하기에 '중간에 무언가를 건너뛴 것 같다.'라는 생각이 들었습니다. 프로젝트 하나 없이 무언가를 시도하려 했던 건 너무 무모했던 것 같습니다. 당연히 공부 후에 남은 것도 없었고요. 그래서 '기초적인 프로젝트 하나라도 해보자. 지식들을 쌓기만 해서는 많은 부분에서 한계가 있을 거고, 어떻게 다루어야 할지 알아야 다음 단계가 보이지 않을까'라는 마음에 간단한 프로젝트를 시작하게 되었습니다.
Duration
- 22.12.05 ~ 22.12.08 (4일)
- 22.12.12 (Modeling 개선)
Project Github
https://github.com/drawcodeboy/Cat_n_Dog_Classification
GitHub - drawcodeboy/Cat_n_Dog_Classification: 고양이와 개를 Binary Classification하는 첫 인공지능 프로젝트입
고양이와 개를 Binary Classification하는 첫 인공지능 프로젝트입니다. Contribute to drawcodeboy/Cat_n_Dog_Classification development by creating an account on GitHub.
github.com
Version Update
Version 2
https://draw-code-boy.tistory.com/506
Dog & Cat Binary Classification Project Version 2
✔️ Contents Intro Purpose Tool Project Structure Data Preprocessing Modeling (Overfitting) Outro Postings related Project Reference ✔️ Intro 기존의 프로젝트를 끝내고 나서 Version 1은 55.51%라는 성능이 '반은 맞추고, 반은
draw-code-boy.tistory.com
Version 2.1
https://draw-code-boy.tistory.com/523
Cat & Dog Binary Classification Project Version 2.1 (FINAL)
✔️ Contents Intro Modifications Modeling Outro Postings related Project ✔️ Intro Version 2를 끝내고 난 후, 공부할 것들을 다 정리하여 공부하는 시간을 갖는 Project After Project의 시간을 가졌었습니다. 공부했었
draw-code-boy.tistory.com
✔️ Purpose
이번 프로젝트의 목적은 '성능이 좋은' 모델을 만들어보는 것이 아닌 인공지능을 만들기 위한 코드들은 어떤 구조로 이루어지며 쓰이는 라이브러리, 패키지, 모듈들을 탐색해보는 시간들을 가져보는 것이 목표입니다.
단순한 프로젝트로 Kaggle Dataset에서 데이터를 가져와 개와 고양이를 분류하는 Binary Classification 모델을 구현하려 했습니다.
Dataset Link
✔️ Tool
IDE: Google Colab
Language: Python
Main Library: Tensorflow, Numpy, PIL, os 등
✔️ Step 1: Get Data
Dataset을 Kaggle로부터 다운로드하여 Google Drive에 저장하여 Colab에서 마운트 해주었습니다. 하지만, '셀에서 파일들을 어떻게 가져오는가'가 처음 문제였습니다. 이를 도와주는 Python 내장 모듈 os를 사용하여 해결할 수 있었습니다. os는 운영체제(Operating System)의 준말로 파이썬에서 운영체제 역할을 할 수 있게 도와줍니다.
+ Kaggle 노트북의 셀 초기 부분들을 보면 항상 os의 메서드를 사용하여 어떤 작업을 하는 과정을 볼 수 있었는데 Dataset을 가져오는 것이었다는 걸 알 수 있었습니다.
이번에 os의 메서드는 4가지를 사용해봤습니다.
- os.listdir()
- os.endswith()
- os.walk()
- os.path.join()
프로젝트의 셀을 보며 어떤 역할을 수행하여 어떤 식으로 사용했는지 알아보겠습니다.
train_path = '/content/drive/MyDrive/training_set/training_set'
test_path = '/content/drive/MyDrive/test_set/test_set'
편의를 위해 문자열 변수를 사용하여 Dataset(Train set, Test set)의 경로를 담아줍니다.
print(os.listdir(train_path))
print(os.listdir(test_path))
# Output
['cats', 'dogs']
['cats', 'dogs']
os.listdir()을 사용하여 해당 경로에 몇 개의 파일 또는 디렉터리가 있는지 확인할 수 있습니다. 리스트로 반환되며 Train set, Test set 둘 다 옳은 경로에서 가져왔고, cats와 dogs라는 Categorical Label임을 확인할 수 있었습니다.
+ 이미지가 맞는지 경로를 통해 확인하는 방법
matplotlib의 imread() 메서드를 사용하여 경로 값을 직접 넣어 바로 이미지를 확인할 수 있었습니다.
plt.imshow(plt.imread(train_list[1]))
plt.axis('off')
그리고, 각 데이터들의 모든 경로 정보들을 담아둘 것이 필요했습니다.
test_list = [] # test_set의 파일 경로들을 담은 리스트
test_target = []
for dirname, _, filenames in os.walk(test_path):
#print(filenames)
for filename in filenames:
#print(filename)
if(filename.endswith('jpg')): # 확장자가 jpg인 것만 담아주기
if(filename[0] == 'c'):
test_target.append(0)
elif(filename[0] == 'd'):
test_target.append(1)
test_count = os.path.join(dirname, filename)
test_list.append(test_count)
Test set의 데이터 경로 값들을 test_list에 담는 코드입니다. os.walk()를 통하여 반복문에서 해당 경로 하위에 존재하는 모든 디렉터리들을 탐색할 수 있습니다. for문의 변수가 3개나 있습니다. 반복문을 실행하면서 3가지 값을 튜플로 반환합니다.
- root: 탐색의 root가 되는 경로를 반환합니다.
- dirs: 하위의 폴더 경로들을 반환합니다.
- files: 하위의 파일 경로들을 리스트의 형태로 반환합니다.
filenames를 리스트의 형태로 반환하기 때문에 filenames 안에서 또 for문을 반복하여 파일 경로(filename)를 얻어냅니다.
Dataset에서 '_DS_Store'같은 연관이 없는 파일이 있는 것을 확인했기 때문에 Dataset에 이런 파일들이 섞이는 것을 방지하기 위해 os.endswtih()을 사용하여 확장자가 'jpg'로 끝나는 것들만 Dataset에 담아주었습니다.
그리고 이 당시 target data는 어떻게 만들지 문제였기 때문에 경로들을 가져오는 과정에서 파일이 'c'로 시작하면 고양이로 판단하여 0(Negative Class), 'd'로 시작하면 개로 판단하여 1(Positive Class)로 target data까지 생성해주었습니다. (결론적으로 이 방법은 사용하지 않았습니다.)
또한, 이 방법이 문제를 야기시키는 것은 아니지만 다른 패키지를 사용하여 구할 수 있는 방법이 있기에 좋은 방법은 아닌 거 같습니다.
filenames 리스트의 for문을 돌며 나온 filename은 경로의 최초 시작점부터 말단까지의 정보가 아닌 root부터 말단까지의 정보이기 때문에 바로 경로 정보를 test_list에 담으면 안 됩니다. 즉, root와 filename을 합쳐주어야 합니다. os에서는 경로 문자열을 합쳐주는 메서드 os.path.join()을 제공하기 때문에 이를 사용하여 결합 후 정보를 담아주면 됩니다.
Train Set 또한 같은 과정을 실행하여 경로 정보를 담은 리스트와 타깃 데이터 리스트를 만들어줍니다.
(미리 말하지만 지금까지 사용된 코드는 프로젝트 실행 과정에 있어서 사용되지 않습니다. 공부 목적을 위해 남겨둡니다.)
✔️ Step 2: Path to Image
현재 작업은 데이터들의 경로 값들을 리스트로 가져온 것까지 되었습니다. 하지만, 모델을 학습시키려면 경로 값이 아닌 이미지 데이터가 필요합니다.
🤔 Try 1: PIL Image.open()
from PIL import Image
train_set = []
for i, jpg_path in enumerate(train_list):
#print('counting... {}'.format(i))
img = Image.open(jpg_path)
img_array = np.array(img)
train_set.append(img_array)
Reference: https://ddolcat.tistory.com/690
PIL이라는 이미지 처리 모듈에서 Image.open()을 사용하여 이미지를 가져오고, numpy로 변환하는 과정을 거쳤는데 30분 정도 걸려서 실행이 끝났었습니다. (이때 당시 image preprocessing은 후에 처리하려 했기 때문에 여기서는 하지 않았습니다.) 모델을 학습시키는 것도 아니라 이미지를 가져오는데 시간이 이렇게 오래 걸리는 건 문제가 있다고 생각해서 다른 방법을 찾아봤습니다.
🤔 Try 2: tensorflow.keras.preprocessing image.load_img()
from tensorflow.keras.preprocessing import image
train_set = []
for i, f in enumerate(train_list):
img = image.load_img(f, target_size = (224, 224, 3)) # 반환형 <class 'PIL.Image.Image'>
#print('count {}'.format(i))
img_np = np.array(img)
train_set.append(img_np)
Reference: https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=baek2sm&logNo=221400912923
Keras에서 제공하는 preprocessing 패키지에서 image 모듈의 load_img()를 사용하여 경로 값과 target_size를 인자로 넘겨주어 preprocessing까지 한 번에 하며 10분까지 줄였었습니다. 하지만, 여전히 10분도 버거웠기 때문에 다른 방법을 찾아봐야 했습니다.
🤔 Try 3: tensorflow.keras.preprocessing image_dataset_from_directory
from tensorflow.keras.preprocessing import image_dataset_from_directory
IMAGE_SIZE = (224, 224)
BATCH_SIZE = 32
train_ds = image_dataset_from_directory(
directory = '/content/drive/MyDrive/training_set/training_set',
labels = 'inferred',
label_mode = 'binary',
batch_size = BATCH_SIZE,
image_size = IMAGE_SIZE,
seed = 123, # train과 val을 분리할 때, seed 값이 다르면 다른 분할을 택하므로 겹치는 데이터가 생긴다.
validation_split=0.02, # 2%만 validation set으로 이용
subset = 'training' # 해당 subset(dataset, 함수를 통해 나온 set)은 training 용으로 사용
)
Documentation: https://www.tensorflow.org/api_docs/python/tf/keras/utils/image_dataset_from_directory
image_dataset_from_directory라는 메서드를 통해 tf.data.Dataset이라는 object를 반환받습니다. tensorflow에서 제공하는 Dataset이라 다루는 방법에 대해 미숙하여 추후에 공부해야 합니다. 작성한 인자에 대해 알아봅시다.
directory는 Dataset이 존재하는 경로를 알려줘야 합니다.
labels에 'inferred'라고 값을 넘겨주었는데 이는 image_dataset_from_directory라는 함수에 대해 알아야 이해할 수 있습니다. 이 함수는 이름처럼 직관적으로 디렉터리로부터 데이터셋을 구성합니다. 데이터셋 하위 폴더에 Label 별로 나누어져 있다면 나눠진 폴더로부터 추론(inferred) 가능하게 하여 폴더의 레이블을 target으로 만들 수 있습니다. 즉, 아까 위에서 경로들을 탐색하며 filename으로 target data를 따로 만들 필요가 없게 됩니다.
label_mode가 'binary'인 이유는 현재 개와 고양이를 분류하는 모델을 만들기 때문에 다중 분류가 아닌 이중 분류로 Label을 0과 1로 encode 하게 하는 것입니다.
batch_size는 모델에 학습시키면서 가중치의 변화를 주는 업데이트를 할 때 배치(샘플들의 묶음) 값을 얼마나 줄지에 대한 인자입니다.
image_size는 resize로 제가 하려 했던 preprocessing에 해당합니다.
+ seed, validation_split, subset은 모두 validation_set에 관한 것으로 모델을 개선하고자 사용했기 때문에 밑에서 다루겠습니다.
해당 방법은 4초 만에 끝나서 이 방법을 채택하여 프로젝트를 진행했습니다.
+ 방법을 해결하는 과정에 Pytorch의 ImageFolder라는 것도 봤는데 Tensorflow를 사용하기에 넘어갔지만, image_dataset_from_directory와 비슷한 기능을 수행하는 듯했습니다.
✔️ Step 3: Modeling
초기의 모델링은 예전 기초 책에서 실습하던 모델을 가져와 수정하여 만들었습니다.
Reference: https://github.com/drawcodeboy/first_ML_DL/blob/main/firstMLDL_08_2.ipynb
model = keras.Sequential()
model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu', padding = 'same', input_shape=(224, 224, 3)))
model.add(keras.layers.MaxPooling2D(2))
model.add(keras.layers.Conv2D(64, kernel_size=3, activation='relu', padding = 'same'))
model.add(keras.layers.MaxPooling2D(2))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(1000, activation='relu'))
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dense(50, activation='relu'))
model.add(keras.layers.Dropout(0.3))
model.add(keras.layers.Dense(1, activation='sigmoid'))
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_2 (Conv2D) (None, 224, 224, 32) 896
max_pooling2d_2 (MaxPooling (None, 112, 112, 32) 0
2D)
conv2d_3 (Conv2D) (None, 112, 112, 64) 18496
max_pooling2d_3 (MaxPooling (None, 56, 56, 64) 0
2D)
flatten_1 (Flatten) (None, 200704) 0
dense_1 (Dense) (None, 1000) 200705000
dense_2 (Dense) (None, 100) 100100
dense_3 (Dense) (None, 50) 5050
dropout (Dropout) (None, 50) 0
dense_4 (Dense) (None, 1) 51
=================================================================
Total params: 200,829,593
Trainable params: 200,829,593
Non-trainable params: 0
_________________________________________________________________
model.compile(optimizer='adam', loss='binary_crossentropy', metrics='accuracy')
checkpoint_cb = keras.callbacks.ModelCheckpoint('best-cnn-model.h5', save_best_only=True)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2, restore_best_weights=True)
history = model.fit(train_ds, epochs=20, validation_data=(val_ds),
callbacks=[checkpoint_cb, early_stopping_cb])
input_shape를 변경하고, Binary Classification이라 Output layer에 Activation function을 'softmax'에서 'sigmoid'로 바꾼 것 말고는 없지만 모델에 대해 간략히 설명해보겠습니다.
📚 Model Summary
Input Layer (Conv)
Filter의 개수를 32개로 주고, Kernel의 사이즈는 3x3으로 줬습니다. Activation function은 CNN(이미지) 분야에 적합한 relu 함수를 사용했습니다. padding은 same padding이 제일 효율적인 방법이라 공부한 기억이 있어서 same padding을 사용했습니다. input_shape는 Dataset을 만들 때 preprocessing을 한대로 똑같이 맞춰주었습니다.
Pooling Layer
MaxPooling을 하여 사이즈를 줄입니다.
Conv Layer
모델의 성능을 더 높이기 위해 Filter의 개수가 64인 Conv Layer를 하나 더 추가하여 깊게 만듭니다.
Pooling Layer
MaxPooling을 하여 사이즈를 줄입니다.
Flatten
Matrix 형태였던 Data를 1차원적으로 펴줍니다.
Dense Layer
200,074개의 input neuron에서 1,000개의 output neuron으로 연결하는 Dense Layer를 쌓아줍니다.
Dense Layer
1,000개의 input neuron에서 100개의 output neuron으로 연결하는 Dense Layer를 쌓아줍니다.
Dense Layer
100개의 input neuron에서 50개의 output neuron으로 연결하는 Dense Layer를 쌓아줍니다.
Dropout
Overfitting 방지를 위해 30%의 뉴런을 랜덤 하게 꺼서 막아줍니다.
Output Layer
출력 층에서는 이진 분류이기 때문에 Active function을 sigmoid function을 써서 출력하게 합니다.
📚 Model Improvement Process
🤔 Try 1
앞서 말한 대로 모델링은 아직 뚜렷한 지식이 없어서 예전 실습에서 사용하던 Model을 가져와서 학습시켰습니다. input_shape를 수정하고, Binary Classification이기 때문에 Activation function만 sigmoid로 수정해줬습니다.
train_set
loss: 0.2813, accuracy:87.58%
test_set
loss: 1.2031, accuracy: 63.03%
test_set의 loss 값이나 train_set과 test_set의 accuracy를 비교했을 때 Overfitting을 의심했습니다. 개선의 필요성을 느꼈습니다.
🤔 Try 2
아무래도 지나친 Epoch로 Overfitting이 되지 않았나 의심되어서 Epoch 횟수를 줄이려 했지만, 직접적으로 줄이기보다는 validation_set을 이용한 교차 검증으로 Early Stopping Callback을 사용하여 적절한 Epoch에서 학습을 멈추게 해 볼 생각이었습니다.
그래서 아까 위에서 image_dataset_from_directory에 대해 설명할 때, validation에 대한 이야기는 아래에서 다룬다고 했습니다. 이 시점에서 교차 검증이 필요했기 때문에 여기서 다루는 게 낫겠다고 판단했습니다.
val_ds = image_dataset_from_directory(
directory = '/content/drive/MyDrive/training_set/training_set',
labels = 'inferred',
label_mode = 'binary',
batch_size = BATCH_SIZE,
image_size = IMAGE_SIZE,
seed = 123,
validation_split=0.02,
subset = 'validation'
)
seed는 random seed를 의미합니다. train_set이나 validation_set이나 둘 다 따로 랜덤 하게 데이터를 가져오기 때문에 중복된 데이터를 가져올 수 있습니다. 이를 방지하기 위해 둘 다 같은 random seed로 정해줍니다.
validation_split은 전체 dataset에서 얼마 큼을 validation_set으로 쓸 것인지에 대해 묻는 것입니다. dataset이 약 8,000개의 데이터로 이루어졌기 때문에 2% 정도를 사용하여 약 160개의 데이터만 가져왔습니다.
subset은 현재 반환받는 변수가 train_set인지 validation_set인지 묻는 것입니다. 전체에서 부분적으로 가져가기 때문에 부분집합을 의미하는 subset이라는 단어를 사용했습니다.
Early Stopping Callback으로 학습을 시키면서 Epoch 총 3번 만에 학습을 멈췄습니다.
train_set
loss: 0.5935, accuracy:63.03%
val_set
loss: 0.9075, accuracy: 53.12%
test_set
loss: 0.6917, accuracy: 55.41%
Try 1보다 전체적인 accuracy는 낮아졌지만 train_set과 test_set의 accuracy 차이는 꽤 줄였습니다. 여기서는 반대로 둘 다 낮게 나와서 Underfitting을 의심했습니다.
🤔 Try 3 (Result)
모델의 구조에 대한 생각을 좀 해봤습니다. Summary를 보다가 Dense Layer 쪽에 궁금한 점이 생겨서 모델에 Layer를 추가적으로 줘봤습니다.
dense_1에서 input neuron이 200,704개나 들어오는데 output neuron이 50개로 확 줄어드는 게 문제가 아닐까 생각해서 중간에 output neuron이 각 1000, 100인 Layer 2개를 추가해주었습니다.
train_set
loss: 0.5939, accuracy:67.15%
val_set
loss: 0.8216, accuracy: 46.25%
test_set
loss: 0.6887, accuracy: 55.07%
Try 2에 비해 효과는 미비하지만 train_set의 accuracy가 약 4% 정도 올랐습니다. test_set에서는 accuracy의 큰 변화가 없어서 Dense Layer에 대한 지적이 좋은 결과는 아니었던 것 같습니다.
✔️ Outro
원하는 결과는 만들어져서 조금 더 개선을 하고자 하던 마음 때문에 쉽사리 프로젝트를 끝내지 못했습니다. 이쯤에서 끝내고 다음 단계로 넘어가서 공부를 하는 게 좋을 거 같아 이쯤에서 마무리합니다.
Step 1을 프로젝트에서는 실질적으로 사용하지는 않았지만 os 모듈과 자주 사용되는 메서드를 공부하게 되어 기록해두었습니다. 파일을 가져오는 과정을 직접 해보니 개발에 첫 발걸음을 내디뎠다는 기분이 들기도 했습니다.
Step 2에서는 여러 시행착오가 있었네요. 이미지를 빠르게 가져오기 위해 여러 방법을 써봤습니다. tensorflow에서 제공하는 Dataset class를 통해 해결했지만 이 Dataset을 제 것처럼 다루지 못하는 점이 아쉽게 다가오는 거 같습니다. 그래서 근본적인 Python의 Class를 공부해보고자 아래 글에서 정리해보기도 했습니다.
https://draw-code-boy.tistory.com/486
파이썬의 클래스에 대하여
객체지향 프로그래밍을 공부하기 위함이기보다는 프로젝트를 하는 데에 있어서 여러 패키지의 모듈들을 사용할 일이 많았습니다. 그러다 보니 코드의 구조를 파악하는 데에 있어서 어려움을
draw-code-boy.tistory.com
tensorflow Dataset을 다루기가 쉽지 않아서 만들었던 모델을 데이터를 가져와서 직접 predict 해보는 경험을 해보지 못한 것은 이번 프로젝트에서 가장 아쉬운 부분이 아니었나 싶습니다.
Step 3의 Modeling 부분에서는 비록 예전 실습 모델을 가져왔지만, Accuracy를 높이거나 Loss를 낮추는 과정 때문에 여러 가지 시도를 해보았습니다. '이건 어떨지, 저건 어떨지' 아이디어를 던져보며 모델을 좋은 모델로 만들어내는 것은 너무나도 좋은 경험이었습니다. 여기서도 아쉬운 부분은 Dataset(tf.data.Dataset)을 다루는 방법을 몰라서 각 이미지들의 Normalization preprocessing을 해주지 못한 것입니다. 전처리를 했다면 성능이 더 올라가지 않을까 했을 텐데 많이 아쉽습니다.
이 밖에도 여러 변수들이 생각이 났었습니다. Image preprocessing의 과정 중에 Dataset으로 가져오면서 resize를 하는데 이 부분은 Warping이라는 기법으로 이미지를 왜곡시키기 때문에 모델에 영향을 줄 수 있겠다는 생각을 했습니다. Center Cropping이나 Padding 같은 기법을 Dataset에 적용시켜보는 방법이 떠올랐고, Early Stopping Callback에서 patience 값을 적게 주어서 Local Minima에 빠진 건가 싶기도 했습니다.
그리고, 모델링을 할 때 느꼈던 건 이론을 배운 지 꽤 시간이 지났다 보니까 지식에 대한 큰 틀은 잡히지만 디테일한 부분들이 기억 안 나는 것들이 있었습니다. ANN이나 CNN에 대해 다시 디테일하게 공부하여 이론적인 부분들을 블로그에 제대로 정리해보는 시간을 가지는 것도 좋을 거 같습니다.
정확한 성능의 비교를 위해 여러 라이브러리에 구현된 유명한 논문의 ResNet, AlexNet 등을 가져와서 비교해보는 것도 좋겠다 싶었습니다.
프로젝트를 하면서 코드가 정말 지저분하다고 느꼈습니다. 특히, 더 나은 버전으로 수정을 할 때 '이런 부분을 고쳤다'라는 것을 남겨두기 위해 여러 코드를 주석 처리하고, 텍스트 셀도 정리를 안 하다 보니까 꽤 지저분해 보였습니다. 이런 부분은 Github를 더 다루어서 Version Control System의 순기능을 더 습득하도록 하여 더 깔끔한 코드를 짜 보도록 해야겠습니다.
이번 포스팅이 아마 블로그에서 제일 긴 포스팅이 될 것입니다. 왜냐하면 여러 문제점들을 한 포스팅에서 다 다루기도 하고, 첫 프로젝트이다 보니 세세한 부분들이 기초적인 부분들로 다가와서 다 정리를 해야겠다 싶어서 글이 길어졌습니다. 앞으로는 여러 포스팅을 통해서 겪는 문제점들과 이에 대한 해결점들과 공부에 대한 정리들을 세분화하여 다룰 생각이고, 이러한 형태의 포스팅은 처음이자 마지막이 되지 않을까 싶습니다.
이번 프로젝트를 통해 '내 인공지능을 만들어봤다.'라는 성취감과 함께 다음 단계에는 무엇을 해야 하는지 어느 정도 정리가 되어 이것만으로 과분한 성과라고 생각합니다. (해야 할 것들이 너무 많이 생겨난 거 같지만)
너무 좋은 경험이었습니다.
이것으로 첫 프로젝트를 마무리합니다 🚀🚀
'AI Projects > Project Description' 카테고리의 다른 글
SRL-AE: ECG 데이터 이상치 탐지에 강인한 오토인코더 알고리즘 (1) | 2024.12.22 |
---|---|
U-Net 기반 아키텍처를 활용한 울혈성 심부전 환자 폐부종 진단 방법론 연구 (3) | 2024.04.07 |
머신 러닝을 활용한 당뇨병 환자의 관상 동맥 질환 모델 개발 (0) | 2023.11.05 |
Cat & Dog Binary Classification Project Version 2.1 (FINAL) (0) | 2023.01.23 |
Cat & Dog Binary Classification Project Version 2 (1) | 2023.01.07 |