Commit b48a7f1e authored by Atreya Majumdar's avatar Atreya Majumdar
Browse files

Added Squared Hinge loss

parent dd8665e9
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -94,6 +94,31 @@ class HingeLoss(Loss):
    return loss


class SquaredHingeLoss(Loss):
  """The Squared Hinge loss function.
  
  Defined as the square of the hinge loss between y_true and y_pred.
  """

  def _compute_tf_loss(self, output, labels):
    import tensorflow as tf
    output, labels = _make_tf_shapes_consistent(output, labels)
    return tf.keras.losses.SquaredHinge(reduction='none')(labels, output)

  def _create_pytorch_loss(self):
    import torch

    def loss(output, labels):
      output, labels = _make_pytorch_shapes_consistent(output, labels)
      return torch.mean(
          torch.pow(
              torch.maximum(1 - torch.multiply(labels, output),
                            torch.tensor(0)), 2),
          dim=-1)

    return loss


class BinaryCrossEntropy(Loss):
  """The cross entropy between pairs of probabilities.

+47 −0
Original line number Diff line number Diff line
@@ -409,3 +409,50 @@ class LinearCosineDecay(LearningRateSchedule):

    import torch
    return torch.optim.lr_scheduler.LambdaLR(optimizer, f)

class ReduceLRonPlateau(LearningRateSchedule):
  """Reduces the Learning Rate when the chosen metric has stopped improving."""

  def __init__(self,
               initial_rate: float,
               decay_steps: int,
               alpha: float = 0.0,
               beta: float = 0.001,
               num_periods: float = 0.5):
    """
    Parameters
    ----------
    learning_rate : float
    initial learning rate
    decay_steps : int
    number of steps to decay over
    num_periods : number of periods in the cosine part of the decay
    """

    self.initial_rate = initial_rate
    self.decay_steps = decay_steps
    self.alpha = alpha
    self.beta = beta
    self.num_periods = num_periods

  def _create_tf_tensor(self, global_step):
    import tensorflow as tf
    return tf.compat.v1.train.linear_cosine_decay(
        learning_rate=self.initial_rate,
        global_step=global_step,
        decay_steps=self.decay_steps,
        alpha=self.alpha,
        beta=self.beta,
        num_periods=self.num_periods)

  def _create_pytorch_schedule(self, optimizer):

    def f(step):
      t = min(step, self.decay_steps) / self.decay_steps
      linear_decay = 1 - t
      cosine_decay = 0.5 * (1 + math.cos(math.pi * 2 * self.num_periods * t))
      decayed = (self.alpha + linear_decay) * cosine_decay + self.beta
      return self.initial_rate * decayed

    import torch
    return torch.optim.lr_scheduler.LambdaLR(optimizer, f)
+20 −0
Original line number Diff line number Diff line
@@ -98,6 +98,26 @@ class TestLosses(unittest.TestCase):
    expected = [np.mean([0.9, 1.8]), np.mean([1.4, 0.4])]
    assert np.allclose(expected, result)

  @unittest.skipIf(not has_tensorflow, 'TensorFlow is not installed')
  def test_squared_hinge_loss_tf(self):
    """Test SquaredHingeLoss."""
    loss = losses.SquaredHingeLoss()
    outputs = tf.constant([[0.1, 0.8], [0.4, 0.6]])
    labels = tf.constant([[1.0, -1.0], [-1.0, 1.0]])
    result = loss._compute_tf_loss(outputs, labels).numpy()
    expected = [np.mean([0.8100, 3.2400]), np.mean([1.9600, 0.1600])]
    assert np.allclose(expected, result)

  @unittest.skipIf(not has_pytorch, 'PyTorch is not installed')
  def test_squared_hinge_loss_pytorch(self):
    """Test SquaredHingeLoss."""
    loss = losses.SquaredHingeLoss()
    outputs = torch.tensor([[0.1, 0.8], [0.4, 0.6]])
    labels = torch.tensor([[1.0, -1.0], [-1.0, 1.0]])
    result = loss._create_pytorch_loss()(outputs, labels).numpy()
    expected = [np.mean([0.8100, 3.2400]), np.mean([1.9600, 0.1600])]
    assert np.allclose(expected, result)

  @unittest.skipIf(not has_tensorflow, 'TensorFlow is not installed')
  def test_binary_cross_entropy_tf(self):
    """Test BinaryCrossEntropy."""
+3 −0
Original line number Diff line number Diff line
@@ -193,6 +193,9 @@ Losses
.. autoclass:: deepchem.models.losses.HingeLoss
  :members:

.. autoclass:: deepchem.models.losses.SquaredHingeLoss
  :members:

.. autoclass:: deepchem.models.losses.BinaryCrossEntropy
  :members: