-[docs]
-classGridEmbedding2D(nn.Module):
-"""A simple positional embedding as a regular 2D grid
- """
- def__init__(self,grid_boundaries=[[0,1],[0,1]]):
-"""GridEmbedding2D applies a simple positional
- embedding as a regular 2D grid
-
- Parameters
- ----------
- grid_boundaries : list, optional
- coordinate boundaries of input grid, by default [[0, 1], [0, 1]]
- """
- super().__init__()
- self.grid_boundaries=grid_boundaries
- self._grid=None
- self._res=None
-
-
-[docs]
- defgrid(self,spatial_dims,device,dtype):
-"""grid generates 2D grid needed for pos encoding
- and caches the grid associated with MRU resolution
-
- Parameters
- ----------
- spatial_dims : torch.size
- sizes of spatial resolution
- device : literal 'cpu' or 'cuda:*'
- where to load data
- dtype : str
- dtype to encode data
-
- Returns
- -------
- torch.tensor
- output grids to concatenate
- """
- # handle case of multiple train resolutions
- ifself._gridisNoneorself._res!=spatial_dims:
- grid_x,grid_y=regular_grid_2d(spatial_dims,
- grid_boundaries=self.grid_boundaries)
- grid_x=grid_x.to(device).to(dtype).unsqueeze(0).unsqueeze(0)
- grid_y=grid_y.to(device).to(dtype).unsqueeze(0).unsqueeze(0)
- self._grid=grid_x,grid_y
- self._res=spatial_dims
-
- returnself._grid
-
-
-
-[docs]
- defforward(self,data,batched=True):
- ifnotbatched:
- ifdata.ndim==3:
- data=data.unsqueeze(0)
- batch_size=data.shape[0]
- x,y=self.grid(data.shape[-2:],data.device,data.dtype)
- out=torch.cat((data,x.expand(batch_size,-1,-1,-1),
- y.expand(batch_size,-1,-1,-1)),
- dim=1)
- # in the unbatched case, the dataloader will stack N
- # examples with no batch dim to create one
- ifnotbatchedandbatch_size==1:
- returnout.squeeze(0)
- else:
- returnout
-
-
-
-
-[docs]
-classGridEmbeddingND(nn.Module):
-"""A positional embedding as a regular ND grid
- """
- def__init__(self,dim:int=2,grid_boundaries=[[0,1],[0,1]]):
-"""GridEmbeddingND applies a simple positional
- embedding as a regular ND grid
-
- Parameters
- ----------
- dim: int
- dimensions of positional encoding to apply
- grid_boundaries : list, optional
- coordinate boundaries of input grid along each dim, by default [[0, 1], [0, 1]]
- """
- super().__init__()
- self.dim=dim
- assertself.dim==len(grid_boundaries),f"Error: expected grid_boundaries to be\
- an iterable of length {self.dim}, received {grid_boundaries}"
- self.grid_boundaries=grid_boundaries
- self._grid=None
- self._res=None
-
-
-[docs]
- defgrid(self,spatial_dims:torch.Size,device:str,dtype:torch.dtype):
-"""grid generates ND grid needed for pos encoding
- and caches the grid associated with MRU resolution
-
- Parameters
- ----------
- spatial_dims : torch.Size
- sizes of spatial resolution
- device : literal 'cpu' or 'cuda:*'
- where to load data
- dtype : str
- dtype to encode data
-
- Returns
- -------
- torch.tensor
- output grids to concatenate
- """
- # handle case of multiple train resolutions
- ifself._gridisNoneorself._res!=spatial_dims:
- grids_by_dim=regular_grid_nd(spatial_dims,
- grid_boundaries=self.grid_boundaries)
- # add batch, channel dims
- grids_by_dim=[x.to(device).to(dtype).unsqueeze(0).unsqueeze(0)forxingrids_by_dim]
- self._grid=grids_by_dim
- self._res=spatial_dims
-
- returnself._grid
-
-
-
-[docs]
- defforward(self,data,batched=True):
-"""
- Params
- --------
- data: torch.Tensor
- assumes shape batch (optional), channels, x_1, x_2, ...x_n
- batched: bool
- whether data has a batch dim
- """
- # add batch dim if it doesn't exist
- ifnotbatched:
- ifdata.ndim==self.dim+1:
- data=data.unsqueeze(0)
- batch_size=data.shape[0]
- grids=self.grid(spatial_dims=data.shape[2:],
- device=data.device,
- dtype=data.dtype)
- grids=[x.repeat(batch_size,*[1]*(self.dim+1))forxingrids]
- out=torch.cat((data,*grids),
- dim=1)
- returnout
-
-
-
-
-[docs]
-classSinusoidalEmbedding2D(nn.Module):
- def__init__(self,num_channels,max_positions=10000,endpoint=False):
-"""SinusoidalEmbedding2D applies a 2d sinusoidal positional encoding
-
- Parameters
- ----------
- num_channels : int
- number of input channels
- max_positions : int, optional
- maximum positions to encode, by default 10000
- endpoint : bool, optional
- whether to set endpoint, by default False
- """
- super().__init__()
- self.num_channels=num_channels
- self.max_positions=max_positions
- self.endpoint=endpoint
-
-
-
-
-
-classRotaryEmbedding2D(nn.Module):
- def__init__(self,dim,min_freq=1/64,scale=1.):
-"""
- Applying rotary positional embedding (https://arxiv.org/abs/2104.09864) to the input feature tensor.
- The crux is the dot product of two rotation matrices R(theta1) and R(theta2) is equal to R(theta2 - theta1).
- """
- super().__init__()
- inv_freq=1./(10000**(torch.arange(0,dim,2).float()/dim))
- self.min_freq=min_freq
- self.scale=scale
- self.register_buffer('inv_freq',inv_freq,persistent=False)
-
- defforward(self,coordinates):
-"""coordinates is tensor of [batch_size, num_points]"""
- coordinates=coordinates*(self.scale/self.min_freq)
- freqs=torch.einsum('... i , j -> ... i j',coordinates,self.inv_freq)# [b, n, d//2]
- returntorch.cat((freqs,freqs),dim=-1)# [b, n, d]
-
- @staticmethod
- defapply_1d_rotary_pos_emb(t,freqs):
- returnapply_rotary_pos_emb(t,freqs)
-
- @staticmethod
- defapply_2d_rotary_pos_emb(t,freqs_x,freqs_y):
-"""Split the last dimension of features into two equal halves
- and apply 1d rotary positional embedding to each half."""
- d=t.shape[-1]
- t_x,t_y=t[...,:d//2],t[...,d//2:]
-
- returntorch.cat((apply_rotary_pos_emb(t_x,freqs_x),
- apply_rotary_pos_emb(t_y,freqs_y)),dim=-1)
-
-
-# Utility functions for GridEmbedding
-defregular_grid_2d(spatial_dims,grid_boundaries=[[0,1],[0,1]]):
-"""
- Creates a 2 x height x width stack of positional encodings A, where
- A[:,i,j] = [[x,y]] at coordinate (i,j) on a (height, width) grid.
- """
- height,width=spatial_dims
-
- xt=torch.linspace(grid_boundaries[0][0],grid_boundaries[0][1],
- height+1)[:-1]
- yt=torch.linspace(grid_boundaries[1][0],grid_boundaries[1][1],
- width+1)[:-1]
-
- grid_x,grid_y=torch.meshgrid(xt,yt,indexing='ij')
-
- grid_x=grid_x.repeat(1,1)
- grid_y=grid_y.repeat(1,1)
-
- returngrid_x,grid_y
-
-defregular_grid_nd(resolutions:List[int],grid_boundaries:List[List[int]]=[[0,1]]*2):
-"""regular_grid_nd generates a tensor of coordinate points that
- describe a bounded regular grid.
-
- Creates a dim x res_d1 x ... x res_dn stack of positional encodings A, where
- A[:,c1,c2,...] = [[d1,d2,...dn]] at coordinate (c1,c2,...cn) on a (res_d1, ...res_dn) grid.
-
- Parameters
- ----------
- resolutions : List[int]
- resolution of the output grid along each dimension
- grid_boundaries : List[List[int]], optional
- List of pairs [start, end] of the boundaries of the
- regular grid. Must correspond 1-to-1 with resolutions default [[0,1], [0,1]]
-
- Returns
- -------
- grid: tuple(Tensor)
- list of tensors describing positional encoding
- """
- assertlen(resolutions)==len(grid_boundaries),"Error: inputs must have same number of dimensions"
- dim=len(resolutions)
-
- meshgrid_inputs=list()
- forres,(start,stop)inzip(resolutions,grid_boundaries):
- meshgrid_inputs.append(torch.linspace(start,stop,res+1)[:-1])
- grid=torch.meshgrid(*meshgrid_inputs,indexing='ij')
- grid=tuple([x.repeat([1]*dim)forxingrid])
- returngrid
-
-
-# Utility fucntions for Rotary embedding
-# modified from https://github.com/lucidrains/x-transformers/blob/main/x_transformers/x_transformers.py
-defrotate_half(x):
-"""
- Split x's channels into two equal halves.
- """
- # split the last dimension of x into two equal halves
- x=x.reshape(*x.shape[:-1],2,-1)
- x1,x2=x.unbind(dim=-2)
- returntorch.cat((-x2,x1),dim=-1)
-
-
-defapply_rotary_pos_emb(t,freqs):
-"""
- Apply rotation matrix computed based on freqs to rotate t.
- t: tensor of shape [batch_size, num_points, dim]
- freqs: tensor of shape [batch_size, num_points, 1]
-
- Formula: see equation (34) in https://arxiv.org/pdf/2104.09864.pdf
- """
- return(t*freqs.cos())+(rotate_half(t)*freqs.sin())
-
-[docs]
-classGNOBlock(nn.Module):
-"""GNOBlock implements a Graph Neural Operator layer as described in _[1].
-
- A GNO layer is a resolution-invariant operator that maps a function defined
- over one coordinate mesh to another defined over another coordinate mesh using
- a pointwise kernel integral that takes contributions from neighbors of distance 1
- within a graph constructed via neighbor search with a specified radius.
-
- The kernel integral computed in IntegralTransform
- computes one of the following:
- (a) \int_{A(x)} k(x, y) dy
- (b) \int_{A(x)} k(x, y) * f(y) dy
- (c) \int_{A(x)} k(x, y, f(y)) dy
- (d) \int_{A(x)} k(x, y, f(y)) * f(y) dy
-
- Parameters
- ----------
- in_channels : int
- number of channels in input function. Only used if transform_type
- is (c) "nonlinear" or (d) "nonlinear_kernelonly"
- out_channels : int
- number of channels in output function
- coord_dim : int
- dimension of domain on which x and y are defined
- radius : float
- radius in which to search for neighbors
- use_open3d_neighbor_search : _type_, optional
- _description_, by default None
- channel_mlp : nn.Module, optional
- ChannelMLP parametrizing the kernel k. Input dimension
- should be dim x + dim y or dim x + dim y + dim f.
- ChannelMLP should not be pointwise and should only operate across
- channels to preserve the discretization-invariance of the
- kernel integral.
- channel_mlp_layers : List[int], optional
- list of layer widths to dynamically construct
- LinearChannelMLP network to parameterize kernel k, by default None
- channel_mlp_non_linearity : torch.nn function, optional
- activation function for ChannelMLPLinear above, by default F.gelu
- transform_type : str, optional
- Which integral transform to compute. The mapping is:
- 'linear_kernelonly' -> (a)
- 'linear' -> (b) [DEFAULT]
- 'nonlinear_kernelonly' -> (c)
- 'nonlinear' -> (d)
- If the input f is not given then (a) is computed
- by default independently of this parameter.
- use_open3d_neighbor_search: bool, optional
- use_torch_scatter_reduce : bool, optional
- whether to reduce in integral computation using a function
- provided by the extra dependency torch_scatter or the slower
- native PyTorch implementation, by default True
-
- References
- -----------
- [1]_ Neural Operator: Graph Kernel Network for Partial Differential Equations.
- Zongyi Li, Kamyar Azizzadenesheli, Burigede Liu, Kaushik Bhattacharya,
- Anima Anandkumar. ArXiV, 2020
- """
- def__init__(self,
- in_channels:int,
- out_channels:int,
- coord_dim:int,
- radius:float,
- channel_mlp:nn.Module=None,
- channel_mlp_layers:List[int]=None,
- channel_mlp_non_linearity=F.gelu,
- transform_type="linear",
- use_open3d_neighbor_search:bool=True,
- use_torch_scatter_reduce=True,):
- super().__init__()
-
- self.in_channels=in_channels
- self.out_channels=out_channels
- self.coord_dim=coord_dim
-
- self.radius=radius
-
- # Create in-to-out nb search module
- ifuse_open3d_neighbor_search:
- assertself.coord_dim==3,f"Error: open3d is only designed for 3d data, \
- GNO instantiated for dim={coord_dim}"
- self.neighbor_search=NeighborSearch(use_open3d=use_open3d_neighbor_search)
-
- # create proper kernel input channel dim
- # if nonlinear of either type, add in_features dim
- # otherwise just add x and y dim
- kernel_in_dim=self.coord_dim*2
- kernel_in_dim_str="dim(y) + dim(x)"
- iftransform_type=="nonlinear"ortransform_type=="nonlinear_kernelonly":
- kernel_in_dim+=self.in_channels
- kernel_in_dim_str+=" + dim(f_y)"
-
- ifchannel_mlpisnotNone:
- assertchannel_mlp.in_channels==kernel_in_dim,f"Error: expected ChannelMLP to take\
- input with {kernel_in_dim} channels (feature channels={kernel_in_dim_str}),\
- got {channel_mlp.in_channels}."
- assertchannel_mlp.out_channels==out_channels,f"Error: expected ChannelMLP to have\
-{out_channels=} but got {channel_mlp.in_channels=}."
- self.channel_mlp=channel_mlp
-
- ifchannel_mlp_layersisnotNone:
- ifchannel_mlp_layers[0]!=kernel_in_dim:
- channel_mlp_layers=[kernel_in_dim]+channel_mlp_layers
- ifchannel_mlp_layers[-1]!=self.out_channels:
- channel_mlp_layers.append(self.out_channels)
- self.channel_mlp=LinearChannelMLP(layers=channel_mlp_layers,non_linearity=channel_mlp_non_linearity)
-
- # Create integral transform module
- self.integral_transform=IntegralTransform(
- channel_mlp=self.channel_mlp,
- transform_type=transform_type,
- use_torch_scatter=use_torch_scatter_reduce
- )
-
-
-[docs]
- defforward(self,y,x,f_y=None):
-"""Compute a GNO neighbor search and kernel integral transform.
-
- Parameters
- ----------
- y : torch.Tensor of shape [n, d1]
- n points of dimension d1 specifying
- the space to integrate over.
- If batched, these must remain constant
- over the whole batch so no batch dim is needed.
- x : torch.Tensor of shape [m, d1], default None
- m points of dimension d1 over which the
- output function is defined. Must share domain
- with y
- f_y : torch.Tensor of shape [batch, n, d2] or [n, d2], default None
- Function to integrate the kernel against defined
- on the points y. The kernel is assumed diagonal
- hence its output shape must be d3 for the transforms
- (b) or (d). If None, (a) is computed.
-
- Output
- ----------
- out_features : torch.Tensor of shape [batch, m, d3] or [m, d3]
- Output function given on the points x.
- d4 is the output size of the kernel k.
- """
-
- neighbors_dict=self.neighbor_search(data=y,queries=x,radius=self.radius)
-
- # TODO: compute weights using the neighborhood dict
- out_features=self.integral_transform(y=y,
- x=x,
- neighbors=neighbors_dict,
- f_y=f_y)
-
- returnout_features
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dev/_modules/neuralop/layers/integral_transform.html b/dev/_modules/neuralop/layers/integral_transform.html
index 1374993..e58d14a 100644
--- a/dev/_modules/neuralop/layers/integral_transform.html
+++ b/dev/_modules/neuralop/layers/integral_transform.html
@@ -16,7 +16,7 @@
-
+
diff --git a/dev/_modules/neuralop/layers/neighbor_search.html b/dev/_modules/neuralop/layers/neighbor_search.html
index 659cec0..d2d0084 100644
--- a/dev/_modules/neuralop/layers/neighbor_search.html
+++ b/dev/_modules/neuralop/layers/neighbor_search.html
@@ -16,7 +16,7 @@
-
+
diff --git a/dev/_modules/neuralop/layers/padding.html b/dev/_modules/neuralop/layers/padding.html
index 75b5210..be8c2f4 100644
--- a/dev/_modules/neuralop/layers/padding.html
+++ b/dev/_modules/neuralop/layers/padding.html
@@ -16,7 +16,7 @@
-
+
@@ -133,7 +133,7 @@
Source code for neuralop.layers.padding
if a list, make sure if matches the dim of (d1, ..., dN) padding_mode : {'symmetric', 'one-sided'}, optional whether to pad on both sides, by default 'one-sided'
- resolution_scaling_factor : int ; default is 1
+ output_scaling_factor : int ; default is 1 Notes -----
@@ -145,14 +145,14 @@
"(excluding batch, ch)")
- resolution_scaling_factor=self.resolution_scaling_factor
- ifnotisinstance(self.resolution_scaling_factor,list):
+ output_scaling_factor=self.output_scaling_factor
+ ifnotisinstance(self.output_scaling_factor,list):# if unset by the user, scaling_factor will be 1 be default,
- # so `resolution_scaling_factor` should never be None.
- resolution_scaling_factor:List[float]=validate_scaling_factor(
- self.resolution_scaling_factor,len(resolution),n_layers=None
+ # so `output_scaling_factor` should never be None.
+ output_scaling_factor:List[float]=validate_scaling_factor(
+ self.output_scaling_factor,len(resolution),n_layers=None)try:
@@ -209,7 +209,7 @@
Source code for neuralop.layers.padding
output_pad=paddingoutput_pad=[
- round(i*j)for(i,j)inzip(resolution_scaling_factor,output_pad)
+ round(i*j)for(i,j)inzip(output_scaling_factor,output_pad)]# padding is being applied in reverse order
@@ -260,7 +260,7 @@
super().__init__()ifout_featuresisnotNoneandin_features!=out_features:raiseValueError(
- f"Got in_features={in_features} and out_features={out_features}, "
+ f"Got in_features={in_features} and out_features={out_features}""but these two must be the same for soft-gating")self.in_features=in_features
diff --git a/dev/_modules/neuralop/layers/spectral_convolution.html b/dev/_modules/neuralop/layers/spectral_convolution.html
index d19152f..275644a 100644
--- a/dev/_modules/neuralop/layers/spectral_convolution.html
+++ b/dev/_modules/neuralop/layers/spectral_convolution.html
@@ -16,7 +16,7 @@
-
+
@@ -333,11 +333,16 @@
Source code for neuralop.layers.spectral_convolution
tensor weight individually
init_std : float or 'auto', default is 'auto' std to use for the init
+ n_layers : int, optional
+ Number of Fourier Layers, by default 4 factorization : str or None, {'tucker', 'cp', 'tt'}, default is None If None, a single dense weight is learned for the FNO. Otherwise, that weight, used for the contraction in the Fourier domain is learned in factorized form. In that case, `factorization` is the tensor factorization of the parameters weight used.
+ joint_factorization : bool, optional
+ Whether all the Fourier Layers should be parametrized by a single tensor
+ (vs one per layer), by default False Ignored if ``factorization is None`` rank : float or rank, optional Rank of the tensor factorization of the Fourier weights, by default 1.0 Ignored if ``factorization is None``
@@ -356,7 +361,7 @@
Source code for neuralop.layers.spectral_convolution
decomposition_kwargs : dict, optional, default is {}
Optionaly additional parameters to pass to the tensor decomposition Ignored if ``factorization is None``
- complex: bool, optional
+ complex_data: bool, optional whether data takes on complex values in the spatial domain, by default False if True, uses different logic for FFT contraction and uses full FFT instead of real-valued """
@@ -366,29 +371,30 @@
Source code for neuralop.layers.spectral_convolution
in_channels,out_channels,n_modes,
- complex=False,max_n_modes=None,bias=True,
+ n_layers=1,separable=False,
- resolution_scaling_factor:Optional[Union[Number,List[Number]]]=None,
+ output_scaling_factor:Optional[Union[Number,List[Number]]]=None,fno_block_precision="full",rank=0.5,factorization=None,implementation="reconstructed",fixed_rank_modes=False,
+ joint_factorization=False,decomposition_kwargs:Optional[dict]=None,
- dtype=torch.float32,
+ complex_data:bool=False,init_std="auto",fft_norm="forward",device=None,
+ dtype=None,):super().__init__(dtype=dtype,device=device)self.in_channels=in_channelsself.out_channels=out_channels
-
- self.dtype=dtype
- self.complex=complex
+ self.joint_factorization=joint_factorization
+ self.complex_data=complex_data# n_modes is the total number of modes kept along each dimensionself.n_modes=n_modes
@@ -403,11 +409,12 @@
Source code for neuralop.layers.spectral_convolution
Source code for neuralop.layers.spectral_convolution
# the real FFT is skew-symmetric, so the last mode has a redundacy if our data is real in space
# As a design choice we do the operation here to avoid users dealing with the +1# if we use the full FFT we cannot cut off informtion from the last mode
- ifnotself.complex:
+ ifnotself.complex_data:n_modes[-1]=n_modes[-1]//2+1self._n_modes=n_modes
[docs]defforward(
- self,x:torch.Tensor,output_shape:Optional[Tuple[int]]=None
+ self,x:torch.Tensor,indices=0,output_shape:Optional[Tuple[int]]=None):"""Generic forward pass for the Factorized Spectral Conv
@@ -508,6 +529,8 @@
Source code for neuralop.layers.spectral_convolution
----------
x : torch.Tensor input activation of size (batch_size, channels, d1, ..., dN)
+ indices : int, default is 0
+ if joint_factorization, index of the layers for n_layers > 1 Returns -------
@@ -516,14 +539,14 @@
Source code for neuralop.layers.spectral_convolution
batchsize,channels,*mode_sizes=x.shapefft_size=list(mode_sizes)
- ifnotself.complex:
+ ifnotself.complex_data:fft_size[-1]=fft_size[-1]//2+1# Redundant last coefficient in real spatial datafft_dims=list(range(-self.order,0))ifself.fno_block_precision=="half":x=x.half()
- ifself.complex:
+ ifself.complex_data:x=torch.fft.fftn(x,norm=self.fft_norm,dim=fft_dims)else:x=torch.fft.rfftn(x,norm=self.fft_norm,dim=fft_dims)
@@ -551,14 +574,14 @@
Source code for neuralop.layers.spectral_convolution
slices_w =[slice(None)]# channelselse:slices_w=[slice(None),slice(None)]# in_channels, out_channels
- ifself.complex:
+ ifself.complex_data:slices_w+=[slice(start//2,-start//2)ifstartelseslice(start,None)forstartinstarts]else:# The last mode already has redundant half removed in real FFTslices_w+=[slice(start//2,-start//2)ifstartelseslice(start,None)forstartinstarts[:-1]]slices_w+=[slice(None,-starts[-1])ifstarts[-1]elseslice(None)]
- weight=self.weight[slices_w]
+ weight=self._get_weight(indices)[slices_w]# if separable conv, weight tensor only has one channel dimifself.separable:
@@ -569,15 +592,15 @@
Source code for neuralop.layers.spectral_convolution
starts =[(size-min(size,n_mode))for(size,n_mode)inzip(list(x.shape[2:]),list(weight.shape[weight_start_idx:]))]slices_x=[slice(None),slice(None)]# Batch_size, channels
- ifself.complex:
+ ifself.complex_data:slices_x+=[slice(start//2,-start//2)ifstartelseslice(start,None)forstartinstarts]else:slices_x+=[slice(start//2,-start//2)ifstartelseslice(start,None)forstartinstarts[:-1]]slices_x+=[slice(None,-starts[-1])ifstarts[-1]elseslice(None)]# The last mode already has redundant half removedout_fft[slices_x]=self._contract(x[slices_x],weight,separable=self.separable)
- ifself.resolution_scaling_factorisnotNoneandoutput_shapeisNone:
- mode_sizes=tuple([round(s*r)for(s,r)inzip(mode_sizes,self.resolution_scaling_factor)])
+ ifself.output_scaling_factorisnotNoneandoutput_shapeisNone:
+ mode_sizes=tuple([round(s*r)for(s,r)inzip(mode_sizes,self.output_scaling_factor[indices])])ifoutput_shapeisnotNone:mode_sizes=output_shape
@@ -585,16 +608,32 @@
Source code for neuralop.layers.spectral_convolution
if self.order>1:out_fft=torch.fft.fftshift(out_fft,dim=fft_dims[:-1])
- ifself.complex:
+ ifself.complex_data:x=torch.fft.ifftn(out_fft,s=mode_sizes,dim=fft_dims,norm=self.fft_norm)else:x=torch.fft.irfftn(out_fft,s=mode_sizes,dim=fft_dims,norm=self.fft_norm)ifself.biasisnotNone:
- x=x+self.bias
+ x=x+self.bias[indices,...]returnx
-
+
+
+
+[docs]
+ defget_conv(self,indices):
+"""Returns a sub-convolutional layer from the joint parametrize main-convolution
+
+ The parametrization of sub-convolutional layers is shared with the main one.
+ """
+ ifself.n_layers==1:
+ Warning("A single convolution is parametrized, directly use the main class.")
+
+ returnSubConv(self,indices)
[docs]
- deftransform(self,x,output_shape=None):
+ deftransform(self,x,layer_index=0,output_shape=None):*_,in_height,in_width=x.shape
- ifself.resolution_scaling_factorisnotNoneandoutput_shapeisNone:
- height=round(in_height*self.resolution_scaling_factor[0])
- width=round(in_width*self.resolution_scaling_factor[1])
+ ifself.output_scaling_factorisnotNoneandoutput_shapeisNone:
+ height=round(in_height*self.output_scaling_factor[layer_index][0])
+ width=round(in_width*self.output_scaling_factor[layer_index][1])elifoutput_shapeisnotNone:height,width=output_shape[0],output_shape[1]else:height,width=in_height,in_width# Return the identity if the resolution and grid of the input and output are the same
- if((in_height,in_width)==(height,width))and(self.sht_grids[0]==self.sht_grids[1]):
+ if((in_height,in_width)==(height,width))and(self.sht_grids[layer_index]==self.sht_grids[layer_index+1]):returnxelse:
- coefs=self.sht_handle.sht(x,s=self.n_modes,norm=self.sht_norm,grid=self.sht_grids[0])
- returnself.sht_handle.isht(coefs,s=(height,width),norm=self.sht_norm,grid=self.sht_grids[1])
[docs]
- defforward(self,x,output_shape=None):
+ defforward(self,x,indices=0,output_shape=None):"""Generic forward pass for the Factorized Spectral Conv Parameters ---------- x : torch.Tensor input activation of size (batch_size, channels, d1, ..., dN)
+ indices : int, default is 0
+ if joint_factorization, index of the layers for n_layers > 1 Returns -------
@@ -561,28 +582,28 @@
Source code for neuralop.layers.spherical_convolution
+[docs]
+ defget_conv(self,indices):
+"""Returns a sub-convolutional layer from the joint parametrize main-convolution
+
+ The parametrization of sub-convolutional layers is shared with the main one.
+ """
+ ifself.n_layers==1:
+ raiseValueError(
+ "A single convolution is parametrized, directly use the main class."
+ )
+
+ returnSubConv(self,indices)
[docs]classFNO(BaseModel,name='FNO'):
-"""N-Dimensional Fourier Neural Operator. The FNO learns a mapping between
- spaces of functions discretized over regular grids.
-
- The key component of an FNO is its SpectralConv layer (see ``neuralop.layers.spectral_convolution``), which
- is similar to a standard CNN conv layer but operates in the frequency domain.
-
- For more information, refer to :ref:`fno-guide`.
+"""N-Dimensional Fourier Neural Operator Parameters ----------
- n_modes : Tuple[int]
+ n_modes : int tuple number of modes to keep in Fourier Layer, along each dimension The dimensionality of the FNO is inferred from ``len(n_modes)``
- in_channels : int
- Number of channels in input function
- out_channels : int
- Number of channels in output function hidden_channels : int
- width of the FNO (i.e. number of channels), by default 256
+ width of the FNO (i.e. number of channels)
+ in_channels : int, optional
+ Number of input channels, by default 3
+ out_channels : int, optional
+ Number of output channels, by default 1
+ lifting_channels : int, optional
+ number of hidden channels of the lifting block of the FNO, by default 256
+ projection_channels : int, optional
+ number of hidden channels of the projection block of the FNO, by default 256 n_layers : int, optional Number of Fourier Layers, by default 4
-
- Documentation for more advanced parameters is below.
-
- Examples
- ---------
-
- >>> from neuralop.models import FNO
- >>> model = FNO(n_modes=(12,12), in_channels=1, out_channels=1, hidden_channels=64)
- >>> model
- FNO(
- (positional_embedding): GridEmbeddingND()
- (fno_blocks): FNOBlocks(
- (convs): SpectralConv(
- (weight): ModuleList(
- (0-3): 4 x DenseTensor(shape=torch.Size([64, 64, 12, 7]), rank=None)
- )
- )
- ... torch.nn.Module printout truncated ...
-
-
- Other parameters
- ------------------
- lifting_channel_ratio : int, optional
- ratio of lifting channels to hidden_channels, by default 2
- The number of liting channels in the lifting block of the FNO is
- lifting_channel_ratio * hidden_channels (e.g. default 512)
- projection_channel_ratio : int, optional
- ratio of projection channels to hidden_channels, by default 2
- The number of projection channels in the projection block of the FNO is
- projection_channel_ratio * hidden_channels (e.g. default 512)
- positional_embedding : Union[str, nn.Module], optional
- Positional embedding to apply to last channels of raw input
- before being passed through the FNO. Defaults to "grid"
-
- * If "grid", appends a grid positional embedding with default settings to
+ positional_embedding : str literal | GridEmbedding2D | GridEmbeddingND | None
+ if "grid", appends a grid positional embedding with default settings to the last channels of raw input. Assumes the inputs are discretized over a grid with entry [0,0,...] at the origin and side lengths of 1.
+ If an initialized GridEmbedding, uses this module directly
+ See `neuralop.embeddings.GridEmbeddingND` for details
+ if None, does nothing
+ max_n_modes : None or int tuple, default is None
+ * If not None, this allows to incrementally increase the number of
+ modes in Fourier domain during training. Has to verify n <= N
+ for (n, m) in zip(max_n_modes, n_modes).
- * If an initialized GridEmbedding module, uses this module directly
- See :mod:`neuralop.embeddings.GridEmbeddingND` for details.
-
- * If None, does nothing
+ * If None, all the n_modes are used.
+ This can be updated dynamically during training.
+ fno_block_precision : str {'full', 'half', 'mixed'}
+ if 'full', the FNO Block runs in full precision
+ if 'half', the FFT, contraction, and inverse FFT run in half precision
+ if 'mixed', the contraction and inverse FFT run in half precision
+ stabilizer : str {'tanh'} or None, optional
+ By default None, otherwise tanh is used before FFT in the FNO block
+ use_channel_mlp : bool, optional
+ Whether to use a ChannelMLP layer after each FNO block, by default False
+ channel_mlp_dropout : float , optional
+ droupout parameter of ChannelMLP layer, by default 0
+ channel_mlp_expansion : float, optional
+ expansion parameter of ChannelMLP layer, by default 0.5 non_linearity : nn.Module, optional
- Non-Linear activation function module to use, by default F.gelu
- norm : str {"ada_in", "group_norm", "instance_norm"}, optional
+ Non-Linearity module to use, by default F.gelu
+ norm : Literal["ada_in", "group_norm", "instance_norm"], optional Normalization layer to use, by default None
- complex : bool, optional
- Whether data is complex-valued (default False)
- if True, initializes complex-valued modules.
- channel_mlp_dropout : float, optional
- dropout parameter for ChannelMLP in FNO Block, by default 0
- channel_mlp_expansion : float, optional
- expansion parameter for ChannelMLP in FNO Block, by default 0.5
- channel_mlp_skip : str {'linear', 'identity', 'soft-gating'}, optional
+ preactivation : bool, default is False
+ if True, use resnet-style preactivation
+ fno_skip : {'linear', 'identity', 'soft-gating'}, optional
+ Type of skip connection to use in fno, by default 'linear'
+ channel_mlp_skip : {'linear', 'identity', 'soft-gating'}, optional Type of skip connection to use in channel-mixing mlp, by default 'soft-gating'
- fno_skip : str {'linear', 'identity', 'soft-gating'}, optional
- Type of skip connection to use in FNO layers, by default 'linear'
- resolution_scaling_factor : Union[Number, List[Number]], optional
- layer-wise factor by which to scale the domain resolution of function, by default None
-
- * If a single number n, scales resolution by n at each layer
-
- * if a list of numbers [n_0, n_1,...] scales layer i's resolution by n_i.
- domain_padding : Union[Number, List[Number]], optional
+ separable : bool, default is False
+ if True, use a depthwise separable spectral convolution
+ factorization : str or None, {'tucker', 'cp', 'tt'}
+ Tensor factorization of the parameters weight to use, by default None.
+ * If None, a dense tensor parametrizes the Spectral convolutions
+ * Otherwise, the specified tensor factorization is used.
+ joint_factorization : bool, optional
+ Whether all the Fourier Layers should be parametrized by a single tensor
+ (vs one per layer), by default False
+ rank : float or rank, optional
+ Rank of the tensor factorization of the Fourier weights, by default 1.0
+ fixed_rank_modes : bool, optional
+ Modes to not factorize, by default False
+ implementation : {'factorized', 'reconstructed'}, optional, default is 'factorized'
+ If factorization is not None, forward mode to use::
+ * `reconstructed` : the full weight tensor is reconstructed from the
+ factorization and used for the forward pass
+ * `factorized` : the input is directly contracted with the factors of
+ the decomposition
+ decomposition_kwargs : dict, optional, default is {}
+ Optionaly additional parameters to pass to the tensor decomposition
+ domain_padding : None, float, or List[float], optional If not None, percentage of padding to use, by default None To vary the percentage of padding used along each input dimension, pass in a list of percentages e.g. [p1, p2, ..., pN] such that p1 corresponds to the percentage of padding along dim 1, etc.
- domain_padding_mode : str {'symmetric', 'one-sided'}, optional
+ domain_padding_mode : {'symmetric', 'one-sided'}, optional How to perform domain padding, by default 'one-sided'
- fno_block_precision : str {'full', 'half', 'mixed'}, optional
- precision mode in which to perform spectral convolution, by default "full"
- stabilizer : str {'tanh'} | None, optional
- whether to use a tanh stabilizer in FNO block, by default None
-
- Note: stabilizer greatly improves performance in the case
- `fno_block_precision='mixed'`.
-
- max_n_modes : Tuple[int] | None, optional
-
- * If not None, this allows to incrementally increase the number of
- modes in Fourier domain during training. Has to verify n <= N
- for (n, m) in zip(max_n_modes, n_modes).
-
- * If None, all the n_modes are used.
-
- This can be updated dynamically during training.
- factorization : str, optional
- Tensor factorization of the FNO layer weights to use, by default None.
-
- * If None, a dense tensor parametrizes the Spectral convolutions
-
- * Otherwise, the specified tensor factorization is used.
- rank : float, optional
- tensor rank to use in above factorization, by default 1.0
- fixed_rank_modes : bool, optional
- Modes to not factorize, by default False
- implementation : str {'factorized', 'reconstructed'}, optional
-
- * If 'factorized', implements tensor contraction with the individual factors of the decomposition
-
- * If 'reconstructed', implements with the reconstructed full tensorized weight.
- decomposition_kwargs : dict, optional
- extra kwargs for tensor decomposition (see `tltorch.FactorizedTensor`), by default dict()
- separable : bool, optional (**DEACTIVATED**)
- if True, use a depthwise separable spectral convolution, by default False
- preactivation : bool, optional (**DEACTIVATED**)
- whether to compute FNO forward pass with resnet-style preactivation, by default False
- conv_module : nn.Module, optional
- module to use for FNOBlock's convolutions, by default SpectralConv
+ conv_module : BaseConv, optional
+ Module to use for convolutions in FNO, by default SpectralConv
+ complex_data: bool, optional
+ whether FNO data takes on complex values
+ in the spatial domain, by default False """def__init__(self,
- n_modes:Tuple[int],
- in_channels:int,
- out_channels:int,
- hidden_channels:int,
- n_layers:int=4,
- lifting_channel_ratio:int=2,
- projection_channel_ratio:int=2,
- positional_embedding:Union[str,nn.Module]="grid",
- non_linearity:nn.Module=F.gelu,
- norm:str=None,
- complex:bool=False,
- channel_mlp_dropout:float=0,
- channel_mlp_expansion:float=0.5,
- channel_mlp_skip:str="soft-gating",
- fno_skip:str="linear",
- resolution_scaling_factor:Union[Number,List[Number]]=None,
- domain_padding:Union[Number,List[Number]]=None,
- domain_padding_mode:str="one-sided",
- fno_block_precision:str="full",
- stabilizer:str=None,
- max_n_modes:Tuple[int]=None,
- factorization:str=None,
- rank:float=1.0,
- fixed_rank_modes:bool=False,
- implementation:str="factorized",
- decomposition_kwargs:dict=dict(),
- separable:bool=False,
- preactivation:bool=False,
- conv_module:nn.Module=SpectralConv,
+ n_modes,
+ hidden_channels,
+ in_channels=3,
+ out_channels=1,
+ lifting_channels=256,
+ projection_channels=256,
+ n_layers=4,
+ positional_embedding="grid",
+ output_scaling_factor=None,
+ max_n_modes=None,
+ fno_block_precision="full",
+ use_channel_mlp=False,
+ channel_mlp_dropout=0,
+ channel_mlp_expansion=0.5,
+ non_linearity=F.gelu,
+ stabilizer=None,
+ norm=None,
+ preactivation=False,
+ fno_skip="linear",
+ channel_mlp_skip="soft-gating",
+ separable=False,
+ factorization=None,
+ rank=1.0,
+ joint_factorization=False,
+ fixed_rank_modes=False,
+ implementation="factorized",
+ decomposition_kwargs=dict(),
+ domain_padding=None,
+ domain_padding_mode="one-sided",
+ conv_module=SpectralConv,
+ complex_data=False,**kwargs):
-
super().__init__()self.n_dim=len(n_modes)
-
- # n_modes is a special property - see the class' property for underlying mechanism
+
+ # See the class' property for underlying mechanism# When updated, change should be reflected in fno blocksself._n_modes=n_modes
-
self.hidden_channels=hidden_channels
+ self.lifting_channels=lifting_channels
+ self.projection_channels=projection_channelsself.in_channels=in_channelsself.out_channels=out_channelsself.n_layers=n_layers
-
- # init lifting and projection channels using ratios w.r.t hidden channels
- self.lifting_channel_ratio=lifting_channel_ratio
- self.lifting_channels=lifting_channel_ratio*self.hidden_channels
-
- self.projection_channel_ratio=projection_channel_ratio
- self.projection_channels=projection_channel_ratio*self.hidden_channels
-
+ self.joint_factorization=joint_factorizationself.non_linearity=non_linearityself.rank=rankself.factorization=factorization
@@ -330,9 +278,8 @@
n_dim=self.n_dim,non_linearity=non_linearity)
- # Convert lifting to a complex ChannelMLP if self.complex==True
- ifself.complex:
+ # Convert lifting to a complex ChannelMLP if self.complex_data==True
+ ifself.complex_data:self.lifting=ComplexValued(self.lifting)self.projection=ChannelMLP(
@@ -433,39 +382,22 @@
[docs]defforward(self,x,output_shape=None,**kwargs):
-"""FNO's forward pass
-
- 1. Applies optional positional encoding
-
- 2. Sends inputs through a lifting layer to a high-dimensional latent
- space
-
- 3. Applies optional domain padding to high-dimensional intermediate function representation
-
- 4. Applies `n_layers` Fourier/FNO layers in sequence (SpectralConvolution + skip connections, nonlinearity)
-
- 5. If domain padding was applied, domain padding is removed
-
- 6. Projection of intermediate function representation to the output channels
+"""TFNO's forward pass Parameters ---------- x : tensor input tensor
- output_shape : {tuple, tuple list, None}, default is None Gives the option of specifying the exact output shape for odd shaped inputs.
- * If None, don't specify an output shape
-
* If tuple, specifies the output-shape of the **last** FNO Block
-
* If tuple list, specifies the exact output-shape of each FNO Block """
@@ -527,12 +459,12 @@
number of channels in FNO's pointwise projection, by default 256 fno_n_layers : int, optional number of layers in FNO, by default 4
- fno_resolution_scaling_factor : float | None, optional
+ fno_output_scaling_factor : float | None, optional factor by which to scale output of FNO, by default None fno_incremental_n_modes : list[int] | None, defaults to None if passed, sets n_modes separately for each FNO layer.
@@ -255,7 +255,7 @@
* If None, all the n_modes are used. This can be updated dynamically during training.
- channel_mlp_dropout: float, optional
- dropout parameter for channelMLP after each FNO Block
- channel_mlp_expansions: float, optional
- expansion parameter for channelMLP after each FNO block
+ use_channel_mlp : bool, optional
+ Whether to use an ChannelMLP layer after each FNO block, by default False
+ ChannelMLP : dict, optional
+ Parameters of the ChannelMLP, by default None
+ {'expansion': float, 'dropout': float} non_linearity : nn.Module, optional Non-Linearity module to use, by default F.gelu norm : F.module, optional
@@ -227,17 +228,19 @@
-"""
-Callbacks store all non-essential logic
-required to run specific training scripts.
-
-The callbacks in this module follow the form and
-logic of callbacks in Pytorch-Lightning (https://lightning.ai/docs/pytorch/stable)
-"""
-
-importos
-frompathlibimportPath
-importsys
-fromtypingimportList,Union,Literal
-
-importtorch
-importwandb
-
-from.training_stateimportsave_training_state,load_training_state
-fromneuralop.utilsimportcompute_rank,compute_stable_rank,compute_explained_variance
-
-
-
-[docs]
-classCallback(object):
-"""
- Base callback class. Each abstract method is called in the trainer's
- training loop at the appropriate time.
-
- Callbacks are stateful, meaning they keep track of a state and
- update it throughout the lifetime of a Trainer class.
- Storing the state as a dict enables the Callback to keep track of
- references to underlying parts of the Trainer's process, such as
- models, cost functions and output encoders
- """
-
- def__init__(self):
- self.state_dict={}
-
- def_update_state_dict(self,**kwargs):
- self.state_dict.update(kwargs)
-
- defon_init_start(self,**kwargs):
- pass
-
- defon_init_end(self,*args,**kwargs):
- pass
-
- defon_before_train(self,*args,**kwargs):
- pass
-
- defon_train_start(self,*args,**kwargs):
- pass
-
- defon_epoch_start(self,*args,**kwargs):
- pass
-
- defon_batch_start(self,*args,**kwargs):
- pass
-
- defon_load_to_device(self,*args,**kwargs):
- pass
-
- defon_before_forward(self,*args,**kwargs):
- pass
-
- defon_before_loss(self,*args,**kwargs):
- pass
-
- defcompute_training_loss(self,*args,**kwargs):
- raiseNotImplementedError
-
- defon_batch_end(self,*args,**kwargs):
- pass
-
- defon_epoch_end(self,*args,**kwargs):
- pass
-
- defon_train_end(self,*args,**kwargs):
- pass
-
- defon_before_val(self,*args,**kwargs):
- pass
-
- defon_val_epoch_start(self,*args,**kwargs):
- pass
-
- defon_val_batch_start(self,*args,**kwargs):
- pass
-
- defon_before_val_loss(self,**kwargs):
- pass
-
- defcompute_val_loss(self,*args,**kwargs):
- pass
-
- defon_val_batch_end(self,*args,**kwargs):
- pass
-
- defon_val_epoch_end(self,*args,**kwargs):
- pass
-
- defon_val_end(self,*args,**kwargs):
- pass
-
-
-
-classPipelineCallback(Callback):
- def__init__(self,callbacks:List[Callback]):
-"""
- PipelineCallback handles logic for the case in which
- a user passes more than one Callback to a trainer.
-
- Parameters
- ----------
- callbacks : List[Callback]
- list of Callbacks to use in Trainer
- """
- self.callbacks=callbacks
-
- overrides_device_load=[
- "on_load_to_device"inc.__class__.__dict__.keys()forcincallbacks
- ]
-
- assert(
- sum(overrides_device_load)<2
- ),"More than one callback cannot override device loading"
- ifsum(overrides_device_load)==1:
- self.device_load_callback_idx=overrides_device_load.index(True)
- print("using custom callback to load data to device.")
- else:
- self.device_load_callback_idx=None
- print("using standard method to load data to device.")
-
- # unless loss computation is overriden, call a basic loss function calculation
- overrides_loss=[
- "compute_training_loss"inc.__class__.__dict__.keys()forcincallbacks
- ]
-
- ifsum(overrides_loss)>=1:
- self.overrides_loss=True
- print("using custom callback to compute loss.")
- else:
- self.overrides_loss=False
- print("using standard method to compute loss.")
-
- def_update_state_dict(self,**kwargs):
- forcinself.callbacks:
- c._update_state_dict(kwargs)
-
- defon_init_start(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_init_start(*args,**kwargs)
-
- defon_init_end(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_init_end(*args,**kwargs)
-
- defon_before_train(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_before_train(*args,**kwargs)
-
- defon_train_start(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_train_start(*args,**kwargs)
-
- defon_epoch_start(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_epoch_start(*args,**kwargs)
-
- defon_batch_start(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_batch_start(*args,**kwargs)
-
- defon_load_to_device(self,*args,**kwargs):
- ifself.device_load_callback_idx:
- self.callbacks[self.device_load_callback_idx].on_load_to_device(
- *args,*kwargs
- )
-
- defon_before_forward(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_before_forward(*args,**kwargs)
-
- defon_before_loss(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_before_loss(*args,**kwargs)
-
- defcompute_training_loss(self,*args,**kwargs):
- ifself.overrides_loss:
- forcinself.callbacks:
- c.compute_training_loss(*args,**kwargs)
- else:
- pass
-
- defon_batch_end(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_batch_end(*args,**kwargs)
-
- defon_epoch_end(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_epoch_end(*args,**kwargs)
-
- defon_train_end(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_train_end(*args,**kwargs)
-
- defon_before_val(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_before_val(*args,**kwargs)
-
- defon_val_epoch_start(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_val_epoch_start(*args,**kwargs)
-
- defon_val_batch_start(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_val_batch_start(*args,**kwargs)
-
- defon_before_val_loss(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_before_val_loss(*args,**kwargs)
-
- defcompute_val_loss(self,*args,**kwargs):
- ifself.overrides_loss:
- forcinself.callbacks:
- c.compute_val_loss(*args,**kwargs)
- else:
- pass
-
- defon_val_batch_end(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_val_batch_end(*args,**kwargs)
-
- defon_val_epoch_end(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_val_epoch_end(*args,**kwargs)
-
- defon_val_end(self,*args,**kwargs):
- forcinself.callbacks:
- c.on_val_end(*args,**kwargs)
-
-
-[docs]
-classCheckpointCallback(Callback):
- def__init__(
- self,
- save_dir:Union[Path,str],
- save_best:str=None,
- save_interval:int=1,
- save_optimizer:bool=False,
- save_scheduler:bool=False,
- save_regularizer:bool=False,
- resume_from_dir:Union[Path,str]=None,
- ):
-"""CheckpointCallback handles saving and resuming
- training state from checkpoint .pt save files.
-
- Parameters
- ----------
- save_dir : Union[Path, str], optional
- folder in which to save checkpoints, by default './checkpoints'
- save_best : str, optional
- metric to monitor for best value in order to save state
- save_interval : int, optional
- interval on which to save/check metric, by default 1
- save_optimizer : bool, optional
- whether to save optimizer state, by default False
- save_scheduler : bool, optional
- whether to save scheduler state, by default False
- save_regularizer : bool, optional
- whether to save regularizer state, by default False
- resume_from_dir : Union[Path, str], optional
- folder from which to resume training state.
- Expects saved states in the form: (all but model optional)
- (best_model.pt or model.pt), optimizer.pt, scheduler.pt, regularizer.pt
- All state files present will be loaded.
- if some metric was monitored during checkpointing,
- the file name will be best_model.pt.
- """
-
- super().__init__()
- ifisinstance(save_dir,str):
- save_dir=Path(save_dir)
- ifnotsave_dir.exists():
- save_dir.mkdir(parents=True)
- self.save_dir=save_dir
-
- self.save_interval=save_interval
- self.save_best=save_best
- self.save_optimizer=save_optimizer
- self.save_scheduler=save_scheduler
- self.save_regularizer=save_regularizer
-
- ifresume_from_dir:
- ifisinstance(resume_from_dir,str):
- resume_from_dir=Path(resume_from_dir)
- assertresume_from_dir.exists()
-
- self.resume_from_dir=resume_from_dir
-
- defon_init_end(self,*args,**kwargs):
- self._update_state_dict(**kwargs)
-
- defon_train_start(self,*args,**kwargs):
- self._update_state_dict(**kwargs)
-
- verbose=self.state_dict.get("verbose",False)
- ifself.save_best:
- assertself.state_dict[
- "eval_losses"
- ],"Error: cannot monitor a metric if no validation metrics exist."
- assert(
- self.save_bestinself.state_dict["eval_losses"].keys()
- ),"Error: cannot monitor a metric outside of eval_losses."
- self.best_metric_value=float("inf")
- else:
- self.best_metric_value=None
-
- # load state dict if resume_from_dir is given
- ifself.resume_from_dir:
- saved_modules=[x.stemforxinself.resume_from_dir.glob("*.pt")]
-
- # check for save model exists
- if(self.resume_from_dir/"best_model_state_dict.pt").exists():
- save_name="best_model"
- elif(self.resume_from_dir/"model_state_dict.pt").exists():
- save_name="model"
- else:
- raiseFileNotFoundError("Error: CheckpointCallback expects a model\
- state dict named model.pt or best_model.pt.")
- # returns key-value pairs "model":model, "optimizer":optimizer...
- training_state=load_training_state(save_dir=self.resume_from_dir,save_name=save_name,
- model=self.state_dict['model'],
- optimizer=self.state_dict.get('optimizer'),
- regularizer=self.state_dict.get('regularizer'),
- scheduler=self.state_dict.get('scheduler'))
-
- self._update_state_dict(**training_state)
-
- defon_epoch_start(self,*args,**kwargs):
- self._update_state_dict(**kwargs)
-
- defon_val_epoch_start(self,*args,**kwargs):
- self._update_state_dict(**kwargs)
-
-
-[docs]
- defon_val_epoch_end(self,*args,**kwargs):
-"""
- Update state dict with errors
- """
- self._update_state_dict(**kwargs)
-
-
-
-[docs]
- defon_epoch_end(self,*args,**kwargs):
-"""
- Save state to dir if all conditions are met
- """
- ifself.save_best:
- log_prefix=self.state_dict["log_prefix"]
- if(
- self.state_dict["errors"][f"{log_prefix}_{self.save_best}"]
- <self.best_metric_value
- ):
- metric_cond=True
- else:
- metric_cond=False
- else:
- metric_cond=True
-
- # Save states to save_dir
- ifself.state_dict["epoch"]%self.save_interval==0andmetric_cond:
- # save model or best_model.pt no matter what
- ifself.save_best:
- model_name="best_model"
- else:
- model_name="model"
-
- save_training_state(
- self.save_dir,
- model_name,
- model=self.state_dict["model"],
- optimizer=self.state_dict.get("optimizer",None),
- regularizer=self.state_dict.get("regularizer",None),
- scheduler=self.state_dict.get("scheduler",None),
- )
-
- ifself.state_dict["verbose"]:
- print(f"Saved training state to {self.save_dir}")
-
-
-
-classIncrementalCallback(Callback):
-"""
- Callback that implements the Incremental Algorithm - Both the Gradient explained and Loss Gap versions
-
- incremental : bool, default is False
- if True, use the base incremental algorithm which is based on gradient variance
- uses the incremental_grad_eps parameter - set the threshold for gradient variance
- uses the incremental_buffer paramater - sets the number of buffer modes to calculate the gradient variance
- uses the incremental_max_iter parameter - sets the initial number of iterations
- uses the incremental_grad_max_iter parameter - sets the maximum number of iterations to accumulate the gradients
- incremental_loss_gap : bool, default is False
- if True, use the incremental algorithm based on loss gap
- uses the incremental_loss_eps parameter
- """
-
- def__init__(self,
- incremental_grad:bool=False,
- incremental_loss_gap:bool=False,
- incremental_grad_eps:float=0.001,
- incremental_buffer:int=5,
- incremental_max_iter:int=1,
- incremental_grad_max_iter:int=10,
- incremental_loss_eps:float=0.001
- ):
- super().__init__()
- self.incremental_loss_gap=incremental_loss_gap
- self.incremental_grad=incremental_grad
- self.incremental=self.incremental_loss_gaporself.incremental_grad
- assertself.incremental,"Error: IncrementalCallback expects at least one incremental algorithm to be True."
- assertnot(self.incremental_loss_gapandself.incremental_grad),"Error: IncrementalCallback expects only one incremental algorithm to be True."
-
- self.incremental_grad_eps=incremental_grad_eps
- self.incremental_buffer=incremental_buffer
- self.incremental_max_iter=incremental_max_iter
- self.incremental_grad_max_iter=incremental_grad_max_iter
- self.incremental_loss_eps=incremental_loss_eps
- self.loss_list=[]
- self.mode="Train"
-
- defon_init_end(self,*args,**kwargs):
- self._update_state_dict(**kwargs)
-
- defon_train_start(self,**kwargs):
- self._update_state_dict(**kwargs)
-
- train_loader=self.state_dict['train_loader']
- test_loaders=self.state_dict['test_loaders']
- verbose=self.state_dict['verbose']
-
- n_train=len(train_loader.dataset)
- self._update_state_dict(n_train=n_train)
-
- ifnotisinstance(test_loaders,dict):
- test_loaders=dict(test=test_loaders)
-
- ifverbose:
- print(f'Training on {n_train} samples')
- print(f'Testing on {[len(loader.dataset)forloaderintest_loaders.values()]} samples'
- f' on resolutions {[namefornameintest_loaders]}.')
- sys.stdout.flush()
-
- defon_epoch_start(self,epoch):
- self._update_state_dict(epoch=epoch)
-
- defon_epoch_end(self,epoch,**kwargs):
- self._update_state_dict(epoch=epoch)
- print(f'Currently the model is using incremental_n_modes = {self.state_dict["model"].fno_blocks.convs.n_modes}')
-
- defon_batch_start(self,idx,**kwargs):
- self._update_state_dict(idx=idx)
- self.mode="Train"
- self.data=self.state_dict['data_processor']
- ifself.dataisnotNone:
- self.data.epoch=self.state_dict['epoch']
-
- defon_before_loss(self,out,**kwargs):
- ifself.state_dict['epoch']==0andself.state_dict['idx']==0 \
- andself.state_dict['verbose']:
- print(f'Raw outputs of size {out.shape=}')
-
- defon_before_val(self,epoch,train_err,time,avg_loss,avg_lasso_loss,**kwargs):
- # track training err and val losses to print at interval epochs
- msg=f'[{epoch}] time={time:.2f}, avg_loss={avg_loss:.4f}, train_err={train_err:.4f}'
-
- self.step(avg_loss)
-
- self._update_state_dict(msg=msg)
- self._update_state_dict(avg_lasso_loss=avg_lasso_loss)
-
- defon_val_epoch_end(self,errors,**kwargs):
- forloss_name,loss_valueinerrors.items():
- ifisinstance(loss_value,float):
- self.state_dict['msg']+=f', {loss_name}={loss_value:.4f}'
- else:
- loss_value={i:e.item()for(i,e)inenumerate(loss_value)}
- self.state_dict['msg']+=f', {loss_name}={loss_value}'
-
- defon_val_batch_start(self,*args,**kwargs):
- self.mode="Validation"
- ifself.dataisnotNone:
- self.data.epoch=self.state_dict['epoch']
-
- defon_val_end(self,*args,**kwargs):
- ifself.state_dict.get('regularizer',False):
- avg_lasso=self.state_dict.get('avg_lasso_loss',0.)
- avg_lasso/=self.state_dict.get('n_epochs')
- self.state_dict['msg']+=f', avg_lasso={avg_lasso:.5f}'
-
- print(self.state_dict['msg'])
- sys.stdout.flush()
-
- # Main step function: which algorithm to run
- defstep(self,loss=None):
- ifself.incremental_loss_gapandlossisnotNone:
- self.loss_gap(loss)
- ifself.incremental_grad:
- self.grad_explained()
-
- # Algorithm 1: Incremental
- defloss_gap(self,loss):
- self.loss_list.append(loss)
- self.ndim=len(self.state_dict['model'].fno_blocks.convs.n_modes)
- # method 1: loss_gap
- incremental_modes=self.state_dict['model'].fno_blocks.convs.n_modes[0]
- max_modes=self.state_dict['model'].fno_blocks.convs.max_n_modes[0]
- iflen(self.loss_list)>1:
- ifabs(self.loss_list[-1]-self.loss_list[-2])<=self.incremental_loss_eps:
- ifincremental_modes<max_modes:
- incremental_modes+=1
- modes_list=tuple([incremental_modes]*self.ndim)
- self.state_dict['model'].fno_blocks.convs.n_modes=modes_list
-
- # Algorithm 2: Gradient based explained ratio
- defgrad_explained(self):
- # for mode 1
- ifnothasattr(self,'accumulated_grad'):
- self.accumulated_grad=torch.zeros_like(
- self.state_dict['model'].fno_blocks.convs.weight[0])
- ifnothasattr(self,'grad_iter'):
- self.grad_iter=1
-
- self.ndim=len(self.state_dict['model'].fno_blocks.convs.n_modes)
- ifself.grad_iter<=self.incremental_grad_max_iter:
- self.grad_iter+=1
- self.accumulated_grad+=self.state_dict['model'].fno_blocks.convs.weight[0]
- else:
- incremental_final=[]
- foriinrange(self.ndim):
- max_modes=self.state_dict['model'].fno_blocks.convs.max_n_modes[i]
- incremental_modes=self.state_dict['model'].fno_blocks.convs.n_modes[i]
- weight=self.accumulated_grad
- strength_vector=[]
- formode_indexinrange(
- min(weight.shape[1],incremental_modes)):
- strength=torch.norm(
- weight[:,mode_index,:],p='fro')
- strength_vector.append(strength)
- expained_ratio=compute_explained_variance(
- incremental_modes-self.incremental_buffer,torch.Tensor(strength_vector))
- ifexpained_ratio<self.incremental_grad_eps:
- ifincremental_modes<max_modes:
- incremental_modes+=1
- incremental_final.append(incremental_modes)
-
- # update the modes and frequency dimensions
- self.grad_iter=1
- self.accumulated_grad=torch.zeros_like(
- self.state_dict['model'].fno_blocks.convs.weight[0])
- main_modes=incremental_final[0]
- modes_list=tuple([main_modes]*self.ndim)
- self.state_dict['model'].fno_blocks.convs.n_modes=tuple(modes_list)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dev/_modules/neuralop/training/incremental.html b/dev/_modules/neuralop/training/incremental.html
index d2298fd..2a8afca 100644
--- a/dev/_modules/neuralop/training/incremental.html
+++ b/dev/_modules/neuralop/training/incremental.html
@@ -16,7 +16,7 @@
-
+
@@ -241,17 +241,17 @@
Source code for neuralop.training.incremental
scalar value of epoch's training loss
"""self.loss_list.append(loss)
- self.ndim=len(self.model.fno_blocks.convs[0].n_modes)
+ self.ndim=len(self.model.fno_blocks.convs.n_modes)# method 1: loss_gap
- incremental_modes=self.model.fno_blocks.convs[0].n_modes[0]
- max_modes=self.model.fno_blocks.convs[0].max_n_modes[0]
+ incremental_modes=self.model.fno_blocks.convs.n_modes[0]
+ max_modes=self.model.fno_blocks.convs.max_n_modes[0]iflen(self.loss_list)>1:ifabs(self.loss_list[-1]-self.loss_list[-2])<=self.incremental_loss_eps:ifincremental_modes<max_modes:incremental_modes+=1modes_list=tuple([incremental_modes]*self.ndim)
- self.model.fno_blocks.convs[0].n_modes=modes_list
+ self.model.fno_blocks.convs.n_modes=modes_list
# Algorithm 2: Gradient based explained ratio
@@ -259,19 +259,19 @@
# update the modes and frequency dimensions
self.grad_iter=1self.accumulated_grad=torch.zeros_like(
- self.model.fno_blocks.convs[0].weight)
+ self.model.fno_blocks.convs.weight[0])main_modes=incremental_final[0]modes_list=tuple([main_modes]*self.ndim)
- self.model.fno_blocks.convs[0].n_modes=tuple(modes_list)
diff --git a/dev/_modules/neuralop/training/trainer.html b/dev/_modules/neuralop/training/trainer.html
index d015f2f..b164348 100644
--- a/dev/_modules/neuralop/training/trainer.html
+++ b/dev/_modules/neuralop/training/trainer.html
@@ -16,7 +16,7 @@
-
+
diff --git a/dev/_sources/auto_examples/checkpoint_FNO_darcy.rst.txt b/dev/_sources/auto_examples/checkpoint_FNO_darcy.rst.txt
index 10290d9..f955fbf 100644
--- a/dev/_sources/auto_examples/checkpoint_FNO_darcy.rst.txt
+++ b/dev/_sources/auto_examples/checkpoint_FNO_darcy.rst.txt
@@ -62,19 +62,12 @@ Loading the Navier-Stokes dataset in 128x128 resolution
We create a tensorized FNO model
-.. GENERATED FROM PYTHON SOURCE LINES 35-51
+.. GENERATED FROM PYTHON SOURCE LINES 35-44
.. code-block:: Python
- model = TFNO(n_modes=(16, 16),
- in_channels=1,
- out_channels=1,
- hidden_channels=32,
- projection_channels=64,
- factorization='tucker',
- rank=0.42)
-
+ model = TFNO(n_modes=(16, 16), in_channels=1, hidden_channels=32, projection_channels=64, factorization='tucker', rank=0.42)
model = model.to(device)
n_params = count_model_params(model)
@@ -83,11 +76,11 @@ We create a tensorized FNO model
-.. GENERATED FROM PYTHON SOURCE LINES 52-53
+.. GENERATED FROM PYTHON SOURCE LINES 45-46
Create the optimizer
-.. GENERATED FROM PYTHON SOURCE LINES 53-59
+.. GENERATED FROM PYTHON SOURCE LINES 46-52
.. code-block:: Python
@@ -98,11 +91,11 @@ Create the optimizer
-.. GENERATED FROM PYTHON SOURCE LINES 60-61
+.. GENERATED FROM PYTHON SOURCE LINES 53-54
Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 61-68
+.. GENERATED FROM PYTHON SOURCE LINES 54-61
.. code-block:: Python
@@ -114,7 +107,7 @@ Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 69-80
+.. GENERATED FROM PYTHON SOURCE LINES 62-73
.. code-block:: Python
@@ -130,11 +123,11 @@ Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 81-82
+.. GENERATED FROM PYTHON SOURCE LINES 74-75
Create the trainer
-.. GENERATED FROM PYTHON SOURCE LINES 82-91
+.. GENERATED FROM PYTHON SOURCE LINES 75-84
.. code-block:: Python
@@ -148,11 +141,11 @@ Create the trainer
-.. GENERATED FROM PYTHON SOURCE LINES 92-93
+.. GENERATED FROM PYTHON SOURCE LINES 85-86
Actually train the model on our small Darcy-Flow dataset
-.. GENERATED FROM PYTHON SOURCE LINES 93-120
+.. GENERATED FROM PYTHON SOURCE LINES 86-113
.. code-block:: Python
@@ -199,6 +192,10 @@ Actually train the model on our small Darcy-Flow dataset
:download:`Download Python source code: checkpoint_FNO_darcy.py `
+ .. container:: sphx-glr-download sphx-glr-download-zip
+
+ :download:`Download zipped: checkpoint_FNO_darcy.zip `
+
.. only:: html
diff --git a/dev/_sources/auto_examples/darcy_data_processor.rst.txt b/dev/_sources/auto_examples/darcy_data_processor.rst.txt
deleted file mode 100644
index 4a6c029..0000000
--- a/dev/_sources/auto_examples/darcy_data_processor.rst.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-
-.. DO NOT EDIT.
-.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
-.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
-.. "auto_examples/darcy_data_processor.py"
-.. LINE NUMBERS ARE GIVEN BELOW.
-
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- :ref:`Go to the end `
- to download the full example code.
-
-.. rst-class:: sphx-glr-example-title
-
-.. _sphx_glr_auto_examples_darcy_data_processor.py:
-
-
-Data Processors
-=============================
-
-In this example, we demonstrate how to use neuralop.data.transforms.DataProcessor
-to preprocess and postprocess the small Darcy Flow example we ship with the package
-for downstream use in training a neural operator model.
-
-.. GENERATED FROM PYTHON SOURCE LINES 12-27
-
-.. code-block:: Python
-
- import torch
- import matplotlib.pyplot as plt
- import sys
- from neuralop.models import TFNO
- from neuralop import Trainer
- from neuralop.training import CheckpointCallback
- from neuralop.data.datasets import load_darcy_flow_small
- from neuralop.utils import count_model_params
- from neuralop import LpLoss, H1Loss
-
- device = 'cpu'
-
- """
- First, let's load the small Darcy Flow dataset:
- """
-
-.. GENERATED FROM PYTHON SOURCE LINES 28-29
-
-Loading the Navier-Stokes dataset in 128x128 resolution
-
-.. GENERATED FROM PYTHON SOURCE LINES 29-36
-
-.. code-block:: Python
-
- train_loader, test_loaders, data_processor = load_darcy_flow_small(
- n_train=1000, batch_size=32,
- test_resolutions=[16, 32], n_tests=[100, 50],
- test_batch_sizes=[32, 32],
- data_root="../neuralop/data/datasets/data/"
- )
-
-
-.. GENERATED FROM PYTHON SOURCE LINES 37-39
-
-.. code-block:: Python
-
- """
- Next let's visualize the data in its raw form.
- """
-
-.. _sphx_glr_download_auto_examples_darcy_data_processor.py:
-
-.. only:: html
-
- .. container:: sphx-glr-footer sphx-glr-footer-example
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: darcy_data_processor.ipynb `
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: darcy_data_processor.py `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/dev/_sources/auto_examples/index.rst.txt b/dev/_sources/auto_examples/index.rst.txt
index e2fa91b..6edc759 100644
--- a/dev/_sources/auto_examples/index.rst.txt
+++ b/dev/_sources/auto_examples/index.rst.txt
@@ -18,7 +18,7 @@ Gallery of examples
.. raw:: html
-
+
.. only:: html
@@ -52,7 +52,7 @@ Gallery of examples
.. raw:: html
-
+
.. only:: html
@@ -69,7 +69,7 @@ Gallery of examples
.. raw:: html
-
+
.. only:: html
@@ -80,13 +80,13 @@ Gallery of examples
.. raw:: html
-
Training an FNO on Darcy-Flow
+
Training a TFNO on Darcy-Flow
.. raw:: html
-
+
.. only:: html
@@ -103,7 +103,7 @@ Gallery of examples
.. raw:: html
-
+
.. only:: html
diff --git a/dev/_sources/auto_examples/plot_FNO_darcy.rst.txt b/dev/_sources/auto_examples/plot_FNO_darcy.rst.txt
index a771d21..85bebd2 100644
--- a/dev/_sources/auto_examples/plot_FNO_darcy.rst.txt
+++ b/dev/_sources/auto_examples/plot_FNO_darcy.rst.txt
@@ -18,21 +18,22 @@
.. _sphx_glr_auto_examples_plot_FNO_darcy.py:
-Training an FNO on Darcy-Flow
+Training a TFNO on Darcy-Flow
=============================
In this example, we demonstrate how to use the small Darcy-Flow example we ship with the package
-to train a Fourier-Neural Operator
+to train a Tensorized Fourier-Neural Operator
-.. GENERATED FROM PYTHON SOURCE LINES 11-25
+.. GENERATED FROM PYTHON SOURCE LINES 11-26
.. code-block:: Python
+
import torch
import matplotlib.pyplot as plt
import sys
- from neuralop.models import FNO
+ from neuralop.models import TFNO
from neuralop import Trainer
from neuralop.training import AdamW
from neuralop.data.datasets import load_darcy_flow_small
@@ -49,11 +50,11 @@ to train a Fourier-Neural Operator
-.. GENERATED FROM PYTHON SOURCE LINES 26-27
+.. GENERATED FROM PYTHON SOURCE LINES 27-28
Loading the Navier-Stokes dataset in 128x128 resolution
-.. GENERATED FROM PYTHON SOURCE LINES 27-35
+.. GENERATED FROM PYTHON SOURCE LINES 28-36
.. code-block:: Python
@@ -73,26 +74,26 @@ Loading the Navier-Stokes dataset in 128x128 resolution
.. code-block:: none
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
Loading test db for resolution 16 with 100 samples
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Loading test db for resolution 32 with 50 samples
-.. GENERATED FROM PYTHON SOURCE LINES 36-37
+.. GENERATED FROM PYTHON SOURCE LINES 37-38
-We create a simple FNO model
+We create a tensorized FNO model
-.. GENERATED FROM PYTHON SOURCE LINES 37-50
+.. GENERATED FROM PYTHON SOURCE LINES 38-47
.. code-block:: Python
- model = FNO(n_modes=(16, 16),
- in_channels=1,
- out_channels=1,
- hidden_channels=32,
- projection_channels=64)
+ model = TFNO(n_modes=(16, 16), in_channels=1, hidden_channels=32, projection_channels=64, factorization='tucker', rank=0.42)
model = model.to(device)
n_params = count_model_params(model)
@@ -109,16 +110,16 @@ We create a simple FNO model
.. code-block:: none
- Our model has 1188385 parameters.
+ Our model has 523257 parameters.
-.. GENERATED FROM PYTHON SOURCE LINES 51-52
+.. GENERATED FROM PYTHON SOURCE LINES 48-49
Create the optimizer
-.. GENERATED FROM PYTHON SOURCE LINES 52-58
+.. GENERATED FROM PYTHON SOURCE LINES 49-55
.. code-block:: Python
@@ -135,11 +136,11 @@ Create the optimizer
-.. GENERATED FROM PYTHON SOURCE LINES 59-60
+.. GENERATED FROM PYTHON SOURCE LINES 56-57
Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 60-67
+.. GENERATED FROM PYTHON SOURCE LINES 57-64
.. code-block:: Python
@@ -157,7 +158,7 @@ Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 68-79
+.. GENERATED FROM PYTHON SOURCE LINES 65-76
.. code-block:: Python
@@ -182,12 +183,12 @@ Creating the losses
### MODEL ###
- FNO(
+ TFNO(
(positional_embedding): GridEmbeddingND()
(fno_blocks): FNOBlocks(
- (convs): ModuleList(
- (0-3): 4 x SpectralConv(
- (weight): DenseTensor(shape=torch.Size([32, 32, 16, 9]), rank=None)
+ (convs): SpectralConv(
+ (weight): ModuleList(
+ (0-3): 4 x TuckerTensor(shape=(32, 32, 16, 9), rank=(26, 26, 13, 7))
)
)
(fno_skips): ModuleList(
@@ -198,8 +199,8 @@ Creating the losses
)
(lifting): ChannelMLP(
(fcs): ModuleList(
- (0): Conv1d(3, 64, kernel_size=(1,), stride=(1,))
- (1): Conv1d(64, 32, kernel_size=(1,), stride=(1,))
+ (0): Conv1d(3, 256, kernel_size=(1,), stride=(1,))
+ (1): Conv1d(256, 32, kernel_size=(1,), stride=(1,))
)
)
(projection): ChannelMLP(
@@ -222,22 +223,22 @@ Creating the losses
)
### SCHEDULER ###
-
+
### LOSSES ###
- * Train:
+ * Train:
- * Test: {'h1': , 'l2': }
+ * Test: {'h1': , 'l2': }
-.. GENERATED FROM PYTHON SOURCE LINES 80-81
+.. GENERATED FROM PYTHON SOURCE LINES 77-78
Create the trainer
-.. GENERATED FROM PYTHON SOURCE LINES 81-90
+.. GENERATED FROM PYTHON SOURCE LINES 78-87
.. code-block:: Python
@@ -257,11 +258,11 @@ Create the trainer
-.. GENERATED FROM PYTHON SOURCE LINES 91-92
+.. GENERATED FROM PYTHON SOURCE LINES 88-89
Actually train the model on our small Darcy-Flow dataset
-.. GENERATED FROM PYTHON SOURCE LINES 92-102
+.. GENERATED FROM PYTHON SOURCE LINES 89-99
.. code-block:: Python
@@ -286,26 +287,26 @@ Actually train the model on our small Darcy-Flow dataset
Training on 1000 samples
Testing on [50, 50] samples on resolutions [16, 32].
Raw outputs of shape torch.Size([32, 1, 16, 16])
- [0] time=1.66, avg_loss=0.5065, train_err=15.8288
- Eval: 16_h1=0.2896, 16_l2=0.2301, 32_h1=0.3807, 32_l2=0.2436
- [3] time=1.55, avg_loss=0.2119, train_err=6.6233
- Eval: 16_h1=0.1865, 16_l2=0.1367, 32_h1=0.3028, 32_l2=0.1624
- [6] time=1.54, avg_loss=0.1922, train_err=6.0064
- Eval: 16_h1=0.2095, 16_l2=0.1634, 32_h1=0.3203, 32_l2=0.1882
- [9] time=1.54, avg_loss=0.1814, train_err=5.6678
- Eval: 16_h1=0.1942, 16_l2=0.1419, 32_h1=0.3132, 32_l2=0.1671
- [12] time=1.54, avg_loss=0.1636, train_err=5.1129
- Eval: 16_h1=0.2336, 16_l2=0.1748, 32_h1=0.3897, 32_l2=0.2129
- [15] time=1.53, avg_loss=0.1126, train_err=3.5185
- Eval: 16_h1=0.1868, 16_l2=0.1356, 32_h1=0.3154, 32_l2=0.1651
- [18] time=1.54, avg_loss=0.1192, train_err=3.7263
- Eval: 16_h1=0.1858, 16_l2=0.1359, 32_h1=0.3326, 32_l2=0.1827
+ [0] time=2.66, avg_loss=0.9003, train_err=28.1341
+ Eval: 16_h1=0.4747, 16_l2=0.3676, 32_h1=0.5249, 32_l2=0.3596
+ [3] time=2.69, avg_loss=0.3368, train_err=10.5251
+ Eval: 16_h1=0.2390, 16_l2=0.1887, 32_h1=0.3212, 32_l2=0.1959
+ [6] time=2.63, avg_loss=0.2176, train_err=6.8002
+ Eval: 16_h1=0.3172, 16_l2=0.2739, 32_h1=0.3649, 32_l2=0.2818
+ [9] time=2.66, avg_loss=0.1803, train_err=5.6347
+ Eval: 16_h1=0.1602, 16_l2=0.1168, 32_h1=0.2624, 32_l2=0.1403
+ [12] time=2.69, avg_loss=0.1738, train_err=5.4326
+ Eval: 16_h1=0.1735, 16_l2=0.1389, 32_h1=0.2747, 32_l2=0.1699
+ [15] time=2.65, avg_loss=0.1604, train_err=5.0136
+ Eval: 16_h1=0.1394, 16_l2=0.0983, 32_h1=0.2542, 32_l2=0.1292
+ [18] time=2.65, avg_loss=0.1506, train_err=4.7071
+ Eval: 16_h1=0.1596, 16_l2=0.1228, 32_h1=0.2629, 32_l2=0.1533
- {'train_err': 3.398870412260294, 'avg_loss': 0.10876385319232941, 'avg_lasso_loss': None, 'epoch_train_time': 1.5358347818255424}
+ {'train_err': 4.956099387258291, 'avg_loss': 0.15859518039226533, 'avg_lasso_loss': None, 'epoch_train_time': 2.642554324999992}
-.. GENERATED FROM PYTHON SOURCE LINES 103-113
+.. GENERATED FROM PYTHON SOURCE LINES 100-110
Plot the prediction, and compare with the ground-truth
Note that we trained on a very small resolution for
@@ -318,7 +319,7 @@ ii) can be trained quickly on CPU
In practice we would train a Neural Operator on one or multiple GPUs
-.. GENERATED FROM PYTHON SOURCE LINES 113-151
+.. GENERATED FROM PYTHON SOURCE LINES 110-148
.. code-block:: Python
@@ -375,7 +376,7 @@ In practice we would train a Neural Operator on one or multiple GPUs
.. rst-class:: sphx-glr-timing
- **Total running time of the script:** (0 minutes 32.144 seconds)
+ **Total running time of the script:** (0 minutes 54.415 seconds)
.. _sphx_glr_download_auto_examples_plot_FNO_darcy.py:
@@ -392,6 +393,10 @@ In practice we would train a Neural Operator on one or multiple GPUs
:download:`Download Python source code: plot_FNO_darcy.py `
+ .. container:: sphx-glr-download sphx-glr-download-zip
+
+ :download:`Download zipped: plot_FNO_darcy.zip `
+
.. only:: html
diff --git a/dev/_sources/auto_examples/plot_SFNO_swe.rst.txt b/dev/_sources/auto_examples/plot_SFNO_swe.rst.txt
index e32be99..d0d3a0d 100644
--- a/dev/_sources/auto_examples/plot_SFNO_swe.rst.txt
+++ b/dev/_sources/auto_examples/plot_SFNO_swe.rst.txt
@@ -80,17 +80,12 @@ Loading the Navier-Stokes dataset in 128x128 resolution
We create a tensorized FNO model
-.. GENERATED FROM PYTHON SOURCE LINES 33-47
+.. GENERATED FROM PYTHON SOURCE LINES 33-42
.. code-block:: Python
- model = SFNO(n_modes=(32, 32),
- in_channels=3,
- out_channels=3,
- hidden_channels=32,
- projection_channels=64,
- factorization='dense')
+ model = SFNO(n_modes=(32, 32), in_channels=3, out_channels=3, hidden_channels=32, projection_channels=64, factorization='dense')
model = model.to(device)
n_params = count_model_params(model)
@@ -106,21 +101,17 @@ We create a tensorized FNO model
.. code-block:: none
- self.sht_grids=['equiangular', 'equiangular']
- self.sht_grids=['equiangular', 'equiangular']
- self.sht_grids=['equiangular', 'equiangular']
- self.sht_grids=['equiangular', 'equiangular']
- Our model has 275555 parameters.
+ Our model has 278435 parameters.
-.. GENERATED FROM PYTHON SOURCE LINES 48-49
+.. GENERATED FROM PYTHON SOURCE LINES 43-44
Create the optimizer
-.. GENERATED FROM PYTHON SOURCE LINES 49-55
+.. GENERATED FROM PYTHON SOURCE LINES 44-50
.. code-block:: Python
@@ -137,11 +128,11 @@ Create the optimizer
-.. GENERATED FROM PYTHON SOURCE LINES 56-57
+.. GENERATED FROM PYTHON SOURCE LINES 51-52
Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 57-64
+.. GENERATED FROM PYTHON SOURCE LINES 52-59
.. code-block:: Python
@@ -159,7 +150,7 @@ Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 65-76
+.. GENERATED FROM PYTHON SOURCE LINES 60-71
.. code-block:: Python
@@ -187,13 +178,13 @@ Creating the losses
SFNO(
(positional_embedding): GridEmbeddingND()
(fno_blocks): FNOBlocks(
- (convs): ModuleList(
- (0-3): 4 x SphericalConv(
- (weight): ComplexDenseTensor(shape=torch.Size([32, 32, 32]), rank=None)
- (sht_handle): SHT(
- (_SHT_cache): ModuleDict()
- (_iSHT_cache): ModuleDict()
- )
+ (convs): SphericalConv(
+ (weight): ModuleList(
+ (0-3): 4 x ComplexDenseTensor(shape=torch.Size([32, 32, 32]), rank=None)
+ )
+ (sht_handle): SHT(
+ (_SHT_cache): ModuleDict()
+ (_iSHT_cache): ModuleDict()
)
)
(fno_skips): ModuleList(
@@ -201,22 +192,11 @@ Creating the losses
(conv): Conv1d(32, 32, kernel_size=(1,), stride=(1,), bias=False)
)
)
- (channel_mlp): ModuleList(
- (0-3): 4 x ChannelMLP(
- (fcs): ModuleList(
- (0): Conv1d(32, 16, kernel_size=(1,), stride=(1,))
- (1): Conv1d(16, 32, kernel_size=(1,), stride=(1,))
- )
- )
- )
- (channel_mlp_skips): ModuleList(
- (0-3): 4 x SoftGating()
- )
)
(lifting): ChannelMLP(
(fcs): ModuleList(
- (0): Conv1d(5, 64, kernel_size=(1,), stride=(1,))
- (1): Conv1d(64, 32, kernel_size=(1,), stride=(1,))
+ (0): Conv1d(5, 256, kernel_size=(1,), stride=(1,))
+ (1): Conv1d(256, 32, kernel_size=(1,), stride=(1,))
)
)
(projection): ChannelMLP(
@@ -239,22 +219,22 @@ Creating the losses
)
### SCHEDULER ###
-
+
### LOSSES ###
- * Train:
+ * Train:
- * Test: {'l2': }
+ * Test: {'l2': }
-.. GENERATED FROM PYTHON SOURCE LINES 77-78
+.. GENERATED FROM PYTHON SOURCE LINES 72-73
Create the trainer
-.. GENERATED FROM PYTHON SOURCE LINES 78-86
+.. GENERATED FROM PYTHON SOURCE LINES 73-81
.. code-block:: Python
@@ -273,11 +253,11 @@ Create the trainer
-.. GENERATED FROM PYTHON SOURCE LINES 87-88
+.. GENERATED FROM PYTHON SOURCE LINES 82-83
Actually train the model on our small Darcy-Flow dataset
-.. GENERATED FROM PYTHON SOURCE LINES 88-98
+.. GENERATED FROM PYTHON SOURCE LINES 83-93
.. code-block:: Python
@@ -302,26 +282,26 @@ Actually train the model on our small Darcy-Flow dataset
Training on 200 samples
Testing on [50, 50] samples on resolutions [(32, 64), (64, 128)].
Raw outputs of shape torch.Size([4, 3, 32, 64])
- [0] time=0.91, avg_loss=2.6421, train_err=10.5682
- Eval: (32, 64)_l2=2.1051, (64, 128)_l2=2.4542
- [3] time=0.84, avg_loss=0.3812, train_err=1.5250
- Eval: (32, 64)_l2=0.5328, (64, 128)_l2=2.3434
- [6] time=0.73, avg_loss=0.2580, train_err=1.0322
- Eval: (32, 64)_l2=0.5245, (64, 128)_l2=2.2983
- [9] time=0.73, avg_loss=0.2163, train_err=0.8652
- Eval: (32, 64)_l2=0.4739, (64, 128)_l2=2.2781
- [12] time=0.73, avg_loss=0.1938, train_err=0.7753
- Eval: (32, 64)_l2=0.4735, (64, 128)_l2=2.2642
- [15] time=0.73, avg_loss=0.1628, train_err=0.6512
- Eval: (32, 64)_l2=0.4826, (64, 128)_l2=2.2505
- [18] time=0.73, avg_loss=0.1391, train_err=0.5565
- Eval: (32, 64)_l2=0.4369, (64, 128)_l2=2.2668
+ [0] time=3.46, avg_loss=2.2655, train_err=9.0619
+ Eval: (32, 64)_l2=1.6165, (64, 128)_l2=2.6751
+ [3] time=3.47, avg_loss=0.4604, train_err=1.8414
+ Eval: (32, 64)_l2=0.5567, (64, 128)_l2=2.3834
+ [6] time=3.44, avg_loss=0.3189, train_err=1.2755
+ Eval: (32, 64)_l2=0.4640, (64, 128)_l2=2.3548
+ [9] time=3.41, avg_loss=0.2569, train_err=1.0278
+ Eval: (32, 64)_l2=0.4651, (64, 128)_l2=2.3221
+ [12] time=3.41, avg_loss=0.2121, train_err=0.8484
+ Eval: (32, 64)_l2=0.3232, (64, 128)_l2=2.3157
+ [15] time=3.40, avg_loss=0.1598, train_err=0.6390
+ Eval: (32, 64)_l2=0.2673, (64, 128)_l2=2.3022
+ [18] time=3.44, avg_loss=0.1432, train_err=0.5729
+ Eval: (32, 64)_l2=0.2376, (64, 128)_l2=2.3091
- {'train_err': 0.5427721077203751, 'avg_loss': 0.13569302693009377, 'avg_lasso_loss': None, 'epoch_train_time': 0.7358115278184414}
+ {'train_err': 0.550230712890625, 'avg_loss': 0.13755767822265624, 'avg_lasso_loss': None, 'epoch_train_time': 3.4114261440000746}
-.. GENERATED FROM PYTHON SOURCE LINES 99-109
+.. GENERATED FROM PYTHON SOURCE LINES 94-104
Plot the prediction, and compare with the ground-truth
Note that we trained on a very small resolution for
@@ -334,7 +314,7 @@ ii) can be trained quickly on CPU
In practice we would train a Neural Operator on one or multiple GPUs
-.. GENERATED FROM PYTHON SOURCE LINES 109-144
+.. GENERATED FROM PYTHON SOURCE LINES 104-139
.. code-block:: Python
@@ -388,7 +368,7 @@ In practice we would train a Neural Operator on one or multiple GPUs
.. rst-class:: sphx-glr-timing
- **Total running time of the script:** (0 minutes 20.521 seconds)
+ **Total running time of the script:** (1 minutes 25.030 seconds)
.. _sphx_glr_download_auto_examples_plot_SFNO_swe.py:
@@ -405,6 +385,10 @@ In practice we would train a Neural Operator on one or multiple GPUs
:download:`Download Python source code: plot_SFNO_swe.py `
+ .. container:: sphx-glr-download sphx-glr-download-zip
+
+ :download:`Download zipped: plot_SFNO_swe.zip `
+
.. only:: html
diff --git a/dev/_sources/auto_examples/plot_UNO_darcy.rst.txt b/dev/_sources/auto_examples/plot_UNO_darcy.rst.txt
index e25dfa5..e6793e3 100644
--- a/dev/_sources/auto_examples/plot_UNO_darcy.rst.txt
+++ b/dev/_sources/auto_examples/plot_UNO_darcy.rst.txt
@@ -54,7 +54,7 @@ the small Darcy-Flow example we ship with the package
Loading the Darcy Flow dataset
-.. GENERATED FROM PYTHON SOURCE LINES 28-53
+.. GENERATED FROM PYTHON SOURCE LINES 28-46
.. code-block:: Python
@@ -64,18 +64,11 @@ Loading the Darcy Flow dataset
test_batch_sizes=[32, 32],
)
- model = UNO(in_channels=1,
- out_channels=1,
- hidden_channels=64,
- projection_channels=64,
- uno_out_channels=[32,64,64,64,32],
- uno_n_modes=[[16,16],[8,8],[8,8],[8,8],[16,16]],
- uno_scalings=[[1.0,1.0],[0.5,0.5],[1,1],[2,2],[1,1]],
- horizontal_skips_map=None,
- channel_mlp_skip="linear",
- n_layers = 5,
- domain_padding=0.2)
+
+ model = UNO(in_channels=1, out_channels=1, hidden_channels=64, projection_channels=64,uno_out_channels = [32,64,64,64,32], \
+ uno_n_modes= [[16,16],[8,8],[8,8],[8,8],[16,16]], uno_scalings= [[1.0,1.0],[0.5,0.5],[1,1],[2,2],[1,1]],\
+ horizontal_skips_map = None, n_layers = 5, domain_padding = 0.2)
model = model.to(device)
n_params = count_model_params(model)
@@ -91,29 +84,23 @@ Loading the Darcy Flow dataset
.. code-block:: none
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
Loading test db for resolution 16 with 100 samples
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Loading test db for resolution 32 with 50 samples
- fno_skip='linear'
- channel_mlp_skip='linear'
- fno_skip='linear'
- channel_mlp_skip='linear'
- fno_skip='linear'
- channel_mlp_skip='linear'
- fno_skip='linear'
- channel_mlp_skip='linear'
- fno_skip='linear'
- channel_mlp_skip='linear'
- Our model has 2700097 parameters.
+ Our model has 2665921 parameters.
-.. GENERATED FROM PYTHON SOURCE LINES 54-55
+.. GENERATED FROM PYTHON SOURCE LINES 47-48
Create the optimizer
-.. GENERATED FROM PYTHON SOURCE LINES 55-61
+.. GENERATED FROM PYTHON SOURCE LINES 48-54
.. code-block:: Python
@@ -130,11 +117,11 @@ Create the optimizer
-.. GENERATED FROM PYTHON SOURCE LINES 62-63
+.. GENERATED FROM PYTHON SOURCE LINES 55-56
Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 63-70
+.. GENERATED FROM PYTHON SOURCE LINES 56-63
.. code-block:: Python
@@ -152,7 +139,7 @@ Creating the losses
-.. GENERATED FROM PYTHON SOURCE LINES 71-82
+.. GENERATED FROM PYTHON SOURCE LINES 64-75
.. code-block:: Python
@@ -188,9 +175,9 @@ Creating the losses
)
(fno_blocks): ModuleList(
(0): FNOBlocks(
- (convs): ModuleList(
- (0): SpectralConv(
- (weight): DenseTensor(shape=torch.Size([64, 32, 16, 9]), rank=None)
+ (convs): SpectralConv(
+ (weight): ModuleList(
+ (0): DenseTensor(shape=torch.Size([64, 32, 16, 9]), rank=None)
)
)
(fno_skips): ModuleList(
@@ -198,24 +185,11 @@ Creating the losses
(conv): Conv1d(64, 32, kernel_size=(1,), stride=(1,), bias=False)
)
)
- (channel_mlp): ModuleList(
- (0): ChannelMLP(
- (fcs): ModuleList(
- (0): Conv1d(32, 16, kernel_size=(1,), stride=(1,))
- (1): Conv1d(16, 32, kernel_size=(1,), stride=(1,))
- )
- )
- )
- (channel_mlp_skips): ModuleList(
- (0): Flattened1dConv(
- (conv): Conv1d(64, 32, kernel_size=(1,), stride=(1,), bias=False)
- )
- )
)
(1): FNOBlocks(
- (convs): ModuleList(
- (0): SpectralConv(
- (weight): DenseTensor(shape=torch.Size([32, 64, 8, 5]), rank=None)
+ (convs): SpectralConv(
+ (weight): ModuleList(
+ (0): DenseTensor(shape=torch.Size([32, 64, 8, 5]), rank=None)
)
)
(fno_skips): ModuleList(
@@ -223,24 +197,11 @@ Creating the losses
(conv): Conv1d(32, 64, kernel_size=(1,), stride=(1,), bias=False)
)
)
- (channel_mlp): ModuleList(
- (0): ChannelMLP(
- (fcs): ModuleList(
- (0): Conv1d(64, 32, kernel_size=(1,), stride=(1,))
- (1): Conv1d(32, 64, kernel_size=(1,), stride=(1,))
- )
- )
- )
- (channel_mlp_skips): ModuleList(
- (0): Flattened1dConv(
- (conv): Conv1d(32, 64, kernel_size=(1,), stride=(1,), bias=False)
- )
- )
)
(2): FNOBlocks(
- (convs): ModuleList(
- (0): SpectralConv(
- (weight): DenseTensor(shape=torch.Size([64, 64, 8, 5]), rank=None)
+ (convs): SpectralConv(
+ (weight): ModuleList(
+ (0): DenseTensor(shape=torch.Size([64, 64, 8, 5]), rank=None)
)
)
(fno_skips): ModuleList(
@@ -248,24 +209,11 @@ Creating the losses
(conv): Conv1d(64, 64, kernel_size=(1,), stride=(1,), bias=False)
)
)
- (channel_mlp): ModuleList(
- (0): ChannelMLP(
- (fcs): ModuleList(
- (0): Conv1d(64, 32, kernel_size=(1,), stride=(1,))
- (1): Conv1d(32, 64, kernel_size=(1,), stride=(1,))
- )
- )
- )
- (channel_mlp_skips): ModuleList(
- (0): Flattened1dConv(
- (conv): Conv1d(64, 64, kernel_size=(1,), stride=(1,), bias=False)
- )
- )
)
(3): FNOBlocks(
- (convs): ModuleList(
- (0): SpectralConv(
- (weight): DenseTensor(shape=torch.Size([128, 64, 8, 5]), rank=None)
+ (convs): SpectralConv(
+ (weight): ModuleList(
+ (0): DenseTensor(shape=torch.Size([128, 64, 8, 5]), rank=None)
)
)
(fno_skips): ModuleList(
@@ -273,24 +221,11 @@ Creating the losses
(conv): Conv1d(128, 64, kernel_size=(1,), stride=(1,), bias=False)
)
)
- (channel_mlp): ModuleList(
- (0): ChannelMLP(
- (fcs): ModuleList(
- (0): Conv1d(64, 32, kernel_size=(1,), stride=(1,))
- (1): Conv1d(32, 64, kernel_size=(1,), stride=(1,))
- )
- )
- )
- (channel_mlp_skips): ModuleList(
- (0): Flattened1dConv(
- (conv): Conv1d(128, 64, kernel_size=(1,), stride=(1,), bias=False)
- )
- )
)
(4): FNOBlocks(
- (convs): ModuleList(
- (0): SpectralConv(
- (weight): DenseTensor(shape=torch.Size([96, 32, 16, 9]), rank=None)
+ (convs): SpectralConv(
+ (weight): ModuleList(
+ (0): DenseTensor(shape=torch.Size([96, 32, 16, 9]), rank=None)
)
)
(fno_skips): ModuleList(
@@ -298,19 +233,6 @@ Creating the losses
(conv): Conv1d(96, 32, kernel_size=(1,), stride=(1,), bias=False)
)
)
- (channel_mlp): ModuleList(
- (0): ChannelMLP(
- (fcs): ModuleList(
- (0): Conv1d(32, 16, kernel_size=(1,), stride=(1,))
- (1): Conv1d(16, 32, kernel_size=(1,), stride=(1,))
- )
- )
- )
- (channel_mlp_skips): ModuleList(
- (0): Flattened1dConv(
- (conv): Conv1d(96, 32, kernel_size=(1,), stride=(1,), bias=False)
- )
- )
)
)
(horizontal_skips): ModuleDict(
@@ -341,22 +263,22 @@ Creating the losses
)
### SCHEDULER ###
-
+
### LOSSES ###
- * Train:
+ * Train:
- * Test: {'h1': , 'l2': }
+ * Test: {'h1': , 'l2': }
-.. GENERATED FROM PYTHON SOURCE LINES 83-84
+.. GENERATED FROM PYTHON SOURCE LINES 76-77
Create the trainer
-.. GENERATED FROM PYTHON SOURCE LINES 84-94
+.. GENERATED FROM PYTHON SOURCE LINES 77-87
.. code-block:: Python
@@ -377,11 +299,11 @@ Create the trainer
-.. GENERATED FROM PYTHON SOURCE LINES 95-96
+.. GENERATED FROM PYTHON SOURCE LINES 88-89
Actually train the model on our small Darcy-Flow dataset
-.. GENERATED FROM PYTHON SOURCE LINES 96-106
+.. GENERATED FROM PYTHON SOURCE LINES 89-99
.. code-block:: Python
@@ -406,26 +328,26 @@ Actually train the model on our small Darcy-Flow dataset
Training on 1000 samples
Testing on [50, 50] samples on resolutions [16, 32].
Raw outputs of shape torch.Size([32, 1, 16, 16])
- [0] time=4.61, avg_loss=0.6586, train_err=20.5798
- Eval: 16_h1=0.4974, 16_l2=0.4004, 32_h1=0.8209, 32_l2=0.6873
- [3] time=4.63, avg_loss=0.2522, train_err=7.8821
- Eval: 16_h1=0.2281, 16_l2=0.1702, 32_h1=0.7338, 32_l2=0.5956
- [6] time=4.52, avg_loss=0.2534, train_err=7.9194
- Eval: 16_h1=0.2041, 16_l2=0.1527, 32_h1=0.6873, 32_l2=0.5407
- [9] time=4.44, avg_loss=0.2240, train_err=6.9998
- Eval: 16_h1=0.2075, 16_l2=0.1543, 32_h1=0.6566, 32_l2=0.4983
- [12] time=4.35, avg_loss=0.2071, train_err=6.4715
- Eval: 16_h1=0.1967, 16_l2=0.1384, 32_h1=0.6875, 32_l2=0.5304
- [15] time=4.36, avg_loss=0.1711, train_err=5.3483
- Eval: 16_h1=0.2300, 16_l2=0.1629, 32_h1=0.6453, 32_l2=0.4576
- [18] time=4.43, avg_loss=0.1268, train_err=3.9616
- Eval: 16_h1=0.1860, 16_l2=0.1351, 32_h1=0.6503, 32_l2=0.4821
+ [0] time=6.61, avg_loss=0.5430, train_err=16.9693
+ Eval: 16_h1=0.3210, 16_l2=0.2597, 32_h1=0.7922, 32_l2=0.5999
+ [3] time=6.48, avg_loss=0.2685, train_err=8.3897
+ Eval: 16_h1=0.2068, 16_l2=0.1545, 32_h1=0.7909, 32_l2=0.6063
+ [6] time=6.47, avg_loss=0.2368, train_err=7.4001
+ Eval: 16_h1=0.2155, 16_l2=0.1649, 32_h1=0.7626, 32_l2=0.5989
+ [9] time=6.47, avg_loss=0.2172, train_err=6.7885
+ Eval: 16_h1=0.2323, 16_l2=0.1762, 32_h1=0.7456, 32_l2=0.5858
+ [12] time=6.48, avg_loss=0.2048, train_err=6.3987
+ Eval: 16_h1=0.1903, 16_l2=0.1337, 32_h1=0.7315, 32_l2=0.5729
+ [15] time=6.46, avg_loss=0.1886, train_err=5.8936
+ Eval: 16_h1=0.1910, 16_l2=0.1350, 32_h1=0.7238, 32_l2=0.5652
+ [18] time=6.48, avg_loss=0.1804, train_err=5.6383
+ Eval: 16_h1=0.1816, 16_l2=0.1254, 32_h1=0.7171, 32_l2=0.5568
- {'train_err': 3.9999673664569855, 'avg_loss': 0.12799895572662354, 'avg_lasso_loss': None, 'epoch_train_time': 4.439005568623543}
+ {'train_err': 5.1316939406096935, 'avg_loss': 0.16421420609951018, 'avg_lasso_loss': None, 'epoch_train_time': 6.497358972000029}
-.. GENERATED FROM PYTHON SOURCE LINES 107-117
+.. GENERATED FROM PYTHON SOURCE LINES 100-110
Plot the prediction, and compare with the ground-truth
Note that we trained on a very small resolution for
@@ -438,7 +360,7 @@ ii) can be trained quickly on CPU
In practice we would train a Neural Operator on one or multiple GPUs
-.. GENERATED FROM PYTHON SOURCE LINES 117-155
+.. GENERATED FROM PYTHON SOURCE LINES 110-148
.. code-block:: Python
@@ -495,7 +417,7 @@ In practice we would train a Neural Operator on one or multiple GPUs
.. rst-class:: sphx-glr-timing
- **Total running time of the script:** (1 minutes 33.254 seconds)
+ **Total running time of the script:** (2 minutes 12.491 seconds)
.. _sphx_glr_download_auto_examples_plot_UNO_darcy.py:
@@ -512,6 +434,10 @@ In practice we would train a Neural Operator on one or multiple GPUs
:download:`Download Python source code: plot_UNO_darcy.py `
+ .. container:: sphx-glr-download sphx-glr-download-zip
+
+ :download:`Download zipped: plot_UNO_darcy.zip `
+
.. only:: html
diff --git a/dev/_sources/auto_examples/plot_count_flops.rst.txt b/dev/_sources/auto_examples/plot_count_flops.rst.txt
index 3294fd1..0598e81 100644
--- a/dev/_sources/auto_examples/plot_count_flops.rst.txt
+++ b/dev/_sources/auto_examples/plot_count_flops.rst.txt
@@ -39,13 +39,13 @@ We will use the FLOP computation to compare the resources used by a base FNO.
device = 'cpu'
fno = FNO(n_modes=(64,64),
- in_channels=1,
+ in_channels=3,
out_channels=1,
hidden_channels=64,
projection_channels=64)
batch_size = 4
- model_input = torch.randn(batch_size, 1, 128, 128)
+ model_input = torch.randn(batch_size, 3, 128, 128)
with FlopTensorDispatchMode(fno) as ftdm:
@@ -80,7 +80,7 @@ This output is organized as a defaultdict object that counts the FLOPS used in e
.. code-block:: none
- defaultdict(. at 0x7f03bbb1be20>, {'': defaultdict(, {'convolution.default': 2470445056, 'bmm.default': 138412032}), 'lifting': defaultdict(, {'convolution.default': 1124073472}), 'lifting.fcs.0': defaultdict(, {'convolution.default': 50331648}), 'lifting.fcs.1': defaultdict(, {'convolution.default': 1073741824}), 'fno_blocks': defaultdict(, {'convolution.default': 1073741824, 'bmm.default': 138412032}), 'fno_blocks.fno_skips.0': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.0.conv': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.convs': defaultdict(, {'bmm.default': 138412032}), 'fno_blocks.fno_skips.1': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.1.conv': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.2': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.2.conv': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.3': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.3.conv': defaultdict(, {'convolution.default': 268435456}), 'projection': defaultdict(, {'convolution.default': 272629760}), 'projection.fcs.0': defaultdict(, {'convolution.default': 268435456}), 'projection.fcs.1': defaultdict(, {'convolution.default': 4194304})})
+ defaultdict(. at 0x7feab52b2e50>, {'': defaultdict(, {'convolution.default': 2503999488, 'bmm.default': 138412032}), 'lifting': defaultdict(, {'convolution.default': 1157627904}), 'lifting.fcs.0': defaultdict(, {'convolution.default': 83886080}), 'lifting.fcs.1': defaultdict(, {'convolution.default': 1073741824}), 'fno_blocks': defaultdict(, {'convolution.default': 1073741824, 'bmm.default': 138412032}), 'fno_blocks.fno_skips.0': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.0.conv': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.convs': defaultdict(, {'bmm.default': 138412032}), 'fno_blocks.fno_skips.1': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.1.conv': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.2': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.2.conv': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.3': defaultdict(, {'convolution.default': 268435456}), 'fno_blocks.fno_skips.3.conv': defaultdict(, {'convolution.default': 268435456}), 'projection': defaultdict(, {'convolution.default': 272629760}), 'projection.fcs.0': defaultdict(, {'convolution.default': 268435456}), 'projection.fcs.1': defaultdict(, {'convolution.default': 4194304})})
@@ -116,8 +116,8 @@ To check the maximum FLOPS used during the forward pass, let's create a recursiv
.. code-block:: none
- Max FLOPS required for FNO.forward: 2470445056
- Max FLOPS required for FNO.backward: 4890558464
+ Max FLOPS required for FNO.forward: 2503999488
+ Max FLOPS required for FNO.backward: 4924112896
@@ -125,7 +125,7 @@ To check the maximum FLOPS used during the forward pass, let's create a recursiv
.. rst-class:: sphx-glr-timing
- **Total running time of the script:** (0 minutes 1.302 seconds)
+ **Total running time of the script:** (0 minutes 4.065 seconds)
.. _sphx_glr_download_auto_examples_plot_count_flops.py:
@@ -142,6 +142,10 @@ To check the maximum FLOPS used during the forward pass, let's create a recursiv
:download:`Download Python source code: plot_count_flops.py `
+ .. container:: sphx-glr-download sphx-glr-download-zip
+
+ :download:`Download zipped: plot_count_flops.zip `
+
.. only:: html
diff --git a/dev/_sources/auto_examples/plot_darcy_flow.rst.txt b/dev/_sources/auto_examples/plot_darcy_flow.rst.txt
index 55194cc..7abc160 100644
--- a/dev/_sources/auto_examples/plot_darcy_flow.rst.txt
+++ b/dev/_sources/auto_examples/plot_darcy_flow.rst.txt
@@ -71,7 +71,11 @@ Training samples are 16x16 and we load testing samples at both
.. code-block:: none
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
Loading test db for resolution 16 with 50 samples
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Loading test db for resolution 32 with 50 samples
@@ -159,7 +163,7 @@ Visualizing the data
.. rst-class:: sphx-glr-timing
- **Total running time of the script:** (0 minutes 0.186 seconds)
+ **Total running time of the script:** (0 minutes 0.429 seconds)
.. _sphx_glr_download_auto_examples_plot_darcy_flow.py:
@@ -176,6 +180,10 @@ Visualizing the data
:download:`Download Python source code: plot_darcy_flow.py `
+ .. container:: sphx-glr-download sphx-glr-download-zip
+
+ :download:`Download zipped: plot_darcy_flow.zip `
+
.. only:: html
diff --git a/dev/_sources/auto_examples/plot_darcy_flow_spectrum.rst.txt b/dev/_sources/auto_examples/plot_darcy_flow_spectrum.rst.txt
index dcb6c9c..72d9c2d 100644
--- a/dev/_sources/auto_examples/plot_darcy_flow_spectrum.rst.txt
+++ b/dev/_sources/auto_examples/plot_darcy_flow_spectrum.rst.txt
@@ -149,7 +149,11 @@ Loading the Navier-Stokes dataset in 128x128 resolution
.. code-block:: none
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
Loading test db for resolution 16 with 50 samples
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Original dataset shape torch.Size([50, 1, 16, 16])
@@ -206,7 +210,7 @@ Loading the Navier-Stokes dataset in 128x128 resolution
.. code-block:: none
- /home/dave/myneurop/examples/plot_darcy_flow_spectrum.py:104: UserWarning: Attempt to set non-positive ylim on a log-scaled axis will be ignored.
+ /home/runner/work/neuraloperator/neuraloperator/examples/plot_darcy_flow_spectrum.py:104: UserWarning: Attempt to set non-positive ylim on a log-scaled axis will be ignored.
ax.set_ylim(10, 10^10)
@@ -215,7 +219,7 @@ Loading the Navier-Stokes dataset in 128x128 resolution
.. rst-class:: sphx-glr-timing
- **Total running time of the script:** (0 minutes 0.139 seconds)
+ **Total running time of the script:** (0 minutes 0.279 seconds)
.. _sphx_glr_download_auto_examples_plot_darcy_flow_spectrum.py:
@@ -232,6 +236,10 @@ Loading the Navier-Stokes dataset in 128x128 resolution
:download:`Download Python source code: plot_darcy_flow_spectrum.py `
+ .. container:: sphx-glr-download sphx-glr-download-zip
+
+ :download:`Download zipped: plot_darcy_flow_spectrum.zip `
+
.. only:: html
diff --git a/dev/_sources/auto_examples/plot_incremental_FNO_darcy.rst.txt b/dev/_sources/auto_examples/plot_incremental_FNO_darcy.rst.txt
index 2076ac9..b7f63db 100644
--- a/dev/_sources/auto_examples/plot_incremental_FNO_darcy.rst.txt
+++ b/dev/_sources/auto_examples/plot_incremental_FNO_darcy.rst.txt
@@ -70,7 +70,11 @@ Loading the Darcy flow dataset
.. code-block:: none
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
Loading test db for resolution 16 with 100 samples
+ /home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Loading test db for resolution 32 with 50 samples
@@ -220,7 +224,7 @@ Set up the losses
### N PARAMS ###
- 2110305
+ 2119329
### OPTIMIZER ###
AdamW (
@@ -234,15 +238,15 @@ Set up the losses
)
### SCHEDULER ###
-
+
### LOSSES ###
### INCREMENTAL RESOLUTION + GRADIENT EXPLAINED ###
- * Train:
+ * Train:
- * Test: {'h1': , 'l2': }
+ * Test: {'h1': , 'l2': }
@@ -323,51 +327,51 @@ Train the model
Training on 100 samples
Testing on [50, 50] samples on resolutions [16, 32].
Raw outputs of shape torch.Size([16, 1, 8, 8])
- [0] time=0.07, avg_loss=0.8236, train_err=11.7655
- Eval: 16_h1=0.7665, 16_l2=0.6166, 32_h1=0.7932, 32_l2=0.6111
- [1] time=0.03, avg_loss=0.6737, train_err=9.6245
- Eval: 16_h1=0.6417, 16_l2=0.4694, 32_h1=0.7263, 32_l2=0.4793
- [2] time=0.03, avg_loss=0.5479, train_err=7.8269
- Eval: 16_h1=0.6615, 16_l2=0.4694, 32_h1=0.8183, 32_l2=0.4896
- [3] time=0.03, avg_loss=0.5040, train_err=7.1998
- Eval: 16_h1=0.5634, 16_l2=0.4002, 32_h1=0.6886, 32_l2=0.4146
- [4] time=0.04, avg_loss=0.4482, train_err=6.4026
- Eval: 16_h1=0.5917, 16_l2=0.4267, 32_h1=0.7822, 32_l2=0.4703
- [5] time=0.04, avg_loss=0.4120, train_err=5.8851
- Eval: 16_h1=0.5466, 16_l2=0.3766, 32_h1=0.7625, 32_l2=0.4164
- [6] time=0.04, avg_loss=0.3683, train_err=5.2609
- Eval: 16_h1=0.4672, 16_l2=0.3235, 32_h1=0.6485, 32_l2=0.3597
- [7] time=0.04, avg_loss=0.3326, train_err=4.7513
- Eval: 16_h1=0.4938, 16_l2=0.3391, 32_h1=0.6948, 32_l2=0.3841
- [8] time=0.04, avg_loss=0.3064, train_err=4.3769
- Eval: 16_h1=0.4673, 16_l2=0.3198, 32_h1=0.6777, 32_l2=0.3651
- [9] time=0.04, avg_loss=0.2868, train_err=4.0965
- Eval: 16_h1=0.4539, 16_l2=0.3072, 32_h1=0.6651, 32_l2=0.3536
+ [0] time=0.21, avg_loss=0.7750, train_err=11.0714
+ Eval: 16_h1=0.7031, 16_l2=0.5348, 32_h1=0.7319, 32_l2=0.5357
+ [1] time=0.21, avg_loss=0.5908, train_err=8.4395
+ Eval: 16_h1=0.6114, 16_l2=0.4391, 32_h1=0.6716, 32_l2=0.4473
+ [2] time=0.20, avg_loss=0.5093, train_err=7.2754
+ Eval: 16_h1=0.5647, 16_l2=0.3843, 32_h1=0.6667, 32_l2=0.3946
+ [3] time=0.21, avg_loss=0.4408, train_err=6.2975
+ Eval: 16_h1=0.5216, 16_l2=0.3600, 32_h1=0.6661, 32_l2=0.3915
+ [4] time=0.21, avg_loss=0.4055, train_err=5.7927
+ Eval: 16_h1=0.5165, 16_l2=0.3631, 32_h1=0.6852, 32_l2=0.4008
+ [5] time=0.21, avg_loss=0.3794, train_err=5.4201
+ Eval: 16_h1=0.5407, 16_l2=0.4053, 32_h1=0.6456, 32_l2=0.4213
+ [6] time=0.22, avg_loss=0.3662, train_err=5.2311
+ Eval: 16_h1=0.4848, 16_l2=0.3434, 32_h1=0.6641, 32_l2=0.3786
+ [7] time=0.22, avg_loss=0.3320, train_err=4.7433
+ Eval: 16_h1=0.4515, 16_l2=0.3280, 32_h1=0.5890, 32_l2=0.3661
+ [8] time=0.22, avg_loss=0.3013, train_err=4.3041
+ Eval: 16_h1=0.4443, 16_l2=0.3024, 32_h1=0.6300, 32_l2=0.3467
+ [9] time=0.23, avg_loss=0.2621, train_err=3.7436
+ Eval: 16_h1=0.4252, 16_l2=0.2978, 32_h1=0.6085, 32_l2=0.3395
Incre Res Update: change index to 1
Incre Res Update: change sub to 1
Incre Res Update: change res to 16
- [10] time=0.06, avg_loss=0.3922, train_err=5.6035
- Eval: 16_h1=0.3690, 16_l2=0.2683, 32_h1=0.4566, 32_l2=0.2656
- [11] time=0.04, avg_loss=0.3392, train_err=4.8454
- Eval: 16_h1=0.3419, 16_l2=0.2484, 32_h1=0.4551, 32_l2=0.2650
- [12] time=0.04, avg_loss=0.3098, train_err=4.4253
- Eval: 16_h1=0.3172, 16_l2=0.2389, 32_h1=0.4273, 32_l2=0.2547
- [13] time=0.04, avg_loss=0.2827, train_err=4.0392
- Eval: 16_h1=0.3155, 16_l2=0.2391, 32_h1=0.4182, 32_l2=0.2516
- [14] time=0.04, avg_loss=0.2774, train_err=3.9626
- Eval: 16_h1=0.2872, 16_l2=0.2186, 32_h1=0.3938, 32_l2=0.2344
- [15] time=0.04, avg_loss=0.2490, train_err=3.5571
- Eval: 16_h1=0.2744, 16_l2=0.2075, 32_h1=0.3745, 32_l2=0.2220
- [16] time=0.04, avg_loss=0.2346, train_err=3.3511
- Eval: 16_h1=0.2758, 16_l2=0.2056, 32_h1=0.3889, 32_l2=0.2249
- [17] time=0.04, avg_loss=0.2293, train_err=3.2760
- Eval: 16_h1=0.2793, 16_l2=0.2077, 32_h1=0.3904, 32_l2=0.2213
- [18] time=0.04, avg_loss=0.2262, train_err=3.2321
- Eval: 16_h1=0.3024, 16_l2=0.2263, 32_h1=0.4136, 32_l2=0.2417
- [19] time=0.04, avg_loss=0.2388, train_err=3.4117
- Eval: 16_h1=0.3040, 16_l2=0.2327, 32_h1=0.4129, 32_l2=0.2462
-
- {'train_err': 3.411697438785008, 'avg_loss': 0.23881882071495056, 'avg_lasso_loss': None, 'epoch_train_time': 0.04143996722996235, '16_h1': tensor(0.3040, device='cuda:0'), '16_l2': tensor(0.2327, device='cuda:0'), '32_h1': tensor(0.4129, device='cuda:0'), '32_l2': tensor(0.2462, device='cuda:0')}
+ [10] time=0.30, avg_loss=0.3530, train_err=5.0422
+ Eval: 16_h1=0.3418, 16_l2=0.2496, 32_h1=0.4258, 32_l2=0.2477
+ [11] time=0.29, avg_loss=0.2891, train_err=4.1300
+ Eval: 16_h1=0.3833, 16_l2=0.2783, 32_h1=0.4696, 32_l2=0.2820
+ [12] time=0.31, avg_loss=0.2975, train_err=4.2504
+ Eval: 16_h1=0.3179, 16_l2=0.2267, 32_h1=0.4156, 32_l2=0.2404
+ [13] time=0.31, avg_loss=0.2420, train_err=3.4567
+ Eval: 16_h1=0.2829, 16_l2=0.2034, 32_h1=0.3807, 32_l2=0.2174
+ [14] time=0.31, avg_loss=0.2147, train_err=3.0676
+ Eval: 16_h1=0.3394, 16_l2=0.2630, 32_h1=0.4255, 32_l2=0.2714
+ [15] time=0.32, avg_loss=0.2232, train_err=3.1885
+ Eval: 16_h1=0.3785, 16_l2=0.2985, 32_h1=0.4668, 32_l2=0.3102
+ [16] time=0.32, avg_loss=0.2555, train_err=3.6494
+ Eval: 16_h1=0.3279, 16_l2=0.2593, 32_h1=0.4078, 32_l2=0.2623
+ [17] time=0.32, avg_loss=0.2769, train_err=3.9559
+ Eval: 16_h1=0.4073, 16_l2=0.3371, 32_h1=0.4499, 32_l2=0.3422
+ [18] time=0.32, avg_loss=0.2840, train_err=4.0576
+ Eval: 16_h1=0.2826, 16_l2=0.2202, 32_h1=0.3649, 32_l2=0.2272
+ [19] time=0.32, avg_loss=0.1984, train_err=2.8340
+ Eval: 16_h1=0.2795, 16_l2=0.2186, 32_h1=0.3582, 32_l2=0.2296
+
+ {'train_err': 2.8339713641575406, 'avg_loss': 0.19837799549102783, 'avg_lasso_loss': None, 'epoch_train_time': 0.3178346639999745, '16_h1': tensor(0.2795), '16_l2': tensor(0.2186), '32_h1': tensor(0.3582), '32_l2': tensor(0.2296)}
@@ -441,7 +445,7 @@ In practice we would train a Neural Operator on one or multiple GPUs
.. rst-class:: sphx-glr-timing
- **Total running time of the script:** (0 minutes 1.140 seconds)
+ **Total running time of the script:** (0 minutes 7.776 seconds)
.. _sphx_glr_download_auto_examples_plot_incremental_FNO_darcy.py:
@@ -458,6 +462,10 @@ In practice we would train a Neural Operator on one or multiple GPUs
:download:`Download Python source code: plot_incremental_FNO_darcy.py `
+ .. container:: sphx-glr-download sphx-glr-download-zip
+
+ :download:`Download zipped: plot_incremental_FNO_darcy.zip `
+
.. only:: html
diff --git a/dev/_sources/auto_examples/sg_execution_times.rst.txt b/dev/_sources/auto_examples/sg_execution_times.rst.txt
index 7f3a427..10a5c1f 100644
--- a/dev/_sources/auto_examples/sg_execution_times.rst.txt
+++ b/dev/_sources/auto_examples/sg_execution_times.rst.txt
@@ -6,7 +6,7 @@
Computation times
=================
-**01:33.254** total execution time for 8 files **from auto_examples**:
+**04:44.485** total execution time for 8 files **from auto_examples**:
.. container::
@@ -33,26 +33,26 @@ Computation times
- Time
- Mem (MB)
* - :ref:`sphx_glr_auto_examples_plot_UNO_darcy.py` (``plot_UNO_darcy.py``)
- - 01:33.254
+ - 02:12.491
- 0.0
- * - :ref:`sphx_glr_auto_examples_checkpoint_FNO_darcy.py` (``checkpoint_FNO_darcy.py``)
- - 00:00.000
+ * - :ref:`sphx_glr_auto_examples_plot_SFNO_swe.py` (``plot_SFNO_swe.py``)
+ - 01:25.030
- 0.0
* - :ref:`sphx_glr_auto_examples_plot_FNO_darcy.py` (``plot_FNO_darcy.py``)
- - 00:00.000
+ - 00:54.415
- 0.0
- * - :ref:`sphx_glr_auto_examples_plot_SFNO_swe.py` (``plot_SFNO_swe.py``)
- - 00:00.000
+ * - :ref:`sphx_glr_auto_examples_plot_incremental_FNO_darcy.py` (``plot_incremental_FNO_darcy.py``)
+ - 00:07.776
- 0.0
* - :ref:`sphx_glr_auto_examples_plot_count_flops.py` (``plot_count_flops.py``)
- - 00:00.000
+ - 00:04.065
- 0.0
* - :ref:`sphx_glr_auto_examples_plot_darcy_flow.py` (``plot_darcy_flow.py``)
- - 00:00.000
+ - 00:00.429
- 0.0
* - :ref:`sphx_glr_auto_examples_plot_darcy_flow_spectrum.py` (``plot_darcy_flow_spectrum.py``)
- - 00:00.000
+ - 00:00.279
- 0.0
- * - :ref:`sphx_glr_auto_examples_plot_incremental_FNO_darcy.py` (``plot_incremental_FNO_darcy.py``)
+ * - :ref:`sphx_glr_auto_examples_checkpoint_FNO_darcy.py` (``checkpoint_FNO_darcy.py``)
- 00:00.000
- 0.0
diff --git a/dev/_sources/modules/_autosummary/neuralop.models.FNO.rst.txt b/dev/_sources/modules/_autosummary/neuralop.models.FNO.rst.txt
deleted file mode 100644
index 6c30201..0000000
--- a/dev/_sources/modules/_autosummary/neuralop.models.FNO.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.models`.FNO
-=================================
-
-.. currentmodule:: neuralop.models
-
-.. autoclass:: FNO
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/api.rst.txt b/dev/_sources/modules/api.rst.txt
index 3521ca1..ec19ae7 100644
--- a/dev/_sources/modules/api.rst.txt
+++ b/dev/_sources/modules/api.rst.txt
@@ -111,7 +111,7 @@ In addition to the full architectures, we also provide
in :mod:`neuralop.layers` building blocks,
in the form of PyTorch layers, that you can use to build your own models:
-Neural operator layers
+Neural operator Layers
------------------------
**Spectral convolutions** (in Fourier domain):
@@ -170,24 +170,6 @@ To support geometry-informed (GINO) models, we also offer the ability to integra
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**Embeddings**
-
-Apply positional embeddings as additional channels on a function:
-
-.. automodule:: neuralop.layers.embeddings
- :no-members:
- :no-inherited-members:
-
-.. autosummary::
- :toctree: generated
- :template: class.rst
-
- GridEmbeddingND
- GridEmbedding2D
- SinusoidalEmbedding2D
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
**Neighbor search**
Find neighborhoods on arbitrary coordinate meshes:
@@ -210,7 +192,6 @@ Find neighborhoods on arbitrary coordinate meshes:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
Other resolution invariant operations
-------------------------------------
diff --git a/dev/_sources/modules/generated/neuralop.datasets.data_transforms.DefaultDataProcessor.rst.txt b/dev/_sources/modules/generated/neuralop.datasets.data_transforms.DefaultDataProcessor.rst.txt
deleted file mode 100644
index e5de184..0000000
--- a/dev/_sources/modules/generated/neuralop.datasets.data_transforms.DefaultDataProcessor.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.datasets.data_transforms`.DefaultDataProcessor
-====================================================================
-
-.. currentmodule:: neuralop.datasets.data_transforms
-
-.. autoclass:: DefaultDataProcessor
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.datasets.data_transforms.MGPatchingDataProcessor.rst.txt b/dev/_sources/modules/generated/neuralop.datasets.data_transforms.MGPatchingDataProcessor.rst.txt
deleted file mode 100644
index 31184fe..0000000
--- a/dev/_sources/modules/generated/neuralop.datasets.data_transforms.MGPatchingDataProcessor.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.datasets.data_transforms`.MGPatchingDataProcessor
-=======================================================================
-
-.. currentmodule:: neuralop.datasets.data_transforms
-
-.. autoclass:: MGPatchingDataProcessor
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.datasets.load_darcy_flow_small.rst.txt b/dev/_sources/modules/generated/neuralop.datasets.load_darcy_flow_small.rst.txt
deleted file mode 100644
index f8d11c5..0000000
--- a/dev/_sources/modules/generated/neuralop.datasets.load_darcy_flow_small.rst.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-:mod:`neuralop.datasets`.load_darcy_flow_small
-===========================================================
-
-.. currentmodule:: neuralop.datasets
-
-.. autofunction:: load_darcy_flow_small
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.layers.embeddings.GridEmbedding2D.rst.txt b/dev/_sources/modules/generated/neuralop.layers.embeddings.GridEmbedding2D.rst.txt
deleted file mode 100644
index f92127e..0000000
--- a/dev/_sources/modules/generated/neuralop.layers.embeddings.GridEmbedding2D.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.layers.embeddings`.GridEmbedding2D
-========================================================
-
-.. currentmodule:: neuralop.layers.embeddings
-
-.. autoclass:: GridEmbedding2D
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.layers.embeddings.GridEmbeddingND.rst.txt b/dev/_sources/modules/generated/neuralop.layers.embeddings.GridEmbeddingND.rst.txt
deleted file mode 100644
index 4cdf0a7..0000000
--- a/dev/_sources/modules/generated/neuralop.layers.embeddings.GridEmbeddingND.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.layers.embeddings`.GridEmbeddingND
-========================================================
-
-.. currentmodule:: neuralop.layers.embeddings
-
-.. autoclass:: GridEmbeddingND
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.layers.embeddings.SinusoidalEmbedding2D.rst.txt b/dev/_sources/modules/generated/neuralop.layers.embeddings.SinusoidalEmbedding2D.rst.txt
deleted file mode 100644
index beb4d36..0000000
--- a/dev/_sources/modules/generated/neuralop.layers.embeddings.SinusoidalEmbedding2D.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.layers.embeddings`.SinusoidalEmbedding2D
-==============================================================
-
-.. currentmodule:: neuralop.layers.embeddings
-
-.. autoclass:: SinusoidalEmbedding2D
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.layers.gno_block.GNOBlock.rst.txt b/dev/_sources/modules/generated/neuralop.layers.gno_block.GNOBlock.rst.txt
deleted file mode 100644
index 3d47fbd..0000000
--- a/dev/_sources/modules/generated/neuralop.layers.gno_block.GNOBlock.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.layers.gno_block`.GNOBlock
-================================================
-
-.. currentmodule:: neuralop.layers.gno_block
-
-.. autoclass:: GNOBlock
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.training.callbacks.BasicLoggerCallback.rst.txt b/dev/_sources/modules/generated/neuralop.training.callbacks.BasicLoggerCallback.rst.txt
deleted file mode 100644
index 7ad12c5..0000000
--- a/dev/_sources/modules/generated/neuralop.training.callbacks.BasicLoggerCallback.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.training.callbacks`.BasicLoggerCallback
-=============================================================
-
-.. currentmodule:: neuralop.training.callbacks
-
-.. autoclass:: BasicLoggerCallback
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.training.callbacks.Callback.rst.txt b/dev/_sources/modules/generated/neuralop.training.callbacks.Callback.rst.txt
deleted file mode 100644
index 403e8d9..0000000
--- a/dev/_sources/modules/generated/neuralop.training.callbacks.Callback.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.training.callbacks`.Callback
-==================================================
-
-.. currentmodule:: neuralop.training.callbacks
-
-.. autoclass:: Callback
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/modules/generated/neuralop.training.callbacks.CheckpointCallback.rst.txt b/dev/_sources/modules/generated/neuralop.training.callbacks.CheckpointCallback.rst.txt
deleted file mode 100644
index 2bf7430..0000000
--- a/dev/_sources/modules/generated/neuralop.training.callbacks.CheckpointCallback.rst.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-:mod:`neuralop.training.callbacks`.CheckpointCallback
-============================================================
-
-.. currentmodule:: neuralop.training.callbacks
-
-.. autoclass:: CheckpointCallback
- :members:
-
-.. raw:: html
-
-
\ No newline at end of file
diff --git a/dev/_sources/sg_execution_times.rst.txt b/dev/_sources/sg_execution_times.rst.txt
index 9da0481..8c18dd5 100644
--- a/dev/_sources/sg_execution_times.rst.txt
+++ b/dev/_sources/sg_execution_times.rst.txt
@@ -6,7 +6,7 @@
Computation times
=================
-**01:33.254** total execution time for 8 files **from all galleries**:
+**04:44.485** total execution time for 8 files **from all galleries**:
.. container::
@@ -33,26 +33,26 @@ Computation times
- Time
- Mem (MB)
* - :ref:`sphx_glr_auto_examples_plot_UNO_darcy.py` (``../../examples/plot_UNO_darcy.py``)
- - 01:33.254
+ - 02:12.491
- 0.0
- * - :ref:`sphx_glr_auto_examples_checkpoint_FNO_darcy.py` (``../../examples/checkpoint_FNO_darcy.py``)
- - 00:00.000
+ * - :ref:`sphx_glr_auto_examples_plot_SFNO_swe.py` (``../../examples/plot_SFNO_swe.py``)
+ - 01:25.030
- 0.0
* - :ref:`sphx_glr_auto_examples_plot_FNO_darcy.py` (``../../examples/plot_FNO_darcy.py``)
- - 00:00.000
+ - 00:54.415
- 0.0
- * - :ref:`sphx_glr_auto_examples_plot_SFNO_swe.py` (``../../examples/plot_SFNO_swe.py``)
- - 00:00.000
+ * - :ref:`sphx_glr_auto_examples_plot_incremental_FNO_darcy.py` (``../../examples/plot_incremental_FNO_darcy.py``)
+ - 00:07.776
- 0.0
* - :ref:`sphx_glr_auto_examples_plot_count_flops.py` (``../../examples/plot_count_flops.py``)
- - 00:00.000
+ - 00:04.065
- 0.0
* - :ref:`sphx_glr_auto_examples_plot_darcy_flow.py` (``../../examples/plot_darcy_flow.py``)
- - 00:00.000
+ - 00:00.429
- 0.0
* - :ref:`sphx_glr_auto_examples_plot_darcy_flow_spectrum.py` (``../../examples/plot_darcy_flow_spectrum.py``)
- - 00:00.000
+ - 00:00.279
- 0.0
- * - :ref:`sphx_glr_auto_examples_plot_incremental_FNO_darcy.py` (``../../examples/plot_incremental_FNO_darcy.py``)
+ * - :ref:`sphx_glr_auto_examples_checkpoint_FNO_darcy.py` (``../../examples/checkpoint_FNO_darcy.py``)
- 00:00.000
- 0.0
diff --git a/dev/_sources/user_guide/fno.rst.txt b/dev/_sources/user_guide/fno.rst.txt
index 3f09950..581b47e 100644
--- a/dev/_sources/user_guide/fno.rst.txt
+++ b/dev/_sources/user_guide/fno.rst.txt
@@ -1,4 +1,3 @@
-.. _fno-guide:
========================
Fourier Neural Operators
========================
diff --git a/dev/_sources/user_guide/getting_started.rst.txt b/dev/_sources/user_guide/getting_started.rst.txt
deleted file mode 100644
index 3a24d0b..0000000
--- a/dev/_sources/user_guide/getting_started.rst.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-.. _getting_started :
-
-Getting Started
-===========
-
-*NeuralOperator* aims to provide you with all the tools
-to easily use, build and train neural operators for your own applications
-and learn mapping between function spaces, in PyTorch.
-
-Intro to operator learning
-----------------------------
-To get a better feel for the theory behind our neural operator models, see :ref:`neuralop_intro` and :ref:`fno_intro`.
-
-~~~~~~~~~~~~
-
-Interactive examples with code
-----------------------------
-To get up to speed on the code, and look through some interactive examples to help you hit the ground running,
-check out :ref:`gallery_examples`.
-
-~~~~~~~~~~~~
-
-NeuralOperator library structure
----------------------------------
-
-Here are the main components of the library:
-
-================================= ================================
-Module Description
-================================= ================================
-:mod:`neuralop` Main library
-:mod:`neuralop.models` Full ready-to-use neural operators
-:mod:`neuralop.layers` Individual layers to build neural operators
-:mod:`neuralop.datasets` Convenience PyTorch data loaders for PDE datasets
-:mod:`neuralop.training` Utilities to train neural operators end-to-end
-================================= ================================
-
-The full API documentation is provided in :ref:`api_ref`.
-
-Finally, if you're building the library from source, your repository will also include the following directories:
-
-================================= ================================
-Directory Description
-================================= ================================
-:mod:`scripts` Training recipe scripts for our models on sample problems
-:mod:`examples` More documented interactive examples, seen in
-================================= ================================
diff --git a/dev/_sources/user_guide/index_old.rst.txt b/dev/_sources/user_guide/index_old.rst.txt
deleted file mode 100644
index 2352602..0000000
--- a/dev/_sources/user_guide/index_old.rst.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-.. _user_guide:
-
-
-User guide
-==========
-
-
-.. toctree::
-
- getting_started
- neural_operators
- fno
- training
diff --git a/dev/_static/searchtools.js b/dev/_static/searchtools.js
index 92da3f8..b08d58c 100644
--- a/dev/_static/searchtools.js
+++ b/dev/_static/searchtools.js
@@ -178,7 +178,7 @@ const Search = {
htmlToText: (htmlString, anchor) => {
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
- for (const removalQuery of [".headerlinks", "script", "style"]) {
+ for (const removalQuery of [".headerlink", "script", "style"]) {
htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() });
}
if (anchor) {
@@ -328,13 +328,14 @@ const Search = {
for (const [title, foundTitles] of Object.entries(allTitles)) {
if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) {
for (const [file, id] of foundTitles) {
- let score = Math.round(100 * queryLower.length / title.length)
+ const score = Math.round(Scorer.title * queryLower.length / title.length);
+ const boost = titles[file] === title ? 1 : 0; // add a boost for document titles
normalResults.push([
docNames[file],
titles[file] !== title ? `${titles[file]} > ${title}` : title,
id !== null ? "#" + id : "",
null,
- score,
+ score + boost,
filenames[file],
]);
}
diff --git a/dev/_static/sg_gallery.css b/dev/_static/sg_gallery.css
index 7222783..9bcd33c 100644
--- a/dev/_static/sg_gallery.css
+++ b/dev/_static/sg_gallery.css
@@ -178,23 +178,44 @@ thumbnail with its default link Background color */
max-height: 112px;
max-width: 160px;
}
-.sphx-glr-thumbcontainer[tooltip]:hover:after {
- background: var(--sg-tooltip-background);
+
+.sphx-glr-thumbcontainer[tooltip]::before {
+ content: "";
+ position: absolute;
+ pointer-events: none;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 97;
+ background-color: var(--sg-tooltip-background);
+ backdrop-filter: blur(3px);
+ opacity: 0;
+ transition: opacity 0.3s;
+}
+
+.sphx-glr-thumbcontainer[tooltip]:hover::before {
+ opacity: 1;
+}
+
+.sphx-glr-thumbcontainer[tooltip]:hover::after {
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
color: var(--sg-tooltip-foreground);
content: attr(tooltip);
- padding: 10px;
+ padding: 10px 10px 5px;
z-index: 98;
width: 100%;
- height: 100%;
+ max-height: 100%;
position: absolute;
pointer-events: none;
top: 0;
box-sizing: border-box;
overflow: hidden;
- backdrop-filter: blur(3px);
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 6;
}
.sphx-glr-script-out {
@@ -283,6 +304,10 @@ div.sphx-glr-download a:hover {
background-color: var(--sg-download-a-hover-background-color);
}
+div.sphx-glr-sidebar-item img {
+ max-height: 20px;
+}
+
.sphx-glr-example-title:target::before {
display: block;
content: "";
diff --git a/dev/auto_examples/checkpoint_FNO_darcy.html b/dev/auto_examples/checkpoint_FNO_darcy.html
index bd9e11b..7585685 100644
--- a/dev/auto_examples/checkpoint_FNO_darcy.html
+++ b/dev/auto_examples/checkpoint_FNO_darcy.html
@@ -17,7 +17,7 @@
-
+
@@ -31,7 +31,7 @@
-
+
@@ -132,7 +132,7 @@
In this example, we demonstrate how to use neuralop.data.transforms.DataProcessor
-to preprocess and postprocess the small Darcy Flow example we ship with the package
-for downstream use in training a neural operator model.
Loading test db for resolution 16 with 100 samples
+
/home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
+Loading test db for resolution 16 with 100 samples
+/home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Loading test db for resolution 32 with 50 samples
Plot the prediction, and compare with the ground-truth
@@ -390,7 +369,7 @@
fig.show()
-
Total running time of the script: (0 minutes 20.521 seconds)
+
Total running time of the script: (1 minutes 25.030 seconds)
-
Loading test db for resolution 16 with 100 samples
+
/home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
+Loading test db for resolution 16 with 100 samples
+/home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Loading test db for resolution 32 with 50 samples
-fno_skip='linear'
-channel_mlp_skip='linear'
-fno_skip='linear'
-channel_mlp_skip='linear'
-fno_skip='linear'
-channel_mlp_skip='linear'
-fno_skip='linear'
-channel_mlp_skip='linear'
-fno_skip='linear'
-channel_mlp_skip='linear'
-
-Our model has 2700097 parameters.
+
+Our model has 2665921 parameters.
Plot the prediction, and compare with the ground-truth
@@ -514,7 +436,7 @@
fig.show()
-
Total running time of the script: (1 minutes 33.254 seconds)
+
Total running time of the script: (2 minutes 12.491 seconds)
-
Loading test db for resolution 16 with 50 samples
+
/home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
+Loading test db for resolution 16 with 50 samples
+/home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Original dataset shape torch.Size([50, 1, 16, 16])
/home/dave/myneurop/examples/plot_darcy_flow_spectrum.py:104: UserWarning: Attempt to set non-positive ylim on a log-scaled axis will be ignored.
+
/home/runner/work/neuraloperator/neuraloperator/examples/plot_darcy_flow_spectrum.py:104: UserWarning: Attempt to set non-positive ylim on a log-scaled axis will be ignored.
ax.set_ylim(10, 10^10)
-
Total running time of the script: (0 minutes 0.139 seconds)
+
Total running time of the script: (0 minutes 0.279 seconds)
Loading test db for resolution 16 with 100 samples
+
/home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:93: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(
+Loading test db for resolution 16 with 100 samples
+/home/runner/work/neuraloperator/neuraloperator/neuralop/data/datasets/pt_dataset.py:172: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.
+ data = torch.load(Path(root_dir).joinpath(f"{dataset_name}_test_{res}.pt").as_posix())
Loading test db for resolution 32 with 50 samples
@@ -271,7 +275,7 @@
### N PARAMS ###
- 2110305
+ 2119329
### OPTIMIZER ###
AdamW (
@@ -285,15 +289,15 @@
)
### SCHEDULER ###
- <torch.optim.lr_scheduler.CosineAnnealingLR object at 0x7f746c2a2b90>
+ <torch.optim.lr_scheduler.CosineAnnealingLR object at 0x7fea8ec5f790>
### LOSSES ###
### INCREMENTAL RESOLUTION + GRADIENT EXPLAINED ###
- * Train: <neuralop.losses.data_losses.H1Loss object at 0x7f746c3ab1f0>
+ * Train: <neuralop.losses.data_losses.H1Loss object at 0x7feab84cca90>
- * Test: {'h1': <neuralop.losses.data_losses.H1Loss object at 0x7f746c3ab1f0>, 'l2': <neuralop.losses.data_losses.LpLoss object at 0x7f746c2a2fe0>}
+ * Test: {'h1': <neuralop.losses.data_losses.H1Loss object at 0x7feab84cca90>, 'l2': <neuralop.losses.data_losses.LpLoss object at 0x7feaa0415d00>}
Set up the IncrementalTrainer
@@ -347,51 +351,51 @@