機械学習のExampleから覚えるPython(class:コンストラクタ)

今までPythonを感覚的に使っていたので、改めて文法を知ろうかなと。
その際にいま流行りの機械学習(深層学習)のExampleを例にすると
わかりやすいのかなと思ったので書いてみる。

※基本的には Python3.x系のつもりで記載してます

Example

https://www.tensorflow.org/tutorials/ に記載されている

import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

※本記事記載の時点のコードです。

class

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

tf.keras.models.Sequentialclassと呼ばれるもので定義されています。

実際のコードは こちらにあります。

@keras_export('keras.models.Sequential', 'keras.Sequential')
class Sequential(Model):

さて、前回の記事では Sequentialクラス Modelは継承(基底クラス)というお話でした。
では、Exampleコードに書かれている

  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)

の部分はどこにあたるのかを今回見ていきたいと思います。

コンストラク

Pythonでは、特殊な関数があります。
その一つが コンストラクタ: __init()__になります。
クラスがインスタンスされた際に自動で呼び出されます。

では、実際の実装のほうを見てみたいと思います。

  def __init__(self, layers=None, name=None):
    super(Sequential, self).__init__(name=name)
    self.supports_masking = True
    self._build_input_shape = None
    self._compute_output_and_mask_jointly = True

    self._layer_call_argspecs = {}

    # Add to the model any layers passed to the constructor.
    if layers:
      for layer in layers:
        self.add(layer)

実際のコードは こちら にあります。

self はクラス自身を指すので、引数としては無視してください。
では、クラスをインスタンス(宣言)時に引数として渡していた
tf.keras.layers.*** はどの引数に該当するかというと layers になります。

    # Add to the model any layers passed to the constructor.
    if layers:
      for layer in layers:
        self.add(layer)

つまり、コンストラクタ(初期化)で行っている処理は
layers が存在していれば(Noneでなければ)、layers の配列数だけ
クラス自身のadd関数を呼び出す です。

add関数が何をしているかは確認してもらえればと思います。

デコンストラク

クラスが削除される際に自動で呼び出されます。
デコンストラクタ: __del()__になります。

Sequentialクラスには実装がありませんね。
必要に応じて実装すればよいかと思いますが、あまり見た記憶がありません。

おまけ

TensorFlow公式ページでは、Kerasによる書き方がいくつか紹介されています。
独自のModelやLayerの書き方などもありますので、参考にすると良いかと思います。

今回のコンストラクタの話でいうと、このような書き方も記載されています。

model = tf.keras.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10,)))
model.add(layers.Dense(1, activation='sigmoid'))

引数なしで Sequentialクラスをインスタンスし、次行で add関数で Layerを追加している書き方になります。