Sandwood adalah bahasa, kompiler, dan runtime untuk model probabilistik berbasis JVM. Hal ini dirancang untuk memungkinkan model ditulis dalam bahasa yang familiar bagi pengembang Java. Model yang dihasilkan mengambil bentuk objek Java yang memungkinkannya menjadi komponen yang diabstraksi dengan baik dari suatu sistem yang mencakup.
Dengan Model Bayesian tradisional, pengguna harus merancang model, dan kemudian mengimplementasikan kode inferensi untuk operasi apa pun yang ingin mereka lakukan pada model tersebut. Hal ini menimbulkan sejumlah masalah:
Membuat kode inferensi secara teknis sulit dilakukan dan memakan waktu. Langkah ini memberikan peluang munculnya bug halus.
Jika model diubah, maka kode inferensi harus diperbarui. Hal ini juga memakan waktu dan menantang secara teknis, sehingga menimbulkan masalah berikut:
Ini bertindak sebagai pencegah untuk memodifikasi model.
Ada kemungkinan operasi inferensi yang berbeda keluar dari langkah sehingga beberapa bekerja pada model lama dan beberapa bekerja pada model baru.
Hal ini memberikan peluang lain bagi bug untuk masuk ke algoritme inferensi saat pengguna mencoba melakukan penyesuaian halus pada kode yang ada.
Pemrograman probabilistik mengatasi masalah ini dengan memungkinkan model dideskripsikan menggunakan API, atau bahasa khusus domain (DSL) seperti halnya Sandwood. Sandwood DSL dikompilasi untuk menghasilkan kelas Java yang mewakili model dan mengimplementasikan semua operasi inferensi yang diperlukan. Ini memiliki sejumlah keuntungan:
Sandwood terdiri dari 3 komponen masing-masing dalam direktori yang sesuai:
Setiap bagian bergantung pada bagian sebelumnya. Setiap direktori komponen berisi file POM Maven untuk membuat komponen. Untuk kompiler dan plugin, ini perlu dipanggil dengan install
agar tersedia untuk tahap selanjutnya, yaitu mvn clean install
. Contohnya hanya boleh dibuat sebagai mvn clean package
.
Setelah menginstal Sandwood, saat ini ada 3 cara untuk mengkompilasi model:
Untuk menggunakan Sandwood dari baris perintah setelah kompiler dan runtime dibuat, skrip baris perintah yang memiliki fungsi serupa dengan javac
dapat ditemukan di commandline/SandwoodC/bin
. Untuk menggunakan ini, pengguna biasanya menambahkan direktori bin ke jalurnya, lalu memanggil sandwoodc.sh HMM.sandwood untuk mengkompilasi model HMM. sandwoodc.sh -h
atau sandwoodc.bat -h
akan menghasilkan deskripsi penggunaan dan opsi yang tersedia yang dicetak.
Semua fungsionalitas SandwoodC dapat dicapai dengan memanggil metode compile
di org.sandwood.compilation.SandwoodC
dan meneruskan array berisi argumen yang akan diteruskan ke baris perintah.
Plugin Maven dapat digunakan untuk secara otomatis memicu kompilasi file sandwood ketika proyek dependen dibuat. Untuk menggunakan plugin, Anda perlu menambahkan runtime sandwood sebagai dependensi, dan menambahkan plugin ke build. Hal ini dicapai dengan tambahan berikut pada file 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>`
Penyertaan elemen <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
menginstruksikan plugin direktori mana yang harus dicari modelnya. Tanda berguna lainnya meliputi:
debug
Opsi ini digunakan untuk memperoleh informasi debugging dari SandwoodC. Menyetel opsi ini ke true
menyebabkan Sandwood menghasilkan jejak tindakannya. Nilai defaultnya adalah false
. Perhatikan tanda ini untuk men-debug kesalahan dengan konfigurasi compiler/kompiler, bukan dengan model yang sedang dikompilasi. Kesalahan dan peringatan pada file model sandwood akan selalu dikembalikan oleh kompiler.
partialInferenceWarning
Opsi ini digunakan untuk menghentikan kegagalan SandwoodC ketika beberapa langkah inferensi tidak dapat dibuat. Menyetel opsi ini ke true
menyebabkan Sandwood hanya menghasilkan peringatan jika ada langkah yang terlewat. Nilai defaultnya adalah false
.
sourceDirectory
Parameter ini menetapkan direktori mana yang akan dicari file model. Di dalam direktori ini model dapat ditempatkan dalam paket yang berbeda.
outputDirectory
Parameter ini menetapkan direktori mana kode sumber Java untuk model harus ditempatkan. Nilai defaultnya adalah ${project.build.directory}/generated-sources/sandwood
.
calculateIndividualProbabilities
Parameter ini menentukan apakah probabilitas untuk setiap variabel acak yang dibangun dalam satu lingkaran harus dihitung, bukan nilai tunggal untuk semua contoh. Nilai defaultnya adalah false
.
javadoc
Parameter ini memerintahkan kompiler untuk menghasilkan JavaDoc untuk melengkapi model. Nilai defaultnya adalah false
.
javadocDirectory
Parameter ini menentukan lokasi penempatan yang dihasilkan.
executable
Parameter ini memungkinkan JVM alternatif ditentukan untuk menjalankan kompiler Sandwood.
Berikut ini adalah pengenalan cara menulis model Sandwood dan cara menggunakan kelas yang dihasilkan yang mengimplementasikan model tersebut.
Garis besar langkah-langkah yang dilalui suatu model dapat dilihat pada diagram ini. Model dimulai sebagai file .sandwood
yang dikompilasi menjadi sekumpulan file kelas. Ini dapat dibuat instance-nya beberapa kali untuk menghasilkan beberapa instance model dengan konfigurasi berbeda.
Sebagai contoh berjalan kita akan menggunakan Hidden Markov Model (HMM). Model ini ditulis di sini di Sandwood. Model ini harus disimpan dalam file bernama HMM.sandwood
di direktori paket org/sandwood/examples/hmm
. Deskripsi bahasa yang lebih lengkap dapat ditemukan di sini.
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 );
}
Selain dokumentasi bahasa Sandwood dan komentar JavaDoc yang dapat dihasilkan untuk suatu model, terdapat sejumlah contoh di direktori Contoh Sandwood dan kami menyarankan pengguna baru untuk memulai dengan memeriksa dan memodifikasinya.
Deskripsi bahasa yang digunakan untuk mendeskripsikan model Sandwood dapat ditemukan di sini. Bahasa ini dibuat dengan tujuan agar familier bagi pengembang Java, namun tidak mengandung kemampuan untuk membuat Objek. Kami berencana menambahkan dukungan untuk tipe rekaman di masa mendatang agar impor dan ekspor data ke dan dari model menjadi lebih sederhana.
Ketika sebuah model dikompilasi, sejumlah file kelas dihasilkan dalam paket yang sama dengan model yang didefinisikan. Salah satu kelas ini akan memiliki nama yang sama dengan nama yang diberikan kepada model, jadi dalam hal ini HMM.class , dan ini adalah kelas yang harus dibuat oleh pengguna untuk mendapatkan instance model. Setiap variabel yang terlihat secara publik dalam model berhubungan dengan bidang di kelas yang dihasilkan. Contoh HMM dapat dilihat dibawah ini.
Dengan menjalankan kompiler dengan set flag javadoc
, JavaDoc akan dibuat untuk setiap metode dan kelas publik dalam file model yang dihasilkan.
Setelah model dikompilasi, kita perlu membuat contoh contohnya. Contoh-contoh ini bersifat independen dan pengguna dapat membuat salinan model yang berbeda sebanyak yang mereka inginkan.
Contoh objek model dibangun melalui konstruktor kelas. Seperti dijelaskan sebelumnya, biasanya ada 3 konstruktor untuk model tersebut. Satu-satunya kasus ketika jumlahnya akan lebih sedikit adalah ketika varian berbeda dari konstruktor dipetakan ke tanda tangan yang sama, dalam hal ini satu konstruktor akan berlaku untuk lebih dari satu skenario ini.
Konstruktor penuh - Konstruktor ini mengambil semua argumen yang muncul di tanda tangan model dan menetapkannya. Konstruktor ini digunakan untuk menyimpulkan nilai dan menyimpulkan operasi probabilitas.
Konstruktor kosong - Konstruktor ini tidak memerlukan argumen, sehingga pengguna dapat mengatur parameternya nanti.
Konstruktor Eksekusi - Konstruktor ini menghapus argumen yang hanya diamati, dan untuk argumen yang diamati yang dimensinya digunakan sebagai masukan ke kode, mengambil dimensi tersebut alih-alih parameter penuh. Jadi dalam contoh HMM parameter eventsMeasured akan menjadi bilangan bulat yang menggambarkan panjang barisan.
Contoh kode ini menunjukkan cara melakukan panggilan ke model yang dikompilasi.
Interaksi dengan model melalui objek model mempunyai dua bentuk:
Panggilan untuk memodelkan metode objek untuk operasi global seperti menetapkan kebijakan penyimpanan default, memeriksa apakah model siap untuk inferensi, dan memulai langkah-langkah inferensi, dll.
Panggilan untuk memodelkan objek parameter. Setiap variabel publik yang diberi nama dalam model diwakili oleh bidang terkait di objek model. Variabel bersifat public jika dideklarasikan pada scope terluar model dan tidak diberi label private
, atau dideklarasikan pada scope dalam dan tidak diberi label public
. Jika suatu bidang dideklarasikan publik dalam lingkup iteratif bagian dalam, misalnya badan perulangan for, nilai dari setiap iterasi akan disimpan.
Jenis objek akan bergantung pada variabelnya. Ini dapat dibagi menjadi 3 kategori:
Masing-masing bidang ini mereferensikan objek dengan serangkaian metode yang memungkinkan pengguna menyetel dan membaca nilai dan properti dari parameter. Properti yang dapat diatur dan dibaca mencakup probabilitas parameter, kebijakan retensi parameter, dan apakah parameter harus ditetapkan pada nilainya saat ini.
Beberapa metode objek parameter yang lebih penting saat melakukan inferensi model adalah:
getSamples untuk mengembalikan nilai sampel.
getMAP untuk mengembalikan nilai Maksimum A Posteriori.
setValue untuk memungkinkan suatu nilai disetel ke nilai tertentu.
setFixed yang menggunakan boolean
untuk menandai nilai sebagai tetap, dan oleh karena itu tidak diperbarui selama inferensi. Penting untuk menetapkan nilai parameter sebelum memperbaikinya.
getLogProbability yang mendapatkan log probabilitas variabel setelah menyimpulkan probabilitas.
Ada lebih banyak metode, dan kami menyarankan Anda berkonsultasi dengan JavaDoc untuk membiasakan diri Anda dengannya.
Ada 3 tipe operasi dasar yang dapat dilakukan pada model:
setRentionPolicy
di kelas model. Secara opsional, kebijakan penyimpanan masing-masing variabel dapat ditetapkan melalui panggilan ke metode setRetentionPolicy
yang sesuai di setiap objek variabel.Ada 3 kebijakan pengambilan sampel:
NONE tidak mencatat nilai apa pun. Hal ini sangat berguna jika salah satu variabel berukuran besar sehingga menghabiskan waktu dan ruang untuk menyimpannya akan sia-sia.
SAMPLE mencatat nilai dari setiap iterasi algoritma inferensi, jadi jika 1000 iterasi dilakukan, 1000 nilai akan diambil sampelnya dari setiap variabel yang diatur ke kebijakan penyimpanan ini. Hal ini berguna untuk menghitung varians serta nilai rata-rata. Namun terdapat kelemahannya, jika posisi nilai dalam model dapat berpindah selama inferensi maka nilai tersebut tidak dapat dirata-ratakan. Misalnya dengan model topik, topik 2 dan 3 boleh bertukar tempat pada saat inferensi, sehingga rata-rata seluruh nilai topik 2 dengan menghasilkan campuran topik 2 dan topik 3. Untuk mengatasi hal tersebut, disediakan juga Maksimum A Posteriori (MAP) sebagai kebijakan retensi.
MAP atau Maximum A Posteriori (MAP) mencatat nilai variabel ketika model berada dalam kondisi yang paling memungkinkan. Hal ini mengatasi masalah posisi nilai sementara yang berarti nilai tidak dapat dirata-ratakan, namun mengorbankan kemampuan menghitung batasan. Opsi ini juga memiliki keunggulan ruang jika beberapa variabelnya besar.
Konfigurasi: Pemanggilan metode tambahan pada objek model memungkinkan pengguna menyetel properti seperti burnin dan penjarangan saat melakukan langkah inferensi ini. Burnin mengabaikan nilai dari n iterasi pertama yang memungkinkan model menjauh dari titik awal dengan probabilitas rendah sebelum mulai mengambil sampel. Penipisan mengurangi autokorelasi yang disebabkan oleh prosedur MCMC dengan hanya mempertimbangkan nilai dari setiap iterasi ke- n .
Menyimpulkan Probabilitas Setelah menetapkan nilai dari beberapa atau semua parameter dalam model, hitung probabilitas untuk menghasilkan nilai-nilai tersebut. Hal ini dapat dihitung untuk setiap variabel dalam model dan model secara keseluruhan.
Jalankan Model Jalankan model seolah-olah itu adalah kode biasa yang menghasilkan nilai baru untuk parameter apa pun yang tidak ditetapkan oleh pengguna. Contoh kapan perilaku ini akan digunakan adalah untuk model regresi linier. Dalam hal ini koefisien model pertama-tama akan disimpulkan menggunakan data pelatihan. Setelah disimpulkan, data tersebut akan diperbaiki dan kumpulan data masukan baru. Model tersebut kemudian akan dieksekusi untuk menghasilkan prediksi yang sesuai untuk data masukan baru ini. Bentuk eksekusi ini juga dapat digunakan untuk menghasilkan data sintetik yang representatif dari model yang dilatih.
Membangun dan melatih model
//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 ();
Bangun model dan simpulkan probabilitas
//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 ()
Untuk bantuan terkait Sandwood, silakan memulai atau bergabung dalam diskusi di halaman diskusi.
Proyek ini menyambut baik kontribusi dari komunitas. Sebelum mengirimkan permintaan penarikan, harap tinjau panduan kontribusi kami.
Silakan baca panduan keamanan untuk proses pengungkapan kerentanan keamanan kami yang bertanggung jawab.
Hak Cipta (c) 2019-2024 Oracle dan/atau afiliasinya.
Dirilis di bawah Lisensi Permisif Universal v1.0 seperti yang ditunjukkan di https://oss.Oracle.com/licenses/upl/.