> 기술 주변기기 > 일체 포함 > 번개 빠른 JAX에 대한 가이드

번개 빠른 JAX에 대한 가이드

Jennifer Aniston
풀어 주다: 2025-03-19 11:21:11
원래의
626명이 탐색했습니다.

이봐, 동료 파이썬 애호가! 당신은 당신의 numpy 코드가 초음속 속도로 실행되기를 바랐습니까? Jax를 만나십시오!. 기계 학습, 딥 러닝 및 수치 컴퓨팅 여행에서 새로운 가장 친한 친구. 초강대국으로 가득 찬 것으로 생각하십시오. 그라디언트를 자동으로 처리하고 JIT를 사용하여 빠르게 실행하도록 코드를 컴파일하고 땀을 흘리지 않고 GPU 및 TPU에서 실행할 수 있습니다. 신경망을 구축하거나 과학 데이터를 크 랜치 링하거나 변압기 모델 조정 또는 계산 속도를 높이려고하든 Jax는 등을 가지고 있습니다. 다이빙을하고 Jax를 특별하게 만드는 것을 보자.

이 안내서는 JAX 및 그 생태계에 대한 자세한 소개를 제공합니다.

학습 목표

  • Jax의 핵심 원칙과 Numpy와 어떻게 다른지 설명하십시오.
  • Python 코드를 최적화하기 위해 JAX의 세 가지 주요 변환을 적용하십시오. Numpy 작업을 효율적인 JAX 구현으로 변환하십시오.
  • JAX 코드에서 일반적인 성능 병목 현상을 식별하고 수정하십시오. 전형적인 함정을 피하면서 JIT 컴파일을 올바르게 구현하십시오.
  • JAX를 사용하여 신경망을 처음부터 신경망을 구축하고 훈련하십시오. JAX의 기능적 접근 방식을 사용하여 일반적인 기계 학습 작업을 구현하십시오.
  • JAX의 자동 차별화를 사용하여 최적화 문제를 해결하십시오. 효율적인 매트릭스 작업 및 수치 계산을 수행하십시오.
  • JAX 관련 문제에 대한 효과적인 디버깅 전략을 적용하십시오. 대규모 계산에 대한 메모리 효율적인 패턴을 구현하십시오.

이 기사는 Data Science Blogathon 의 일부로 출판되었습니다 .

목차

  • Jax는 무엇입니까?
  • Jax가 눈에 띄는 이유는 무엇입니까?
  • Jax를 시작합니다
  • Jax를 배우는 이유는 무엇입니까?
  • 필수 JAX 변환
  • JAX로 신경망 구축
  • 모범 사례 및 팁
  • 성능 최적화
  • 디버깅 전략
  • Jax의 일반적인 패턴과 관용구
  • 다음은 무엇입니까?
  • 결론
  • 자주 묻는 질문

Jax는 무엇입니까?

공식 문서에 따르면 Jax는 고성능 수치 컴퓨팅 및 대규모 기계 학습을 위해 설계된 가속 지향 배열 계산 및 프로그램 변환을위한 파이썬 라이브러리입니다. 따라서 Jax는 본질적으로 스테로이드에 흠이 없으며 친숙한 Numpy 스타일의 작동과 자동 차별화 및 하드웨어 가속도를 결합합니다. 세상을 최대한 활용하는 것으로 생각하십시오.

  • Numpy의 우아한 구문 및 배열 작동
  • 자동 차별화 기능을 좋아 합니다
  • 하드웨어 가속 및 컴파일 혜택을위한 XLA (가속 선형 대수).

Jax가 눈에 띄는 이유는 무엇입니까?

Jax를 차별화하는 것은 변형입니다. 이들은 파이썬 코드를 수정할 수있는 강력한 기능입니다.

  • JIT : 더 빠른 실행을위한 정시 컴파일
  • GRAD : 컴퓨팅 그라디언트를위한 자동 차별화
  • VMAP : 배치 처리를위한 자동 벡터화

다음은 빠른 모습입니다.

 jax.numpy를 JNP로 가져옵니다
Jax Import Grad, Jit에서
# 간단한 기능을 정의하십시오
@jit # 컴파일로 속도를 높이십시오
def square_sum (x) :
return jnp.sum (jnp.square (x))
# 그라디언트 기능을 자동으로 가져옵니다
gradient_fn = Grad (square_sum)
# 시도해보십시오
x = jnp.array ([1.0, 2.0, 3.0])
print (f "gradient : {gradient_fn (x)}")
로그인 후 복사

산출:

 구배 : [2. 4. 6.]
로그인 후 복사

Jax를 시작합니다

아래에서 우리는 Jax를 시작하기위한 몇 가지 단계를 따를 것입니다.

1 단계 : 설치

JAX를 설정하는 것은 CPU 전용 사용을 위해 간단합니다. 자세한 내용은 JAX 문서를 사용할 수 있습니다.

2 단계 : 프로젝트를위한 환경 생성

프로젝트를위한 콘다 환경을 만듭니다

 # Jax를위한 콘다 env를 만듭니다
$ conda create -name jaxdev python = 3.11

#env를 활성화하십시오
$ Conda는 jaxdev를 활성화합니다

# 프로젝트 생성 DIR 이름 JAX101
$ mkdir jax101

# DIR로 가십시오
$ cd jax101
로그인 후 복사

3 단계 : JAX 설치

새로 생성 된 환경에서 JAX 설치

 # CPU의 경우
PIP 설치 -업그레이드 PIP
PIP 설치 -업그레이드 "JAX"

# GPU의 경우
PIP 설치 -업그레이드 PIP
PIP 설치 -업그레이드 "JAX [CUDA12]
로그인 후 복사

이제 당신은 실제 일로 뛰어들 준비가되었습니다. 실용적인 코딩에 손이 더러워지기 전에 몇 가지 새로운 개념을 배우겠습니다. 나는 개념을 먼저 설명하고 실용적인 관점을 이해하기 위해 함께 코드 할 것입니다.

먼저, 동기 부여를 얻으십시오. 그건 그렇고, 왜 우리는 새로운 도서관을 다시 배우는가? 이 가이드 전체에서 그 질문에 가능한 한 간단하게 단계별로 대답 할 것입니다.

Jax를 배우는 이유는 무엇입니까?

Jax를 전동 공구로 생각하십시오. Numpy는 신뢰할 수있는 손 톱과 같지만 Jax는 현대 전기 톱과 같습니다. 약간 더 많은 단계와 지식이 필요하지만 성능 이점은 집중적 인 계산 작업에 가치가 있습니다.

  • 성능 : JAX 코드는 특히 GPU 및 TPU에서 순수한 파이썬 또는 Numpy 코드보다 훨씬 빠르게 실행될 수 있습니다.
  • 유연성 : 기계 학습만을위한 것이 아닙니다. JAX는 과학 컴퓨팅, 최적화 및 시뮬레이션에서 탁월합니다.
  • 현대적인 접근법 : JAX는 클리너적이고 유지 가능한 코드로 이어지는 기능적 프로그래밍 패턴을 장려합니다.

다음 섹션에서는 JIT 컴파일을 시작으로 Jax의 변환에 깊이 빠져들게됩니다. 이러한 변형은 Jax에게 초강대국을 부여하며이를 이해하는 것은 Jax를 효과적으로 활용하는 데 핵심입니다.

필수 JAX 변환

Jax의 변환은 Numpy 또는 Scipy와 같은 수치 계산 라이브러리와 차별화되는 것입니다. 각각을 탐색하고 코드를 어떻게 충전 할 수 있는지 살펴 보겠습니다.

JIT 또는 정시 컴파일

정시 컴파일은 미리가 아니라 런타임에 프로그램의 부품을 컴파일하여 코드 실행을 최적화합니다.

JIT는 JAX에서 어떻게 작동합니까?

Jax에서 Jax.jit은 Python 함수를 JIT 컴파일 버전으로 변환합니다. @jax.jit로 함수를 장식하면 실행 그래프를 캡처하고 최적화하며 XLA를 사용하여 컴파일합니다. 컴파일 된 버전은 실행되어 특히 반복 된 기능 호출에 대해 상당한 속도를 제공합니다.

다음은 시도 할 수있는 방법입니다.

 jax.numpy를 JNP로 가져옵니다
JAX 가져 오기 JIT에서
수입 시간


# 계산 집중 기능
def slow_function (x) :
    _ 범위 (1000)의 경우 :
        x = jnp.sin (x) jnp.cos (x)
    반환 x


# JIT와 동일한 기능입니다
@jit
def fast_function (x) :
    _ 범위 (1000)의 경우 :
        x = jnp.sin (x) jnp.cos (x)
    반환 x
로그인 후 복사

여기에 동일한 기능이 있습니다. 하나는 단지 일반 파이썬 컴파일 프로세스이고 다른 하나는 JAX의 JIT 컴파일 프로세스로 사용됩니다. 사인 및 코사인 함수의 1000 개의 데이터 포인트 합계를 계산합니다. 우리는 시간을 사용하여 성능을 비교할 것입니다.

 # 성능 비교
x = jnp.arange (1000)

# 워밍업 JIT
fast_function (x) # 첫 번째 호출은 함수를 컴파일합니다

# 시간 비교
start = time.time ()
slow_result = slow_function (x)
print (f "jit없이 : {time.time () - 시작 : .4f} seconds")

start = time.time ()
fast_result = fast_function (x)
print (f "with jit : {time.time () - 시작 : .4f} seconds")
로그인 후 복사

결과는 당신을 놀라게 할 것입니다. JIT 컴파일은 일반 편집보다 333 배 빠릅니다. 자전거를 Buggati Chiron과 비교하는 것과 같습니다.

산출:

 JIT없이 : 0.0330 초
JIT : 0.0010 초
로그인 후 복사

JIT는 당신에게 초고속 실행 부스트를 제공 할 수 있지만, 그렇지 않으면 슈퍼카 시설을 제공하지 않는 진흙 투성이의 마을 도로에서 부가티를 운전하는 것과 같습니다.

일반적인 JIT 함정

JIT는 정적 모양 및 유형에서 가장 잘 작동합니다. 배열 값에 의존하는 Python 루프 및 조건을 사용하지 마십시오. JIT는 동적 배열과 함께 작동하지 않습니다.

 # BAD- 파이썬 제어 흐름을 사용합니다
@jit
def bad_function (x) :
    If x [0]> 0 : # jit과 잘 작동하지 않습니다.
        반환 x
    반환 -X


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


# 양호 - JAX 제어 흐름을 사용합니다
@jit
def good_function (x) :
    jnp.where (x [0]> 0, x, -x) # jax -native 조건을 반환합니다


print (good_function (jnp.array ([1, 2, 3])))
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

즉, JIT가 계산 중에 X 값에 없기 때문에 BAD_Function이 나쁘다는 것을 의미합니다.

산출:

 [1 2 3]
로그인 후 복사

제한 및 고려 사항

  • 컴파일 오버 헤드 : JIT 컴파일 함수가 처음 실행되면 컴파일로 인해 약간의 오버 헤드가 있습니다. 컴파일 비용은 작은 기능 또는 한 번만 호출되는 성능 이점을 능가 할 수 있습니다.
  • 동적 파이썬 기능 : JAX의 JIT에는 기능이 "정적" 이어야합니다. Python 루프를 기반으로 한 모양 또는 값 변경과 같은 동적 제어 흐름은 컴파일 된 코드에서 지원되지 않습니다. Jax는 동적 제어 흐름을 처리하기 위해`jax.lax.cond` 및`jax.lax.scan`와 같은 대안을 제공했습니다.

자동 차별화

자동 차별화 또는 자동 도식은 기능의 미분을 정확하고 효과적으로 계산하기위한 계산 기술입니다. 기계 학습 모델을 최적화하는 데 중요한 역할을합니다. 특히 교육을 사용하여 그라디언트가 모델 매개 변수를 업데이트하는 데 사용됩니다.

번개 빠른 JAX에 대한 가이드

JAX에서 자동 차별화는 어떻게 작동합니까?

AutoDiff는 복잡한 기능을 더 간단한 기능으로 분해하여 이러한 하위 기능의 파생물을 계산 한 다음 결과를 결합하여 미적분학의 체인 규칙을 적용하여 작동합니다. 함수 실행 중 각 작업을 기록하여 계산 그래프를 구성 한 다음 파생 상품을 자동으로 계산하는 데 사용됩니다.

Auto-Diff의 두 가지 주요 모드가 있습니다.

  • 전방 모드 : 컴퓨팅 그래프를 통해 단일 전방 패스로 파생 상품을 계산하며, 소수의 매개 변수로 기능에 효율적입니다.
  • 리버스 모드 : 컴퓨팅 그래프를 통해 단일 후진 통과로 파생 상품을 계산하며, 많은 매개 변수와 기능에 효율적입니다.

번개 빠른 JAX에 대한 가이드

JAX 자동 차별화의 주요 기능

  • 그라디언트 계산 (Jax.grad) : `jax.grad`는 입력에 대한 스케일러 출력 함수의 파생물을 계산합니다. 다중 입력이있는 함수의 경우 부분 미분을 얻을 수 있습니다.
  • 고차 미분 (Jax.jacobian, Jax.hessian) : Jax는 Jacobians 및 Hessains와 같은 고차 미분의 계산을 지원하므로 고급 최적화 및 물리 시뮬레이션에 적합합니다.
  • 다른 JAX 변환과의 합성 가능성 : JAX의 AutoDiff는`jax.jit` 및`jax.vmap`과 같은 다른 변환과 완벽하게 통합되어 효율적이고 확장 가능한 계산이 가능합니다.
  • Reverse-Mode Differentiation (Backpropagation) : Jax의 자동 디프는 스케일러 출력 함수에 리버스 모드 차별화를 사용하여 딥 러닝 작업에 매우 효과적입니다.
 jax.numpy를 JNP로 가져옵니다
JAX Import Grad, Value_and_grad에서


# 간단한 신경 네트워크 계층을 정의하십시오
DEF 계층 (PARAMS, X) :
    무게, 바이어스 = 매개 변수
    jnp.dot (x, weight) 바이어스를 반환합니다


# 스칼라 값 손실 함수를 정의하십시오
def loss_fn (params, x) :
    출력 = 레이어 (Params, x)
    jnp.sum (output) # 스칼라로 줄입니다


# 출력과 그라디언트를 모두 얻으십시오
layer_grad = grad (loss_fn, argnums = 0) # 매개 변수에 대한 그라디언트
layer_value_and_grad = value_and_grad (loss_fn, argnums = 0) # 값과 그라디언트 모두

# 예제 사용
key = jax.random.prngkey (0)
x = jax.random.normal (키, (3, 4))
weight = jax.random.normal (키, (4, 2))
bias = jax.random.normal (키, (2,))

# 계산
grads = layer_grad ((무게, 바이어스), x)
출력, Grads = Layer_Value_and_grad ((무게, 바이어스), x)

# 다중 파생 상품이 쉽습니다
두 번 _grad = grad (grad (jnp.sin))
x = jnp.array (2.0)
print (f "x = 2 : {twole_grad (x)}에서 sin의 두 번째 파생물
로그인 후 복사

산출:

 x = 2 : -0.9092974066734314에서 죄의 2 차 미분
로그인 후 복사

Jax의 효율성

  • 효율성 : JAX의 자동 차별화는 XLA와의 통합으로 인해 매우 효율적이므로 기계 코드 수준에서 최적화 할 수 있습니다.
  • Composability : 다양한 변환을 결합하는 기능으로 인해 JAX는 복잡한 기계 학습 파이프 라인 및 CNN, RNN 및 변압기와 같은 신경망 아키텍처를 구축하기위한 강력한 도구입니다.
  • 사용 편의성 : Autodiff 용 Jax의 구문은 간단하고 직관적이므로 사용자는 XLA 및 복잡한 라이브러리 API의 세부 사항을 파악하지 않고도 그라디언트를 계산할 수 있습니다.

JAX 벡터 매핑

JAX에서`vmap`은 계산을 자동으로 벡터화하는 강력한 기능으로, 루프를 수동으로 쓰지 않고 데이터 배치에 대한 기능을 적용 할 수 있습니다. 배열 축 (또는 다중 축)에 대한 함수를 매핑하고 효율적으로 병렬로 평가하여 성능이 크게 향상 될 수 있습니다.

JAX에서 VMAP는 어떻게 작동합니까?

VMAP 함수는 계산의 효율을 유지하면서 입력 배열의 지정된 축을 따라 각 요소에 함수를 적용하는 프로세스를 자동화합니다. 주어진 함수를 변환하여 배치 된 입력을 수락하고 벡터화 된 방식으로 계산을 실행합니다.

VMAP는 명시 적 루프를 사용하는 대신 입력 축을 통해 벡터화하여 작업을 병렬로 수행 할 수 있도록합니다. 이는 하드웨어의 SIMD (단일 명령어, 다중 데이터) 작업을 수행 할 수있는 기능을 활용하여 상당한 속도를 초래할 수 있습니다.

VMAP의 주요 기능

  • 자동 벡터화 : VAMP는 계산의 배치를 자동화하여 원래 함수 로직을 변경하지 않고 배치 치수를 통해 코드를 병렬화하는 것이 간단합니다.
  • 다른 변환과의 합성 가능성 : JAX.Grade for Differentiation 및 Jax.jit과 같은 다른 JAX 변환과 완벽하게 작동하여 최적화되고 유연한 코드가 가능합니다.
  • 다중 배치 치수 처리 : VMAP는 다중 입력 배열 또는 축에 대한 매핑을 지원하므로 다차원 데이터 또는 다중 변수를 동시에 처리하는 것과 같은 다양한 사용 사례의 경우 다재다능합니다.
 jax.numpy를 JNP로 가져옵니다
JAX 가져 오기 VMAP에서


# 단일 입력에서 작동하는 함수
def single_input_fn (x) :
    jnp.sin (x) jnp.cos (x)를 반환합니다.


# 배치에서 작동하도록 벡터화하십시오
batch_fn = vmap (single_input_fn)

# 성능 비교
x = jnp.arange (1000)

# VMAP없이 (목록 이해력 사용)
result1 = jnp.array (xi의 xi에 대한 [Single_Input_fn (xi))))

# vmap과 함께
result2 = batch_fn (x) # 훨씬 더 빠릅니다!


# 여러 인수를 벡터화합니다
def two_input_fn (x, y) :
    x * jnp.sin (y) 반환


# 두 입력을 통해 벡터화합니다
vectorized_fn = vmap (2_input_fn, in_axes = (0, 0))

# 또는 첫 번째 입력만으로 벡터화하십시오
particile_vectorized_fn = vmap (2_input_fn, in_axes = (0, none)))


# 인쇄
print (result1. shape)
print (result2. shape)
print (partically_vectorized_fn (x, y) .shape)
로그인 후 복사

산출:

 (1000,)
(1000,)
(1000,3)
로그인 후 복사

JAX에서 VMAP의 효과

  • 성능 향상 : 계산을 벡터화함으로써 VMAP는 GPU 및 TPU (텐서 처리 장치)와 같은 최신 하드웨어의 병렬 처리 기능을 활용하여 실행 속도를 크게 높일 수 있습니다.
  • 클리너 코드 : 수동 루프의 필요성을 제거하여 간결하고 읽기 쉬운 코드가 가능합니다.
  • JAX 및 AutoDiff와의 호환성 : VMAP는 자동 차별화 (JAX.Grad)와 결합하여 데이터 배치에 대한 미분의 효율적인 계산을 허용 할 수 있습니다.

각 변환을 사용하는시기

@jit를 사용하여 :

  • 기능은 유사한 입력 모양으로 여러 번 호출됩니다.
  • 이 기능에는 무거운 수치 계산이 포함되어 있습니다.

다음과 같은 grad 사용

  • 최적화를 위해서는 파생 상품이 필요합니다.
  • 머신 러닝 알고리즘 구현
  • 시뮬레이션을위한 미분 방정식 해결

다음과 같은 경우 vmap을 사용하십시오.

  • 데이터 배치 처리.
  • 병렬 계산
  • 명백한 루프를 피합니다

JAX를 사용한 매트릭스 작동 및 선형 대수

JAX는 매트릭스 작업 및 선형 대수에 대한 포괄적 인 지원을 제공하여 과학 컴퓨팅, 머신 러닝 및 수치 최적화 작업에 적합합니다. Jax의 선형 대수 기능은 Numpy와 같은 라이브러리에서 발견되는 것과 유사하지만 자동 차별화 및 최적화 된 성능을위한 정시 컴파일과 같은 추가 기능이 있습니다.

매트릭스 첨가 및 뺄셈

이 작업은 같은 모양의 요소 별 행렬로 수행됩니다.

 # 1 매트릭스 추가 및 뺄셈 :

jax.numpy를 JNP로 가져옵니다

a = jnp.array ([[1, 2], [3, 4]))
b = jnp.array ([[5, 6], [7, 8]))

# 매트릭스 추가
C = AB
# 매트릭스 뺄셈
d = a -b

print (f "행렬 A : \ n {a}")
print ( "============================")).
print (f "matrix b : \ n {b}")
print ( "============================")).
print (f "ab의 행렬 옆 : \ n {c}")
print ( "============================")).
print (f "ab의 행렬 기판 : \ n {d}")
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

매트릭스 곱셈

JAX는 요소 별 곱셈과 DOR 제품 기반 매트릭스 곱셈을 모두 지원합니다.

 # 요소 별 곱셈
e = a * b

# 매트릭스 곱셈 (도트 제품)
f = jnp.dot (a, b)

print (f "행렬 A : \ n {a}")
print ( "============================")).
print (f "matrix b : \ n {b}")
print ( "============================")).
print (f "a*b : \ n {e}의 요소 별 곱셈")
print ( "============================")).
print (f "a*b : \ n {f}의 행렬 곱셈"))
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

매트릭스가 전달됩니다

`jnp.transpose ()`을 사용하여 행렬의 전환을 얻을 수 있습니다.

 # Matric Transpose
g = jnp.transpose (a)

print (f "행렬 A : \ n {a}")
print ( "============================")).
print (f "매트릭스 a : \ n {g}")
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

매트릭스 역수

Jax는`jnp.linalg.inv ()`을 사용하여 행렬 역전 기능을 제공합니다

 # Matric 반전
h = jnp.linalg.inv (a)

print (f "행렬 A : \ n {a}")
print ( "============================")).
print (f "매트릭스 반전 a : \ n {h}")
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

매트릭스 결정 요인

매트릭스의 결정 요인은`jnp.linalg.det ()`을 사용하여 계산할 수 있습니다.

 # 매트릭스 결정 요인
det_a = jnp.linalg.det (a)

print (f "행렬 A : \ n {a}")
print ( "============================")).
print (f "행렬 결정 인자 : \ n {det_a}")
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

매트릭스 고유 값 및 고유 벡터

`jnp.linalg.eigh ()`를 사용하여 행렬의 고유 값과 고유 벡터를 계산할 수 있습니다.

 # 고유 값 및 고유 벡터
jax.numpy를 JNP로 가져옵니다

a = jnp.array ([[1, 2], [3, 4]))
고유 값, 고유 벡터 = jnp.linalg.eigh (a)

print (f "행렬 A : \ n {a}")
print ( "============================")).
print (f "a : \ n {eigenValues}")
print ( "============================")).
print (f "a : \ n {eigenvectors}의 고유 벡터")
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

매트릭스 단일 값 분해

SVD는`jnp.linalg.svd`를 통해 지원되며, 차원 감소 및 매트릭스 인수화에 유용합니다.

 # 단일 가치 분해 (SVD)

jax.numpy를 JNP로 가져옵니다

a = jnp.array ([[1, 2], [3, 4]))
u, s, v = jnp.linalg.svd (a)

print (f "행렬 A : \ n {a}")
print ( "============================")).
print (f "matrix u : \ n {u}")
print ( "============================")).
print (f "matrix s : \ n {s}")
print ( "============================")).
print (f "matrix v : \ n {v}")
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

선형 방정식의 해결 시스템

선형 방정식 AX = B 시스템을 해결하기 위해`jnp.linalg.solve ()`을 사용합니다. 여기서 A는 제곱 행렬이고 B는 동일한 수의 행의 벡터 또는 매트릭스입니다.

 # 선형 방정식의 해결 시스템
jax.numpy를 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)

print (f "값 x : {x}")
로그인 후 복사

산출:

 X의 값 : [1.8 1.4]
로그인 후 복사

매트릭스 함수의 그라디언트 계산

JAX의 자동 차별화를 사용하면 매트릭스와 관련하여 스칼라 함수의 기울기를 계산할 수 있습니다.
아래 함수의 기울기와 x의 값을 계산합니다.

기능

번개 빠른 JAX에 대한 가이드

 # 매트릭스 함수의 그라디언트 계산
Jax를 가져옵니다
jax.numpy를 JNP로 가져옵니다


def matrix_function (x) :
    jnp.sum을 반환합니다 (jnp.sin (x) x ** 2)


# 함수의 졸업생을 계산합니다
grad_f = jax.grad (matrix_function)

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

print (f "matrix x : \ n {x}")
print ( "============================")).
print (f "matrix_function의 그라디언트 : \ n {gradient}")
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

수치 컴퓨팅, 머신 러닝 및 물리 계산에 사용되는 JAX의 가장 유용한 기능. 당신이 탐험 할 더 많은 남은 것이 있습니다.

JAX와의 과학 컴퓨팅

JAX의 과학 컴퓨팅을위한 강력한 라이브러리 인 JAX는 JIT 컴파일, 자동 차별화, 벡터화, 병렬화 및 GPU-TPU 가속도와 같은 사전 기능을위한 과학 컴퓨팅에 가장 좋습니다. JAX의 고성능 컴퓨팅을 지원하는 능력은 물리 시뮬레이션, 머신 러닝, 최적화 및 수치 분석을 포함한 광범위한 과학 응용 프로그램에 적합합니다.

이 섹션에서 최적화 문제를 살펴 보겠습니다.

최적화 문제

아래의 최적화 문제 단계를 살펴 보겠습니다.

1 단계 : 기능을 최소화 할 (또는 문제)를 정의합니다.

 # 최소화 할 함수 정의 (예 : Rosenbrock 함수)

@jit

Def Rosenbrock (x) :

반환 합 (100.0 * (x [1 :] - x [: -1] ** 2.0) ** 2.0 (1 -x [: -1]) ** 2.0)
로그인 후 복사

여기에서 Rosenbrock 함수가 정의되어 최적화에서 일반적인 테스트 문제입니다. 이 함수는 배열 x를 입력으로 사용하고 함수의 글로벌 최소에서 X가 얼마나 멀리 떨어져 있는지를 나타내는 밸리를 계산합니다. @jit 데코레이터는 Jut-In-Time 컴파일을 가능하게하는 데 사용되며 CPU 및 GPU에서 기능을 효율적으로 실행하도록 기능을 컴파일하여 계산 속도를 높입니다.

2 단계 : 그라디언트 하강 단계 구현

 # 그라디언트 하강 최적화

@jit

def gradient_descent_step (X, Learning_Rate) :

반환 x -learning_rate * Grad (Rosenbrock) (x)
로그인 후 복사

이 함수는 그라디언트 하강 최적화의 단일 단계를 수행합니다. Rosenbrock 함수의 기울기는 Grad (Rosenbrock) (x)를 사용하여 계산되며, 이는 x에 대한 유도체를 제공합니다. X의 새 값은 chaintraction으로 업데이트됩니다.

3 단계 : 최적화 루프 실행

 # 최적화
x = jnp.array ([0.0, 0.0]) # 시작점

Learning_rate = 0.001

IN RANGE (2000)의 경우 :

x = gradient_descent_step (X, Learning_rate)

I % 100 == 0이면 :

print (f "step {i}, 값 : {Rosenbrock (x) :. 4f}")
로그인 후 복사

최적화 루프는 출발점 X를 초기화하고 1000 개의 구배 하강을 수행합니다. 각 반복에서 Gradient_descent_step 기능은 현재 기울기를 기반으로 업데이트됩니다. 100 단계마다, 현재 단계 번호 및 x에서 Rosenbrock 함수의 값이 인쇄되어 최적화의 진행 상황을 제공합니다.

산출:

번개 빠른 JAX에 대한 가이드

JAX의 실제 물리 문제 해결

우리는 물리적 시스템을 시뮬레이션하여 감쇠 된 고조파 발진기의 움직임을 시뮬레이션합니다.이 고조파 오실레이터의 움직임은 마찰, 차량의 충격 흡수 장치 또는 전기 회로의 진동과 같은 대량 스프링 시스템과 같은 것을 모델링합니다. 좋지 않습니까? 하자.

1 단계 : 매개 변수 정의

 Jax를 가져옵니다
jax.numpy를 JNP로 가져옵니다


# 정의 매개 변수
질량 = 1.0 # 물체의 질량 (kg)
댐핑 = 0.1 # 댐핑 계수 (kg/s)
spring_constant = 1.0 # 스프링 상수 (N/M)

# 시간 단계와 총 시간을 정의하십시오
dt = 0.01 # 시간 단계 (들)
num_steps = 3000 # 단계 수
로그인 후 복사

질량, 댐핑 계수 및 스프링 상수가 정의됩니다. 이들은 감쇠 된 고조파 발진기의 물리적 특성을 결정합니다.

2 단계 : ODE 정의

 # ODE 시스템을 정의하십시오
def damped_harmonic_oscillator (state, t) :
    "" "감쇠 고조파 발진기의 파생 상품을 계산하십시오.

    상태 : 위치와 속도를 포함하는 배열 [X, V]
    T : 시간 (이 자율 시스템에서 사용되지 않음)
    "" "
    x, v = 상태
    dxdt = v
    dvdt = -damping / mass * v -spring_constant / mass * x
    return jnp.array ([dxdt, dvdt])
로그인 후 복사

감쇠 된 고조파 오실레이터 함수는 동적 시스템을 나타내는 발진기의 위치와 속도의 유도체를 정의합니다.

3 단계 : Euler의 방법

 # Euler의 방법을 사용하여 ODE를 해결하십시오
def euler_step (state, t, dt) :
    "" "Euler의 방법의 한 단계를 수행하십시오." "" "" "" "" "" "" "" "" "" "" "" "한 단계
    파생 상품 = damped_harmonic_oscillator (state, t)
    반환 상태 파생 상품 * DT
로그인 후 복사

간단한 수치 방법은 ODE를 해결하는 데 사용됩니다. 다음은 현재 상태와 파생 상품에 기초하여 다음 단계에서 상태에 근사합니다.

4 단계 : 시간 진화 루프

 # 초기 상태 : [위치, 속도]
initial_state = jnp.array ([1.0, 0.0]) # 질량으로 x = 1, v = 0으로 시작합니다.

# 시간 진화
states = [initial_state]
시간 = 0.0
범위의 단계 (num_steps) :
    next_state = euler_step (states [-1], Time, DT)
    States.Append (next_state)
    시간 = dt

# 상태 목록을 분석을 위해 JAX 배열로 변환
states = jnp.stack (상태)
로그인 후 복사

루프는 지정된 시간 단계를 통해 반복되어 Euler의 방법을 사용하여 각 단계에서 상태를 업데이트합니다.

산출:

번개 빠른 JAX에 대한 가이드

5 단계 : 결과를 플로팅합니다

마지막으로, 우리는 감쇠 된 고조파 발진기의 거동을 시각화하기 위해 결과를 플로팅 할 수 있습니다.

 # 결과를 플로팅합니다
matplotlib.pyplot을 plt로 가져옵니다

plt.style.use ( "ggplot")

위치 = 상태 [:, 0]
속도 = 상태 [:, 1]
time_points = jnp.arange (0, (num_steps 1) * dt, dt)

plt.figure (figsize = (12, 6))
Subplot (2, 1, 1)
plt.plot (time_points, 위치, 레이블 = "위치")
plt.xlabel ( "시간")
plt.ylabel ( "위치 (m)")
plt.legend ()

Subplot (2, 1, 2)
plt.plot (time_points, velocities, label = "velocity", color = "Orange")
plt.xlabel ( "시간")
plt.ylabel ( "속도 (m/s)")
plt.legend ()

plt.tight_layout ()
plt.show ()
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

나는 당신이 JAX로 신경망을 어떻게 구축 할 수 있는지를보고 싶어한다는 것을 알고 있습니다. 그래서, 그것에 깊이 빠져들겠습니다.

여기서 값이 점차 최소화되었음을 알 수 있습니다.

JAX로 신경망 구축

JAX는 고성능 수치 컴퓨팅과 Numpy와 같은 구문을 쉽게 사용하는 데있어 강력한 라이브러리입니다. 이 섹션에서는 JAX를 사용하여 신경망을 구성하는 프로세스를 안내하여 자동 차별화 및 정시 컴파일을위한 고급 기능을 활용하여 성능을 최적화합니다.

1 단계 : 라이브러리 가져 오기

신경망을 구축하기 전에 필요한 라이브러리를 가져와야합니다. JAX는 효율적인 수치 계산을 생성하기위한 일련의 도구를 제공하며 추가 라이브러리는 결과의 최적화 및 시각화를 지원합니다.

 Jax를 가져옵니다
jax.numpy를 JNP로 가져옵니다
Jax Import Grad, Jit에서
Jax.random import Prngkey, Normal에서
Optax # Jax의 최적화 라이브러리를 가져옵니다
matplotlib.pyplot을 plt로 가져옵니다
로그인 후 복사

2 단계 : 모델 레이어 생성

효과적인 모델 계층을 만드는 것은 신경망의 아키텍처를 정의하는 데 중요합니다. 이 단계에서는 밀도가 높은 레이어의 매개 변수를 초기화하여 모델이 효과적인 학습을 위해 잘 정의 된 가중치 및 편견으로 시작하도록합니다.

 def init_layer_params (key, n_in, n_out) :
    "" "단일 조밀 한 계층의 매개 변수 초기화" ""
    key_w, key_b = jax.random.split (key)
    # 초기화
    w = 정상 (key_w, (n_in, n_out)) * jnp.sqrt (2.0 / n_in)  
    b = 정상 (key_b, (n_out,)) * 0.1
    반환 (w, b)
    
def relu (x) :
    "" "Relu 활성화 기능" ""
    jnp.maximum (0, x)을 반환합니다.
    
로그인 후 복사
  • 초기화 기능 : init_layer_params는 체중에 대한 초기화 및 바이어스에 대한 작은 값을 사용하여 밀도가 높은 레이어의 가중치 (W) 및 바이어스 (b)를 초기화합니다 (b). 그 또는 Kaiming He 초기화는 Relu 활성화 기능을 갖는 계층에서 더 잘 작동하며, Xavier 초기화와 같은 다른 인기있는 초기화 방법이 있으며 Sigmoid 활성화가있는 층에 더 잘 작동합니다.
  • 활성화 기능 : Relu 함수는 Relu 활성화 함수를 입력에 적용하여 음수 값을 0으로 설정합니다.

3 단계 : 전방 패스 정의

포워드 패스는 입력 데이터가 네트워크를 통해 출력을 생성하는 방법을 지시하기 때문에 신경망의 초석입니다. 여기서는 초기 레이어를 통해 입력 데이터로 변환을 적용하여 모델의 출력을 계산하는 메소드를 정의합니다.

 def forward (params, x) :
    "" "2 층 신경망의 전진 패스" "" "" "" "" "" "" "" "" "" "" ""신경 네트워크 ""
    (W1, B1), (W2, B2) = 매개 변수
    # 첫 번째 레이어
    H1 = Relu (jnp.dot (x, w1) b1)
    # 출력 계층
    logits = jnp.dot (H1, W2) B2
    리턴 로짓
    
로그인 후 복사
  • 포워드 패스 : Forward는 선형 변환과 Relu 및 기타 선형 변환을 적용하여 출력 (로이트)을 계산하는 2 층 신경망을 통해 전방 패스를 수행합니다.

S TEP4 : 손실 함수 정의

잘 정의 된 손실 기능은 모델의 교육을 안내하는 데 필수적입니다. 이 단계에서는 평균 제곱 오차 (MSE) 손실 함수를 구현하여 예측 된 출력이 목표 값과 얼마나 잘 일치하는지 측정하여 모델을 효과적으로 학습 할 수 있습니다.

 def loss_fn (params, x, y) :
    "" "평균 제곱 오류 손실" "" "" "
    pred = promper (params, x)
    jnp.mean ((Pred -Y) ** 2)를 반환합니다.
로그인 후 복사
  • 손실 기능 : Loss_FN은 예측 된 로이트와 대상 레이블 (y) 사이의 평균 제곱 오차 (MSE) 손실을 계산합니다.

5 단계 : 모델 초기화

모델 아키텍처 및 손실 기능이 정의되면 이제 모델 초기화로 전환합니다. 이 단계에는 신경망의 매개 변수를 설정하여 각 계층이 무작위이지만 적절하게 스케일링 된 가중치와 바이어스로 훈련 프로세스를 시작할 준비가되도록합니다.

 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),
    ]]
    반환 매개 변수
    
로그인 후 복사
  • 모델 초기화 : init_model은 신경망의 두 층에 대한 가중치와 바이어스를 초기화합니다. 각 레이어의 매개 변수 초기화에 대해 두 개의 개별 랜덤 키를 사용합니다.

6 단계 : 훈련 단계

신경망을 훈련하려면 손실 함수의 계산 된 그라디언트를 기반으로 매개 변수에 대한 반복 업데이트가 포함됩니다. 이 단계에서는 이러한 업데이트를 효율적으로 적용하는 교육 기능을 구현하여 모델이 여러 에포크를 통해 데이터를 통해 배울 수 있습니다.

 @jit
def train_step (params, opt_state, x_batch, y_batch) :
    손실, grads = jax.value_and_grad (loss_fn) (params, x_batch, y_batch)
    업데이트, opt_state = Optimizer.update (Grads, opt_state)
    params = optax.apply_updates (Params, 업데이트)
    반환 매개 변수, opt_state, 손실
로그인 후 복사
  • 교육 단계 : Train_Step 함수는 단일 기울기 하강 업데이트를 수행합니다.
  • 함수 값과 기타 그라디언트를 모두 계산하는 Value_and_grad를 사용하여 손실 및 기울기를 계산합니다.
  • Optimizer 업데이트가 계산되고 모델 매개 변수가 그에 따라 업데이트됩니다.
  • 성능을 위해 JIT 컴파일됩니다.

Step7 : 데이터 및 교육 루프

모델을 효과적으로 교육하려면 적절한 데이터를 생성하고 교육 루프를 구현해야합니다. 이 섹션에서는 예제에 대한 합성 데이터를 만드는 방법과 여러 배치 및 에포크에서 교육 프로세스를 관리하는 방법을 다룹니다.

 # 일부 예제 데이터를 생성합니다
key = prngkey (0)
x_data = 정상 (키, (1000, 10)) # 1000 샘플, 10 개의 기능
y_data = jnp.sum (x_data ** 2, axis = 1, keepdims = true) # 간단한 비선형 함수

# 모델 및 최적화를 초기화합니다
params = init_model (key, input_dim = 10, hidden_dim = 32, output_dim = 1)
Optimizer = Optax.adam (Learning_rate = 0.001)
opt_state = implizer.init (params)

# 훈련 루프
batch_size = 32
num_epochs = 100
num_batches = x_data.shape [0] // batch_size

# epoch 및 손실 값을 저장하는 배열
epoch_array = []
loss_array = []

범위의 Epoch (num_epochs) :
    epoch_loss = 0.0
    배치 범위 (NUM_BATCHES) :
        idx = jax.random.permutation (key, batch_size)
        x_batch = x_data [idx]
        y_batch = y_data [idx]
        매개 변수, opt_state, loss = train_step (params, opt_state, x_batch, y_batch)
        epoch_loss = 손실

    # 시대의 평균 손실을 저장하십시오
    avg_loss = epoch_loss / num_batches
    epoch_array.append (epoch)
    loss_array.append (avg_loss)

    epoch % 10 == 0 인 경우 :
        print (f "epoch {epoch}, 손실 : {avg_loss : .4f}")
로그인 후 복사
  • 데이터 생성 : 랜덤 트레이닝 데이터 (x_data) 및 해당 대상 (Y_DATA) 값이 생성됩니다. 모델 및 최적화 초기화 : 모델 매개 변수 및 최적화 상태가 초기화됩니다.
  • 교육 루프 : 네트워크는 미니 배치 구배 하강을 사용하여 특정 수의 에포크에 대해 교육됩니다.
  • 교육 루프는 배치를 통해 반복하여 Train_Step 기능을 사용하여 기울기 업데이트를 수행합니다. 에포크 당 평균 손실은 계산되고 저장됩니다. 에포크 번호와 평균 손실을 인쇄합니다.

Step8 : 결과를 플로팅합니다

교육 결과 시각화는 신경망의 성능을 이해하는 데 핵심입니다. 이 단계에서 우리는 모델이 얼마나 잘 배우고 있는지 관찰하고 훈련 과정에서 잠재적 인 문제를 식별하기 위해 에포크를 통해 훈련 손실을 그릴 것입니다.

 # 결과를 플롯하십시오
plt.plot (epoch_array, loss_array, label = "훈련 손실")
plt.xlabel ( "epoch")
plt.ylabel ( "손실")
plt.title ( "에포크의 훈련 손실")
plt.legend ()
plt.show ()
로그인 후 복사

이 예제는 JAX가 고성능을 깨끗하고 읽을 수있는 코드와 결합하는 방법을 보여줍니다. JAX가 장려하는 기능적 프로그래밍 스타일을 사용하면 작업을 쉽게 구성하고 변환을 적용 할 수 있습니다.

산출:

번개 빠른 JAX에 대한 가이드

구성:

번개 빠른 JAX에 대한 가이드

이 예제는 JAX가 고성능을 깨끗하고 읽을 수있는 코드와 결합하는 방법을 보여줍니다. JAX가 권장하는 기능적 프로그래밍 스타일을 사용하면 작업을 쉽게 구성하고 변환을 적용 할 수 있습니다.

모범 사례 및 팁

신경망을 구축 할 때 모범 사례를 준수하면 성능과 유지 관리가 크게 향상 될 수 있습니다. 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
    
로그인 후 복사

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))
로그인 후 복사

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))
로그인 후 복사

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.

출력 :

 ===========================
===========================
1001
===========================
1001
로그인 후 복사

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)
로그인 후 복사

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
로그인 후 복사

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])
인쇄 (x)
print(inefficient_function(x))
print(efficient_function(x))
로그인 후 복사

산출:

 [1 2 3]
0.49678695
0.49678695
로그인 후 복사

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
로그인 후 복사
 # For more complex debugging, break out of JIT
def debug_values(x):
    print("Input:", x)
    result = debug_function(x)
    print("Output:", result)
    반환 결과
    
로그인 후 복사
  • 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.

산출:

 print("===========================")
print(debug_function(jnp.array([1, 2, 3])))
print("===========================")
print(debug_values(jnp.array([1, 2, 3])))
로그인 후 복사

번개 빠른 JAX에 대한 가이드

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
    결과 = []

    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
로그인 후 복사

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.

산출:

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

print("===========================")
인쇄 (데이터)

print("===========================")
print(process_large_data(data))
로그인 후 복사

번개 빠른 JAX에 대한 가이드

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
    
로그인 후 복사

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
    반품 {
        "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}")
로그인 후 복사

산출:

번개 빠른 JAX에 대한 가이드

번개 빠른 JAX에 대한 가이드

Using Static Arguments in JIT

 def g(x, n):
    i = 0
    while i <p> <strong>산출:</strong></p><pre class="brush:php;toolbar:false"> 30
로그인 후 복사

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>산출:</strong></p><pre class="brush:php;toolbar:false"> 30
로그인 후 복사

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

결론

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.

주요 테이크 아웃

  • 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.

자주 묻는 질문

Q1. What makes JAX different from NumPY?

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

Q2. 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.

Q5. 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.

이 기사에 표시된 미디어는 분석 Vidhya가 소유하지 않으며 저자의 재량에 따라 사용됩니다.

위 내용은 번개 빠른 JAX에 대한 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿