Beispiel #1
0
    def read_result_to_ndarray(pixels, width, height, metadata, grayscale, as_uint16, num_channels):
        if metadata["bitdepth"] == 16 and not as_uint16:
            raise ValueError("cannot convert 16bit image to 8bit image."
                             " Original range of pixel values is unknown.")

        output_type = np.uint16 if as_uint16 else np.uint8
        img = np.asarray(list(pixels), output_type)

        if metadata["bitdepth"] == 8 and as_uint16:
            logger.warning("You want to read image as uint16, but the original bit-depth is 8 bit."
                           "All pixel values are simply increased by 256 times.")
            img *= 256

        # shape is (height, width * planes), planes = 1 (gray), 3 (rgb) or 4 (rgba)

        if not metadata["greyscale"]:
            # read image is rgb or rgba
            img = img.reshape((height, width, -1))

            if grayscale:
                img = PngBackend.rgb2gray(img).astype(output_type)

        img = PngBackend.convert_num_channles(img, num_channels)

        return img
Beispiel #2
0
def create_communicator(ignore_error=False,
                        extension_module='cudnn',
                        type_config='float'):
    global _current_communicator

    if os.environ.get('OMPI_COMM_WORLD_SIZE') is not None:
        from nnabla.ext_utils import get_extension_context
        context = get_extension_context(extension_module,
                                        type_config=type_config)
        try:
            logger.log(99,
                       'Create communicator with contexts {}'.format(context))
            _current_communicator = C.MultiProcessCommunicator(context)
            _current_communicator.init()
            context.device_id = str(_current_communicator.rank %
                                    _current_communicator.size)
            if _current_communicator.size == 1:
                _current_communicator = None
        except:
            if not ignore_error:
                raise
            logger.warning("Failed to initialize nnabla.communicators.")
            _current_communicator = None
    else:
        _current_communicator = None

    return _current_communicator
Beispiel #3
0
    def imsave(self, path, img, channel_first=False, as_uint16=False, auto_scale=True):
        """
        Save image by pillow module.
        Currently, pillow supports only uint8 to save.

        Args:
            path (str): output filename
            img (numpy.ndarray): Image array to save. Image shape is considered as (height, width, channel) by default.
            channel_first (bool):
                This argument specifies the shape of img is whether (height, width, channel) or (channel, height, width).
                Default value is False, which means the img shape is considered as (height, width, channel)
            as_uint16 (bool):
                In this backend, this argument is always False because pillow dose not support uint16.
                If True, exception will be raised.
            auto_scale (bool) :
                Whether upscale pixel values or not.
                If you want to save float image, this argument must be True.
                In pillow backend, only float ([0, 1]) to uint8 ([0, 255]) is supported.
        """
        img = _imsave_before(img, channel_first, auto_scale)

        if img.dtype == np.uint16 or as_uint16:
            logger.warning("Pillow only supports uint8 image to save. Cast img to uint8."
                           "If you want to save image as uint16, install pypng or cv2 "
                           "and nnabla.utils.image_utils automatically change backend to use these module.")
            return self.next_available(path).imsave(path, img, channel_first=channel_first, as_uint16=as_uint16, auto_scale=auto_scale)

        if auto_scale and img.dtype != np.uint8:
            img = (img * 255).astype(np.uint8)

        if len(img.shape) == 3 and img.shape[-1] == 1:
            img = np.squeeze(img, axis=-1)

        Image.fromarray(img).save(path)
Beispiel #4
0
    def imread(self,
               path,
               grayscale=False,
               size=None,
               interpolate="bilinear",
               channel_first=False,
               as_uint16=False,
               num_channels=-1):
        """
        Read image by pypng module.

        Args:
            path (str or 'file object'): File path or object to read.
            grayscale (bool):
            size (tupple of int):
                (width, height).
                If None, output img shape depends on the files to read.
            channel_first (bool):
                This argument specifies the shape of img is whether (height, width, channel) or (channel, height, width).
                Default value is False, which means the img shape is (height, width, channel).
            interpolate (str):
                must be one of ["nearest", "box", "bilinear", "hamming", "bicubic", "lanczos"].
            as_uint16 (bool):
                If True, this function reads image as uint16.
            num_channels (int):
                channel size of output array.
                Default is -1 which preserves raw image shape.

        Returns:
            numpy.ndarray
        """

        _imread_before(grayscale, num_channels)

        f = path if hasattr(path, "read") else open(path, "rb")

        r = png.Reader(file=f)
        width, height, pixels, metadata = r.asDirect()

        bit_depth = metadata.get("bitdepth")

        if bit_depth not in [8, 16]:
            logger.warning(
                "The bit-depth of the image you want to read is unsupported ({}bit)."
                "Currently, pypng backend`s imread supports only [8, 16] bit-depth."
                "the path for this image is {}".format(bit_depth, path))
            return self.next_available(path).imread(
                path,
                grayscale=grayscale,
                size=size,
                interpolate=interpolate,
                channel_first=channel_first,
                as_uint16=as_uint16,
                num_channels=num_channels)

        img = self.read_result_to_ndarray(pixels, width, height, metadata,
                                          grayscale, as_uint16, num_channels)

        return _imread_after(img, size, interpolate, channel_first,
                             self.imresize)
Beispiel #5
0
    def imread(self, path, grayscale=False, size=None, interpolate="bilinear",
               channel_first=False, as_uint16=False, num_channels=-1, return_palette_indices=False):
        """
        Read image by PIL module.
        Notice that PIL only supports uint8 for RGB (not uint16).
        So this imread function returns only uint8 array for both RGB and gray-scale.
        (Currently ignore "I" mode for gray-scale (32bit integer).)

        Args:
            path (str or 'file object'): File path or object to read.
            grayscale (bool):
            size (tupple of int):
                (width, height).
                If None, output img shape depends on the files to read.
            channel_first (bool):
                This argument specifies the shape of img is whether (height, width, channel) or (channel, height, width).
                Default value is False, which means the img shape is (height, width, channel).
            interpolate (str):
                must be one of ["nearest", "box", "bilinear", "hamming", "bicubic", "lanczos"].
            as_uint16 (bool):
                If you specify this argument, you can use only False for pil backend.
            num_channels (int):
                channel size of output array.
                Default is -1 which preserves raw image shape.
            return_palette_indices (bool):
                Whether to return a raw palette indices without any conversion or not.
                If this flag is True and read Image has the mode "P",
                then this function returns 2-D array containing the indices into palette.
                We recommend that this flag should be False unless you intend to use the raw palette indices.

        Returns:
            numpy.ndarray
        """

        if as_uint16:
            logger.warning("pillow only supports uint8 for RGB image."
                           " If you want to load image as uint16,"
                           " install pypng or cv2 and"
                           " nnabla.utils.image_utils automatically change backend to use these module.")
            return self.next_available(path).imread(path, grayscale=grayscale, size=size, interpolate=interpolate,
                                                    channel_first=channel_first, as_uint16=as_uint16, num_channels=num_channels)

        _imread_before(grayscale, num_channels)

        pil_img = Image.open(path, mode="r")

        try:
            img = self.pil_image_to_ndarray(
                pil_img, grayscale, num_channels, return_palette_indices)
        except:
            return self.next_available(path).imread(path, grayscale=grayscale, size=size, interpolate=interpolate,
                                                    channel_first=channel_first, as_uint16=as_uint16, num_channels=num_channels)

        return _imread_after(img, size, interpolate, channel_first, self.imresize)
Beispiel #6
0
def check_type_and_cast_if_necessary(img, as_uint16):
    if not as_uint16 and img.dtype == np.uint16:
        raise ValueError("Input img type is uint16, but as_uint16 is False."
                         " If you want to save img as uint8, be sure all pixel values are in the range of [0, 255]"
                         " and cast it before you call imsave function.")

    if as_uint16 and img.dtype != np.uint16:
        # in the case of as_uint16 is True and upscale is False. Save uint8 as uint16 without scaling.
        logger.warning(
            "Save image as uint16, but the original input image type is not uint16")
        img = np.asarray(img, np.uint16)

    return img
Beispiel #7
0
def imread(path,
           grayscale=False,
           size=None,
           interpolate="bilinear",
           channel_first=False,
           as_uint16=False,
           num_channels=-1):
    """
    Read image by cv2 module.

    Args:
        path (str or 'file object'): File path or object to read.
        grayscale (bool):
        size (tupple of int):
            (width, height).
            If None, output img shape depends on the files to read.
        channel_first (bool):
            This argument specifies the shape of img is whether (height, width, channel) or (channel, height, width).
            Default value is False, which means the img shape is (height, width, channel).
        interpolate (str):
            must be one of ["nearest", "bilinear", "bicubic", "lanczos"].
        as_uint16 (bool):
            If True, this function reads image as uint16.
        num_channels (int):
            channel size of output array.
            Default is -1 which preserves raw image shape.

    Returns:
         numpy.ndarray
    """

    _imread_before(grayscale, num_channels)

    r_mode = cv2.IMREAD_GRAYSCALE if grayscale else cv2.IMREAD_UNCHANGED
    img = _imread_helper(path, r_mode)

    if as_uint16 and img.dtype != np.uint16:
        if img.dtype == np.uint8:
            logger.warning(
                "You want to read image as uint16, but the original bit-depth is 8 bit."
                "All pixel values are simply increased by 256 times.")
            img = img.astype(np.uint16) * 256
        else:
            raise ValueError("casting {} to uint16 is not safe.".format(
                img.dtype))

    img = _cvtColor_helper(img, num_channels)

    img = _imread_after(img, size, interpolate, channel_first, imresize)

    return img
Beispiel #8
0
def imread(path,
           grayscale=False,
           size=None,
           interpolate="bilinear",
           channel_first=False,
           as_uint16=False,
           num_channels=-1):
    """
    Read image by pydicom module.

    Before using pydicom module, opencv needs to be installed.
    Args:
        path (str or 'file object'): File path or object to read.
        grayscale (bool):
        size (tupple of int):
            (width, height).
            If None, output img shape depends on the files to read.
        channel_first (bool):
            This argument specifies the shape of img is whether (height, width, channel) or (channel, height, width).
            Default value is False, which means the img shape is (height, width, channel).
        interpolate (str):
            must be one of ["nearest", "bilinear", "bicubic", "lanczos"].
        as_uint16 (bool):
            If you specify this argument, you can use only False for pil backend.
        num_channels (int):
            channel size of output array.
            Default is -1 which preserves raw image shape.

    Returns:
         numpy.ndarray
    """
    _imread_before(grayscale, num_channels)

    dicom_dataset = pydicom.dcmread(path)

    img = dicom_dataset.pixel_array
    if as_uint16 and img.dtype != np.uint16:
        if img.dtype == np.uint8:
            logger.warning(
                "You want to read image as uint16, but the original bit-depth is 8 bit."
                "All pixel values are simply increased by 256 times.")
            img = img.astype(np.uint16) * 256
        else:
            raise ValueError("casting {} to uint16 is not safe.".format(
                img.dtype))

    if num_channels == -1 and grayscale:
        num_channels = 0
    img = _cvtColor_helper(img, num_channels)

    return _imread_after(img, size, interpolate, channel_first, imresize)
def create_communicator(ignore_error=False):
    global _current_communicator

    from nnabla.ext_utils import get_extension_context
    extension_module = "cudnn"
    context = get_extension_context(extension_module)
    try:
        logger.log(99, 'Create communicator with contexts {}'.format(context))
        _current_communicator = C.MultiProcessCommunicator(context)
        _current_communicator.init()
        context.device_id = str(_current_communicator.rank %
                                _current_communicator.size)
        if _current_communicator.size == 1:
            _current_communicator = None
    except:
        if not ignore_error:
            raise
        logger.warning("Failed to initialize nnabla.communicators.")
        _current_communicator = None

    return _current_communicator
Beispiel #10
0
    def predict(self, graph):
        self._visitor.reset()
        graph.visit(self._visitor)
        flops = 0
        for func in self._visitor._functions:

            args = [func.info.type_name] + \
                   [str(inp.shape) for inp in func.inputs] + \
                   [str(func.info.args)]
            key = '-'.join(args)

            ff = getattr(F, func.info.type_name)(get_current_context(),
                                                 **func.info.args)

            if key not in self.memo:
                try:  # run profiler
                    nnabla_vars = [
                        nn.Variable(inp.shape, need_grad=inp.need_grad)
                        for inp in func.inputs
                    ]
                    runner = Profiler(
                        ff(*nnabla_vars),
                        device_id=self._device_id,
                        ext_name=self._ext_name,
                        n_run=self._n_run,
                        outlier=self._outlier,
                        max_measure_execution_time=self.
                        _max_measure_execution_time,  # noqa: E501
                        time_scale=self._time_scale,
                        n_warmup=self._n_warmup)
                    runner.run()
                    latency = float(runner.result['forward_all'])

                except Exception as err:
                    latency = 0
                    logger.warning(f'Latency calculation failed: {key}')
                    logger.warning(str(err))
                self.memo[key] = latency
            flops += self.memo[key]
        return flops
Beispiel #11
0
    def _get_analysis(self, comm):
        def _analyse_gpu_cost_time(result, threshold):
            aver = np.mean(result, axis=0)[1]
            _node_l = [*filter(lambda n: n[1] > aver * threshold, result)]
            if len(_node_l):
                ranks = ', '.join([str(int(n[0])) for n in _node_l])
                _str = ('Gpu of Rank {} ran slower than average '
                        'by a factor of {} or more'.format(ranks, threshold))
                return _str
            return ''

        result = self._reap_multinode_data(comm)
        if comm.rank == 0:
            error_str = _analyse_gpu_cost_time(result, self._error_threshold)
            if error_str:
                logger.error(error_str)
                raise Exception(error_str)
            else:
                warning_str = _analyse_gpu_cost_time(result,
                                                     self._warning_threshold)
                if warning_str:
                    logger.warning(warning_str)
Beispiel #12
0
    def predict(self, module):
        """Returns the estimation of a single module"""

        idm = str(module)
        if idm not in self.memo:
            self.memo[idm] = dict()
        mem = self.memo[idm]
        key = '-'.join([str(k[1:]) for k in module.input_shapes])

        if key not in mem:
            state = module.training
            module.apply(training=False)  # turn off training
            try:
                # run profiler
                nnabla_vars = [
                    nn.Variable((1, ) + s[1:]) for s in module.input_shapes
                ]
                runner = Profiler(
                    module.call(*nnabla_vars),
                    device_id=self._device_id,
                    ext_name=self._ext_name,
                    n_run=self._n_run,
                    outlier=self._outlier,
                    max_measure_execution_time=self.
                    _max_measure_execution_time,  # noqa: E501
                    time_scale=self._time_scale,
                    n_warmup=self._n_warmup)
                runner.run()
                latency = float(runner.result['forward_all'])
            except Exception as err:
                latency = 0
                logger.warning(f'Latency calculation fails: {idm}[{key}]')
                logger.warning(str(err))

            mem[key] = latency
            module.apply(training=state)  # recover training state
        return mem[key]
Beispiel #13
0
def load_checkpoint(path, solvers):
    """Given the checkpoint file, loads the parameters and solver states.

        Args:
            path: Path to the checkpoint file.
            solvers: A dictionary about solver's info, which is like;
                     solvers = {"identifier_for_solver_0": solver_0,
                               {"identifier_for_solver_1": solver_1, ...}
                     The keys are used for retrieving proper info from the checkpoint.
                     so must be the same as the one used when saved.
                     Also, you can give a solver object if only one solver exists.
                     Then, the "" is used as an identifier.

        Returns:
            current_iter: The number of iteretions that the training resumes from.
                          Note that this assumes that the numbers of the update for
                          each solvers is the same.

        Examples:
            # Create computation graph with parameters.
            pred = construct_pred_net(input_Variable, ...)

            # Create solver and set parameters.
            solver = S.Adam(learning_rate)
            solver.set_parameters(nn.get_parameters())

            # AFTER setting parameters.
            start_point = load_checkpoint(path, solver)

            # Training loop.

        Notes:
            It requires the checkpoint file. For details, refer to save_checkpoint;
            checkpoint_1000 = {
                    "":{
                        "states_path": <path to the states file>
                        "params_names":["conv1/conv/W", ...],
                        "num_update":1000
                       },
                    "current_iter": 1000
                    }

            If you have multiple solvers.
            checkpoint_1000 = {
                    "generator":{
                        "states_path": <path to the states file>,
                        "params_names":["deconv1/conv/W", ...],
                        "num_update":1000
                       },
                    "discriminator":{
                        "states_path": <path to the states file>,
                        "params_names":["conv1/conv/W", ...],
                        "num_update":1000
                       },
                    "current_iter": 1000
                    }

    """

    assert os.path.isfile(path), "checkpoint file not found"

    with open(path, 'r') as f:
        checkpoint_info = json.load(f)

    if isinstance(solvers, nn.solver.Solver):
        solvers = {"": solvers}

    logger.info("Checkpoint load (.json): {}".format(path))

    # load parameters (stored in global).
    params_path = checkpoint_info["params_path"]
    assert os.path.isfile(params_path), "parameters file not found."

    nn.parameter.load_parameters(params_path)

    for solvername, solver_obj in solvers.items():
        partial_info = checkpoint_info[solvername]
        if set(solver_obj.get_parameters().keys()) != set(partial_info["params_names"]):
            logger.warning("Detected parameters do not match.")

        # load solver states.
        states_path = partial_info["states_path"]
        assert os.path.isfile(states_path), "states file not found."

        # set solver states.
        solver_obj.load_states(states_path)

    # get current iteration. note that this might differ from the numbers of update.
    current_iter = checkpoint_info["current_iter"]

    return current_iter
Beispiel #14
0
    def calc_latency_all_modules(self, path, graph, func_latency=None):
        """
            Calculate the latency for each of the modules in a graph.
            The modules are extracted using the graph structure information.
            The latency is then calculated based on each individual module's
            nnabla graph.
            It also saves the accumulated latency of all modules.

            Args:
                path
                graph:
                func_latency: function to use to calc latency of
                              each of the modules
                              This function needs to work based on the graph
        """
        import nnabla.function as Function
        from nnabla_nas.utils.estimator.latency import Profiler
        from nnabla.context import get_current_context
        from nnabla.logger import logger

        func_latency._visitor.reset()
        graph.visit(func_latency._visitor)
        total_latency = 0.0
        idx = 0
        for func in func_latency._visitor._functions:
            args = [func.info.type_name] + \
                   [str(inp.shape) for inp in func.inputs] + \
                   [str(func.info.args)]
            key = '-'.join(args)

            ff = getattr(Function, func.info.type_name)(get_current_context(),
                                                        **func.info.args)

            if key not in func_latency.memo:
                try:  # run profiler
                    nnabla_vars = [
                        nn.Variable(inp.shape, need_grad=inp.need_grad)
                        for inp in func.inputs
                    ]
                    runner = Profiler(
                        ff(*nnabla_vars),
                        device_id=func_latency._device_id,
                        ext_name=func_latency._ext_name,
                        n_run=func_latency._n_run,
                        outlier=func_latency._outlier,
                        max_measure_execution_time=func_latency.
                        _max_measure_execution_time,  # noqa: E501
                        time_scale=func_latency._time_scale,
                        n_warmup=func_latency._n_warmup)
                    runner.run()
                    latency = float(runner.result['forward_all'])

                except Exception as err:
                    latency = 0.0
                    logger.warning(f'Latency calculation failed: {key}')
                    logger.warning(str(err))

                func_latency.memo[key] = latency
            else:
                latency = func_latency.memo[key]

            total_latency += latency

            # save latency of this layer (name: id_XXX_{key}.acclat)
            filename = path + '/id_' + str(idx) + '_' + key + '.acclat'
            pathname = os.path.dirname(filename)
            upper_pathname = os.path.dirname(pathname)
            if not os.path.exists(upper_pathname):
                os.mkdir(upper_pathname)
            if not os.path.exists(pathname):
                os.mkdir(pathname)
            idx += 1
            with open(filename, 'w') as f:
                print(latency.__str__(), file=f)

        # save accum latency of all layers
        filename = path + '.acclat'
        with open(filename, 'w') as f:
            print(total_latency.__str__(), file=f)

        return total_latency