⊙ 케라스를 사용하여 데이터셋 적재하기
MNIST 데이터셋은 고등학생과 미국 인구 조사국 직원들이 손으로 쓴 70,000개의 작은 숫자 이미지를 모은 데이터이다. 각 이미지에는 어떤 숫자를 나타내는지 레이블되어 있으며, 머신러닝/딥러닝 분야에서 새로운 분류 알고리즘이 나올 때마다 얼마나 잘 작동하는지 MNIST 데이터셋을 이용한다. 패션 MNIST는 MNIST와 형태(28X28 = 784 픽셀 크기)가 같지만 손글씨 숫자가 아니라 패션 아이템을 나타낸다는 점에서 분류가 까다롭다. 그렇기 때문에 어떤 모델들에서 MNIST의 분류가 93%의 정확도를 내지만, 패션 MNIST에서는 83% 정도만 달성하는 경우가 있다.
케라스는 MNIST, 패션 MNIST, 캘리포니아 주택 데이터셋을 포함하여 널리 사용되는 데이터셋을 다운로드하고 적재할 수 있는 유틸리티 함수를 제공한다. 이를 이용하여 패션 MNIST 데이터셋을 적재해보자.
#패션 MNIST 데이터셋 적재
fashion_mnist = keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()
# X_train_full, y_train_full: 훈련 세트
# X_test, y_test: 테스트 세트
여기서 우리가 주의해야 할 점은 바로 각 이미지는 28X28 크기의 배열이라는 것과 픽셀은 0(흰색)부터 255(검은색)까지 정수형으로 표현되어 있다는 것이다. 이 데이터셋은 이미 훈련 세트와 테스트 세트로 나누어져 있지만 검증 세트가 없으므로 따로 만들어줘야 한다. 또한, 경사 하강법으로 신경망을 훈련하기 때문에 입력 특성의 스케일을 조정해야 한다. 마지막으로 패션 MNIST의 레이블에 해당하는 아이템을 나타내기 위해 클래스 이름의 리스트를 만들어준다.
경사 하강법, 특성 스케일 :2021/02/01 - [Deep learning _TensorFlow] - [TensorFlow] 경사 하강법(Gradient Descent)
#X_valid, y_valid: 검증 세트 설정 & 특성 스케일(0~1로 정규화)
X_valid, X_train = X_train_full[:5000] / 255.0, X_train_full[5000:] / 255.0
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
X_test = X_test / 255.0
#레이블에 해당하는 아이템 이름
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress','Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
⊙ 시퀀스 API를 사용하여 모델 만들기
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28,28]))
model.add(keras.layers.Dense(300, activation="relu"))
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dense(10, activation="softmax"))
다음은 두개의 은닉층으로 이루어진 분류용 다층 퍼셉트론이다.
- 첫 번째 라인은 Sequential 모델을 만든다. 이 모델은 가장 간단한 케라스의 신경망 모델이다. 순서대로 연결된 층을 일렬로 쌓아서 구성한다. 이를 시퀀스 API라고 부른다.
- 그다음 첫 번째 층을 만들고 모델에 추가한다. Flatten 층은 기존의 28X28 이미지를 784의 1차원 배열로 변환한다. 이 층은 보다시피 어떤 모델 파라미터도 가지지 않고 간단한 전처리를 수행한다. 그리고 모델의 첫번째 층이므로 input_shape = [28,28]로 지정해준다. 이때 input_shape에는 배치 크기(가중치를 한 번 업데이트시킬 때마다 사용되는 샘플들의 묶음)를 제외하고 샘플의 크기만 써야 한다.
- 그다음 뉴런 300개를 가진 Dense 은닉층을 추가한다. 이 층은 ReLU 활성화 함수를 사용한다. Dense층마다 각자 가중치 행렬을 관리한다. 이 행렬에는 층의 뉴런과 입력 사이의 모든 연결 가중치가 포함된다. 또한 (뉴런마다 하나씩 있는) 편향도 벡터로 관리한다. 이 층은 입력 테이터를 받으면 그 전 층의 입력 데이터와 가중치 행렬의 곱을 편향과 더해 활성화 함수를 통과하게 된다.
- 다음 뉴런 100개를 가진 두 번째 Dense 은닉층을 추가한다. 역시 ReLU 활성화 함수를 사용한다.
- 마지막으로 (클래스마다 하나씩) 뉴런 10개를 가진 Dense 출력층을 추가한다.
앞에서와 같이 model.add를 이용해 하나씩 추가하지 않고 Sequential 모델을 만들 때 층의 리스트를 전달할 수 있다.
model = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28,28]),
keras.layers.Dense(300, activation="relu"),
keras.layers.Dense(100, activation="relu"),
keras.layers.Dense(10, activation="softmax")
])
모델의 summary() 메서드는 모델에 있는 모든 층을 출력한다. 각 층의 이름(미지정 시 자동 생성), 출력 크기(None은 배치 크기에 어떤 값도 가능하다는 뜻), 파라미터 개수가 차례대로 열로 출력되며, 마지막에는 훈련되는 파라미터와 훈련되지 않은 파라미터를 포함하여 전체 파라미터 개수를 출력한다.
print(model.summary())
첫 번째 dense (Dense) 층에서 파라미터 개수가 235500개가 나온 이유는 784개의 입력에 대하여 300개의 가중치가 곱해지고 300개의 편향이 더해져 나온다.(784 * 300 + 300)
summay() 메서드 말고도 layers 메서드를 통해 각 층의 리스트를 출력하거나 인덱스로 접근할 수 있다.
for i in model.layers:
print(i)
layer_1st = model.layers[1]
print(layer_1st.name)
층의 모든 파라미터는 get_weights() 메서드를 통해 인수로 받아와 접근할 수 있으며, set_weights() 메서드를 사용해 가중치와 편향에 대한 값을 직접 접근할 수 있다. 직접 초기화해주지 않을 경우 가중치를 무작위(대칭성 파괴: 가중치가 대칭적이면 뉴런을 통과할 때 OUTPUT이 같은 경우가 나오므로 의미가 없음)로 초기화하며, 편향은 0으로 통일된다.
layer_1st = model.layers[1]
weights, bias = layer_1st.get_weights()
print(weights)
print(weights.shape)
print(bias)
print(bias.shape)
전체 소스 코드)
github.com/Chocochip101/TensorFlow/blob/main/sequence_API(1).py
다음 글에서는 Sequential 모델의 컴파일, 훈련, 평가와 예측에 대해 알아보자.
⊙해당 문서는 '핸즈온 머신러닝(2판) - 오렐리앙 제롱 저'의 책을 공부하며 정리한 글입니다.
book.naver.com/bookdb/book_detail.nhn?bid=16328592
'ML & DL (Machine Learning&Deep Learning) > Deep Learning (DL)' 카테고리의 다른 글
[Deep Learning] ResNet - Deep Residual Learning for Image Recognition (CVPR 2016) (0) | 2021.11.11 |
---|---|
[TensorFlow] Data Scaling의 중요성 (0) | 2021.09.17 |
[TensorFlow] 시퀀스 API를 사용하여 이미지 분류기 만들기 (2) (0) | 2021.02.20 |
[TensorFlow] 경사 하강법(Gradient Descent) (0) | 2021.02.01 |
[TensorFlow] TensorFlow&Keras 개발환경 구축 (0) | 2021.02.01 |
댓글