导入
CNN 构成模块
了解最常用的CNN构建模块。
...
树莓派电路板底部
...
5x5卷积核
1import torch 2import cv2 3 4weight = torch.zeros(1, 3, 5, 5) # (N_kernels, N_channels, W, H) 5bias = torch.zeros(1) 6weight[0, 0, :, 0: 2] = 90 # 左侧绿色通道条带 7weight[0, 1, :, 0: 2] = 120 8weight[0, 2, :, 0: 2] = 35 9weight[0, 0, :, 2:] = 75 # 右侧黄色通道条带 10weight[0, 1, :, 2:] = 160 11weight[0, 2, :, 2:] = 160 12 13cv2.imwrite("./output/0_kernel_weight.png", cv2.resize(torch.moveaxis(weight.squeeze(0), 0, 2).int().numpy(), dsize=(300, 300), interpolation=cv2.INTER_NEAREST)) 14# 标准化权重 15weight = (weight - torch.mean(weight))/torch.std(weight) 16bias[0] = 0.
1# ... 续上 2# 使用设计好的权重和偏置创建一个二维卷积层 3conv = torch.nn.Conv2d(3, 1, kernel_size=(5, 5), padding='same') 4# 张量必须包装为 torch.nn.Parameter 对象 5conv.weight = torch.nn.Parameter(weight) 6conv.bias = torch.nn.Parameter(bias) 7 8# 加载图像 9original_img = cv2.imread("./images/electronics/rpi_back.jpg") 10cv2.imwrite("./output/1_original.png", original_img) 11 12# 将图像转换为张量 13input_tsr = torch.from_numpy(original_img).float()/255.0 # (H, W, C) 14input_tsr = torch.moveaxis(input_tsr, 2, 0) # (C, H, W) 15 16# 在输入张量上执行卷积运算 17convolution_tsr = conv(input_tsr) 18 19# 保存卷积结果图像 20convolution_img = convolution_tsr.squeeze(0).detach().numpy() # (H, W) 21cv2.imwrite("./output/2_convolution.png", 127 + 10 * convolution_img)
...
原始图像的一部分(左)与对应的卷积结果图像(右)
1import torch 2 3input_tsr = torch.randn(1, 6, 2, 2) # (N, C, H, W) 4print(f"input_tsr = {input_tsr}") 5dropout2d = torch.nn.Dropout2d(p=0.5) # p 表示将被丢弃的通道比例 6print(f"dropout2d.training = {dropout2d.training}") 7output_tsr = dropout2d(input_tsr) # 将输入张量传入 Dropout2d 层 8print(f"output_tsr = {output_tsr}")
1import torch 2 3input_tsr = torch.randn(1, 6, 2, 2) # (N, C, H, W) 4print(f"input_tsr = {input_tsr}") 5dropout2d = torch.nn.Dropout2d(p=0.5) 6dropout2d.training = False 7output_tsr = dropout2d(input_tsr) 8print(f"output_tsr = {output_tsr}")
1import torch 2 3input_tsr = torch.randn(3, 1, 2, 2) 4print(f"input_tsr = {input_tsr}") 5batch_norm = torch.nn.BatchNorm2d(num_features=1) # num_features 是输入张量的通道数 6output_tsr = batch_norm(input_tsr) 7print(f"output_tsr = {output_tsr}")
1import torch 2 3input_tsr = torch.randn(1, 1, 4, 4) 4print(f"input_tsr = \n{input_tsr}") 5maxpool2d = torch.nn.MaxPool2d(kernel_size=(2, 2)) 6output_tsr = maxpool2d(input_tsr) 7print(f"output_tsr = \n{output_tsr}")
1import torch 2 3input_tsr = torch.randn(3, 1, 2, 2) 4print(f"input_tsr = {input_tsr}") 5print(f"input_tsr.shape = {input_tsr.shape}") 6output_tsr = input_tsr.view(-1, 1 * 2 * 2) # 第一个参数为 -1 时, 7 # 输出维度会自动调整以保持元素总数不变 8print(f"output_tsr = {output_tsr}") 9print(f"output_tsr.shape = {output_tsr.shape}")