Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ja/tutorials/customization/custom_layers.ipynb
25118 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

カスタムレイヤー

ニューラルネットワークの構築には、高レベルの API である tf.keras を使うことを推奨しますが、TensorFlow API のほとんどは、eager execution でも使用可能です。

import tensorflow as tf
print(tf.config.list_physical_devices('GPU'))

レイヤー:有用な演算の共通セット

機械学習モデルのコーディングでは、個々の演算やひとつひとつの変数を操作するよりは、より高度に抽象化された演算を実行することが望ましい場合が多くあります。

多くの機械学習モデルは、比較的単純なレイヤーの合成やスタックとして表現することができますが、TensorFlow には一般的なレイヤーが多数用意されているだけでなく、独自のアプリケーション固有のレイヤーをゼロからまたは既存のレイヤーの合成として記述する簡単な方法が提供されています。

TensorFlow では、tf.keras パッケージに Keras API のすべてが含まれています。Keras のレイヤーは、独自のモデルを構築する際に大変便利です。

# In the tf.keras.layers package, layers are objects. To construct a layer, # simply construct the object. Most layers take as a first argument the number # of output dimensions / channels. layer = tf.keras.layers.Dense(100) # The number of input dimensions is often unnecessary, as it can be inferred # the first time the layer is used, but it can be provided if you want to # specify it manually, which is useful in some complex models. layer = tf.keras.layers.Dense(10, input_shape=(None, 5))

既存のレイヤーのすべての一覧は、ドキュメントを参照してください。Dense(全結合レイヤー)、Conv2D、LSTM、BatchNormalization、Dropoutなどのたくさんのレイヤーが含まれています。

# To use a layer, simply call it. layer(tf.zeros([10, 5]))
# Layers have many useful methods. For example, you can inspect all variables # in a layer using `layer.variables` and trainable variables using # `layer.trainable_variables`. In this case a fully-connected layer # will have variables for weights and biases. layer.variables
# The variables are also accessible through nice accessors layer.kernel, layer.bias

カスタムレイヤーの実装

独自のレイヤーを実装する最良の方法は、tf.keras.Layer クラスを拡張し、下記のメソッドを実装することです。

  1. __init__:入力に依存しないすべての初期化を実行できます

  2. build:入力テンソルの形状を知っている場合、残りの初期化を行うことができます。

  3. call:フォワード計算を行います。

build が呼ばれるまで変数の生成を待つ必要はなく、__init__ で作成できることに注意してください。しかしながら、build で変数を生成することの優位な点は、レイヤーが演算する入力の形状に基づいて、後から定義できる点です。これに対して、__init__ で変数を生成するには、必要な形状を明示的に指定する必要があります。

class MyDenseLayer(tf.keras.layers.Layer): def __init__(self, num_outputs): super(MyDenseLayer, self).__init__() self.num_outputs = num_outputs def build(self, input_shape): self.kernel = self.add_weight("kernel", shape=[int(input_shape[-1]), self.num_outputs]) def call(self, inputs): return tf.matmul(inputs, self.kernel) layer = MyDenseLayer(10)
_ = layer(tf.zeros([10, 5])) # Calling the layer `.builds` it.
print([var.name for var in layer.trainable_variables])

できるだけ標準のレイヤーを使ったほうが、概してコードは読みやすく保守しやすくなります。コードを読む人は標準的なレイヤーの振る舞いに慣れているからです。tf.keras.layers にはないレイヤーを使うことを希望する場合には、github の課題を作成するか、プルリクエスト (推薦) を送ってください。

モデル:レイヤーの組み合わせ

機械学習では、多くのレイヤーに類するものが、既存のレイヤーを組み合わせることで実装されています。例えば、ResNet の残差ブロックは、畳込み、バッチ正規化とショートカットの組み合わせです。レイヤーは他のレイヤー内にネストできます。

通常、Model.fitModel.evaluate、および、Model.save などのモデルメソッドが必要な場合は、keras.Model から継承します。

keras.Modelにより提供されるもう 1 つの機能(keras.layers.Layerの代わりに)として、変数の追跡に加えて、keras.Modelもその内部レイヤーを追跡し、検査を容易にします。

たとえば、ResNet ブロックは次のとおりです。

class ResnetIdentityBlock(tf.keras.Model): def __init__(self, kernel_size, filters): super(ResnetIdentityBlock, self).__init__(name='') filters1, filters2, filters3 = filters self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1)) self.bn2a = tf.keras.layers.BatchNormalization() self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same') self.bn2b = tf.keras.layers.BatchNormalization() self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1)) self.bn2c = tf.keras.layers.BatchNormalization() def call(self, input_tensor, training=False): x = self.conv2a(input_tensor) x = self.bn2a(x, training=training) x = tf.nn.relu(x) x = self.conv2b(x) x = self.bn2b(x, training=training) x = tf.nn.relu(x) x = self.conv2c(x) x = self.bn2c(x, training=training) x += input_tensor return tf.nn.relu(x) block = ResnetIdentityBlock(1, [1, 2, 3])
_ = block(tf.zeros([1, 2, 3, 3]))
block.layers
len(block.variables)
block.summary()

しかし、ほとんどの場合には、モデルはレイヤーを次々に呼び出すことで構成されます。tf.keras.Sequential クラスを使うことで、これをかなり短いコードで実装できます。

my_seq = tf.keras.Sequential([tf.keras.layers.Conv2D(1, (1, 1), input_shape=( None, None, 3)), tf.keras.layers.BatchNormalization(), tf.keras.layers.Conv2D(2, 1, padding='same'), tf.keras.layers.BatchNormalization(), tf.keras.layers.Conv2D(3, (1, 1)), tf.keras.layers.BatchNormalization()]) my_seq(tf.zeros([1, 2, 3, 3]))
my_seq.summary()

次のステップ

それでは、前のノートブックに戻り、レイヤーとモデルを使って、線形回帰の例をより構造化された形で実装してみてください。