이제부터 이미지 분류기 AI를 해볼건데, 우리가 직접 모델을 만들거에요.
어제까진 우리가 scikit 으로 간단한 숫자로 된 AI를 해봤어요.
scikit 인공지능들 모델들은 cpu에서도 돌아간다는 장점이 있지만,
숫자화된 데이터밖에 처리 못해요.
- scikit은 숫자 데이터 (ex: 테이블 형태 데이터)에 강점
- TensorFlow/Keras는 이미지, 오디오처럼 고차원 데이터 처리에 강점
이 부분을 한 문장 더 덧붙이면 좋겠어요:
“그래서 scikit-learn으로는 CNN 같은 복잡한 이미지 분류는 잘 못하고, TensorFlow/Keras를 써야 합니다.”
이번에는 tensorflow, keras 라는 프레임워크를 이용해서 이미지 분류를 해볼건데,
간단한 모델을 만들어 볼거에요.
모델 만드는걸 왜하지? 그거 시간낭비 아니야? 라고 생각하실수 있는데,
간단한 모델을 만들어 봄으로써 왜 사람들이 모델 만드는걸 기피 하는지,
왜 모델 연구하는 사람들이 인기가 없는지 알수도 있고,
또 모델을 만들면 컴퓨터가 어떻게 생각하는지 체험할 수 있다
그리고 재가 클래스 초반에 이런말 했던거 기억 나시나요?
이미지 분석은 실제 많이 쓰입니다.
의학에서 쓰이고, 해충 모니터링 쪽에서도 쓰입니다
그럼 이렇게 생각할수 있어요
"GPT 쓰면 되는데 왜 굳이 이런거 배워요?"
재가 클래스 초반에 했던만 기억 나시나요?
gpt 연동해서 서비스 만들었는데 회사에서 정책을 바꾼다
이러면 내가 회사에서 서비스 하고있는 사업이 다 날라가는 거에요
내가 모델을 빌드해서 돌릴수 있는것도 필요해요
--------------------------------------------------------------------------------------------
(x_train, y_train), (x_test, y_test) = mnist.load_data()
plt.figure(figsize=(15, 5)) # 가로_인치, 세로_인치. 디자인 선택
# For each digit (0 to 9)
for digit in range(10):
# Get indices of images with this digit
indices = (y_train == digit).nonzero()[0][:3] # first 3 samples
# Show each of the 3 samples
for row in range(3):
plt.subplot(3, 10, row * 10 + digit + 1)
plt.imshow(x_train[indices[row]], cmap='gray')
plt.title(f"{digit}" if row == 0 else "")
plt.axis('off')
plt.suptitle("3 Samples per Digit (0~9)", fontsize=16)
plt.tight_layout()
plt.show()
AI를 학습시키려면 데이터가 있어야되죠?
근데 데이터를 이미 가져왔어요.
응? 난 데이터를 준비한적이 없는데? 라는 의문이 드시죠?
mnist 라는 모듈을 만든 사람이 AI 학습에 쓰라고 이미 만들어놓은 데이터가 있어요.
그게
(x_train, y_train), (x_test, y_test) = mnist.load_data()
이 코드에요.
- x_train: 학습에 쓸 이미지 6만 장
- y_train: 각 이미지에 해당하는 숫자 라벨
- x_test: 테스트에 쓸 이미지 1만 장
- y_test: 테스트 이미지 라벨
그러면 이게 뭔 데이터인지 볼까요?
plt.figure(figsize=(15, 5)) # 가로_인치, 세로_인치. 디자인 선택
# For each digit (0 to 9)
for digit in range(10):
# Get indices of images with this digit
indices = (y_train == digit).nonzero()[0][:3] # first 3 samples
# Show each of the 3 samples
for row in range(3):
plt.subplot(3, 10, row * 10 + digit + 1)
plt.imshow(x_train[indices[row]], cmap='gray')
plt.title(f"{digit}" if row == 0 else "")
plt.axis('off')
plt.suptitle("3 Samples per Digit (0~9)", fontsize=16)
plt.tight_layout()
plt.show()
이게 데이터가 대체 어떻게 생겨먹은지 matplot 을 이용해서 봅시다
아래 코드를 실행하면 0부터 9까지 숫자 이미지가 3장씩 나옵니다.
-----------------------------------------------------------------------------------------------
자, 여러분
뭐 이미지 가져왔네요 박수~~ 👏👏👏
이제 이 이미지를 컴퓨터가 계산할 수 있게 숫자로 변환해야 하는데요.
보통은:
- 사진 파일을 불러오면 jpg나 png 같은 형태로 저장됩니다.
- 이걸 numpy라는 “숫자 배열”로 바꿔줘야 딥러닝에 쓸 수 있어요.
그런데, 여기서 중요한 포인트!
MNIST 데이터셋을 만든 박사님들이 이미 다 numpy로 바꿔놨어요.
그래서 우리는 이미지가 numpy인지 아닌지 고민할 필요가 없습니다.
우리가 받은 x_train, x_test는 이미 이런 상태예요:
- x_train.shape: (60000, 28, 28)
- 6만 개 이미지
- 각 이미지는 28x28 숫자
- type(x_train): <class 'numpy.ndarray'>
즉, 이건 그냥 숫자가 쭈욱 들어있는 덩어리예요.
(이미 "컴퓨터가 바로 계산할 수 있게" 준비 완료!)
그러면 뭐 앞으로도 numpy 화 안한단 거란 소리에요?
아니요, 추후에 있을 예제에선 할건데, 지금은 모델 만든 다는게 뭔지 모르니깐 이밎 numpy 된걸로 시작 하자 이거에요
-----------------------------------------------------------------------------------------------------------------------------------------------------
자, 데이터가 준비됐으면 이제 AI를 학습시킬 모델이 필요하죠?
우리가 지금까지는 누가 만들어둔 모델을 갖다 쓰는 방식으로 해봤어요.
예를 들어 scikit-learn에서 RandomForestClassifier() 같은 걸 불러오면 이미 완성된 모델 뼈대를 쓰는 거였죠.
그런데 이번에는 다릅니다.
우리가 직접 모델을 처음부터 조립해서 만들어볼 거예요.
여기서 중요한 코드:
이게 뭘까요?
🏗️ 공장에 비유하면
- model = Sequential()
👉 “AI 공장을 지을 땅을 준비하는 거예요.”- 지금은 아무 기계도 없고, 벽도 없습니다.
- 그냥 “여기다 공장을 짓겠다” 선언만 한 상태예요.
이렇게 빈 모델을 만든 다음에
한 층씩 기계를 넣고,
벨트를 깔고,
조립 라인을 연결하는 작업을 할 거예요.
예를 들어:
- 첫 번째 층: 이미지 특징을 찾아주는 기계
- 두 번째 층: 중요한 특징을 모아주는 기계
- 마지막 층: 어떤 숫자인지 판단하는 기계
이런 식으로 여러 층을 차례로 쌓아야 모델이 완성됩니다.
💡 왜 ‘Sequential’인가?
이름이 Sequential(순차적) 인 이유:
층을 하나씩 순서대로 쌓는다
- 앞에 있는 층에서 나온 결과가
- 뒤에 있는 층으로 차례차례 흘러가요
-------------------------------------------------------------------------------------------------------------------------------------
자, 이제 모델에 첫 번째 기계를 설치할 거예요.
model.add(Conv2D(32, kernel_size=(3, 3), strides=(1, 1), padding='same',
activation='relu', input_shape=(28, 28, 1)))
와...뭔가 복잡해 보이죠? 걱정 마세요. 하나씩 풀어볼게요.
🧐 이게 뭐냐면?
Conv2D는 이미지를 분석하는 돋보기라고 생각하면 돼요.
- 이미지를 작은 구역으로 잘라서
- 그 구역에 어떤 특징이 있는지 찾아내요.
🔍 돋보기 예시
여기서 kernel_size=(3,3) 이라는 건:
3x3 크기의 돋보기를 만든다는 뜻이에요.
- 가로 3칸, 세로 3칸
- 총 9칸짜리 창으로 이미지를 들여다봅니다.
이 돋보기가 이미지를 한 칸씩, 한 칸씩 움직이면서 조사해요.
💡 그러면 뭘 찾나요?
컴퓨터는 사람처럼 "여기 숫자 2 있네!" 라고 못해요.
대신:
- 선의 굵기
- 곡선의 각도
- 밝은 부분과 어두운 부분의 경계
이런 걸 찾아냅니다.
이걸 **“특징”**이라고 부릅니다.
🧮 32라는 숫자의 의미
Conv2D(32, ...) 라는 건 이렇게 말하는 거예요:
“이 돋보기를 32개 만들어서
같은 이미지를 각각 다른 관점으로 살펴보겠다.”
그래서 하나의 이미지에서 32가지 다른 특징을 뽑아냅니다.
이 32개를 전문 용어로 필터라고도 부릅니다.
(필터=돋보기=특징 찾는 눈)
⚙️ input_shape=(28,28,1)
- 이 모델에 처음 들어오는 이미지의 크기와 모양을 알려줘야 돼요.
- 28 x 28 크기
- 1은 “흑백”이라는 뜻입니다.
- 컬러는 보통 (28,28,3)이에요.
자, 우리가 Conv2D(32, ...) 이렇게 하면
컴퓨터는 하나의 이미지를 32개 버전으로 바꿔서 저장합니다.
예를 들어:
- 첫 번째 버전은 곡선을 잘 드러나게 하는 이미지
- 두 번째 버전은 경계를 잘 보여주는 이미지
- 세 번째 버전은 밝기 차이를 더 부각하는 이미지
- …
- 이렇게 32가지 방식으로 해석한 결과를 만듭니다.
그래서 Conv2D는 단순히 "이미지를 줄인다"가 아니라,
여러 가지 눈으로 이미지를 보는 과정이에요.
🔥 "그럼 5000 넣으면?"
예를 들어:
이렇게 하면:
- 돋보기를 5000개 만들어요.
- 각 돋보기는 다른 방식으로 이미지를 해석합니다.
결과적으로:
- 한 장의 이미지를 넣으면
- 내부적으로 5000개의 특징 이미지가 만들어져요.
🧠 중요한 포인트
여기서 “특징”이라는 개념은
사람이 “아, 이건 곡선!” 하고 바로 알아보는 것과 달라요.
컴퓨터가 찾는 특징은:
- 곡선, 직선 같은 단순한 것뿐 아니라
- 수학적으로 복잡하게 조합된 패턴
- 사람은 보면서 “이게 뭐지?” 싶을 정도의 무늬
이런 것들도 포함됩니다.
자, 이제 activation='relu' 이 부분을 볼게요.
이건 무슨 뜻이냐면:
“이 층에서 계산된 숫자들을 이렇게 변형해서 다음으로 넘겨라”
라고 컴퓨터한테 알려주는 거예요.
🧠 왜 변형을 해요?
모델은 이미지를 보고
- 선이 있나?
- 밝은 부분이 있나?
이런 걸 숫자로 계산합니다.
근데 이 숫자가:
- 음수(-)일 수도 있고
- 0일 수도 있고
- 양수(+)일 수도 있어요.
🪄 ReLU는 뭐하냐?
ReLU는 간단하게 말하면:
0보다 작은 값은 다 0으로 만들고, 0보다 큰 값은 그대로 두는 기능
즉:
- -5 → 0
- -0.1 → 0
- 3 → 3
- 10 → 10
이렇게 바꿔줍니다.
🤔 왜 이런 걸 써요?
ReLU를 쓰면:
- 계산이 훨씬 빨라지고
- 음수 때문에 학습이 꼬이는 문제를 줄여줘요.
- “활성화 함수”라고 부르는데,
이건 모델이 더 잘 배우게 도와주는 필터 같은 역할을 합니다.
---------------------------------------------------------------------------------------------------------------------------------------------------
🙋 왜 크기를 줄여요?
사람 입장에서 생각해봅시다.
- 사진을 줄이면 화나죠?
- “화질 왜 떨어뜨려요?!”
- “얼굴 잘 안 보이는데?!”
- 근데 컴퓨터는 다릅니다.
컴퓨터는 이미지를 숫자 표로 보고 있어요.
숫자가 많다는 건:
- 데이터가 많아진다는 뜻
- 계산할 게 늘어난다는 뜻
그래서 컴퓨터는 큰 이미지를 주면 이렇게 생각합니다:
“으악... 숫자 너무 많아... 힘들어...”
😂 (여기서 학생들이 빵 터집니다.)
🧠 또 한 가지 중요한 이유
컴퓨터는 바보예요.
픽셀 하나하나에 너무 집착합니다.
예를 들어:
- 회색1
- 회색2
- 회색3
- 회색4
- 회색5
사람이 보면 “그냥 다 회색”인데,
컴퓨터는:
“아냐! 얘네 다 달라!!”
이렇게 쓸데없는 구분을 하려고 해요.
🧽 그래서 MaxPooling은 뭐하냐?
이 과정을 거치면:
- 비슷한 값들은 하나로 묶어주고
- 덜 중요한 정보를 버리고
- 크기를 줄여서 계산을 빠르게 합니다.
✅ 요약
MaxPooling은
이미지 크기를 줄이고, 불필요한 숫자 집착을 줄여주는 청소기 역할입니다.
-----------------------------------------------------------------------------------------------------------------
자, 모델에 또 뭔가를 추가합니다.
model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
“어라? 또 Conv2D 나오고 또 MaxPooling 나오네요?”
맞아요. 이번에는 이전에 나온 특징들을 더 자세히 분석하려고 하는 거예요.
🔍 이번 Conv2D는 뭐가 다르냐?
첫 번째 Conv2D는:
- “가장 기본적인 특징”을 찾았어요.
- 선
- 모서리
- 밝기 변화
두 번째 Conv2D는:
- “첫 번째에서 찾아낸 특징들을 조합해서 더 복잡한 특징”을 찾아냅니다.
- 예를 들어 숫자의 구부러진 모양
- 여러 선이 교차하는 부분
- 특정 패턴
🧐 64개의 돋보기?
이번에는:
“돋보기를 64개 만들어서, 64가지 다른 방식으로 이미지를 해석해라.”
라고 말하는 겁니다.
그래서:
- 이전 층에서는 32개의 이미지가 나왔고
- 이번 층에서는 각 이미지를 다시 64가지 특징으로 변환
즉, 점점 더 많은 정보를 뽑아내는 겁니다.
✂️ 그리고 또 줄인다?
맞아요.
MaxPooling2D(pool_size=(2,2))
“이제 다시 크기를 반으로 줄여라.”
계속 줄이는 이유:
- 이미지가 커지면 계산이 느려져요.
- 특징만 남기고 나머지 정보는 과감히 버리는 게 좋아요.
- 크기를 줄여야 다음 단계(Dense 층)에서 다루기 쉽습니다.
✅ 요약
이 두 줄은 이렇게 해석하면 됩니다:
“첫 번째 돋보기에서 나온 특징들을 더 자세히 파고들어라(64가지 돋보기).
그리고 그걸 다시 반으로 줄여서 중요한 것만 남겨라.”
이렇게 층을 여러 번 쌓는 이유는:
간단한 특징 → 복잡한 특징 → 더 복잡한 특징
점점 더 고급스러운 정보를 찾아내기 위해서입니다.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
🪄 Flatten 층
먼저 Flatten() 부터 볼게요.
이건 무슨 뜻이냐면:
“지금까지 여러 층에서 만들어진 특징 이미지들을
쫙 펴서 하나의 긴 줄로 만들겠다.”
🤔 왜 펴요?
지금까지 MaxPooling까지 거치면서 데이터 모양이 이렇게 되어 있어요:
예를 들어:
- 높이 = 7
- 너비 = 7
- 채널 = 64
이런 모양이죠.
그런데 Dense 층으로 보내려면:
이렇게 일렬로 된 벡터여야 합니다.
Flatten은 쉽게 말해:
“그림판을 다 잘라서 한 줄로 쭉 이어붙여라.”
하는 역할이에요.
✅ 요약
Flatten = 이미지 데이터를 일렬 숫자 리스트로 바꾸는 층
🏢 Dense 층
이제 Dense 층을 추가합니다.
이건 CNN에서 뽑아낸 특징들을 바탕으로 실제 판단을 내리는 단계입니다.
Dense는 “완전히 연결된 층”이라고 해서:
- 일렬로 나열된 숫자들을
- 여러 개의 노드(뉴런)에 다 연결해서
- 더 복잡한 패턴을 배우게 해요.
✨ 쉽게 비유하면?
- 지금까지는 사진을 돋보기로 여러 번 훑어서
- “여기 선이 있어요”
- “여기 구부러진 부분 있어요”
- “여기 밝은 점 있어요”
이런 식으로 정보를 수집했어요.
- Dense 층은 이제 그 정보를 종합해서
- “이건 숫자 3이다!”
- “이건 숫자 7이다!”
라고 판단하는 단계입니다.
🤖 Dense 층의 숫자
Dense(128)은 이렇게 말하는 거예요:
“128개의 똑똑한 뉴런을 써서 정보를 분석해라.”
각 뉴런은 조금씩 다른 방식으로 데이터를 해석해서,
최종적으로 더 정확한 결론을 내리게 도와줍니다.
🧠 마지막 출력층
마지막에 또 Dense 층이 하나 더 있습니다.
이 층은:
- 숫자 0~9 중 어떤 숫자인지 확률을 출력합니다.
- “softmax”는 각 숫자에 대한 “이게 맞을 확률”을 계산해서
합이 1이 되도록 만듭니다.
예를 들어:
이렇게 나오면:
- “이 이미지는 숫자 3일 확률이 90%입니다.”
라고 컴퓨터가 판단합니다.
✅ 전체 요약
1️⃣ Conv2D: 돋보기로 특징 찾기
2️⃣ MaxPooling: 이미지 줄이고 데이터 줄이기
3️⃣ Flatten: 2차원 이미지를 1차원 벡터로 펴기
4️⃣ Dense(128): 특징을 종합해서 분석하기
5️⃣ Dense(10, softmax): 최종 숫자 예측하기
-----------------------------------------------------------------------------------------------------------------------------------------------
자, 우리가 이렇게 쓰면:
무슨 뜻일까요?
“5000개의 똑똑한 뉴런을 만들어서 데이터를 분석해라.”
라고 하는 거예요.
🤔 그럼 뉴런 숫자를 크게 하면 더 똑똑할까?
그렇게만 되면 참 좋겠지만... 현실은 다릅니다.
뉴런 숫자를 무조건 크게 하면:
- 모델이 너무 복잡해져서 학습이 잘 안 될 수도 있고
- 컴퓨터 메모리가 왕창 차지되고
- 오히려 성능이 떨어지는 경우도 많아요.
그래서 적당한 숫자를 쓰는 게 중요합니다.
보통 128, 256, 512 정도가 많이 쓰여요.
✅ 요약
“숫자만 크게 한다고 모델이 더 똑똑해지는 건 아니다.”
🧠 activation=’relu’ vs activation=’softmax’
여기서 많은 분들이 헷갈립니다.
Dense 층에서는:
- activation='relu': 학습할 때 많이 쓰는 방식
- 음수 값을 0으로 바꾸고
- 양수 값은 그대로 둡니다.
- 특징을 더 잘 구분하도록 도와줍니다.
- activation='softmax': 최종 판단할 때 쓰는 방식
- “어떤 숫자일지 확률”을 계산해서
- 결과가 0~1 사이 값으로 나오게 합니다.
- 결과 확률의 합이 1이 되도록 자동으로 맞춥니다.
그런데 어떤 분들이 물어봐요:
“Conv2D에서도 activation='relu' 쓴다면서요?
거기선 음수를 없앤다 그러고...
Dense에서는 학습 모드라고 그러고...
왜 말이 다 달라요???”
좋은 질문이에요.
✅ 핵심 이유
“각 함수가 다르기 때문이에요.”
- Conv2D, Dense, MaxPooling2D 전부 역할과 내부 기능이 다릅니다.
- activation 옵션은 “이 층에서 출력값을 어떻게 바꿀 거냐”만 정하는 겁니다.
- relu 자체는 같은 방식으로 동작하지만, 그 층이 하는 역할이 달라요.
- Conv2D: 이미지 특징 뽑기
- Dense: 숫자 종합 판단
📢 비유
activation 함수는 요리의 “양념” 같은 거예요.
- 같은 고추장을 써도:
- 찌개에 넣으면 찌개 맛이 나고
- 볶음에 넣으면 볶음 맛이 나는 것처럼
- 같은 relu를 써도
- Conv2D에 쓰면 “이미지 특징”이 나오고
- Dense에 쓰면 “숫자 판단”이 나옵니다.
✅ 결론 요약
1️⃣ Dense(5000): 숫자가 커진다고 무조건 좋진 않다.
2️⃣ activation='relu': 음수 없애고 학습 쉽게 한다.
3️⃣ activation='softmax': 최종 결과를 확률로 만든다.
4️⃣ 각 층마다 역할과 내부 동작 방식이 다르다.
----------------------------------------------------------------------------------------------------------------------------------------------------
자, 이제 우리가 CNN 모델을 한 층 한 층 다 쌓았습니다.
이제 뭐 해야 되죠?
바로 학습(Training) 단계로 넘어갑니다.
🏋️ 학습 코드
history = model.fit(x_train, y_train,
validation_data=(x_test, y_test),
epochs=20,
batch_size=100)
이 코드 많이 봤죠?
model.fit() 이게 바로:
“모델아, 네가 똑똑해질 때까지 열심히 공부해라!”
라고 명령하는 코드입니다.
⚙️ 옵션 해석
- x_train, y_train
학습에 쓸 데이터와 정답 - validation_data=(x_test, y_test)
중간중간에 “잘 배우고 있나?” 확인용 테스트 데이터 - epochs=20
총 20번 반복해서 공부하기 - batch_size=100
한 번에 100개씩 데이터 묶어서 공부하기
💾 결과 저장
학습이 끝나면, 결과가 history에 뿅 하고 담깁니다.
이 안에는:
- 매 epoch마다의 손실(loss)
- 정확도(accuracy)
- 검증 데이터 성능(validation loss, validation accuracy)
이런 데이터들이 다 들어 있어요.
나중에 그래프로 학습 과정을 그릴 때 이걸 씁니다.
🗃️ 모델 저장
그리고 이렇게 학습이 끝난 모델은 파일로 저장할 수 있어요.
final_model_name = f"my_mnist_{final_acc_percent}acc_{final_loss_percent}loss.h5"
model.save(final_model_name)
이건 뭐냐면:
“내가 땀 흘려서 공부시킨 모델을 하드에 저장해놔라.”
하는 거예요.
이렇게 저장하면:
- 나중에 다시 불러와서 예측에 사용할 수 있고
- 다른 사람에게 배포할 수도 있어요.
✅ 요약
1️⃣ model.fit() → 모델이 데이터 보고 학습
2️⃣ history → 학습 과정 기록
3️⃣ model.save() → 학습된 모델 파일로 저장
이제 진짜 AI가 스스로 손글씨 숫자를 구분할 수 있는 똑똑이 모델이 완성됐습니다! 🎉
전체 Colab 예측 코드
from keras.models import load_model
from google.colab import files
from PIL import Image
import numpy as np
# 1. 모델 불러오기
model_path = '/content/my_mnist_XXacc_XXloss.h5'
model = load_model(model_path)
print("모델 불러오기 완료!")
# 2. 사용자 이미지 업로드
uploaded = files.upload()
filename = list(uploaded.keys())[0]
# 3. 이미지 전처리
img = Image.open(filename).convert('L')
img = img.resize((28,28))
img_array = np.array(img)
img_array = img_array.astype('float32') / 255.0
input_data = img_array.reshape(1,28,28,1)
# 4. 예측
pred = model.predict(input_data)
predicted_class = np.argmax(pred)
print(f"예측 결과: 이 이미지는 '{predicted_class}' 숫자입니다!")
------------------------------------------------------------------------------------------------------------------------------------------------------
여러분, 여기서 꼭 기억하셔야 할 게 하나 있어요.
지금까지 우리가 써본 것들은:
- Keras라는 프레임워크에서
- Sequential(), Conv2D(), Dense() 같은
아주 기본적이고 대표적인 함수들입니다.
하지만 현실에서는:
- 다른 프레임워크 (예: PyTorch, TensorFlow, MXNet 등)
- 다른 함수와 계층 (예: ResNet, Inception, Transformer 등)
- 또 다른 이름과 동작 방식
이렇게 수십, 수백 가지 다른 도구들이 있어요.
🤔 그래서 어떻게 해야 할까?
새로운 모델을 만들려면 단순히 코드만 바꾸는 게 아니라:
✅ 어떤 프레임워크를 쓸지 결정하고
✅ 거기서 제공하는 모듈과 함수의 특징을 분석하고
✅ 내가 만들고자 하는 목적에 맞게 조합과 실험을 반복해야 합니다.
예를 들어:
- PyTorch에는 Keras와 함수 이름도 다르고 쓰는 방식도 달라요.
- 어떤 함수는 “relu” 대신 “leaky_relu”를 쓰기도 합니다.
- 다른 프레임워크에서는 pooling 방식조차 이름이 다르게 나옵니다.
✅ 요약
“지금 배운 것만이 전부가 아니고,
다른 도구, 다른 함수는 전부 다 이름과 성질이 다르다.”
그래서 여러분이 나중에 신규 모델을 만들거나 논문에 나오는 구조를 구현할 때는:
- 어떤 모듈이 필요한지 조사하고
- 사용법 문서를 꼼꼼히 읽고
- 여러 번 실험하면서
내 프로젝트에 맞는 방식을 찾아야 해요.
이 과정을 많이 겪어봐야
“아, 모델 만드는 게 이렇게 복잡하구나.”
하는 걸 몸으로 이해하게 됩니다.
여러분, 지금까지 배운 모델들은 CNN 계열이에요.
- Conv2D(돋보기)로 특징을 찾고
- MaxPooling으로 줄이고
- Dense로 예측하고
이런 전통적인 이미지 분류 방식이죠.
그런데 꼭 이런 방식만 있는 건 아니에요.
✅ 예를 들어, 최근에 나온 Vision Transformer (ViT) 같은 모델은
“아예 Conv2D를 안 쓰고, Transformer라는 방식을 이미지에 적용”합니다.
이 방식은 사람이 이미지를 볼 때 중요한 부분에만 집중하는 것과 비슷하게 동작합니다.
🧠 이런 아이디어는 어디서 나올까요?
이게 바로 모델 연구 분야입니다.
모델 연구자들은 이렇게 고민해요:
1️⃣ 이미지를 볼 때,
“컴퓨터는 어떤 규칙으로 특징을 찾아야 하지?”
2️⃣ 이 과정을
“사람이 생각하는 방식으로 바꿔볼 수 없을까?”
3️⃣ 그러면 이 아이디어를
“수학식으로 표현하면 어떻게 될까?”
4️⃣ 이 수학식을
“파이썬 함수로 만들면 어떻게 짜야 하지?”
이런 과정을 수없이 반복해서 새로운 모델을 만듭니다.
예를 들어 ViT 모델은 이렇게 했어요:
- CNN 대신 Self-Attention(자기 주의) 라는 수학 방식을 이미지에 적용
- 작은 패치 단위로 이미지를 나눠서 처리
- 더 유연하게 특징을 파악
✅ 요약
이미지 분류라고 해서 무조건 “특징 찾아서 줄이고”만 하는 건 아니다.
다른 방식으로도 분류할 수 있고,
이런 새로운 아이디어를 연구하고,
수학으로 표현하고,
코드로 만드는 게 모델 연구 분야다.
📢 마무리
여러분이 나중에 이쪽 분야에 관심이 생기면,
- 논문을 읽고
- 수식과 알고리즘을 분석하고
- 새로운 모델을 구현해보는
이런 “모델 연구”도 도전할 수 있어요.
'AI' 카테고리의 다른 글
| VIT 원리 (0) | 2025.07.09 |
|---|---|
| 파인튜닝 기본적인 골격 (1) | 2025.07.09 |
| [VGG16] 뼈대 강의 (0) | 2025.07.08 |
| [코드] 트랜스포머 vit 파인튜닝 (1) | 2025.07.01 |
| 트랜스포머 finetuning (0) | 2025.06.29 |