こんにちは、ヒガシです。
前回の記事にて、KeasのLambda層についての解説しましたが、Sequentialモデルでは複雑な処理を実行することができませんでした。
ということで今回はFunctionAPIモデルを使ってSequentialモデルではできなかった複雑な処理を実施してみようと思います。
それではさっそくやっていきましょう!
KerasのLambda層についての解説
KerasのLambda層を一言で言ってしまうと、自由な関数組み込み層であると言えます。
要は入力をシンプルに2倍したり2乗して出力する、なんて処理をニューラルネットワーク上で簡単に行えるということです。
意図的にノイズを加えたりする際に使われるみたいですね。
Keras-Lambda層の実装 (SequantialとFunctionAPIの比較)
それではLambda層を組み込んだモデルを実際に作ってみましょう。
今回はFunctionAPIモデルを使って単純に入力をLambda層に入れ、Lambda層での処理後の結果をそのまま出力するというシンプルなものを作ってみます。
以下がそのサンプルコードです。
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Lambda, InputLayer, Input
import numpy as np
#Sequentialモデルの場合
inout_dim = 2
model = Sequential()
model.add(InputLayer(input_shape=(inout_dim,)))
model.add(Lambda(lambda x: x**2))
model.summary()
input_data = np.array([3.,3.])
output_data = model(input_data)
print('input_data=', input_data)
print('output_data=', np.array(output_data))
#FunctionAPIモデルの場合
inout_dim = 2
inputs = Input(shape=inout_dim)
outputs = Lambda(lambda x: x**2)(inputs)
model = Model(inputs=inputs, outputs=outputs)
model.summary()
input_data = np.array([3.,3.])
output_data = model(input_data)
output_data = np.array(output_data)
print('input_data=', input_data)
print('output_data=', np.array(output_data))
上記のプログラムだとLambda層に書いてある通り、入力を単純に2乗して出力するというものになっています。
以下が実行結果です。
問題なく入力が2乗されていますね。
この程度の簡単なものだとSequentialモデルでも実行きることがわかります。
Lambda層で複雑な処理を実施したい場合
次はもう少し複雑な処理に変えてみましょう。
2次元ある入力のうち1次元目を2乗し、2次元目を2分の1にするという処理を実施してみます。
こんな時に活躍するのがFunctionAPIモデルです。
ということで先ほどとは順番を変えて、まずはFunctionAPIモデルで書いてみます。
4行目が先ほどと少し変わっていることがわかると思います。
#FunctionAPIモデルの場合
inout_dim = 2
inputs = Input(shape=inout_dim)
outputs = Lambda(lambda x: ([x[0]**2, x[1]/2]))(inputs)
model = Model(inputs=inputs, outputs=outputs)
model.summary()
input_data = np.array([3.,3.])
output_data = model(input_data)
output_data = np.array(output_data)
print('input_data=', input_data)
print('output_data=', np.array(output_data))
こいつを実行すると以下の結果が得られました。
問題なく2乗&2分の1化されてますね。
ということでFunctionAPIモデルではやりたいことを実行できました。
次にSequentialモデルで同じように書いてみます。
以下がそのコードです。
#Sequentialモデルの場合
inout_dim = 2
model = Sequential()
model.add(InputLayer(input_shape=(inout_dim,)))
model.add(Lambda(lambda x: ([x[0]**2, x[1]/2])))
model.summary()
input_data = np.array([3.,3.])
output_data = model(input_data)
print('input_data=', input_data)
print('output_data=', np.array(output_data))
Lambda層の中は先ほどのFunctionAPIモデルと全く同じです。
実行してみましょう。
すると以下のようなメッセージが出力されました。
ValueError: All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API.
まぁだいたい言ってることはわかりますが、念のためDeepLに入れて翻訳してみます。
以下がその結果です。
ValueError: シーケンシャルモデルのすべてのレイヤーは単一の出力テンソルを持つべきです。複数のレイヤーを出力する場合は、関数APIを使用してください。
こんな感じでSequentialだとできないのでFunctionAPI使ってね、と言われます。
まぁLambda層を組み込むようなモデルはそもそも複雑なものでしょうから、最初からFunctionAPI使ってるとは思いますけどね。
おわりに
ということで今回はKeras-FunctioonAPIモデルでのLambda層の解説、実演を行いました。
ぜひ複雑な処理の実行にご活用ください。
このブログでは、このようなAIスキルを多数紹介しています。
ぜひ他のページもご覧ください。
それではまた!
コメント