reflectorch 1.3.0__py3-none-any.whl → 1.5.0__py3-none-any.whl
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.
Potentially problematic release.
This version of reflectorch might be problematic. Click here for more details.
- reflectorch/__init__.py +17 -17
- reflectorch/data_generation/__init__.py +128 -126
- reflectorch/data_generation/dataset.py +210 -210
- reflectorch/data_generation/likelihoods.py +80 -80
- reflectorch/data_generation/noise.py +470 -470
- reflectorch/data_generation/priors/__init__.py +60 -60
- reflectorch/data_generation/priors/base.py +55 -55
- reflectorch/data_generation/priors/exp_subprior_sampler.py +298 -298
- reflectorch/data_generation/priors/independent_priors.py +195 -195
- reflectorch/data_generation/priors/multilayer_models.py +311 -311
- reflectorch/data_generation/priors/multilayer_structures.py +104 -104
- reflectorch/data_generation/priors/no_constraints.py +206 -206
- reflectorch/data_generation/priors/parametric_models.py +841 -841
- reflectorch/data_generation/priors/parametric_subpriors.py +369 -369
- reflectorch/data_generation/priors/params.py +252 -252
- reflectorch/data_generation/priors/sampler_strategies.py +369 -369
- reflectorch/data_generation/priors/scaler_mixin.py +65 -65
- reflectorch/data_generation/priors/subprior_sampler.py +371 -371
- reflectorch/data_generation/priors/utils.py +118 -118
- reflectorch/data_generation/process_data.py +41 -41
- reflectorch/data_generation/q_generator.py +280 -246
- reflectorch/data_generation/reflectivity/__init__.py +102 -102
- reflectorch/data_generation/reflectivity/abeles.py +97 -97
- reflectorch/data_generation/reflectivity/kinematical.py +70 -70
- reflectorch/data_generation/reflectivity/memory_eff.py +105 -105
- reflectorch/data_generation/reflectivity/numpy_implementations.py +120 -120
- reflectorch/data_generation/reflectivity/smearing.py +138 -138
- reflectorch/data_generation/reflectivity/smearing_pointwise.py +109 -109
- reflectorch/data_generation/scale_curves.py +112 -112
- reflectorch/data_generation/smearing.py +98 -98
- reflectorch/data_generation/utils.py +223 -222
- reflectorch/extensions/jupyter/__init__.py +11 -6
- reflectorch/extensions/jupyter/api.py +85 -0
- reflectorch/extensions/jupyter/callbacks.py +34 -34
- reflectorch/extensions/jupyter/components.py +758 -0
- reflectorch/extensions/jupyter/custom_select.py +268 -0
- reflectorch/extensions/jupyter/log_widget.py +241 -0
- reflectorch/extensions/jupyter/model_selection.py +495 -0
- reflectorch/extensions/jupyter/plotly_plot_manager.py +329 -0
- reflectorch/extensions/jupyter/widget.py +625 -0
- reflectorch/extensions/matplotlib/__init__.py +5 -5
- reflectorch/extensions/matplotlib/losses.py +32 -32
- reflectorch/extensions/refnx/refnx_conversion.py +76 -76
- reflectorch/inference/__init__.py +28 -24
- reflectorch/inference/inference_model.py +847 -851
- reflectorch/inference/input_interface.py +239 -0
- reflectorch/inference/loading_data.py +37 -0
- reflectorch/inference/multilayer_fitter.py +171 -171
- reflectorch/inference/multilayer_inference_model.py +193 -193
- reflectorch/inference/plotting.py +524 -98
- reflectorch/inference/preprocess_exp/__init__.py +6 -6
- reflectorch/inference/preprocess_exp/attenuation.py +36 -36
- reflectorch/inference/preprocess_exp/cut_with_q_ratio.py +31 -31
- reflectorch/inference/preprocess_exp/footprint.py +81 -81
- reflectorch/inference/preprocess_exp/interpolation.py +19 -16
- reflectorch/inference/preprocess_exp/normalize.py +21 -21
- reflectorch/inference/preprocess_exp/preprocess.py +121 -121
- reflectorch/inference/query_matcher.py +81 -81
- reflectorch/inference/record_time.py +43 -43
- reflectorch/inference/sampler_solution.py +56 -56
- reflectorch/inference/scipy_fitter.py +272 -248
- reflectorch/inference/torch_fitter.py +87 -87
- reflectorch/ml/__init__.py +32 -32
- reflectorch/ml/basic_trainer.py +292 -292
- reflectorch/ml/callbacks.py +80 -80
- reflectorch/ml/dataloaders.py +26 -26
- reflectorch/ml/loggers.py +55 -55
- reflectorch/ml/schedulers.py +355 -355
- reflectorch/ml/trainers.py +200 -191
- reflectorch/ml/utils.py +2 -2
- reflectorch/models/__init__.py +15 -14
- reflectorch/models/activations.py +50 -50
- reflectorch/models/encoders/__init__.py +19 -17
- reflectorch/models/encoders/conv_encoder.py +218 -218
- reflectorch/models/encoders/conv_res_net.py +115 -115
- reflectorch/models/encoders/fno.py +133 -133
- reflectorch/models/encoders/integral_kernel_embedding.py +390 -0
- reflectorch/models/networks/__init__.py +14 -14
- reflectorch/models/networks/mlp_networks.py +434 -428
- reflectorch/models/networks/residual_net.py +156 -156
- reflectorch/paths.py +29 -27
- reflectorch/runs/__init__.py +31 -31
- reflectorch/runs/config.py +25 -25
- reflectorch/runs/slurm_utils.py +93 -93
- reflectorch/runs/train.py +78 -78
- reflectorch/runs/utils.py +404 -401
- reflectorch/test_config.py +4 -4
- reflectorch/train.py +4 -4
- reflectorch/train_on_cluster.py +4 -4
- reflectorch/utils.py +98 -68
- {reflectorch-1.3.0.dist-info → reflectorch-1.5.0.dist-info}/METADATA +129 -125
- reflectorch-1.5.0.dist-info/RECORD +96 -0
- {reflectorch-1.3.0.dist-info → reflectorch-1.5.0.dist-info}/WHEEL +1 -1
- {reflectorch-1.3.0.dist-info → reflectorch-1.5.0.dist-info}/licenses/LICENSE.txt +20 -20
- reflectorch-1.3.0.dist-info/RECORD +0 -86
- {reflectorch-1.3.0.dist-info → reflectorch-1.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,219 +1,219 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
import torch
|
|
5
|
-
from torch import nn, load
|
|
6
|
-
|
|
7
|
-
from reflectorch.models.activations import activation_by_name
|
|
8
|
-
from reflectorch.paths import SAVED_MODELS_DIR
|
|
9
|
-
|
|
10
|
-
__all__ = [
|
|
11
|
-
"ConvEncoder",
|
|
12
|
-
"ConvDecoder",
|
|
13
|
-
"ConvAutoencoder",
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
logger = logging.getLogger(__name__)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class ConvEncoder(nn.Module):
|
|
20
|
-
"""A 1D CNN encoder / embedding network
|
|
21
|
-
|
|
22
|
-
Args:
|
|
23
|
-
in_channels (int, optional): the number of input channels. Defaults to 1.
|
|
24
|
-
hidden_channels (tuple, optional): the number of intermediate channels of each convolutional layer. Defaults to (32, 64, 128, 256, 512).
|
|
25
|
-
dim_embedding (int, optional): the dimension of the output latent embedding. Defaults to 64.
|
|
26
|
-
dim_avpool (int, optional): the output size of the adaptive average pooling layer. Defaults to 1.
|
|
27
|
-
use_batch_norm (bool, optional): whether to use batch normalization. Defaults to True.
|
|
28
|
-
activation (str, optional): the type of activation function. Defaults to 'relu'.
|
|
29
|
-
"""
|
|
30
|
-
def __init__(self,
|
|
31
|
-
in_channels: int = 1,
|
|
32
|
-
hidden_channels: tuple = (32, 64, 128, 256, 512),
|
|
33
|
-
kernel_size: int = 3,
|
|
34
|
-
dim_embedding: int = 64,
|
|
35
|
-
dim_avpool: int = 1,
|
|
36
|
-
use_batch_norm: bool = True,
|
|
37
|
-
use_se: bool = False,
|
|
38
|
-
activation: str = 'relu',
|
|
39
|
-
):
|
|
40
|
-
super().__init__()
|
|
41
|
-
|
|
42
|
-
modules = []
|
|
43
|
-
|
|
44
|
-
activation = activation_by_name(activation)
|
|
45
|
-
|
|
46
|
-
for h in hidden_channels:
|
|
47
|
-
layers = [
|
|
48
|
-
nn.Conv1d(in_channels, out_channels=h, kernel_size=kernel_size, stride=2, padding=kernel_size // 2),
|
|
49
|
-
activation(),
|
|
50
|
-
]
|
|
51
|
-
|
|
52
|
-
if use_batch_norm:
|
|
53
|
-
layers.insert(1, nn.BatchNorm1d(h))
|
|
54
|
-
|
|
55
|
-
if use_se:
|
|
56
|
-
layers.insert(2, SEBlock(h))
|
|
57
|
-
|
|
58
|
-
modules.append(nn.Sequential(*layers))
|
|
59
|
-
in_channels = h
|
|
60
|
-
|
|
61
|
-
self.core = nn.Sequential(*modules)
|
|
62
|
-
self.avpool = nn.AdaptiveAvgPool1d(dim_avpool)
|
|
63
|
-
self.fc = nn.Linear(hidden_channels[-1] * dim_avpool, dim_embedding)
|
|
64
|
-
|
|
65
|
-
def forward(self, x):
|
|
66
|
-
if len(x.shape) < 3:
|
|
67
|
-
x = x.unsqueeze(1)
|
|
68
|
-
x = self.core(x)
|
|
69
|
-
x = self.avpool(x).view(x.size(0), -1)
|
|
70
|
-
x = self.fc(x)
|
|
71
|
-
return x
|
|
72
|
-
|
|
73
|
-
def load_weights(self, path: str or Path = None, strict: bool = False):
|
|
74
|
-
if not path:
|
|
75
|
-
return
|
|
76
|
-
|
|
77
|
-
if isinstance(path, str):
|
|
78
|
-
if not path.endswith('.pt'):
|
|
79
|
-
path = path + '.pt'
|
|
80
|
-
path = SAVED_MODELS_DIR / path
|
|
81
|
-
|
|
82
|
-
if not path.is_file():
|
|
83
|
-
logger.error(f'File {str(path)} is not found.')
|
|
84
|
-
return
|
|
85
|
-
try:
|
|
86
|
-
state_dict = load(path)
|
|
87
|
-
self.load_state_dict(state_dict, strict=strict)
|
|
88
|
-
except Exception as err:
|
|
89
|
-
logger.exception(err)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
class ConvDecoder(nn.Module):
|
|
93
|
-
"""A 1D CNN decoder
|
|
94
|
-
|
|
95
|
-
Args:
|
|
96
|
-
hidden_dims (tuple, optional): the number of intermediate channels of each convolutional layer. Defaults to (512, 256, 128, 64, 32).
|
|
97
|
-
latent_dim (int, optional): the dimension of the input latent embedding. Defaults to 64.
|
|
98
|
-
in_size (int, optional): the initial size for upscaling. Defaults to 8.
|
|
99
|
-
use_batch_norm (bool, optional): whether to use batch normalization. Defaults to True.
|
|
100
|
-
activation (str, optional): the type of activation function. Defaults to 'relu'.
|
|
101
|
-
"""
|
|
102
|
-
def __init__(self,
|
|
103
|
-
hidden_channels: tuple = (512, 256, 128, 64, 32),
|
|
104
|
-
dim_latent: int = 64,
|
|
105
|
-
in_size: int = 8,
|
|
106
|
-
kernel_size: int = 3,
|
|
107
|
-
use_batch_norm: bool = True,
|
|
108
|
-
activation: str = 'relu',
|
|
109
|
-
):
|
|
110
|
-
|
|
111
|
-
super().__init__()
|
|
112
|
-
|
|
113
|
-
self.in_size = in_size
|
|
114
|
-
modules = []
|
|
115
|
-
|
|
116
|
-
self.decoder_input = nn.Linear(dim_latent, hidden_channels[0] * in_size)
|
|
117
|
-
|
|
118
|
-
activation = activation_by_name(activation)
|
|
119
|
-
|
|
120
|
-
for i in range(len(hidden_channels) - 1):
|
|
121
|
-
modules.append(
|
|
122
|
-
nn.Sequential(
|
|
123
|
-
nn.ConvTranspose1d(
|
|
124
|
-
hidden_channels[i],
|
|
125
|
-
hidden_channels[i + 1],
|
|
126
|
-
kernel_size=kernel_size, #3
|
|
127
|
-
stride=2,
|
|
128
|
-
padding=kernel_size // 2, #1
|
|
129
|
-
output_padding=1,
|
|
130
|
-
),
|
|
131
|
-
nn.BatchNorm1d(hidden_channels[i + 1]) if use_batch_norm else nn.Identity(),
|
|
132
|
-
activation(),
|
|
133
|
-
)
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
self.decoder = nn.Sequential(*modules)
|
|
137
|
-
|
|
138
|
-
self.final_layer = nn.Sequential(
|
|
139
|
-
nn.ConvTranspose1d(hidden_channels[-1],
|
|
140
|
-
hidden_channels[-1],
|
|
141
|
-
kernel_size=kernel_size, #3
|
|
142
|
-
stride=2,
|
|
143
|
-
padding=kernel_size // 2, #1
|
|
144
|
-
output_padding=1),
|
|
145
|
-
nn.BatchNorm1d(hidden_channels[-1]) if use_batch_norm else nn.Identity(),
|
|
146
|
-
activation(),
|
|
147
|
-
nn.Conv1d(hidden_channels[-1], out_channels=1,
|
|
148
|
-
kernel_size=3, padding=1)
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
def forward(self, x):
|
|
152
|
-
batch_size = x.shape[0]
|
|
153
|
-
x = self.decoder_input(x).view(batch_size, -1, self.in_size)
|
|
154
|
-
x = self.decoder(x)
|
|
155
|
-
x = self.final_layer(x).flatten(1)
|
|
156
|
-
return x
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
class ConvAutoencoder(nn.Module):
|
|
160
|
-
"""A 1D convolutional denoising autoencoder"""
|
|
161
|
-
def __init__(self,
|
|
162
|
-
in_channels: int = 1,
|
|
163
|
-
encoder_hidden_channels: tuple = (32, 64, 128, 256, 512),
|
|
164
|
-
decoder_hidden_channels: tuple = (512, 256, 128, 64, 32),
|
|
165
|
-
dim_latent: int = 64,
|
|
166
|
-
dim_avpool: int = 1,
|
|
167
|
-
kernel_size: int = 3,
|
|
168
|
-
use_batch_norm: bool = True,
|
|
169
|
-
activation: str = 'relu',
|
|
170
|
-
decoder_in_size: int = 8,
|
|
171
|
-
**kwargs
|
|
172
|
-
):
|
|
173
|
-
super().__init__()
|
|
174
|
-
self.encoder = ConvEncoder(
|
|
175
|
-
in_channels=in_channels,
|
|
176
|
-
hidden_channels=encoder_hidden_channels,
|
|
177
|
-
kernel_size=kernel_size,
|
|
178
|
-
dim_embedding=dim_latent,
|
|
179
|
-
dim_avpool=dim_avpool,
|
|
180
|
-
use_batch_norm=use_batch_norm,
|
|
181
|
-
activation=activation,
|
|
182
|
-
**kwargs)
|
|
183
|
-
|
|
184
|
-
self.decoder = ConvDecoder(
|
|
185
|
-
hidden_channels=decoder_hidden_channels,
|
|
186
|
-
dim_latent=dim_latent,
|
|
187
|
-
in_size=decoder_in_size,
|
|
188
|
-
kernel_size=kernel_size,
|
|
189
|
-
use_batch_norm=use_batch_norm,
|
|
190
|
-
activation=activation,
|
|
191
|
-
**kwargs)
|
|
192
|
-
|
|
193
|
-
def forward(self, x):
|
|
194
|
-
return self.decoder(self.encoder(x))
|
|
195
|
-
|
|
196
|
-
class SEBlock(nn.Module):
|
|
197
|
-
"""Squeeze-and-excitation block (https://arxiv.org/abs/1709.01507) """
|
|
198
|
-
def __init__(self, in_channels, reduction=16):
|
|
199
|
-
super().__init__()
|
|
200
|
-
self.fc1 = nn.Linear(in_channels, in_channels // reduction, bias=False)
|
|
201
|
-
self.fc2 = nn.Linear(in_channels // reduction, in_channels, bias=False)
|
|
202
|
-
self.relu = nn.ReLU()
|
|
203
|
-
self.sigmoid = nn.Sigmoid()
|
|
204
|
-
self.global_avg_pool = nn.AdaptiveAvgPool1d(1)
|
|
205
|
-
|
|
206
|
-
def forward(self, x):
|
|
207
|
-
batch_size, channels, _ = x.size()
|
|
208
|
-
|
|
209
|
-
#Squeeze
|
|
210
|
-
se = self.global_avg_pool(x).view(batch_size, channels)
|
|
211
|
-
|
|
212
|
-
#Excitation
|
|
213
|
-
se = self.fc1(se)
|
|
214
|
-
se = self.relu(se)
|
|
215
|
-
se = self.fc2(se)
|
|
216
|
-
se = self.sigmoid(se).view(batch_size, channels, 1)
|
|
217
|
-
|
|
218
|
-
#Scale the input feature maps (channel-wise attention)
|
|
1
|
+
import logging
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import torch
|
|
5
|
+
from torch import nn, load
|
|
6
|
+
|
|
7
|
+
from reflectorch.models.activations import activation_by_name
|
|
8
|
+
from reflectorch.paths import SAVED_MODELS_DIR
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"ConvEncoder",
|
|
12
|
+
"ConvDecoder",
|
|
13
|
+
"ConvAutoencoder",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ConvEncoder(nn.Module):
|
|
20
|
+
"""A 1D CNN encoder / embedding network
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
in_channels (int, optional): the number of input channels. Defaults to 1.
|
|
24
|
+
hidden_channels (tuple, optional): the number of intermediate channels of each convolutional layer. Defaults to (32, 64, 128, 256, 512).
|
|
25
|
+
dim_embedding (int, optional): the dimension of the output latent embedding. Defaults to 64.
|
|
26
|
+
dim_avpool (int, optional): the output size of the adaptive average pooling layer. Defaults to 1.
|
|
27
|
+
use_batch_norm (bool, optional): whether to use batch normalization. Defaults to True.
|
|
28
|
+
activation (str, optional): the type of activation function. Defaults to 'relu'.
|
|
29
|
+
"""
|
|
30
|
+
def __init__(self,
|
|
31
|
+
in_channels: int = 1,
|
|
32
|
+
hidden_channels: tuple = (32, 64, 128, 256, 512),
|
|
33
|
+
kernel_size: int = 3,
|
|
34
|
+
dim_embedding: int = 64,
|
|
35
|
+
dim_avpool: int = 1,
|
|
36
|
+
use_batch_norm: bool = True,
|
|
37
|
+
use_se: bool = False,
|
|
38
|
+
activation: str = 'relu',
|
|
39
|
+
):
|
|
40
|
+
super().__init__()
|
|
41
|
+
|
|
42
|
+
modules = []
|
|
43
|
+
|
|
44
|
+
activation = activation_by_name(activation)
|
|
45
|
+
|
|
46
|
+
for h in hidden_channels:
|
|
47
|
+
layers = [
|
|
48
|
+
nn.Conv1d(in_channels, out_channels=h, kernel_size=kernel_size, stride=2, padding=kernel_size // 2),
|
|
49
|
+
activation(),
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
if use_batch_norm:
|
|
53
|
+
layers.insert(1, nn.BatchNorm1d(h))
|
|
54
|
+
|
|
55
|
+
if use_se:
|
|
56
|
+
layers.insert(2, SEBlock(h))
|
|
57
|
+
|
|
58
|
+
modules.append(nn.Sequential(*layers))
|
|
59
|
+
in_channels = h
|
|
60
|
+
|
|
61
|
+
self.core = nn.Sequential(*modules)
|
|
62
|
+
self.avpool = nn.AdaptiveAvgPool1d(dim_avpool)
|
|
63
|
+
self.fc = nn.Linear(hidden_channels[-1] * dim_avpool, dim_embedding)
|
|
64
|
+
|
|
65
|
+
def forward(self, x):
|
|
66
|
+
if len(x.shape) < 3:
|
|
67
|
+
x = x.unsqueeze(1)
|
|
68
|
+
x = self.core(x)
|
|
69
|
+
x = self.avpool(x).view(x.size(0), -1)
|
|
70
|
+
x = self.fc(x)
|
|
71
|
+
return x
|
|
72
|
+
|
|
73
|
+
def load_weights(self, path: str or Path = None, strict: bool = False):
|
|
74
|
+
if not path:
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
if isinstance(path, str):
|
|
78
|
+
if not path.endswith('.pt'):
|
|
79
|
+
path = path + '.pt'
|
|
80
|
+
path = SAVED_MODELS_DIR / path
|
|
81
|
+
|
|
82
|
+
if not path.is_file():
|
|
83
|
+
logger.error(f'File {str(path)} is not found.')
|
|
84
|
+
return
|
|
85
|
+
try:
|
|
86
|
+
state_dict = load(path)
|
|
87
|
+
self.load_state_dict(state_dict, strict=strict)
|
|
88
|
+
except Exception as err:
|
|
89
|
+
logger.exception(err)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class ConvDecoder(nn.Module):
|
|
93
|
+
"""A 1D CNN decoder
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
hidden_dims (tuple, optional): the number of intermediate channels of each convolutional layer. Defaults to (512, 256, 128, 64, 32).
|
|
97
|
+
latent_dim (int, optional): the dimension of the input latent embedding. Defaults to 64.
|
|
98
|
+
in_size (int, optional): the initial size for upscaling. Defaults to 8.
|
|
99
|
+
use_batch_norm (bool, optional): whether to use batch normalization. Defaults to True.
|
|
100
|
+
activation (str, optional): the type of activation function. Defaults to 'relu'.
|
|
101
|
+
"""
|
|
102
|
+
def __init__(self,
|
|
103
|
+
hidden_channels: tuple = (512, 256, 128, 64, 32),
|
|
104
|
+
dim_latent: int = 64,
|
|
105
|
+
in_size: int = 8,
|
|
106
|
+
kernel_size: int = 3,
|
|
107
|
+
use_batch_norm: bool = True,
|
|
108
|
+
activation: str = 'relu',
|
|
109
|
+
):
|
|
110
|
+
|
|
111
|
+
super().__init__()
|
|
112
|
+
|
|
113
|
+
self.in_size = in_size
|
|
114
|
+
modules = []
|
|
115
|
+
|
|
116
|
+
self.decoder_input = nn.Linear(dim_latent, hidden_channels[0] * in_size)
|
|
117
|
+
|
|
118
|
+
activation = activation_by_name(activation)
|
|
119
|
+
|
|
120
|
+
for i in range(len(hidden_channels) - 1):
|
|
121
|
+
modules.append(
|
|
122
|
+
nn.Sequential(
|
|
123
|
+
nn.ConvTranspose1d(
|
|
124
|
+
hidden_channels[i],
|
|
125
|
+
hidden_channels[i + 1],
|
|
126
|
+
kernel_size=kernel_size, #3
|
|
127
|
+
stride=2,
|
|
128
|
+
padding=kernel_size // 2, #1
|
|
129
|
+
output_padding=1,
|
|
130
|
+
),
|
|
131
|
+
nn.BatchNorm1d(hidden_channels[i + 1]) if use_batch_norm else nn.Identity(),
|
|
132
|
+
activation(),
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
self.decoder = nn.Sequential(*modules)
|
|
137
|
+
|
|
138
|
+
self.final_layer = nn.Sequential(
|
|
139
|
+
nn.ConvTranspose1d(hidden_channels[-1],
|
|
140
|
+
hidden_channels[-1],
|
|
141
|
+
kernel_size=kernel_size, #3
|
|
142
|
+
stride=2,
|
|
143
|
+
padding=kernel_size // 2, #1
|
|
144
|
+
output_padding=1),
|
|
145
|
+
nn.BatchNorm1d(hidden_channels[-1]) if use_batch_norm else nn.Identity(),
|
|
146
|
+
activation(),
|
|
147
|
+
nn.Conv1d(hidden_channels[-1], out_channels=1,
|
|
148
|
+
kernel_size=3, padding=1)
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def forward(self, x):
|
|
152
|
+
batch_size = x.shape[0]
|
|
153
|
+
x = self.decoder_input(x).view(batch_size, -1, self.in_size)
|
|
154
|
+
x = self.decoder(x)
|
|
155
|
+
x = self.final_layer(x).flatten(1)
|
|
156
|
+
return x
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class ConvAutoencoder(nn.Module):
|
|
160
|
+
"""A 1D convolutional denoising autoencoder"""
|
|
161
|
+
def __init__(self,
|
|
162
|
+
in_channels: int = 1,
|
|
163
|
+
encoder_hidden_channels: tuple = (32, 64, 128, 256, 512),
|
|
164
|
+
decoder_hidden_channels: tuple = (512, 256, 128, 64, 32),
|
|
165
|
+
dim_latent: int = 64,
|
|
166
|
+
dim_avpool: int = 1,
|
|
167
|
+
kernel_size: int = 3,
|
|
168
|
+
use_batch_norm: bool = True,
|
|
169
|
+
activation: str = 'relu',
|
|
170
|
+
decoder_in_size: int = 8,
|
|
171
|
+
**kwargs
|
|
172
|
+
):
|
|
173
|
+
super().__init__()
|
|
174
|
+
self.encoder = ConvEncoder(
|
|
175
|
+
in_channels=in_channels,
|
|
176
|
+
hidden_channels=encoder_hidden_channels,
|
|
177
|
+
kernel_size=kernel_size,
|
|
178
|
+
dim_embedding=dim_latent,
|
|
179
|
+
dim_avpool=dim_avpool,
|
|
180
|
+
use_batch_norm=use_batch_norm,
|
|
181
|
+
activation=activation,
|
|
182
|
+
**kwargs)
|
|
183
|
+
|
|
184
|
+
self.decoder = ConvDecoder(
|
|
185
|
+
hidden_channels=decoder_hidden_channels,
|
|
186
|
+
dim_latent=dim_latent,
|
|
187
|
+
in_size=decoder_in_size,
|
|
188
|
+
kernel_size=kernel_size,
|
|
189
|
+
use_batch_norm=use_batch_norm,
|
|
190
|
+
activation=activation,
|
|
191
|
+
**kwargs)
|
|
192
|
+
|
|
193
|
+
def forward(self, x):
|
|
194
|
+
return self.decoder(self.encoder(x))
|
|
195
|
+
|
|
196
|
+
class SEBlock(nn.Module):
|
|
197
|
+
"""Squeeze-and-excitation block (https://arxiv.org/abs/1709.01507) """
|
|
198
|
+
def __init__(self, in_channels, reduction=16):
|
|
199
|
+
super().__init__()
|
|
200
|
+
self.fc1 = nn.Linear(in_channels, in_channels // reduction, bias=False)
|
|
201
|
+
self.fc2 = nn.Linear(in_channels // reduction, in_channels, bias=False)
|
|
202
|
+
self.relu = nn.ReLU()
|
|
203
|
+
self.sigmoid = nn.Sigmoid()
|
|
204
|
+
self.global_avg_pool = nn.AdaptiveAvgPool1d(1)
|
|
205
|
+
|
|
206
|
+
def forward(self, x):
|
|
207
|
+
batch_size, channels, _ = x.size()
|
|
208
|
+
|
|
209
|
+
#Squeeze
|
|
210
|
+
se = self.global_avg_pool(x).view(batch_size, channels)
|
|
211
|
+
|
|
212
|
+
#Excitation
|
|
213
|
+
se = self.fc1(se)
|
|
214
|
+
se = self.relu(se)
|
|
215
|
+
se = self.fc2(se)
|
|
216
|
+
se = self.sigmoid(se).view(batch_size, channels, 1)
|
|
217
|
+
|
|
218
|
+
#Scale the input feature maps (channel-wise attention)
|
|
219
219
|
return x * se
|
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from torch import nn
|
|
4
|
-
from torch.nn import functional as F
|
|
5
|
-
from torch.nn import init
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
'ConvResidualNet1D',
|
|
9
|
-
]
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ConvResidualBlock1D(nn.Module):
|
|
13
|
-
def __init__(
|
|
14
|
-
self,
|
|
15
|
-
channels,
|
|
16
|
-
activation=F.gelu,
|
|
17
|
-
dropout_probability=0.0,
|
|
18
|
-
use_batch_norm=False,
|
|
19
|
-
zero_initialization=True,
|
|
20
|
-
kernel_size: int = 3,
|
|
21
|
-
dilation: int = 1,
|
|
22
|
-
padding: int = 1,
|
|
23
|
-
):
|
|
24
|
-
super().__init__()
|
|
25
|
-
self.activation = activation
|
|
26
|
-
|
|
27
|
-
self.use_batch_norm = use_batch_norm
|
|
28
|
-
|
|
29
|
-
if use_batch_norm:
|
|
30
|
-
self.batch_norm_layers = nn.ModuleList(
|
|
31
|
-
[nn.BatchNorm1d(channels, eps=1e-3) for _ in range(2)]
|
|
32
|
-
)
|
|
33
|
-
self.conv_layers = nn.ModuleList(
|
|
34
|
-
[nn.Conv1d(channels, channels, kernel_size=kernel_size, padding=padding, dilation=dilation)
|
|
35
|
-
for _ in range(2)]
|
|
36
|
-
)
|
|
37
|
-
self.dropout = nn.Dropout(p=dropout_probability)
|
|
38
|
-
|
|
39
|
-
if zero_initialization:
|
|
40
|
-
init.uniform_(self.conv_layers[-1].weight, -1e-3, 1e-3)
|
|
41
|
-
init.uniform_(self.conv_layers[-1].bias, -1e-3, 1e-3)
|
|
42
|
-
|
|
43
|
-
def forward(self, inputs):
|
|
44
|
-
temps = inputs
|
|
45
|
-
if self.use_batch_norm:
|
|
46
|
-
temps = self.batch_norm_layers[0](temps)
|
|
47
|
-
temps = self.activation(temps)
|
|
48
|
-
temps = self.conv_layers[0](temps)
|
|
49
|
-
if self.use_batch_norm:
|
|
50
|
-
temps = self.batch_norm_layers[1](temps)
|
|
51
|
-
|
|
52
|
-
temps = self.activation(temps)
|
|
53
|
-
temps = self.dropout(temps)
|
|
54
|
-
temps = self.conv_layers[1](temps)
|
|
55
|
-
|
|
56
|
-
return inputs + temps
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class ConvResidualNet1D(nn.Module):
|
|
60
|
-
def __init__(
|
|
61
|
-
self,
|
|
62
|
-
in_channels: int = 1,
|
|
63
|
-
out_channels: int = 64,
|
|
64
|
-
hidden_channels: int = 128,
|
|
65
|
-
num_blocks=5,
|
|
66
|
-
activation=F.gelu,
|
|
67
|
-
dropout_probability=0.0,
|
|
68
|
-
use_batch_norm=True,
|
|
69
|
-
kernel_size: int = 3,
|
|
70
|
-
dilation: int = 1,
|
|
71
|
-
padding: int = 1,
|
|
72
|
-
avpool: int = 8,
|
|
73
|
-
|
|
74
|
-
):
|
|
75
|
-
super().__init__()
|
|
76
|
-
|
|
77
|
-
self.hidden_channels = hidden_channels
|
|
78
|
-
|
|
79
|
-
self.initial_layer = nn.Conv1d(
|
|
80
|
-
in_channels=in_channels,
|
|
81
|
-
out_channels=hidden_channels,
|
|
82
|
-
kernel_size=1,
|
|
83
|
-
padding=0,
|
|
84
|
-
)
|
|
85
|
-
self.blocks = nn.ModuleList(
|
|
86
|
-
[
|
|
87
|
-
ConvResidualBlock1D(
|
|
88
|
-
channels=hidden_channels,
|
|
89
|
-
activation=activation,
|
|
90
|
-
dropout_probability=dropout_probability,
|
|
91
|
-
use_batch_norm=use_batch_norm,
|
|
92
|
-
kernel_size=kernel_size,
|
|
93
|
-
dilation=dilation,
|
|
94
|
-
padding=padding,
|
|
95
|
-
)
|
|
96
|
-
for _ in range(num_blocks)
|
|
97
|
-
]
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
self.avpool = nn.AdaptiveAvgPool1d(avpool)
|
|
101
|
-
|
|
102
|
-
self.final_layer = nn.Linear(
|
|
103
|
-
hidden_channels * avpool, out_channels
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
def forward(self, x):
|
|
107
|
-
temps = self.initial_layer(x.unsqueeze(1))
|
|
108
|
-
|
|
109
|
-
for block in self.blocks:
|
|
110
|
-
temps = block(temps)
|
|
111
|
-
|
|
112
|
-
temps = self.avpool(temps).view(temps.size(0), -1)
|
|
113
|
-
outputs = self.final_layer(temps)
|
|
114
|
-
|
|
115
|
-
return outputs
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from torch import nn
|
|
4
|
+
from torch.nn import functional as F
|
|
5
|
+
from torch.nn import init
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
'ConvResidualNet1D',
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ConvResidualBlock1D(nn.Module):
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
channels,
|
|
16
|
+
activation=F.gelu,
|
|
17
|
+
dropout_probability=0.0,
|
|
18
|
+
use_batch_norm=False,
|
|
19
|
+
zero_initialization=True,
|
|
20
|
+
kernel_size: int = 3,
|
|
21
|
+
dilation: int = 1,
|
|
22
|
+
padding: int = 1,
|
|
23
|
+
):
|
|
24
|
+
super().__init__()
|
|
25
|
+
self.activation = activation
|
|
26
|
+
|
|
27
|
+
self.use_batch_norm = use_batch_norm
|
|
28
|
+
|
|
29
|
+
if use_batch_norm:
|
|
30
|
+
self.batch_norm_layers = nn.ModuleList(
|
|
31
|
+
[nn.BatchNorm1d(channels, eps=1e-3) for _ in range(2)]
|
|
32
|
+
)
|
|
33
|
+
self.conv_layers = nn.ModuleList(
|
|
34
|
+
[nn.Conv1d(channels, channels, kernel_size=kernel_size, padding=padding, dilation=dilation)
|
|
35
|
+
for _ in range(2)]
|
|
36
|
+
)
|
|
37
|
+
self.dropout = nn.Dropout(p=dropout_probability)
|
|
38
|
+
|
|
39
|
+
if zero_initialization:
|
|
40
|
+
init.uniform_(self.conv_layers[-1].weight, -1e-3, 1e-3)
|
|
41
|
+
init.uniform_(self.conv_layers[-1].bias, -1e-3, 1e-3)
|
|
42
|
+
|
|
43
|
+
def forward(self, inputs):
|
|
44
|
+
temps = inputs
|
|
45
|
+
if self.use_batch_norm:
|
|
46
|
+
temps = self.batch_norm_layers[0](temps)
|
|
47
|
+
temps = self.activation(temps)
|
|
48
|
+
temps = self.conv_layers[0](temps)
|
|
49
|
+
if self.use_batch_norm:
|
|
50
|
+
temps = self.batch_norm_layers[1](temps)
|
|
51
|
+
|
|
52
|
+
temps = self.activation(temps)
|
|
53
|
+
temps = self.dropout(temps)
|
|
54
|
+
temps = self.conv_layers[1](temps)
|
|
55
|
+
|
|
56
|
+
return inputs + temps
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ConvResidualNet1D(nn.Module):
|
|
60
|
+
def __init__(
|
|
61
|
+
self,
|
|
62
|
+
in_channels: int = 1,
|
|
63
|
+
out_channels: int = 64,
|
|
64
|
+
hidden_channels: int = 128,
|
|
65
|
+
num_blocks=5,
|
|
66
|
+
activation=F.gelu,
|
|
67
|
+
dropout_probability=0.0,
|
|
68
|
+
use_batch_norm=True,
|
|
69
|
+
kernel_size: int = 3,
|
|
70
|
+
dilation: int = 1,
|
|
71
|
+
padding: int = 1,
|
|
72
|
+
avpool: int = 8,
|
|
73
|
+
|
|
74
|
+
):
|
|
75
|
+
super().__init__()
|
|
76
|
+
|
|
77
|
+
self.hidden_channels = hidden_channels
|
|
78
|
+
|
|
79
|
+
self.initial_layer = nn.Conv1d(
|
|
80
|
+
in_channels=in_channels,
|
|
81
|
+
out_channels=hidden_channels,
|
|
82
|
+
kernel_size=1,
|
|
83
|
+
padding=0,
|
|
84
|
+
)
|
|
85
|
+
self.blocks = nn.ModuleList(
|
|
86
|
+
[
|
|
87
|
+
ConvResidualBlock1D(
|
|
88
|
+
channels=hidden_channels,
|
|
89
|
+
activation=activation,
|
|
90
|
+
dropout_probability=dropout_probability,
|
|
91
|
+
use_batch_norm=use_batch_norm,
|
|
92
|
+
kernel_size=kernel_size,
|
|
93
|
+
dilation=dilation,
|
|
94
|
+
padding=padding,
|
|
95
|
+
)
|
|
96
|
+
for _ in range(num_blocks)
|
|
97
|
+
]
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
self.avpool = nn.AdaptiveAvgPool1d(avpool)
|
|
101
|
+
|
|
102
|
+
self.final_layer = nn.Linear(
|
|
103
|
+
hidden_channels * avpool, out_channels
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
def forward(self, x):
|
|
107
|
+
temps = self.initial_layer(x.unsqueeze(1))
|
|
108
|
+
|
|
109
|
+
for block in self.blocks:
|
|
110
|
+
temps = block(temps)
|
|
111
|
+
|
|
112
|
+
temps = self.avpool(temps).view(temps.size(0), -1)
|
|
113
|
+
outputs = self.final_layer(temps)
|
|
114
|
+
|
|
115
|
+
return outputs
|