-
神經網絡 卷積操作
例子:
輸入:二維圖像
[1,2,0,3,1]
[0,1,2,3,1]
[1,2,1,0,0]
[5,2,3,1,1]
[2,1,0,1,1]
卷積核:
[1,2,1]
[0,1,0]
[2,1,0]
然后需要將輸入圖像和卷積核轉化為4維張量
為什么轉為4維張量?因為卷積操作需要輸入圖像和卷積核的維度相同,所以需要將其轉化為相同的維度。
(插入 channel:彩色圖像就是rgb為3 灰度圖像就是1)
下面進行二維卷積操作:
-
步長為1 就是每次移動一步
stride = 1
-
步長為2 就是每次移動兩步
-
填充為1
padding = 1
達到填充后的輸出和輸入的大小相同 都是5x5
為了充分學習邊緣信息 提取邊緣特征
-
上述輸出
code:
import torch import torch.nn.functional as F#原始輸入圖像 input = torch.tensor([[1,2,0,3,1],[0,1,2,3,1],[1,2,1,0,0],[5,2,3,1,1],[2,1,0,1,1]]) #卷積核 kernel = torch.tensor([[1,2,1],[0,1,0],[2,1,0]]) #將輸入圖像和卷積核轉化為4維張量 reshape(batch_size, channel, height, width) #為什么轉為4維張量?因為卷積操作需要輸入圖像和卷積核的維度相同,所以需要將其轉化為相同的維度 input = torch.reshape(input,(1,1,5,5)) kernel = torch.reshape(kernel,(1,1,3,3))#二維卷積 #stride=1 表示步長為1 output = F.conv2d(input,kernel,stride=1) print(output)#步長為2 output = F.conv2d(input,kernel,stride=2) print(output)#填充為1 #填充后輸出的大小和輸入相同 #就是卷積的時候在原輸入的周圍補0 上下左右補0 #padding 也是為了充分利用邊緣信息 提取邊緣特征 output = F.conv2d(input,kernel,stride=1,padding=1) print(output)
-
-
神經網絡 卷積層
作用:提取特征
流程:
-
選取數據集
這里我用的是自定義的數據集 還是放一下目錄結構
數據集在images下 注意DataLoader加載數據集需要的目錄結構是datasets/classes 需要注意下
-
數據預處理
主要是使用transforms工具箱
這里我先統一大小
轉成Tensor格式
標準化
#數據預處理 transform = transforms.Compose([transforms.Resize((224,224)),transforms.ToTensor(),transforms.Normalize(mean = [0.5,0.5,0.5],std = [0.5,0.5,0.5]) ])
-
加載數據集
ImageFloder()的時候應用transform
batch_size是指一次取出多少圖片來處理(2的倍數)
folder_path = '../images' dataset = ImageFolder(folder_path,transform=transform) dataloader = DataLoader(dataset,batch_size=1)
-
構建卷積層
這里的in_channels為3(彩色圖片)out_channels為6(說明應該是應用了兩個卷積核去卷積操作 會產生兩個輸出 所以最后的output的數量是input的兩倍)kernel_size=3 卷積核設置的3x3的
然后前向傳播 輸出結果
class convNet(nn.Module):def __init__(self):#調用父類nn.Module的構造函數super(convNet,self).__init__()self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)def forward(self,x):x = self.conv1(x)return xconvnet = convNet()
-
使用tensorboard觀察結果
日志存在logs文件夾下
writer = SummaryWriter('../logs') ... ... ... writer.close()
writer.add_images('input',img,cnt)writer.add_images('output',output,cnt)
-
開始遍歷處理加載的圖片(見后面完整代碼中)
output = torch.reshape(output,(-1,3,222,222))
這一個操作是因為output的通道數是6 運行會報錯 這里就給他強制性轉換一下shape
輸入通道數變成幾不知道 就填寫-1
(222,222)這個是怎么得到的?
print(output.shape)得到的
-
tensorboard結果:
tensorboard --logdir=../logs
(我數據集中就放了一張圖片哈哈哈哈哈 大家能夠認出是誰嗎)
(笑死我了 這里是變形的小蘇蘇)
-
完整代碼
code:
import torch import torchvision from torch import nn from torch.nn import Conv2d from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter from torchvision.datasets import ImageFolder from torchvision import transforms#數據預處理 transform = transforms.Compose([transforms.Resize((224,224)),transforms.ToTensor(),transforms.Normalize(mean = [0.5,0.5,0.5],std = [0.5,0.5,0.5]) ])#加載數據集 folder_path = '../images' dataset = ImageFolder(folder_path,transform=transform) dataloader = DataLoader(dataset,batch_size=1)class convNet(nn.Module):def __init__(self):#調用父類nn.Module的構造函數super(convNet,self).__init__()self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)def forward(self,x):x = self.conv1(x)return xconvnet = convNet()writer = SummaryWriter('../logs')cnt = 0 for data in dataloader:img,label = dataprint(img.shape)output = convnet(img)print(output.shape)writer.add_images('input',img,cnt)output = torch.reshape(output,(-1,3,222,222))writer.add_images('output',output,cnt)cnt = cnt + 1writer.close()
-