A faster (but more memory intensive) implementation of the 2D "convolution" (technically, cross-correlation) of input `X` with a collection of kernels in `W`. Notes ----- Relies on the :func:`im2col` function to perform the convolution as a single matrix multiplication.
(X, W, stride, pad, dilation=0)
| 601 | |
| 602 | |
| 603 | def conv2D(X, W, stride, pad, dilation=0): |
| 604 | """ |
| 605 | A faster (but more memory intensive) implementation of the 2D "convolution" |
| 606 | (technically, cross-correlation) of input `X` with a collection of kernels in |
| 607 | `W`. |
| 608 | |
| 609 | Notes |
| 610 | ----- |
| 611 | Relies on the :func:`im2col` function to perform the convolution as a single |
| 612 | matrix multiplication. |
| 613 | |
| 614 | For a helpful diagram, see Pete Warden's 2015 blogpost [1]. |
| 615 | |
| 616 | References |
| 617 | ---------- |
| 618 | .. [1] Warden (2015). "Why GEMM is at the heart of deep learning," |
| 619 | https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/ |
| 620 | |
| 621 | Parameters |
| 622 | ---------- |
| 623 | X : :py:class:`ndarray <numpy.ndarray>` of shape `(n_ex, in_rows, in_cols, in_ch)` |
| 624 | Input volume (unpadded). |
| 625 | W: :py:class:`ndarray <numpy.ndarray>` of shape `(kernel_rows, kernel_cols, in_ch, out_ch)` |
| 626 | A volume of convolution weights/kernels for a given layer. |
| 627 | stride : int |
| 628 | The stride of each convolution kernel. |
| 629 | pad : tuple, int, or 'same' |
| 630 | The padding amount. If 'same', add padding to ensure that the output of |
| 631 | a 2D convolution with a kernel of `kernel_shape` and stride `stride` |
| 632 | produces an output volume of the same dimensions as the input. If |
| 633 | 2-tuple, specifies the number of padding rows and colums to add *on both |
| 634 | sides* of the rows/columns in `X`. If 4-tuple, specifies the number of |
| 635 | rows/columns to add to the top, bottom, left, and right of the input |
| 636 | volume. |
| 637 | dilation : int |
| 638 | Number of pixels inserted between kernel elements. Default is 0. |
| 639 | |
| 640 | Returns |
| 641 | ------- |
| 642 | Z : :py:class:`ndarray <numpy.ndarray>` of shape `(n_ex, out_rows, out_cols, out_ch)` |
| 643 | The covolution of `X` with `W`. |
| 644 | """ |
| 645 | s, d = stride, dilation |
| 646 | _, p = pad2D(X, pad, W.shape[:2], s, dilation=dilation) |
| 647 | |
| 648 | pr1, pr2, pc1, pc2 = p |
| 649 | fr, fc, in_ch, out_ch = W.shape |
| 650 | n_ex, in_rows, in_cols, in_ch = X.shape |
| 651 | |
| 652 | # update effective filter shape based on dilation factor |
| 653 | _fr, _fc = fr * (d + 1) - d, fc * (d + 1) - d |
| 654 | |
| 655 | # compute the dimensions of the convolution output |
| 656 | out_rows = int((in_rows + pr1 + pr2 - _fr) / s + 1) |
| 657 | out_cols = int((in_cols + pc1 + pc2 - _fc) / s + 1) |
| 658 | |
| 659 | # convert X and W into the appropriate 2D matrices and take their product |
| 660 | X_col, _ = im2col(X, W.shape, p, s, d) |