如何編寫3d CNN的PyTorch教程
首先,我們需要簡單解釋一下什麼是3d CNN,以及它與通用2d CNN的區別。然後,我們將逐步分析如何使用Pytorch實現3D卷積神經網絡。
什麼是3D卷積神經網絡?
無論我們說的CNN與2d CNN非常相似,都保留3d CNN。區別在於以下幾點(非詳盡列表):
3d卷積層
最初2d卷積層是輸入與不同過濾器之間的逐項乘法運算,其中過濾器和輸入是2d矩陣
在3d卷積層中,使用相同的操作。我們對多對二維矩陣進行這些操作。
填充選項和幻燈片步驟選項的工作方式相同。
3d MaxPool圖層
2d Maxpool圖層(2x2濾鏡)大約要取一個我們從輸入中劃定的2x2小正方形的最大元素。
現在,在3d Maxpool(2x2x2)中,我們在寬度為2的立方體中查找最大元素。此多維數據集表示從輸入以2x2x2區域分隔的空間。
請注意,運算數量(與2d CNN層相比)乘以使用的過濾器的大小(與Maxpool或卷積無關),也乘以輸入本身的大小。
3d數據點看起來如何?
那麼3D CNN的數據點看起來如何?
生動描述圖片的一種方法是使用以下圖片:
可用於CNN的其他現有數據集包括:
- RGB-D設備:Google Tango,Microsoft Kinect等。
- 激光雷達
- 從多個圖像進行3D重建
現在如何實施?
可以自己嘗試使用我們正在使用的 Kaggle在該數據集上的代碼。
整個筆記本中將使用多個庫。這是它的列表。
<code># importing the libraries import pandas as pd import numpy as np from tqdm import tqdm import os # for reading and displaying images from skimage.io import imread import matplotlib.pyplot as plt # for creating validation set from sklearn.model_selection import train_test_split # for evaluating the model from sklearn.metrics import accuracy_score # PyTorch libraries and modules import torch from torch.autograd import Variable import torch.nn as nn import torch.nn.functional as F from torch.optim import * import h5py from plot3D import */<code>
首先,由於數據集是特定的,因此在將它們提供給網絡之前,我們使用以下幫助函數來處理它們。
另外,數據集存儲為h5文件,因此要提取實際數據點,我們需要從h5文件讀取數據,並使用to_categorical函數將其轉換為向量。在此步驟中,我們還準備進行交叉驗證。
<code>def array_to_color(array, cmap="Oranges"): s_m = plt.cm.ScalarMappable(cmap=cmap) return s_m.to_rgba(array)[:,:-1] def rgb_data_transform(data): data_t = [] for i in range(data.shape[0]): data_t.append(array_to_color(data[i]).reshape(16, 16, 16, 3)) return np.asarray(data_t, dtype=np.float32)/<code>
假設變量X_train / X_test分別具有(10000,16,16,16,3)和(2000,16,16,16,3)的形狀,而target_train / targets_test分別具有(10000,)(2000,)的形狀。但是現在我們再次將所有這些轉換為PyTorch張量格式。我們通過以下方式做到這一點。
<code>with h5py.File("./full_dataset_vectors.h5", "r") as hf: # Split the data into training/test features/targets X_train = hf["X_train"][:] targets_train = hf["y_train"][:] X_test = hf["X_test"][:] targets_test = hf["y_test"][:] # Determine sample shape sample_shape = (16, 16, 16, 3) # Reshape data into 3D format X_train = rgb_data_transform(X_train) X_test = rgb_data_transform(X_test) # Convert target vectors to categorical targets targets_train = to_categorical(targets_train).astype(np.integer) targets_test = to_categorical(targets_test).astype(np.integer)/<code>
<code>train_x = torch.from_numpy(X_train).float() train_y = torch.from_numpy(targets_train).long() test_x = torch.from_numpy(X_test).float() test_y = torch.from_numpy(targets_test).long() batch_size = 100 #We pick beforehand a batch_size that we will use for the training # Pytorch train and test sets train = torch.utils.data.TensorDataset(train_x,train_y) test = torch.utils.data.TensorDataset(test_x,test_y) # data loader train_loader = torch.utils.data.DataLoader(train, batch_size = batch_size, shuffle = False) test_loader = torch.utils.data.DataLoader(test, batch_size = batch_size, shuffle = False)/<code>
對於模型,這裡是我們將使用的架構:
2套ConvMake:
· 兩個集合的過濾器大小為(3x3x3),步幅為(1x1x1)的3d卷積層
· 洩漏的Relu激活功能
· 具有濾鏡大小(2x2x2)和跨度(2x2x2)的3d MaxPool層
2個FC層,分別具有512和128個節點。
在第一個FC層之後有一個Dropout層。
然後將模型通過以下方式轉換為代碼:
<code>num_classes = 10 # Create CNN Model class CNNModel(nn.Module): def __init__(self): super(CNNModel, self).__init__() self.conv_layer1 = self._conv_layer_set(3, 32) self.conv_layer2 = self._conv_layer_set(32, 64) self.fc1 = nn.Linear(2**3*64, 128) self.fc2 = nn.Linear(128, num_classes) self.relu = nn.LeakyReLU() self.batch=nn.BatchNorm1d(128) self.drop=nn.Dropout(p=0.15) def _conv_layer_set(self, in_c, out_c): conv_layer = nn.Sequential( nn.Conv3d(in_c, out_c, kernel_size=(3, 3, 3), padding=0), nn.LeakyReLU(), nn.MaxPool3d((2, 2, 2)), ) return conv_layer def forward(self, x): # Set 1 out = self.conv_layer1(x) out = self.conv_layer2(out) out = out.view(out.size(0), -1) out = self.fc1(out) out = self.relu(out) out = self.batch(out) out = self.drop(out) out = self.fc2(out) return out #Definition of hyperparameters n_iters = 4500 num_epochs = n_iters / (len(train_x) / batch_size) num_epochs = int(num_epochs) # Create CNN model = CNNModel() #model.cuda() print(model) # Cross Entropy Loss error = nn.CrossEntropyLoss() # SGD Optimizer learning_rate = 0.001 optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)/<code>
在參數方面,請注意第一個完全卷積層上的輸入節點數。我們的數據集的形狀為(16,16,16,3),這就是我們獲得大小為(2x2x2)的濾波輸出的方式。
以下是訓練代碼。可以通過將優化器更改為Adam來進行優化,調整學習速度(有一定的動力)等等。
<code># CNN model training count = 0 loss_list = [] iteration_list = [] accuracy_list = [] for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): train = Variable(images.view(100,3,16,16,16)) labels = Variable(labels) # Clear gradients optimizer.zero_grad() # Forward propagation outputs = model(train) # Calculate softmax and ross entropy loss loss = error(outputs, labels) # Calculating gradients loss.backward() # Update parameters optimizer.step() count += 1 if count % 50 == 0: # Calculate Accuracy correct = 0 total = 0 # Iterate through test dataset for images, labels in test_loader: test = Variable(images.view(100,3,16,16,16)) # Forward propagation outputs = model(test) # Get predictions from the maximum value predicted = torch.max(outputs.data, 1)[1] # Total number of labels total += len(labels) correct += (predicted == labels).sum() accuracy = 100 * correct / float(total) # store loss and iteration loss_list.append(loss.data) iteration_list.append(count) accuracy_list.append(accuracy) if count % 500 == 0: # Print Loss print('Iteration: {} Loss: {} Accuracy: {} %'.format(count, loss.data, accuracy))/<code>
經過少量樣本培訓,我們得到了以下準確性和損失。
3D CNN的應用場景
- IRM數據處理及其推斷
- 自動駕駛
- 距離估算