딥러닝_케라스 API_3. 케라스 모델을 만드는 여러 방법

주지윤·2022년 12월 1일
0

딥러닝

목록 보기
10/21
post-custom-banner

케라스 모델을 만드는 여러 방법

🔸 케라스 API설계는 단계적 공개(progressive disclosure) 원칙을 따른다.

  • 시작은 쉽게, 필요할때 점진적으로 학습

🔸 케라스에서 모델을 만드는 방법

  • Sequential 모델: 단순히 층을 쌓은 것이고 하나의 입력을 하나의 출력에 매핑한다.
  • 함수형 API: 그래프 같은 모델, 사용성과 유연성 적절
  • Model 서브클래싱: 모든 것을 밑바닥부터 만들 수 있는 저수준 방법


Sequential모델: keras.Sequential

import keras
from keras import Sequential
from keras import layers
from keras.layers import Dense, Input

model = Sequential([
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

==

model= Sequential()
model.add(Dense(64,activation='relu'))
model.add(Dense(10,activation='softmax'))
  • layer는 처음 호출될 때(fit) 만들어짐 = 가중치를 만듦
  • 현재 위의 코드만으로는 가중치를 가지고 있지 않음
  • build() 함수 호출로 모델의 가중치를 설정할 수 있음

🔸 build()

model.build(input_shape=(None, 3))
model.weights

🔸 model.summary()

model.summary()


🔸 모델 input 미리지정: 가중치 바로 생성

model = Sequential(name='Input 미리지정')
model.add(keras.Input(shape=(3,))) # == model.add(Dense(64,activation='relu',input_shape=(3,)))
model.add(Dense(64, activation='relu'))
model.add(Dense(10, activation='softmax'))

model.summary()


함수형 API: keras.Model

  • Sequential은 사용하기 쉽지만 적용할 수 있는 곳이 제한적
    • 단일 입, 출력만 가능
  • 다중입력, 다중출력 또는 비선형적 구조에서는 함수형 API를 사용한다.

1) 단일 입·출력: 2개의 Dense층을 가진 함수형 모델

inputs = keras.Input(shape=(3,)) 
features = Dense(64, activation='relu')(inputs)
outputs = Dense(10, activation='softmax')(features)
model = keras.Model(inputs,outputs)
model.summary()

🔸 심볼릭텐서(symbolic tensor):

  • inputs = keras.Input(shape=(3,))
  • 실제 데이터를 가지고 있지 않지만 텐서 사양 인코딩, 미래의 데이터 텐서를 표시

🔸 모델 토폴로지(topology) : keras.utils.plot_model

keras.utils.plot_model(model)


🔸 mnist로 테스트

from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

train_images = train_images.reshape((60000, 28*28))
test_images = test_images.reshape((10000, 28*28))

train_images = train_images / 255.0
test_images = test_images / 255.0


inputs= keras.Input(shape=(train_images.shape[1],)) 
features = Dense(64, activation='relu')(inputs)
outputs = Dense(10, activation='softmax')(features)
model = keras.Model(inputs,outputs)

model.compile(optimizer="rmsprop",
              loss="sparse_categorical_crossentropy",
              metrics='accuracy')
              
model.summary()

keras.utils.plot_model(model,show_shapes=True)

model.fit(train_images, train_labels, epochs=5, batch_size=128)
model.evaluate(test_images, test_labels)


2) 다중 입·출력: 예제_고객 이슈 티켓

  • 입력: 3개
    • 제목
    • 텍스트
    • 태그(범주입력)
  • 출력: 2개
    • 우선순위(sigmoid,(0 혹은 1))
    • 처리 부서(softmax)

🔸 모델 구성

vocabulary_size = 10000 
num_tags = 100 
num_departments = 4 

#-----------------모델 입력--------------------#  
title = Input(shape=(vocabulary_size,), name="title")
text_body = Input(shape=(vocabulary_size,), name="text_body")
tags = Input(shape=(num_tags,), name="tags")

#------------------중간 층---------------------# 

features = layers.Concatenate()([title, text_body, tags])
features = Dense(64, activation="relu")(features)

#-----------------모델 출력--------------------#  
priority = Dense(1, activation="sigmoid", name="priority")(features)
department = Dense(num_departments, activation="softmax", name="department")(features)


model = keras.Model(inputs=[title, text_body, tags],
                    outputs=[priority, department])
keras.utils.plot_model(model, show_shapes=True)

  • 중간층으로 갈 때 입력특성을 하나의 텐서로 연결
    • features = layers.Concatenate()([title, text_body, tags])

🔸 더미 데이터 입력

import numpy as np
  
num_samples = 1280 
  
title_data = np.random.randint(0, 2, size=(num_samples, vocabulary_size))
text_body_data = np.random.randint(0, 2, size=(num_samples, vocabulary_size))
tags_data = np.random.randint(0, 2, size=(num_samples, num_tags))
 
priority_data = np.random.random(size=(num_samples, 1))
department_data = np.random.randint(0, 2, size=(num_samples, num_departments))

🔸 모델 훈련

model.compile(optimizer="rmsprop",
              loss={"priority": "mean_squared_error", "department":
                    "categorical_crossentropy"},
              metrics={"priority": ["mean_absolute_error"], "department":
                       ["accuracy"]})

model.fit({"title": title_data, "text_body": text_body_data,
           "tags": tags_data},
          {"priority": priority_data, "department": department_data},
          epochs=1)

model.evaluate({"title": title_data, "text_body": text_body_data,
                "tags": tags_data},
               {"priority": priority_data, "department": department_data})
priority_preds, department_preds = model.predict(
    {"title": title_data, "text_body": text_body_data, "tags": tags_data})

🔸 model.layers

  • 각 층 설명
model.layers


  • 층의 input, output
model.layers[0].input

<KerasTensor: shape=(None, 10000) dtype=float32 (created by layer 'title')>

model.layers[4].output

<KerasTensor: shape=(None, 64) dtype=float32 (created by layer 'dense_4')>


🔸 특성추출/ 중간층 재사용하여 새 output을 만들고, 새로운 모델 생성

features = model.layers[4].output
difficulty = layers.Dense(3, activation="softmax", name="difficulty")(features)
  
new_model = keras.Model(
    inputs=[title, text_body, tags],
    outputs=[priority, department, difficulty])

keras.utils.plot_model(
    new_model, show_shapes=True)



Model 서브클래싱

  • __init__(): 모델이 사용할 층 정의
  • call(): 정방향 패스 정의
  • 서브클래스의 객체를 만들고, 가중치를 만듦

🔸 코드 참고

class CustomerTicketModel(keras.Model):
  
    def __init__(self, num_departments):
        super().__init__()
        self.concat_layer = layers.Concatenate()
        self.mixing_layer = layers.Dense(64, activation="relu")
        self.priority_scorer = layers.Dense(1, activation="sigmoid")
        self.department_classifier = layers.Dense(
            num_departments, activation="softmax")
 
    def call(self, inputs):
        title = inputs["title"]
        text_body = inputs["text_body"]
        tags = inputs["tags"]
  
        features = self.concat_layer([title, text_body, tags])
        features = self.mixing_layer(features)
        priority = self.priority_scorer(features)
        department = self.department_classifier(features)
        return priority, department
model = CustomerTicketModel(num_departments=4)
 
priority, department = model(
    {"title": title_data, "text_body": text_body_data, "tags": tags_data})
model.compile(optimizer="rmsprop",
              loss=["mean_squared_error", "categorical_crossentropy"],
              metrics=[["mean_absolute_error"], ["accuracy"]])
model.fit({"title": title_data,
           "text_body": text_body_data,
           "tags": tags_data},
          [priority_data, department_data],
          epochs=1)
model.evaluate({"title": title_data,
                "text_body": text_body_data,
                "tags": tags_data},
               [priority_data, department_data])
priority_preds, department_preds = model.predict({"title": title_data,
                                                  "text_body": text_body_data,
                                                  "tags": tags_data})
post-custom-banner

0개의 댓글