● 케라스
- 파이썬으로 작성된 고수준 신경망 API로 TensorFlow, CNTK, Theano와 함께 사용 가능
- 사용자 친화성, 모듈성, 확장성을 통해 빠르고 간편한 프로토타이핑 가능
- 컨볼루션 신경망, 순환 신경망, 둘의 조합까지 모두 지원
- CPU와 GPU에서 매끄럽게 실행
import numpy as np
import tensorflow as tf
- 레이어들을 import하는 방식(1)
- 일일히 import 하지 않아도 됨
- 코드가 다소 길어질 수 있음
# keras까지만 import 하여 이후 필요한 것은 keras.**으로 사용
from tensorflow import keras
keras.__version__
# 출력 결과
'2.11.0'
keras.layers.Dense(10, activation = 'sigmoid')
# 출력 결과
<keras.layers.core.dense.Dense at 0x1eaa357ecd0>
keras.Model()
# 출력 결과
<keras.engine.training.Model at 0x1eabdafa0d0>
keras.models.Sequential()
# 출력 결과
<keras.engine.sequential.Sequential at 0x1eabda0feb0>
- 레이어들을 import하는 방식(2)
- 일일히 import 해야함
- 코드가 간결
# keras.layers, keras.models 등으로 사용할 레이어들을 한번에 import
from tensorflow.keras.layers import Dense, Input, Flatten, Activation
from tensorflow.keras.models import Sequential
from tensorflow.keras import Model
Dense(10, activation = 'relu')
# 출력 결과
<keras.layers.core.dense.Dense at 0x1eaa3455730>
Flatten(input_shape = [28, 28])
# 출력 결과
<keras.layers.reshaping.flatten.Flatten at 0x1eabdafae80>
X_train = np.random.randn(5500, 2)
Input(shape = X_train.shape[1:])
# 출력 결과
<KerasTensor: shape=(None, 2) dtype=float32 (created by layer 'input_1')>
1. 주요 레이어
- Dense
- Fully-Connected Layer
- 노드수(유닛 수), 활성화 함수 등을 지정
- name을 통한 레이어 간 구분 가능
- 기본적으로 'Glorot uniform' 가중치(Xavier 분포 초기화), zeros bias로 초기화
- kernel_initializer 인자를 통해 다른 가중치 초기화를 진행할 수 있음
dense = Dense(10, activation = 'relu', name = 'Dense Layer')
dense
# 출력 결과
<keras.layers.core.dense.Dense at 0x1eabdb1e760>
dense2 = Dense(15, activation = 'softmax')
dense2
# 출력 결과
<keras.layers.core.dense.Dense at 0x1eabdbd4a60>
- 단 한줄로 레이어 선언이 끝남, keras의 장점
- Activation
- Dense layer에서 미리 활성화 함수를 지정할 수도 있지만 때에 따라서 따로 레이어를 만들어줄 수 있음
dense = Dense(10, kernel_initializer = 'he_normal', name = 'Dense Layer')
dense = Activation(dense)
dense
# 출력 결과
<keras.layers.core.activation.Activation at 0x1eabdb1e7c0>
- Flatten
- 배치 크기(또는 데이터 크기)를 제외하고 데이터를 1차원으로 쭉 펼치는 작업
- 예시
(128, 3, 2, 2) -> (128, 12)
Flatten(input_shape = (28, 28))
# 출력 결과
<keras.layers.reshaping.flatten.Flatten at 0x1eabda5ddc0>
- input
- 모델의 입력을 정의
- shape, dtype을 포함
- 하나의 모델은 여러 개의 입력을 가질 수 있음
- summary() 메소드를 통해서는 보이지 않음
input_1 = Input(shape = (28, 28), dtype = tf.float32)
input_2 = Input(shape = (8,), dtype = tf.int32)
input_1
# 출력 결과
<KerasTensor: shape=(None, 28, 28) dtype=float32 (created by layer 'input_2')>
input_2
# 출력 결과
<KerasTensor: shape=(None, 8) dtype=int32 (created by layer 'input_3')>
2. 모델 구성 방법
- Sequential()
- 서브클래싱(Subclassing)
- 함수형 API
- Sequential()
- 모델이 순차적으로 진행할 때 사용
- 간단한 방법
- Sequential 객체 생성 후, add를 통한 방법
- Sequential 인자에 한번에 추가
- 다중 입력 및 출력이 존재하는 등의 복잡한 모델을 구성할 수 없음
from tensorflow.keras.layers import Dense, Input, Flatten
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.utils import plot_model
model = Sequential()
# Input 레이어 - Dense 레이어(relu 활성화 함수) - Dense 레이어(relu 활성화 함수) - Dense 레이어(softmax 활성화 함수) 연결
model.add(Input(shape = (28, 28)))
model.add(Dense(300, activation = 'relu'))
model.add(Dense(100, activation = 'relu'))
model.add(Dense(10, activation = 'softmax'))
- 모델 구조 확인(model 객체의 summary() 이용)
model.summary()
# 출력 결과
# Input 레이어는 나타나지 않으므로 추가한 Dense 레이어만 표시됨
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_5 (Dense) (None, 28, 300) 8700
dense_6 (Dense) (None, 28, 100) 30100
dense_7 (Dense) (None, 28, 10) 1010
=================================================================
Total params: 39,810
Trainable params: 39,810
Non-trainable params: 0
_________________________________________________________________
plot_model(model)
# model의 레이어 한번에 정의하기
model = Sequential([Input(shape = (28, 28), name = 'Input'),
Dense(300, activation = 'relu', name = 'Dense1'),
Dense(100, activation = 'relu', name = 'Dense2'),
Dense(10, activation = 'softmax', name = 'Output')])
model.summary()
# 출력 결과
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
Dense1 (Dense) (None, 28, 300) 8700
Dense2 (Dense) (None, 28, 100) 30100
Output (Dense) (None, 28, 10) 1010
=================================================================
Total params: 39,810
Trainable params: 39,810
Non-trainable params: 0
_________________________________________________________________
plot_model(model)
- 함수형 API
- 가장 권장되는 방법
- 모델을 복잡하고 유연하게 구성 가능
- 다중 입출력을 다룰 수 있음
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Flatten, Dense
from tensorflow.keras.utils import plot_model
inputs = Input(shape = (28, 28, 1))
x = Flatten(input_shape = (28, 28, 1))(inputs)
x = Dense(300, activation = 'relu')(x)
x = Dense(100, activation = 'relu')(x)
x = Dense(10, activation = 'softmax')(x)
model = Model(inputs = inputs, outputs = x)
model.summary()
# 출력 결과
Model: "model_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_6 (InputLayer) [(None, 28, 28, 1)] 0
flatten_3 (Flatten) (None, 784) 0
dense_6 (Dense) (None, 300) 235500
dense_7 (Dense) (None, 100) 30100
dense_8 (Dense) (None, 10) 1010
=================================================================
Total params: 266,610
Trainable params: 266,610
Non-trainable params: 0
_________________________________________________________________
plot_model(model)
from tensorflow.keras.layers import Concatenate
# wide & deep 모델
# 입력 하나를 wide 모델과 deep 모델에 분산시켜야함
# 다중 입력 필요
input_layer = Input(shape = (28, 28))
hidden1 = Dense(100, activation = 'relu')(input_layer)
hidden2 = Dense(30, activation = 'relu')(hidden1)
concat = Concatenate()([input_layer, hidden2])
output = Dense(1)(concat)
model = Model(inputs = [input_layer], outputs = [output])
model.summary()
# 출력 결과
Model: "model_2"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_8 (InputLayer) [(None, 28, 28)] 0 []
dense_12 (Dense) (None, 28, 100) 2900 ['input_8[0][0]']
dense_13 (Dense) (None, 28, 30) 3030 ['dense_12[0][0]']
concatenate_1 (Concatenate) (None, 28, 58) 0 ['input_8[0][0]',
'dense_13[0][0]']
dense_14 (Dense) (None, 28, 1) 59 ['concatenate_1[0][0]']
==================================================================================================
Total params: 5,989
Trainable params: 5,989
Non-trainable params: 0
__________________________________________________________________________________________________
plot_model(model)
# 다중 입력
input_1 = Input(shape = (10, 10), name = 'input_1')
input_2 = Input(shape = (10, 28), name = 'input_2')
hidden1 = Dense(100, activation = 'relu')(input_2)
hidden2 = Dense(10, activation = 'relu')(hidden1)
concat = Concatenate()([input_1, hidden2])
output = Dense(1, activation = 'sigmoid', name= 'output')(concat)
model = Model(inputs = [input_1, input_2], outputs = [output])
model.summary()
# 출력 결과
Model: "model_3"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_2 (InputLayer) [(None, 10, 28)] 0 []
dense_17 (Dense) (None, 10, 100) 2900 ['input_2[0][0]']
input_1 (InputLayer) [(None, 10, 10)] 0 []
dense_18 (Dense) (None, 10, 10) 1010 ['dense_17[0][0]']
concatenate_3 (Concatenate) (None, 10, 20) 0 ['input_1[0][0]',
'dense_18[0][0]']
output (Dense) (None, 10, 1) 21 ['concatenate_3[0][0]']
==================================================================================================
Total params: 3,931
Trainable params: 3,931
Non-trainable params: 0
__________________________________________________________________________________________________
plot_model(model)
# 다중 출력
input_ = Input(shape = (10, 10), name = 'input_')
hidden1 = Dense(100, activation = 'relu')(input_)
hidden2 = Dense(10, activation = 'relu')(hidden1)
output = Dense(1, activation = 'sigmoid', name = 'main_output')(hidden2)
sub_out = Dense(1, name = 'sum_output')(hidden2)
model = Model(inputs = [input_], outputs = [output, sub_out])
model.summary()
# 출력 결과
Model: "model_4"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_ (InputLayer) [(None, 10, 10)] 0 []
dense_20 (Dense) (None, 10, 100) 1100 ['input_[0][0]']
dense_21 (Dense) (None, 10, 10) 1010 ['dense_20[0][0]']
main_output (Dense) (None, 10, 1) 11 ['dense_21[0][0]']
sum_output (Dense) (None, 10, 1) 11 ['dense_21[0][0]']
==================================================================================================
Total params: 2,132
Trainable params: 2,132
Non-trainable params: 0
__________________________________________________________________________________________________
plot_model(model)
# 다중 입력, 다중 출력
input_1 = Input(shape = (10, 10), name = 'input_1')
input_2 = Input(shape = (10, 28), name = 'input_2')
hidden1 = Dense(100, activation = 'relu')(input_2)
hidden2 = Dense(10, activation = 'relu')(hidden1)
concat = Concatenate()([input_1, hidden2])
output = Dense(1, activation = 'sigmoid', name = 'main_output')(concat)
sub_out = Dense(1, name = 'sum_output')(hidden2)
model = Model(inputs = [input_1, input_2], outputs = [output, sub_out])
model.summary()
# 출력 결과
Model: "model_5"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_2 (InputLayer) [(None, 10, 28)] 0 []
dense_26 (Dense) (None, 10, 100) 2900 ['input_2[0][0]']
input_1 (InputLayer) [(None, 10, 10)] 0 []
dense_27 (Dense) (None, 10, 10) 1010 ['dense_26[0][0]']
concatenate_6 (Concatenate) (None, 10, 20) 0 ['input_1[0][0]',
'dense_27[0][0]']
main_output (Dense) (None, 10, 1) 21 ['concatenate_6[0][0]']
sum_output (Dense) (None, 10, 1) 11 ['dense_27[0][0]']
==================================================================================================
Total params: 3,942
Trainable params: 3,942
Non-trainable params: 0
__________________________________________________________________________________________________
plot_model(model)
- 서브클래싱(Subclassing)
- 커스터마이징에 최적화된 방법
- Model 클래스를 상속받아 Model이 포함하는 기능을 사용할 수 있음
- fit(), evaluate(), predict()
- save(), load()
- 주로 call() 메소드 안에서 원하는 계산 가능
- for, if, 저수준 연산 등
- 권장되는 방법은 아니지만 어떤 모델의 구현 코드를 참고할 때 해석할 수 있어야 함
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Flatten, Dense
from tensorflow.keras.utils import plot_model
class MyModel(Model):
def __init__(self, units = 30, activation = 'relu', **kwargs):
super(MyModel, self).__init__(**kwargs)
self.dense_layer1 = Dense(300, activation = activation)
self.dense_layer2 = Dense(100, activation = activation)
self.dense_layer3 = Dense(units, activation = activation)
self.output_layer = Dense(10, activation = 'softmax')
def call(self, inputs):
x = self.dense_layer1(inputs)
x = self.dense_layer2(x)
x = self.dense_layer3(x)
x = self.output_layer(x)
return x
3. 모델 가중치 확인
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Flatten, Dense
from tensorflow.keras.utils import plot_model
inputs = Input(shape = (28, 28, 1))
x = Flatten(input_shape = (28, 28, 1))(inputs)
x = Dense(300, activation = 'relu')(x)
x = Dense(100, activation = 'relu')(x)
x = Dense(10, activation = 'softmax')(x)
model = Model(inputs = inputs, outputs = x)
model.summary()
# 출력 결과
Model: "model_7"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_9 (InputLayer) [(None, 28, 28, 1)] 0
flatten_4 (Flatten) (None, 784) 0
dense_28 (Dense) (None, 300) 235500
dense_29 (Dense) (None, 100) 30100
dense_30 (Dense) (None, 10) 1010
=================================================================
Total params: 266,610
Trainable params: 266,610
Non-trainable params: 0
_________________________________________________________________
- 모델의 레이어들이 리스트로 표현됨
model.layers
# 출력 결과
[<keras.engine.input_layer.InputLayer at 0x1b51b66a0a0>,
<keras.layers.reshaping.flatten.Flatten at 0x1b51d577c10>,
<keras.layers.core.dense.Dense at 0x1b51d54a250>,
<keras.layers.core.dense.Dense at 0x1b51d54a970>,
<keras.layers.core.dense.Dense at 0x1b51d5997c0>]
# 위의 레이어 충 2번 인덱스의 레이어의 이름 출력
hidden_2 = model.layers[2]
hidden_2.name
# 출력 결과
'dense_28'
- 위의 layer name 참고
# hidden_2(두번째 레이어)의 이름이 dense_28인지 확인
model.get_layer('dense_28') is hidden_2
# 출력 결과
True
# hidden_2에서 계산된 가중치(weights)와 편향(biases) 출력
weights, biases = hidden_2.get_weights()
weights
# 출력 결과
array([[-0.04896989, 0.00405482, 0.02683295, ..., -0.07056625,
-0.04177827, 0.00787882],
[-0.05326419, -0.0303001 , 0.00274137, ..., -0.02837748,
0.05391636, -0.04700017],
[-0.05597277, 0.03437241, -0.00236335, ..., 0.04641164,
0.04785167, -0.02015593],
...,
[ 0.04056622, -0.05879534, 0.01665498, ..., 0.02095272,
0.05407439, -0.069397 ],
[-0.02786053, -0.02436828, -0.03833799, ..., 0.06946112,
-0.02327226, 0.04145432],
[ 0.00797608, -0.07426289, 0.04644973, ..., 0.02902658,
-0.04708448, -0.02754754]], dtype=float32)
biases
# 출력 결과
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)
print(weights.shape)
print(biases.shape)
# 출력 결과
# hidden_2 레이어의 units를 300으로 지정했으므로 가중치와 편향도 각각 300개
(784, 300)
(300,)
4. 모델 컴파일(compile)
- 모델을 구성한 후, 사용할 손실함수(loss), 옵티마이저(optimizer)를 지정
model.compile(loss = 'sparse_categorical_crossentropy',
optimizer = 'sgd',
metrics = ['accuracy'])
- 참고1
- loss
- keras.losses.square_categorical_crossentropy등과 같이 지정 가능
- sparse_categorical_crossentropy클래스가 배타적
즉, MNIST 예제에서 (0, 1, 2, ..., 9)와 같은 방식으로 구분되어 있을 때 사용 - categorical_crossentropy클래스가 원-핫 인코딩 방식으로 되어있을 때 사용
- binary_crossentropy 이진 분류를 수행할 때 사용
- sparse_categorical_crossentropy클래스가 배타적
- optimizer
- kera.optimizer.SGD() 등과 같이 사용
- 보통 옵티마이저의 튜닝을 위해 따로 객체를 생성하여 컴파일
optimizer = keras.optimizer.SGD(learning_rate = 1e-5)
model.compile(...,
optimizer = optimizer,
...)
- keras.optimizer.Adam()도 많이 사용
- metrics
- 모니터링할 지표
- 주로 'accuracy', 'acc'로도 가능
- 참고2-컴파일 설정 예시
- 평균 제곱 오차 회귀 문제
model.compile(loss = 'mse',
optimizer = RMSpop(),
metrics = ['mae'])
- 이진 분류
model.compile(loss = 'binary_crossentropy',
optimizer = RMSpop(),
metrics = ['accuracy'])
- 다항 분류
model.compile(loss = 'categorical_crossentropy',
optimizer = RMSpop(),
metrics = ['accuarcy'])
5. 모델 훈련, 평가 및 예측
- fit() 함수
- train_data(학습 데이터), train_label(데이터의 정답)
- epochs
- batch_size
- validation_data
- evaluate() 함수
- 테스트 데이터
- predict() 임의의 데이터를 인자로 넣어 예측 가능
'Python > Deep Learning' 카테고리의 다른 글
[딥러닝-케라스] 케라스 보스턴 주택 가격 모델 (0) | 2023.04.28 |
---|---|
[딥러닝-케라스] 케라스 기초(2) (1) | 2023.04.27 |
[딥러닝-텐서플로우] 텐서플로우 회귀 모델 (0) | 2023.04.26 |
[딥러닝-텐서플로우] 텐서플로우 기초 (0) | 2023.04.25 |
[딥러닝 기초] RNN(순환신경망) (0) | 2023.03.27 |