第3次作业-卷积神经网络
第三次作業:卷積神經網絡基礎
文章目錄
- 第三次作業:卷積神經網絡基礎
- 一、要求:
- 二、`Part1` 視頻學習
- 以下是在視頻學習后,根據所學繪制的思維導圖,其大致涵蓋了本次學習卷積神經網絡的所得。
- 三、`Part2` 代碼練習
- 1.MNIST 數據集分類:構建簡單的CNN對 mnist 數據集進行分類。同時,還會在實驗中學習池化與卷積操作的基本作用。
- (1)加載數據 (MNIST)
- (2)創建網絡
- (3)在小型全連接網絡上訓練(Fully-connected network)
- (4)在卷積神經網絡上訓練
- (5)打亂像素順序再次在兩個網絡上訓練與測試
- 2.CIFAR10 數據集分類:使用 CNN 對 CIFAR10 數據集進行分類
- (1)加載并歸一化 CIFAR10 使用 torchvision
- (2)展示 CIFAR10 里面的一些圖片
- (3)定義網絡,損失函數和優化器
- (4)從測試集中取出8張圖片,檢測CNN識圖的能力
- (5)測試驗證準確率
- 3.使用 VGG16 對 CIFAR10 分類
- (1)定義 dataloader
- (2)VGG 網絡定義
- (3)網絡訓練
- (4)測試驗證準確率
- (5)運行結果:
- ①找到`cfg`所在的位置:
- ②報錯信息變為
- ③出現新的錯誤
- 四、思考的問題:
- 1、dataloader 里面 shuffle 取不同值有什么區別?
- 2、transform 里,取了不同值,這個有什么區別?
- 3、epoch 和 batch 的區別?
- 4、1x1的卷積和 FC 有什么區別?主要起什么作用?
- 5、residual leanring 為什么能夠提升準確率?
- 6、代碼練習二里,網絡和1989年 Lecun 提出的 LeNet 有什么區別?
- 7、代碼練習二里,卷積以后feature map 尺寸會變小,如何應用 Residual Learning?
- 8、有什么方法可以進一步提升準確率?
一、要求:
Part1 視頻學習:學習專知課程《卷積神經網絡》,主要內容包括:
- CNN的基本結構:卷積、池化、全連接
- 典型的網絡結構:AlexNet、VGG、GoogleNet、ResNet
Part2 代碼練習:需要使用谷歌的 Colab ,大家有任何問題可以隨時在群里 AT 我。有部分同學已經做過這部分代碼練習,可以略過。
- MNIST 數據集分類:構建簡單的CNN對 mnist 數據集進行分類。同時,還會在實驗中學習池化與卷積操作的基本作用。鏈接:https://github.com/OUCTheoryGroup/colab_demo/blob/master/05_01_ConvNet.ipynb
- CIFAR10 數據集分類:使用 CNN 對 CIFAR10 數據集進行分類,鏈接:https://github.com/OUCTheoryGroup/colab_demo/blob/master/05_02_CNN_CIFAR10.ipynb
- 使用 VGG16對 CIFAR10分類,鏈接:https://github.com/OUCTheoryGroup/colab_demo/blob/master/05_03_VGG_CIFAR10.ipynb
本周需要各個小組寫一個學習博客,并回答下面的問題,博客鏈接在下面提交任務即可,時間截止為本周六(10月15日22:00)
本周寫博客需要思考的問題:
1、dataloader 里面 shuffle 取不同值有什么區別?
2、transform 里,取了不同值,這個有什么區別?
3、epoch 和 batch 的區別?
4、1x1的卷積和 FC 有什么區別?主要起什么作用?
5、residual leanring 為什么能夠提升準確率?
6、代碼練習二里,網絡和1989年 Lecun 提出的 LeNet 有什么區別?
7、代碼練習二里,卷積以后feature map 尺寸會變小,如何應用 Residual Learning?
8、有什么方法可以進一步提升準確率?
二、Part1 視頻學習
以下是在視頻學習后,根據所學繪制的思維導圖,其大致涵蓋了本次學習卷積神經網絡的所得。
三、Part2 代碼練習
1.MNIST 數據集分類:構建簡單的CNN對 mnist 數據集進行分類。同時,還會在實驗中學習池化與卷積操作的基本作用。
學習資料:https://github.com/OUCTheoryGroup/colab_demo/blob/master/05_01_ConvNet.ipynb
深度卷積神經網絡中,有如下特性
- 很多層: compositionality
- 卷積: locality + stationarity of images
- 池化: Invariance of object class to translations
(1)加載數據 (MNIST)
PyTorch里包含了 MNIST, CIFAR10 等常用數據集,調用 torchvision.datasets 即可把這些數據由遠程下載到本地,下面給出MNIST的使用方法:
torchvision.datasets.MNIST(root, train=True, transform=None, target_transform=None, download=False)
- root 為數據集下載到本地后的根目錄,包括 training.pt 和 test.pt 文件
- train,如果設置為True,從training.pt創建數據集,否則從test.pt創建。
- download,如果設置為True, 從互聯網下載數據并放到root文件夾下
- transform, 一種函數或變換,輸入PIL圖片,返回變換之后的數據。
- target_transform 一種函數或變換,輸入目標,進行變換。
另外值得注意的是,DataLoader是一個比較重要的類,提供的常用操作有:batch_size(每個batch的大小), shuffle(是否進行隨機打亂順序的操作), num_workers(加載數據的時候使用幾個子進程)
input_size = 28*28 # MNIST上的圖像尺寸是 28x28 output_size = 10 # 類別為 0 到 9 的數字,因此為十類train_loader = torch.utils.data.DataLoader(datasets.MNIST('./data', train=True, download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))])),batch_size=64, shuffle=True)test_loader = torch.utils.data.DataLoader(datasets.MNIST('./data', train=False, transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))])),batch_size=1000, shuffle=True)顯示數據集中的部分圖像
plt.figure(figsize=(8, 5)) for i in range(20):plt.subplot(4, 5, i + 1)image, _ = train_loader.dataset.__getitem__(i)plt.imshow(image.squeeze().numpy(),'gray')plt.axis('off');(2)創建網絡
定義網絡時,需要繼承nn.Module,并實現它的forward方法,把網絡中具有可學習參數的層放在構造函數init中。
只要在nn.Module的子類中定義了forward函數,backward函數就會自動被實現(利用autograd)。
class FC2Layer(nn.Module):def __init__(self, input_size, n_hidden, output_size):# nn.Module子類的函數必須在構造函數中執行父類的構造函數# 下式等價于nn.Module.__init__(self) super(FC2Layer, self).__init__()self.input_size = input_size# 這里直接用 Sequential 就定義了網絡,注意要和下面 CNN 的代碼區分開self.network = nn.Sequential(nn.Linear(input_size, n_hidden), nn.ReLU(), nn.Linear(n_hidden, n_hidden), nn.ReLU(), nn.Linear(n_hidden, output_size), nn.LogSoftmax(dim=1))def forward(self, x):# view一般出現在model類的forward函數中,用于改變輸入或輸出的形狀# x.view(-1, self.input_size) 的意思是多維的數據展成二維# 代碼指定二維數據的列數為 input_size=784,行數 -1 表示我們不想算,電腦會自己計算對應的數字# 在 DataLoader 部分,我們可以看到 batch_size 是64,所以得到 x 的行數是64# 大家可以加一行代碼:print(x.cpu().numpy().shape)# 訓練過程中,就會看到 (64, 784) 的輸出,和我們的預期是一致的# forward 函數的作用是,指定網絡的運行過程,這個全連接網絡可能看不啥意義,# 下面的CNN網絡可以看出 forward 的作用。x = x.view(-1, self.input_size)return self.network(x)class CNN(nn.Module):def __init__(self, input_size, n_feature, output_size):# 執行父類的構造函數,所有的網絡都要這么寫super(CNN, self).__init__()# 下面是網絡里典型結構的一些定義,一般就是卷積和全連接# 池化、ReLU一類的不用在這里定義self.n_feature = n_featureself.conv1 = nn.Conv2d(in_channels=1, out_channels=n_feature, kernel_size=5)self.conv2 = nn.Conv2d(n_feature, n_feature, kernel_size=5)self.fc1 = nn.Linear(n_feature*4*4, 50)self.fc2 = nn.Linear(50, 10) # 下面的 forward 函數,定義了網絡的結構,按照一定順序,把上面構建的一些結構組織起來# 意思就是,conv1, conv2 等等的,可以多次重用def forward(self, x, verbose=False):x = self.conv1(x)x = F.relu(x)x = F.max_pool2d(x, kernel_size=2)x = self.conv2(x)x = F.relu(x)x = F.max_pool2d(x, kernel_size=2)x = x.view(-1, self.n_feature*4*4)x = self.fc1(x)x = F.relu(x)x = self.fc2(x)x = F.log_softmax(x, dim=1)return x定義訓練和測試函數
# 訓練函數 def train(model):model.train()# 主里從train_loader里,64個樣本一個batch為單位提取樣本進行訓練for batch_idx, (data, target) in enumerate(train_loader):# 把數據送到GPU中data, target = data.to(device), target.to(device)optimizer.zero_grad()output = model(data)loss = F.nll_loss(output, target)loss.backward()optimizer.step()if batch_idx % 100 == 0:print('Train: [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))def test(model):model.eval()test_loss = 0correct = 0for data, target in test_loader:# 把數據送到GPU中data, target = data.to(device), target.to(device)# 把數據送入模型,得到預測結果output = model(data)# 計算本次batch的損失,并加到 test_loss 中test_loss += F.nll_loss(output, target, reduction='sum').item()# get the index of the max log-probability,最后一層輸出10個數,# 值最大的那個即對應著分類結果,然后把分類結果保存在 pred 里pred = output.data.max(1, keepdim=True)[1]# 將 pred 與 target 相比,得到正確預測結果的數量,并加到 correct 中# 這里需要注意一下 view_as ,意思是把 target 變成維度和 pred 一樣的意思 correct += pred.eq(target.data.view_as(pred)).cpu().sum().item()test_loss /= len(test_loader.dataset)accuracy = 100. * correct / len(test_loader.dataset)print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset),accuracy))(3)在小型全連接網絡上訓練(Fully-connected network)
n_hidden = 8 # number of hidden unitsmodel_fnn = FC2Layer(input_size, n_hidden, output_size) model_fnn.to(device) optimizer = optim.SGD(model_fnn.parameters(), lr=0.01, momentum=0.5) print('Number of parameters: {}'.format(get_n_params(model_fnn)))train(model_fnn) test(model_fnn)(4)在卷積神經網絡上訓練
需要注意的是,上在定義的CNN和全連接網絡,擁有相同數量的模型參數
# Training settings n_features = 6 # number of feature mapsmodel_cnn = CNN(input_size, n_features, output_size) model_cnn.to(device) optimizer = optim.SGD(model_cnn.parameters(), lr=0.01, momentum=0.5) print('Number of parameters: {}'.format(get_n_params(model_cnn)))train(model_cnn) test(model_cnn)通過上面的測試結果,可以發現,含有相同參數的 CNN 效果要明顯優于 簡單的全連接網絡,是因為 CNN 能夠更好的挖掘圖像中的信息,主要通過兩個手段:
- 卷積:Locality and stationarity in images
- 池化:Builds in some translation invariance
(5)打亂像素順序再次在兩個網絡上訓練與測試
考慮到CNN在卷積與池化上的優良特性,如果我們把圖像中的像素打亂順序,這樣 卷積 和 池化 就難以發揮作用了,為了驗證這個想法,我們把圖像中的像素打亂順序再試試。
首先下面代碼展示隨機打亂像素順序后,圖像的形態:
# 這里解釋一下 torch.randperm 函數,給定參數n,返回一個從0到n-1的隨機整數排列 perm = torch.randperm(784) plt.figure(figsize=(8, 4)) for i in range(10):image, _ = train_loader.dataset.__getitem__(i)# permute pixelsimage_perm = image.view(-1, 28*28).clone()image_perm = image_perm[:, perm]image_perm = image_perm.view(-1, 1, 28, 28)plt.subplot(4, 5, i + 1)plt.imshow(image.squeeze().numpy(), 'gray')plt.axis('off')plt.subplot(4, 5, i + 11)plt.imshow(image_perm.squeeze().numpy(), 'gray')plt.axis('off')重新定義訓練與測試函數,我們寫了兩個函數 train_perm 和 test_perm,分別對應著加入像素打亂順序的訓練函數與測試函數。
與之前的訓練與測試函數基本上完全相同,只是對 data 加入了打亂順序操作。
# 對每個 batch 里的數據,打亂像素順序的函數 def perm_pixel(data, perm):# 轉化為二維矩陣data_new = data.view(-1, 28*28)# 打亂像素順序data_new = data_new[:, perm]# 恢復為原來4維的 tensordata_new = data_new.view(-1, 1, 28, 28)return data_new# 訓練函數 def train_perm(model, perm):model.train()for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)# 像素打亂順序data = perm_pixel(data, perm)optimizer.zero_grad()output = model(data)loss = F.nll_loss(output, target)loss.backward()optimizer.step()if batch_idx % 100 == 0:print('Train: [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))# 測試函數 def test_perm(model, perm):model.eval()test_loss = 0correct = 0for data, target in test_loader:data, target = data.to(device), target.to(device)# 像素打亂順序data = perm_pixel(data, perm)output = model(data)test_loss += F.nll_loss(output, target, reduction='sum').item()pred = output.data.max(1, keepdim=True)[1] correct += pred.eq(target.data.view_as(pred)).cpu().sum().item()test_loss /= len(test_loader.dataset)accuracy = 100. * correct / len(test_loader.dataset)print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset),accuracy))在全連接網絡上訓練與測試:
在卷積神經網絡上訓練與測試:
從打亂像素順序的實驗結果來看,全連接網絡的性能基本上沒有發生變化,但是 卷積神經網絡的性能明顯下降。
這是因為對于卷積神經網絡,會利用像素的局部關系,但是打亂順序以后,這些像素間的關系將無法得到利用。
2.CIFAR10 數據集分類:使用 CNN 對 CIFAR10 數據集進行分類
學習資料:colab_demo/05_02_CNN_CIFAR10.ipynb at master · OUCTheoryGroup/colab_demo (github.com)
對于視覺數據,PyTorch 創建了一個叫做 totchvision 的包,該包含有支持加載類似Imagenet,CIFAR10,MNIST 等公共數據集的數據加載模塊 torchvision.datasets 和支持加載圖像數據數據轉換模塊 torch.utils.data.DataLoader。
下面將使用CIFAR10數據集,它包含十個類別:‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’。CIFAR-10 中的圖像尺寸為3x32x32,也就是RGB的3層顏色通道,每層通道內的尺寸為32*32。
(1)加載并歸一化 CIFAR10 使用 torchvision
torchvision 數據集的輸出是范圍在[0,1]之間的 PILImage,我們將他們轉換成歸一化范圍為[-1,1]之間的張量 Tensors。
大家肯定好奇,下面代碼中說的是 0.5,怎么就變化到[-1,1]之間了?PyTorch源碼中是這么寫的:
input[channel] = (input[channel] - mean[channel]) / std[channel]這樣就是:((0,1)-0.5)/0.5=(-1,1)。
import torch import torchvision import torchvision.transforms as transforms import matplotlib.pyplot as plt import numpy as np import torch.nn as nn import torch.nn.functional as F import torch.optim as optim# 使用GPU訓練,可以在菜單 "代碼執行工具" -> "更改運行時類型" 里進行設置 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])# 注意下面代碼中:訓練的 shuffle 是 True,測試的 shuffle 是 false # 訓練時可以打亂順序增加多樣性,測試是沒有必要 trainset = torchvision.datasets.CIFAR10(root='./data', train=True,download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,shuffle=True, num_workers=2)testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=True, transform=transform) testloader = torch.utils.data.DataLoader(testset, batch_size=8,shuffle=False, num_workers=2)classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')(2)展示 CIFAR10 里面的一些圖片
def imshow(img):plt.figure(figsize=(8,8))img = img / 2 + 0.5 # 轉換到 [0,1] 之間npimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0)))plt.show()# 得到一組圖像 images, labels = iter(trainloader).next() # 展示圖像 imshow(torchvision.utils.make_grid(images)) # 展示第一行圖像的標簽 for j in range(8):print(classes[labels[j]])運行報錯:
解決方法:搜索BrokenPipeError: [Errno 32] Broken pipe
在CSDN中找到問題的原因和解決方法:
原因:線程數為2
解決方法:設為0
成功!
(3)定義網絡,損失函數和優化器
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(3, 6, 5)self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, 5)self.fc1 = nn.Linear(16 * 5 * 5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):x = self.pool(F.relu(self.conv1(x)))x = self.pool(F.relu(self.conv2(x)))x = x.view(-1, 16 * 5 * 5)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return x# 網絡放到GPU上 net = Net().to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(net.parameters(), lr=0.001)#訓練網絡 for epoch in range(10): # 重復多輪訓練for i, (inputs, labels) in enumerate(trainloader):inputs = inputs.to(device)labels = labels.to(device)# 優化器梯度歸零optimizer.zero_grad()# 正向傳播 + 反向傳播 + 優化 outputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# 輸出統計信息if i % 100 == 0: print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item())) print('Finished Training')結果:
(4)從測試集中取出8張圖片,檢測CNN識圖的能力
# 得到一組圖像 images, labels = iter(testloader).next() # 展示圖像 imshow(torchvision.utils.make_grid(images)) # 展示圖像的標簽 for j in range(8):print(classes[labels[j]]) outputs = net(images.to(device)) _, predicted = torch.max(outputs, 1)# 展示預測的結果 for j in range(8):print(classes[predicted[j]])
識別效果還是很不錯的。
(5)測試驗證準確率
準確率達到了63%,還可以,通過改進網絡結構,性能還可以進一步提升。在 Kaggle 的LeaderBoard上,準確率高的達到95%以上。
3.使用 VGG16 對 CIFAR10 分類
學習資料:colab_demo/05_03_VGG_CIFAR10.ipynb at master · OUCTheoryGroup/colab_demo (github.com)
VGG是由Simonyan 和Zisserman在文獻《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷積神經網絡模型,其名稱來源于作者所在的牛津大學視覺幾何組(Visual Geometry Group)的縮寫。
該模型參加2014年的 ImageNet圖像分類與定位挑戰賽,取得了優異成績:在分類任務上排名第二,在定位任務上排名第一。
VGG16的網絡結構如下圖所示:
16層網絡的結節信息如下:
(1)定義 dataloader
這里的 transform,dataloader 和之前定義的有所不同
import torch import torchvision import torchvision.transforms as transforms import matplotlib.pyplot as plt import numpy as np import torch.nn as nn import torch.nn.functional as F import torch.optim as optim# 使用GPU訓練,可以在菜單 "代碼執行工具" -> "更改運行時類型" 里進行設置 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")transform_train = transforms.Compose([transforms.RandomCrop(32, padding=4),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))])transform_test = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))])trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train) testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2) testloader = torch.utils.data.DataLoader(testset, batch_size=128, shuffle=False, num_workers=2)classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')本地CUDA運行,num_workers=2報錯,要修改為num_workers=0
(2)VGG 網絡定義
參數有很多,可手動修改別的。現在的結構基本上是:
(這樣設置沒有什么特殊用意,作者說:“就是覺得對稱,我自己隨便改的。。。”)
模型的實現代碼如下:
class VGG(nn.Module):def __init__(self):super(VGG, self).__init__()self.cfg = [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M']self.features = self._make_layers(cfg)self.classifier = nn.Linear(2048, 10)def forward(self, x):out = self.features(x)out = out.view(out.size(0), -1)out = self.classifier(out)return outdef _make_layers(self, cfg):layers = []in_channels = 3for x in cfg:if x == 'M':layers += [nn.MaxPool2d(kernel_size=2, stride=2)]else:layers += [nn.Conv2d(in_channels, x, kernel_size=3, padding=1),nn.BatchNorm2d(x),nn.ReLU(inplace=True)]in_channels = xlayers += [nn.AvgPool2d(kernel_size=1, stride=1)]return nn.Sequential(*layers)初始化網絡,根據實際需要,修改分類層。因為 tiny-imagenet 是對200類圖像分類,這里把輸出修改為200。
# 網絡放到GPU上 net = VGG().to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(net.parameters(), lr=0.001)(3)網絡訓練
訓練代碼同之前一模一樣。
(4)測試驗證準確率
測試代碼也同之前一模一樣。
(5)運行結果:
解決過程:方法就1個字:搜!
①找到cfg所在的位置:
將其修改為:
②報錯信息變為
找到out:
將其修改為
out = self.classifier(self.out)③出現新的錯誤
一番查找之下,猜測可能的原因有以下幾種:
- 環境配置有問題,torch或其他包版本過低,項目中中當真沒有’out’
- 在本地運行代碼,由多線程&&CPU運行改為單線程&&CUDA,代碼不支持
- ……
實在無從下手,只得作罷…
四、思考的問題:
參考研究生新生培訓第二周:卷積神經網絡基礎
1、dataloader 里面 shuffle 取不同值有什么區別?
shuffle的取值為 “True” 或 “False”,不同取值標志著是否要對數據進行打亂洗牌。
“True” ->每次加載的數據都是隨機的,將輸入數據進行打亂洗牌;“False”->輸入數據順序固定。
通常需要對訓練集打亂洗牌,測試集可以不打亂。
2、transform 里,取了不同值,這個有什么區別?
在進行CIFAR10 數據集分類部分時,transform取不同值的代碼為:
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])所以transform取不同值就是調用了不同的函數。
在配置conda和環境時,安裝了torch和torchvision。其中的torchvision是計算機視覺工具。torchvision.transforms提供了大量的圖像數據預處理的方法,如數據中心化、數據標準化、縮放、裁剪、旋轉、翻轉、填充、噪聲增加、灰度變化、線性變換、仿射變換、亮度等。
-
transforms.Compose()是將一系列的transforms有序組合,實現時按照這些方法依次對圖像操作。
-
transforms.ToTensor() 作用是轉換為tensor格式,這個格式可以直接輸入進神經網絡;
-
transforms.Normalize()是對像素值進行歸一化處理,使得數據服從均值為0,標準差為1的分布;
3、epoch 和 batch 的區別?
epoch和batch都是神經網絡訓練中的超參數,epoch表示神經網絡訓練的輪數,batch用于定義在更新內部模型參數之前要處理的樣本數,一次epoch至少要訓練完成一個batch.
4、1x1的卷積和 FC 有什么區別?主要起什么作用?
FC可以看作全局卷積,1*1卷積可以替代FC,FC主要起到線性變化和分類的作用,1*1通常用于實現降維,用作非線性變化。
5、residual leanring 為什么能夠提升準確率?
解決了梯度消失問題 。
6、代碼練習二里,網絡和1989年 Lecun 提出的 LeNet 有什么區別?
代碼練習二中激活函數為ReLU,而LeNet激活函數是Sigmoid。代碼二中的網絡結構通常較=叫LeNet-5。
7、代碼練習二里,卷積以后feature map 尺寸會變小,如何應用 Residual Learning?
通過線性變換將原圖像縮小為和feature map大小相同的圖像。當輸入輸出維度上升時有兩種處理方式:第一種是仍使用恒等映射,多出來的通道使用零矩陣填充,這樣做的好處是不會帶來額外的參數;第二種是添加變換方程,通常來說會使用 1*1 卷積來完成升維。
8、有什么方法可以進一步提升準確率?
- 改進網絡結構
- 選擇合適優化器
- 選擇合適損失函數
- 選擇合適激活函數
- 增加網絡深度
- 增加訓練輪數
- 采用更大的數據集
總結
以上是生活随笔為你收集整理的第3次作业-卷积神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安装cnpm后运行报cnpm :无法加载
- 下一篇: 【深度学习】5:CNN卷积神经网络原理