Paper · 2020-12-18 · cs.CV
TDN: Temporal Difference Networks for Efficient Action Recognition
Adds two temporal difference modules to a 2D ResNet: a short-term one that uses RGB differences of neighbouring frames in early stages, and a long-term one that uses differences between sampled segments as attention in later stages. Author-reported: 52.3% top-1 on Something-Something V1 with 8 frames of ResNet-50, and state of the art on SSv1 and SSv2 among RGB-only models.
Convolutional neural networkOptical flowFrame differenceaction-recognitionvideotemporal-modelingefficient-inference
arXivPDFCodeMarkdown18 min read
AI-compiled by claude-haiku-5-5 on 2026-10-24, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Recognising an action in a video needs motion, not only appearance. A single frame shows a person and a cup, but not whether the cup is being lifted or pushed. Most fast video models get motion by stacking frames or by running a separate optical-flow network, and both can be slow.
TDN takes a cheaper route. It looks at the difference between neighbouring frames, which is closely related to what optical flow measures and is used as a cheaper stand-in for it. Where the pixels barely change, the difference is near zero, so the difference marks the parts of the picture that move. The network adds that motion signal to an ordinary 2D image network. It does this at two scales: a short-term signal from frames that sit next to each other, and a long-term signal that compares chunks of the whole video and uses the result to highlight the parts that matter for the action.
The design keeps the cost of a standard 2D convolutional network and adds a small overhead. The authors report that it beats other efficient video models on motion-heavy datasets. The paper is about the design and its ablations; the code is public.
TL;DR
- TDN is a video classifier built on a 2D ResNet with two temporal difference modules (TDMs), one short-term and one long-term §3.1.
- The short-term TDM (S-TDM) adds RGB differences of a small frame window to early stages. The long-term TDM (L-TDM) compares features of neighbouring sampled segments and uses the result as an attention gate in later stages §3.2 §3.3.
- Author-reported: 52.3% top-1 on Something-Something V1 with 8 frames of ResNet-50 at 36 GFLOPs, and state of the art among RGB-only models on SSv1 and SSv2 with similar backbones §4.3 tab. 2.
- Relevant if you need a 2D-cost action recognizer that is sensitive to motion. Check the paper-vs-code section first: the released code differs from the paper in several places.
Problem
Action recognition needs temporal modelling. Two common routes are costly. Two-stream networks need optical flow, which is expensive to compute §1. 3D convolutions add cost in the time dimension and often model time weakly §1. Plain 2D networks with late fusion over sampled frames (TSN-style) fail to capture fine temporal structure §2. The paper targets a video-level model that captures short-term and long-term motion at low extra FLOPs §1 §3.1.
Assumptions: the frames of a clip are sampled sparsely and uniformly across the video, as in TSN §3.1. The paper argues that Something-Something labels depend on motion rather than on objects or scene §4.1.
Method
TDN samples T segments from each video and reads one centre frame per segment plus its temporal neighbours §3.1. Each segment is processed by the same 2D backbone with shared weights fig. 2. Two modules add motion:
- S-TDM (early stages, Conv1 and Res2): RGB differences in a local window around the centre frame are downsampled, passed through a small CNN and upsampled, then added to the centre-frame feature §3.2 eq. 1 eq. 3.
- L-TDM (Res3 to Res5): for each pair of neighbouring segments, an aligned difference is computed, passed through a multi-scale branch and a sigmoid, and used as a spatiotemporal gate on the feature of the earlier segment §3.3 eq. 2 eq. 4 eq. 5 eq. 6.
The S-TDM and the L-TDM are shown in fig. 3. The overall architecture is in fig. 2. The exemplar is TDN-ResNet, which takes the TSN ResNet and inserts the two modules, placing S-TDM in the first two stages and L-TDM in the last three §3.4. Stage naming follows the paper: Conv1, Res2 to Res5 §3.4 tab. 1(d).
Overview
The T sampled frames form a tensor I of shape [T, C, H, W] §3.1. The short-term module adds motion to the frame feature F_i:
# Short-term TDM as a residual add [§3.1] [eq. 1]
# F_i: frame feature at an early stage; I_i: centre RGB frame
def short_term_fusion(frame_feature, centre_frame):
motion = short_term_tdm(centre_frame)
return frame_feature + motionThe long-term module is a multiplicative gate on the frame feature:
# Long-term TDM as a gated residual [§3.3] [eq. 2]
# F_i: frame feature of segment i; F_{i+1}: next segment
def long_term_fusion(frame_feature, next_feature):
gate = long_term_tdm(frame_feature, next_feature)
return frame_feature + frame_feature * gateShort-term TDM
The motion input is a stack of temporal RGB differences in a local window centred on I_i. The window contains four differences, D_-2, D_-1, D_1 and D_2, stacked along the channel axis §3.2. The module then works at low resolution, because the differences are small and sparse §3.2:
# Short-term TDM H(I_i) [§3.2] [eq. 3]
# Input: centre frame and its window of RGB differences
# Output: motion feature at the same size as the frame feature
def short_term_tdm(window):
# Four differences D_-2, D_-1, D_1, D_2 stacked on channels [§3.2]
diffs = stack_channels(window_differences(window)) # (12, H, W)
# Downsample by half with average pooling [§3.2]
low = avg_pool(diffs, factor=2) # (12, H/2, W/2)
# Light-weight 2D CNN on the low-resolution differences [§3.2]
motion = small_cnn(low) # (C, H/2, W/2)
# Upsample back to the frame feature size [§3.2] [eq. 3]
return upsample(motion) # (C, H, W)window_differences and stack_channels are described in words here: the
differences are consecutive differences of the window frames, flattened into
a 12-channel tensor for five RGB frames. The paper's own wording for the
differences and their order is loose, so see the pitfalls.
Most of the RGB difference values are small, and large values appear only in moving regions, so a low-resolution network is enough §3.2. The S-TDM is fused by addition at Conv1 and at Res2 §3.2 tab. 1(b).
Long-term TDM
The L-TDM works on the features of all T segments of one video, so it needs the batch of segments at once §3.3.
# Long-term TDM, one direction [§3.3] [eq. 4] [eq. 5]
# feats: (T, C', H, W) features after channel reduction by ratio r [§3.3]
# Output: attention map, one per segment, in (0, 1)
def aligned_difference(feats, neighbour):
# Smooth the neighbour spatially with a channel-wise conv [§3.3] [eq. 4]
return feats - channelwise_conv(neighbour) # (C', H, W)
def long_term_attention(feats, neighbours):
# Aligned temporal difference for each pair of segments [§3.3]
diff = aligned_difference(feats, neighbours) # (T, C', H, W)
# Three spatial scales, summed [§3.3] [eq. 5]
scales = scale_branch_1(diff) + scale_branch_2(diff) + scale_branch_3(diff)
# One more convolution and a sigmoid [§3.3] [eq. 5]
return sigmoid(conv(scales)) # (T, C, H, W)The gate is built in both directions and averaged, so the module sees both the past and the future neighbour §3.3 eq. 6:
# Bidirectional gate and residual output [§3.3] [eq. 6] [eq. 2]
# frames: (T, C, H, W) frame features of one stage
def long_term_tdm(frames):
forward = long_term_attention(frames, next_segment(frames))
backward = long_term_attention(frames, previous_segment(frames))
# Average the two directions [§3.3] [eq. 6]
gate = 0.5 * (forward + backward) # (T, C, H, W)
# Residual gating of the frame features [§3.3] [eq. 2]
return frames + frames * gateThe paper does not say how the first and last segments, which have no neighbour on one side, are handled. The released code pads with zeros (see Paper vs code and Pitfalls).
TDN-ResNet
The exemplar follows TSN and V4D §3.4. The first two stages carry S-TDMs for local motion. The last three stages carry L-TDMs and a temporal convolution in each residual block for longer-range structure §3.4. The paper states that this adds about 9% FLOPs over the 2D TSN-ResNet §3.4. That figure is not verified here.
Hyperparameters
Values are from the paper where stated, and from the released training commands and defaults where the paper is silent. Entries marked as code-only are not in the paper.
| Name | Value | Where | Notes |
|---|---|---|---|
| Backbone | ResNet-50, ResNet-101 | §4.1 | ImageNet pre-training §4.1 |
| Segments T | 8 or 16; "8+16" in the comparison tables | §4.1 tab. 2 tab. 3 | the paper does not define "8+16"; its FLOPs equal the sum of the 8- and 16-frame costs (36+72=108, 66+132=198), so it is likely an ensemble, inferred |
| Frames per segment | 5 consecutive frames | dataset.py models.py | not stated in the paper; the differences need the window |
| Input size | 224x224 crop | §4.1 | |
| Resize before crop | shorter side in [256, 320] | §4.1 | code uses multi-scale crop, scales 1, .875, .75, .66 models.py |
| Horizontal flip | not stated | - | code: on, with a label swap for Something-Something main.py models.py |
| Test scale | shorter side 256 | §4.1 | models.py |
| Test, 1 clip | centre 224x224 crop, one clip | §4.1 tab. 2 | used for Something-Something |
| Test, 10 clips | 3 crops of 256x256, 10 clips, 30 views | §4.1 tab. 3 | README.md |
| Batch size | 128 | §4.1 | README commands use 8 per GPU on Something-Something V1 and 16 per GPU on Kinetics, 8 GPUs README.md |
| Optimiser | SGD | not stated | main.py |
| Momentum | not stated | - | 0.9 default opts.py |
| Initial learning rate | 0.02 | §4.1 | README: 0.01 for Something-Something V1, 0.02 for Kinetics README.md README.md; argparse default 0.001 opts.py |
| Epochs | 100 Kinetics; 60 Something-Something | §4.1 | README matches README.md |
| LR schedule | divide by 10 when validation saturates | §4.1 | README uses fixed milestones: Something-Something V1 at 30, 45, 55; Kinetics at 50, 75, 90 README.md README.md; step gamma 0.1 opts.py lr_scheduler.py |
| Warm-up | not stated | - | off by default opts.py |
| Weight decay | not stated | - | README: 5e-4 for Something-Something V1, 1e-4 for Kinetics README.md README.md |
| Dropout before FC | not stated | - | 0.5 in README and default opts.py |
| Gradient clip | not stated | - | README passes gradient norm 20 README.md; applied only when set main.py |
| Segment consensus | not stated | - | average opts.py |
| Loss | not stated | - | negative log-likelihood is the only option in code opts.py |
| Partial BN | not stated | - | off: flag is always True, so partial BN is disabled opts.py main.py |
| Reduction ratio r (L-TDM) | "ratio r", value not stated | §3.3 | 16 in code base_module.py |
| L-TDM scales N | 3 | §3.3 eq. 5 | three branches, averaged in code base_module.py |
| L-TDM pooling | not stated | §3.3 | 2x2 average pool in code base_module.py |
| S-TDM downsampling | average pooling by half | §3.2 | 2x2 tdn_net.py |
| S-TDM fusion weights | addition, F + H | §3.2 eq. 1 tab. 1(b) | code: 0.5 and 0.5 for T=8, 0.75 and 0.25 for T=16 tdn_net.py |
| Temporal conv | not stated | §3.4 | depthwise 3-tap conv, shift-initialised, 2 of 8 channel groups shifted base_module.py base_module.py |
| Hardware and speed | Tesla V100, batch 16, includes data loading | app. B | 22.1 ms per video for TDN with 8 frames |
Results
Author-reported. Setup: 1-clip centre-crop test on Something-Something unless noted; 10-clip, 3-crop on Kinetics §4.1 §4.3. Backbones are ResNet-50 or ResNet-101 with ImageNet pre-training. Numbers are from the paper's tables, as printed there. Something-Something V1 and V2 comparison, RGB only, similar backbones §4.3 tab. 2:
| Method | Backbone | Frames | GFLOPs | SSv1 Top-1 | SSv1 Top-5 | SSv2 Top-1 | SSv2 Top-5 |
|---|---|---|---|---|---|---|---|
| TSN-RGB | BNInception | 8 | 16 | 19.5 | - | - | - |
| TRN-Multiscale | BNInception | 8 | 33 | 34.4 | - | 48.8 | 77.6 |
| S3D-G | Inception | 64 | 71.38 | 48.2 | 78.7 | - | - |
| TSM | ResNet-50 | 8+16 | 98 | 49.7 | 78.5 | - | - |
| TEINet | ResNet-50 | 8+16 | 99 (SSv1) / 98 (SSv2) | 52.5 | - | 65.5 | 89.8 |
| TANet | ResNet-50 | 8+16 | 99 | 50.6 | 79.3 | - | - |
| TEA | ResNet-50 | 16 | 70 | 51.9 | 80.3 | - | - |
| TAM | bLResNet-50 | 16x2 | 47.7 | 48.4 | 78.8 | 61.7 | 88.1 |
| ECO-Lite | BNInception+R18 | 92 | 267 | 46.4 | - | - | - |
| I3D | ResNet-50 | 32x2 | 306 | 41.6 | 72.2 | - | - |
| NL I3D+GCN | R50+GCN | 32x2 | 606 | 46.1 | 76.8 | - | - |
| GST | ResNet-50 | 16 | 59 | 48.6 | 77.9 | 62.6 | 87.9 |
| STM | ResNet-50 | 16x30 | 67x30 | 50.7 | 80.4 | 64.2 | 89.8 |
| V4D | ResNet-50 | 8x4 | 167.6 | 50.4 | - | - | - |
| SmallBigNet | ResNet-50 | 8+16 | 157 | 50.4 | 80.5 | 63.3 | 88.8 |
| CorrNet | ResNet-50 | 32x10 | 115x10 | 49.3 | - | - | - |
| TANet (24x6) | ResNet-50 | 24x6 | 99x6 | - | - | 66.0 | 90.1 |
| TDN | ResNet-50 | 8 | 36 | 52.3 | 80.6 | 64.0 | 88.8 |
| TDN | ResNet-50 | 16 | 72 | 53.9 | 82.1 | 65.3 | 89.5 |
| TDN | ResNet-50 | 8+16 | 108 | 55.1 | 82.9 | 67.0 | 90.3 |
| CorrNet | ResNet-101 | 32x30 | 224x30 | 51.7 | - | - | - |
| CorrNet (Sports-1M pre-trained) | ResNet-101 | 32x30 | 224x30 | 53.3 | - | - | - |
| GSM | Inception V3 | fusion | 268 | 55.2 | - | - | - |
| TDN | ResNet-101 | 8 | 66 | 54.1 | 81.9 | 65.8 | 90.2 |
| TDN | ResNet-101 | 16 | 132 | 55.3 | 83.3 | 66.9 | 90.9 |
| TDN | ResNet-101 | 8+16 | 198 | 56.8 | 84.1 | 68.2 | 91.6 |
Notes on the table: "-" means the value was not available to the authors tab. 2. The paper's footnote marks CorrNet with Sports-1M pre-training tab. 2. The Something-Something V2 rows for TDN are the paper's values. Other baselines are listed at 8 and 16 frames exactly as in the source.
Kinetics-400, RGB, similar backbones, 10 clips and 3 crops §4.3 tab. 3:
| Method | Backbone | Frames x Clips x Crops | GFLOPs | Top-1 | Top-5 |
|---|---|---|---|---|---|
| TSN | InceptionV3 | 25x1x10 | 3.2x250 | 72.5 | 90.2 |
| S3D-G | InceptionV1 | 64x10x3 | 71.4x30 | 74.7 | 93.4 |
| R(2+1)D | ResNet-34 | 32x10x1 | 152x10 | 74.3 | 91.4 |
| TSM | ResNet-50 | 16x10x3 | 65x30 | 74.7 | 91.4 |
| TEINet | ResNet-50 | 16x10x3 | 66x30 | 76.2 | 92.5 |
| TEA | ResNet-50 | 16x10x3 | 70x30 | 76.1 | 92.5 |
| TAM | bLResNet-50 | 48x3x3 | 93.4x9 | 73.5 | 91.2 |
| TANet | ResNet-50 | 16x4x3 | 86x12 | 76.9 | 92.9 |
| ARTNet | ResNet-18 | 16x25x10 | 23.5x250 | 70.7 | 89.3 |
| I3D | InceptionV1 | 64 | 108 | 72.1 | 90.3 |
| NL I3D | ResNet-50 | 128x10x3 | 282x30 | 76.5 | 92.6 |
| SlowOnly | ResNet-50 | 8x10x3 | 41.9x30 | 74.8 | 91.6 |
| SlowFast | ResNet-50 | (4+32)x10x3 | 36.1x30 | 75.6 | 92.1 |
| SlowFast | ResNet-50 | (8+32)x10x3 | 65.7x30 | 77.0 | 92.6 |
| SmallBigNet | ResNet-50 | 8x10x3 | 57x30 | 76.3 | 92.5 |
| CorrNet | ResNet-50 | 32x10x1 | 115x10 | 77.2 | - |
| TDN | ResNet-50 | 8x10x3 | 36x30 | 76.6 | 92.8 |
| TDN | ResNet-50 | 16x10x3 | 72x30 | 77.5 | 93.2 |
| TDN | ResNet-50 | (8+16)x10x3 | 108x30 | 78.4 | 93.6 |
| NL I3D | ResNet-101 | 128x10x3 | 359x30 | 77.7 | 93.3 |
| ip-CSN | ResNet-101 | 32x10x3 | 83.0x30 | 76.7 | 92.3 |
| SlowFast | ResNet-101 | (8+32)x10x3 | 106x30 | 77.9 | 93.2 |
| SlowFast | ResNet-101 | (16+64)x10x3 | 213x30 | 78.9 | 93.5 |
| SmallBigNet | ResNet-101 | 32x4x3 | 418x12 | 77.4 | 93.3 |
| CorrNet | ResNet-101 | 32x10x3 | 224x30 | 79.2 | - |
| TDN | ResNet-101 | 8x10x3 | 66x30 | 77.5 | 93.6 |
| TDN | ResNet-101 | 16x10x3 | 132x30 | 78.5 | 93.9 |
| TDN | ResNet-101 | (8+16)x10x3 | 198x30 | 79.4 | 94.4 |
| SlowFast | R101+NL | (16+64)x10x3 | 234x30 | 79.8 | 93.9 |
| X3D | X3D-XL | 16x10x3 | 48.4x30 | 79.1 | 93.9 |
The paper states that the best Kinetics Top-1 is the SlowFast plus non-local combination, which is slightly better than TDN on Top-1, while its Top-5 is lower §4.3.
Transfer, 16-frame TDN-ResNet-50 pre-trained on Kinetics-400, mean over three splits app. A: UCF101 97.4% and HMDB51 76.3%. The paper says the gain is more visible on HMDB51, by around 2.5 points, than on UCF101 app. A.
Ablations on Something-Something V1, 8-frame TDN-ResNet-50, 1-clip centre crop tab. 1:
| Setting | Variant | FLOPs | Top-1 |
|---|---|---|---|
| tab. 1(a) S-TDM and L-TDM operator | concat + average (baseline) | 36.2G | 41.5% |
| concat + difference in L-TDM | 36.2G | 51.4% | |
| difference in S-TDM + average in L-TDM | 35.9G | 51.6% | |
| difference in both | 35.9G | 52.3% | |
| tab. 1(b) S-TDM fusion | F * H (multiplicative) | - | 43.7% |
| F + F * H | - | 47.6% | |
| F + H (chosen) | - | 52.3% | |
| F * H_channel | - | 47.3% | |
| F + F * H_channel | - | 47.9% | |
| tab. 1(c) L-TDM fusion | F + G, multi-scale, bidirectional | - | 44.1% |
| F + F * G_channel, bidirectional | - | 50.9% | |
| F + F * G, multi-scale only | - | 50.0% | |
| F + F * G, bidirectional only | - | 49.7% | |
| F + F * G, multi-scale and bidirectional (chosen) | - | 52.3% | |
| tab. 1(d) Placement (stage labels as in the table) | none | 33G | 46.6% |
| S-TDM stage 1, L-TDM stages 2-5 | 35G | 50.6% | |
| S-TDM stages 1-2, L-TDM stages 3-5 (chosen) | 36G | 52.3% | |
| S-TDM stages 1-3, L-TDM stages 4-5 | 38G | 51.7% | |
| tab. 1(e) Module choice | none | - | 46.6% |
| S-TDM at Conv1 only | - | 51.3% | |
| S-TDM at Conv1 and Res2 | - | 51.5% | |
| L-TDM only | - | 49.9% | |
| S-TDM and L-TDM | - | 52.3% | |
| tab. 1(f) Other temporal modules, 8 frames | T-Conv, 33G / 40 frames, 165G | 33G / 165G | 47.5% / 48.2% |
| TSM, 33G / 40 frames, 165G | 33G / 165G | 47.1% / 47.6% | |
| TEINet, 33G / 40 frames, 165G | 33G / 165G | 48.4% / 49.0% | |
| TDM | 36G | 52.3% |
Table 1(e) in the paper's text is the same S-TDM versus L-TDM comparison that the appendix cites. The paper reports the baseline for Table 1(f) at 8 frames with ResNet-50 and at 40 frames for the "++" rows §4.2. The table rows above use the paper's own labels. Top-5 for the module comparison is 80.6% for TDM against 76.2% to 79.1% for the baselines tab. 1(f).
Running time on a Tesla V100, batch 16, including data loading app. B: TSN with 8 frames 7.9 ms per video, TSM with 16 frames 16.7 ms, STM with 8 frames 11.1 ms, I3D with 32x3x2 2095 ms, and TDN with 8 frames 22.1 ms. The paper states that TDN is slower than the previous methods but still real-time at 25 FPS or more app. B.
Visualisation with Grad-CAM shows that the TDN models attend to the moving hand and the object it interacts with, where the temporal-convolution baseline focuses more on background §4.4 fig. 4 app. C. This is qualitative.
Paper vs code
Code: https://github.com/MCG-NJU/TDN, commit
a7c7e9bcd109d8256cd27a11505bd6e00de39ce0, Apache-2.0. The repository belongs
to the authors' lab and is linked from the abstract. The code
differs from the paper in these places. Each item is a discrepancy, not a
bug report; the README results match the paper's headline numbers, so the
released checkpoints presumably follow the code, not the text. That is an
inference.
- S-TDM fusion. The paper adds the motion feature to the frame feature, F + H §3.2 eq. 1 tab. 1(b). The code blends them with fixed weights: 0.5 and 0.5 for 8 segments, 0.75 and 0.25 for 16 tdn_net.py. The fusion is applied after the stem and after Res2 tdn_net.py.
- S-TDM motion branch. The paper calls the motion CNN light-weight §3.2. The code uses a 7x7 stride-2 convolution with 12 input channels, initialised from the mean of the RGB stem kernel and repeated four times tdn_net.py, then a max-pool and a full ImageNet-initialised ResNet layer 1 tdn_net.py tdn_net.py. That is not light-weight.
- Window and differences. The paper gives the four differences D_-2, D_-1, D_1, D_2 §3.2. The code takes five consecutive frames per segment and forms four consecutive differences tdn_net.py dataset.py.
- L-TDM difference sign. The paper writes C(F_i, F_{i+1}) = F_i - Conv(F_{i+1}) eq. 4. The code computes Conv(F_{i+1}) - F_i for the forward direction base_module.py. The sign is reversed.
- L-TDM convolution. The paper calls the smoothing convolution channel-wise §3.3. The code uses a depthwise 3x3 convolution with groups equal to C/r base_module.py.
- L-TDM gate. The paper's gate is 0.5 times the sum of the two directional attentions, in (0, 1), used as F + F * G eq. 2 eq. 6. The code subtracts 0.5 from each sigmoid, so the gate lies in (-0.5, 0.5), and the output is x + x * gate base_module.py.
- L-TDM scale branches. The paper lists a short connection, a 3x3 convolution, and average pooling, a 3x3 convolution and bilinear upsampling, and sums them §3.3 eq. 5. The code uses three branches: the difference itself, a 3x3 convolution on the full-resolution difference, and a 2x2 average pool, a 3x3 convolution and upsampling with the default nearest mode. It averages the three branches with weight 1/3 each base_module.py base_module.py. The paper's upsampling is bilinear.
- L-TDM normalisation. The paper's attention is a convolution followed by a sigmoid eq. 5. The code adds BatchNorm after the 1x1 convolution base_module.py base_module.py. The two directions share the BatchNorm modules base_module.py.
- L-TDM input. The paper applies the module to the frame feature F_i eq. 2. The code applies it to the ReLU output of the block's first 1x1 convolution, inside the residual branch, before the 3x3 convolution base_module.py. The outer residual is unchanged.
- Temporal convolution. The paper mentions a temporal convolution in each residual block of Res3 to Res5 without specifying it §3.4. The code uses a learnable depthwise 3-tap convolution along the segment axis, initialised as a shift: one eighth of the channels take the previous frame, one eighth the next, and the rest are unchanged base_module.py base_module.py. It is inserted after the L-TDM and before the 3x3 convolution base_module.py.
- Layer placement. The paper puts L-TDMs in Res3 to Res5 §3.4. In the code, the BottleneckShift block, which carries the L-TDM and the temporal convolution, is used for Res3 to Res5. Res2 uses the plain bottleneck base_module.py.
- Batch and learning rate for Something-Something V1. The paper uses batch 128 and learning rate 0.02 §4.1. The README command uses learning rate 0.01 and batch 8 per process on 8 GPUs README.md.
- LR schedule. The paper decays the learning rate when validation saturates §4.1. The code uses fixed milestones README.md lr_scheduler.py.
- Augmentation. The paper resizes the shorter side to 256 to 320 and takes a 224 crop §4.1. The code uses multi-scale cropping with scales 1, .875, .75 and .66 models.py and horizontal flipping, which the paper does not mention. For Something-Something, flipping swaps the left and right classes main.py models.py.
- Partial BN. Not in the paper. The flag is defined with
default=True, action="store_true", so it is always True, and partial BN is therefore disabled opts.py main.py. - Results. The paper gives 89.5% Top-5 for TDN-ResNet-50 with 16 frames on Something-Something V2 tab. 2. The README gives 89.7% README.md. The README also lists Something-Something V2 entries with multi-crop testing (8x3x1, 16x3x1 for ResNet-101, and 8+16 with 3 crops) that the paper does not report README.md README.md.
Pitfalls
- Five frames per segment, not one. The dataset loader reads five consecutive frames for each segment, and the network reshapes its input to five frames dataset.py models.py. Decoding and I/O cost is five times a TSN loader that reads one frame per segment. The paper never states this; the window size is only implied by the four differences §3.2.
- Fusion weights change the pretrained features. Adding the motion feature (paper) and blending it with 0.5 weights (code) are different operations for the pretrained layers. Before reproducing the numbers, check which one the training code uses. The code selects weights by segment count, using
num_segments is 8, an identity comparison that works for small integers but is fragile tdn_net.py. - Boundary segments. For the first and last segment, the L-TDM has no neighbour on one side. The paper does not say what it does. The code zero-pads the difference base_module.py.
- Sign and offset of the gate. The reversed difference sign (item 4) and the -0.5 offset (item 6) change the gate's range and direction. A reimplementation that follows Eq. 2 and Eq. 6 literally will not match the released code.
- Shared BatchNorm across directions. The forward and backward branches reuse the same BatchNorm and convolution modules base_module.py. The running statistics are computed on both directions combined. The paper does not mention this.
- "8+16" is not defined in the text. The tables use it, but the paper never says what it means. The FLOPs equal the sum of the 8- and 16-frame costs, which suggests an ensemble of two models. This is an inference. Compare "8+16" rows with care.
- Test-time protocol. The 1-clip rows use centre cropping with a shorter side of 256 §4.1. The 10-clip, 3-crop rows need 30 forward passes per video README.md. Reported numbers depend on this.
- Kinetics videos. The authors note that downloaded Kinetics videos may differ from the originals, so results may vary README.md. The paper uses about 240k training videos §4.1.
- Variance and seeds. Seeds, number of runs and variance are not stated for any table.
- Speed. The paper reports 22.1 ms per 8-frame video on a V100 with batch 16, including data loading app. B. That is slower than the baselines it names in the same table. The paper calls this real-time (25 FPS or more) app. B. The timing includes data loading, so it is not a pure model cost, and a five-frame loader affects it (see the first pitfall).
- Equation numbering. Equation numbers here (eq. 1 to eq. 6) follow the order of the equations in the LaTeX source. Verify against the PDF before citing a number in another document.
- Table numbering. Table 1 is the ablation with sub-tables (a) to (f) tab. 1. Table 2 and Table 3 are the Something-Something and Kinetics comparisons tab. 2 tab. 3, numbered by source order. Appendix tables and figures are cited by section.
- Efficiency claims. The paper's FLOP counts are per 224x224 1-clip inputs tab. 1 caption. Wall-clock time is a separate measure app. B and was not compared with the FLOPs.
Lineage
- Builds on: TSN sparse segment sampling and late fusion §3.1 §2; ResNet backbone §3.4; the stage split of V4D §3.4; feature-difference ideas from TEINet, TEA and STM §2; the released code is built on the TSN and TSM code bases README.md.
- Compared against: TSM, TEINet, TANet, TEA, TAM, GST, STM, SmallBigNet, CorrNet, GSM, I3D, Non-local I3D, SlowFast, X3D and others, as listed in tab. 2 and tab. 3.
- Superseded by: not stated in this wiki.
Source and license
Adapted from “TDN: Temporal Difference Networks for Efficient Action Recognition” by Limin Wang, Zhan Tong, Bin Ji, Gangshan Wu (arXiv:2012.10071), 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/MCG-NJU/TDN at commit a7c7e9bcd109 (Apache-2.0). Any quoted code is shown under that license.