Rumah > Peranti teknologi > AI > Panduan untuk Jax kilat cepat

Panduan untuk Jax kilat cepat

Jennifer Aniston
Lepaskan: 2025-03-19 11:21:11
asal
626 orang telah melayarinya

Hei ada, peminat Python! Pernahkah anda berharap kod Numpy anda berjalan pada kelajuan supersonik? Berjumpa dengan Jax!. Sahabat baru anda dalam pembelajaran mesin, pembelajaran mendalam, dan perjalanan pengkomputeran berangka. Fikirkannya sebagai numpy dengan kuasa besar. Ia secara automatik boleh mengendalikan kecerunan, menyusun kod anda untuk berjalan dengan cepat menggunakan JIT, dan juga berjalan di GPU dan TPU tanpa melanggar peluh. Sama ada anda membina rangkaian saraf, mencetuskan data saintifik, model pengubah tweaking, atau hanya cuba mempercepatkan pengiraan anda, Jax mempunyai belakang anda. Mari menyelam dan lihat apa yang menjadikan Jax begitu istimewa.

Panduan ini memberikan pengenalan terperinci kepada Jax dan ekosistemnya.

Objektif pembelajaran

  • Terangkan prinsip teras Jax dan bagaimana mereka berbeza dari Numpy.
  • Sapukan tiga transformasi utama Jax untuk mengoptimumkan kod python. Tukar Operasi Numpy ke dalam pelaksanaan JAX yang cekap.
  • Mengenal pasti dan menetapkan kesesakan prestasi biasa dalam kod JAX. Melaksanakan kompilasi JIT dengan betul sambil mengelakkan perangkap biasa.
  • Membina dan melatih rangkaian saraf dari awal menggunakan Jax. Melaksanakan operasi pembelajaran mesin biasa menggunakan pendekatan fungsi Jax.
  • Menyelesaikan masalah pengoptimuman menggunakan pembezaan automatik Jax. Melaksanakan operasi matriks yang cekap dan pengiraan berangka.
  • Memohon strategi debugging yang berkesan untuk isu-isu khusus JAX. Melaksanakan corak efisien memori untuk pengiraan berskala besar.

Artikel ini diterbitkan sebagai sebahagian daripada Blogathon Sains Data.

Jadual Kandungan

  • Apa itu Jax?
  • Mengapa Jax menonjol?
  • Bermula dengan Jax
  • Mengapa Belajar Jax?
  • Transformasi Jax penting
  • Membina rangkaian saraf dengan jax
  • Amalan dan petua terbaik
  • Pengoptimuman Prestasi
  • Strategi debugging
  • Corak dan idiom biasa dalam jax
  • Apa yang seterusnya?
  • Kesimpulan
  • Soalan yang sering ditanya

Apa itu Jax?

Menurut dokumentasi rasmi, Jax adalah perpustakaan Python untuk pengiraan array berorientasikan percepatan dan transformasi program, yang direka untuk pengkomputeran berangka berprestasi tinggi dan pembelajaran mesin berskala besar. Oleh itu, Jax pada dasarnya adalah Numpy pada steroid, ia menggabungkan operasi gaya Numpy yang biasa dengan pembezaan automatik dan pecutan perkakasan. Fikirkan ia sebagai yang terbaik dari tiga dunia.

  • Operasi Sintaks dan Array Elegant Numpy
  • Pytorch seperti keupayaan pembezaan automatik
  • XLA (Algebra Linear Dipercepatkan) untuk pecutan perkakasan dan faedah penyusunan.

Mengapa Jax menonjol?

Apa yang membezakan Jax adalah transformasinya. Ini adalah fungsi yang kuat yang dapat mengubah kod python anda:

  • JIT : Penyusunan tepat pada masa untuk pelaksanaan yang lebih cepat
  • Grad : Pembezaan automatik untuk kecerunan pengkomputeran
  • VMAP : Vektorisasi secara automatik untuk pemprosesan batch

Berikut adalah penampilan cepat:

 import jax.numpy sebagai jnp
Dari graduan import Jax, JIT
# Tentukan fungsi mudah
@jit # mempercepatkannya dengan penyusunan
def square_sum (x):
kembali jnp.sum (jnp.square (x))
# Dapatkan fungsi kecerunannya secara automatik
gradient_fn = grad (square_sum)
# Cubalah
x = JNP.Array ([1.0, 2.0, 3.0])
cetak (f "gradien: {gradient_fn (x)}")
Salin selepas log masuk

Output:

 Kecerunan: [2. 4. 6.]
Salin selepas log masuk

Bermula dengan Jax

Di bawah ini kita akan mengikuti beberapa langkah untuk memulakan dengan Jax.

Langkah1: Pemasangan

Menyediakan Jax adalah mudah untuk kegunaan CPU sahaja. Anda boleh menggunakan dokumentasi JAX untuk maklumat lanjut.

Langkah2: Mencipta persekitaran untuk projek

Buat persekitaran konda untuk projek anda

 # Buat env conda untuk jax
$ conda create -nama jaxdev python = 3.11

#Activate env
$ conda mengaktifkan jaxdev

# Buat Projek Dir Name Jax101
$ mkdir jax101

# Masuk ke dir.
$ CD JAX101
Salin selepas log masuk

Langkah3: Memasang Jax

Memasang Jax di persekitaran yang baru dibuat

 # Untuk CPU sahaja
PIP Pasang -PIPGGRADE PIP
PIP INSTALL --upgrade "Jax"

# untuk GPU
PIP Pasang -PIPGGRADE PIP
PIP Pasang --upgrade "Jax [cuda12]"
Salin selepas log masuk

Sekarang anda sudah bersedia untuk menyelam ke dalam perkara sebenar. Sebelum mendapatkan tangan anda kotor pada pengekodan praktikal mari kita pelajari beberapa konsep baru. Saya akan menerangkan konsep -konsep terlebih dahulu dan kemudian kita akan bersama untuk memahami pandangan praktikal.

Pertama, dapatkan motivasi, dengan cara, mengapa kita belajar perpustakaan baru lagi? Saya akan menjawab soalan itu sepanjang panduan ini secara langkah demi langkah semudah mungkin.

Mengapa Belajar Jax?

Fikirkan Jax sebagai alat kuasa. Walaupun Numpy adalah seperti tangan yang boleh dipercayai, Jax adalah seperti gergaji elektrik moden. Ia memerlukan sedikit langkah dan pengetahuan, tetapi manfaat prestasi bernilai untuk tugas pengiraan yang intensif.

  • Prestasi : Kod Jax dapat berjalan dengan lebih cepat daripada kod Python atau Numpy yang tulen, terutama pada GPU dan TPU
  • Fleksibiliti : Bukan hanya untuk pembelajaran mesin- Jax cemerlang dalam pengkomputeran saintifik, pengoptimuman, dan simulasi.
  • Pendekatan Moden: Jax menggalakkan corak pengaturcaraan berfungsi yang membawa kepada kod yang lebih bersih dan lebih diselenggara.

Di bahagian seterusnya, kami akan menyelam jauh ke dalam transformasi Jax, bermula dengan kompilasi JIT. Transformasi ini adalah apa yang memberi Jax kuasa besarnya, dan memahami mereka adalah kunci untuk memanfaatkan Jax dengan berkesan.

Transformasi Jax penting

Transformasi Jax adalah apa yang benar -benar membezakannya daripada perpustakaan pengiraan berangka seperti numpy atau scipy. Mari kita meneroka setiap satu dan lihat bagaimana mereka dapat menembusi kod anda.

JIT atau kompilasi hanya dalam masa

Kompilasi hanya dalam masa mengoptimumkan pelaksanaan kod dengan menyusun bahagian program semasa runtime dan bukannya lebih awal daripada masa.

Bagaimana JIT Berfungsi di Jax?

Di Jax, Jax.jit mengubah fungsi python ke dalam versi JIT yang dikompilasi. Menghias fungsi dengan @jax.jit menangkap graf pelaksanaannya, mengoptimumkannya, dan menyusunnya menggunakan XLA. Versi yang disusun kemudian dijalankan, menyampaikan kelajuan yang ketara, terutamanya untuk panggilan fungsi berulang.

Inilah cara anda boleh mencubanya.

 import jax.numpy sebagai jnp
dari jit import jax
masa import


# Fungsi intensif yang komputasi
def slow_function (x):
    untuk _ dalam julat (1000):
        x = jnp.sin (x) jnp.cos (x)
    kembali x


# Fungsi yang sama dengan JIT
@jit
def fast_function (x):
    untuk _ dalam julat (1000):
        x = jnp.sin (x) jnp.cos (x)
    kembali x
Salin selepas log masuk

Berikut adalah fungsi yang sama, satu hanyalah proses kompilasi Python biasa dan yang lain digunakan sebagai proses kompilasi JIT JAX. Ia akan mengira 1000 titik data jumlah fungsi sinus dan kosinus. Kami akan membandingkan prestasi menggunakan masa.

 # Bandingkan prestasi
x = jnp.arange (1000)

# Jit pemanasan
fast_function (x) # panggilan pertama menyusun fungsi

# Perbandingan masa
mula = time.time ()
SLOW_RESULT = SLOW_FUNCTION (x)
cetak (f "tanpa jit: {time.time () - start: .4f} saat")

mula = time.time ()
fast_result = fast_function (x)
cetak (f "dengan jit: {time.time () - start: .4f} saat")
Salin selepas log masuk

Hasilnya akan mengejutkan anda. Kompilasi JIT adalah 333 kali lebih cepat daripada kompilasi biasa. Ia seperti membandingkan basikal dengan buggati chiron.

Output:

 Tanpa JIT: 0.0330 saat
Dengan JIT: 0.0010 saat
Salin selepas log masuk

JIT boleh memberi anda peningkatan pelaksanaan superfast tetapi anda mesti menggunakannya dengan betul jika tidak, ia akan menjadi seperti memandu Bugatti di jalan kampung berlumpur yang tidak menawarkan kemudahan supercar.

JIT biasa perangkap

JIT berfungsi dengan baik dengan bentuk dan jenis statik. Elakkan menggunakan gelung python dan keadaan yang bergantung kepada nilai array. JIT tidak berfungsi dengan tatasusunan dinamik.

 # Buruk - menggunakan aliran kawalan python
@jit
def bad_function (x):
    jika x [0]> 0: # ini tidak akan berfungsi dengan baik dengan jit
        kembali x
    kembali -x


# cetak (bad_function (jnp.array ([1, 2, 3])))


# Baik - menggunakan aliran kawalan jax
@jit
def good_function (x):
    Kembalikan JNP.WHERE (X [0]> 0, X, -X) # keadaan JAX -NATIVE


Cetak (Good_Function (JNP.Array ([1, 2, 3])))
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Ini bermakna BAD_FUNCTION adalah buruk kerana JIT tidak terletak pada nilai x semasa pengiraan.

Output:

 [1 2 3]
Salin selepas log masuk

Batasan dan pertimbangan

  • Kompilasi Overhead: Kali pertama fungsi JIT yang dikompilasi dilaksanakan, terdapat beberapa overhead disebabkan oleh penyusunan. Kos kompilasi mungkin melebihi manfaat prestasi untuk fungsi kecil atau yang dipanggil hanya sekali.
  • Ciri -ciri Python Dinamik: JIT JAX memerlukan fungsi untuk menjadi "statik" . Aliran kawalan dinamik, seperti perubahan bentuk atau nilai berdasarkan gelung python, tidak disokong dalam kod yang disusun. Jax menyediakan alternatif seperti `jax.lax.cond` dan` jax.lax.scan` untuk mengendalikan aliran kawalan dinamik.

Pembezaan automatik

Pembezaan automatik, atau autodiff, adalah teknik pengiraan untuk mengira derivatif fungsi dengan tepat dan berkesan. Ia memainkan peranan penting dalam mengoptimumkan model pembelajaran mesin, terutamanya dalam latihan rangkaian saraf, di mana kecerunan digunakan untuk mengemas kini parameter model.

Panduan untuk Jax kilat cepat

Bagaimanakah pembezaan automatik berfungsi di Jax?

Autodiff berfungsi dengan menggunakan peraturan rantai kalkulus untuk menguraikan fungsi kompleks ke dalam yang lebih mudah, mengira derivatif sub-fungsi ini, dan kemudian menggabungkan hasilnya. Ia merekodkan setiap operasi semasa pelaksanaan fungsi untuk membina graf pengiraan, yang kemudiannya digunakan untuk mengira derivatif secara automatik.

Terdapat dua mod utama auto-diff:

  • Mod Forward: Mengira derivatif dalam satu lulus ke hadapan melalui graf pengiraan, cekap untuk fungsi dengan sebilangan kecil parameter.
  • Mod terbalik: Mengira derivatif dalam satu lulus ke belakang melalui graf pengiraan, cekap untuk fungsi dengan sejumlah besar parameter.

Panduan untuk Jax kilat cepat

Ciri -ciri utama dalam pembezaan automatik Jax

  • Pengiraan Kecerunan (jax.grad): `jax.grad` mengira derivatif fungsi scaler-output untuk inputnya. Untuk fungsi dengan pelbagai input, derivatif separa boleh diperolehi.
  • Derivatif pesanan lebih tinggi (Jax.jacobian, Jax.Hessian): Jax menyokong pengiraan derivatif pesanan tinggi, seperti Jacobians dan Hessains, menjadikannya sesuai untuk pengoptimuman lanjutan dan simulasi fizik.
  • Komposiliti dengan transformasi Jax yang lain: Autodiff dalam Jax mengintegrasikan dengan lancar dengan transformasi lain seperti `jax.jit` dan` jax.vmap` yang membolehkan pengiraan yang cekap dan berskala.
  • Pembezaan mod terbalik (backpropagation): Jax's Auto-Diff menggunakan pembezaan mod terbalik untuk fungsi scaler-output, yang sangat berkesan untuk tugas pembelajaran mendalam.
 import jax.numpy sebagai jnp
dari jax import grad, value_and_grad


# Tentukan lapisan rangkaian saraf yang mudah
Lapisan DEF (Params, X):
    Berat, Bias = Params
    Kembali jnp.dot (x, berat) Bias


# Tentukan fungsi kehilangan nilai skalar
def loss_fn (params, x):
    output = lapisan (param, x)
    kembali jnp.sum (output) # Mengurangkan ke skalar


# Dapatkan output dan kecerunan
layer_grad = grad (loss_fn, argnums = 0) # gradien berkenaan dengan param
Layer_Value_and_grad = value_and_grad (loss_fn, argnums = 0) # kedua -dua nilai dan kecerunan

# Contoh penggunaan
kunci = jax.random.prngKey (0)
x = jax.random.normal (kunci, (3, 4))
berat = jax.random.normal (kunci, (4, 2))
Bias = jax.random.normal (kunci, (2,))

# Mengira kecerunan
grads = layer_grad ((berat, bias), x)
output, grads = layer_value_and_grad ((berat, bias), x)

# Derivatif berganda mudah
dua kali_grad = grad (grad (jnp.sin))
x = JNP.Array (2.0)
cetak (f "derivatif kedua dosa di x = 2: {twip_grad (x)}")
Salin selepas log masuk

Output:

 Derivatif Kedua Dosa di X = 2: -0.9092974066734314
Salin selepas log masuk

Keberkesanan dalam Jax

  • Kecekapan: Pembezaan automatik Jax sangat berkesan kerana integrasi dengan XLA, yang membolehkan pengoptimuman di peringkat kod mesin.
  • KOMPOSIBILITI : Keupayaan untuk menggabungkan transformasi yang berbeza menjadikan Jax alat yang berkuasa untuk membina saluran paip pembelajaran mesin kompleks dan seni bina rangkaian saraf seperti CNN, RNN, dan Transformers.
  • Kemudahan Penggunaan: Sintaks Jax untuk Autodiff adalah mudah dan intuitif, membolehkan pengguna mengira kecerunan tanpa membincangkan butiran API Perpustakaan XLA dan kompleks.

Jax Vectorize Pemetaan

Dalam Jax, `vMap` adalah fungsi yang kuat yang secara automatik mengira perhitungan, yang membolehkan anda menggunakan fungsi ke atas kumpulan data tanpa menulis gelung secara manual. Ia memetakan fungsi ke atas paksi array (atau pelbagai paksi) dan menilai dengan cekap secara selari, yang boleh membawa kepada penambahbaikan prestasi yang signifikan.

Bagaimana VMAP berfungsi di Jax?

Fungsi VMAP mengautomasikan proses memohon fungsi ke setiap elemen di sepanjang paksi tertentu dari array input sambil mengekalkan kecekapan pengiraan. Ia mengubah fungsi yang diberikan untuk menerima input yang dibatalkan dan melaksanakan pengiraan secara vektor.

Daripada menggunakan gelung eksplisit, VMAP membolehkan operasi dilakukan selari dengan vektori melalui paksi input. Ini memanfaatkan keupayaan perkakasan untuk melaksanakan operasi SIMD (arahan tunggal, pelbagai data), yang boleh menghasilkan kelajuan besar.

Ciri -ciri utama VMAP

  • Vektorisasi automatik: VAMP mengautomasikan pengumpulan pengiraan, menjadikannya mudah untuk kod selari melalui dimensi batch tanpa mengubah logik fungsi asal.
  • Komposiliti dengan transformasi lain: Ia berfungsi dengan lancar dengan transformasi Jax yang lain, seperti Jax.Grad untuk pembezaan dan jax.jit untuk kompilasi yang tepat pada masa, yang membolehkan kod yang sangat dioptimumkan dan fleksibel.
  • Mengendalikan pelbagai dimensi batch: VMAP menyokong pemetaan ke atas pelbagai susunan input atau paksi, menjadikannya serba boleh untuk pelbagai kes penggunaan seperti memproses data pelbagai dimensi atau pelbagai pembolehubah secara serentak.
 import jax.numpy sebagai jnp
dari jax import vmap


# Fungsi yang berfungsi pada input tunggal
def single_input_fn (x):
    Kembalikan jnp.sin (x) jnp.cos (x)


# Vektorkan untuk mengerjakan kelompok
batch_fn = vmap (single_input_fn)

# Bandingkan prestasi
x = jnp.arange (1000)

# Tanpa VMAP (menggunakan pemahaman senarai)
hasil1 = jnp.array ([Single_input_fn (xi) untuk xi dalam x])

# Dengan VMAP
hasil2 = batch_fn (x) # lebih cepat!


# Vektor pelbagai argumen
def two_input_fn (x, y):
    kembali x * jnp.sin (y)


# Vektori atas kedua -dua input
vectorized_fn = vmap (two_input_fn, in_axes = (0, 0))

# Atau vectorize hanya input pertama
sebahagiannya_vectorized_fn = vmap (two_input_fn, in_axes = (0, tiada))


# cetak
cetak (result1.shape)
cetak (result2.shape)
cetak (sebahagiannya_vectorized_fn (x, y) .shape)
Salin selepas log masuk

Output:

 (1000,)
(1000,)
(1000,3)
Salin selepas log masuk

Keberkesanan vmap dalam jax

  • Penambahbaikan prestasi: Dengan mengira pengiraan, VMAP dapat mempercepat pelaksanaan dengan memanfaatkan keupayaan pemprosesan selari perkakasan moden seperti GPU, dan TPU (unit pemprosesan tensor).
  • Kod bersih: Ia membolehkan lebih banyak kod ringkas dan boleh dibaca dengan menghapuskan keperluan untuk gelung manual.
  • Keserasian dengan Jax dan Autodiff: VMAP boleh digabungkan dengan pembezaan automatik (jax.grad), yang membolehkan pengiraan derivatif yang cekap berbanding kumpulan data.

Bila Menggunakan Setiap Transformasi

Menggunakan @jit bila:

  • Fungsi anda dipanggil beberapa kali dengan bentuk input yang sama.
  • Fungsi ini mengandungi perhitungan berangka berat.

Gunakan grad semasa:

  • Anda memerlukan derivatif untuk pengoptimuman.
  • Melaksanakan algoritma pembelajaran mesin
  • Menyelesaikan persamaan pembezaan untuk simulasi

Gunakan VMAP ketika:

  • Pemprosesan kumpulan data dengan.
  • Pengiraan Parallelizing
  • Mengelakkan gelung yang jelas

Operasi matriks dan aljabar linear menggunakan jax

Jax menyediakan sokongan komprehensif untuk operasi matriks dan aljabar linear, menjadikannya sesuai untuk pengkomputeran saintifik, pembelajaran mesin, dan tugas pengoptimuman berangka. Keupayaan algebra linear Jax adalah serupa dengan yang terdapat di perpustakaan seperti Numpy tetapi dengan ciri-ciri tambahan seperti pembezaan automatik dan kompilasi hanya dalam masa untuk prestasi yang dioptimumkan.

Penambahan dan pengurangan matriks

Operasi ini dilakukan matriks elemen yang sama dengan bentuk yang sama.

 Tambahan dan penolakan matriks # 1:

import jax.numpy sebagai jnp

A = JNP.Array ([[1, 2], [3, 4]])
B = JNP.Array ([[5, 6], [7, 8]])

# Penambahan matriks
C = ab
# Penolakan matriks
D = A - B

cetak (f "matriks a: \ n {a}")
Cetak ("==========================")
cetak (f "matriks b: \ n {b}")
Cetak ("==========================")
cetak (f "matriks pemadaman ab: \ n {c}")
Cetak ("==========================")
cetak (f "substraksi matriks AB: \ n {d}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Pendaraban matriks

Jax menyokong kedua-dua pendaraban elemen-bijak dan pendaraban matriks berasaskan produk DOR.

 # Pendaraban yang bijak
E = a * b

# Pendaraban Matrix (Produk Dot)
F = jnp.dot (a, b)

cetak (f "matriks a: \ n {a}")
Cetak ("==========================")
cetak (f "matriks b: \ n {b}")
Cetak ("==========================")
cetak (f "pendaraban elemen-bijak a*b: \ n {e}")
Cetak ("==========================")
cetak (f "pendaraban matriks A*b: \ n {f}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Matriks transpose

Transpose matriks boleh didapati menggunakan `jnp.transpose ()`

 # Matrik transpose
G = jnp.transpose (a)

cetak (f "matriks a: \ n {a}")
Cetak ("==========================")
cetak (f "matriks transpose a: \ n {g}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Matriks songsang

Jax menyediakan fungsi untuk penyongsangan matriks menggunakan `jnp.linalg.inv ()`

 # Penyongsangan matrik
H = jnp.linalg.inv (a)

cetak (f "matriks a: \ n {a}")
Cetak ("==========================")
cetak (f "penyongsangan matriks a: \ n {h}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Penentu matriks

Penentu matriks boleh dikira menggunakan `jnp.linalg.det ()`.

 # penentu matriks
det_a = jnp.linalg.det (a)

cetak (f "matriks a: \ n {a}")
Cetak ("==========================")
cetak (f "penentu matriks a: \ n {det_a}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Nilai Eigen Matrix dan Eigenvectors

Anda boleh mengira nilai eigen dan eigenvectors matriks menggunakan `jnp.linalg.eigh ()`

 # Nilai eigen dan vektor eigen
import jax.numpy sebagai jnp

A = JNP.Array ([[1, 2], [3, 4]])
Nilai eigen, eigenvectors = jnp.linalg.eigh (a)

cetak (f "matriks a: \ n {a}")
Cetak ("==========================")
cetak (f "nilai eigen a: \ n {eigenvalues}")
Cetak ("==========================")
cetak (f "eigenvectors of a: \ n {eigenvectors}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Penguraian nilai tunggal matriks

SVD disokong melalui `jnp.linalg.svd`, berguna dalam pengurangan dimensi dan pemfaktoran matriks.

 # Penguraian nilai tunggal (SVD)

import jax.numpy sebagai jnp

A = JNP.Array ([[1, 2], [3, 4]])
U, s, v = jnp.linalg.svd (a)

cetak (f "matriks a: \ n {a}")
Cetak ("==========================")
cetak (f "matriks u: \ n {u}")
Cetak ("==========================")
cetak (f "matriks s: \ n {s}")
Cetak ("==========================")
cetak (f "matriks v: \ n {v}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Menyelesaikan sistem persamaan linear

Untuk menyelesaikan sistem persamaan linear AX = B, kami menggunakan `jnp.linalg.solve ()`, di mana A adalah matriks persegi dan b adalah vektor atau matriks bilangan baris yang sama.

 # Menyelesaikan sistem persamaan linear
import jax.numpy sebagai jnp

A = JNP.Array ([[2.0, 1.0], [1.0, 3.0]])
B = JNP.Array ([5.0, 6.0])
x = jnp.linalg.solve (a, b)

cetak (f "nilai x: {x}")
Salin selepas log masuk

Output:

 Nilai x: [1.8 1.4]
Salin selepas log masuk

Mengira kecerunan fungsi matriks

Menggunakan pembezaan automatik Jax, anda boleh mengira kecerunan fungsi skalar berkenaan dengan matriks.
Kami akan mengira kecerunan fungsi dan nilai di bawah x

Fungsi

Panduan untuk Jax kilat cepat

 # Mengira kecerunan fungsi matriks
Import Jax
import jax.numpy sebagai jnp


def matrix_function (x):
    kembali jnp.sum (jnp.sin (x) x ** 2)


# Kirakan graduan fungsi
grad_f = jax.grad (matrix_function)

X = jnp.array ([[1.0, 2.0], [3.0, 4.0]])
kecerunan = grad_f (x)

cetak (f "matriks x: \ n {x}")
Cetak ("==========================")
cetak (f "kecerunan matrix_function: \ n {gradien}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Fungsi Jax yang paling berguna ini digunakan dalam pengkomputeran berangka, pembelajaran mesin, dan pengiraan fizik. Terdapat banyak lagi yang tersisa untuk anda meneroka.

Pengkomputeran saintifik dengan Jax

Perpustakaan kuat Jax untuk pengkomputeran saintifik, Jax adalah yang terbaik untuk pengkomputeran saintifik untuk ciri-ciri awalnya seperti penyusunan JIT, pembezaan automatik, vektorisasi, penyesuaian, dan pecutan GPU-TPU. Keupayaan Jax untuk menyokong pengkomputeran prestasi tinggi menjadikannya sesuai untuk pelbagai aplikasi saintifik, termasuk simulasi fizik, pembelajaran mesin, pengoptimuman dan analisis berangka.

Kami akan meneroka masalah pengoptimuman dalam bahagian ini.

Masalah pengoptimuman

Marilah kita melalui masalah pengoptimuman langkah di bawah:

Langkah1: Tentukan fungsi untuk meminimumkan (atau masalah)

 # Tentukan fungsi untuk meminimumkan (misalnya, fungsi Rosenbrock)

@jit

Def Rosenbrock (x):

kembali jumlah (100.0 * (x [1:] - x [: - 1] ** 2.0) ** 2.0 (1 - x [: - 1]) ** 2.0)
Salin selepas log masuk

Di sini, fungsi Rosenbrock ditakrifkan, yang merupakan masalah ujian biasa dalam pengoptimuman. Fungsi ini mengambil array x sebagai input dan mengira valie yang mewakili sejauh mana X adalah dari minimum global fungsi. Penghias @Jit digunakan untuk membolehkan penyusunan JUT-in-time, yang mempercepat pengiraan dengan menyusun fungsi untuk berjalan dengan cekap pada CPU dan GPU.

Langkah2: Pelaksanaan Langkah Keturunan Gradien

 # Pengoptimuman keturunan kecerunan

@jit

def gradient_descent_step (x, learning_rate):

kembali x - learning_rate * grad (rosenbrock) (x)
Salin selepas log masuk

Fungsi ini melakukan satu langkah pengoptimuman keturunan kecerunan. Kecerunan fungsi Rosenbrock dikira menggunakan grad (Rosenbrock) (x), yang memberikan derivatif dengan aspek kepada x. Nilai baru x dikemas kini dengan pengurangan kecerunan yang diperkatakan oleh pembelajaran_rate.the @jit melakukan perkara yang sama seperti sebelumnya.

Langkah3: Menjalankan Gelung Pengoptimuman

 # Mengoptimumkan
x = jnp.array ([0.0, 0.0]) # titik permulaan

learning_rate = 0.001

untuk I in Range (2000):

x = gradient_descent_step (x, learning_rate)

jika saya % 100 == 0:

cetak (f "langkah {i}, nilai: {rosenbrock (x): 4f}")
Salin selepas log masuk

Gelung pengoptimuman memulakan titik permulaan X dan melakukan 1000 lelaran keturunan kecerunan. Dalam setiap lelaran, kemas kini fungsi Gradient_descent_Step berdasarkan kecerunan semasa. Setiap 100 langkah, nombor langkah semasa dan nilai fungsi Rosenbrock di x dicetak, memberikan kemajuan pengoptimuman.

Output:

Panduan untuk Jax kilat cepat

Menyelesaikan masalah fizik dunia nyata dengan jax

Kami akan mensimulasikan sistem fizikal gerakan pengayun harmonik yang lembap, yang memodelkan perkara-perkara seperti sistem spring massa dengan geseran, penyerap kejutan dalam kenderaan, atau ayunan dalam litar elektrik. Adakah tidak bagus? Mari Lakukan.

Langkah1: Definisi parameter

 Import Jax
import jax.numpy sebagai jnp


# Tentukan parameter
jisim = 1.0 # jisim objek (kg)
redaman = 0.1 # pekali redaman (kg/s)
spring_constant = 1.0 # pemalar musim bunga (n/m)

# Tentukan langkah masa dan jumlah masa
dt = 0.01 # langkah masa (s)
num_steps = 3000 # bilangan langkah
Salin selepas log masuk

Jisim, pekali redaman, dan pemalar musim bunga ditakrifkan. Ini menentukan sifat fizikal pengayun harmonik yang lembap.

Langkah2: Definisi Ode

 # Tentukan sistem odes
def damped_harmonic_oscillator (state, t):
    "" "Kirakan derivatif untuk pengayun harmonik yang lembap.

    Negeri: Arahan yang mengandungi kedudukan dan halaju [x, v]
    T: Masa (tidak digunakan dalam sistem autonomi ini)
    "" "
    x, v = keadaan
    dxdt = v
    dvdt = -damping / jisim * v - spring_constant / massa * x
    kembali jnp.array ([dxdt, dvdt])
Salin selepas log masuk

Fungsi pengayun harmonik yang lembap mentakrifkan derivatif kedudukan dan halaju pengayun, yang mewakili sistem dinamik.

Langkah3: Kaedah Euler

 # Selesaikan ode menggunakan kaedah Euler
def euler_step (state, t, dt):
    "" "Lakukan satu langkah kaedah Euler." ""
    Derivatif = damped_harmonic_oscillator (Negeri, T)
    kembali derivatif negeri * dt
Salin selepas log masuk

Kaedah berangka mudah digunakan untuk menyelesaikan ODE. Ia menghampiri keadaan pada langkah seterusnya berdasarkan keadaan semasa dan derivatif.

Langkah4: Gelung evolusi masa

 # Keadaan awal: [kedudukan, halaju]
initial_state = jnp.array ([1.0, 0.0]) # bermula dengan jisim pada x = 1, v = 0

# Evolusi masa
negeri = [initial_state]
masa = 0.0
untuk langkah dalam julat (num_steps):
    next_state = euler_step (menyatakan [-1], masa, dt)
    negeri.append (next_state)
    masa = dt

# Tukar senarai negeri ke array jax untuk analisis
negeri = jnp.stack (negeri)
Salin selepas log masuk

Gelung itu melangkah melalui bilangan langkah masa yang ditentukan, mengemas kini keadaan pada setiap langkah menggunakan kaedah Euler.

Output:

Panduan untuk Jax kilat cepat

Langkah 5: Merancang hasilnya

Akhirnya, kita boleh merancang hasilnya untuk memvisualisasikan tingkah laku pengayun harmonik yang lembap.

 # Merancang hasilnya
import matplotlib.pyplot sebagai PLT

plt.style.use ("ggplot")

kedudukan = menyatakan [:, 0]
halaju = menyatakan [:, 1]
time_points = jnp.arange (0, (num_steps 1) * dt, dt)

PLT.Figure (figsize = (12, 6))
plt.subplot (2, 1, 1)
plt.plot (time_points, posisi, label = "kedudukan")
plt.xlabel ("masa (s)")
plt.ylabel ("kedudukan (m)")
plt.legend ()

plt.subplot (2, 1, 2)
plt.plot (time_points, halaju, label = "halaju", warna = "oren")
plt.xlabel ("masa (s)")
plt.ylabel ("halaju (m/s)")
plt.legend ()

plt.tight_layout ()
plt.show ()
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Saya tahu anda tidak sabar -sabar untuk melihat bagaimana rangkaian saraf boleh dibina dengan Jax. Jadi, mari kita menyelam jauh ke dalamnya.

Di sini, anda dapat melihat bahawa nilai -nilai diminimumkan secara beransur -ansur.

Membina rangkaian saraf dengan jax

Jax adalah perpustakaan yang kuat yang menggabungkan pengkomputeran berangka berprestasi tinggi dengan kemudahan menggunakan sintaks seperti numpy. Bahagian ini akan membimbing anda melalui proses membina rangkaian saraf menggunakan Jax, memanfaatkan ciri-ciri canggihnya untuk pembezaan automatik dan kompilasi hanya dalam masa untuk mengoptimumkan prestasi.

Langkah1: Mengimport perpustakaan

Sebelum kita menyelam untuk membina rangkaian saraf kita, kita perlu mengimport perpustakaan yang diperlukan. Jax menyediakan satu set alat untuk mewujudkan perhitungan berangka yang cekap, sementara perpustakaan tambahan akan membantu pengoptimuman dan visualisasi hasil kami.

 Import Jax
import jax.numpy sebagai jnp
Dari graduan import Jax, JIT
dari jax.random import prngkey, normal
Import Optax # Perpustakaan Pengoptimuman Jax
import matplotlib.pyplot sebagai PLT
Salin selepas log masuk

Langkah2: Membuat Lapisan Model

Mewujudkan lapisan model yang berkesan adalah penting dalam menentukan seni bina rangkaian saraf kami. Dalam langkah ini, kami akan memulakan parameter untuk lapisan padat kami, memastikan model kami bermula dengan berat dan berat sebelah yang jelas untuk pembelajaran yang berkesan.

 def init_layer_params (kunci, n_in, n_out):
    "" "Inisialisasi parameter untuk lapisan padat tunggal" ""
    key_w, key_b = jax.random.split (kekunci)
    # Dia inisialisasi
    w = normal (key_w, (n_in, n_out)) * jnp.sqrt (2.0 / n_in)  
    b = normal (key_b, (n_out,)) * 0.1
    kembali (w, b)
    
def relu (x):
    "" "Fungsi pengaktifan relu" "" "
    kembali jnp.maximum (0, x)
    
Salin selepas log masuk
  • Fungsi Inisialisasi : init_layer_params memulakan berat (w) dan bias (b) untuk lapisan padat menggunakan permulaannya untuk berat dan nilai kecil untuk bias. Beliau atau Kaiming He Inisialisasi berfungsi lebih baik untuk lapisan dengan fungsi pengaktifan relu, terdapat kaedah inisialisasi popular yang lain seperti inisialisasi Xavier yang berfungsi lebih baik untuk lapisan dengan pengaktifan sigmoid.
  • Fungsi Pengaktifan: Fungsi RELU menggunakan fungsi pengaktifan relu kepada input yang menetapkan nilai negatif kepada sifar.

Langkah3: Menentukan Pas Forward

Pas ke hadapan adalah asas rangkaian saraf, kerana ia menentukan bagaimana data input mengalir melalui rangkaian untuk menghasilkan output. Di sini, kami akan menentukan kaedah untuk mengira output model kami dengan menggunakan transformasi ke data input melalui lapisan yang diasaskan.

 Def Forward (Params, X):
    "" "Lulus ke hadapan untuk rangkaian saraf dua lapisan" ""
    (W1, B1), (W2, B2) = Params
    # Lapisan pertama
    H1 = relu (jnp.dot (x, w1) b1)
    # Lapisan output
    logit = jnp.dot (H1, W2) b2
    kembali logit
    
Salin selepas log masuk
  • Forward Pass: Forward melakukan lulus ke hadapan melalui rangkaian saraf dua lapisan, mengira output (logit) dengan menggunakan transformasi linear diikuti oleh Relu, dan transformasi linear yang lain.

S TEP4: Menentukan fungsi kerugian

Fungsi kerugian yang jelas adalah penting untuk membimbing latihan model kami. Dalam langkah ini, kami akan melaksanakan fungsi kerugian kesilapan (MSE) min, yang mengukur seberapa baik output yang diramalkan sepadan dengan nilai sasaran, membolehkan model untuk belajar dengan berkesan.

 def loss_fn (params, x, y):
    "" "Maksud kehilangan kesilapan kuadrat" ""
    pred = ke hadapan (param, x)
    kembali jnp.mean ((pred - y) ** 2)
Salin selepas log masuk
  • Fungsi kerugian: loss_fn mengira kerugian ralat kuadrat (MSE) antara log yang diramalkan dan label sasaran (Y).

Langkah 5: Model Inisialisasi

Dengan fungsi seni bina dan kehilangan model kami, kami kini beralih kepada permulaan model. Langkah ini melibatkan penubuhan parameter rangkaian saraf kami, memastikan setiap lapisan bersedia untuk memulakan proses latihan dengan berat dan berat badan yang rawak tetapi sesuai.

 def init_model (rng_key, input_dim, hidden_dim, output_dim):
    key1, key2 = jax.random.split (rng_key)
    params = [
        init_layer_params (key1, input_dim, hidden_dim),
        init_layer_params (key2, hidden_dim, output_dim),
    ]
    kembali param
    
Salin selepas log masuk
  • Inisialisasi model: init_model memulakan berat dan bias untuk kedua -dua lapisan rangkaian saraf. Ia menggunakan dua kekunci rawak berasingan untuk setiap lapisan parameter;

Langkah 6: Langkah Latihan

Latihan Rangkaian saraf melibatkan kemas kini berulang kepada parameternya berdasarkan kecerunan yang dikira fungsi kerugian. Dalam langkah ini, kami akan melaksanakan fungsi latihan yang menggunakan kemas kini ini dengan cekap, yang membolehkan model kami belajar dari data melalui pelbagai zaman.

 @jit
def train_step (params, opt_state, x_batch, y_batch):
    kerugian, graduan = jax.value_and_grad (loss_fn) (params, x_batch, y_batch)
    kemas kini, opt_state = optimizer.update (grads, opt_state)
    params = optax.apply_updates (params, kemas kini)
    Kembali param, opt_state, kerugian
Salin selepas log masuk
  • Langkah Latihan: Fungsi Train_Step melakukan kemas kini keturunan kecerunan tunggal.
  • Ia mengira kerugian dan kecerunan menggunakan value_and_grad, yang mengira kedua -dua nilai fungsi dan kecerunan lain.
  • Kemas kini pengoptimuman dikira, dan parameter model dikemas kini dengan sewajarnya.
  • JIT-disusun untuk prestasi.

Langkah7: Gelung data dan latihan

Untuk melatih model kami dengan berkesan, kami perlu menjana data yang sesuai dan melaksanakan gelung latihan. Bahagian ini akan meliputi cara membuat data sintetik untuk contoh kami dan bagaimana untuk menguruskan proses latihan merentasi pelbagai kelompok dan zaman.

 # Menghasilkan beberapa contoh data
kunci = prngkey (0)
x_data = normal (kekunci, (1000, 10)) # 1000 sampel, 10 ciri
y_data = jnp.sum (x_data ** 2, paksi = 1, keepdims = true) # fungsi nonlinear mudah

# Inisialisasi model dan pengoptimum
params = init_model (kunci, input_dim = 10, hidden_dim = 32, output_dim = 1)
Optimizer = optax.adam (learning_rate = 0.001)
opt_state = optimizer.init (params)

# LOOP LATIHAN
batch_size = 32
num_epochs = 100
num_batches = x_data.shape [0] // batch_size

# Array untuk menyimpan nilai zaman dan kerugian
epoch_array = []
loss_array = []

untuk zaman dalam julat (num_epochs):
    Epoch_loss = 0.0
    untuk batch dalam julat (num_batches):
        idx = jax.random.permutation (kunci, batch_size)
        x_batch = x_data [idx]
        y_batch = y_data [idx]
        params, opt_state, kehilangan = train_step (params, opt_state, x_batch, y_batch)
        Epoch_loss = kehilangan

    # Simpan kerugian purata untuk zaman
    avg_loss = epoch_loss / num_batches
    epoch_array.append (Epoch)
    loss_array.append (avg_loss)

    Jika Epoch % 10 == 0:
        cetak (f "epoch {epoch}, kehilangan: {avg_loss: .4f}")
Salin selepas log masuk
  • Penjanaan data : Data latihan rawak (X_DATA) dan nilai sasaran yang sama (Y_DATA) dibuat. Model dan pengoptimuman inisialisasi: Parameter model dan keadaan pengoptimum dimulakan.
  • Gelung Latihan: Rangkaian dilatih sepanjang bilangan zaman yang ditentukan, menggunakan keturunan kecerunan mini-batch.
  • Gelung latihan melangkah ke atas kelompok, melakukan kemas kini kecerunan menggunakan fungsi train_step. Kerugian purata setiap zaman dikira dan disimpan. Ia mencetak nombor zaman dan kerugian purata.

Langkah8: Merancang hasilnya

Menggambarkan hasil latihan adalah kunci untuk memahami prestasi rangkaian saraf kami. Dalam langkah ini, kami akan merancang kerugian latihan ke atas Epochs untuk melihat bagaimana model belajar dan mengenal pasti sebarang isu yang berpotensi dalam proses latihan.

 # Plot hasilnya
plt.plot (Epoch_array, loss_array, label = "kehilangan latihan")
plt.xlabel ("Epoch")
plt.ylabel ("kehilangan")
PLT.TITLE ("Kerugian Latihan ke atas Epochs")
plt.legend ()
plt.show ()
Salin selepas log masuk

Contoh -contoh ini menunjukkan bagaimana Jax menggabungkan prestasi tinggi dengan kod yang bersih dan boleh dibaca. Gaya pengaturcaraan berfungsi yang digalakkan oleh Jax menjadikannya mudah untuk menyusun operasi dan memohon transformasi.

Output:

Panduan untuk Jax kilat cepat

Plot:

Panduan untuk Jax kilat cepat

Contoh -contoh ini menunjukkan bagaimana Jax menggabungkan prestasi tinggi dengan kod yang bersih dan boleh dibaca. Gaya pengaturcaraan berfungsi yang digalakkan oleh Jax menjadikannya mudah untuk menyusun operasi dan memohon transformasi.

Amalan dan petua terbaik

In building neural networks, adhering to best practices can significantly enhance performance and maintainability. This section will discuss various strategies and tips for optimizing your code and improving the overall efficiency of your JAX-based models.

Performance Optimization

Optimizing performance is essential when working with JAX, as it enables us to fully leverage its capabilities. Here, we will explore different techniques for improving the efficiency of our JAX functions, ensuring that our models run as quickly as possible without sacrificing readability.

JIT Compilation Best Practices

Just-In-Time (JIT) compilation is one of the standout features of JAX, enabling faster execution by compiling functions at runtime. This section will outline best practices for effectively using JIT compilation, helping you avoid common pitfalls and maximize the performance of your code.

Bad Function

 import jax
import jax.numpy as jnp
from jax import jit
from jax import lax


# BAD: Dynamic Python control flow inside JIT
@jit
def bad_function(x, n):
    for i in range(n): # Python loop - will be unrolled
        x = x 1
    return x
    
    
print("===========================")
# print(bad_function(1, 1000)) # does not work
    
Salin selepas log masuk

This function uses a standard Python loop to iterate n times, incrementing the of x by 1 on each iteration. When compiled with jit, JAX unrolls the loop, which can be inefficient, especially for large n. This approach does not fully leverage JAX's capabilities for performance.

Good Function

 # GOOD: Use JAX-native operations
@jit
def good_function(x, n):
    return xn # Vectorized operation


print("===========================")
print(good_function(1, 1000))
Salin selepas log masuk

This function does the same operation, but it uses a vectorized operation (xn) instead of a loop. This approach is much more efficient because JAX can better optimize the computation when expressed as a single vectorized operation.

Best Function

 # BETTER: Use scan for loops


@jit
def best_function(x, n):
    def body_fun(i, val):
        return val 1

    return lax.fori_loop(0, n, body_fun, x)


print("===========================")
print(best_function(1, 1000))
Salin selepas log masuk

This approach uses `jax.lax.fori_loop`, which is a JAX-native way to implement loops efficiently. The `lax.fori_loop` performs the same increment operation as the previous function, but it does so using a compiled loop structure. The body_fn function defines the operation for each iteration, and `lax.fori_loop` executes it from o to n. This method is more efficient than unrolling loops and is especially suitable for cases where the number of iterations isn't known ahead of time.

Output :

 ===========================
===========================
1001
===========================
1001
Salin selepas log masuk

The code demonstrates different approaches to handling loops and control flow within JAX's jit-complied functions.

Memory Management

Efficient memory management is crucial in any computational framework, especially when dealing with large datasets or complex models. This section will discuss common pitfalls in memory allocation and provide strategies for optimizing memory usage in JAX.

Inefficient Memory Management

 # BAD: Creating large temporary arrays
@jit
def inefficient_function(x):
    temp1 = jnp.power(x, 2) # Temporary array
    temp2 = jnp.sin(temp1) # Another temporary
    return jnp.sum(temp2)
Salin selepas log masuk

inefficient_function(x): This function creates multiple intermediate arrays, temp1, temp1 and finally the sum of the elements in temp2. Creating these temporary arrays can be inefficient because each step allocates memory and incurs computational overhead, leading to slower execution and higher memory usage.

Efficient Memory Management

 # GOOD: Combining operations
@jit
def efficient_function(x):
    return jnp.sum(jnp.sin(jnp.power(x, 2))) # Single operation
Salin selepas log masuk

This version combines all operations into a single line of code. It computes the sine of squared elements of x directly and sums the results. By combining the operation, it avoids creating intermediate arrays, reducing memory footprints and improving performance.

Test Code

 x = jnp.array([1, 2, 3])
print(x)
print(inefficient_function(x))
print(efficient_function(x))
Salin selepas log masuk

Output:

 [1 2 3]
0.49678695
0.49678695
Salin selepas log masuk

The efficient version leverages JAX's ability to optimize the computation graph, making the code faster and more memory-efficient by minimizing temporary array creation.

Debugging Strategies

Debugging is an essential part of the development process, especially in complex numerical computations. In this section, we will discuss effective debugging strategies specific to JAX, enabling you to identify and resolve issues quickly.

Using print inside JIT for Debugging

The code shows techniques for debugging within JAX, particularly when using JIT-compiled functions.

 import jax.numpy as jnp
from jax import debug


@jit
def debug_function(x):
    # Use debug.print instead of print inside JIT
    debug.print("Shape of x: {}", x.shape)
    y = jnp.sum(x)
    debug.print("Sum: {}", y)
    return y
Salin selepas log masuk
 # For more complex debugging, break out of JIT
def debug_values(x):
    print("Input:", x)
    result = debug_function(x)
    print("Output:", result)
    return result
    
Salin selepas log masuk
  • debug_function(x): This function shows how to use debug.print() for debugging inside a jit compiled function. In JAX, regular Python print statements are not allowed inside JIT due to compilation restrictions, so debug.print() is used instead.
  • It prints the shape of the input array x using debug.print()
  • After computing the sum of the elements of x, it prints the resulting sum using debug.print()
  • Finally, the function returns the computed sum y.
  • debug_values(x) function serves as a higher-level debugging approach, breaking out of the JIT context for more complex debugging. It first prints the inputs x using regular print statement. Then calls debug_function(x) to compute the result and finally prints the output before returning the results.

Output:

 print("===========================")
print(debug_function(jnp.array([1, 2, 3])))
print("===========================")
print(debug_values(jnp.array([1, 2, 3])))
Salin selepas log masuk

Panduan untuk Jax kilat cepat

This approach allows for a combination of in-JIT debugging with debug.print() and more detailed debugging outside of JIT using standard Python print statements.

Common Patterns and Idioms in JAX

Finally, we will explore common patterns and idioms in JAX that can help streamline your coding process and improve efficiency. Familiarizing yourself with these practices will aid in developing more robust and performant JAX applications.

Device Memory Management for Processing Large Datasets

 # 1. Device Memory Management
def process_large_data(data):
    # Process in chunks to manage memory
    chunk_size = 100
    results = []

    for i in range(0, len(data), chunk_size):
        chunk = data[i : i chunk_size]
        chunk_result = jit(process_chunk)(chunk)
        results.append(chunk_result)

    return jnp.concatenate(results)


def process_chunk(chunk):
    chunk_temp = jnp.sqrt(chunk)
    return chunk_temp
Salin selepas log masuk

This function processes large datasets in chunks to avoid overwhelming device memory.

It sets chunk_size to 100 and iterates over the data increments of the chunk size, processing each chunk separately.

For each chunk, the function uses jit(process_chunk) to JIT-compile the processing operation, which improves performance by compiling it ahead of time.

The result of each chunk is concatenated into a single array using jnp.concatenated(result) to form a single list.

Output:

 print("===========================")
data = jnp.arange(10000)
print(data.shape)

print("===========================")
print(data)

print("===========================")
print(process_large_data(data))
Salin selepas log masuk

Panduan untuk Jax kilat cepat

Handling Random Seed for Reproducibility and Better Data Generation

The function create_traing_state() demonstrates managing random number generators (RNGs) in JAX, which is essential for reproducibility and consistent results.

 # 2. Handling Random Seeds
def create_training_state(rng):
    # Split RNG for different uses
    rng, init_rng = jax.random.split(rng)
    params = init_network(init_rng)

    return params, rng # Return new RNG for next use
    
Salin selepas log masuk

It starts with an initial RNG (rng) and splits it into two new RNGs using jax.random.split(). Split RNGs perform different tasks: `init_rng` initializes network parameters, and the updated RNG returns for subsequent operations.

The function returns both the initialized network parameters and the new RNG for further use, ensuring proper handling of random states across different steps.

Now test the code using mock data

 def init_network(rng):
    # Initialize network parameters
    return {
        "w1": jax.random.normal(rng, (784, 256)),
        "b1": jax.random.normal(rng, (256,)),
        "w2": jax.random.normal(rng, (256, 10)),
        "b2": jax.random.normal(rng, (10,)),
    }


print("===========================")

key = jax.random.PRNGKey(0)
params, rng = create_training_state(key)


print(f"Random number generator: {rng}")

print(params.keys())

print("===========================")


print("===========================")
print(f"Network parameters shape: {params['w1'].shape}")

print("===========================")
print(f"Network parameters shape: {params['b1'].shape}")
print("===========================")
print(f"Network parameters shape: {params['w2'].shape}")

print("===========================")
print(f"Network parameters shape: {params['b2'].shape}")


print("===========================")
print(f"Network parameters: {params}")
Salin selepas log masuk

Output:

Panduan untuk Jax kilat cepat

Panduan untuk Jax kilat cepat

Using Static Arguments in JIT

 def g(x, n):
    i = 0
    while i <p> <strong>Output:</strong></p><pre class="brush:php;toolbar:false"> 30
Salin selepas log masuk

You can use a static argument if JIT compiles the function with the same arguments each time. This can be useful for the performance optimization of JAX functions.

 from functools import partial


@partial(jax.jit, static_argnames=["n"])
def g_jit_decorated(x, n):
    i = 0
    while i <p>If You want to use static arguments in JIT as a decorator you can use jit inside of functools. partial() function.</p><p> <strong>Output:</strong></p><pre class="brush:php;toolbar:false"> 30
Salin selepas log masuk

Now, we have learned and dived deep into many exciting concepts and tricks in JAX and overall programming style.

What's Next?

  • Experiment with Examples: Try to modify the code examples to learn more about JAX. Build a small project for a better understanding of JAX's transformations and APIs. Implement classical Machine Learning algorithms with JAX such as Logistic Regression, Support Vector Machine, and more.
  • Explore Advanced Topics : Parallel computing with pmap, Custom JAX transformations, Integration with other frameworks

All code used in this article is here

Kesimpulan

JAX is a powerful tool that provides a wide range of capabilities for machine learning, Deep Learning, and scientific computing. Start with basics, experimenting, and get help from JAX's beautiful documentation and community. There are so many things to learn and it will not be learned by just reading others' code you have to do it on your own. So, start creating a small project today in JAX. The key is to Keep Going, learn on the way.

Takeaways utama

  • Familiar NumPY-like interface and APIs make learning JAX easy for beginners. Most NumPY code works with minimal modifications.
  • JAX encourages clean functional programming patterns that lead to cleaner, more maintainable code and upgradation. But If developers want JAX fully compatible with Object Oriented paradigm.
  • What makes JAX's features so powerful is automatic differentiation and JAX's JIT compilation, which makes it efficient for large-scale data processing.
  • JAX excels in scientific computing, optimization, neural networks, simulation, and machine learning which makes developer easy to use on their respective project.

Soalan yang sering ditanya

Q1. What makes JAX different from NumPY?

A. Although JAX feels like NumPy, it adds automatic differentiation, JIT compilation, and GPU/TPU support.

S2. Do I need a GPU to use JAX?

A. In a single word big NO, though having a GPU can significantly speed up computation for larger data.

Q3. Is JAX a good alternative to NumPy?

A. Yes, You can use JAX as an alternative to NumPy, though JAX's APIs look familiar to NumPy JAX is more powerful if you use JAX's features well.

Q4. Can I use my existing NumPy code with JAX?

A. Most NumPy code can be adapted to JAX with minimal changes. Usually just changing import numpy as np to import jax.numpy as jnp.

S5. Is JAX harder to learn than NumPy?

A. The basics are just as easy as NumPy! Tell me one thing, will you find it hard after reading the above article and hands-on? I answered it for you. YES hard. Every framework, language, libraries is hard not because it is hard by design but because we don't give much time to explore it. Give it time to get your hand dirty it will be easier day by day.

Media yang ditunjukkan dalam artikel ini tidak dimiliki oleh Analytics Vidhya dan digunakan atas budi bicara penulis.

Atas ialah kandungan terperinci Panduan untuk Jax kilat cepat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan