Theano-クイックガイド
Pythonで機械学習モデルを開発しましたか?次に、明らかに、これらのモデルの開発の複雑さを知っています。開発は通常、数時間と数日の計算能力を必要とする遅いプロセスです。
機械学習モデルの開発には、多くの数学的計算が必要です。これらは一般に算術計算、特に多次元の大きな行列を必要とします。最近では、機械学習アプリケーションの開発に従来の統計手法ではなくニューラルネットワークを使用しています。ニューラルネットワークは、膨大な量のデータについてトレーニングする必要があります。トレーニングは、妥当なサイズのデータのバッチで行われます。したがって、学習プロセスは反復的です。したがって、計算が効率的に行われない場合、ネットワークのトレーニングには数時間または数日かかる場合があります。したがって、実行可能コードの最適化が強く望まれます。そしてそれはまさにTheanoが提供するものです。
Theanoは、機械学習で使用される数式を定義し、これらの数式を最適化し、重要な領域でGPUを決定的に使用することにより、それらを非常に効率的に評価できるPythonライブラリです。ほとんどの場合、典型的な完全なC実装に匹敵する可能性があります。
Theanoは、効率的な機械学習アルゴリズムの迅速な開発を提供することを目的として、LISAラボで作成されました。BSDライセンスでリリースされています。
このチュートリアルでは、Theanoライブラリの使用方法を学習します。
Theanoは、Windows、MacOS、およびLinuxにインストールできます。すべての場合のインストールは簡単です。Theanoをインストールする前に、その依存関係をインストールする必要があります。以下は依存関係のリストです-
- Python
- NumPy-必須
- SciPy-スパース行列と特殊関数にのみ必要
- BLAS-基本的なベクトルおよび行列演算を実行するための標準的な構成要素を提供します
ニーズに応じてインストールすることを選択できるオプションのパッケージは次のとおりです。
- 鼻:Theanoのテストスイートを実行するには
- Sphinx-ドキュメントの作成用
- Graphizとpydot-グラフィックと画像を処理する
- NVIDIACUDAドライバー-GPUコードの生成/実行に必要
- libgpuarray-CUDAおよびOpenCLデバイスでのGPU / CPUコード生成に必要
MacOSにTheanoをインストールする手順について説明します。
MacOSのインストール
Theanoとその依存関係をインストールするには、 pip次のようにコマンドラインから。これらは、このチュートリアルで必要となる最小限の依存関係です。
$ pip install Theano
$ pip install numpy
$ pip install scipy
$ pip install pydot
また、次のコマンドを使用してOSxコマンドライン開発者ツールをインストールする必要があります-
$ xcode-select --install
次の画面が表示されます。クリックしてくださいInstall ツールをインストールするためのボタン。
インストールが成功すると、コンソールに成功メッセージが表示されます。
インストールのテスト
インストールが正常に完了したら、AnacondaJupyterで新しいノートブックを開きます。コードセルに、次のPythonスクリプトを入力します-
例
import theano
from theano import tensor
a = tensor.dscalar()
b = tensor.dscalar()
c = a + b
f = theano.function([a,b], c)
d = f(1.5, 2.5)
print (d)
出力
スクリプトを実行すると、次の出力が表示されます-
4.0
クイックリファレンスとして、実行のスクリーンショットを以下に示します-
上記の出力が得られれば、Theanoのインストールは成功しています。そうでない場合は、Theanoダウンロードページのデバッグ手順に従って問題を修正してください。
テアーノとは?
Theanoのインストールに成功したので、まずTheanoとは何かを理解してみましょう。TheanoはPythonライブラリです。これにより、数式、特に機械学習モデルの開発で使用される数式を定義、最適化、および評価できます。Theano自体には、事前定義されたMLモデルは含まれていません。それは単にその開発を容易にします。これは、多次元配列を扱うときに特に役立ちます。これは、Pythonの科学計算に広く使用されている基本的なパッケージであるNumPyとシームレスに統合されます。
Theanoは、ML開発で使用される数式の定義を容易にします。このような表現には、通常、行列の算術、微分、勾配計算などが含まれます。
Theanoはまず、モデルの計算グラフ全体を作成します。次に、グラフにいくつかの最適化手法を適用することにより、それを非常に効率的なコードにコンパイルします。コンパイルされたコードは、と呼ばれる特別な操作によってTheanoランタイムに挿入されます。functionTheanoで利用できます。これを実行しますfunctionニューラルネットワークをトレーニングするために繰り返し。純粋なPythonコーディングや完全なC実装を使用する場合と比較して、トレーニング時間は大幅に短縮されます。
ここで、Theano開発のプロセスを理解します。Theanoで数式を定義する方法から始めましょう。
Theanoでの些細な表現を定義して評価することから、Theanoの旅を始めましょう。2つのスカラーを追加する次の自明な式を考えてみましょう-
c = a + b
どこ a、 b 変数であり c式の出力です。Theanoでは、この些細な表現でさえ定義して評価するのは難しいです。
上記の式を評価する手順を理解しましょう。
Theanoのインポート
まず、プログラムにTheanoライブラリをインポートする必要があります。これは、次のステートメントを使用して行います。
from theano import *
個々のパッケージをインポートするのではなく、上記のステートメントで*を使用して、Theanoライブラリからすべてのパッケージを含めました。
変数の宣言
次に、という変数を宣言します a 次のステートメントを使用する-
a = tensor.dscalar()
ザ・ dscalarメソッドは、10進スカラー変数を宣言します。上記のステートメントを実行すると、という変数が作成されます。aプログラムコードで。同様に、変数を作成しますb 次のステートメントを使用する-
b = tensor.dscalar()
式の定義
次に、これら2つの変数を操作する式を定義します a そして b。
c = a + b
Theanoでは、上記のステートメントを実行しても、2つの変数のスカラー加算は実行されません。 a そして b。
Theano関数の定義
上記の式を評価するには、Theanoで次のように関数を定義する必要があります。
f = theano.function([a,b], c)
関数 function2つの引数を取ります。最初の引数は関数への入力であり、2番目の引数はその出力です。上記の宣言は、最初の引数が2つの要素で構成される配列型であることを示していますa そして b。出力はと呼ばれるスカラー単位ですc。この関数は変数名で参照されますf 私たちのさらなるコードで。
Theano関数の呼び出し
関数fの呼び出しは、次のステートメントを使用して行われます。
d = f(3.5, 5.5)
関数への入力は、2つのスカラーで構成される配列です。 3.5 そして 5.5。実行の出力はスカラー変数に割り当てられますd。の内容を印刷するにはd、使用します print ステートメント-
print (d)
実行すると、 d コンソールに印刷されます。この場合は9.0です。
完全なプログラムリスト
完全なプログラムリストは、クイックリファレンスとしてここにあります-
from theano import *
a = tensor.dscalar()
b = tensor.dscalar()
c = a + b
f = theano.function([a,b], c)
d = f(3.5, 5.5)
print (d)
上記のコードを実行すると、出力は9.0として表示されます。スクリーンショットはここに示されています-
ここで、2つの行列の乗算を計算するもう少し複雑な例について説明します。
2つの行列の内積を計算します。最初の行列は次元2x 3で、2番目の行列は次元3 x2です。入力として使用した行列とその積は次のように表されます。
$$ \ begin {bmatrix} 0&-1&2 \\ 4&11&2 \ end {bmatrix} \:\ begin {bmatrix} 3&-1 \\ 1&2 \\ 35&20 \ end {bmatrix} = \ begin {bmatrix} 11&0 \\ 35&20 \ end {bmatrix} $$変数の宣言
上記のTheano式を書くために、最初に次のように行列を表す2つの変数を宣言します。
a = tensor.dmatrix()
b = tensor.dmatrix()
dmatrixは、doubleの行列のタイプです。マトリックスサイズはどこにも指定しないことに注意してください。したがって、これらの変数は任意の次元の行列を表すことができます。
式の定義
内積を計算するために、と呼ばれる組み込み関数を使用しました dot 次のように-
c = tensor.dot(a,b)
乗算の出力は、と呼ばれる行列変数に割り当てられます。 c。
Theano関数の定義
次に、前の例のように関数を定義して、式を評価します。
f = theano.function([a,b], c)
関数への入力は、行列タイプの2つの変数aとbであることに注意してください。関数出力は変数に割り当てられますc これは自動的にマトリックスタイプになります。
Theano関数の呼び出し
次のステートメントを使用して関数を呼び出します-
d = f([[0, -1, 2], [4, 11, 2]], [[3, -1],[1,2], [6,1]])
上記のステートメントの2つの変数は、NumPy配列です。ここに示すように、NumPy配列を明示的に定義できます-
f(numpy.array([[0, -1, 2], [4, 11, 2]]),
numpy.array([[3, -1],[1,2], [6,1]]))
後 d 計算され、その値を出力します-
print (d)
出力に次の出力が表示されます-
[[11. 0.]
[25. 20.]]
完全なプログラムリスト
The complete program listing is given here:
from theano import *
a = tensor.dmatrix()
b = tensor.dmatrix()
c = tensor.dot(a,b)
f = theano.function([a,b], c)
d = f([[0, -1, 2],[4, 11, 2]], [[3, -1],[1,2],[6,1]])
print (d)
プログラム実行のスクリーンショットをここに示します-
上記の2つの例から、Theanoで式を作成し、最終的にTheanoを使用して評価されることに気付いたかもしれません。 function。Theanoは、高度な最適化手法を使用して、式の実行を最適化します。計算グラフを視覚化するために、Theanoはprinting ライブラリ内のパッケージ。
スカラー加算のシンボリックグラフ
スカラー加算プログラムの計算グラフを表示するには、次のように印刷ライブラリを使用します。
theano.printing.pydotprint(f, outfile="scalar_addition.png", var_with_name_simple=True)
このステートメントを実行すると、 scalar_addition.pngマシン上に作成されます。保存された計算グラフは、クイックリファレンスとしてここに表示されます-
上記の画像を生成するための完全なプログラムリストを以下に示します-
from theano import *
a = tensor.dscalar()
b = tensor.dscalar()
c = a + b
f = theano.function([a,b], c)
theano.printing.pydotprint(f, outfile="scalar_addition.png", var_with_name_simple=True)
行列乗数のシンボリックグラフ
ここで、行列乗数の計算グラフを作成してみてください。このグラフを生成するための完全なリストを以下に示します-
from theano import *
a = tensor.dmatrix()
b = tensor.dmatrix()
c = tensor.dot(a,b)
f = theano.function([a,b], c)
theano.printing.pydotprint(f, outfile="matrix_dot_product.png", var_with_name_simple=True)
生成されたグラフをここに示します-
複雑なグラフ
より大きな式では、計算グラフは非常に複雑になる可能性があります。Theanoのドキュメントから取られたそのようなグラフの1つをここに示します-
Theanoの動作を理解するには、最初にこれらの計算グラフの重要性を知ることが重要です。この理解により、Theanoの重要性を知ることができます。
なぜTheano?
計算グラフの複雑さを見ると、Theanoの開発の背後にある目的を理解できるようになります。一般的なコンパイラは、計算全体を単一のユニットと見なすことはないため、プログラムでローカル最適化を提供します。
Theanoは、完全な計算グラフを最適化するために非常に高度な最適化手法を実装しています。これは、代数の側面と最適化コンパイラの側面を組み合わせたものです。グラフの一部はC言語コードにコンパイルされる場合があります。繰り返し計算する場合、評価速度は重要であり、Theanoは非常に効率的なコードを生成することでこの目的を満たします。
これで、Theanoの基本を理解したので、式を作成するために使用できるさまざまなデータ型から始めましょう。次の表に、Theanoで定義されているデータ型の部分的なリストを示します。
データ・タイプ | テアノタイプ |
---|---|
バイト | bscalar、bvector、bmatrix、brow、bcol、btensor3、btensor4、btensor5、btensor6、btensor7 |
16ビット整数 | wscalar、wvector、wmatrix、wrow、wcol、wtensor3、wtensor4、wtensor5、wtensor6、wtensor7 |
32ビット整数 | iscalar、ivector、imatrix、irow、icol、itensr3、itensor4、itens5、itens6、itensr7 |
64ビット整数 | lscalar、lvector、lmatrix、lrow、lcol、ltensor3、ltensor4、ltensor5、ltensor6、ltensor7 |
浮く | fscalar、fvector、fmatrix、frow、fcol、ftensor3、ftensor4、ftensor5、ftensor6、ftensor7 |
ダブル | dscalar、dvector、dmatrix、drow、dcol、dtensor3、dtensor4、dtensor5、dtensor6、dtensor7 |
繁雑 | cscalar、cvector、cmatrix、crow、ccol、ctensor3、ctensor4、ctensor5、ctensor6、ctensor7 |
上記のリストは網羅的なものではなく、完全なリストについては、テンソル作成ドキュメントを参照してください。
次に、Theanoでさまざまな種類のデータの変数を作成する方法の例をいくつか示します。
スカラー
スカラー変数を作成するには、構文-を使用します。
構文
x = theano.tensor.scalar ('x')
x = 5.0
print (x)
出力
5.0
一次元配列
1次元配列を作成するには、次の宣言を使用します-
例
f = theano.tensor.vector
f = (2.0, 5.0, 3.0)
print (f)f = theano.tensor.vector
f = (2.0, 5.0, 3.0)
print (f)
print (f[0])
print (f[2])
出力
(2.0, 5.0, 3.0)
2.0
3.0
もしあなたがそうするなら f[3] ここに示すように、範囲外のインデックスエラーが生成されます-
print f([3])
出力
IndexError Traceback (most recent call last)
<ipython-input-13-2a9c2a643c3a> in <module>
4 print (f[0])
5 print (f[2])
----> 6 print (f[3])
IndexError: tuple index out of range
二次元配列
2次元配列を宣言するには、次のコードスニペットを使用します-
例
m = theano.tensor.matrix
m = ([2,3], [4,5], [2,4])
print (m[0])
print (m[1][0])
出力
[2, 3]
4
5次元配列
5次元配列を宣言するには、次の構文を使用します-
例
m5 = theano.tensor.tensor5
m5 = ([0,1,2,3,4], [5,6,7,8,9], [10,11,12,13,14])
print (m5[1])
print (m5[2][3])
出力
[5, 6, 7, 8, 9]
13
データ型を使用して3次元配列を宣言できます tensor3 代わりに tensor5、データ型を使用した4次元配列 tensor4、など tensor7。
複数のコンストラクター
場合によっては、1つの宣言で同じタイプの変数を作成したいことがあります。次の構文を使用してこれを行うことができます-
構文
from theano.tensor import * x, y, z = dmatrices('x', 'y', 'z')
x = ([1,2],[3,4],[5,6])
y = ([7,8],[9,10],[11,12])
z = ([13,14],[15,16],[17,18])
print (x[2])
print (y[1])
print (z[0])
出力
[5, 6]
[9, 10]
[13, 14]
前の章では、データ型について説明しながら、Theano変数を作成して使用しました。繰り返しになりますが、次の構文を使用してTheano −に変数を作成します。
x = theano.tensor.fvector('x')
このステートメントでは、変数を作成しました x32ビットfloatを含むタイプvectorの。また、名前を付けていますx。これらの名前は通常、デバッグに役立ちます。
32ビット整数のベクトルを宣言するには、次の構文を使用します-
i32 = theano.tensor.ivector
ここでは、変数の名前は指定しません。
64ビットのfloatで構成される3次元ベクトルを宣言するには、次の宣言を使用します。
f64 = theano.tensor.dtensor3
さまざまなタイプのコンストラクターとそのデータ型を以下の表に示します。
コンストラクタ | データ・タイプ | 寸法 |
---|---|---|
fvector | float32 | 1 |
ivector | int32 | 1 |
fscalar | float32 | 0 |
fmatrix | float32 | 2 |
ftensor3 | float32 | 3 |
dtensor3 | float64 | 3 |
汎用ベクトルコンストラクターを使用して、次のようにデータ型を明示的に指定できます。
x = theano.tensor.vector ('x', dtype=int32)
次の章では、共有変数を作成する方法を学習します。
多くの場合、異なる関数間および同じ関数への複数の呼び出し間で共有される変数を作成する必要があります。例を挙げると、ニューラルネットワークのトレーニング中に、検討中の各特徴に重みを割り当てるための重みベクトルを作成します。このベクトルは、ネットワークトレーニング中の反復ごとに変更されます。したがって、同じ関数への複数の呼び出しにわたってグローバルにアクセスできる必要があります。したがって、この目的のために共有変数を作成します。通常、Theanoは、使用可能な場合、そのような共有変数をGPUに移動します。これにより、計算が高速化されます。
構文
次の構文を使用して共有変数を作成します-
import numpy
W = theano.shared(numpy.asarray([0.1, 0.25, 0.15, 0.3]), 'W')
例
ここでは、4つの浮動小数点数で構成されるNumPy配列が作成されます。設定/取得するにはW 次のコードスニペットを使用する値-
import numpy
W = theano.shared(numpy.asarray([0.1, 0.25, 0.15, 0.3]), 'W')
print ("Original: ", W.get_value())
print ("Setting new values (0.5, 0.2, 0.4, 0.2)")
W.set_value([0.5, 0.2, 0.4, 0.2])
print ("After modifications:", W.get_value())
出力
Original: [0.1 0.25 0.15 0.3 ]
Setting new values (0.5, 0.2, 0.4, 0.2)
After modifications: [0.5 0.2 0.4 0.2]
テアノ functionシンボリックグラフと対話するためのフックのように機能します。シンボリックグラフは、非常に効率的な実行コードにコンパイルされます。これは、数式を再構築して高速化することで実現されます。式の一部をC言語コードにコンパイルします。いくつかのテンソルをGPUに移動します。
効率的なコンパイル済みコードがTheanoへの入力として提供されるようになりました function。Theanoを実行するときfunction、計算結果を指定された変数に割り当てます。最適化のタイプは、FAST_COMPILEまたはFAST_RUNとして指定できます。これは、環境変数THEANO_FLAGSで指定されます。
テアノ function 次の構文を使用して宣言されます-
f = theano.function ([x], y)
最初のパラメータ [x] 入力変数と2番目のパラメーターのリストです y 出力変数のリストです。
Theanoの基本を理解したので、簡単な例からTheanoコーディングを始めましょう。
Theanoは、最適化を達成するためにコストと勾配を繰り返し計算する必要があるニューラルネットワークのトレーニングに非常に役立ちます。大規模なデータセットでは、これは計算集約的になります。Theanoは、以前に見た計算グラフの内部最適化により、これを効率的に実行します。
問題文
次に、Theanoライブラリを使用してネットワークをトレーニングする方法を学習します。4つの特徴データセットから始める簡単なケースを取り上げます。各特徴に特定の重み(重要度)を適用した後、これらの特徴の合計を計算します。
トレーニングの目標は、合計が100の目標値に達するように、各機能に割り当てられた重みを変更することです。
sum = f1 * w1 + f2 * w2 + f3 * w3 + f4 * w4
どこ f1、 f2、...は機能値であり、 w1、 w2、...は重みです。
問題の説明をよりよく理解するために、例を量子化してみましょう。各機能の初期値を1.0と想定し、w1は次のようになります。0.1、 w2 等しい 0.25、 w3 等しい 0.15、および w4 等しい 0.3。重み値の割り当てに明確なロジックはありません。それは私たちの直感にすぎません。したがって、初期合計は次のようになります。
sum = 1.0 * 0.1 + 1.0 * 0.25 + 1.0 * 0.15 + 1.0 * 0.3
合計すると 0.8。ここで、この合計が100に近づくように、重みの割り当てを変更し続けます。0.8 目標値である100からはほど遠いです。機械学習の用語では、次のように定義します。 cost目標値から現在の出力値を引いた差として、通常はエラーを爆発させるために2乗されます。勾配を計算し、重みベクトルを更新することで、各反復でこのコストを削減します。
このロジック全体がTheanoでどのように実装されているかを見てみましょう。
変数の宣言
まず、入力ベクトルxを次のように宣言します。
x = tensor.fvector('x')
どこ x float値の1次元配列です。
スカラーを定義します target 以下に示す変数-
target = tensor.fscalar('target')
次に、重みテンソルを作成します W 上記の初期値で-
W = theano.shared(numpy.asarray([0.1, 0.25, 0.15, 0.3]), 'W')
Theano式の定義
ここで、次の式を使用して出力を計算します。
y = (x * W).sum()
上記のステートメントで注意してください x そして Wはベクトルであり、単純なスカラー変数ではありません。ここで、次の式を使用してエラー(コスト)を計算します。
cost = tensor.sqr(target - y)
コストは、目標値と現在の出力の差の2乗です。
ターゲットからの距離を示す勾配を計算するには、組み込みのを使用します grad 次のような方法-
gradients = tensor.grad(cost, [W])
更新します weights の学習率を取ることによるベクトル 0.1 次のように-
W_updated = W - (0.1 * gradients[0])
次に、上記の値を使用して重みベクトルを更新する必要があります。これは次のステートメントで行います-
updates = [(W, W_updated)]
Theano関数の定義/呼び出し
最後に、 function 合計を計算するためにTheanoで。
f = function([x, target], y, updates=updates)
上記の関数を特定の回数呼び出すために、 for 次のようにループします-
for i in range(10):
output = f([1.0, 1.0, 1.0, 1.0], 100.0)
前に述べたように、関数への入力は4つの特徴の初期値を含むベクトルです-の値を割り当てます 1.0特定の理由なしに各機能に。選択したさまざまな値を割り当てて、関数が最終的に収束するかどうかを確認できます。各反復で重みベクトルの値と対応する出力を出力します。以下のコードに示されています-
print ("iteration: ", i)
print ("Modified Weights: ", W.get_value())
print ("Output: ", output)
完全なプログラムリスト
完全なプログラムリストは、クイックリファレンスとしてここに複製されています-
from theano import *
import numpy
x = tensor.fvector('x')
target = tensor.fscalar('target')
W = theano.shared(numpy.asarray([0.1, 0.25, 0.15, 0.3]), 'W')
print ("Weights: ", W.get_value())
y = (x * W).sum()
cost = tensor.sqr(target - y)
gradients = tensor.grad(cost, [W])
W_updated = W - (0.1 * gradients[0])
updates = [(W, W_updated)]
f = function([x, target], y, updates=updates)
for i in range(10):
output = f([1.0, 1.0, 1.0, 1.0], 100.0)
print ("iteration: ", i)
print ("Modified Weights: ", W.get_value())
print ("Output: ", output)
プログラムを実行すると、次の出力が表示されます-
Weights: [0.1 0.25 0.15 0.3 ]
iteration: 0
Modified Weights: [19.94 20.09 19.99 20.14]
Output: 0.8
iteration: 1
Modified Weights: [23.908 24.058 23.958 24.108]
Output: 80.16000000000001
iteration: 2
Modified Weights: [24.7016 24.8516 24.7516 24.9016]
Output: 96.03200000000001
iteration: 3
Modified Weights: [24.86032 25.01032 24.91032 25.06032]
Output: 99.2064
iteration: 4
Modified Weights: [24.892064 25.042064 24.942064 25.092064]
Output: 99.84128
iteration: 5
Modified Weights: [24.8984128 25.0484128 24.9484128 25.0984128]
Output: 99.968256
iteration: 6
Modified Weights: [24.89968256 25.04968256 24.94968256 25.09968256]
Output: 99.9936512
iteration: 7
Modified Weights: [24.89993651 25.04993651 24.94993651 25.09993651]
Output: 99.99873024
iteration: 8
Modified Weights: [24.8999873 25.0499873 24.9499873 25.0999873]
Output: 99.99974604799999
iteration: 9
Modified Weights: [24.89999746 25.04999746 24.94999746 25.09999746]
Output: 99.99994920960002
4回の反復後、出力は次のようになります。 99.96 そして5回の反復の後、それは 99.99、これは私たちの望ましい目標に近い 100.0。
必要な精度に応じて、ネットワークは4〜5回の反復でトレーニングされていると安全に結論付けることができます。トレーニングが完了したら、重みベクトルを調べます。これは、5回の反復後に次の値を取ります-
iteration: 5
Modified Weights: [24.8984128 25.0484128 24.9484128 25.0984128]
これで、モデルを展開するためにネットワークでこれらの値を使用できます。
機械学習モデルの構築には、テンソルを含む集中的で反復的な計算が含まれます。これらには、集中的なコンピューティングリソースが必要です。通常のコンパイラはローカルレベルで最適化を提供するため、通常、高速実行コードは生成されません。
Theanoはまず、計算全体の計算グラフを作成します。計算の全体像はコンパイル中に単一の画像として利用できるため、コンパイル前にいくつかの最適化手法を適用できます。これはまさにTheanoが行うことです。計算グラフを再構築し、部分的にCに変換し、共有変数をGPUに移動するなどして、非常に高速な実行可能コードを生成します。コンパイルされたコードは、Theanoによって実行されますfunctionこれは、コンパイルされたコードをランタイムに挿入するためのフックとして機能します。Theanoはその資格を証明しており、学者と業界の両方で広く受け入れられています。