Yoshimitsu Systems
YS-EN-0006 · Engineering Note · YS·FLOOR

Tomorrow's air: a dilated CNN against the forecasts it has to beat

A stack of dilated convolutions can read a whole week of sensor data with a handful of layers. We tested whether that makes it a better day-ahead forecaster for office CO2 than the simple forecasts any building engineer already has, on 13 real rooms with the holidays held out.

Report YS-EN-0006 Rev 1 Published Author Morimoto Kenji, Lattice Process Lead Reading time 16 min Code & data ↓
A building-services desk at dusk. On the wall, a white CO2 sensor labelled YS·FLOOR · RM 3-07 · CO2 reads 418 ppm. A monitor titled YS·FLOOR · AIR PLAN · TOMORROW plots a week of hourly CO2 for room 3-07, five weekday humps and a flat weekend, then an amber 24-hour forecast, beside a vent schedule of times and fan percentages and a row of small charts for rooms 3-01 to 3-12. On the desk, a December planner with a red marker bracket across the last days of the month reading 年末休業 — SITE CLOSED and a circled note, ADD TO CALENDAR FEED; a ventilation balancing sheet on a clipboard, a 良光 mug, and a bagged spare sensor with a calibration tag. Behind a glass partition, an empty open-plan office under exposed ductwork and a VAV box, a 良光 Yoshimitsu Systems sign, and through the window Kyoto at dusk with a pagoda
YS·FLOOR · Building services desk · Kyoto

Abstract

A temporal convolutional network (TCN) stacks causal convolutions whose dilation doubles at every layer, so eight layers with two-tap kernels see 256 hours, more than a week of hourly data. We test the idea as a day-ahead forecaster: at midnight, read the last 168 hours of a room's CO2 and predict the next 24. Our comparison set is seven forecasts that need no training, ridge and linear models, and a GRU. The data is the VTT SCOTT dataset: 13 offices in Finland, 2019, trained on February to August and tested on October to December, holidays included.1

The TCN works. With a calendar input it scores a mean absolute error of 15.5 ppm against 17.3 ppm for the best baseline (the mean of last week's days of the same type), 10% better and better in 12 of 13 rooms. Most of the gain is on days the office stays empty. On ordinary workdays the best baseline and every network land within about 1.5 ppm of each other, because whether people come in is not in last week's data. A one-layer GRU did better still, 14.9 ppm and better than the baseline in all 13 rooms. The calendar input cut the error on weekday holidays from 18.9 to 6.2 ppm and cost nothing on ordinary workdays; its worst errors came on the days between Christmas and New Year, when the national calendar said "work" and the offices were empty.

15.5 vs 17.3 ppmday-ahead error of the TCN against the best forecast that needs no training
14.9 ppma plain GRU, better than the TCN; better than the baseline in all 13 rooms
18.9 → 6.2 ppmTCN error on weekday holidays, without and with a calendar input
0.183 vs 0.226the 2023 TCN on the clean synthetic series, against the expected error of copying a past day; the noise floor is 0.160

A day ahead

Building services at our Kyoto site ventilate rooms on a schedule set the evening before. Ventilate too little and air goes stale by mid-morning; ventilate an empty room and you pay to heat or cool outside air for nobody. Every room has a CO2 sensor, so the obvious question is whether tomorrow's readings can be forecast well enough to set that schedule.

CO2 is the right signal for this job and the wrong one for most others. ASHRAE's position is that indoor CO2 concentrations "are not overall indicators of IAQ", and that the familiar 1,000 ppm figure "is at best an indicator of outdoor air ventilation rate per person".2 What CO2 does track is people: an average adult doing office work exhales about 0.0052 litres a second,3 so in a room with fixed ventilation it rises when the room fills and decays when it empties. Forecasting CO2 a day ahead is mostly forecasting occupancy.

In 2023 one of us proposed a model for it: a stack of dilated causal convolutions in the style of WaveNet, reading a week and writing a day. It was tested on synthetic data and looked promising, but it was never compared with anything. This note rebuilds it and makes the comparison. The hypotheses, from that report, made testable:

  1. H1. The TCN beats the simple forecasts (same hour last week, yesterday, and so on) and a linear model on the same inputs.
  2. H2. Telling it which future hours are working days fixes public holidays without costing accuracy on ordinary days.
  3. H3. Normalising each input window fixes its failure on levels it has never seen.
  4. H4. A week of history beats one to three days.
  5. H5. It beats a recurrent network, which the report expected to struggle with long seasonality.

A week in eight layers

A one-dimensional convolution with kernel size k computes each output from k adjacent inputs. Make it causal by padding on the left only, so the output at hour t depends on hours up to t and never later; that is what lets the same network forecast. Stacking plain layers grows the window by k − 1 per layer, so seeing 168 hours with k = 2 would take 167 layers. WaveNet's answer was dilation: layer i skips 2i − 1 inputs between its taps, so the dilations run 1, 2, 4, 8 and the window doubles with every layer (Figure 1).4 Bai, Kolter and Koltun called the general recipe, causal dilated convolutions with residual connections, a temporal convolutional network, "not as a label for a truly new architecture, but as a simple descriptive term".5 Borovykh and colleagues applied it to forecasting in 2017.6

FIG. 1 — HOW FAR A DILATED STACK SEES
input (hours) layer 1 · dilation 1 layer 2 · dilation 2 layer 3 · dilation 4 layer 4 · dilation 8 t − 15 t
Figure 1. Causal convolutions with kernel size 2 and dilation doubling at each layer. The highlighted paths are every connection that reaches the last output: it depends on the last 24 = 16 inputs and on nothing later. With eight layers (dilations 1 to 128) the same construction sees 28 = 256 hours, enough for a week of hourly data.

Each layer with dilation d adds (k − 1)d hours of history,5 so L layers with dilations 1 to 2L−1 see the window of Equation 1:

r=1+(k−1)∑i=0L−12i=1+(k−1)(2L−1),r=2L when k=2 (1)

Eight layers give 256 hours, which covers the 168 the forecast reads. We checked it on the network itself: fed 400 hours, the gradient of the stack's last position is non-zero for exactly the last 256 (check_rf.py).

The 2023 report also said this design "would only require the model to learn 2 × 8 = 16 kernel values". That is true for a network with one filter per layer, which could learn very little. Its own architecture had 32 filters per layer, and a layer with Cin inputs and Cout filters has 2CinCout + Cout parameters: 96 for the first layer, 2,080 for each of the other seven, and 64 for the 1 × 1 convolution that lets the first residual connection add up. That makes 14,720 in the convolutions, and 19,073 in our rebuild of the whole model with its dense layers (the report's adds its input without the 1 × 1 convolution, 64 fewer). Still small: the point of dilation is not that it needs few weights, but that the count grows with log2 of the window instead of with the window.

We use residual blocks as the report did (one dilated convolution, ReLU and dropout, plus the block's input) and test two ways of turning the stack into 24 forecasts. The report's 2023 head runs a small dense network at every time step and keeps the last 24 positions. Because the convolutions are causal, the forecast for each hour then sees data only up to the same hour the day before. In the report's calendar version, each of those 24 values is paired with its own hour's workday flag and passed through a second small dense network, hour by hour. Our direct head flattens the last 24 positions, adds the 24 future workday flags and hour-of-day features, and maps them to all 24 hours at once, so every hour sees the whole history and the whole of tomorrow's calendar.

What it has to beat

Hyndman and Athanasopoulos open their benchmark chapter with "some forecasting methods are extremely simple and surprisingly effective", and close it with the rule that a new method should be compared with them: "If not, the new method is not worth considering."7 On 1,045 monthly series from the M3 competition, Makridakis and colleagues found that "even Naive 2 (a seasonal Random Walk (RW) benchmark) is more accurate than half of the ML methods", LSTMs included.8 On long-horizon benchmarks, one-layer linear models have beaten far more complex transformers.9 So before any network, we built the forecasts a building engineer could write in an afternoon. All but the room profile see only the same 168 hours as the networks, plus the calendar:

  • Same hour last week and same hour yesterday: seasonal naive forecasts with periods of 168 and 24 hours.7
  • Last day of the same type: copy the most recent workday if tomorrow is a workday, or the most recent non-working day if it isn't.
  • Mean and median of same-type days: average every day of tomorrow's type in the last week, hour by hour.
  • Room profile: the median of each hour of the day over the training months, separately for workdays and other days.
  • Ridge regression on the 168 hours of CO2, with and without tomorrow's calendar, and a linear model trained exactly like the networks, which also sees the past workday flags (see below).

The networks are trained on absolute error, with Adam and early stopping on a validation month. Every score in this note is mean absolute error (MAE) over the 24 hours of a forecast day, averaged over days.

The clean version

The 2023 report tested on synthetic "office CO2": a flat baseline at night, a double hump on workdays (a truncated sine with a lunch dip), a low single hump at weekends and on statutory holidays, and noise. We rebuilt it from the report's description (not its code, which didn't survive) with Gaussian noise of σ = 0.2 on a scale where the workday peak is about 15, over three years of Ontario holidays: train 2021–22, validate the first half of 2023, test the second half, Thanksgiving included.

Synthetic data has a property real data lacks: we know the best possible score. A forecast that knew the true profile would be wrong only by the noise, and a forecast that copies a noisy past day carries two lots of noise:

MAEbest=σ2/π=0.160,MAEcopy=σ22/π=0.226 (2)
FIG. 2 — THE CLEAN VERSION
0 0.2 0.4 0.6 0.8 1 1.2 Mean absolute error (noise σ = 0.2; lower is better) copy floor 0.226 best possible 0.160 Same hour last week 0.310 Same hour yesterday 0.977 Last day of the same type 0.224 Ridge regression 0.373 Ridge + calendar 0.281 TCN, 2023 design 0.259 TCN 0.296 TCN, 2023 design + calendar 0.183 TCN + calendar 0.225 GRU + calendar 0.169
Baseline, no trainingLinear modelNeural network
Figure 2. Mean absolute error on the rebuilt synthetic series, July–December 2023, two independent noise draws. Dashed lines: the best any forecast can do (it knows the true profile) and the best a copy of one noisy past day can do (Equation 2). Neural rows average three seeds.
Table view
Day-ahead MAE, synthetic test half-year (two noise draws)
MethodMAE95% intervalWeekday holidays
Same hour last week0.3100.252–0.3832.83
Same hour yesterday0.9770.806–1.1610.23
Last day of the same type0.2240.221–0.2270.23
Ridge regression0.3730.317–0.4432.61
Ridge + calendar0.2810.245–0.3241.78
TCN, 2023 design0.2590.210–0.3202.67
TCN0.2960.246–0.3562.64
TCN, 2023 design + calendar0.1830.168–0.2031.04
TCN + calendar0.2250.216–0.2340.62
GRU + calendar0.1690.167–0.1720.17

Figure 2 shows the result. Copying the last day of the same type scores 0.224, on its expected value; no copy of a single day can do much better. The report's TCN with its calendar input scores 0.183, below anything copying can reach, so it has learned the profile rather than repeating a day, though it stays 14% above the floor. Its holidays are better than without the calendar (1.04 against 2.67) but far from right. Our direct head does worse here, 0.225. The GRU comes closest to the floor, 0.169, and gets holidays right too (0.17). Without a calendar every trained model misses the holidays, since nothing in the past says one is coming. That is the report's own conclusion, and it holds.

The report also claimed something subtler: that a network with no calendar can infer weekends by counting. After five workdays comes a weekend; after two weekend days comes a workday. Figure 3 tests it by cutting the history the TCN sees. With 24 hours it gets Mondays and Saturdays wrong. With 48 or 72 hours it fixes Mondays, since it can see the weekend that just ended, but still calls every Saturday a workday, because two or three workdays look the same whether tomorrow is Friday or Saturday. With 120 hours Saturdays are mostly fixed, and with 168 every day of the week is close to the floor (Mondays, at 0.39, are the worst). That is what the report described: the model "can correctly account for weekends if it knows how many weekdays have just occurred. Otherwise, it assumes the next day is a weekday." Saturday after three days of history is the "otherwise". With a calendar input the counting is unnecessary, and history length stops mattering.

FIG. 3 — COUNTING THE WEEK
0 0.5 1 1.5 2 2.5 3 Mon Tue Wed Thu Fri Sat Sun Day being forecast Mean absolute error
24 h of history72 h168 h72 h + calendar
Figure 3. Error of the TCN (no calendar) on the synthetic series by day of the week, when it sees only the last 24, 72 or 168 hours. Holidays and the days after them are left out. With 72 hours it cannot tell Friday from Saturday; given the calendar it doesn't need to. Three seeds each.
Table view
MAE by day of the week
HistoryMonTueWedThuFriSatSun
24 h2.500.310.310.300.302.610.40
72 h0.260.240.250.310.332.590.24
168 h0.390.230.220.200.230.220.21
72 h + calendar0.240.190.200.200.210.240.22

Thirteen real offices

The VTT SCOTT IAQ dataset is a year of indoor-air measurements from 13 rooms at VTT's premises in Northern Finland: 11 office cubicles for two to four people and two 12-person meeting rooms, recorded every minute through 2019, published under CC BY 4.0.1 In the files each room has one CO2 node and two to four motion (PIR) nodes. Its authors used it to forecast 1 to 15 minutes ahead;10 we use it for a day ahead.

We converted the timestamps to Finnish local time and averaged each hour that had at least 30 minutes of readings. Gaps of up to three hours were filled by straight lines; any day with a longer gap in its forecast or the week before it was dropped. Most rooms report from January and all of them by 11 February, where training starts. We trained on hourly windows to 31 August (including the July holiday, when most rooms sit empty), chose models on September, and tested on midnight forecasts from 1 October to 31 December: 780 room-days. One model is trained for all 13 rooms. Public holidays come from the holidays package's Finnish calendar,11 which counts Christmas Eve as a holiday.

Real rooms are much quieter than the synthetic series. At night every room's median sits between 414 and 420 ppm. On a median test workday, CO2 rises about 124 ppm from its lowest to its highest hour, and the median between 10:00 and 16:00 on workdays ranges from 429 ppm in one room to 588 ppm in another. People are also less regular than a sine wave: they arrive late, work from elsewhere, go to meetings. A forecast that holds last week's night-time median all day scores 36.8 ppm on workdays; that is the scale to judge everything else against.

Results

FIG. 4 — TOMORROW'S CO2, 13 ROOMS
10 15 20 25 30 Mean absolute error, ppm CO2 (lower is better) best baseline 17.3 Same hour last week 25.1 Same hour yesterday 23.0 Last day of the same type 18.4 Room profile from training 18.0 Mean of same-type days 17.3 Median of same-type days 17.4 Ridge + calendar 19.7 Linear + calendar, L1 loss 18.1 TCN, 2023 design 16.7 TCN, 2023 design + calendar 16.1 TCN 15.9 TCN + calendar 15.5 GRU + calendar 14.9
Baseline, no trainingLinear modelNeural network
Figure 4. Mean absolute error of each forecast over the 24 hours of the next day, issued at midnight, on 780 room-days from October to December 2019. Whiskers are 95% intervals from resampling whole dates. Neural rows average five training seeds. The vertical line marks the best baseline.
Table view
Day-ahead MAE, VTT SCOTT test set (Oct–Dec 2019)
MethodMAE, ppm95% intervalKind
Same hour last week25.1022.40–27.71baseline
Same hour yesterday23.0320.15–25.94baseline
Last day of the same type18.4016.29–20.51baseline
Room profile from training18.0215.94–20.08baseline
Mean of same-type days17.3215.43–19.02baseline
Median of same-type days17.3915.54–19.21baseline
Ridge + calendar19.6818.32–21.17linear
Linear + calendar, L1 loss18.1316.61–19.81linear
TCN, 2023 design16.6615.08–18.31neural
TCN, 2023 design + calendar16.1314.46–17.82neural
TCN15.9214.15–17.71neural
TCN + calendar15.5113.71–17.40neural
GRU + calendar14.9313.12–16.77neural

Figure 4 has the main result. The simple forecasts fall into two groups. Copying the same hour last week (25.1 ppm) or yesterday (23.0) is poor, because neither knows that tomorrow is a different kind of day. Anything that uses the calendar does much better: the last same-type day scores 18.4, the room's training profile 18.0, and averaging last week's same-type days 17.3 ppm. That last one is the forecast to beat. Ridge regression on the raw week does worse than every calendar-aware one, 19.7 ppm even with the calendar.

Every TCN beats it. The report's own design with its calendar input scores 16.1 ppm, 1.2 better (interval 0.0–2.4). Our direct head scores 15.5, 1.8 ppm better than the baseline (95% interval 0.8–3.0, resampling whole dates) or 10%, and is better in 12 of the 13 rooms. Adding the motion sensors as an input channel changed nothing (15.5), and neither did normalising each window (15.5). Across five training seeds the standard deviation is 0.10–0.18 ppm (0.46 for the report's calendar design, the least stable model here), and repeating a run on the GPU can move it by about 0.1, so differences smaller than that are noise.

FIG. 5 — WHERE THE GAIN IS
Day-ahead MAE in ppm by kind of day
MethodWorkday (467)First workday back (87)Weekend (208)Weekday holiday (44)23–31 Dec workday (50)All (780)
Mean of same-type days21.621.69.35.623.417.3
Ridge + calendar22.924.812.121.621.319.7
TCN, 2023 design20.822.87.519.515.116.7
TCN, 2023 design + calendar20.521.96.314.819.516.1
TCN20.622.15.618.914.815.9
TCN + calendar20.623.15.26.220.715.5
GRU + calendar20.323.14.53.519.714.9
Figure 5. Mean absolute error by kind of test day, room-days in brackets. The workday columns leave out 23–31 December, shown separately: those are working days on the national calendar on which the offices were empty. Neural rows average five seeds.

Figure 5 says where the gain comes from. On ordinary workdays the TCN is 0.9 ppm better than the baseline and the interval (−0.1 to 2.0) includes zero; on weekends it is 4.1 ppm better, nearly halving the error. The baseline copies last week's weekend, sensor wobble and the odd visitor included, while the network has learned that an empty room is flat. On workdays nobody does much better than 20 ppm, about 45% below the flat forecast. Whether a particular person comes in tomorrow is not in last week's data, and no architecture can find it there.

The network or the loss?

One difference between the TCN and ridge regression is not architecture. The networks are trained on absolute error, which aims at the median; ridge minimises squared error, which aims at the mean, and CO2 has spikes that pull the mean around. To separate the two we trained a plain linear model, the same map from 168 hours to 24 that ridge learns, with the networks' loss, optimiser and early stopping. It scores 18.1 ppm with the calendar, against 19.5 ppm for the same linear model on squared error. Conversely the TCN trained on squared error scores 16.4 instead of 15.5. So the loss is worth about a point either way, and with the same loss the TCN still beats the linear model by 2.6 ppm. The convolutions are doing real work.

The calendar input

The report found that adding a workday variable "had the effect of decreasing the accuracy of the non-holiday predictions". We see a version of that, and a reason. Without the calendar, the TCN's error on weekday holidays is 18.9 ppm: it forecasts an ordinary working day. With it, 6.2 ppm. Figure 6 shows the week of Finnish Independence Day, a Friday. The report's own way of adding the calendar, one flag per forecast hour at the very last layer, does much less: 19.5 to 14.8 ppm, an interval that includes no change. The report called its holiday forecasts "improved, yet imperfect", and that reproduces.

FIG. 6 — INDEPENDENCE DAY
350 400 450 500 550 Mon 02 Tue 03 Wed 04 Thu 05 Fri 06 Sat 07 Sun 08 CO2, ppm
ObservedMean of same-type daysTCNTCN + calendar
Figure 6. One two-person office in the week of Finnish Independence Day, Friday 6 December. Each line segment is one midnight forecast of the next 24 hours; forecasts shown are a baseline and the TCN without and with the calendar input.

On first workdays back after a weekend or holiday, though, the calendar version was 2.9 ppm worse (interval 0.3 to 6.0). Four-fifths of that came from 27 and 30 December. Both are working days on the Finnish calendar, and on both the offices stayed empty: average CO2 was 420 and 399 ppm. The model with the calendar believed it and forecast a working day; the model without it saw a week of quiet and forecast more quiet (Figure 7). Leave out 23–31 December and the calendar costs nothing on ordinary workdays (+0.1 ppm, interval −0.3 to +0.5) and about 1 ppm on the remaining first days back (interval 0.1 to 2.0), a small cost we can't explain. On the calendar "workdays" of that week it costs 5.9 ppm.

FIG. 7 — BETWEEN THE YEARS
350 400 450 500 550 Mon 23 Tue 24 Wed 25 Thu 26 Fri 27 Sat 28 Sun 29 Mon 30 Tue 31 CO2, ppm
ObservedMean of same-type daysTCNTCN + calendar
Figure 7. The same office over Christmas. 24–26 December are public holidays; 23, 27, 30 and 31 December are working days on the national calendar, but the office stayed empty.

So H2 mostly holds, with a condition. The network does what the calendar says, so the calendar has to say what the building will do. A national holiday list is not a site calendar: the week between Christmas and New Year, bridge days, company shutdowns and the summer holiday all need to be in it.

How much history

On the real rooms, with the calendar, cutting the history from 168 hours to 72 or 120 costs only 0.2–0.3 ppm, within the noise. Cutting to 24 or 48 hours costs 1.3–1.4 ppm (Figure 8). Tomorrow depends on the last few days, not on last Tuesday. That fits the synthetic result: once the calendar is given, the long receptive field is no longer needed to work out what kind of day is next, only to estimate the room's level.

FIG. 8 — HOW MUCH HISTORY
14 15 16 17 18 19 24 h 48 h 72 h 120 h 168 h Hours of history MAE, ppm best baseline 17.3 TCN + calendar
Figure 8. Day-ahead error of the TCN with the calendar input when it reads only the last 24 to 168 hours. Band: 95% interval of the error level, resampling dates. Most of that width is day-to-day difficulty shared by every length; paired on the same days, 72 and 120 hours are within 0.3 ppm of 168 and 24 hours is 1.3 ppm worse (interval 0.6–2.0). Five seeds each.
Table view
MAE by history length
HistoryMAE, ppm95% interval
24 h16.8414.61–19.02
48 h17.0314.87–19.40
72 h15.8913.98–17.89
120 h15.8013.86–17.76
168 h15.5813.78–17.44

Levels it has never seen

The report's TCN failed on a series whose level drifted outside anything in training. The standard fix is to normalise each window by its own statistics and undo it on the output, as RevIN does.12 We use the simplest form: subtract the input week's mean and add it back to the forecast. We tested it on synthetic series whose level wandered between 0 and 10 in training. For the test half-year, one series stayed in that range and the other moved to 15–25 (Figure 9).

FIG. 9 — LEVELS IT HAS NEVER SEEN
MAE on synthetic series with a drifting level
MethodFamiliar level (0–10)Unseen level (15–25)
Last day of the same type0.440.63
Ridge + calendar0.370.90
Ridge + calendar, window norm0.380.53
TCN + calendar0.313.57
TCN + calendar, window norm0.280.46
Figure 9. Synthetic series with a slowly wandering level, 0–10 in training. In the test half-year one series stays in that range and one moves to 15–25. Window norm subtracts each input week's mean and adds it back to the forecast. Three seeds.

Scaled with fixed training statistics, the TCN does well on the familiar series (0.31) and is by far the worst on the unseen one, 3.6 against 0.6 for copying a same-type day: the report's failure, reproduced. Subtracting each window's mean brings it to 0.46, the best on that series, and to 0.28 on the familiar one. On the real rooms the same change made no difference (15.5 against 15.5 ppm), because October to December sat at the same levels as training. H3 holds, and since the fix costs nothing when levels are stable, we would always use it.

The recurrent network

The report motivated the TCN by saying recurrent networks suffer from vanishing gradients, which "restricts the length of seasonality that the models can capture". That is the problem gated recurrent units were designed to solve: the LSTM was built so error could flow across long gaps without vanishing,13 and the GRU's gates serve the same purpose.14 Bai and colleagues did find TCNs ahead of LSTMs and GRUs on most of their benchmarks, though not all, and none of them was forecasting.5

On our data a single GRU layer with 64 units, reading the same 168 hours and the same calendar, scores 14.9 ppm: 0.6 ppm better than the TCN (interval 0.3–0.9), better than the baseline in all 13 rooms, and no worse on any kind of day, holidays most of all (3.5 against 6.2 ppm). It has a quarter of the parameters, 33,688 against 125,560, and trains in about the same time. H5 fails on this data.

Verdict

FIG. 10 — THE 2023 HYPOTHESES
What held up
HypothesisVerdictEvidence
H1 · beats simple forecasts and a linear modelYesDirect head 15.5 vs 17.3 ppm (best baseline); the 2023 design 16.1; linear with the same loss 18.1
H2 · a calendar fixes holidays at no costMostly, if the calendar is rightHolidays 18.9 → 6.2 ppm; ordinary workdays +0.1; other first days back +1.0; 23–31 Dec calendar workdays +5.9
H3 · window norm fixes unseen levelsYes (synthetic)Unseen level 3.57 → 0.46; no effect on the real rooms
H4 · a week beats 1–3 daysBeats 1–2 days; 3 days tiesWith the calendar, vs 168 h: 24 h +1.3, 48 h +1.4, 72 h +0.3 (interval includes 0). Without one (synthetic only), Saturdays need 5 days
H5 · beats a recurrent networkNoGRU 14.9 ppm, 0.6 better (interval 0.3–0.9); also closest to the synthetic noise floor
Figure 10. The report's hypotheses against the evidence in this note.

Figure 10 sums up. The 2023 idea was sound. A dilated causal CNN does learn a week of office rhythm with a few layers: on the clean series it beats anything that copies the past, and on real rooms it beats every forecast that needs no training. Two of its claims didn't survive: that it needs only 16 weights, and that it beats recurrent networks. The real limit is not the architecture but what's in the data. Most of the remaining error on working days is whether people turn up, and the biggest single failure was a calendar that didn't match the building.

What we do with this

For the day-ahead ventilation schedule, YS·FLOOR now works to four rules:

  1. Start with the same-type-day mean. It needs no training, takes a few lines to write, and set a bar that ridge regression failed to clear. Publish every model's score against it.
  2. Feed the site calendar, not the national one. Bridge days, shutdowns and the week between Christmas and New Year belong in the input. A model follows its calendar, wrong or not.
  3. Use a small network if the gain is worth it to you. Here it is 10–14%, nearly all on empty days, which is where ventilation is wasted. Try a GRU alongside the TCN; on this data it won.
  4. Train on absolute error if you score on it, and normalise each window. The loss was worth about a point here, as much as a change of architecture; window normalisation cost nothing on these rooms and rescued the synthetic test, so it is cheap insurance.

Where this started

This note grew out of a 2023 internal report by one of us, "Time Series Forecasting Using 1D CNN". It set out the dilation argument well, built the model in Keras, and found three things we reproduced: the network infers weekends from what it has seen, it misses holidays without a calendar, and it fails on levels outside training. It borrowed most of its diagrams from a Unit8 blog post,15 and it scored its forecasts without anything to compare the scores with. Our runs use its architecture as "TCN, 2023 design". The one result we could not reproduce is its loss of detail on ordinary days after adding the workday variable. With its head rebuilt as its diagram draws it, the calendar improved ordinary days on the synthetic series (0.17 against 0.22) and made no difference on the real rooms. We don't have its code or training settings, so we can't say where the loss came from.

Limits of this note

  • One building, one year, 13 rooms in Northern Finland. Rooms with different occupancy (labs, cleanrooms, classrooms) may favour a different model. Three months of test data contain four weekday holidays, so the holiday results rest on 44 room-days.
  • Rooms contribute between 31 and 92 test days, depending on their gaps, so the pooled scores lean towards the best-covered rooms; the per-room comparison (12 and 13 of 13) is the check on that. The "best baseline" was picked on the test set; the mean and median of same-type days differ by 0.07 ppm, so the choice doesn't matter.
  • The rooms share a building, holidays and weather, so we resample whole dates for every interval. That is more honest than resampling room-days but still treats dates as independent.
  • We tuned little: one width and depth per network, and fixed learning rate and dropout. A tuned TCN might close the gap to the GRU, and a tuned GRU might widen it. We didn't try transformers or pretrained forecasting models.
  • Models are trained on windows starting every third hour rather than every hour. We checked: training on every hour scored 16.2 ppm against 15.6, no better.
  • The synthetic series is our reconstruction of the 2023 report's description, not its code or data.
  • No model saw outdoor temperature, room bookings or anything else that knows who is coming. Those would likely help more than any change of architecture, and we haven't tested them.

References

  1. P. Räsänen, J. Koivusaari, J. Kallio, J. Rehu, J. Ronkainen, J. Tervonen, J. Peltola. VTT SCOTT IAQ Dataset (v01). Zenodo, 2020. CC BY 4.0. doi:10.5281/zenodo.3774723.
  2. ASHRAE. ASHRAE Position Document on Indoor Carbon Dioxide. Approved 12 February 2025 (© 2022, 2025), pp. 2, 7. ashrae.org/about/position-documents.
  3. A. Persily, L. de Jonge. "Carbon dioxide generation rates for building occupants." Indoor Air 27(5):868–879, 2017. doi:10.1111/ina.12383.
  4. A. van den Oord et al. "WaveNet: A Generative Model for Raw Audio." arXiv preprint, 2016. arXiv:1609.03499.
  5. S. Bai, J. Z. Kolter, V. Koltun. "An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling." arXiv preprint, 2018, §3. arXiv:1803.01271.
  6. A. Borovykh, S. Bohte, C. W. Oosterlee. "Conditional Time Series Forecasting with Convolutional Neural Networks." arXiv preprint, 2017 (v5, 2018). arXiv:1703.04691.
  7. R. J. Hyndman, G. Athanasopoulos. Forecasting: Principles and Practice, 3rd ed., OTexts, 2021, §5.2. otexts.com/fpp3. Accessed 2026-10-17.
  8. S. Makridakis, E. Spiliotis, V. Assimakopoulos. "Statistical and Machine Learning forecasting methods: Concerns and ways forward." PLOS ONE 13(3):e0194889, 2018. doi:10.1371/journal.pone.0194889.
  9. A. Zeng, M. Chen, L. Zhang, Q. Xu. "Are Transformers Effective for Time Series Forecasting?" Proc. AAAI 37(9):11121–11128, 2023. doi:10.1609/aaai.v37i9.26317.
  10. J. Kallio, J. Tervonen, P. Räsänen, R. Mäkynen, J. Koivusaari, J. Peltola. "Forecasting office indoor CO2 concentration using machine learning with a one-year dataset." Building and Environment 187:107409, 2021. doi:10.1016/j.buildenv.2020.107409.
  11. Vacanza team and contributors. holidays, version 0.106, MIT licence. github.com/vacanza/holidays.
  12. T. Kim, J. Kim, Y. Tae, C. Park, J.-H. Choi, J. Choo. "Reversible Instance Normalization for Accurate Time-Series Forecasting against Distribution Shift." ICLR 2022. openreview.net/forum?id=cGDAkQo1C0p.
  13. S. Hochreiter, J. Schmidhuber. "Long Short-Term Memory." Neural Computation 9(8):1735–1780, 1997. doi:10.1162/neco.1997.9.8.1735.
  14. J. Chung, C. Gulcehre, K. Cho, Y. Bengio. "Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling." NIPS 2014 Deep Learning Workshop. arXiv:1412.3555. The gated unit is from K. Cho et al., EMNLP 2014, doi:10.3115/v1/D14-1179.
  15. F. Lässig. "Temporal Convolutional Networks and Forecasting." Unit8 blog, 6 July 2021. unit8.com.

Reproduce

Data: the VTT SCOTT IAQ dataset, CC BY 4.0.1 The 140 MB archive reduces to a 600 kB file of hourly CO2 and motion per room, which we ship, so you can skip the download. That file is our reduction of VTT's data (hourly means, local time), redistributed under the same CC BY 4.0 licence. You need Python 3.10+, NumPy, pandas, PyTorch and holidays. On a GTX 1060 every experiment runs in about two hours; a CPU works but takes several times longer. GPU convolutions are not bit-for-bit repeatable, so expect differences of about 0.1 ppm.

shell
bash code/ys-en-0006/run_all.sh                        # everything below, in order
python code/ys-en-0006/prep_vtt.py VTT_SCOTT_IAQ_dataset.zip results/vtt_hourly.csv.gz
python code/ys-en-0006/exp_synth.py main               # also: hist, trend
python code/ys-en-0006/exp_vtt.py main                 # also: hist, loss, check
python code/ys-en-0006/analyse.py results/vtt_main.npz sametype_mean
python code/ys-en-0006/check_rf.py                     # Equation 1, parameter counts
python code/ys-en-0006/build_figures.py                # rebuild the figures in this page

Changelog

  • Rev 1. First publication.