Пример #1
0
    def weight_initiallize(self, input_size):
        # The first dimension is to allow different types of uncorrelated images as inputs, such as RGB information.
        # After this dimension, the image data is assumed to be meaningfully correlated.
        self._dims = len(input_size[1:])
        if is_cuda_active():
            assert self._dims < 4, "GPU Version currently only supports 2 and 3 dimensions"

        if self._dims == 1 and is_cuda_active():
            padding, stride, filter = self._initial_value
            self._kernel = np.append(filter, 1).astype(np.int32)
            self._padding = np.append(padding, 0).astype(np.int32)
            self._stride = np.append(stride, 1).astype(np.int32)

        def func(var):
            return check_input(var, self._dims)
        self._kernel, self._padding, self._stride = map(
            func, [self._kernel, self._padding, self._stride])

        assert all([s > 0 for s in input_size[1:]]), \
            "The shape of input array {} is too small. Please give an array which size is lager than 0.".format(
                input_size[1:])

        f_lst = [self._channel, input_size[0]]
        f_lst.extend(self._kernel)
        size_f = tuple(f_lst)
        size_b = tuple([1, self._channel] + [1 for _ in range(self._dims)])

        self.params = {"w": Variable(self._initializer(size_f), auto_update=True)}
        if not self._ignore_bias:
            self.params["b"] = Variable(np.zeros(size_b), auto_update=True)
Пример #2
0
def _grad(self, initial=None, detach_graph=True, weight_decay=None, **kwargs):
    '''This method follows computational graph and returns the gradients of
    Variable object.

    Args:
        initial (ndarray): Initial value of following the graph.
        detach_graph (bool): If it's True, the computational graph will be destroyed.
        weight_decay (float): Sets the default weight decay of the model.
                            See the Variable class for more info.
    '''
    if not self._has_autoupdate():
        return Grads()

    if initial is None:
        if self.size > 1:
            raise ValueError("Initial diff is required for scalar value.")

        if is_cuda_active():
            initial = Node(get_gpu(self).ones_like_me())
        else:
            initial = np.ones_like(self).astype(precision)

    context = Grads(self, weight_decay=weight_decay)
    self._update_diff(context, initial, **kwargs)

    if detach_graph:
        self.detach_graph()
    return context
Пример #3
0
    def __call__(self, x):
        dims = len(x.shape[2:])
        if self._dims is None:
            if dims < 2:
                dims = 2
            self._dims = dims
        if is_cuda_active():
            assert self._dims < 4, "GPU Version can only 1, 2 and 3 dimensions"

        if self._dims == 1:
            self._kernel = np.append(self._kernel, 1).astype(np.int32)
            self._padding = np.append(self._padding, 0).astype(np.int32)
            self._stride = np.append(self._stride, 1).astype(np.int32)

        def func(var):
            return check_input(var, self._dims)

        self._padding, self._stride, self._kernel = map(
            func, [self._padding, self._stride, self._kernel])

        assert len(
            x.shape
        ) >= 3, "The dimension of input array must be greater than 3. Actual dim is {}".format(
            x.ndim)
        assert all([s > 0 for s in x.shape[2:]]), \
            "The shape of input array {} is too small. Please give an array which size is lager than 0.".format(
                x.shape)
        return self.forward(x)
    def __init__(self, array=None, shape=None, ptr=None, dtype=None):
        self._ptr = None
        if not is_cuda_active():
            raise ValueError('Cuda is not active. '
                             'Use renom.cuda.set_cuda_active() to activate.')

        if shape is not None:
            self.shape = tuple(shape)
        else:
            self.shape = getattr(array, "shape", None) or ()

        if not dtype:
            self.dtype = np.dtype(precision)
        else:
            self.dtype = np.dtype(dtype)

        self.itemsize = self.dtype.itemsize
        self.size = (calc_int_prod(self.shape) if self.shape else 1)
        self.nbytes = self.size * self.itemsize

        self._ptr = ptr
        if array is not None:
            self.to_gpu(array)
        elif not self._ptr:
            self.alloc()
        else:
            self.device_id = cuGetDevice()

        if debug.GET_ACTIVE_GPU() is not None:
            debug.SET_GPU_DICT(id(self), self)

        assert self._ptr
        self._ptr.refcount += 1
Пример #5
0
 def __init__(self, x, y, **kwargs):
     if not cuda_imported:
         raise ImportError(
             "Failed to import cuda during distributor.py import, cannot launch GPUDistributor.")
     assert is_cuda_active(), "Cuda must be activated to use GPU distributor"
     super(GPUDistributor, self).__init__(x=x, y=y, data_table=kwargs.get("data_table"))
     assert len(x) == len(y), "Input batches must have same number as output batches"
     self._data_size = len(x)
Пример #6
0
 def sync(self):
     if is_cuda_active():
         done = set()
         for m in self.iter_models():
             device_id = m._device_id
             if device_id not in done:
                 done.add(device_id)
                 with use_device(m._device_id):
                     renom.cuda.cuDeviceSynchronize()
Пример #7
0
def assert_cuda_active(should_be_active):
    if should_be_active is True:
        # assert has_cuda()  # Make sure we have cuda for the test
        if not has_cuda():
            warnings.warn("You are trying to use cuda but it's not installed.")
            return

    set_cuda_active(should_be_active)

    if should_be_active is True:
        assert is_cuda_active()  # Make sure it is properly activated
Пример #8
0
def check_input(var, length):
    if isinstance(var, tuple):
        assert len(var) is length
        var = list(var)
    elif not isinstance(var, np.ndarray):
        var = np.array(
            tuple([var for _ in range(length)]), dtype=np.int32)
    elif not var.dtype == np.int32:
        var = var.astype(np.int32)
    if length < 2 and is_cuda_active():
        length = 2
    assert len(var) is length, str(len(var)) + '/' + str(length)
    return var
Пример #9
0
def test_spatial_dropout(node, seed, use_gpu):
    use_gpu = use_gpu and is_cuda_active()
    node = Variable(node)
    set_cuda_active(use_gpu)

    layer = SpatialDropout()

    def func(node):
        if use_gpu:
            curand_generator().set_seed(seed)
        else:
            np.random.seed(seed)
        return sum(layer(node))
    compare(func, node, node)
Пример #10
0
    def update_node(self, node, opt=None):
        import time
        if node.prevent_update:
            return

        with self.unlock_node(node):
            dy = self.get(node) if opt is None else opt(self.get(node), node)
            if node._auto_update:
                if callable(node.auto_update):
                    node.auto_update(dy)
                else:
                    if is_cuda_active():
                        ngpu = get_gpu(node)
                        ngpu -= get_gpu(dy)
                    else:
                        node[...] -= dy
            node.detach_graph()
Пример #11
0
def test_convnd(node, error, use_gpu, ignore_bias):
    node = Variable(node)
    assert_cuda_active(use_gpu)
    layer = ConvNd(channel=1, filter=3, stride=1)  # , ignore_bias=ignore_bias)

    def func(node):
        return sum(layer(node))
    if error and is_cuda_active():
        # CuDNN can manage tensor dim < 6.
        try:
            func(node)
            assert False
        except:
            pass
    else:
        compare(func, node, node)
        compare(func, layer.params["w"], node)
        try:
            compare(func, layer.params["b"], node)
        except Exception:
            assert ignore_bias
Пример #12
0
    def _get_cpu(self, dy, node):
        node_id = id(node)
        pdy = self._params.get(node_id, None)
        nth = 0
        if pdy is None:
            b = self._b
            g = self._g
            u = (1 - self._b) * dy
            r = (1 - self._g) * (dy**2)
        else:
            u = pdy["u"]
            r = pdy["r"]
            b = pdy["beta"]
            g = pdy["gamma"]
            nth = pdy["nth"]

            if nth % self.CHECK_ZERO_VALUE == 0:
                if not is_cuda_active():
                    min_flug = np.where(np.abs(u) < self._min, True, False)
                    min_flug = np.where(np.abs(r) < self._min, True, False)
                    u.setflags(write=True)
                    r.setflags(write=True)
                    u[min_flug] = 0
                    r[min_flug] = 0
            u = self._b * u + (1 - self._b) * dy
            r = self._g * r + (1 - self._g) * (dy * dy)

        self._params[node_id] = {
            "beta": b * self._b,
            "gamma": g * self._g,
            "u": u,
            "r": r,
            "nth": nth + 1
        }

        ret = self._lr * u / (sqrt(r / (1 - g)) + self._epsilon) / (1 - b)
        if isinstance(ret, Node):
            ret.detach_graph()
        return ret
Пример #13
0
    def train(self, train_distributor, test_distributor=None):
        """Train method.
        This method executes train loop.
        If test_distributor is given, validation loss will be calculated.

        Args:
            train_distributor (Distributor): Distributor for yielding train data.
            test_distributor (Distributor): Distributor for yielding test data.
        """

        self.epoch = 0
        self.train_distributor = train_distributor
        self.test_distributor = test_distributor
        self.on_event('start')
        self.train_loss_list = []
        self.test_loss_list = []

        models = [self.model]
        if self.num_gpu > 1:
            models.extend(
                [self.model.__class__() for _ in range(self.num_gpu - 1)])
            for n in range(self.num_gpu):
                models[n].set_gpu(n)

        while self.epoch < self.num_epoch:
            self.on_event('start_epoch')
            self.nth = 0
            self.avg_train_loss = 0

            for iteration, (data, target) in enumerate(
                    self.train_distributor.batch(self.batch_size,
                                                 self.shuffle)):
                datalen = len(data) // len(models)
                self.data = [
                    data[i:i + datalen]
                    for i in range(0, datalen * len(models), datalen)
                ]
                if is_cuda_active():
                    self.data = [Node(d) for d in self.data]
                    for n, d in enumerate(self.data):
                        with use_device(n):
                            d.to_gpu()

                targetlen = len(target) // len(models)
                self.targets = [
                    target[i:i + targetlen]
                    for i in range(0, targetlen * len(models), targetlen)
                ]
                if is_cuda_active():
                    self.targets = [Node(d) for d in self.targets]
                    for n, d in enumerate(self.targets):
                        with use_device(n):
                            d.to_gpu()

                for gpu in range(1, self.num_gpu):
                    models[gpu].copy_params(models[0])

                for gpu in range(0, self.num_gpu):
                    models[gpu].set_models(inference=False)

                self.on_event('forward')
                self.outputs = []

                for gpu in range(self.num_gpu):
                    model = models[gpu]
                    with model.train():
                        self.outputs.append(model(self.data[gpu]))

                self.on_event('loss')
                self.losses = []

                for gpu in range(self.num_gpu):
                    model = models[gpu]
                    with use_device(gpu):
                        self.losses.append(
                            self.loss_func(self.outputs[gpu],
                                           self.targets[gpu]))

                self.avg_train_loss += (self.losses[0] -
                                        self.avg_train_loss) / (iteration + 1)

                self.on_event('backward')
                self.grads = []

                for gpu in range(self.num_gpu):
                    model = models[gpu]
                    with use_device(gpu):
                        self.grads.append(self.losses[gpu].grad())

                self.on_event('grad')

                if self.num_gpu > 1:
                    models[0].join_grads(self.grads[0],
                                         zip(models[1:], self.grads[1:]))

                self.grads[0].update(self.optimizer)

                self.on_event('updated')
                self.nth += 1

            self.on_event('end_epoch')
            self.epoch += 1

            # release objects
            self.data = self.target = None
            self.outputs = self.losses = self.grads = None
            self.avg_train_loss = None
Пример #14
0
 def __call__(self, x):
     dims = len(x.shape[2:])
     if is_cuda_active():
         assert dims == 3, "Pool 3D expects 3 dimensions"
     super(Pool3Base, self).__call__(x)
Пример #15
0
 def func(node):
     if is_cuda_active():
         curand_generator().set_seed(seed)
     else:
         np.random.seed(seed)
     return sum(layer(node))
Пример #16
0
 def __call__(self, *args, **kwargs):
     if is_cuda_active():
         return self._get_gpu(*args, **kwargs)
     else:
         return self._get_cpu(*args, **kwargs)
Пример #17
0
    def fit(self, train_img_path_list, train_annotation_list,
            valid_img_path_list=None, valid_annotation_list=None,
            epoch=160, batch_size=16, imsize_list=None, augmentation=None, callback_end_epoch=None):
        """
        This function performs training with given data and hyper parameters.
        Yolov2 is trained using multiple scale images. Therefore, this function
        requires list of image size. If it is not given, the model will be trained
        using fixed image size.

        Args:
            train_img_path_list(list): List of image path.
            train_annotation_list(list): List of annotations.
            valid_img_path_list(list): List of image path for validation.
            valid_annotation_list(list): List of annotations for validation.
            epoch(int): Number of training epoch.
            batch_size(int): Number of batch size.
            imsize_list(list): List of image size.
            augmentation(Augmentation): Augmentation object.
            callback_end_epoch(function): Given function will be called at the end of each epoch.

        Returns:
            (tuple): Training loss list and validation loss list.

        Example:
            >>> from renom_img.api.detection.yolo_v2 import Yolov2
            >>> train_img_path_list, train_annot_list = ... # Define own data.
            >>> valid_img_path_list, valid_annot_list = ...
            >>> model = Yolov2()
            >>> model.fit(
            ...     # Feeds image and annotation data.
            ...     train_img_path_list,
            ...     train_annot_list,
            ...     valid_img_path_list,
            ...     valid_annot_list,
            ...     epoch=8,
            ...     batch_size=8)
            >>>

        Following arguments will be given to the function ``callback_end_epoch``.

        - **epoch** (int) - Number of current epoch.
        - **model** (Model) - Yolo2 object.
        - **avg_train_loss_list** (list) - List of average train loss of each epoch.
        - **avg_valid_loss_list** (list) - List of average valid loss of each epoch.

        """

        if imsize_list is None:
            imsize_list = [self.imsize]
        else:
            for ims in imsize_list:
                assert (ims[0] / 32.) % 1 == 0 and (ims[1] / 32.) % 1 == 0, \
                    "Yolo v2 only accepts 'imsize' argument which is list of multiple of 32. \
                    exp),imsize=[(288, 288), (320, 320)]."

        train_dist = ImageDistributor(
            train_img_path_list, train_annotation_list, augmentation=augmentation, num_worker=8)
        if valid_img_path_list is not None and valid_annotation_list is not None:
            valid_dist = ImageDistributor(valid_img_path_list, valid_annotation_list)
        else:
            valid_dist = None

        batch_loop = int(np.ceil(len(train_dist) / batch_size))
        avg_train_loss_list = []
        avg_valid_loss_list = []

        for e in range(epoch):
            bar = tqdm(range(batch_loop))
            display_loss = 0
            for i, (train_x, train_y) in enumerate(train_dist.batch(batch_size, shuffle=True, target_builder=self.build_data(imsize_list))):
                # This is for avoiding memory over flow.
                if is_cuda_active() and i % 10 == 0:
                    release_mem_pool()
                self.set_models(inference=False)
                with self.train():
                    loss = self.loss(self(train_x), train_y)
                    reg_loss = loss + self.regularize()
                reg_loss.grad().update(self.get_optimizer(loss.as_ndarray(), e, epoch, i, batch_loop))

                try:
                    loss = float(loss.as_ndarray()[0])
                except:
                    loss = float(loss.as_ndarray())
                display_loss += loss
                bar.set_description("Epoch:{:03d} Train Loss:{:5.3f}".format(e, loss))
                bar.update(1)
            avg_train_loss = display_loss / (i + 1)
            avg_train_loss_list.append(avg_train_loss)

            if valid_dist is not None:
                if is_cuda_active():
                    release_mem_pool()
                bar.n = 0
                bar.total = int(np.ceil(len(valid_dist) / batch_size))
                display_loss = 0
                for i, (valid_x, valid_y) in enumerate(valid_dist.batch(batch_size, shuffle=False, target_builder=self.build_data())):
                    self.set_models(inference=True)
                    loss = self.loss(self(valid_x), valid_y)

                    try:
                        loss = float(loss.as_ndarray()[0])
                    except:
                        loss = float(loss.as_ndarray())
                    display_loss += loss
                    bar.set_description("Epoch:{:03d} Valid Loss:{:5.3f}".format(e, loss))
                    bar.update(1)
                avg_valid_loss = display_loss / (i + 1)
                avg_valid_loss_list.append(avg_valid_loss)
                bar.set_description("Epoch:{:03d} Avg Train Loss:{:5.3f} Avg Valid Loss:{:5.3f}".format(
                    e, avg_train_loss, avg_valid_loss))
            else:
                bar.set_description("Epoch:{:03d} Avg Train Loss:{:5.3f}".format(e, avg_train_loss))
            bar.close()
            if callback_end_epoch is not None:
                callback_end_epoch(e, self, avg_train_loss_list, avg_valid_loss_list)
        return avg_train_loss_list, avg_valid_loss_list