"Keras:모델 제작"의 두 판 사이의 차이

Pywiki
둘러보기로 가기 검색하러 가기
 
(같은 사용자의 중간 판 17개는 보이지 않습니다)
1번째 줄: 1번째 줄:
 
== 개요 ==
 
== 개요 ==
 
학습 모델을 설계하고 제작한다. 층을 쌓아서 제작하는 형태.
 
학습 모델을 설계하고 제작한다. 층을 쌓아서 제작하는 형태.
 +
 +
모델을 만드는 방법은 클래스를 사용하느냐 안하느냐, 연쇄형이냐 분산형이냐에 따라 4가지 방법이 있다.
  
 
=== 예시와 사용 ===
 
=== 예시와 사용 ===
40번째 줄: 42번째 줄:
 
|모델 교육
 
|모델 교육
 
|모델을 교육한다.
 
|모델을 교육한다.
 +
 +
 +
만약 입력하는 데이터가 제너레이터라면 fit 대신
 +
 +
fit_generato 함수로 교육해야 한다.
 
|<syntaxhighlight lang="python">
 
|<syntaxhighlight lang="python">
 
# 어떤 방식으로 교육할지 지정.
 
# 어떤 방식으로 교육할지 지정.
70번째 줄: 77번째 줄:
  
 
= 모델 제작 =
 
= 모델 제작 =
 +
모델은 Sequential과 add를 이용한 연쇄방식과, 순차적으로 넘겨주는 분산방식이 있다.
  
== Sequential 사용 ==
+
이외 클래스 상속을 통해 모델을 정의하여 객체지향형으로 사용할 수도 있는데, 이 때에도 역시 연쇄형, 분산형으로 나뉜다.
keras.models.Sequential() 순차적으로 쌓일 모델 객체를 생성한다.<syntaxhighlight lang="python">
+
{| class="wikitable"
 +
|+
 +
!방식
 +
!설명
 +
!한계
 +
!예시
 +
|-
 +
|연쇄방식
 +
(순차적 모델)
 +
|순차적으로 쌓는 직관적 방식.
 +
간단해서 별다른 설명이 필요치 않다.
 +
|
 +
* 모델에 하나의 출력, 하나의 입력만 가능.
 +
* 레이어를 공유하는 형태 불가.
 +
* 차례대로 층을 쌓는 간단한 방식만 가능.
 +
|<syntaxhighlight lang="python">
 
from keras.models import Sequential
 
from keras.models import Sequential
 
from keras import layers  # 층을 불러온다.
 
from keras import layers  # 층을 불러온다.
78번째 줄: 101번째 줄:
 
model = Sequential()
 
model = Sequential()
 
# 필요한 층을 더한다.
 
# 필요한 층을 더한다.
model.add(layers.LSTM(50, return_sequences=True, input_shape=(50,1))) # 50개 유닛을 갖는 LSTM층 생성.
+
model.add(layers.LSTM(50, return_sequences=True, input_shape=(50,1)))
# 50개 OUT.
+
# 50개 유닛을 갖는 LSTM층 생성. 50개 OUT.
model.add(layers.Dense(1, activation='linear')) # 일반 뉴런층 1개. 결과가 1개가 나온다.
+
model.add(layers.Dense(1, activation='linear'))
# 1개 OUT.
+
# 일반 뉴런층 1개. 결과가 1개가 나온다.
 
model.compile(loss='mse', optimizer='rmsprop')  # 손실함수 따위를 결정한다.
 
model.compile(loss='mse', optimizer='rmsprop')  # 손실함수 따위를 결정한다.
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
|-
 +
|분산방식
 +
(함수형 API)
 +
|함수처럼 생겨서 함수형 API라 부른다.
 +
|
 +
|<syntaxhighlight lang="python">
 +
from keras.models import Model
 +
from keras import layers  # 층을 불러온다.
 +
from keras import Input
 +
 +
input = Input(shape=(50,1))
 +
x = layers.Dense(50, activation='relu')(input)
 +
predict = layers.LSTM(50, activation='relu')(x)
 +
 +
model = Model(input, predict)  # 인풋과 아웃풋을 지정하여 모델을 설정한다.
 +
# 인풋이나 아웃풋이 여러개인 경우 리스트로 넣을 수 있다.
 +
 +
</syntaxhighlight>
 +
|-
 +
|
 +
|
 +
|
 +
|
 +
|}
 +
 +
== 분산방식(함수형 API 사용) ==
 +
다음의 예시를 참고하면 다양하게 활용할 수 있을 것이다.
 +
 +
함수형 API를 사용하면 다중 입력, 다중 출력을 갖는 모델을 만들 수 있다. 혹은 하나의 층을 여러 출력에서 공유할 수도 있고.
 +
 +
=== 인풋이 여러 개인 경우 ===
 +
<syntaxhighlight lang="python">
 +
from keras import layers, models
 +
 +
input = layers.Input(shape(50,200,200))
 +
input_2 = layers.Input(shape(50,200,200))
 +
concatenated = layers.Concatenate(axis=-1)([input, input_2])
 +
x = layers.Dense(32, activation='relu')(concatenated)
 +
output = layers.Dense(10, activation='softmax')(x)
 +
 +
model = models.Model(inputs=[input, input_2], outputs=output)  # 모델생성.
 +
</syntaxhighlight><code>axis=</code>에 주어지는 숫자는 input_shape의 어떤 곳에 추가할 것이냐에 대한 결정값이다. 2번째 차원방향으로 추가할 거라면 axis=1을 넣어주면 된다.
 +
 +
== 이외 팁 ==
  
 
=== input ===
 
=== input ===
96번째 줄: 163번째 줄:
 
|가로세로 200인 이미지는 다음과 같이 변형해 사용된다.
 
|가로세로 200인 이미지는 다음과 같이 변형해 사용된다.
 
(samples, height, width, channels) 혹은 (samples, channels, height, width)로 입력한다.
 
(samples, height, width, channels) 혹은 (samples, channels, height, width)로 입력한다.
|images.reshape((이미지갯수, 200 * 200))
+
|images.reshape((이미지갯수, 200 * 200)) # 이미지를 1줄로 늘어놓겠다는 것.
 
images.astype('float32')/255  # 값을 0~1 사이로 정규화 한다. float32와 64의 차이는 무엇일까?
 
images.astype('float32')/255  # 값을 0~1 사이로 정규화 한다. float32와 64의 차이는 무엇일까?
 
|-
 
|-
128번째 줄: 195번째 줄:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
|}
 
|}
 
== 함수형 API 사용 ==
 
<syntaxhighlight lang="python">
 
from keras import layers, models
 
 
input = layers.Input(shape(50,200,200))
 
x = layers.Dense(32, activation='relu')(Input)
 
output = layers.Dense(10, activation='softmax')(x)
 
 
model = models.Model(inputs=input, outputs=output)  # 모델생성.
 
</syntaxhighlight>
 
  
 
= 모델 교육 =
 
= 모델 교육 =
150번째 줄: 206번째 줄:
 
                 metrics= ['accuracy'])              # 모니터링 지표.
 
                 metrics= ['accuracy'])              # 모니터링 지표.
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
  
 
== 교육 ==
 
== 교육 ==
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
model.fit(x, y,
+
history = model.fit(x, y,
 
     validation_data = (x_test, y_test),
 
     validation_data = (x_test, y_test),
 
     batch_size = 10,    # 한 번에 몇 개의 데이터를 묶어서 학습시킬 것인가.
 
     batch_size = 10,    # 한 번에 몇 개의 데이터를 묶어서 학습시킬 것인가.
159번째 줄: 216번째 줄:
 
     )     
 
     )     
  
</syntaxhighlight>
+
</syntaxhighlight>history.history 안의 loss, val_loss 등의 속성에 접근하여 교육 결과를 살펴볼 수 있다.
 +
 
 +
 
 +
= 모델평가 =
  
= 모델 검증 =
+
== 모델 검증 ==
 
validation_data를 넣어 loss 검사를 할 수도 있지만...
 
validation_data를 넣어 loss 검사를 할 수도 있지만...
  
 
validation_split를 0~1 사이로 넣으면, 데이터를 처리하기 전에 해당 비율만큼 마지막에서 떼내어 epoch가 끝나면 loss를 계산하는 데 쓰인다.
 
validation_split를 0~1 사이로 넣으면, 데이터를 처리하기 전에 해당 비율만큼 마지막에서 떼내어 epoch가 끝나면 loss를 계산하는 데 쓰인다.
 +
 +
== 최종평가 ==
 +
모델을 훈련한 후 최종적으로 모델을 평가할 땐 evaluate를 사용한다.<syntaxhighlight lang="python">
 +
test_loss, test_add = models.evaluate(test, lables)
 +
</syntaxhighlight>
 +
 +
== 시각화 ==
 +
다음과 같은 코드로 훈련의 결과를 시각화 할 수 있다.(각 에포크마다 loss가 어떻게 변하는지...)<syntaxhighlight lang="python">
 +
loss = history.history['loss']
 +
val_loss = history.history['val_loss']
 +
 +
epochs = range(1, len(loss) + 1)
 +
 +
plt.figure()
 +
 +
plt.plot(epochs, loss, 'bo', label='Training loss')
 +
plt.plot(epochs, val_loss, 'b', label='Validation loss')
 +
plt.title('Training and validation loss')
 +
plt.legend()
 +
 +
plt.show()
 +
</syntaxhighlight>
 +
 +
= 모델 저장과 불러우기 =
 +
 +
== 모델 저장 ==
 +
디렉터리 형태로 저장된다.<syntaxhighlight lang="python">
 +
model.save('\경로\디렉토리명')
 +
</syntaxhighlight>디렉토리를 생성하기 때문에 관리자 권한이 필요하다.
 +
 +
어째서인지.... 경로를 하나의 텍스트가 아니라 +로 잇는 방식을 사용하면 \가 /로 바뀌어버리고 만다.(그래서 윈도우에선 에러가 난다;) 때문에 하나의 따옴표쌍 안에 경로를 수기로 입력해야 한다....
 +
 +
== 모델 불러오기 ==
 +
<syntaxhighlight lang="python">
 +
from keras.models import load_model
 +
 +
model = load_model('모델경로')
 +
model.summary()  # 불러온 모델 확인.
 +
</syntaxhighlight>
  
 
[[분류:Keras]]
 
[[분류:Keras]]

2022년 4월 19일 (화) 23:26 기준 최신판

1 개요[편집 | 원본 편집]

학습 모델을 설계하고 제작한다. 층을 쌓아서 제작하는 형태.

모델을 만드는 방법은 클래스를 사용하느냐 안하느냐, 연쇄형이냐 분산형이냐에 따라 4가지 방법이 있다.

1.1 예시와 사용[편집 | 원본 편집]

이미지 분류에 대한 모델은 다음과 같이 만들어진다.

의도 설명 방법
모델 제작
from tensorflow.keras import layers

# 입력 데이터 처리.
inputs = keras.Input(shape=(None, None, 3))     # 3개의 채널, 크기제한 없음.
x = CenterCrop(height=150, width=150)(inputs)   # 이미지 크롭.
x = Rescaling(scale=1.0 / 255)(x)               # 0~1 사이의 값으로 스케일링.

# 층 만들기.
x = layers.Conv2D(filters=32, kernel_size=(3, 3), activation="relu")(x)     # 합성곱 레이어.
x = layers.MaxPooling2D(pool_size=(3, 3))(x)                                # 풀링층 
x = layers.Conv2D(filters=32, kernel_size=(3, 3), activation="relu")(x)
x = layers.MaxPooling2D(pool_size=(3, 3))(x)
x = layers.Conv2D(filters=32, kernel_size=(3, 3), activation="relu")(x)
x = layers.GlobalAveragePooling2D()(x)                                      # 평균풀링.

num_classes = 10
outputs = layers.Dense(num_classes, activation="softmax")(x)  # 분류 갯수(num_classes)에 따라 분류한다.

# 모델 제작
model = keras.Model(inputs=inputs, outputs=outputs)
모델 정보 보기 모델에 대한 요악정보를 볼 수 있다. model.summary()
모델 교육 모델을 교육한다.


만약 입력하는 데이터가 제너레이터라면 fit 대신

fit_generato 함수로 교육해야 한다.

# 어떤 방식으로 교육할지 지정.
model.compile(optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
              loss=keras.losses.CategoricalCrossentropy())
batch_size = 32  # 검증데이터의 배치사이즈에서도 공유해야 하기 때문에 변수로 지정.
callbacks = [  # 각 에포크마다 교육데이터를 저장한다.
    keras.callbacks.ModelCheckpoint(
        filepath='path/to/my/model_{epoch}',
        save_freq='epoch')
]

# 사용할 데이터 지정.
dataset = tf.data.Dataset.from_tensor_slices((numpy_array_of_samples, numpy_array_of_labels)).batch(batch_size)
# 검증 데이터 설정.
val_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(batch_size)

# 모델 교육 및 검증. dataset 안에 배치사이즈를 지정해 담았다.
history = model.fit(dataset, epochs=1, callbacks=callbacks,
                    validation_data=val_dataset)
print(history.history)  # 로스, 정확도 등의 데이터를 보여준다.

2 모델 제작[편집 | 원본 편집]

모델은 Sequential과 add를 이용한 연쇄방식과, 순차적으로 넘겨주는 분산방식이 있다.

이외 클래스 상속을 통해 모델을 정의하여 객체지향형으로 사용할 수도 있는데, 이 때에도 역시 연쇄형, 분산형으로 나뉜다.

방식 설명 한계 예시
연쇄방식

(순차적 모델)

순차적으로 쌓는 직관적 방식.

간단해서 별다른 설명이 필요치 않다.

  • 모델에 하나의 출력, 하나의 입력만 가능.
  • 레이어를 공유하는 형태 불가.
  • 차례대로 층을 쌓는 간단한 방식만 가능.
from keras.models import Sequential
from keras import layers  # 층을 불러온다.

model = Sequential()
# 필요한 층을 더한다.
model.add(layers.LSTM(50, return_sequences=True, input_shape=(50,1)))
# 50개 유닛을 갖는 LSTM층 생성. 50개 OUT.
model.add(layers.Dense(1, activation='linear'))
# 일반 뉴런층 1개. 결과가 1개가 나온다.
model.compile(loss='mse', optimizer='rmsprop')  # 손실함수 따위를 결정한다.
분산방식

(함수형 API)

함수처럼 생겨서 함수형 API라 부른다.
from keras.models import Model
from keras import layers  # 층을 불러온다.
from keras import Input

input = Input(shape=(50,1))
x = layers.Dense(50, activation='relu')(input)
predict = layers.LSTM(50, activation='relu')(x)

model = Model(input, predict)  # 인풋과 아웃풋을 지정하여 모델을 설정한다.
# 인풋이나 아웃풋이 여러개인 경우 리스트로 넣을 수 있다.

2.1 분산방식(함수형 API 사용)[편집 | 원본 편집]

다음의 예시를 참고하면 다양하게 활용할 수 있을 것이다.

함수형 API를 사용하면 다중 입력, 다중 출력을 갖는 모델을 만들 수 있다. 혹은 하나의 층을 여러 출력에서 공유할 수도 있고.

2.1.1 인풋이 여러 개인 경우[편집 | 원본 편집]

from keras import layers, models

input = layers.Input(shape(50,200,200))
input_2 = layers.Input(shape(50,200,200))
concatenated = layers.Concatenate(axis=-1)([input, input_2])
x = layers.Dense(32, activation='relu')(concatenated)
output = layers.Dense(10, activation='softmax')(x)

model = models.Model(inputs=[input, input_2], outputs=output)  # 모델생성.

axis=에 주어지는 숫자는 input_shape의 어떤 곳에 추가할 것이냐에 대한 결정값이다. 2번째 차원방향으로 추가할 거라면 axis=1을 넣어주면 된다.

2.2 이외 팁[편집 | 원본 편집]

2.2.1 input[편집 | 원본 편집]

데이터별로 input의 형태가 달라진다.

의도 설명 방법
이미지 가로세로 200인 이미지는 다음과 같이 변형해 사용된다.

(samples, height, width, channels) 혹은 (samples, channels, height, width)로 입력한다.

images.reshape((이미지갯수, 200 * 200)) # 이미지를 1줄로 늘어놓겠다는 것.

images.astype('float32')/255 # 값을 0~1 사이로 정규화 한다. float32와 64의 차이는 무엇일까?

동영상 이미지에 frame을 추가한다.

(samples, frame, height, width, channels) 형태.

시계열 (samples, timesteps, features) 형태로 입력한다.
텍스트 2만개의 단어를 가진 사전으로 만든 데이터셋으로 분석할 때, 500개 문서의 데이터셋은..

(500, 20000) 형태이다.

2.2.2 레이블 변형[편집 | 원본 편집]

의도 설명 방법
범주형 인코딩 레이블을 범주형으로 인코딩한다.
from keras.utils import to_categorical

lable = to_categorical(lable)

3 모델 교육[편집 | 원본 편집]

3.1 컴파일[편집 | 원본 편집]

모델을 어떻게 교육할 것인가에 대한 설정.

from keras import optimizers

model.compile(optimizer= 'rmsprop',                 # 어떻게 교육할 것인가.
                loss= 'categorical_crossentropy',   # 손실함수.
                metrics= ['accuracy'])              # 모니터링 지표.


3.2 교육[편집 | 원본 편집]

history = model.fit(x, y,
    validation_data = (x_test, y_test),
    batch_size = 10,    # 한 번에 몇 개의 데이터를 묶어서 학습시킬 것인가.
    epochs = 20,        # 몇 번 학습시킬 것인가?
    )

history.history 안의 loss, val_loss 등의 속성에 접근하여 교육 결과를 살펴볼 수 있다.


4 모델평가[편집 | 원본 편집]

4.1 모델 검증[편집 | 원본 편집]

validation_data를 넣어 loss 검사를 할 수도 있지만...

validation_split를 0~1 사이로 넣으면, 데이터를 처리하기 전에 해당 비율만큼 마지막에서 떼내어 epoch가 끝나면 loss를 계산하는 데 쓰인다.

4.2 최종평가[편집 | 원본 편집]

모델을 훈련한 후 최종적으로 모델을 평가할 땐 evaluate를 사용한다.

test_loss, test_add = models.evaluate(test, lables)

4.3 시각화[편집 | 원본 편집]

다음과 같은 코드로 훈련의 결과를 시각화 할 수 있다.(각 에포크마다 loss가 어떻게 변하는지...)

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1, len(loss) + 1)

plt.figure()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

5 모델 저장과 불러우기[편집 | 원본 편집]

5.1 모델 저장[편집 | 원본 편집]

디렉터리 형태로 저장된다.

model.save('\경로\디렉토리명')

디렉토리를 생성하기 때문에 관리자 권한이 필요하다.

어째서인지.... 경로를 하나의 텍스트가 아니라 +로 잇는 방식을 사용하면 \가 /로 바뀌어버리고 만다.(그래서 윈도우에선 에러가 난다;) 때문에 하나의 따옴표쌍 안에 경로를 수기로 입력해야 한다....

5.2 모델 불러오기[편집 | 원본 편집]

from keras.models import load_model

model = load_model('모델경로')
model.summary()  # 불러온 모델 확인.