Skip to content

Commit

Permalink
fixed bug in cosine
Browse files Browse the repository at this point in the history
  • Loading branch information
benja263 committed Jan 22, 2025
1 parent d3b3949 commit 15e21d9
Show file tree
Hide file tree
Showing 21 changed files with 283 additions and 172 deletions.
10 changes: 5 additions & 5 deletions gbrl/ac_gbrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(self,
self.value_grad = None

@classmethod
def load_model(cls, load_name: str) -> "ActorCritic":
def load_model(cls, load_name: str, device: str) -> "ActorCritic":
"""Loads GBRL model from a file
Args:
Expand All @@ -92,11 +92,11 @@ def load_model(cls, load_name: str) -> "ActorCritic":

instance = cls.__new__(cls)
if os.path.isfile(policy_file) and os.path.isfile(value_file):
instance._model = SeparateActorCriticWrapper.load(load_name)
instance._model = SeparateActorCriticWrapper.load(load_name, device)
instance.shared_tree_struct = False
instance.bias = instance._model.policy_model.get_bias()
else:
instance._model = SharedActorCriticWrapper.load(load_name)
instance._model = SharedActorCriticWrapper.load(load_name, device)
instance.shared_tree_struct = True
instance.bias = instance._model.get_bias()
instance.value_optimizer = instance._model.value_optimizer
Expand Down Expand Up @@ -314,7 +314,7 @@ def step(self, observations: Union[np.ndarray, th.Tensor], policy_grad_clip: flo
self.grad = policy_grad

@classmethod
def load_model(cls, load_name: str) -> "ParametricActor":
def load_model(cls, load_name: str, device: str) -> "ParametricActor":
"""Loads GBRL model from a file
Args:
Expand All @@ -324,7 +324,7 @@ def load_model(cls, load_name: str) -> "ParametricActor":
ParametricActor: loaded ActorCriticModel
"""
instance = cls.__new__(cls)
instance._model = GBTWrapper.load(load_name)
instance._model = GBTWrapper.load(load_name, device)
instance.bias = instance._model.get_bias()
instance.policy_optimizer = instance._model.optimizer
instance.output_dim = instance._model.output_dim
Expand Down
32 changes: 21 additions & 11 deletions gbrl/gbrl_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#
##############################################################################
import os
from typing import Dict, List, Union, Tuple
from typing import Dict, List, Union, Tuple, Optional, Any

import numpy as np
import torch as th
Expand Down Expand Up @@ -49,6 +49,7 @@ def __init__(self, output_dim: int, tree_struct: Dict, optimizer: Union[Dict, Li
assert np.all(feature_weights >= 0), "feature weights contains non-positive values"
self.feature_weights = feature_weights


def reset(self) -> None:
if self.cpp_model is not None:
lrs = self.cpp_model.get_scheduler_lrs()
Expand Down Expand Up @@ -129,14 +130,15 @@ def export(self, filename: str, modelname: str = None) -> None:
print(f"Caught an exception in GBRL: {e}")

@classmethod
def load(cls, filename: str) -> "GBTWrapper":
def load(cls, filename: str, device: str) -> "GBTWrapper":
filename = filename.rstrip('.')
if '.gbrl_model' not in filename:
filename += '.gbrl_model'
assert os.path.isfile(filename), "filename doesn't exist!"
try:
instance = cls.__new__(cls)
instance.cpp_model = GBRL_CPP.load(filename)
instance.set_device(device)
metadata = instance.cpp_model.get_metadata()
instance.tree_struct = {'max_depth': metadata['max_depth'],
'min_data_in_leaf': metadata['min_data_in_leaf'],
Expand All @@ -162,6 +164,7 @@ def load(cls, filename: str) -> "GBTWrapper":
instance.iteration = metadata['iteration']
instance.total_iterations = metadata['iteration']
instance.student_model = None
instance.device = instance.params['device']
return instance
except RuntimeError as e:
print(f"Caught an exception in GBRL: {e}")
Expand All @@ -186,12 +189,12 @@ def set_bias(self, bias: Union[np.ndarray, float]) -> None:
raise TypeError("Input should be a numpy array or float")

if isinstance(bias, float):
bias = np.array([float])
bias = np.ndarray([float])

if bias.ndim > 1:
bias = bias.ravel()
elif bias.ndim == 0:
bias = np.array([bias.item()]) # Converts 0D arrays to 1D
bias = np.ndarray([bias.item()]) # Converts 0D arrays to 1D
try:
self.cpp_model.set_bias(bias)
except RuntimeError as e:
Expand Down Expand Up @@ -246,7 +249,9 @@ def shap(self, features: Union[np.ndarray, th.Tensor]) -> np.ndarray:
base_poly, norm_values, offset = get_poly_vectors(self.params['max_depth'], numerical_dtype)
return self.cpp_model.ensemble_shap(num_features, cat_features, np.ascontiguousarray(norm_values), np.ascontiguousarray(base_poly), np.ascontiguousarray(offset))

def set_device(self, device: str) -> None:
def set_device(self, device: Union[str, th.device]) -> None:
if isinstance(device, th.device):
device = device.type
try:
self.cpp_model.to_device(device)
self.device = device
Expand Down Expand Up @@ -292,7 +297,7 @@ def distil(self, obs: Union[np.ndarray, th.Tensor], targets: np.ndarray, params:

bias = np.mean(targets, axis=0)
if isinstance(bias, float):
bias = np.array([bias])
bias = np.ndarray([bias])
self.student_model.set_bias(bias.astype(numerical_dtype))
tr_loss = self.student_model.fit(num_obs, cat_obs, targets, params['min_steps'])
while tr_loss> params.get('min_distillation_loss', 0.1):
Expand All @@ -308,6 +313,9 @@ def distil(self, obs: Union[np.ndarray, th.Tensor], targets: np.ndarray, params:
def copy(self):
return self.__copy__()

def print_ensemble_metadata(self):
self.cpp_model.print_ensemble_metadata()

def __copy__(self):
copy_ = GBTWrapper(self.output_dim, self.tree_struct.copy(), [opt.copy() if opt is not None else opt for opt in self.optimizer], self.gbrl_params, self.verbose, self.device)
copy_.iteration = self.iteration
Expand Down Expand Up @@ -413,10 +421,12 @@ def plot_tree(self, tree_idx: int, filename: str) -> None:
self.value_model.plot_tree(tree_idx, filename.rstrip(".") + "_value")

@classmethod
def load(cls, filename: str) -> "SeparateActorCriticWrapper":
def load(cls, filename: str, device: str) -> "SeparateActorCriticWrapper":
instance = cls.__new__(cls)
instance.policy_model = GBTWrapper.load(filename + '_policy')
instance.value_model = GBTWrapper.load(filename + '_value')
instance.policy_model = GBTWrapper.load(filename + '_policy', device)
instance.value_model = GBTWrapper.load(filename + '_value', device)
instance.policy_model.set_device(device)
instance.value_model.set_device(device)
instance.tree_struct = instance.policy_model.tree_struct
instance.total_iterations = instance.policy_model.iteration + instance.value_model.iteration
instance.output_dim = instance.policy_model.output_dim
Expand Down Expand Up @@ -527,8 +537,8 @@ def predict_critic(self, observations: Union[np.ndarray, th.Tensor], requires_gr
return pred_values

@classmethod
def load(cls, filename: str) -> "SharedActorCriticWrapper":
instance = super().load(filename)
def load(cls, filename: str, device: str) -> "SharedActorCriticWrapper":
instance = super().load(filename, device)
instance.policy_optimizer = instance.optimizer[0]
instance.value_optimizer = None if len(instance.optimizer) != 2 else instance.optimizer[1]
return instance
Expand Down
18 changes: 5 additions & 13 deletions gbrl/gbt.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# https://nvlabs.github.io/gbrl/license.html
#
##############################################################################
from typing import Dict, List, Union, Tuple, Optional
from typing import Dict, List, Union, Tuple, Optional, Any

import numpy as np
import torch as th
Expand Down Expand Up @@ -99,14 +99,6 @@ def set_bias(self, bias: Union[np.ndarray, th.Tensor]):
if len(bias.shape) == 1:
bias = bias[:, np.newaxis]
self._model.set_bias(bias.astype(np.single))

def get_bias(self) -> np.ndarray:
"""Sets GBRL bias
Returns:
np.ndarray: bias
"""
return self._model.get_bias()

def set_bias_from_targets(self, targets: Union[np.ndarray, th.Tensor]):
"""Sets bias as mean of targets
Expand All @@ -123,7 +115,7 @@ def set_bias_from_targets(self, targets: Union[np.ndarray, th.Tensor]):
arr = arr[:, np.newaxis]
mean_arr = np.mean(arr, axis=0)
if isinstance(mean_arr, float):
mean_arr = np.array([mean_arr])
mean_arr = np.ndarray([mean_arr])
self._model.set_bias(mean_arr.astype(np.single)) # GBRL only works with float32

def get_iteration(self) -> int:
Expand Down Expand Up @@ -180,7 +172,7 @@ def get_params(self) -> Tuple[np.ndarray, np.ndarray]:
params = (params[0].detach().cpu().numpy(), params[1].detach().cpu().numpy())
return params, self.grad

def fit(self, X: Union[np.ndarray, th.Tensor], targets: Union[np.ndarray, th.Tensor], iterations: int, shuffle: bool=True, loss_type: str='MultiRMSE') -> float:
def fit(self, X: Union[np.ndarray, th.Tensor], targets: Union[np.ndarray, th.Tensor], iterations: int, shuffle: bool = True, loss_type: str = 'MultiRMSE') -> float:
"""Fit multiple iterations (as in supervised learning)
Args:
Expand Down Expand Up @@ -251,7 +243,7 @@ def export_model(self, filename: str, modelname: str = None) -> None:
self._model.export(filename, modelname)

@classmethod
def load_model(cls, load_name: str) -> "GBRL":
def load_model(cls, load_name: str, device: str) -> "GBRL":
"""Loads GBRL model from a file
Args:
Expand All @@ -261,7 +253,7 @@ def load_model(cls, load_name: str) -> "GBRL":
GBRL instance
"""
instance = cls.__new__(cls)
instance._model = GBTWrapper.load(load_name)
instance._model = GBTWrapper.load(load_name, device)
instance.optimizer = instance._model.optimizer
instance.output_dim = instance._model.output_dim
instance.verbose = instance._model.verbose
Expand Down
2 changes: 1 addition & 1 deletion gbrl/src/cpp/fitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ int Fitter::fit_greedy_tree(dataSet *dataset, ensembleData *edata, ensembleMetaD
int feat_idx = (split_candidates[j].categorical_value == nullptr) ? split_candidates[j].feature_idx : split_candidates[j].feature_idx + metadata->n_num_features;
score = score * dataset->feature_weights[feat_idx] - parent_score;
#ifdef DEBUG
// std::cout << " cand: " << j << " score: " << score << " parent score: " << parent_score << " info: " << split_candidates[j] << std::endl;
std::cout << " cand: " << j << " score: " << score << " parent score: " << parent_score << " info: " << split_candidates[j] << std::endl;
#endif
if (score > local_best_score) {
local_best_score = score;
Expand Down
Loading

0 comments on commit 15e21d9

Please sign in to comment.