Exemple #1
0
    def default_input_fn(self, input_data, content_type):
        """Take request data and deserialize it into an object for prediction.
        When an InvokeEndpoint operation is made against an Endpoint running SageMaker model server,
        the model server receives two pieces of information:

            - The request's content type, for example "application/json"
            - The request data

        The ``input_fn`` is responsible for preprocessing request data before prediction.

        Args:
            input_data (obj): the request data
            content_type (str): the request's content type

        Returns:
            mxnet.io.NDArrayIter: data ready for prediction.

        Raises:
            sagemaker_containers.beta.framework.errors.UnsupportedFormatError: if an unsupported
                accept type is used.
        """
        if content_type not in self.VALID_CONTENT_TYPES:
            raise errors.UnsupportedFormatError(content_type)

        np_array = encoders.decode(input_data, content_type)
        ndarray = mx.nd.array(np_array).as_in_context(_context())

        # We require model to only have one input
        [data_shape] = self._model.data_shapes

        # Reshape flattened CSV as specified by the model
        if content_type == content_types.CSV:
            _, target_shape = data_shape
            ndarray = ndarray.reshape(target_shape)

        # Batch size is first dimension of model input
        model_batch_size = data_shape[1][0]
        pad_rows = max(0, model_batch_size - ndarray.shape[0])

        # If ndarray has fewer rows than model_batch_size, then pad it with zeros.
        if pad_rows:
            num_pad_values = pad_rows
            for dimension in ndarray.shape[1:]:
                num_pad_values *= dimension
            padding_shape = tuple([pad_rows] + list(ndarray.shape[1:]))
            padding = mx.ndarray.zeros(shape=padding_shape)
            ndarray = mx.ndarray.concat(ndarray, padding, dim=0)

        model_input = mx.io.NDArrayIter(ndarray, batch_size=model_batch_size,
                                        last_batch_handle='pad')

        if pad_rows:
            # Update the getpad method on the model_input data iterator to return the amount of
            # padding. MXNet will ignore the last getpad() rows during Module predict.
            def _getpad():
                return pad_rows

            model_input.getpad = _getpad

        return model_input
Exemple #2
0
    def default_input_fn(self, input_data, content_type):
        """Take request data and deserialize it into an object for prediction.
        When an InvokeEndpoint operation is made against an Endpoint running SageMaker model server,
        the model server receives two pieces of information:

            - The request's content type, for example "application/json"
            - The request data

        The ``input_fn`` is responsible for preprocessing request data before prediction.

        Args:
            input_data (obj): the request data
            content_type (str): the request's content type

        Returns:
            mxnet.nd.array: an MXNet NDArray

        Raises:
            sagemaker_containers.beta.framework.errors.UnsupportedFormatError: if an unsupported
                content type is used.
        """
        if content_type in self.VALID_CONTENT_TYPES:
            np_array = encoders.decode(input_data, content_type)
            return mx.nd.array(np_array).as_in_context(_context())
        else:
            raise errors.UnsupportedFormatError(content_type)
    def default_output_fn(self, prediction, accept):
        """Serialize the prediction into a response.

        Args:
            prediction (mxnet.nd.array): an MXNet NDArray that is the result of a prediction
            accept (str): the accept content type expected by the client

        Returns:
            sagemaker_containers.beta.framework.worker.Response: a Flask response object

        Raises:
            sagemaker_containers.beta.framework.errors.UnsupportedFormatError: if an unsupported
                accept type is used.
        """
        if accept in self.VALID_CONTENT_TYPES:
            return worker.Response(encoders.encode(prediction.asnumpy().tolist(), accept), accept)
        else:
            raise errors.UnsupportedFormatError(accept)