Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@ryota717

KerasのContainer内部のtrainable設定について検証してみた

Kerasには、複数レイヤをまとめてインスタンス化するContainerが用意されている。例えば以下のように書くと、2層の全結合層をインスタンス化したshared_layerが作成される。これによってネットワーク内に共通のパラメータを持った層を組み込むことができる。

inputs = Input((3,))
x = Dense(3, activation="sigmoid", use_bias=False)(inputs)
x = Dense(3, activation="sigmoid", use_bias=False)(x)
shared_layer = Container(inputs=inputs, outputs=x, name="shared_layer")

検証すること

kerasではモデルを構成するそれぞれの層のtrainableを変更することでその層の重みを更新するかどうか決定するが、どうやらContainerで作ったインスタンスとContainerを構成する各層でこの設定が独立してるらしい。
ということで以下の2つの設定をそれぞれ変更した4通りについて層の重みが更新されるか検証する。
①Containerでインスタンス化した層のtrainable設定
②Container内部の層のtrainable設定

実行環境

Keras:2.1.6
Python:3.6.4

※keras2.2以降ではContainerの代わりにNetworkを使うらしいので注意

検証モデル

使用するライブラリは以下の通り。

from keras.layers import Input, Dense
from keras.models import Model
from keras.engine.topology import Container
from keras.optimizers import sgd

import numpy as np

3層のニューラルネットワークを構築し、shared_layer内のtrainable設定をいじっておく。

model.py
#共有レイヤ作成
inputs = Input((3,))
x = Dense(3, activation="sigmoid", use_bias=False)(inputs)
x = Dense(3, activation="sigmoid", use_bias=False)(x)
shared_layer = Container(inputs=inputs, outputs=x, name="shared_layer")

#テストモデル構築
y = shared_layer(inputs)

model = Model(inputs=inputs, outputs=y)

#shared_layerのうち片方の重みを固定
model.get_layer("shared_layer").layers[1].trainable=False

①shared_layer.trainable=True

trainableの状況確認

print("shared_layer.trainable = " + str(model.get_layer("shared_layer").trainable) + "\n")
print("--each layer.trainable in shared_layer--")
for i in model.get_layer("shared_layer").layers:
    print(i.name, i.trainable)

shared_layer.trainable = True

--each layer.trainable in shared_layer--
input_1 False
dense_1 False
dense_2 True

パラメータの確認

for i in model.layers:
    print(i.name, i.get_weights())

input_1 []
shared_layer [array([[-0.43590093, -0.49712682, -0.5146408 ],
[ 0.51134324, 0.07132649, 0.2040441 ],
[-0.62061524, 0.42325187, -0.5272429 ]], dtype=float32), array([[-0.09528399, 0.9781587 , 0.22182012],
[ 0.90270543, 0.23723674, -0.18667579],
[ 0.929554 , -0.57312965, 0.7156825 ]], dtype=float32)]

学習

#optimizer作成
SGD = sgd(lr = 10)

#ダミーデータ作成(バッチサイズ5)
train_x = np.random.rand(5,3)
train_y = np.random.rand(5,3)

#重み更新
model.compile(optimizer=SGD, loss="mean_squared_error")
model.fit(x=train_x, y=train_y)

#重みの確認
for i in model.layers:
    print(i.name, i.get_weights())

input_1 []
shared_layer [array([[-0.43590093, -0.49712682, -0.5146408 ],
[ 0.51134324, 0.07132649, 0.2040441 ],
[-0.62061524, 0.42325187, -0.5272429 ]], dtype=float32), array([[-0.18501434, 0.9731035 , 0.05751626],
[ 0.8193617 , 0.24262278, -0.386313 ],
[ 0.8491909 , -0.57754445, 0.57252395]], dtype=float32)]

2番めのDense層のみパラメータが更新されている。。。

②shared_layer.trainable=False

設定変更、trainableの状況確認

#設定の変更
model.get_layer("shared_layer").trainable=False

print("shared_layer.trainable = " + str(model.get_layer("shared_layer").trainable) + "\n")
print("--each layer.trainable in shared_layer--")
for i in model.get_layer("shared_layer").layers:
    print(i.name, i.trainable)

shared_layer.trainable = False

--each layer.trainable in shared_layer--
input_1 False
dense_1 False
dense_2 True

パラメータの確認

for i in model.layers:
    print(i.name, i.get_weights())

input_1 []
shared_layer [array([[-0.43590093, -0.49712682, -0.5146408 ],
[ 0.51134324, 0.07132649, 0.2040441 ],
[-0.62061524, 0.42325187, -0.5272429 ]], dtype=float32), array([[-0.18501434, 0.9731035 , 0.05751626],
[ 0.8193617 , 0.24262278, -0.386313 ],
[ 0.8491909 , -0.57754445, 0.57252395]], dtype=float32)]

学習

#ダミーデータ作成(バッチサイズ5)
train_x = np.random.rand(5,3)
train_y = np.random.rand(5,3)

#重み更新
model.compile(optimizer=SGD, loss="mean_squared_error")
model.fit(x=train_x, y=train_y)

#重みの確認
for i in model.layers:
    print(i.name, i.get_weights())

input_1 []
shared_layer [array([[-0.43590093, -0.49712682, -0.5146408 ],
[ 0.51134324, 0.07132649, 0.2040441 ],
[-0.62061524, 0.42325187, -0.5272429 ]], dtype=float32), array([[-0.18501434, 0.9731035 , 0.05751626],
[ 0.8193617 , 0.24262278, -0.386313 ],
[ 0.8491909 , -0.57754445, 0.57252395]], dtype=float32)]

どの層も重みの変化なし。。。

結論

まとめるとこんな感じ。早い話、コンテナのtrainableとコンテナ内の層のtrainableの論理積だった。

コンテナのtrainable\コンテナ内のlayer.trainable True False
True ×
False × ×
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?