1. Keras 모델을 만드는 여러 가지 표현방법
1-1. Sequential 방식
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(2, input_shape=[2]))
model.add(tf.keras.layers.Dense(2))
x_1 = tf.constant([1,2])
x_2 = tf.constant([[1,2]])
model(x_2)
model.predict(x_2)
model.call(x_2)
model.summary()
- tf.keras.models.Sequential(): 레이어를 순차적으로 쌓아 구성하는 고수준 API.
- 첫 Dense(2, input_shape=[2]): 입력이 2차원(배치차원 제외), 출력 노드 2개.
- 내부적으로 2×2개의 weight와 2개의 bias를 가짐(총 2*2+2=6).
- 두 번째 Dense(2): 첫 번째 레이어의 출력(2차원)을 입력받아 2차원으로 매핑.
- 그 역시 2×2 weight + 2 bias = 6개 파라미터.
- model.summary(): 레이어별 파라미터 수와 연결 정보를 요약 출력.
- x_2 = tf.constant([[1,2]]): 배치 차원(1,2) 형태로 1개의 샘플.
- model(x_2) vs model.predict(x_2):
- model(x_2)는 텐서 연산으로 즉시 결과를 텐서 형태로 반환.
- model.predict(x_2)는 넘파이 배열로 반환.
1-2. 모델에 다양한 모양의 입력 테스트
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(2, input_shape=[2]))
model.add(tf.keras.layers.Dense(2))
x_test1 = tf.constant([[1,2]])
x_test2 = tf.constant([[1,2],[1,2]])
x_test3 = tf.constant([[[1,2],[1,2]], [[1,2],[1,2]]])
x_test4 = tf.constant([[[1,2,3],[4,5,6]], [[3,4,5],[4,5,6]]])
model(x_test3)
model(x_test4)
- 같은 모델: 2D 입력.
- x_test3의 shape = (2,2,2) / x_test4의 shape = (2,2,3)
- 실제로는 (batch, 2), Dense에서 기대하는 shape가 (batch, 2).
- 3D 이상의 텐서를 Dense로 바로 넣으면 브로드캐스팅 및 에러 발생 가능.
- 여기서 model(x_test4) → 오류 또는 내부적으로 flatten-like 동작이 없으므로 모양 mismatch.
- model_test2 = tf.keras.models.Sequential()
model_test2.add(tf.keras.layers.Dense(2, input_shape=[2,3])) model_test2.add(tf.keras.layers.Dense(2))
- 이제 입력이 (batch, 2,3) 형태로 설정. 2D가 아니라 3D 입력임.
- Dense 레이어는 (2×3)=6개 차원을 한꺼번에 FC로 취급.
- 즉, 한 샘플이 shape=(2,3)인 행렬. Dense는 이를 모두 곱하여 units=2로 매핑.
- model_test2(x_test4):
1-3. InputLayer를 명시적으로 쓰는 경우
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.InputLayer(input_shape=(2,2)))
model.add(tf.keras.layers.Dense(2))
model.add(tf.keras.layers.Dense(1))
model.summary()
- InputLayer(...)를 통해 입력 형태를 명시적으로 설정 가능.
- 이 모델은:
- 입력: (batch, 2,2)
- 첫 Dense: 2×2=4개의 요소를 하나로 flatten해서 units=2로 매핑
- 다음 Dense: 2차원->1차원
- model.summary()에서 param 계산을 볼 수 있음.
2. MLP
2-1. 기초
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()
print(X_train.shape)
X_train = X_train / 255.0
X_test = X_test / 255.0
- MNIST 로드: (60000, 28, 28) shape의 흑백 이미지.
- 정규화: /255.0로 픽셀값을 [0,1] 범위로 스케일링.
- MLP를 위해선 보통 (batch, 784) 형태로 2D 변형(Flatten) 필요.
2-2. Flatten 예시
x = tf.keras.layers.Flatten()
x2 = x(X_train)
print(x2)
- Flatten(): 마지막 축(28×28=784)을 1차원으로 펴줌.
- 원래 (60000,28,28) → (60000, 784).
- 이후 Dense를 적용하면, fully-connected(784->units).
3. MLP를 구성하는 다양한 방법
3-1. Option1 (직접 Activation Layer 사용)
input = tf.keras.Input(shape=(28,28))
x = tf.keras.layers.Flatten()(input)
x = tf.keras.layers.Dense(2)(x)
x = tf.keras.layers.Activation('relu')(x)
- Flatten: (28,28)→784차원
- Dense(2): 은닉 노드 2개 (단순 예시).
- tf.keras.layers.Activation('relu'): ReLU를 별도 레이어로 둠.
- 이렇게 하면 BatchNorm이나 Dropout 등을 Activation 이전/이후 자유 배치 가능.
3-2. Option2 (좀 더 현실적인 구조)
input = tf.keras.Input(shape=(28,28))
x = tf.keras.layers.Flatten()(input)
x = tf.keras.layers.Dense(128)(x)
x = tf.keras.layers.Activation('relu')(x)
x = tf.keras.layers.Dropout(0.2)(x)
output = tf.keras.layers.Dense(10, activation='softmax')(x)
model = tf.keras.models.Model(input, output)
model.summary()
- Flatten → Dense(128) + ReLU → Dropout(20%) → Dense(10, softmax).
- 요약: 784 input → 128 은닉 → 10 출력(분류용).
- model.weights 또는 model.trainable_weights:
- 예: weights[0] = (784×128) 크기의 가중치, weights[1] = (128,)의 bias
- weights[2], weights[3] = 두 번째 Dense(128->10) 파라미터.
model.weights[0].shape # ([784, 128])
model.weights[1].shape # ([128])
model.weights[2].shape # ([128])
model.weights[3].shape # ([10])
- 첫 번째 Dense 레이어 파라미터 2개(가중치, 편향), 두 번째 Dense도 2개.
- 합쳐서 4개 파라미터 텐서.
이 로직:
- (28,28) 이미지가 들어오면 Flatten으로 (batch,784) → Dense(128) + ReLU + Dropout(0.2) → Dense(10, softmax)
- 이런 전형적인 MLP 구조를 다양한 방법(Sequential, Model)으로 구현 가능.
결론
- 다양한 Keras API:
- Sequential: 순차적 레이어 쌓기(간단).
- Functional API: Input, Dense(...), etc.로 유연하게 연결 그래프 정의.
- Mixed: Sequential 레이어를 부분적으로 Functional Model에 삽입하거나, InputLayer 등을 섞어 사용할 수 있음.
- Flatten vs InputLayer:
- Flatten()은 (28,28)→(784) 변환.
- InputLayer(input_shape=(2,3)) 등으로 들어오는 텐서 차원을 명시.
- model(x) vs model.predict(x):
- model(x) → 즉시 텐서 연산 수행, 결과가 Tensor
- model.predict(x) → 넘파이 array 반환, 내부적으로 batch iteration 등 처리.
- MLP 예시: MNIST 로드 → 정규화 → Flatten → Dense(…)*n → Output Dense.
- 배치 차원: Keras 레이어는 항상 (batch_size, ...) 형태를 기본 가정.
- Dense는 마지막 (feature) 축을 입력으로 보고, units개의 노드로 매핑.