"""第 15 章：二维滑动点积、池化与残差；只用标准库。"""


def correlate(image, kernel, stride=1):
    height, width = len(image), len(image[0])
    kh, kw = len(kernel), len(kernel[0])
    return [[sum(image[row+i][col+j]*kernel[i][j]
                 for i in range(kh) for j in range(kw))
             for col in range(0, width-kw+1, stride)]
            for row in range(0, height-kh+1, stride)]


def max_pool(image, size=2, stride=2):
    return [[max(image[row+i][col+j] for i in range(size) for j in range(size))
             for col in range(0, len(image[0])-size+1, stride)]
            for row in range(0, len(image)-size+1, stride)]


def example():
    image = [[0, 0, 1, 1, 1] for _ in range(5)]
    kernel = [[-1, 0, 1] for _ in range(3)]
    return image, kernel, correlate(image, kernel)


def main():
    image, kernel, output = example()
    print("原图的卷积输出：")
    for row in output:
        print(row)
    shifted = [[0] + row[:-1] for row in image]
    print("右移一格后，输出第一行：" + str(correlate(shifted, kernel)[0]))
    print("2×2 最大池化：" + str(max_pool(output)))
    values = [-2, 1]
    print("残差 x+ReLU(x)：" + str([x+max(0, x) for x in values]))
    print(f"1 个输入通道、2 个输出通道、3×3 核的参数数：{2*(1*3*3+1)}")


if __name__ == "__main__":
    main()
