Langevin dynamics is a powerful sampling method that uses gradients of the energy function to guide the exploration of the state space, combined with random noise to ensure proper exploration. It's particularly useful for sampling from complex, high-dimensional distributions.
importtorchimportmatplotlib.pyplotaspltfromtorchebm.coreimportGaussianEnergyfromtorchebm.samplers.langevin_dynamicsimportLangevinDynamicsdefbasic_example():""" Simple Langevin dynamics sampling from a 2D Gaussian distribution. """# Create energy function for a 2D Gaussiandevice=torch.device("cuda"iftorch.cuda.is_available()else"cpu")dim=2# dimension of the state spacen_steps=100# steps between samplesn_samples=1000# num of samplesmean=torch.tensor([1.0,-1.0])cov=torch.tensor([[1.0,0.5],[0.5,2.0]])energy_fn=GaussianEnergy(mean,cov,device=device)# Initialize samplersampler=LangevinDynamics(energy_function=energy_fn,step_size=0.01,noise_scale=0.1,device=device,)# Generate samplesinitial_state=torch.zeros(n_samples,dim,device=device)samples=sampler.sample(x=initial_state,n_steps=n_steps,n_samples=n_samples,)# Plot resultssamples=samples.cpu().numpy()plt.figure(figsize=(10,5))plt.scatter(samples[:,0],samples[:,1],alpha=0.1)plt.title("Samples from 2D Gaussian using Langevin Dynamics")plt.xlabel("x₁")plt.ylabel("x₂")plt.show()
TorchEBM's Langevin dynamics sampler works efficiently on both CPU and GPU. When available, using a GPU can significantly accelerate sampling, especially for high-dimensional distributions or large sample sizes.
Langevin dynamics is a versatile sampling approach suitable for many energy-based models. It combines the efficiency of gradient-based methods with the exploration capability of stochastic methods, making it an excellent choice for complex distributions.
For a more visual exploration of Langevin dynamics, see the Langevin Sampler Trajectory example that visualizes sampling trajectories overlaid on energy landscapes.
This plot shows 1000 samples from a 2D Gaussian distribution generated using Langevin dynamics. The samples are concentrated around the mean [1.0, -1.0] and reflect the covariance structure with the characteristic elliptical shape.
importtorchimportmatplotlib.pyplotaspltfromtorchebm.coreimportDoubleWellEnergyfromtorchebm.samplers.langevin_dynamicsimportLangevinDynamics# Create Double Well energy functiondevice=torch.device("cuda"iftorch.cuda.is_available()else"cpu")energy_fn=DoubleWellEnergy(barrier_height=2.0)# Initialize samplersampler=LangevinDynamics(energy_function=energy_fn,step_size=0.1,noise_scale=0.3,device=device)# Generate samples with trajectory and diagnosticsinitial_state=torch.tensor([-1.5],device=device).view(1,1)trajectory,diagnostics=sampler.sample(x=initial_state,n_steps=5000,return_trajectory=True,return_diagnostics=True)# Plot trajectory and energyfig,(ax1,ax2)=plt.subplots(1,2,figsize=(12,5))ax1.plot(trajectory[0,:,0].cpu().numpy())ax1.set_title("Single Chain Trajectory")ax1.set_xlabel("Step")ax1.set_ylabel("Position")ax2.plot(diagnostics[:,2,0,0].cpu().numpy())ax2.set_title("Energy Evolution")ax2.set_xlabel("Step")ax2.set_ylabel("Energy")plt.tight_layout()plt.show()
The left plot shows a single sampling chain trajectory in a Double Well energy landscape. The trajectory moves between the two wells over time. The right plot shows the corresponding energy evolution during sampling, with drops indicating transitions between wells.