池化层前向传播 参数说明: X:输入数组,形状为 (n_samp, in_rows, in_cols, in_ch) retain_derived:是否保留中间变量,以便反向传播时再次使用,bool型 输出说明: Y:输出结果,形状为 (n_samp, out_rows, out_cols, out_ch)
(self, X, retain_derived=True)
| 631 | self.is_initialized = True |
| 632 | |
| 633 | def forward(self, X, retain_derived=True): |
| 634 | """ |
| 635 | 池化层前向传播 |
| 636 | |
| 637 | 参数说明: |
| 638 | X:输入数组,形状为 (n_samp, in_rows, in_cols, in_ch) |
| 639 | retain_derived:是否保留中间变量,以便反向传播时再次使用,bool型 |
| 640 | |
| 641 | 输出说明: |
| 642 | Y:输出结果,形状为 (n_samp, out_rows, out_cols, out_ch) |
| 643 | """ |
| 644 | if not self.is_initialized: |
| 645 | self.in_ch = self.out_ch = X.shape[3] |
| 646 | self._init_params() |
| 647 | |
| 648 | n_samp, in_rows, in_cols, nc_in = X.shape |
| 649 | (fr, fc), s, p = self.kernel_shape, self.stride, self.pad |
| 650 | X_pad, (pr1, pr2, pc1, pc2) = pad2D(X, p, self.kernel_shape, s) |
| 651 | |
| 652 | out_rows = int((in_rows + pr1 + pr2 - fr) / s + 1) |
| 653 | out_cols = int((in_cols + pc1 + pc2 - fc) / s + 1) |
| 654 | |
| 655 | if self.mode == "max": |
| 656 | pool_fn = np.max |
| 657 | elif self.mode == "average": |
| 658 | pool_fn = np.mean |
| 659 | |
| 660 | Y = np.zeros((n_samp, out_rows, out_cols, self.out_ch)) |
| 661 | for m in range(n_samp): |
| 662 | for i in range(out_rows): |
| 663 | for j in range(out_cols): |
| 664 | for c in range(self.out_ch): |
| 665 | i0, i1 = i * s, (i * s) + fr |
| 666 | j0, j1 = j * s, (j * s) + fc |
| 667 | |
| 668 | xi = X_pad[m, i0:i1, j0:j1, c] |
| 669 | Y[m, i, j, c] = pool_fn(xi) |
| 670 | |
| 671 | if retain_derived: |
| 672 | self.X.append(X) |
| 673 | self.derived_variables["out_rows"].append(out_rows) |
| 674 | self.derived_variables["out_cols"].append(out_cols) |
| 675 | |
| 676 | return Y |
| 677 | |
| 678 | def backward(self, dLdy, retain_grads=True): |
| 679 | """ |
nothing calls this directly
no test coverage detected