def T(self, T): if not isinstance(T, tuple): raise e.TypeError('`T` should be a tuple') if len(T) != self.n_layers: raise e.SizeError(f'`T` should have size equal as {self.n_layers}') self._T = T
def test_size_error(): new_exception = exception.SizeError("error") try: raise new_exception except exception.SizeError: pass
def decay(self, decay): if not isinstance(decay, tuple): raise e.TypeError('`decay` should be a tuple') if len(decay) != self.n_layers: raise e.SizeError( f'`decay` should have size equal as {self.n_layers}') self._decay = decay
def momentum(self, momentum): if not isinstance(momentum, tuple): raise e.TypeError('`momentum` should be a tuple') if len(momentum) != self.n_layers: raise e.SizeError( f'`momentum` should have size equal as {self.n_layers}') self._momentum = momentum
def lr(self, lr): if not isinstance(lr, tuple): raise e.TypeError('`lr` should be a tuple') if len(lr) != self.n_layers: raise e.SizeError( f'`lr` should have size equal as {self.n_layers}') self._lr = lr
def steps(self, steps): if not isinstance(steps, tuple): raise e.TypeError('`steps` should be a tuple') if len(steps) != self.n_layers: raise e.SizeError( f'`steps` should have size equal as {self.n_layers}') self._steps = steps
def plot( *args, labels: Optional[List[str]] = None, title: Optional[str] = "", subtitle: Optional[str] = "", xlabel: Optional[str] = "epoch", ylabel: Optional[str] = "value", grid: Optional[bool] = True, legend: Optional[bool] = True, ) -> None: """Plots the convergence graph of desired variables. Essentially, each variable is a list or numpy array with size equals to (epochs x 1). Args: labels: Labels to be applied for each plot in legend. title: The title of the plot. subtitle: The subtitle of the plot. xlabel: The `x` axis label. ylabel: The `y` axis label. grid: If grid should be used or not. legend: If legend should be displayed or not. """ # Gathering the amount of possible ticks ticks = np.arange(1, len(args[0]) + 1) # Creating figure and axis subplots _, ax = plt.subplots(figsize=(7, 5)) # Defining some properties, such as axis labels, ticks and limits ax.set(xlabel=xlabel, ylabel=ylabel) ax.set_xticks(ticks) ax.set_xlim(xmin=1, xmax=ticks[-1]) # Setting both title and subtitles ax.set_title(title, loc="left", fontsize=14) ax.set_title(subtitle, loc="right", fontsize=8, color="grey") if grid: ax.grid() if labels: if len(labels) != len(args): raise e.SizeError("`args` and `labels` should have the same size") else: labels = [f"variable_{i}" for i in range(len(args))] # Plotting the axis for (arg, label) in zip(args, labels): ax.plot(ticks, arg, label=label) if legend: ax.legend() # Displaying the plot plt.show()
def fit( self, dataset: Union[torch.utils.data.Dataset, Dataset], batch_size: Optional[int] = 128, epochs: Optional[Tuple[int, ...]] = (10, 10), ) -> float: """Fits a new ConvDBN model. Args: dataset: A Dataset object containing the training data. batch_size: Amount of samples per batch. epochs: Number of training epochs per layer. Returns: (float): MSE (mean squared error) from the training step. """ # Checking if the length of number of epochs' list is correct if len(epochs) != self.n_layers: # If not, raises an error raise e.SizeError( ("`epochs` should have size equal as %d", self.n_layers)) # Initializing MSE as a list mse = [] # Initializing the dataset's variables samples, targets, transform = ( dataset.data.numpy(), dataset.targets.numpy(), dataset.transform, ) # For every possible model (ConvRBM) for i, model in enumerate(self.models): logger.info("Fitting layer %d/%d ...", i + 1, self.n_layers) # Creating the dataset d = Dataset(samples, targets, transform) # Fits the RBM model_mse = model.fit(d, batch_size, epochs[i]) # Appending the metrics mse.append(model_mse) # If the dataset has a transform if d.transform: # Applies the transform over the samples samples = d.transform(d.data) # If there is no transform else: # Just gather the samples samples = d.data # Checking whether GPU is avaliable and if it should be used if self.device == "cuda": # Applies the GPU usage to the data samples = samples.cuda() # Reshape the samples into an appropriate shape samples = samples.reshape( len(dataset), model.n_channels, model.visible_shape[0], model.visible_shape[1], ) # Gathers the targets targets = d.targets # Gathers the transform callable from current dataset transform = None # Performs a forward pass over the samples to get their probabilities samples, _ = model.hidden_sampling(samples) # Checking whether GPU is being used if self.device == "cuda": # If yes, get samples back to the CPU samples = samples.cpu() # Detaches the variable from the computing graph samples = samples.detach() return mse
def decay(self, decay: Tuple[float, ...]) -> None: if len(decay) != self.n_layers: raise e.SizeError( f"`decay` should have size equal as {self.n_layers}") self._decay = decay
def momentum(self, momentum: Tuple[float, ...]) -> None: if len(momentum) != self.n_layers: raise e.SizeError( f"`momentum` should have size equal as {self.n_layers}") self._momentum = momentum
def lr(self, lr: Tuple[float, ...]) -> None: if len(lr) != self.n_layers: raise e.SizeError( f"`lr` should have size equal as {self.n_layers}") self._lr = lr
def steps(self, steps: Tuple[int, ...]) -> None: if len(steps) != self.n_layers: raise e.SizeError( f"`steps` should have size equal as {self.n_layers}") self._steps = steps
def fit( self, dataset: Union[torch.utils.data.Dataset, Dataset], batch_size: Optional[int] = 128, epochs: Optional[Tuple[int, ...]] = (10, ), ) -> Tuple[float, float]: """Fits a new ResidualDBN model. Args: dataset: A Dataset object containing the training data. batch_size: Amount of samples per batch. epochs: Number of training epochs per layer. Returns: (Tuple[float, float]): MSE (mean squared error) and log pseudo-likelihood from the training step. """ # Checking if the length of number of epochs' list is correct if len(epochs) != self.n_layers: # If not, raises an error raise e.SizeError( f"`epochs` should have size equal as {self.n_layers}") # Initializing MSE and pseudo-likelihood as lists mse, pl = [], [] # Initializing the dataset's variables samples, targets, transform = ( dataset.data.numpy(), dataset.targets.numpy(), dataset.transform, ) # For every possible model (RBM) for i, model in enumerate(self.models): logger.info("Fitting layer %d/%d ...", i + 1, self.n_layers) # Creating the dataset d = Dataset(samples, targets, transform) # Fits the RBM model_mse, model_pl = model.fit(d, batch_size, epochs[i]) # Appending the metrics mse.append(model_mse) pl.append(model_pl) # If the dataset has a transform if d.transform: # Applies the transform over the samples samples = d.transform(d.data) # If there is no transform else: # Just gather the samples samples = d.data # Checking whether GPU is avaliable and if it should be used if self.device == "cuda": # Applies the GPU usage to the data samples = samples.cuda() # Reshape the samples into an appropriate shape samples = samples.reshape(len(dataset), model.n_visible) # Gathers the targets targets = d.targets # Gathers the transform callable from current dataset transform = None # Calculates pre-activation values pre_activation = model.pre_activation(samples) # Performs a forward pass over the samples samples, _ = model.hidden_sampling(samples) # Aggregates the residual learning samples = torch.mul(samples, self.zetta1) + torch.mul( self.calculate_residual(pre_activation), self.zetta2) # Normalizes the input for the next layer samples = torch.div(samples, torch.max(samples)) # Checking whether GPU is being used if self.device == "cuda": # If yes, get samples back to the CPU samples = samples.cpu() # Detaches the variable from the computing graph samples = samples.detach() return mse, pl
def plot(*args, labels=None, title='', subtitle='', xlabel='epoch', ylabel='value', grid=True, legend=True): """Plots the convergence graph of desired variables. Essentially, each variable is a list or numpy array with size equals to (epochs x 1). Args: labels (list): Labels to be applied for each plot in legend. title (str): The title of the plot. subtitle (str): The subtitle of the plot. xlabel (str): The `x` axis label. ylabel (str): The `y` axis label. grid (bool): If grid should be used or not. legend (bool): If legend should be displayed or not. """ # Gathering the amount of possible ticks ticks = np.arange(1, len(args[0]) + 1) # Creating figure and axis subplots _, ax = plt.subplots(figsize=(7, 5)) # Defining some properties, such as axis labels, ticks and limits ax.set(xlabel=xlabel, ylabel=ylabel) ax.set_xticks(ticks) ax.set_xlim(xmin=1, xmax=ticks[-1]) # Setting both title and subtitles ax.set_title(title, loc='left', fontsize=14) ax.set_title(subtitle, loc='right', fontsize=8, color='grey') # If grid usage is true if grid: # Adds the grid property to the axis ax.grid() # Check if labels argument exists if labels: # Also check if it is a list if not isinstance(labels, list): raise e.TypeError('`labels` should be a list') # And check if it has the same size of arguments if len(labels) != len(args): raise e.SizeError('`args` and `labels` should have the same size') # If labels argument does not exists else: # Creates a list with indicators labels = [f'variable_{i}' for i in range(len(args))] # Plotting the axis for (arg, label) in zip(args, labels): ax.plot(ticks, arg, label=label) # If legend usage is true if legend: # Adds the legend property to the axis ax.legend() # Displaying the plot plt.show()
def fit(self, dataset, batch_size=128, epochs=(10, )): """Fits a new DBN model. Args: dataset (torch.utils.data.Dataset | Dataset): A Dataset object containing the training data. batch_size (int): Amount of samples per batch. epochs (tuple): Number of training epochs per layer. Returns: MSE (mean squared error) and log pseudo-likelihood from the training step. """ # Checking if the length of number of epochs' list is correct if len(epochs) != self.n_layers: # If not, raises an error raise e.SizeError( ('`epochs` should have size equal as %d', self.n_layers)) # Initializing MSE and pseudo-likelihood as lists mse, pl = [], [] # Initializing the dataset's variables samples, targets, transform = dataset.data.numpy( ), dataset.targets.numpy(), dataset.transform # For every possible model (RBM) for i, model in enumerate(self.models): logger.info('Fitting layer %d/%d ...', i + 1, self.n_layers) # Creating the dataset d = Dataset(samples, targets, transform) # Fits the RBM model_mse, model_pl = model.fit(d, batch_size, epochs[i]) # Appending the metrics mse.append(model_mse) pl.append(model_pl) # If the dataset has a transform if d.transform: # Applies the transform over the samples samples = d.transform(d.data) # If there is no transform else: # Just gather the samples samples = d.data # Checking whether GPU is avaliable and if it should be used if self.device == 'cuda': # Applies the GPU usage to the data samples = samples.cuda() # Reshape the samples into an appropriate shape samples = samples.reshape(len(dataset), model.n_visible) # Gathers the targets targets = d.targets # Gathers the transform callable from current dataset transform = None # Performs a forward pass over the samples to get their probabilities samples, _ = model.hidden_sampling(samples) # Checking whether GPU is being used if self.device == 'cuda': # If yes, get samples back to the CPU samples = samples.cpu() # Detaches the variable from the computing graph samples = samples.detach() return mse, pl
def T(self, T: Tuple[float, ...]) -> None: if len(T) != self.n_layers: raise e.SizeError(f"`T` should have size equal as {self.n_layers}") self._T = T