日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 卷积神经网络 >内容正文

卷积神经网络

第3次作业-卷积神经网络

發布時間:2023/12/14 卷积神经网络 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第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
import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms import matplotlib.pyplot as plt import numpy# 一個函數,用來計算模型中有多少參數 def get_n_params(model):np=0for p in list(model.parameters()):np += p.nelement()return np# 使用GPU訓練,可以在菜單 "代碼執行工具" -> "更改運行時類型" 里進行設置 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

(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所在的位置:


將其修改為:

self.features = self._make_layers(self.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次作业-卷积神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。