deepsensor 0.1.2__tar.gz → 0.1.3__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.
- {deepsensor-0.1.2 → deepsensor-0.1.3}/PKG-INFO +1 -1
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor.egg-info/PKG-INFO +1 -1
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor.egg-info/SOURCES.txt +0 -5
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor.egg-info/requires.txt +1 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/pyproject.toml +0 -4
- {deepsensor-0.1.2 → deepsensor-0.1.3}/setup.cfg +2 -1
- deepsensor-0.1.2/LICENSE +0 -21
- deepsensor-0.1.2/deepsensor/_version.py +0 -12
- deepsensor-0.1.2/deepsensor/active_learning/acquisition_fns.py +0 -220
- deepsensor-0.1.2/deepsensor/utils.py +0 -0
- deepsensor-0.1.2/tests/__init__.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/README.md +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/__init__.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/config.py +0 -0
- {deepsensor-0.1.2/deepsensor/active_learning → deepsensor-0.1.3/deepsensor/data}/__init__.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/data/loader.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/data/processor.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/data/task.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/data/utils.py +0 -0
- {deepsensor-0.1.2/deepsensor/data → deepsensor-0.1.3/deepsensor/model}/__init__.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/model/defaults.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/model/models.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/model/nps.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/plot.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/py.typed +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/tensorflow/__init__.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/torch/__init__.py +0 -0
- {deepsensor-0.1.2/deepsensor/model → deepsensor-0.1.3/deepsensor/train}/__init__.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor/train/train.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor.egg-info/dependency_links.txt +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor.egg-info/not-zip-safe +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/deepsensor.egg-info/top_level.txt +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/setup.py +0 -0
- {deepsensor-0.1.2/deepsensor/train → deepsensor-0.1.3/tests}/__init__.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/tests/test_data_processor.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/tests/test_model.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/tests/test_task_loader.py +0 -0
- {deepsensor-0.1.2 → deepsensor-0.1.3}/tests/utils.py +0 -0
|
@@ -1,22 +1,17 @@
|
|
|
1
|
-
LICENSE
|
|
2
1
|
README.md
|
|
3
2
|
pyproject.toml
|
|
4
3
|
setup.cfg
|
|
5
4
|
setup.py
|
|
6
5
|
deepsensor/__init__.py
|
|
7
|
-
deepsensor/_version.py
|
|
8
6
|
deepsensor/config.py
|
|
9
7
|
deepsensor/plot.py
|
|
10
8
|
deepsensor/py.typed
|
|
11
|
-
deepsensor/utils.py
|
|
12
9
|
deepsensor.egg-info/PKG-INFO
|
|
13
10
|
deepsensor.egg-info/SOURCES.txt
|
|
14
11
|
deepsensor.egg-info/dependency_links.txt
|
|
15
12
|
deepsensor.egg-info/not-zip-safe
|
|
16
13
|
deepsensor.egg-info/requires.txt
|
|
17
14
|
deepsensor.egg-info/top_level.txt
|
|
18
|
-
deepsensor/active_learning/__init__.py
|
|
19
|
-
deepsensor/active_learning/acquisition_fns.py
|
|
20
15
|
deepsensor/data/__init__.py
|
|
21
16
|
deepsensor/data/loader.py
|
|
22
17
|
deepsensor/data/processor.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = deepsensor
|
|
3
|
-
version = 0.1.
|
|
3
|
+
version = 0.1.3
|
|
4
4
|
author = Tom R. Andersson
|
|
5
5
|
author_email = tomand@bas.ac.uk
|
|
6
6
|
description = A Python package for modelling xarray and pandas data with neural processes.
|
|
@@ -31,6 +31,7 @@ install_requires =
|
|
|
31
31
|
distributed
|
|
32
32
|
pyshp
|
|
33
33
|
tqdm
|
|
34
|
+
pooch
|
|
34
35
|
|
|
35
36
|
[options.extras_require]
|
|
36
37
|
testing =
|
deepsensor-0.1.2/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 Tom Robin Andersson
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
class GreedySensorSearch:
|
|
2
|
-
"""
|
|
3
|
-
Parent class for a greedy search algorithm that proposes locations for
|
|
4
|
-
new sensor measurements from a starting set of query locations.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
def __init__(
|
|
8
|
-
self,
|
|
9
|
-
tasks,
|
|
10
|
-
N_new_sensors,
|
|
11
|
-
region,
|
|
12
|
-
data_processor_ID,
|
|
13
|
-
reference_grid=None,
|
|
14
|
-
mask_da=None,
|
|
15
|
-
context_set_idx=None,
|
|
16
|
-
target_var=None,
|
|
17
|
-
maxormin="max",
|
|
18
|
-
progressbar=0,
|
|
19
|
-
):
|
|
20
|
-
"""
|
|
21
|
-
Args:
|
|
22
|
-
tasks (dict): Dictionary mapping from dates of observation to
|
|
23
|
-
tasks output by child of `ToySensorData`.
|
|
24
|
-
For each task:
|
|
25
|
-
- The `X_target` entry is treated as the initial search space
|
|
26
|
-
(assumed the same for each task).
|
|
27
|
-
- The `X_context`, `Y_context` entries comprise the context set
|
|
28
|
-
(starting sensor network).
|
|
29
|
-
|
|
30
|
-
N_new_sensors (int): The total number of new sensor locations to propose.
|
|
31
|
-
|
|
32
|
-
reference_grid (xr.DataArray):
|
|
33
|
-
If running search on a grid, contains the grid coordinates
|
|
34
|
-
to search over. Used for instantiating an xr.DataArray storing acquisition
|
|
35
|
-
function values.
|
|
36
|
-
|
|
37
|
-
mask_da (boolean xr.DataArray):
|
|
38
|
-
If running search on a grid, contains the grid coordinates to remove from the
|
|
39
|
-
search (example use case: masking out the ocean for land sensors). Boolean True
|
|
40
|
-
values are interpreted as valid points, and False as invalid points. The mask will
|
|
41
|
-
be interpolated onto the search grid using nearest-neighbour interpolation
|
|
42
|
-
(i.e. the mask and search grid do not need to be the same).
|
|
43
|
-
|
|
44
|
-
maxormin (str): 'max' or 'min' - whether to maximise or minimise the
|
|
45
|
-
acquisition function within each greedy search iteration.
|
|
46
|
-
|
|
47
|
-
progressbar (int): Progress bar verbosity:
|
|
48
|
-
- 0-2: no effect
|
|
49
|
-
- 3: sensor progressbar
|
|
50
|
-
- 4: date progressbar
|
|
51
|
-
- 5: search progressbar
|
|
52
|
-
"""
|
|
53
|
-
self.tasks = tasks
|
|
54
|
-
self.N_new_sensors = N_new_sensors
|
|
55
|
-
self.region = region
|
|
56
|
-
self.data_processor_ID = data_processor_ID
|
|
57
|
-
self.reference_grid = reference_grid
|
|
58
|
-
self.mask_da = mask_da
|
|
59
|
-
self.context_set_idx = context_set_idx
|
|
60
|
-
self.maxormin = maxormin
|
|
61
|
-
self.progressbar = progressbar
|
|
62
|
-
|
|
63
|
-
# TODO use to determine target_set_idx?
|
|
64
|
-
self.target_var = target_var
|
|
65
|
-
|
|
66
|
-
self.dates = list(self.tasks.keys())
|
|
67
|
-
|
|
68
|
-
# Don't edit by reference if running multiple classes with same `tasks` input
|
|
69
|
-
self.tasks = copy.deepcopy(self.tasks)
|
|
70
|
-
|
|
71
|
-
# Uninstrumented locations to search over: initialise as whole search space
|
|
72
|
-
self.X_search_init = self.tasks[self.dates[0]]["X_search"][0].copy()
|
|
73
|
-
if self.X_search_init.ndim == 3:
|
|
74
|
-
self.X_search_init = self.X_search_init[0]
|
|
75
|
-
self.search_size = self.X_search_init.shape[-1]
|
|
76
|
-
self.check_X_search_large_enough()
|
|
77
|
-
|
|
78
|
-
def check_X_search_large_enough(self):
|
|
79
|
-
"""Ensure number of sensors to place is less than the search space size."""
|
|
80
|
-
if self.search_size < self.N_new_sensors:
|
|
81
|
-
raise ValueError(
|
|
82
|
-
f"Initial search size ({self.search_size}) is smaller "
|
|
83
|
-
f"than number of sensors to place ({self.N_new_sensors})."
|
|
84
|
-
)
|
|
85
|
-
elif self.search_size == self.N_new_sensors:
|
|
86
|
-
raise ValueError(
|
|
87
|
-
f"Initial search size ({self.search_size}) is equal to "
|
|
88
|
-
f"the number of sensors to place ({self.N_new_sensors})."
|
|
89
|
-
)
|
|
90
|
-
else:
|
|
91
|
-
print(
|
|
92
|
-
f"Placing {self.N_new_sensors} sensors in search space of {self.search_size}.\n"
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
def acquisition_fn(self, task, x_query, sample_i):
|
|
96
|
-
"""
|
|
97
|
-
Acquisition function for assigning an importance value to a single
|
|
98
|
-
sensor location `x_query`. To be overridden by child classes implementing
|
|
99
|
-
specific acquisition functions for the greedy search.
|
|
100
|
-
|
|
101
|
-
Child class overridden methods should take the form:
|
|
102
|
-
```
|
|
103
|
-
task = self.append_query_obs_to_task(task, x_query, sample_i)
|
|
104
|
-
task = self.sample_task(task, sample_i)
|
|
105
|
-
# Code to compute importance of `x_query...
|
|
106
|
-
return importance
|
|
107
|
-
```
|
|
108
|
-
"""
|
|
109
|
-
raise NotImplementedError()
|
|
110
|
-
|
|
111
|
-
def search(self, X_search):
|
|
112
|
-
"""
|
|
113
|
-
Run one greedy pass by looping over each point in `X_search` and
|
|
114
|
-
computing the acquisition function.
|
|
115
|
-
|
|
116
|
-
If the search algorithm can be run over all points in parallel,
|
|
117
|
-
this method should be overridden by the child class so that `self.run()`
|
|
118
|
-
uses the parallel implementation.
|
|
119
|
-
|
|
120
|
-
TODO check if below is still valid in GreedyOptimal:
|
|
121
|
-
If the search method uses the y-values at search points (i.e. for
|
|
122
|
-
an optimal benchmark), its `acquisition_fn` should expect a y_query input.
|
|
123
|
-
"""
|
|
124
|
-
importances_list = []
|
|
125
|
-
for date, task in tqdm(
|
|
126
|
-
self.tasks.items(),
|
|
127
|
-
desc="Date",
|
|
128
|
-
position=4,
|
|
129
|
-
leave=True,
|
|
130
|
-
disable=self.progressbar < 4,
|
|
131
|
-
):
|
|
132
|
-
for sample_i in range(self.n_samples_or_1):
|
|
133
|
-
# Add size-1 dim after row dim to preserve row dim for passing to
|
|
134
|
-
# acquisition_fn. Also roll final axis to first axis for looping over search points.
|
|
135
|
-
importances = []
|
|
136
|
-
for x_query in tqdm(
|
|
137
|
-
np.rollaxis(X_search[:, np.newaxis], 2),
|
|
138
|
-
desc="Search",
|
|
139
|
-
position=6,
|
|
140
|
-
leave=True,
|
|
141
|
-
disable=self.progressbar < 5,
|
|
142
|
-
):
|
|
143
|
-
importance = self.acquisition_fn(task, x_query, sample_i)
|
|
144
|
-
importances.append(importance)
|
|
145
|
-
|
|
146
|
-
importances = np.array(importances)
|
|
147
|
-
self.store_acquisition_fn_values(
|
|
148
|
-
self.iteration, date, sample_i, importances
|
|
149
|
-
)
|
|
150
|
-
importances_list.append(importances)
|
|
151
|
-
|
|
152
|
-
return np.mean(importances_list, axis=0)
|
|
153
|
-
|
|
154
|
-
def select_best(self, importances, X_search):
|
|
155
|
-
"""Select sensor location corresponding to best importance value.
|
|
156
|
-
|
|
157
|
-
Appends the chosen search index to a list of chosen search indexes.
|
|
158
|
-
"""
|
|
159
|
-
if self.maxormin == "max":
|
|
160
|
-
best_idx = np.argmax(importances)
|
|
161
|
-
elif self.maxormin == "min":
|
|
162
|
-
best_idx = np.argmin(importances)
|
|
163
|
-
|
|
164
|
-
best_x_query = X_search[:, best_idx : best_idx + 1]
|
|
165
|
-
|
|
166
|
-
# Index into original search space of chosen sensor location
|
|
167
|
-
self.best_idxs_all.append(
|
|
168
|
-
np.where((self.X_search_init == best_x_query).all(axis=0))[0][0]
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
return best_x_query
|
|
172
|
-
|
|
173
|
-
def single_greedy_iteration(self):
|
|
174
|
-
"""
|
|
175
|
-
Run a single greedy grid search iteration and append the optimal
|
|
176
|
-
sensor location to self.X_new.
|
|
177
|
-
"""
|
|
178
|
-
importances = self.search(self.X_search)
|
|
179
|
-
best_x_query = self.select_best(importances, self.X_search)
|
|
180
|
-
|
|
181
|
-
# Remove greedily chosen sensor from search space
|
|
182
|
-
# TEMP turning off this so that results always on grid for storing in xarray
|
|
183
|
-
# This means 'waste' predictions over previously placed sensors/risk placing
|
|
184
|
-
# multiple sensors at same location!
|
|
185
|
-
# self.X_search = self.X_search[~(self.X_search == best_x_query).all(axis=1)]
|
|
186
|
-
|
|
187
|
-
self.X_new.append(best_x_query)
|
|
188
|
-
self.iteration += 1
|
|
189
|
-
|
|
190
|
-
def run(self):
|
|
191
|
-
"""
|
|
192
|
-
Iteratively... docstring TODO
|
|
193
|
-
|
|
194
|
-
Returns a tensor of proposed new sensor locations (in greedy iteration/priority order)
|
|
195
|
-
and their corresponding list of indexes in the search space.
|
|
196
|
-
"""
|
|
197
|
-
# Have separate `self.X_search` in case search space changes as placements are made
|
|
198
|
-
# (although this functionality isn't implemented yet)
|
|
199
|
-
self.X_search = self.X_search_init
|
|
200
|
-
self.iteration = 0
|
|
201
|
-
|
|
202
|
-
# List of new proposed sensor locations
|
|
203
|
-
self.X_new = []
|
|
204
|
-
|
|
205
|
-
# List to track indexes into original search grid of chosen sensor locations
|
|
206
|
-
# as optimisation progresses. Used for filling y-values at chosen
|
|
207
|
-
# sensor locations, `self.X_new`
|
|
208
|
-
self.best_idxs_all = []
|
|
209
|
-
|
|
210
|
-
for _ in tqdm(
|
|
211
|
-
range(self.N_new_sensors),
|
|
212
|
-
desc="Placement",
|
|
213
|
-
position=2,
|
|
214
|
-
leave=True,
|
|
215
|
-
disable=self.progressbar < 3,
|
|
216
|
-
):
|
|
217
|
-
self.single_greedy_iteration()
|
|
218
|
-
|
|
219
|
-
X_new = np.concatenate(self.X_new, axis=1)
|
|
220
|
-
return X_new, self.best_idxs_all
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deepsensor-0.1.2/deepsensor/active_learning → deepsensor-0.1.3/deepsensor/data}/__init__.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|