PVNet 4.1.7__tar.gz → 4.1.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {pvnet-4.1.7 → pvnet-4.1.8}/PKG-INFO +1 -1
  2. {pvnet-4.1.7 → pvnet-4.1.8}/PVNet.egg-info/PKG-INFO +1 -1
  3. pvnet-4.1.8/pvnet/__init__.py +2 -0
  4. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/multimodal.py +28 -12
  5. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/unimodal_teacher.py +31 -12
  6. pvnet-4.1.7/pvnet/__init__.py +0 -2
  7. {pvnet-4.1.7 → pvnet-4.1.8}/LICENSE +0 -0
  8. {pvnet-4.1.7 → pvnet-4.1.8}/MANIFEST.in +0 -0
  9. {pvnet-4.1.7 → pvnet-4.1.8}/PVNet.egg-info/SOURCES.txt +0 -0
  10. {pvnet-4.1.7 → pvnet-4.1.8}/PVNet.egg-info/dependency_links.txt +0 -0
  11. {pvnet-4.1.7 → pvnet-4.1.8}/PVNet.egg-info/requires.txt +0 -0
  12. {pvnet-4.1.7 → pvnet-4.1.8}/PVNet.egg-info/top_level.txt +0 -0
  13. {pvnet-4.1.7 → pvnet-4.1.8}/README.md +0 -0
  14. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/callbacks.py +0 -0
  15. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/data/__init__.py +0 -0
  16. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/data/base_datamodule.py +0 -0
  17. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/data/site_datamodule.py +0 -0
  18. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/data/uk_regional_datamodule.py +0 -0
  19. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/load_model.py +0 -0
  20. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/__init__.py +0 -0
  21. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/base_model.py +0 -0
  22. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/baseline/__init__.py +0 -0
  23. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/baseline/last_value.py +0 -0
  24. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/baseline/single_value.py +0 -0
  25. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/ensemble.py +0 -0
  26. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/model_cards/pv_india_model_card_template.md +0 -0
  27. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/model_cards/pv_uk_regional_model_card_template.md +0 -0
  28. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/model_cards/wind_india_model_card_template.md +0 -0
  29. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/__init__.py +0 -0
  30. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/basic_blocks.py +0 -0
  31. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/encoders/__init__.py +0 -0
  32. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/encoders/basic_blocks.py +0 -0
  33. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/encoders/encoders2d.py +0 -0
  34. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/encoders/encoders3d.py +0 -0
  35. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/encoders/encodersRNN.py +0 -0
  36. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/linear_networks/__init__.py +0 -0
  37. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/linear_networks/basic_blocks.py +0 -0
  38. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/linear_networks/networks.py +0 -0
  39. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/multimodal_base.py +0 -0
  40. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/site_encoders/__init__.py +0 -0
  41. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/site_encoders/basic_blocks.py +0 -0
  42. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/multimodal/site_encoders/encoders.py +0 -0
  43. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/models/utils.py +0 -0
  44. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/optimizers.py +0 -0
  45. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/training.py +0 -0
  46. {pvnet-4.1.7 → pvnet-4.1.8}/pvnet/utils.py +0 -0
  47. {pvnet-4.1.7 → pvnet-4.1.8}/pyproject.toml +0 -0
  48. {pvnet-4.1.7 → pvnet-4.1.8}/setup.cfg +0 -0
  49. {pvnet-4.1.7 → pvnet-4.1.8}/tests/test_end2end.py +0 -0
  50. {pvnet-4.1.7 → pvnet-4.1.8}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PVNet
3
- Version: 4.1.7
3
+ Version: 4.1.8
4
4
  Summary: PVNet
5
5
  Author-email: Peter Dudfield <info@openclimatefix.org>
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PVNet
3
- Version: 4.1.7
3
+ Version: 4.1.8
4
4
  Summary: PVNet
5
5
  Author-email: Peter Dudfield <info@openclimatefix.org>
6
6
  Description-Content-Type: text/markdown
@@ -0,0 +1,2 @@
1
+ """PVNet"""
2
+ __version__ = "4.1.8"
@@ -1,7 +1,7 @@
1
1
  """The default composite model architecture for PVNet"""
2
2
 
3
3
  from collections import OrderedDict
4
- from typing import Optional
4
+ from typing import Any, Optional
5
5
 
6
6
  import torch
7
7
  from omegaconf import DictConfig
@@ -47,6 +47,7 @@ class Model(MultimodalBaseModel):
47
47
  include_gsp_yield_history: bool = True,
48
48
  include_sun: bool = True,
49
49
  include_time: bool = False,
50
+ location_id_mapping: Optional[dict[Any, int]] = None,
50
51
  embedding_dim: Optional[int] = 16,
51
52
  forecast_minutes: int = 30,
52
53
  history_minutes: int = 60,
@@ -64,7 +65,6 @@ class Model(MultimodalBaseModel):
64
65
  pv_interval_minutes: int = 5,
65
66
  sat_interval_minutes: int = 5,
66
67
  sensor_interval_minutes: int = 30,
67
- num_embeddings: Optional[int] = 318,
68
68
  timestep_intervals_to_plot: Optional[list[int]] = None,
69
69
  adapt_batches: Optional[bool] = False,
70
70
  forecast_minutes_ignore: Optional[int] = 0,
@@ -94,8 +94,9 @@ class Model(MultimodalBaseModel):
94
94
  include_gsp_yield_history: Include GSP yield data.
95
95
  include_sun: Include sun azimuth and altitude data.
96
96
  include_time: Include sine and cosine of dates and times.
97
- embedding_dim: Number of embedding dimensions to use for GSP ID. Not included if set to
98
- `None`.
97
+ location_id_mapping: A dictionary mapping the location ID to an integer. ID embedding is
98
+ not used if this is not provided.
99
+ embedding_dim: Number of embedding dimensions to use for GSP ID.
99
100
  forecast_minutes: The amount of minutes that should be forecasted.
100
101
  history_minutes: The default amount of historical minutes that are used.
101
102
  sat_history_minutes: Length of recent observations used for satellite inputs. Defaults
@@ -116,7 +117,6 @@ class Model(MultimodalBaseModel):
116
117
  pv_interval_minutes: The interval between each sample of the PV data
117
118
  sat_interval_minutes: The interval between each sample of the satellite data
118
119
  sensor_interval_minutes: The interval between each sample of the sensor data
119
- num_embeddings: The number of dimensions to use for the image embedding
120
120
  timestep_intervals_to_plot: Intervals, in timesteps, to plot in
121
121
  addition to the full forecast
122
122
  sensor_encoder: Encoder for sensor data
@@ -136,12 +136,24 @@ class Model(MultimodalBaseModel):
136
136
  self.include_sun = include_sun
137
137
  self.include_time = include_time
138
138
  self.include_sensor = sensor_encoder is not None
139
+ self.location_id_mapping = location_id_mapping
139
140
  self.embedding_dim = embedding_dim
140
141
  self.add_image_embedding_channel = add_image_embedding_channel
141
142
  self.interval_minutes = interval_minutes
142
143
  self.min_sat_delay_minutes = min_sat_delay_minutes
143
144
  self.adapt_batches = adapt_batches
144
145
 
146
+ if location_id_mapping is None and add_image_embedding_channel:
147
+ raise ValueError(
148
+ "If `add_image_embedding_channel` is set to True, `location_id_mapping` must be "
149
+ "provided."
150
+ )
151
+
152
+ self.use_id_embedding = location_id_mapping is not None
153
+
154
+ if self.use_id_embedding:
155
+ num_embeddings = max(location_id_mapping.values())
156
+
145
157
  super().__init__(
146
158
  history_minutes=history_minutes,
147
159
  forecast_minutes=forecast_minutes,
@@ -246,7 +258,7 @@ class Model(MultimodalBaseModel):
246
258
  # Update num features
247
259
  fusion_input_features += self.sensor_encoder.out_features
248
260
 
249
- if self.embedding_dim:
261
+ if self.use_id_embedding:
250
262
  self.embed = nn.Embedding(num_embeddings=num_embeddings, embedding_dim=embedding_dim)
251
263
 
252
264
  # Update num features
@@ -289,6 +301,14 @@ class Model(MultimodalBaseModel):
289
301
  if self.adapt_batches:
290
302
  x = self._adapt_batch(x)
291
303
 
304
+ if self.use_id_embedding:
305
+ # eg: x['gsp_id] = [1] with location_id_mapping = {1:0}, would give [0]
306
+ id = torch.tensor(
307
+ [self.location_id_mapping[i.item()] for i in x[f"{self._target_key}_id"]],
308
+ device=self.device,
309
+ dtype=torch.int64,
310
+ )
311
+
292
312
  modes = OrderedDict()
293
313
  # ******************* Satellite imagery *************************
294
314
  if self.include_sat:
@@ -297,7 +317,6 @@ class Model(MultimodalBaseModel):
297
317
  sat_data = torch.swapaxes(sat_data, 1, 2).float() # switch time and channels
298
318
 
299
319
  if self.add_image_embedding_channel:
300
- id = x[f"{self._target_key}_id"].int()
301
320
  sat_data = self.sat_embed(sat_data, id)
302
321
  modes["sat"] = self.sat_encoder(sat_data)
303
322
 
@@ -313,7 +332,6 @@ class Model(MultimodalBaseModel):
313
332
  nwp_data = torch.clip(nwp_data, min=-50, max=50)
314
333
 
315
334
  if self.add_image_embedding_channel:
316
- id = x[f"{self._target_key}_id"].int()
317
335
  nwp_data = self.nwp_embed_dict[nwp_source](nwp_data, id)
318
336
 
319
337
  nwp_out = self.nwp_encoders_dict[nwp_source](nwp_data)
@@ -339,10 +357,8 @@ class Model(MultimodalBaseModel):
339
357
  modes["gsp"] = gsp_history
340
358
 
341
359
  # ********************** Embedding of GSP/Site ID ********************
342
- if self.embedding_dim:
343
- id = x[f"{self._target_key}_id"].int()
344
- id_embedding = self.embed(id)
345
- modes["id"] = id_embedding
360
+ if self.use_id_embedding:
361
+ modes["id"] = self.embed(id)
346
362
 
347
363
  if self.include_sun:
348
364
  # Use only new direct keys
@@ -2,7 +2,7 @@
2
2
 
3
3
  import glob
4
4
  from collections import OrderedDict
5
- from typing import Optional
5
+ from typing import Any, Optional
6
6
 
7
7
  import hydra
8
8
  import torch
@@ -44,6 +44,7 @@ class Model(MultimodalBaseModel):
44
44
  output_quantiles: Optional[list[float]] = None,
45
45
  include_gsp_yield_history: bool = True,
46
46
  include_sun: bool = True,
47
+ location_id_mapping: Optional[dict[Any, int]] = None,
47
48
  embedding_dim: Optional[int] = 16,
48
49
  forecast_minutes: int = 30,
49
50
  history_minutes: int = 60,
@@ -74,8 +75,9 @@ class Model(MultimodalBaseModel):
74
75
  None the output is a single value.
75
76
  include_gsp_yield_history: Include GSP yield data.
76
77
  include_sun: Include sun azimuth and altitude data.
77
- embedding_dim: Number of embedding dimensions to use for GSP ID. Not included if set to
78
- `None`.
78
+ location_id_mapping: A dictionary mapping the location ID to an integer. ID embedding is
79
+ not used if this is not provided.
80
+ embedding_dim: Number of embedding dimensions to use for GSP ID
79
81
  forecast_minutes: The amount of minutes that should be forecasted.
80
82
  history_minutes: The default amount of historical minutes that are used.
81
83
  optimizer: Optimizer factory function used for network.
@@ -93,6 +95,7 @@ class Model(MultimodalBaseModel):
93
95
 
94
96
  self.include_gsp_yield_history = include_gsp_yield_history
95
97
  self.include_sun = include_sun
98
+ self.location_id_mapping = location_id_mapping
96
99
  self.embedding_dim = embedding_dim
97
100
  self.enc_loss_frac = enc_loss_frac
98
101
  self.include_sat = False
@@ -100,6 +103,11 @@ class Model(MultimodalBaseModel):
100
103
  self.include_pv = False
101
104
  self.adapt_batches = adapt_batches
102
105
 
106
+ self.use_id_embedding = location_id_mapping is not None
107
+
108
+ if self.use_id_embedding:
109
+ num_embeddings = max(location_id_mapping.values())
110
+
103
111
  # This is set but modified later based on the teachers
104
112
  self.add_image_embedding_channel = False
105
113
 
@@ -167,7 +175,7 @@ class Model(MultimodalBaseModel):
167
175
  fusion_input_features += self.nwp_encoders_dict[nwp_source].out_features
168
176
 
169
177
  if self.embedding_dim:
170
- self.embed = nn.Embedding(num_embeddings=318, embedding_dim=embedding_dim)
178
+ self.embed = nn.Embedding(num_embeddings=num_embeddings, embedding_dim=embedding_dim)
171
179
  fusion_input_features += embedding_dim
172
180
 
173
181
  if self.include_sun:
@@ -209,6 +217,15 @@ class Model(MultimodalBaseModel):
209
217
 
210
218
  def teacher_forward(self, x):
211
219
  """Run the teacher models and return their encodings"""
220
+
221
+ if self.use_id_embedding:
222
+ # eg: x['gsp_id] = [1] with location_id_mapping = {1:0}, would give [0]
223
+ id = torch.tensor(
224
+ [self.location_id_mapping[i.item()] for i in x[f"{self._target_key}_id"]],
225
+ device=self.device,
226
+ dtype=torch.int64,
227
+ )
228
+
212
229
  modes = OrderedDict()
213
230
  for mode, teacher_model in self.teacher_models.items():
214
231
  # ******************* Satellite imagery *************************
@@ -218,7 +235,6 @@ class Model(MultimodalBaseModel):
218
235
  sat_data = torch.swapaxes(sat_data, 1, 2).float() # switch time and channels
219
236
 
220
237
  if self.add_image_embedding_channel:
221
- id = x["gsp_id"].int()
222
238
  sat_data = teacher_model.sat_embed(sat_data, id)
223
239
 
224
240
  modes[mode] = teacher_model.sat_encoder(sat_data)
@@ -232,7 +248,6 @@ class Model(MultimodalBaseModel):
232
248
  nwp_data = torch.swapaxes(nwp_data, 1, 2) # switch time and channels
233
249
  nwp_data = torch.clip(nwp_data, min=-50, max=50)
234
250
  if teacher_model.add_image_embedding_channel:
235
- id = x["gsp_id"].int()
236
251
  nwp_data = teacher_model.nwp_embed_dict[nwp_source](nwp_data, id)
237
252
 
238
253
  nwp_out = teacher_model.nwp_encoders_dict[nwp_source](nwp_data)
@@ -251,6 +266,14 @@ class Model(MultimodalBaseModel):
251
266
  if self.adapt_batches:
252
267
  x = self._adapt_batch(x)
253
268
 
269
+ if self.use_id_embedding:
270
+ # eg: x['gsp_id] = [1] with location_id_mapping = {1:0}, would give [0]
271
+ id = torch.tensor(
272
+ [self.location_id_mapping[i.item()] for i in x[f"{self._target_key}_id"]],
273
+ device=self.device,
274
+ dtype=torch.int64,
275
+ )
276
+
254
277
  modes = OrderedDict()
255
278
  # ******************* Satellite imagery *************************
256
279
  if self.include_sat:
@@ -259,7 +282,6 @@ class Model(MultimodalBaseModel):
259
282
  sat_data = torch.swapaxes(sat_data, 1, 2).float() # switch time and channels
260
283
 
261
284
  if self.add_image_embedding_channel:
262
- id = x["gsp_id"].int()
263
285
  sat_data = self.sat_embed(sat_data, id)
264
286
  modes["sat"] = self.sat_encoder(sat_data)
265
287
 
@@ -275,7 +297,6 @@ class Model(MultimodalBaseModel):
275
297
  nwp_data = torch.clip(nwp_data, min=-50, max=50)
276
298
 
277
299
  if self.add_image_embedding_channel:
278
- id = x["gsp_id"].int()
279
300
  nwp_data = self.nwp_embed_dict[nwp_source](nwp_data, id)
280
301
 
281
302
  nwp_out = self.nwp_encoders_dict[nwp_source](nwp_data)
@@ -299,10 +320,8 @@ class Model(MultimodalBaseModel):
299
320
  modes["gsp"] = gsp_history
300
321
 
301
322
  # ********************** Embedding of GSP ID ********************
302
- if self.embedding_dim:
303
- id = x["gsp_id"].int()
304
- id_embedding = self.embed(id)
305
- modes["id"] = id_embedding
323
+ if self.use_id_embedding:
324
+ modes["id"] = self.embed(id)
306
325
 
307
326
  if self.include_sun:
308
327
  # Use only new direct keys
@@ -1,2 +0,0 @@
1
- """PVNet"""
2
- __version__ = "4.1.7"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes