Python言語の文法を、コードを書く流れに沿って説明していく連載。今回と次回は、クラスを取り上げる。今回は、そのうちの利用方法について説明する。
ご注意:本記事は、@IT/Deep Insider編集部(デジタルアドバンテージ社)が「deepinsider.jp」というサイトから、内容を改変することなく、そのまま「@IT」へと転載したものです。このため用字用語の統一ルールなどは@ITのそれとは一致しません。あらかじめご了承ください。
前回は「制御構文(ループ処理)」について紹介した。今回は「クラスの利用」、次回は「クラスの定義」について説明する。※脚注や図、コードリストの番号は前回からの続き番号としている。
本連載は、実際にライブラリ「TensorFlow」でディープラーニングのコードを書く流れに沿って、具体的にはLesson 1で掲載した図1-a/b/c/dのサンプルコードの順で、基礎文法が学んでいけるように目次を構成している。これまでの連載中ですでにクラスに関するメソッドやコンストラクターなどの用語は登場しているとおり、クラスやメソッドはTensorFlowサンプルコードのあらゆる場面で使われている。そこで今回は、図1-a内の一部(図1-a【再掲】における赤枠内)に絞って、コードを取り上げる。
なお、本稿で示すサンプルコードの実行環境については、Lesson 1を一読してほしい。
Lesson 1でも示したように、本連載のすべてのサンプルコードは、下記のリンク先で実行もしくは参照できる。
これまでの連載内容だけでも、大半のPythonコードは読み書きできる。特に「本連載『機械学習&ディープラーニング入門』シリーズレベルのPythonコードを書く」という観点では、ここまでで十分なのだが、ライブラリ「TensorFlow」のチュートリアルドキュメントに含まれているコードを読む場合、もう一つだけ知っておかなければならない機能がある。それがクラス(class)である。そこで、最後にクラスの利用方法(や次回解説する定義方法)について簡単に説明しておこう。
実際にクラスを利用しているのがリスト14-1だ。これは、図1-aの中にあるコードである。
#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
# 以下のコードを動かすためには、上記4行を事前に実行しておく必要がある
#---------------------------------------------------------------------
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.までがモジュールの階層(=名前空間:namespaceと表現される場合もある)で、Sequentialがクラスである。クラス名の後には()があり、Lesson 7で説明した「関数」と同じ書き方になっている。Pythonではクラスは「呼び出し可能型」なオブジェクトであり、()内にインスタンスの生成に必要な引数を与えることで関数のように呼び出せる(多くのプログラミング言語でコンストラクターと呼ばれる機能と同様なもの)。この形式で呼び出しを行うと、最終的にはそのクラス内部で__init__(self, <引数>……)という特殊な名前で定義されている関数(メソッド)が呼び出される。このときには、「クラス名(引数)」として渡した引数がその__init__関数に渡されて、それらを使ってインスタンスの初期化が行われる。「init」は「初期化(initialize)」の意味で、つまりコンストラクターとはインスタンスを初期状態にするためのものである。
コードを見ると、Sequentialクラスのコンストラクターの引数には、角括弧[〜]により生成された(4つの値を持つ)リスト値が渡されている。ちなみに、リスト値内に含まれる4つの値は、それぞれFlatten/Dense/Dropout関数の戻り値である*8。コンストラクターが呼び出されると、内部で初期化処理が実行され、その戻り値としてSequentialクラスのインスタンス(=実体)が変数modelに代入されている(※なお、コンストラクターの定義自体にはretrun文による戻り値の実装はない。あくまでクラスインスタンス生成の記法が、あたかも関数のように書けるというだけである)。
*8 tf.keras.layers.モジュール階層に含まれるFlatten()/Dense()/Dropout()関数もまた、実際にはクラスのコンストラクターであり、つまり、Flatten/Dense/Dropoutクラスのインスタンス(=実体)がここでは生成され、リスト値の4つの値として使われている。これらの各クラスの意味は、言語仕様とは無関係なので、説明を割愛する。
というのもクラスは、実体のない「設計図」でしかない。クラスのコンストラクターを呼び出すことで初めて、その「設計図」に記されたとおりに何らかの処理を実行する、いわば「クラスの実体」(これが先ほどから何度か出てきた「インスタンス」と呼ばれるものだ)が得られるのだ。例えて言うなら、クラスは「車の設計図」のようなもので、インスタンスは設計図を基に製作した「車の実体」のようなものである(図15-1)。車のユーザーは、車のタンクにガソリンを入れて、走らせる。その「ガソリン」に相当するものが「データ」で、ガソリンを入れる「タンク」に相当するものが「インスタンス変数」(=クラスの実体の中にある変数のこと)、実際に「走る」ことに相当するのが「インスタンスメソッド」(=クラスの実体の中にある関数のこと)である。ちなみにインスタンス変数は、クラスの属性と呼ばれる場合もある。
リスト14-1に続くコードは、リスト14-2のようになっている。変数modelの中(.)のcompile関数やfit関数、evaluate関数が呼び出されているが、これらがインスタンスメソッドである(先ほどの車の例なら「走る」ことに相当する処理を行っている)。
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)
インスタンスメソッドは、通常、単にメソッドと呼ぶことの方が多い。これまでの説明どおり、メソッドは、クラス版の関数である。関数とほぼ同じ機能を持つので、(Lesson 8で説明した)デフォルト引数やキーワード引数なども使える。構文や使い方は、関数と変わらないので、本連載で学んだことがそのまま生かせる。
インスタンス変数やインスタンスメソッド、属性などが、クラスに含まれているわけだが、これらをクラスメンバーと呼ぶ。応用して、メンバー変数やメンバー関数と呼ばれる場合もある。
以上、「クラスの利用方法」を説明した。いよいよ次回、基本文法については本当に最後となる「クラスの定義」を説明する。
Copyright© Digital Advantage Corp. All Rights Reserved.