示例#1
0
    def __init__(self,
                 filters,
                 shape,
                 kernel_size,
                 stride=1,
                 name=None,
                 initializer=Normal(loc=0, scale=0.01)):
        super(Conv2D, self).__init__(shape=shape, name=name)
        self.initializer = initializer
        self.trainable = True

        assert len(shape) == 3  # (image_height, image_width, num_channels)
        self.input_size = shape

        assert len(kernel_size) == 2  # (kernel_height, kernel_width)
        self.kernel_size = kernel_size

        self.nb_filters = filters
        self.stride = stride  # TODO: not used

        self.weights = self.initializer(
            (self.nb_filters, self.input_size[-1], self.kernel_size[0],
             self.kernel_size[1]))
        self.bias = Zeros()(self.nb_filters)

        self.weights_grad = Zeros()(shape=self.weights.shape)
        self.bias_grad = Zeros()(shape=self.bias.shape)
示例#2
0
    def forward(self, x):
        self.last_input = x

        assert len(
            x.shape) == 4  # (batch, channels, image_height, image_width)

        nb_batches = x.shape[0]
        img_height, img_width = x.shape[1:3]

        output_height = (img_height - self.kernel_size[0]) // self.stride + 1
        output_width = (img_width - self.kernel_size[1]) // self.stride + 1

        output = Zeros()(shape=(nb_batches, output_height, output_width,
                                self.nb_filters))

        kernel_height, kernel_width = self.kernel_size

        for batch in np.arange(nb_batches):
            for filter in np.arange(self.nb_filters):
                for h in np.arange(img_height - kernel_height):
                    for w in np.arange(img_width - kernel_width):
                        patch = x[batch, h:h + kernel_height,
                                  w:w + kernel_width, :]
                        output[batch, h, w,
                               filter] = np.sum(patch * self.weights[filter] +
                                                self.bias[filter])

        return output
示例#3
0
    def backward(self, prev_delta):
        kernel_height, kernel_width = self.kernel_size
        nb_batch, input_img_height, input_img_width, nb_input_channels = self.last_input.shape

        for filter in np.arange(self.nb_filters):
            for input_channel in np.arange(nb_input_channels):
                for h in np.arange(kernel_height):
                    for w in np.arange(kernel_width):
                        patch = self.last_input[:, h:h + input_img_height -
                                                kernel_height + 1,
                                                w:w + input_img_width -
                                                kernel_width + 1,
                                                input_channel]
                        grad_window = prev_delta[..., filter]
                        self.weights_grad[filter, input_channel, h,
                                          w] = np.sum(
                                              patch * grad_window) / nb_batch

        for filter in np.arange(self.nb_filters):
            self.bias_grad[filter] = np.sum(prev_delta[..., filter]) / nb_batch

        kernel_grads = Zeros()(shape=self.last_input.shape)
        for batch in np.arange(nb_batch):
            for filter in np.arange(self.nb_filters):
                for input_channel in np.arange(nb_input_channels):
                    for h in np.arange(input_img_height - kernel_height):
                        for w in np.arange(input_img_width - kernel_width):
                            kernel_grads[
                                batch, h:h + kernel_height, w:w + kernel_width,
                                input_channel] += self.weights[
                                    filter, input_channel] * prev_delta[batch,
                                                                        h, w,
                                                                        filter]
        return kernel_grads
示例#4
0
    def __init__(self, num_in, num_out, w_init=XavierUniform(),
                 b_init=Zeros()):
        super().__init__('Dense')

        self.params = {
            "w": w_init([num_in, num_out]),
            "b": b_init([1, num_out])
        }

        self.inputs = None
示例#5
0
    def __init__(self,
                 shape,
                 name=None,
                 initializer=Normal(loc=0, scale=0.01)):
        super(Dense, self).__init__(shape=shape, name=name)
        self.initializer = initializer
        self.trainable = True

        self.weights = self.initializer(shape)
        self.bias = Zeros()(self.weights.shape[-1])

        self.weights_grad = None
        self.bias_grad = None
示例#6
0
    def __init__(self,
                 num_out,
                 num_in=None,
                 w_init=XavierUniform(),
                 b_init=Zeros()):
        super().__init__("Linear")
        self.initializers = {"w": w_init, "b": b_init}
        self.shapes = {"w": [num_in, num_out], "b": [num_out]}
        self.params = {"w": None, "b": None}

        self.is_init = False
        if num_in is not None:
            self._init_parameters(num_in)

        self.inputs = None
示例#7
0
    def backward(self, prev_delta):

        nb_batch, input_img_height, input_img_width, nb_input_channels = self.last_input.shape
        pool_height, pool_width = self.shape

        grads = Zeros()(self.last_input.shape)

        for batch in np.arange(nb_batch):
            for channel in np.arange(nb_input_channels):
                for h in np.arange(input_img_height, step=pool_height):
                    for w in np.arange(input_img_width, step=pool_width):
                        patch = self.last_input[batch, h:h + pool_height,
                                                w:w + pool_width, channel]
                        if patch.sum() <= 0.:
                            continue
                        h_shift, w_shift = np.unravel_index(
                            patch.argmax(), patch.shape)
                        grads[batch, h + h_shift, w + w_shift,
                              channel] = prev_delta[batch, h // pool_height,
                                                    w // pool_width, channel]
        return grads
示例#8
0
    def forward(self, x):
        self.last_input = x

        nb_batch, input_img_height, input_img_width, nb_input_channels = self.last_input.shape

        pool_height, pool_width = self.shape
        output_height = input_img_height // pool_height
        output_width = input_img_width // pool_width

        output = Zeros()(
            (nb_batch, output_height, output_width, nb_input_channels))

        for batch in np.arange(nb_batch):
            for channel in np.arange(nb_input_channels):
                for h in np.arange(input_img_height, step=pool_height):
                    for w in np.arange(input_img_width, step=pool_width):
                        output[batch, h // pool_height, w // pool_width,
                               channel] = np.max(x[batch, h:h + pool_height,
                                                   w:w + pool_width, channel])

        return output
示例#9
0
    def __init__(self,
                 kernel,
                 stride=(1, 1),
                 padding="SAME",
                 w_init=XavierUniform(),
                 b_init=Zeros()):
        super().__init__("Conv2D")

        # verify arguments
        assert len(kernel) == 4
        assert len(stride) == 2
        assert padding in ("SAME", "VALID")

        self.kernel_shape = kernel
        self.stride = stride
        self.initializers = {"w": w_init, "b": b_init}

        # calculate padding needed for this layer
        self.pad = self._get_padding(kernel[:2], padding)

        self.is_init = False