Пример #1
0
    def output_shape(self):
        pad_height, pad_width = get_pad(self.padding, self.input_shape[1],
                                        self.input_shape[2], self.strides[0],
                                        self.strides[1], self.kernel_size[0],
                                        self.kernel_size[1])

        # alternate formula: [((W - KernelW + 2P) / Sw) + 1] and [((H - KernelH + 2P) / Sh) + 1]
        # output_height = ((self.input_shape[1] - self.kernel_size[0] + np.sum(pad_height)) / self.strides[0]) + 1
        # output_width = ((self.input_shape[2] - self.kernel_size[1] + np.sum(pad_width)) / self.strides[1]) + 1

        if self.padding == 'same':
            output_height = np.ceil(
                np.float32(self.input_shape[1]) / np.float32(self.strides[0]))
            output_width = np.ceil(
                np.float32(self.input_shape[2]) / np.float32(self.strides[1]))

        if self.padding == 'valid':
            output_height = np.ceil(
                np.float32(self.input_shape[1] - self.kernel_size[0] + 1) /
                np.float32(self.strides[0]))
            output_width = np.ceil(
                np.float32(self.input_shape[2] - self.kernel_size[1] + 1) /
                np.float32(self.strides[1]))

        return self.filters, int(output_height), int(output_width)
Пример #2
0
    def output_shape(self):
        input_channels, input_height, input_width = self.input_shape

        self.pad_height, self.pad_width = get_pad(self.padding, input_height,
                                                  input_width, self.strides[0],
                                                  self.strides[1],
                                                  self.pool_size[0],
                                                  self.pool_size[1])

        # alternate formula: [((W - PoolW + 2P) / Sw) + 1] and [((H - PoolH + 2P) / Sh) + 1]
        # out_height = ((input_height - self.pool_size[0] + np.sum(self.pad_height)) / self.strides[0]) + 1
        # out_width = ((input_width - self.pool_size[1] + np.sum(self.pad_width)) / self.strides[1]) + 1

        if self.padding == 'same':
            out_height = np.ceil(
                np.float32(input_height) / np.float32(self.strides[0]))
            out_width = np.ceil(
                np.float32(input_width) / np.float32(self.strides[1]))

        if self.padding == 'valid':
            out_height = np.ceil(
                np.float32(input_height - self.pool_size[0] + 1) /
                np.float32(self.strides[0]))
            out_width = np.ceil(
                np.float32(input_width - self.pool_size[1] + 1) /
                np.float32(self.strides[1]))

        assert out_height % 1 == 0
        assert out_width % 1 == 0

        return input_channels, int(out_height), int(out_width)
Пример #3
0
    def pass_forward(self, inputs, train_mode=True, **kwargs):
        self.filter_num, _, _, _ = self.weights.shape
        input_num, input_depth, input_height, input_width = inputs.shape
        self.input_shape = inputs.shape
        self.inputs = inputs

        pad_height, pad_width = get_pad(self.padding, input_height,
                                        input_width, self.strides[0],
                                        self.strides[1], self.kernel_size[0],
                                        self.kernel_size[1])

        x_padded = np.pad(self.inputs, ((0, 0), (0, 0), pad_height, pad_width),
                          mode='constant')

        # confirm dimensions
        assert (input_height + np.sum(pad_height) - self.kernel_size[0]
                ) % self.strides[0] == 0, 'height does not work'
        assert (input_width + np.sum(pad_width) - self.kernel_size[1]
                ) % self.strides[1] == 0, 'width does not work'

        # alternate formula: [((W - KernelW + 2P) / Sw) + 1] and [((H - KernelH + 2P) / Sh) + 1]
        # output_height = (input_height - self.kernel_size[0] + np.sum(pad_height)) / self.strides[0] + 1
        # output_width = (input_width - self.kernel_size[1] + np.sum(pad_width)) / self.strides[1] + 1

        if self.padding == 'same':
            output_height = np.ceil(
                np.float32(input_height) / np.float32(self.strides[0]))
            output_width = np.ceil(
                np.float32(input_width) / np.float32(self.strides[1]))

        if self.padding == 'valid':
            output_height = np.ceil(
                np.float32(input_height - self.kernel_size[0] + 1) /
                np.float32(self.strides[0]))
            output_width = np.ceil(
                np.float32(input_width - self.kernel_size[1] + 1) /
                np.float32(self.strides[1]))

        output = np.zeros(
            (input_num, self.filter_num, output_height, output_width))

        # convolutions
        for b in np.arange(input_num):  # batch number
            for f in np.arange(self.filter_num):  # filter number
                for h in np.arange(output_height):  # output height
                    for w in np.arange(output_width):  # output width
                        h_stride, w_stride = h * self.strides[
                            0], w * self.strides[1]
                        x_patch = x_padded[b, :, h_stride:h_stride +
                                           self.kernel_size[0],
                                           w_stride:w_stride +
                                           self.kernel_size[1]]
                        output[b, f, h, w] = np.sum(
                            x_patch * self.weights[f]) + self.bias[f]

        return output
Пример #4
0
    def output_shape(self):
        pad_height, pad_width = get_pad(self.padding, self.input_shape[1],
                                        self.input_shape[2], self.strides[0],
                                        self.strides[1], self.kernel_size[0],
                                        self.kernel_size[1])

        output_height, output_width = get_output_dims(self.input_shape[1],
                                                      self.input_shape[2],
                                                      self.kernel_size,
                                                      self.strides,
                                                      self.padding)

        return self.filters, int(output_height), int(output_width)
Пример #5
0
    def pass_forward(self, inputs, train_mode=True, **kwargs):
        self.filter_num, _, _, _ = self.weights.shape
        input_num, input_depth, input_height, input_width = inputs.shape
        self.input_shape = inputs.shape
        self.inputs = inputs

        pad_height, pad_width = get_pad(self.padding, input_height,
                                        input_width, self.strides[0],
                                        self.strides[1], self.kernel_size[0],
                                        self.kernel_size[1])

        # confirm dimensions
        assert (input_height + np.sum(pad_height) - self.kernel_size[0]
                ) % self.strides[0] == 0, 'height does not work'
        assert (input_width + np.sum(pad_width) - self.kernel_size[1]
                ) % self.strides[1] == 0, 'width does not work'

        # alternate formula: [((W - KernelW + 2P) / Sw) + 1] and [((H - KernelH + 2P) / Sh) + 1]
        # output_height = ((input_height - self.kernel_size[0] + np.sum(pad_height)) / self.strides[0]) + 1
        # output_width = ((input_width - self.kernel_size[1] + np.sum(pad_width)) / self.strides[1]) + 1

        if self.padding == 'same':
            output_height = np.ceil(
                np.float32(input_height) / np.float32(self.strides[0]))
            output_width = np.ceil(
                np.float32(input_width) / np.float32(self.strides[1]))

        if self.padding == 'valid':
            output_height = np.ceil(
                np.float32(input_height - self.kernel_size[0] + 1) /
                np.float32(self.strides[0]))
            output_width = np.ceil(
                np.float32(input_width - self.kernel_size[1] + 1) /
                np.float32(self.strides[1]))

        # convert to columns
        self.input_col = im2col_indices(inputs,
                                        self.kernel_size[0],
                                        self.kernel_size[1],
                                        padding=(pad_height, pad_width),
                                        stride=1)

        self.weight_col = self.weights.reshape(self.filter_num, -1)

        # calculate ouput
        output = self.weight_col @ self.input_col + self.bias
        output = output.reshape(self.filter_num, int(output_height),
                                int(output_width), input_num)

        return output.transpose(3, 0, 1, 2)
Пример #6
0
    def pass_forward(self, inputs, train_mode=True, **kwargs):
        self.filter_num, _, _, _ = self.weights.shape
        self.input_shape = inputs.shape
        self.inputs = inputs

        input_num, input_depth, input_height, input_width = inputs.shape

        pad_height, pad_width = get_pad(self.padding, input_height,
                                        input_width, self.strides[0],
                                        self.strides[1], self.kernel_size[0],
                                        self.kernel_size[1])

        x_padded = np.pad(self.inputs, ((0, 0), (0, 0), pad_height, pad_width),
                          mode='constant')

        # confirm dimensions
        assert (input_height + np.sum(pad_height) - self.kernel_size[0]
                ) % self.strides[0] == 0, 'height does not work'
        assert (input_width + np.sum(pad_width) - self.kernel_size[1]
                ) % self.strides[1] == 0, 'width does not work'

        # compute output_height and output_width
        output_height, output_width = get_output_dims(input_height,
                                                      input_width,
                                                      self.kernel_size,
                                                      self.strides,
                                                      self.padding)

        output = np.zeros(
            (input_num, self.filter_num, output_height, output_width))

        self.input_col = unroll_inputs(x_padded, x_padded.shape[0],
                                       x_padded.shape[1], output_height,
                                       output_width, self.kernel_size[0])

        # TODO: weights need to be rearraged in a way to have a matrix
        #       multiplication with the generated toeplitz matrix
        self.weight_col = self.weights.reshape(self.filter_num, -1)

        # calculate ouput
        output = self.weight_col @ self.input_col + self.bias
        # output = np.matmul(self.weight_col, self.input_col) + self.bias
        output = output.reshape(self.filter_num, int(output_height),
                                int(output_width), input_num)

        return output.transpose(3, 0, 1, 2)
Пример #7
0
    def pass_forward(self, inputs, train_mode=True, **kwargs):
        self.filter_num, _, _, _ = self.weights.shape
        self.input_shape = inputs.shape
        self.inputs = inputs

        input_num, input_depth, input_height, input_width = inputs.shape

        pad_height, pad_width = get_pad(self.padding, input_height,
                                        input_width, self.strides[0],
                                        self.strides[1], self.kernel_size[0],
                                        self.kernel_size[1])

        x_padded = np.pad(self.inputs, ((0, 0), (0, 0), pad_height, pad_width),
                          mode='constant')

        # confirm dimensions
        assert (input_height + np.sum(pad_height) - self.kernel_size[0]
                ) % self.strides[0] == 0, 'height does not work'
        assert (input_width + np.sum(pad_width) - self.kernel_size[1]
                ) % self.strides[1] == 0, 'width does not work'

        # compute output_height and output_width
        output_height, output_width = get_output_dims(input_height,
                                                      input_width,
                                                      self.kernel_size,
                                                      self.strides,
                                                      self.padding)

        output = np.zeros(
            (input_num, self.filter_num, output_height, output_width))

        # convolutions
        for b in np.arange(input_num):  # batch number
            for f in np.arange(self.filter_num):  # filter number
                for h in np.arange(output_height):  # output height
                    for w in np.arange(output_width):  # output width
                        h_stride, w_stride = h * self.strides[
                            0], w * self.strides[1]
                        x_patch = x_padded[b, :, h_stride:h_stride +
                                           self.kernel_size[0],
                                           w_stride:w_stride +
                                           self.kernel_size[1]]
                        output[b, f, h, w] = np.sum(
                            x_patch * self.weights[f]) + self.bias[f]

        return output
Пример #8
0
    def output_shape(self):
        input_channels, input_height, input_width = self.input_shape

        self.pad_height, self.pad_width = get_pad(self.padding, input_height,
                                                  input_width, self.strides[0],
                                                  self.strides[1],
                                                  self.pool_size[0],
                                                  self.pool_size[1])

        output_height, output_width = get_output_dims(input_height,
                                                      input_width,
                                                      self.pool_size,
                                                      self.strides,
                                                      self.padding)

        assert output_height % 1 == 0
        assert output_width % 1 == 0

        return input_channels, int(output_height), int(output_width)
Пример #9
0
    def pass_forward(self, inputs, train_mode=True, **kwargs):
        self.filter_num, _, _, _ = self.weights.shape
        self.input_shape = inputs.shape
        self.inputs = inputs

        input_num, input_depth, input_height, input_width = inputs.shape

        pad_height, pad_width = get_pad(self.padding, input_height,
                                        input_width, self.strides[0],
                                        self.strides[1], self.kernel_size[0],
                                        self.kernel_size[1])

        # confirm dimensions
        assert (input_height + np.sum(pad_height) - self.kernel_size[0]
                ) % self.strides[0] == 0, 'height does not work'
        assert (input_width + np.sum(pad_width) - self.kernel_size[1]
                ) % self.strides[1] == 0, 'width does not work'

        # compute output_height and output_width
        output_height, output_width = get_output_dims(input_height,
                                                      input_width,
                                                      self.kernel_size,
                                                      self.strides,
                                                      self.padding)

        # convert to columns
        self.input_col = im2col_indices(inputs,
                                        self.kernel_size[0],
                                        self.kernel_size[1],
                                        padding=(pad_height, pad_width),
                                        stride=1)

        self.weight_col = self.weights.reshape(self.filter_num, -1)

        # calculate ouput
        output = self.weight_col @ self.input_col + self.bias
        output = output.reshape(self.filter_num, int(output_height),
                                int(output_width), input_num)

        return output.transpose(3, 0, 1, 2)
Пример #10
0
    def pass_backward(self, grad):
        input_num, input_depth, input_height, input_width = self.input_shape

        if self.is_trainable:

            dbias = np.sum(grad, axis=(0, 2, 3))
            dbias = dbias.reshape(self.filter_num, -1)

            doutput_reshaped = grad.transpose(1, 2, 3,
                                              0).reshape(self.filter_num, -1)

            dweights = doutput_reshaped @ self.input_col.T
            dweights = dweights.reshape(self.weights.shape)

            # optimize the weights and bias
            self.weights = optimizer(self.weight_optimizer).update(
                self.weights, dweights)
            self.bias = optimizer(self.weight_optimizer).update(
                self.bias, dbias)

        # endif self.is_trainable

        weight_reshape = self.weights.reshape(self.filter_num, -1)
        dinput_col = weight_reshape.T @ doutput_reshaped

        pad_height, pad_width = get_pad(self.padding, input_height,
                                        input_width, self.strides[0],
                                        self.strides[1], self.kernel_size[0],
                                        self.kernel_size[1])

        dinputs = col2im_indices(dinput_col,
                                 self.input_shape,
                                 self.kernel_size[0],
                                 self.kernel_size[1],
                                 padding=(pad_height, pad_width),
                                 stride=self.strides[0])

        return dinputs
Пример #11
0
    def pass_backward(self, grad):
        input_num, input_depth, input_height, input_width = self.inputs.shape

        # initialize the gradient(s)
        dinputs = np.zeros(self.inputs.shape)

        if self.is_trainable:

            # initialize the gradient(s)
            dweights = np.zeros(self.weights.shape)
            dbias = np.zeros(self.bias.shape)

            pad_height, pad_width = get_pad(self.padding, input_height,
                                            input_width, self.strides[0],
                                            self.strides[1],
                                            self.kernel_size[0],
                                            self.kernel_size[1])

            pad_size = np.sum(pad_height) / 2
            if pad_size != 0:
                grad = grad[:, :, pad_size:-pad_size, pad_size:-pad_size]

            # dweights
            for f in np.arange(self.filter_num):  # filter number
                for c in np.arange(input_depth):  # input depth (channels)
                    for h in np.arange(self.kernel_size[0]):  # kernel height
                        for w in np.arange(
                                self.kernel_size[1]):  # kernel width
                            input_patch = self.inputs[:, c, h:input_height -
                                                      self.kernel_size[0] + h +
                                                      1:self.strides[0],
                                                      w:input_width -
                                                      self.kernel_size[1] + w +
                                                      1:self.strides[1]]
                            grad_patch = grad[:, f]
                            dweights[f, c, h, w] = np.sum(
                                input_patch * grad_patch) / input_num

            # dbias
            for f in np.arange(self.filter_num):  # filter number
                dbias[f] = np.sum(grad[:, f]) / input_num

            # optimize the weights and bias
            self.weights = optimizer(self.weight_optimizer).update(
                self.weights, dweights)
            self.bias = optimizer(self.weight_optimizer).update(
                self.bias, dbias)

        # endif self.is_trainable

        # dinputs
        for b in np.arange(input_num):  # batch number
            for f in np.arange(self.filter_num):  # filter number
                for c in np.arange(input_depth):  # input depth (channels)
                    for h in np.arange(self.kernel_size[0]):  # kernel height
                        for w in np.arange(
                                self.kernel_size[1]):  # kernel width
                            h_stride, w_stride = h * self.strides[
                                0], w * self.strides[1]
                            dinputs[b, c,
                                    h_stride:h_stride + self.kernel_size[0],
                                    w_stride:w_stride +
                                    self.kernel_size[1]] += self.weights[
                                        f, c] * grad[b, f, h, w]

        return dinputs