Ejemplo n.º 1
0
    def send_metric(self, channel_name, x, y=None, timestamp=None):
        x, y = self._get_valid_x_y(x, y)

        if not is_float(y):
            raise InvalidChannelValue(expected_type='float', actual_type=type(y).__name__)

        value = ChannelValue(x, dict(numeric_value=y), timestamp)
        self._channels_values_sender.send(channel_name, 'numeric', value)
Ejemplo n.º 2
0
    def _get_valid_x_y(x, y):
        if x is None:
            raise NoChannelValue()

        if y is None:
            y = x
            x = None
        elif not is_float(x):
            raise InvalidChannelValue(expected_type='float', actual_type=type(x).__name__)

        return x, y
Ejemplo n.º 3
0
    def _convert_to_api_parameters(self, raw_params):
        Parameter = self.backend_swagger_client.get_model('Parameter')

        params = []
        for name, value in raw_params.items():
            parameter_type = 'double' if is_float(value) else 'string'

            params.append(
                Parameter(id=str(uuid.uuid4()),
                          name=name,
                          parameterType=parameter_type,
                          value=str(value)))

        return params
Ejemplo n.º 4
0
    def _get_valid_x_y(x, y):
        """
        The goal of this function is to allow user to call experiment.log_* with any of:
            - single parameter treated as y value
            - both parameters (named/unnamed)
            - single named y parameter
        If intended X-coordinate is provided, it is validated to be a float value
        """
        if x is None and y is None:
            raise NoChannelValue()

        if x is None and y is not None:
            return None, y

        if x is not None and y is None:
            return None, x

        if x is not None and y is not None:
            if not is_float(x):
                raise InvalidChannelValue(expected_type='float', actual_type=type(x).__name__)
            return x, y
Ejemplo n.º 5
0
    def log_metric(self, log_name, x, y=None, timestamp=None):
        """Log metrics (numeric values) in Neptune

        | If a log with provided ``log_name`` does not exist, it is created automatically.
        | If log exists (determined by ``log_name``), then new value is appended to it.

        Args:
            log_name (:obj:`str`): The name of log, i.e. `mse`, `loss`, `accuracy`.
            x (:obj:`double`): Depending, whether ``y`` parameter is passed:

                * ``y`` not passed: The value of the log (data-point).
                * ``y`` passed: Index of log entry being appended. Must be strictly increasing.

            y (:obj:`double`, optional, default is ``None``): The value of the log (data-point).
            timestamp (:obj:`time`, optional, default is ``None``):
                Timestamp to be associated with log entry. Must be Unix time.
                If ``None`` is passed, `time.time() <https://docs.python.org/3.6/library/time.html#time.time>`_
                (Python 3.6 example) is invoked to obtain timestamp.

        Example:
            Assuming that `experiment` is an instance of :class:`~neptune.experiments.Experiment` and
            'accuracy' log does not exists:

            .. code:: python3

                # Both calls below have the same effect

                # Common invocation, providing log name and value
                experiment.log_metric('accuracy', 0.5)
                experiment.log_metric('accuracy', 0.65)
                experiment.log_metric('accuracy', 0.8)

                # Providing both x and y params
                experiment.log_metric('accuracy', 0, 0.5)
                experiment.log_metric('accuracy', 1, 0.65)
                experiment.log_metric('accuracy', 2, 0.8)

        Note:
            For efficiency, logs are uploaded in batches via a queue.
            Hence, if you log a lot of data, you may experience slight delays in Neptune web application.
        Note:
            Passing either ``x`` or ``y`` coordinate as NaN or +/-inf causes this log entry to be ignored.
            Warning is printed to ``stdout``.
        """
        x, y = self._get_valid_x_y(x, y)

        if not is_float(y):
            raise InvalidChannelValue(expected_type='float',
                                      actual_type=type(y).__name__)

        if is_nan_or_inf(y):
            _logger.warning(
                'Invalid metric value: %s for channel %s. '
                'Metrics with nan or +/-inf values will not be sent to server',
                y, log_name)
        elif x is not None and is_nan_or_inf(x):
            _logger.warning(
                'Invalid metric x-coordinate: %s for channel %s. '
                'Metrics with nan or +/-inf x-coordinates will not be sent to server',
                x, log_name)
        else:
            value = ChannelValue(x, dict(numeric_value=y), timestamp)
            self._channels_values_sender.send(log_name,
                                              ChannelType.NUMERIC.value, value)