in tabular/src/autogluon/tabular/models/tabular_nn/torch/torch_network_modules.py [0:0]
def __init__(self,
problem_type,
num_net_outputs=None,
quantile_levels=None,
train_dataset=None,
architecture_desc=None,
device=None,
**kwargs):
if (architecture_desc is None) and (train_dataset is None):
raise ValueError("train_dataset cannot = None if architecture_desc=None")
super().__init__()
self.problem_type = problem_type
if self. problem_type == QUANTILE:
self.register_buffer('quantile_levels', torch.Tensor(quantile_levels).float().reshape(1, -1))
self.device = torch.device('cpu') if device is None else device
if architecture_desc is None:
params = self._set_params(**kwargs)
# adpatively specify network architecture based on training dataset
self.from_logits = False
self.has_vector_features = train_dataset.has_vector_features()
self.has_embed_features = train_dataset.num_embed_features() > 0
if self.has_embed_features:
num_categs_per_feature = train_dataset.getNumCategoriesEmbeddings()
embed_dims = get_embed_sizes(train_dataset, params, num_categs_per_feature)
if self.has_vector_features:
vector_dims = train_dataset.data_list[train_dataset.vectordata_index].shape[-1]
else:
# ignore train_dataset, params, etc. Recreate architecture based on description:
self.architecture_desc = architecture_desc
self.has_vector_features = architecture_desc['has_vector_features']
self.has_embed_features = architecture_desc['has_embed_features']
self.from_logits = architecture_desc['from_logits']
params = architecture_desc['params']
if self.has_embed_features:
num_categs_per_feature = architecture_desc['num_categs_per_feature']
embed_dims = architecture_desc['embed_dims']
if self.has_vector_features:
vector_dims = architecture_desc['vector_dims']
# init input size
input_size = 0
# define embedding layer:
if self.has_embed_features:
self.embed_blocks = nn.ModuleList()
for i in range(len(num_categs_per_feature)):
self.embed_blocks.append(nn.Embedding(num_embeddings=num_categs_per_feature[i],
embedding_dim=embed_dims[i]))
input_size += embed_dims[i]
# update input size
if self.has_vector_features:
input_size += vector_dims
# activation
act_fn = nn.Identity()
if params['activation'] == 'elu':
act_fn = nn.ELU()
elif params['activation'] == 'relu':
act_fn = nn.ReLU()
elif params['activation'] == 'tanh':
act_fn = nn.Tanh()
layers = []
if params['use_batchnorm']:
layers.append(nn.BatchNorm1d(input_size))
layers.append(nn.Linear(input_size, params['hidden_size']))
layers.append(act_fn)
for _ in range(params['num_layers'] - 1):
if params['use_batchnorm']:
layers.append(nn.BatchNorm1d(params['hidden_size']))
layers.append(nn.Dropout(params['dropout_prob']))
layers.append(nn.Linear(params['hidden_size'], params['hidden_size']))
layers.append(act_fn)
layers.append(nn.Linear(params['hidden_size'], num_net_outputs))
self.main_block = nn.Sequential(*layers)
if self.problem_type in [REGRESSION, QUANTILE]: # set range for output
y_range = params['y_range'] # Used specifically for regression. = None for classification.
self.y_constraint = None # determines if Y-predictions should be constrained
if y_range is not None:
if y_range[0] == -np.inf and y_range[1] == np.inf:
self.y_constraint = None # do not worry about Y-range in this case
elif y_range[0] >= 0 and y_range[1] == np.inf:
self.y_constraint = 'nonnegative'
elif y_range[0] == -np.inf and y_range[1] <= 0:
self.y_constraint = 'nonpositive'
else:
self.y_constraint = 'bounded'
self.y_lower = y_range[0]
self.y_upper = y_range[1]
self.y_span = self.y_upper - self.y_lower
if self.problem_type == QUANTILE:
self.alpha = params['alpha'] # for huber loss
if self.problem_type == SOFTCLASS:
self.log_softmax = torch.nn.LogSoftmax(dim=1)
if self.problem_type in [BINARY, MULTICLASS, SOFTCLASS]:
self.softmax = torch.nn.Softmax(dim=1)
if architecture_desc is None: # Save Architecture description
self.architecture_desc = {'has_vector_features': self.has_vector_features,
'has_embed_features': self.has_embed_features,
'params': params, 'num_net_outputs': num_net_outputs,
'from_logits': self.from_logits}
if self.has_embed_features:
self.architecture_desc['num_categs_per_feature'] = num_categs_per_feature
self.architecture_desc['embed_dims'] = embed_dims
if self.has_vector_features:
self.architecture_desc['vector_dims'] = vector_dims