# codes06001_cross_correlation
import paddle
def cross_correlation(X, W):
h, w = W.shape
Y = paddle.zeros((X.shape[0]-h+1, X.shape[1]-w+1))
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
Y[i, j] = (X[i:i+h, j:j+w]*W).sum()
return Y
X = paddle.to_tensor([[1.0,2.0,3.0,4.0], [5.0,6.0,7.0,8.0], [9.0,10.0,11.0,12.0]])
W = paddle.to_tensor([[1.0,2.0], [3.0,4.0]])
cross_correlation(X, W)
Tensor(shape=[2, 3], dtype=float32, place=Place(gpu:0), stop_gradient=True, [[44. , 54. , 64. ], [84. , 94. , 104.]])
import sys
sys.path.append(r'D:\WorkSpace\DeepLearning\WebsiteV2') # 定义自定义模块保存位置
from codes.paddle import common
import paddle
# codes06002_Conv2D
class Conv2D(paddle.nn.Layer):
def __init__(self, kernel_size):
super().__init__()
self.weight = paddle.ParamAttr(paddle.rand(kernel_size))
self.bias = paddle.ParamAttr(paddle.zeros(1))
def forward(self, x):
Y = common.cross_correlation(x, self.weight) + self.bias
return Y
import paddle
# 生成9×9的垂直条纹图
X = paddle.ones((9, 9))
X[:, 3:6] = 0
print(X) # 输出图像矩阵
Tensor(shape=[9, 9], dtype=float32, place=Place(gpu:0), stop_gradient=True, [[1., 1., 1., 0., 0., 0., 1., 1., 1.], [1., 1., 1., 0., 0., 0., 1., 1., 1.], [1., 1., 1., 0., 0., 0., 1., 1., 1.], [1., 1., 1., 0., 0., 0., 1., 1., 1.], [1., 1., 1., 0., 0., 0., 1., 1., 1.], [1., 1., 1., 0., 0., 0., 1., 1., 1.], [1., 1., 1., 0., 0., 0., 1., 1., 1.], [1., 1., 1., 0., 0., 0., 1., 1., 1.], [1., 1., 1., 0., 0., 0., 1., 1., 1.]])
import matplotlib.pylab as plt
plt.figure(figsize=(3,3))
plt.imshow(X, cmap=plt.cm.gray)
<matplotlib.image.AxesImage at 0x25824331fd0>
# 3×3的垂直边缘检测器
W1 = paddle.to_tensor([[1,0,-1], [1,0,-1], [1,0,-1]])
# 2×2的垂直边缘检测器
W2 = paddle.to_tensor([[1,-1], [1,-1]])
# 2×2的水平边缘检测器
W3 = paddle.to_tensor([[1,1], [-1,-1]])
# 使用3×3垂直边缘检测器获得的边缘
Y1 = common.cross_correlation(X, W1)
# 使用2×2垂直边缘检测器获得的边缘
Y2 = common.cross_correlation(X, W2)
# 使用2×2水平边缘检测器获得垂直条纹图
Y3 = common.cross_correlation(X, W3)
print('{} \n {} \n {}'.format(Y1, Y2, Y3))
Tensor(shape=[7, 7], dtype=float32, place=Place(gpu:0), stop_gradient=True, [[ 0., 3., 3., 0., -3., -3., 0.], [ 0., 3., 3., 0., -3., -3., 0.], [ 0., 3., 3., 0., -3., -3., 0.], [ 0., 3., 3., 0., -3., -3., 0.], [ 0., 3., 3., 0., -3., -3., 0.], [ 0., 3., 3., 0., -3., -3., 0.], [ 0., 3., 3., 0., -3., -3., 0.]]) Tensor(shape=[8, 8], dtype=float32, place=Place(gpu:0), stop_gradient=True, [[ 0., 0., 2., 0., 0., -2., 0., 0.], [ 0., 0., 2., 0., 0., -2., 0., 0.], [ 0., 0., 2., 0., 0., -2., 0., 0.], [ 0., 0., 2., 0., 0., -2., 0., 0.], [ 0., 0., 2., 0., 0., -2., 0., 0.], [ 0., 0., 2., 0., 0., -2., 0., 0.], [ 0., 0., 2., 0., 0., -2., 0., 0.], [ 0., 0., 2., 0., 0., -2., 0., 0.]]) Tensor(shape=[8, 8], dtype=float32, place=Place(gpu:0), stop_gradient=True, [[0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.]])
plt.figure(figsize=(24,6))
ax = plt.subplot(1,4,1)
plt.imshow(X, cmap=plt.cm.gray)
ax.set_title('Original Image', fontsize=20)
ax = plt.subplot(1,4,2)
plt.imshow(Y1)
ax.set_title('Y1: 3×3 Vertical Edge Detector', fontsize=20)
ax = plt.subplot(1,4,3)
plt.imshow(Y2)
ax.set_title('Y2: 2×2 Vertical Edge Detector', fontsize=20)
ax = plt.subplot(1,4,4)
plt.imshow(Y3)
ax.set_title('Y3: 2×2 Horizontal Edge Detector', fontsize=20)
Text(0.5, 1.0, 'Y3: 2×2 Horizontal Edge Detector')
# 使用2×2垂直边缘检测器检测垂直条纹图
Y3 = common.cross_correlation(X.T, W2)
# 使用2×2水平边缘检测器获得垂直条纹图
Y4 = common.cross_correlation(X.T, W3)
print('{} \n {}'.format(Y3, Y4))
Tensor(shape=[8, 8], dtype=float32, place=Place(gpu:0), stop_gradient=True, [[0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.]]) Tensor(shape=[8, 8], dtype=float32, place=Place(gpu:0), stop_gradient=True, [[ 0., 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0., 0.], [ 2., 2., 2., 2., 2., 2., 2., 2.], [ 0., 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0., 0.], [-2., -2., -2., -2., -2., -2., -2., -2.], [ 0., 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0., 0.]])
# codes06007_EdgeDetection_LearnKernel
# 调用Paddle工具包,构造一个二维卷积层,它包含一个的形状为[3,3]的卷积核
conv2d = paddle.nn.Conv2D(1, 1, kernel_size=(3, 3))
w_start = conv2d.weight.reshape((3,3)).numpy()
# 卷积层使用四维张量进行输入和输出(批量大小、通道、高度、宽度)
# 其中批量大小和通道数都为1
X = X.reshape((1, 1, 9, 9)) # 输入
Y = Y1.reshape((1, 1, 7, 7)) # 输出
lr = 4e-3 # 学习率
for i in range(100):
Y_hat = conv2d(X)
l = (Y_hat - Y) ** 2
conv2d.clear_gradients()
l.sum().backward()
with paddle.no_grad(): # 迭代卷积核
conv2d.weight[:] -= lr * conv2d.weight.grad
if (i + 1) % 10 == 0:
print(f'epoch {i+1}, loss {l.sum().item():.5f}')
epoch 10, loss 0.90101 epoch 20, loss 0.07812 epoch 30, loss 0.00799 epoch 40, loss 0.00082 epoch 50, loss 0.00008 epoch 60, loss 0.00001 epoch 70, loss 0.00000 epoch 80, loss 0.00000 epoch 90, loss 0.00000 epoch 100, loss 0.00000
w_learned = conv2d.weight.reshape((3,3))
print('W_GT={} \n w_start={} \n w_end={}'.format(W1.numpy(), w_start, w_learned.numpy()))
W_GT=[[ 1 0 -1] [ 1 0 -1] [ 1 0 -1]] w_start=[[ 0.3962333 -0.48529047 -0.05017222] [ 0.35991043 0.00333536 0.31979078] [ 0.44011578 0.1082949 0.48617285]] w_end=[[ 0.997482 -0.36074042 -1.302101 ] [ 0.961159 0.12788537 -0.9321376 ] [ 1.0413648 0.23284493 -0.7657556 ]]
import cv2
import matplotlib.pyplot as plt
image = cv2.imread('../../Images/Materials/chapter04Datasets/chapter04008AugmentationExampleRIO.jpg', 0)
image = cv2.resize(image, (200,100))
img = paddle.to_tensor(image, dtype='float32')
out_hand_crafted = common.cross_correlation(img, W1)
out_learned = common.cross_correlation(img, conv2d.weight.reshape((3,3)))
plt.figure(figsize=(18,6))
ax = plt.subplot(1,3,1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
ax.set_title('Original Image', fontsize=18)
ax = plt.subplot(1,3,2)
plt.imshow(out_hand_crafted)
ax.set_title('The Hand-crafted Kernel', fontsize=18)
ax = plt.subplot(1,3,3)
plt.imshow(out_learned)
ax.set_title('The Learned Kernel', fontsize=18)
Text(0.5, 1.0, 'The Learned Kernel')