KerasのFunctional API で多入力・多出力モデル

2021.05.18
2024.03.24
機械学習
PythonKeras

本ページはAmazonアフィリエイトのリンクを含みます。

はじめに

こちらの記事はQiitaで投稿した「Functional API で多入力・多出力モデル」の再投稿になります。

Keras の Functional API を使った基本的なモデルの実装と多入力・多出力モデルを実装する方法について紹介します。

環境

今回は Tensorflow に統合された Keras を利用しています。

1tensorflow==2.3.0

ゴール

  • Functional API が使える
  • 多入力・多出力モデルを実装できる

Functional API とは

Sequential モデルより柔軟なモデルを実装できるものになります。 今回は、Sequential モデルでは表現できないモデルの中から多入力・多出力モデルを実装していきます。

基本的な使い方

まずは、Functional API の基本的な使い方を説明していきます。 Functional API はモデルを定義する方法なので、学習・評価・予測は Sequential モデルと同じになります。

入力層

まずは、keras.Inputで入力層を定義します。

1inputs = keras.Input(shape=(128,))

中間層・出力層

以下のように層を追加していくことができ、最後の層が出力層になります。

1x = layers.Dense(64, activation="relu")(inputs)
2outputs = layers.Dense(10)(x)

モデル作成

層の定義が完了したら、入力層と出力層を指定して、モデルを作成します。

1model = keras.Model(inputs=inputs, outputs=outputs, name="model")

Sequential モデルとの比較

Sequential モデルと Functional API で同じモデルを実装してみます。

実装するモデルは以下の通りです。

sequential_model.png

Sequential モデル

1from tensorflow import keras
2from tensorflow.keras import layers
3from tensorflow.keras.models import Sequential
4
5model = Sequential()
6model.add(layers.Dense(64, activation='relu', input_shape=(784,)))
7model.add(layers.Dense(64, activation='relu'))
8model.add(layers.Dense(10, activation='softmax'))

Functional API

1from tensorflow import keras
2from tensorflow.keras import layers
3
4inputs = keras.Input(shape=(784,))
5x = layers.Dense(64, activation='relu')(inputs)
6x = layers.Dense(64, activation='relu')(x)
7outputs = layers.Dense(10, activation='softmax')(x)
8model = keras.Model(inputs=inputs, outputs=outputs)

多入力・多出力モデル

Functional API で多入力・多出力モデルを実装していきます。

多入力

入力層を複数定義することで、多入力にすることができます。 複数の層をまとめるときは、layers.concatenateを利用します。

1inputs1 = keras.Input(shape=(64,), name="inputs1_name")
2inputs2 = keras.Input(shape=(32,), name="inputs2_name")
3
4x = layers.concatenate([inputs1, inputs2])

多出力

中間層を複数に渡すことで、層を分岐させることができます。 終点となる層が複数になることで、多出力になります。

1outputs1 = layers.Dense(64, name="outputs1_name")(x)
2outputs2 = layers.Dense(32, name="outputs2_name")(X)

コンパイル

複数の出力層がある場合は、それぞれに損失関数と重みを指定できます。

1model.compile(
2    optimizer=keras.optimizers.RMSprop(1e-3),
3    loss={
4        "outputs1_name": keras.losses.BinaryCrossentropy(from_logits=True),
5        "outputs2_name": keras.losses.CategoricalCrossentropy(from_logits=True),
6    },
7    loss_weights=[1.0, 0.5],
8)

学習

層につけた名前で入力データと出力データ(ターゲット)を指定して、学習させることができます。

1model.fit(
2    {"inputs1_name": inputs1_data, "inputs2_name": inputs2_data},
3    {"outputs1_name": outputs1_targets, "outputs2_name": outputs2_targets},
4    epochs=2,
5    batch_size=32,
6)

具体例

具体的な例を用いて実装してきます。

ここでは、顧客からの問い合わせのタイトルと本文とタグから、その問い合わせの優先度と対応部門を予測します。

入力

  • タイトル
  • 本文
  • タグ

出力

  • 優先度
  • 対応部門

image.png

1from tensorflow import keras
2from tensorflow.keras import layers
3import numpy as np
4
5num_tags = 12
6num_words = 10000
7num_departments = 4
8
9# ダミーデータの作成
10title_data = np.random.randint(num_words, size=(1280, 10))
11body_data = np.random.randint(num_words, size=(1280, 100))
12tags_data = np.random.randint(2, size=(1280, num_tags)).astype("float32")
13priority_targets = np.random.random(size=(1280, 1))
14dept_targets = np.random.randint(2, size=(1280, num_departments))
15
16# タイトルの層
17title_input = keras.Input(
18    shape=(None,), name="title"
19)
20title_features = layers.Embedding(num_words, 64)(title_input)
21title_features = layers.LSTM(128)(title_features)
22
23# 本文の層
24body_input = keras.Input(shape=(None,), name="body")
25body_features = layers.Embedding(num_words, 64)(body_input)
26body_features = layers.LSTM(32)(body_features)
27
28# タグの層
29tags_input = keras.Input(
30    shape=(num_tags,), name="tags"
31)
32tags_features = layers.Dense(36, activation='relu')(tags_input)
33
34# 層を結合
35x = layers.concatenate([title_features, body_features, tags_features])
36
37# 出力層
38priority_output = layers.Dense(1, name="priority")(x)
39department_output = layers.Dense(num_departments, name="department")(x)
40
41model = keras.Model(
42    inputs=[title_input, body_input, tags_input],
43    outputs=[priority_output, department_output],
44)
45
46# モデルをコンパイル
47model.compile(
48    optimizer=keras.optimizers.RMSprop(1e-3),
49    loss={
50        "priority": keras.losses.BinaryCrossentropy(from_logits=True),
51        "department": keras.losses.CategoricalCrossentropy(from_logits=True),
52    },
53    loss_weights=[1.0, 0.5],
54)
55
56# 学習
57model.fit(
58    {"title": title_data, "body": body_data, "tags": tags_data},
59    {"priority": priority_targets, "department": dept_targets},
60    epochs=2,
61    batch_size=32,
62)

まとめ

  • Functional API を使うと多入力・多出力のモデルを実装できる

参考文献

Support

\ この記事が役に立ったと思ったら、サポートお願いします! /

buy me a coffee
Share

Profile

author

Masa

都内のIT企業で働くエンジニア
自分が学んだことをブログでわかりやすく発信していきながらスキルアップを目指していきます!

buy me a coffee