Paper · 2021-11-17 · cs.CV, eess.IV
Local Texture Estimator for Implicit Representation Function
Local Texture Estimator (LTE) adds a learned Fourier-style head to a local implicit image function. A deep SR encoder yields per-cell amplitudes, frequencies and a scale-dependent phase, and a shared MLP decodes an RGB value at any continuous coordinate. Trained on DIV2K at x1-x4 scales, SwinIR-LTE gets the best DIV2K PSNR at every tested scale, up to x30 (author-reported).
Image super-resolutionImplicit neural representation (INR)Fourier featuressuper-resolutionarbitrary-scaleimplicit-representationfourier-features
arXivPDFCodeMarkdown12 min read
AI-compiled by claude-haiku-5-5 on 2026-11-05, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Super-resolution means producing a sharp, larger version of a small image. A popular trick is a small neural function that, given any position in the picture, outputs the colour there. Because it can be asked about any position, one network can enlarge an image by any factor. The catch is that such functions tend to learn smooth shapes first and struggle with fine texture such as stripes, text edges and grids.
This paper adds a small helper that looks at the low-resolution image around each spot and works out which repeating patterns dominate there, how strong they are and where they line up. The colour function then uses this description to draw fine detail at any zoom level. The plain enlarged image is also added back in, so the network only has to supply the missing detail.
The authors report higher scores than earlier arbitrary-scale methods on most entries of their test tables, and faster timings in their own tests. Those numbers come from the authors' own experiments.
TL;DR
- Arbitrary-scale super-resolution with an implicit MLP tends to miss high-frequency texture (spectral bias) and distorts structure at large scales §1 §2.
- LTE predicts, per latent cell, Fourier amplitudes and frequencies plus a scale-dependent phase, then decodes the sum with a shared 4-layer MLP and adds the bilinearly upscaled low-resolution input §4.1 §3.
- Trained on DIV2K with scales from x1 to x4 and L1 loss, it reports the best DIV2K PSNR among the compared arbitrary-scale methods at every tested scale, including out-of-scale x6 to x30 tab. 1.
- Speed claims depend on the query setting; the abstract's 40% figure is not a direct reading of tab. 4 (see Pitfalls).
- The official code (BSD-3-Clause) matches most of the paper, but the frequency count, the phase bias and the cell clamp differ in detail (see Paper vs code).
Problem
- Storing one super-resolution model per scale factor is costly, and sub-pixel upsamplers are fixed to their training scale §1.
- A standalone MLP learns low frequencies first and fails on fine detail (spectral bias). Fourier feature mappings and sinusoidal activations address this with fixed or random frequencies §1 §2.
- Local implicit image functions (LIIF) handle arbitrary scales but show structural distortion at extreme factors §2.
- Large outputs are memory-heavy at evaluation time, which makes the memory and time cost of arbitrary-scale decoders a practical concern §1 §6.
Method
Overview
The network has four parts §4.1 fig. 2:
- Encoder
E_φ: EDSR-baseline, RDN or SwinIR with their upsampling layers removed, so the feature map has the LR resolution §4.1. - LTE
h_ψ: an amplitude estimatorh_aand a frequency estimatorh_f, each a 3x3 convolution with 256 output channels (2K) that is equivalent to a fully connected layer on the unfolded 3x3 neighbourhood. A phase estimatorh_pis one fully connected layer with hidden size 128 that takes the cell size §4.1 eq. 5 eq. 7. - Decoder
f_θ: a 4-layer MLP with ReLU and 256 hidden units, shared by all images §4.1. - LR skip connection: the bilinearly upscaled LR image is added to the decoder output §4.1 eq. 8.
The paper's central equation for a query point x is a weighted sum over the
four nearest latent cells j eq. 4:
\mathbf s(\mathbf x,\mathbf I^{LR};\Theta,\psi)=\sum_{j\in\mathcal J} w_j\, f_\theta\big(h_\psi(\mathbf z_j,\mathbf x-\mathbf x_j)\big) eq. 4
The LTE term, with the scale-dependent phase added eq. 5 eq. 7, is
h_\psi(\hat{\mathbf z}_j,\boldsymbol\delta,\mathbf c)=\mathbf A_j\odot \begin{bmatrix}\cos\big(\pi(\mathbf F_j\boldsymbol\delta+h_p(\hat{\mathbf c}))\big)\\ \sin\big(\pi(\mathbf F_j\boldsymbol\delta+h_p(\hat{\mathbf c}))\big)\end{bmatrix} eq. 7
with A_j = h_a(z_j), F_j = h_f(z_j) eq. 5 and ĉ = max(c, c_tr), where
c_tr is the smallest cell size seen in training §3 eq. 7. The final
prediction adds the LR skip eq. 8:
\hat{\mathbf s}(\mathbf x)=\mathbf s(\mathbf x,\mathbf I^{LR};\Theta,\psi)+\mathbf I^{LR}_{\uparrow}(\mathbf x) eq. 8
Steps
- Encode the LR image into a feature map
zof the same height and width as the LR image §4.1 §3. - For each latent cell, let the 3x3 convolutional estimators see the 3x3 neighbourhood. The amplitude vector has 2K entries and the frequency matrix has K x 2 entries §3 eq. 5.
- For each query coordinate, take the four nearest latent cells. Compute the
offset
δfrom each cell centre, using the local grid §3. - Compute the phase term from the cell size, clamped to the training minimum §3 eq. 7.
- Form the Fourier basis, cos and sin of
π(Fδ + phase), and multiply by the amplitudes eq. 5 eq. 7. - Decode each latent's contribution with the shared MLP, then blend the four
results with local ensemble weights
w_jeq. 4 §3. - Add the bilinearly upscaled LR value at
xeq. 8.
# Predict a colour at query coordinate x with cell size c [§3] [eq. 4]
def query_rgb(x, c, lr_image, features):
# Encode and predict per-cell amplitudes and frequencies [§4.1] [eq. 5]
amplitudes = conv3x3_amp(features) # (B, 2K, H, W), 2K = 256
frequencies = conv3x3_freq(features) # (B, 2K, H, W)
total = 0
# Loop over the 4 nearest latent cells [§3] [code: models/lte.py#L51-L57]
for j in four_nearest_cells(x):
# Offset from the cell centre on the local grid [§3]
delta = x - centre_j
# Phase from the clamped cell size [§3] [eq. 7]
phase = phase_fc(max(c, c_train)) # (K,)
# Scaled frequency dot offset, plus phase [eq. 7]
angles = pi * (freq_j_matrix @ delta + phase) # (K,)
# Fourier basis gated by amplitudes [eq. 5]
basis = amp_j * concat(cos(angles), sin(angles)) # (2K,)
# Decode and blend with local ensemble weight w_j [eq. 4]
total = total + w_j * decoder(basis)
# LR skip connection [eq. 8]
return total + bilinear(lr_image, x)Training minimises the L1 distance between predicted and ground-truth pixels eq. 3 §5.1:
\hat\Theta=\arg\min_\Theta\sum_{m,n}\big\|\mathbf I^{HR}_n(\mathbf x_m)-\mathbf s(\mathbf x_m,\mathbf I^{LR}_n;\Theta)\big\|_1 eq. 3
Hyperparameters
| Name | Value | Where | Notes |
|---|---|---|---|
| Encoders | EDSR-baseline, RDN, SwinIR, upsampling layers removed | §4.1 train_edsr-baseline-lte.yaml | Output has LR size |
| Decoder | 4-layer MLP, ReLU, hidden 256 | §4.1 train_edsr-baseline-lte.yaml | Code: hidden list [256, 256, 256] plus output layer, so 4 linear layers in total mlp.py |
| Amplitude and frequency convs | 3x3, 256 output channels (2K) | §4.1 lte.py | K = 128 is implied by 2K = 256; not stated as K directly |
| Phase estimator | one FC layer, hidden 128 | §4.1 lte.py | Code: no bias term |
| Input patch | 48 x 48 LR | §5.1 train_edsr-baseline-lte.yaml | |
| Pixels per patch | 2304 (= 48 x 48) sampled from the HR patch | §4.2 train_edsr-baseline-lte.yaml | Loss computed on these |
| Training scale | uniform in [x1, x4], one value per image | §4.2 wrappers.py | Code draws a continuous value |
| Batch size | 16 (EDSR-baseline, RDN); 32 (SwinIR) | §5.1 train_edsr-baseline-lte.yaml train_swinir-lte.yaml | |
| Optimiser | Adam | §5.1 train_edsr-baseline-lte.yaml | Betas and epsilon not stated |
| Learning rate | 1e-4 (CNN encoders); 2e-4 (SwinIR) | §5.1 train_edsr-baseline-lte.yaml train_swinir-lte.yaml | |
| LR schedule | halved at [200, 400, 600, 800] (CNN); at [500, 800, 900, 950] (SwinIR) | §5.1 train_edsr-baseline-lte.yaml | Epoch total 1000 train_edsr-baseline-lte.yaml |
| Loss | L1 | eq. 3 §5.1 train.py | |
| Downsampling | bicubic | §5.1 wrappers.py | Code uses PIL bicubic via torchvision |
| Augmentation | not stated | train_edsr-baseline-lte.yaml wrappers.py | Random horizontal and vertical flip, plus transpose |
| Training data | DIV2K train | §5.1 train_edsr-baseline-lte.yaml | Code repeats the set 20 times |
| Validation | DIV2K valid, first 10 images | train_edsr-baseline-lte.yaml | Not stated in the paper |
| Input normalisation | (x - 0.5) / 0.5 on input and target | train_edsr-baseline-lte.yaml | Not stated in the paper |
| Test scales | in-scale x2, x3, x4; out-of-scale x6 to x30 | tab. 1 tab. 2 | |
| Training hardware and time | not stated | §5.1 | Only the timing test names a GPU tab. 4 |
| Random seeds, runs | not stated | No variance reported |
Results
Author-reported. All values are PSNR in dB. Table 1 uses the DIV2K validation
set. Table 2 uses four benchmark sets. † marks the authors' own
implementation; the paper does not say how the other rows were obtained
tab. 1 tab. 2. The paper's red and blue highlighting is not reproduced.
Table 1: DIV2K validation, arbitrary-scale SR tab. 1
| Method | x2 | x3 | x4 | x6 | x12 | x18 | x24 | x30 |
|---|---|---|---|---|---|---|---|---|
| Bicubic | 31.01 | 28.22 | 26.66 | 24.82 | 22.27 | 21.00 | 20.19 | 19.59 |
| EDSR-baseline | 34.55 | 30.90 | 28.94 | - | - | - | - | - |
| EDSR-baseline-MetaSR | 34.64 | 30.93 | 28.92 | 26.61 | 23.55 | 22.03 | 21.06 | 20.37 |
| EDSR-baseline-LIIF | 34.67 | 30.96 | 29.00 | 26.75 | 23.71 | 22.17 | 21.18 | 20.48 |
| EDSR-baseline-LTE | 34.72 | 31.02 | 29.04 | 26.81 | 23.78 | 22.23 | 21.24 | 20.53 |
| RDN-MetaSR | 35.00 | 31.27 | 29.25 | 26.88 | 23.73 | 22.18 | 21.17 | 20.47 |
| RDN-LIIF | 34.99 | 31.26 | 29.27 | 26.99 | 23.89 | 22.34 | 21.31 | 20.59 |
| RDN-LTE | 35.04 | 31.32 | 29.33 | 27.04 | 23.95 | 22.40 | 21.36 | 20.64 |
| SwinIR-MetaSR† | 35.15 | 31.40 | 29.33 | 26.94 | 23.80 | 22.26 | 21.26 | 20.54 |
| SwinIR-LIIF† | 35.17 | 31.46 | 29.46 | 27.15 | 24.02 | 22.43 | 21.40 | 20.67 |
| SwinIR-LTE | 35.24 | 31.50 | 29.51 | 27.20 | 24.09 | 22.50 | 21.47 | 20.73 |
Table 2: Benchmark sets, arbitrary-scale SR tab. 2. Columns are x2, x3, x4 (in-scale) and x6, x8 (out-of-scale). The table is laid out here with one row per dataset and method.
| Dataset | Method | x2 | x3 | x4 | x6 | x8 |
|---|---|---|---|---|---|---|
| Set5 | RDN | 38.24 | 34.71 | 32.47 | - | - |
| Set5 | RDN-MetaSR | 38.22 | 34.63 | 32.38 | 29.04 | 26.96 |
| Set5 | RDN-LIIF | 38.17 | 34.68 | 32.50 | 29.15 | 27.14 |
| Set5 | RDN-LTE | 38.23 | 34.72 | 32.61 | 29.32 | 27.26 |
| Set5 | SwinIR | 38.35 | 34.89 | 32.72 | - | - |
| Set5 | SwinIR-MetaSR† | 38.26 | 34.77 | 32.47 | 29.09 | 27.02 |
| Set5 | SwinIR-LIIF† | 38.28 | 34.87 | 32.73 | 29.46 | 27.36 |
| Set5 | SwinIR-LTE | 38.33 | 34.89 | 32.81 | 29.50 | 27.35 |
| Set14 | RDN | 34.01 | 30.57 | 28.81 | - | - |
| Set14 | RDN-MetaSR | 33.98 | 30.54 | 28.78 | 26.51 | 24.97 |
| Set14 | RDN-LIIF | 33.97 | 30.53 | 28.80 | 26.64 | 25.15 |
| Set14 | RDN-LTE | 34.09 | 30.58 | 28.88 | 26.71 | 25.16 |
| Set14 | SwinIR | 34.14 | 30.77 | 28.94 | - | - |
| Set14 | SwinIR-MetaSR† | 34.14 | 30.66 | 28.85 | 26.58 | 25.09 |
| Set14 | SwinIR-LIIF† | 34.14 | 30.75 | 28.98 | 26.82 | 25.34 |
| Set14 | SwinIR-LTE | 34.25 | 30.80 | 29.06 | 26.86 | 25.42 |
| B100 | RDN | 32.34 | 29.26 | 27.72 | - | - |
| B100 | RDN-MetaSR | 32.33 | 29.26 | 27.71 | 25.90 | 24.83 |
| B100 | RDN-LIIF | 32.32 | 29.26 | 27.74 | 25.98 | 24.91 |
| B100 | RDN-LTE | 32.36 | 29.30 | 27.77 | 26.01 | 24.95 |
| B100 | SwinIR | 32.44 | 29.37 | 27.83 | - | - |
| B100 | SwinIR-MetaSR† | 32.39 | 29.31 | 27.75 | 25.94 | 24.87 |
| B100 | SwinIR-LIIF† | 32.39 | 29.34 | 27.84 | 26.07 | 25.01 |
| B100 | SwinIR-LTE | 32.44 | 29.39 | 27.86 | 26.09 | 25.03 |
| Urban100 | RDN | 32.89 | 28.80 | 26.61 | - | - |
| Urban100 | RDN-MetaSR | 32.92 | 28.82 | 26.55 | 23.99 | 22.59 |
| Urban100 | RDN-LIIF | 32.87 | 28.82 | 26.68 | 24.20 | 22.79 |
| Urban100 | RDN-LTE | 33.04 | 28.97 | 26.81 | 24.28 | 22.88 |
| Urban100 | SwinIR | 33.40 | 29.29 | 27.07 | - | - |
| Urban100 | SwinIR-MetaSR† | 33.29 | 29.12 | 26.76 | 24.16 | 22.75 |
| Urban100 | SwinIR-LIIF† | 33.36 | 29.33 | 27.15 | 24.59 | 23.14 |
| Urban100 | SwinIR-LTE | 33.50 | 29.41 | 27.24 | 24.62 | 23.17 |
Table 3: Ablation on Set14, EDSR-baseline encoder tab. 3 §5.3. -A
removes the amplitude estimator, -F keeps 128 estimated frequencies, -P
removes the phase estimator and -L removes the LR skip §5.3.
| Variant | x2 | x3 | x4 | x6 | x8 |
|---|---|---|---|---|---|
| LTE | 33.72 | 30.37 | 28.65 | 26.50 | 24.99 |
| LTE (-A) | 33.66 | 30.07 | 28.66 | 26.49 | 24.93 |
| LTE (-F) | 33.66 | 30.35 | 28.64 | 26.50 | 24.98 |
| LTE (-P) | 33.58 | 30.26 | 28.58 | 26.40 | 24.90 |
| LTE (-L) | 33.62 | 30.36 | 28.64 | 26.48 | 24.98 |
Table 4: Memory and time, x2 SR, 624 x 624 input, EDSR-baseline encoder, RTX 3090 24 GB tab. 4 §6.
| Queries per call | Method | Params | Memory (GB) | Time (ms) |
|---|---|---|---|---|
| 9216 (96 x 96) | MetaSR | 1.7M | 1.9 | 3462 |
| 9216 (96 x 96) | LIIF | 1.6M | 1.9 | 4559 |
| 9216 (96 x 96) | LTE | 1.7M | 2.3 | 2912 |
| 1.6M (1248 x 1248) | MetaSR | 1.7M | OOM | - |
| 1.6M (1248 x 1248) | LIIF | 1.6M | 11.4 | 873 |
| 1.6M (1248 x 1248) | LTE | 1.7M | 10.2 | 925 |
| 1.6M (1248 x 1248) | LTE+ | 1.7M | 7.1 | 483 |
Figures are described in the text only: the qualitative comparisons are fig. 3 to fig. 6, the Fourier-space visualisations are fig. 7 to fig. 9, the qualitative ablation is fig. 10, and the discussion figures on DFT, aliasing and Gibbs ringing are fig. 11 to fig. 13. Figure numbers follow the order of appearance in the LaTeX source.
Paper vs code
Repository: github.com/jaewon-lee-b/lte at a8815d6, linked from the paper's
author block. The GitHub owner matches the first author's name, and the LICENSE
credits jaewon-lee-b LICENSE. Licence is BSD-3-Clause.
- Frequency count. The paper says the amplitude and frequency convolutions
produce 2K = 256 channels §4.1. The code applies the same 256 channels as 128
(frequency, pair) entries, so K = 128 lte.py
lte.py. The ablation text, however, says
-Festimates "only 128 frequencies (not 256)" §5.3, which implies the full model uses 256. The code matches K = 128, not 256. Follow the code. - Phase estimator. The paper describes it as a single FC layer with hidden
size 128 §4.1. The code is
Linear(2, 128, bias=False)lte.py, so it has no bias term and maps the cell size to a 128-vector. - Cell clamp. The paper defines
ĉ = max(c, c_tr)for the phase input §3 eq. 7. The model itself does not clamp. The clamp is applied only at test time, by multiplying the cell bymax(scale / scale_max, 1), withscale_max = 4test.py test.py. Training scales lie in [1, 4], so the clamp never changes a training cell. - Clamp only in batched evaluation. When
eval_bsizeis unset, the test path passes the raw cell and skips the clamp test.py. The shipped configs seteval_bsize: 30000, so the clamped path is the one used test-div2k-6.yaml. Apply the clamp in every path if you reimplement it. - Downsampling. The paper says bicubic resizing "in PyTorch" §5.1. The code resizes with PIL's bicubic filter via torchvision wrappers.py.
- Undocumented training details. The code adds random flips and a transpose wrappers.py, normalises inputs to [-1, 1] train_edsr-baseline-lte.yaml, and repeats the training set 20 times train_edsr-baseline-lte.yaml. None of these appear in the paper.
- PSNR protocol. The paper does not state it. The code computes DIV2K PSNR
on RGB with a border of
scale + 6pixels shaved utils.py. For the benchmark sets it converts to luminance with fixed weights and shavesscalepixels utils.py. - SwinIR evaluation. The code pads the LR input by reflection to a multiple of the window size before inference test.py. The README runs SwinIR with window size 8 README.md. The paper does not describe this padding.
- Decoder depth. The paper says "4-layer MLP" §4.1. The code has three hidden layers plus an output layer train_edsr-baseline-lte.yaml mlp.py. Under the "output layer counted" reading, these agree.
- Local ensemble weights. The paper calls
w_ja bilinear interpolation weight §3. The code weights each corner by the area of the opposite corner, swapping the indices lte.py. This is the standard local-ensemble rule of LIIF. Implement it as the code does. - Training loss and schedule. L1 loss, Adam, learning rates, batch sizes, epochs and milestones match train.py train_edsr-baseline-lte.yaml train_swinir-lte.yaml.
- LTE+. The paper describes it only in the discussion and in tab. 4, as
a 1x1-convolution decoder §6. The code is
lte-fastltep.py, with three 1x1 hidden layers and a 1x1 output ltep.py. The paper gives no training details for it. - Ablations and Fourier figures. No ablation configs are shipped. The Fourier
visualisations are in
Eval-Fourier-Feature-Space.ipynb, which was not read for this card.
Pitfalls
- Frequency count. Implement K = 128 (256 amplitude channels) as the code does. The ablation text's "256 frequencies" reading is not what the code computes.
- The 40% claim. The abstract says memory and time fall by 40%. Table 4 does not show that for LTE itself. At 9216 queries LTE is 36% faster than LIIF (2912 vs 4559 ms) but uses more memory (2.3 vs 1.9 GB). At 1.6M queries LTE takes 925 ms against LIIF's 873 ms, which is slower, but uses less memory (10.2 GB against 11.4 GB). The large saving appears only for LTE+ (483 ms, 7.1 GB), which is a different decoder §6 tab. 4.
- Four decoder calls per query. The local ensemble runs the decoder four times per query point lte.py. Cost grows with the number of queries, which is why the paper's timing depends on how many points are queried at once §6.
- Cell size is a hidden input. The phase term reads the cell size. Training
cells are
2 / (HR patch side)wrappers.py, and test cells are2 / (LR side x scale)test.py. A different convention shifts the phase, so keep cells consistent with training. - Out-of-scale results. Training scales stop at x4. Results at x6 to x30 depend on the test-time cell clamp described above §5.2. Apply it, or those results will not match.
- In-scale comparisons are not like-for-like. RDN and SwinIR are trained at fixed scales, so they win some in-scale entries in Table 2. For example, RDN scores 38.24 at Set5 x2, against 38.23 for RDN-LTE, and SwinIR scores 38.35, against 38.33 for SwinIR-LTE tab. 2 §5.2.
- Encoder dependence. EDSR-baseline-LTE captures mostly low-frequency components, while SwinIR-LTE captures diagonal frequencies §5.4 fig. 8. Encoder choice changes the Fourier behaviour, not just the PSNR.
- Ablation gaps are small. In tab. 3 most differences are at most 0.15 dB.
-Ais 0.30 dB below LTE at x3 and within 0.01 dB at x4. The number of runs and their variance are not reported. - Failure modes the paper names. Severe aliasing in the LR input makes the estimated dominant frequencies disagree with the ground truth §6 fig. 12. Ringing (Gibbs) overshoot appears at large scale, such as x12 §6 fig. 13.
- Training hardware and time are not stated, so the training budget cannot be reproduced from the paper alone.
Lineage
- Builds on: LIIF (local implicit image function, cited as
chen2021learning), which the paper extends by adding the Fourier-style estimator, the phase term and the LR skip §2 §3. Also on EDSR-baseline, RDN and SwinIR as encoders §4.1. Fourier feature mapping and NeRF-style position encoding inspired the frequency term §3. - Compared against: MetaSR (
hu2019meta), LIIF, and RDN and SwinIR trained at fixed scales §5.2. - Superseded by: not stated in the paper.
Source and license
Adapted from “Local Texture Estimator for Implicit Representation Function” by Jaewon Lee, Kyong Hwan Jin (arXiv:2111.08918), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/jaewon-lee-b/lte at commit a8815d6ac8a6 (BSD-3-Clause). Any quoted code is shown under that license.