Sandwood は、JVM ベースの確率モデルの言語、コンパイラ、およびランタイムです。 Java 開発者にとって使い慣れた言語でモデルを記述できるように設計されています。結果として得られるモデルは Java オブジェクトの形式をとり、包括的なシステムの適切に抽象化されたコンポーネントにすることができます。
従来のベイジアン モデルでは、ユーザーはモデルを設計し、そのモデル上で実行したい操作のための推論コードを実装する必要があります。これにより、次のような多くの問題が発生します。
推論コードの構築は技術的に難しく、時間がかかります。このステップでは、微妙なバグが発生する可能性があります。
モデルが変更された場合は、推論コードを更新する必要があります。これには時間がかかり、技術的にも困難なため、次の問題が発生します。
モデルの変更に対する抑止力として機能します。
さまざまな推論操作が歩調を合わせられなくなる可能性があるため、一部は古いモデルで動作し、一部は新しいモデルで動作します。
ユーザーが既存のコードに微妙な調整を加えようとすると、推論アルゴリズムにバグが入り込む新たな機会が生じます。
確率的プログラミングは、Sandwood の場合のように、API またはドメイン固有言語 (DSL) のいずれかを使用してモデルを記述できるようにすることで、これらの問題を克服します。 Sandwood DSL は、モデルを表し、必要なすべての推論操作を実装する Java クラスを生成するためにコンパイルされます。これには次のような多くの利点があります。
Sandwood は、それぞれ対応するディレクトリにある 3 つのコンポーネントで構成されます。
各部分は前の部分に依存しています。各コンポーネント ディレクトリには、コンポーネントを構築するための Maven POM ファイルが含まれています。コンパイラーとプラグインの場合、後の段階で使用できるようにするには、 install
でこれらを呼び出す必要があります (つまり、 mvn clean install
。サンプルはmvn clean package
としてのみビルドする必要があります。
Sandwood をインストールした後、モデルをコンパイルするには現在 3 つの方法があります。
コンパイラとランタイムが構築された後でコマンド ラインから Sandwood を使用するには、 javac
と同様の機能を持つコマンド ライン スクリプトがcommandline/SandwoodC/bin
にあります。これを使用するには、通常、ユーザーは bin ディレクトリをパスに追加し、sandwoodc.sh HMM.sandwood を呼び出して HMM モデルをコンパイルします。 sandwoodc.sh -h
またはsandwoodc.bat -h
実行すると、使用方法と使用可能なオプションの説明が出力されます。
SandwoodC のすべての機能は、 org.sandwood.compilation.SandwoodC
でメソッドcompile
を呼び出し、コマンド ラインに渡される引数を含む配列を渡すことでアクセスできます。
Maven プラグインを使用すると、依存プロジェクトのビルド時に Sandwood ファイルのコンパイルを自動的にトリガーできます。このプラグインを使用するには、Sandwood ランタイムを依存関係として追加し、プラグインをビルドに追加する必要があります。これは、POM ファイルに次の追加を行うことで実現されます。
<dependencies>
<dependency>
<groupId>org.sandwood</groupId>
<artifactId>sandwood-runtime</artifactId>
<version>0.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.sandwood</groupId>
<artifactId>sandwoodc-maven-plugin</artifactId>
<version>0.3-SNAPSHOT</version>
<executions>
<execution>
<configuration>
<partialInferenceWarning>true</partialInferenceWarning>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
</configuration>
<goals>
<goal>sandwoodc</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>`
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
要素を含めることで、モデルを検索するディレクトリをプラグインに指示します。その他の便利なフラグは次のとおりです。
debug
このオプションは、SandwoodC からデバッグ情報を取得するために使用されます。このオプションをtrue
に設定すると、Sandwood はそのアクションのトレースを生成します。デフォルト値はfalse
です。このフラグは、コンパイル中のモデルではなく、コンパイラ構成/コンパイラに関するエラーをデバッグするためのものであることに注意してください。 Sandwood モデル ファイル内のエラーと警告は、コンパイラによって常に返されます。
partialInferenceWarning
このオプションは、一部の推論ステップを構築できない場合に SandwoodC が失敗するのを防ぐために使用されます。このオプションをtrue
に設定すると、Sandwood は欠落しているステップについてのみ警告を生成します。デフォルト値はfalse
です。
sourceDirectory
このパラメータは、モデル ファイルを検索するディレクトリを設定します。このディレクトリ内では、モデルをさまざまなパッケージに配置できます。
outputDirectory
このパラメータは、モデルの Java ソース コードを配置するディレクトリを設定します。デフォルト値は${project.build.directory}/generated-sources/sandwood
です。
calculateIndividualProbabilities
このパラメータは、ループ内で構築される各確率変数の確率を、すべてのインスタンスの単一の値ではなく計算するかどうかを指定します。デフォルト値はfalse
です。
javadoc
このパラメータは、モデルを補完する JavaDoc を生成するようにコンパイラに指示します。デフォルト値はfalse
です。
javadocDirectory
このパラメータは、生成されたファイルを配置する場所を指定します。
executable
このパラメータを使用すると、Sandwood コンパイラを実行するための代替 JVM を指定できます。
以下に、Sandwood モデルの作成方法と、そのモデルを実装する結果のクラスの使用方法を紹介します。
モデルが実行するステップの概要を次の図に示します。モデルは、一連のクラス ファイルにコンパイルされる.sandwood
ファイルとして開始されます。これらは複数回インスタンス化して、異なる構成を持つモデルの複数のインスタンスを生成できます。
実行例として、隠れマルコフ モデル (HMM) を使用します。このモデルはここでは Sandwood で書かれています。このモデルは、パッケージ ディレクトリorg/sandwood/examples/hmm
内のHMM.sandwood
というファイルに保存する必要があります。この言語の詳しい説明はここでご覧いただけます。
package org . sandwood . examples . hmm ;
model HMM ( int [] eventsMeasured , int numStates , int numEvents ) {
//Construct a transition matrix m.
double [] v = new double [ numStates ] <~ 0.1 ;
double [][] m = dirichlet ( v ). sample ( numStates );
//Construct weighting for which state to start in.
double [] initialState = new Dirichlet ( v ). sample ();
//Construct weighting for each event in each state.
double [] w = new double [ numEvents ] <~ 0.1 ;
double [][] bias = dirichlet ( w ). sample ( numStates );
//Allocate space to record the sequence of states.
int sequenceLength = eventsMeasured . length ;
int [] st = new int [ sequenceLength ];
//Calculate the movements between states.
st [ 0 ] = categorical ( initialState ). sampleDistribution ();
for ( int i : [ 1. . sequenceLength ) )
st [ i ] = categorical ( m [ st [ i - 1 ]]). sampleDistribution ();
//Emit the events for each state.
int [] events = new int [ sequenceLength ];
for ( int j = 0 ; j < sequenceLength ; j ++)
events [ j ] = new Categorical ( bias [ st [ j ]]). sample ();
//Assert that the events match the eventsMeasured data.
events . observe ( eventsMeasured );
}
Sandwood 言語のドキュメントとモデルに対して生成できる JavaDoc コメントに加えて、Sandwood Examples ディレクトリには多数の例があり、新しいユーザーはこれらを調べて変更することから始めることをお勧めします。
Sandwood モデルの記述に使用される言語の説明は、ここにあります。この言語は、Java 開発者にとって馴染みやすいものとなるように構築されていますが、オブジェクトを構築する機能は含まれていません。将来的には、モデルへのデータのインポートとモデルからのデータのエクスポートを簡単にするために、レコード タイプのサポートを追加する予定です。
モデルがコンパイルされると、モデルが定義されているのと同じパッケージ内に多数のクラス ファイルが生成されます。これらのクラスの 1 つは、モデルに指定された名前と同じ名前になります。つまり、この場合はHMM.class 、そして thisモデルのインスタンスを取得するためにユーザーがインスタンス化する必要があるクラスです。モデル内で公開されている各変数は、生成されたクラス内のフィールドに対応します。 HMM の例を以下に示します。
javadoc
フラグを設定してコンパイラを実行すると、生成されたモデル ファイル内のパブリック メソッドおよびクラスごとに JavaDoc が作成されます。
モデルがコンパイルされたら、そのインスタンスをインスタンス化する必要があります。これらのインスタンスは独立しているため、ユーザーはモデルの異なるコピーを必要なだけ作成できます。
モデル オブジェクトのインスタンスは、クラス コンストラクターを介して構築されます。前述したように、モデルには通常 3 つのコンストラクターがあります。コンストラクターの数が少なくなる唯一のケースは、コンストラクターのさまざまなバリアントが同じシグネチャにマップされる場合です。この場合、1 つのコンストラクターがこれらのシナリオの複数に適用されます。
完全なコンストラクター - このコンストラクターは、モデル署名に現れるすべての引数を受け取り、それらを設定します。このコンストラクターは、値の推論と確率の推論操作に使用されます。
空のコンストラクター - このコンストラクターは引数をとらず、ユーザーが後で設定できるパラメーターを残します。
実行コンストラクター - このコンストラクターは、監視されるだけの引数を削除し、ディメンションがコードへの入力として使用される監視される引数については、完全なパラメーターの代わりにそれらのディメンションを取得します。したがって、HMM の例では、eventsMeasured パラメーターはシーケンスの長さを表す整数になります。
これらのコード サンプルは、コンパイルされたモデルを呼び出す方法を示しています。
モデル オブジェクトを介したモデルとの対話には、次の 2 つの形式があります。
デフォルトの保持ポリシーの設定、モデルが推論の準備ができているかどうかの確認、推論ステップの開始などのグローバル操作のためのモデル オブジェクト メソッドの呼び出し。
モデルパラメータオブジェクトの呼び出し。モデル内の名前付きパブリック変数はそれぞれ、モデル オブジェクト内の対応するフィールドによって表されます。変数は、モデルの最も外側のスコープで宣言されていてprivate
ラベルが付けられていない場合、または内部スコープで宣言されていてpublic
ラベルが付けられていない場合に public になります。フィールドが内部反復スコープ (for ループの本体など) で public に宣言されている場合、各反復の値が保管されます。
オブジェクトのタイプは変数によって異なります。これらは 3 つのカテゴリに分類できます。
これらの各フィールドは、ユーザーがパラメータの値とプロパティを設定および読み取ることを可能にする一連のメソッドを備えたオブジェクトを参照します。設定および読み取りできるプロパティには、パラメータの確率、パラメータの保持ポリシー、パラメータを現在の値に固定する必要があるかどうかなどが含まれます。
モデル推論を実行する際のパラメーター オブジェクトのより重要なメソッドには、次のようなものがあります。
getSamples はサンプリングされた値を返します。
getMAP を使用して事後最大値を返します。
setValue を使用すると、値を特定の値に設定できるようになります。
setFixed は、値を固定としてマークするためのboolean
を受け取り、推論中に更新されません。パラメータを修正する前に、パラメータの値を設定することが重要です。
getLogProbability は、確率を推論した後、変数の対数確率を取得します。
他にもメソッドがあるため、JavaDoc を参照してよく理解しておくことをお勧めします。
モデルに対して実行できる操作には、次の 3 つの基本的なタイプがあります。
setRentionPolicy
メソッドを呼び出すことによって、モデル全体に設定できます。オプションで、各変数オブジェクトの対応するsetRetentionPolicy
メソッドを呼び出すことによって、個々の変数に保持ポリシーを設定できます。サンプリング ポリシーは 3 つあります。
NONE は値を記録しません。これは、変数の 1 つが大きく、それを保存するのに時間とスペースがかかる場合に特に便利です。
SAMPLE は、推論アルゴリズムのすべての反復からの値を記録するため、1000 回の反復が実行されると、この保持ポリシーに設定された各変数から 1000 個の値がサンプリングされます。これは、平均値だけでなく分散を計算するのにも役立ちます。ただし、これには弱点があり、モデル内の値の位置が推論中に移動する可能性がある場合、値の平均を取得できません。たとえば、トピック モデルの場合、推論中にトピック 2 と 3 の位置が入れ替わる可能性があるため、トピック 2 のすべての値を平均すると、トピック 2 とトピック 3 の混合が生成されます。これを克服するために、最大事後確率 (MAP) も提供されます。保持ポリシー。
MAPまたは最大事後確率 (MAP) は、モデルが最も確率の高い状態にあるときの変数の値を記録します。これにより、値の平均化ができないという一時的な値の位置の問題が解決されますが、境界の計算が可能になります。一部の変数が大きい場合、このオプションにはスペースの利点もあります。
構成: モデル オブジェクトに対する追加のメソッド呼び出しにより、ユーザーはこの推論ステップを実行するときにバーニンやシンニングなどのプロパティを設定できます。 Burnin は最初のn回の反復の値を無視し、サンプリングを開始する前にモデルが確率の低い開始点から離れることを可能にします。間引きにより、 n回ごとの反復からの値のみを考慮することで、MCMC 手順によって引き起こされる自己相関が減少します。
確率の推論モデル内の一部またはすべてのパラメーターの値を設定すると、それらの値を生成する確率が計算されます。これは、モデル内の各変数に対しても、モデル全体に対しても計算できます。
モデルの実行ユーザーが固定していないパラメータに対して新しい値を生成する通常のコードであるかのようにモデルを実行します。この動作が使用される例は、線形回帰モデルです。この場合、モデル係数はまずトレーニング データを使用して推測されます。それらが推論されると、それらは修正され、新しい入力データ セットになります。次に、モデルが実行されて、この新しい入力データに対応する予測が生成されます。この実行形式は、トレーニングされたモデルから代表的な合成データを生成するために使用することもできます。
モデルの構築とトレーニング
//Load inputs
int nStates = 25 ;
int [] actions = loadActions (....);
int nActions = maxActions (....);
//Construct the model
HMM model = new HMM ( actions , nActions , nStates );
//Set the retention policies
model . setDefaultRetentionPolicy ( RetentionPolicy . MAP );
model . st . setRetentionPolicy ( RetentionPolicy . NONE );
//Pick a random number generator. The ones introduced in Java 17 are faster and better quality.
model . setRNGType ( RandomType . L64X1024MixRandom );
//Instruct the model to use the ForkJoin framework for parallel execution.
model . setExecutionTarget ( ExecutionTarget . forkJoin );
//Run 2000 inference steps to infer model values
model . inferValues ( 2000 );
//Gather the results.
double [] initialState = model . initialState . getMAP ();
double [][] bias = model . bias . getMAP ();
double [][] transitions = model . m . getMAP ();
モデルを構築して確率を推測する
//Load inputs
int nStates = 25 ;
int [] actions = loadActions (....);
int nActions = maxActions (....);
//Load model parameters
double [][] bias = model . bias . getMAP ();
double [][] transitions = model . m . getMAP ();
//Construct the model
HMM model = new HMM ( actions , nActions , nStates );
//Set and fix trained values
model . bias . setValue ( bias );
Model . m . setValue ( transitions );
//Run 2000 inference steps to infer probabilities
model . inferProbabilities ( 2000 );
//Recover the probabilities of the model parameter actions.
double actionsProbability = model . actions . getProbability ();
//Recover the probability of the model as a whole
double modelProbability = model . getProbability ()
Sandwood に関するサポートが必要な場合は、ディスカッション ページでディスカッションを開始するか、ディスカッションに参加してください。
このプロジェクトはコミュニティからの貢献を歓迎します。プル リクエストを送信する前に、コントリビュート ガイドを確認してください。
当社の責任あるセキュリティ脆弱性開示プロセスについては、セキュリティ ガイドを参照してください。
Copyright (c) 2019-2024 Oracle および/またはその関連会社。
https://oss.oracle.com/licenses/upl/ に示されているように、Universal Permissive License v1.0 に基づいてリリースされています。