Python小練習:創建卷積層

Python小練習:創建卷積層

作者:凱魯嘎吉 - 博客園 http://www.cnblogs.com/kailugaji/

使用Pytorch中的nn.Conv2d函數來創建卷積層,構建卷積神經網絡(僅含卷積層與激活函數)。

1. cnn_test.py

 1 # -*- coding: utf-8 -*-
 2 # Author:凱魯嘎吉 Coral Gajic
 3 # https://www.cnblogs.com/kailugaji/
 4 # Python小練習:創建卷積層
 5 import torch
 6 import torch.nn as nn
 7 import numpy as np
 8 import os
 9 import imageio
10 from PIL import Image
11 import torchvision.transforms as transforms
12 import matplotlib.pyplot as plt
13 from pylab import *
14 from warnings import simplefilter
15 simplefilter(action="ignore",category=UserWarning)
16 
17 # 構建卷積神經網絡(僅用到卷積層)
18 def build_CNN(input_size):
19     module_list = []
20     last_h = input_size[2]
21     last_w = input_size[3]
22     cnn_kernels = [[input_size[1], 256, 4],
23                    [256, 128, 3, 2, 1, 1],
24                    [128, 64, 3, 2, 1, 1],
25                    [64, 32, 3, 2, 1, 1],
26                    [32, 3, 5, 2, 2, 1]]
27     # 除了輸入層,後面有5層,5個激活函數
28     # 6個參數的含義:
29     # 1. in_channels (int) – 輸入圖像中的通道數
30     # 2. out_channels (int) – 卷積產生的通道數即輸出圖片的通道數
31     # 3. kernel_size (int or tuple) – 卷積核的大小(可以是個數,也可以是元組)
32     # 4. stride (int or tuple, optional) — 卷積的步幅。 默認值:1
33     # 5. padding (int, tuple or str, optional) – 填充添加到輸入的所有四個邊。 默認值:0
34     # 6. dilation (int or tuple, optional) – 內核元素之間的間距。 默認值:1。
35     act_func = [nn.LeakyReLU(), nn.Tanh(), nn.ReLU(), nn.ELU(), nn.CELU()] # 激活函數
36     default = [None, None, None, 1, 0] # in_c, out_c, kernel, stride, pad
37     for i, ck in enumerate(cnn_kernels):
38         # i: 0, 1, 2, 3, 4 ...
39         ck = ck + default[len(ck):]
40         last_h = int((last_h + 2 * ck[4] - ck[2]) / ck[3] + 1) #(h+2*pad-k)/stride+1
41         last_w = int((last_w + 2 * ck[4] - ck[2]) / ck[3] + 1)
42         module_list.append(nn.Conv2d(*ck))
43         module_list.append(act_func[i])
44     output_shape = (cnn_kernels[-1][1], last_h, last_w)
45     return nn.Sequential(*module_list), output_shape
46 
47 # 使用方法
48 # 圖像例子:
49 path = "./img" # 打開存放圖像的文件夾
50 dirs = os.listdir(path) # ['1.jpg', '2.jpg', '3.jpg']
51 len_dir = len(dirs) # len_dir張圖片
52 outs = []
53 count = 0
54 fig = plt.figure(figsize=(24, 6)) # 畫布佈局
55 for i in dirs:
56     image_pad = imageio.imread(os.path.join(path, i))  # i: 'xxx.jpg'
57     image_pad = Image.fromarray(image_pad).resize((600, 300))  # 重新調整圖像尺寸
58     transf = transforms.ToTensor()  # 將原始數據形式(圖像)轉換成tensor
59     outs.append(transf(image_pad)) # tensor數據格式是torch(C,H,W)
60     plt.subplot(2, len_dir, count+1) # 2行,len_dir列,第count+1個子圖
61     plt.axis('off')
62     plt.imshow(image_pad)
63     count += 1
64 outs= torch.tensor([np.array(item) for item in outs]) # 將list轉換爲tensor
65 model, output_shape = build_CNN(outs.shape)
66 # N, C, H, W = outs.shape # 樣本個數5, 通道數3, 高300, 寬600
67 print('網絡結構:\n', model)
68 print('單個樣本的輸出維度:', output_shape)
69 print('輸入數據維度:', outs.shape)
70 y = model(outs) # 實例化
71 print('實際輸出維度:', y.shape)
72 for i in range(outs.shape[0]): # 展示結果
73     toPIL = transforms.ToPILImage()
74     pic = toPIL(y[i])
75     plt.subplot(2, len_dir, int(i + 1 + outs.shape[0]))
76     plt.imshow(pic)
77     plt.axis('off')
78 plt.savefig('CNN_fig.png', bbox_inches='tight', pad_inches=0.0, dpi=500)
79 plt.show()
80 print('-------------------------------------------------')
81 # 隨機數據例子:
82 input_size = [10, 3, 84, 84]
83 # 10張圖片,3通道,每張圖片長*寬爲84*84
84 model, output_shape = build_CNN(input_size)
85 x = torch.randn(input_size)
86 print('輸入數據維度:', x.shape)
87 y = model(x)
88 print('實際輸出維度:', y.shape)

2. 結果

D:\ProgramData\Anaconda3\python.exe "D:/Python code/2023.3 exercise/Neural Network/cnn_test.py"
網絡結構:
 Sequential(
  (0): Conv2d(3, 256, kernel_size=(4, 4), stride=(1, 1))
  (1): LeakyReLU(negative_slope=0.01)
  (2): Conv2d(256, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
  (3): Tanh()
  (4): Conv2d(128, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
  (5): ReLU()
  (6): Conv2d(64, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
  (7): ELU(alpha=1.0)
  (8): Conv2d(32, 3, kernel_size=(5, 5), stride=(2, 2), padding=(2, 2))
  (9): CELU(alpha=1.0)
)
單個樣本的輸出維度: (3, 19, 38)
輸入數據維度: torch.Size([5, 3, 300, 600])
實際輸出維度: torch.Size([5, 3, 19, 38])
-------------------------------------------------
輸入數據維度: torch.Size([10, 3, 84, 84])
實際輸出維度: torch.Size([10, 3, 6, 6])

Process finished with exit code 0

完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章