国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

這篇具有很好參考價(jià)值的文章主要介紹了十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、確定輸入樣本特征和輸出特征

輸入樣本通道數(shù)4、期待輸出樣本通道數(shù)2、卷積核大小3×3
具體卷積層的構(gòu)建可參考博文:八、卷積層
設(shè)定卷積層
torch.nn.Conv2d(in_channels=in_channel,out_channels=out_channel,kernel_size=kernel_size,padding=1,stride=1)
必要參數(shù):輸入樣本通道數(shù)in_channels、輸出樣本通道數(shù)out_channels、卷積核大小kernel_size
padding是否加邊,默認(rèn)不加,這里為了保證輸出圖像的大小不變,加邊數(shù)設(shè)為1
stride步長設(shè)置,默認(rèn)為1
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

import torch
in_channel, out_channel = 4, 2
width, heigh = 512, 512
batch_size = 1
inputs = torch.randn(batch_size,in_channels,width,heigh)#[B,C,W,H]

kernel_size = 3

conv_layer = torch.nn.Conv2d(in_channels=in_channel,out_channels=out_channel,kernel_size=kernel_size,padding=1,stride=1)
outputs = conv_layer(inputs)

print(inputs.shape)
"""
torch.Size([1, 4, 512, 512])
"""
print(outputs.shape)
"""
torch.Size([1, 2, 512, 512])
"""
print(conv_layer.weight.shape)#看下卷積層核參數(shù)信息
# 卷積層權(quán)重參數(shù)大小,因?yàn)閎atch_size為1,故卷積核參數(shù)的B也為1;
# 因?yàn)檩斎霕颖镜耐ǖ罃?shù)是3,故卷積層傳入?yún)?shù)的channel也為3;
# 因?yàn)檩敵鰳颖镜耐ǖ罃?shù)是1,故卷積層傳入?yún)?shù)的
"""
torch.Size([2, 4, 3, 3])
"""

二、確定卷積核內(nèi)容進(jìn)行卷積

十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

import torch
inputs = [1,1,1,1,1,
          2,2,2,2,2,
          1,1,2,1,1,
          1,1,2,1,1,
          1,1,2,1,1]

inputs = torch.Tensor(inputs).view(1,1,5,5)

kernel_size = 3
padding = 0
stride = 1

kernel = torch.Tensor([1,2,1,
                       2,1,2,
                       1,2,1]).view(1,1,3,3)

conv_layer = torch.nn.Conv2d(1,1,kernel_size=kernel_size,padding=padding,stride=stride,bias=False)
conv_layer.weight.data = kernel.data

outputs = conv_layer(inputs)

print(outputs)
"""
tensor([[[[19., 20., 19.],
          [20., 20., 20.],
          [17., 18., 17.]]]], grad_fn=<SlowConv2DBackward0>)
"""

print(inputs)
"""
tensor([[[[1., 1., 1., 1., 1.],
          [2., 2., 2., 2., 2.],
          [1., 1., 1., 1., 1.],
          [2., 2., 2., 2., 2.],
          [1., 1., 1., 1., 1.]]]])
"""
print(kernel)
"""
tensor([[[[1., 2., 1.],
          [2., 1., 2.],
          [1., 2., 1.]]]])
"""
print(inputs.shape)
"""
torch.Size([1, 1, 5, 5])
"""
print(outputs.shape)
"""
torch.Size([1, 1, 3, 3])
"""
print(kernel.shape)
"""
torch.Size([1, 1, 3, 3])
"""
print(conv_layer.weight.shape)
"""
torch.Size([1, 1, 3, 3])
"""

三、根據(jù)需求進(jìn)行網(wǎng)絡(luò)模型搭建

①準(zhǔn)備數(shù)據(jù)集

還是以MNIST手寫數(shù)字?jǐn)?shù)據(jù)集為例,數(shù)據(jù)集細(xì)節(jié)可參考博文:九、多分類問題

設(shè)置batch_size=64,每個(gè)batch中有64張樣本,至于一共有多少個(gè)batch,取決于數(shù)據(jù)集的總數(shù)量
使用transforms.Compose(),組合操作,把數(shù)據(jù)集都轉(zhuǎn)換為Tensor數(shù)據(jù)類型,并且全部都取均值和標(biāo)準(zhǔn)差,方便訓(xùn)練,強(qiáng)化訓(xùn)練效果,這里的值都是經(jīng)過計(jì)算過的,直接用就行

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #為了使用relu激活函數(shù)
import torch.optim as optim 

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),#把圖片變成張量形式
    transforms.Normalize((0.1307,),(0.3081,)) #均值和標(biāo)準(zhǔn)差進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化,這倆值都是經(jīng)過整個(gè)樣本集計(jì)算過的
])

②加載數(shù)據(jù)集

pytorch提供MNIST接口,直接調(diào)用相關(guān)函數(shù)即可

datasets
參數(shù)root表示數(shù)據(jù)集路徑;
參數(shù)train表示是否是訓(xùn)練集,True表示下載訓(xùn)練集,False則表示下載測試集;
參數(shù)download表示是否下載,True表示若指定路徑不存在數(shù)據(jù)集則聯(lián)網(wǎng)下載;
將所有的數(shù)據(jù)集都經(jīng)過上面定義的transforms組合操作,轉(zhuǎn)換成Tensor格式和均值標(biāo)準(zhǔn)差歸一化。

DataLoader
參數(shù)train_dataset指定數(shù)據(jù)集datasets;
參數(shù)shuffle表示是否將數(shù)據(jù)集中的樣本打亂順序,訓(xùn)練集需要,測試集不需要
參數(shù)batch_size表示一次(batch)取多少個(gè)樣本,至于一共取多少次取決于數(shù)據(jù)集總樣本數(shù)

train_dataset = datasets.MNIST(root='./',train=True,download=True,transform = transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root="./",train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

③模型構(gòu)建

十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)
由圖可知,輸入圖像(通道數(shù)為1)首先進(jìn)入一個(gè)卷積層,卷積核大小為5×5,輸出特征通道數(shù)為10,即torch.nn.Conv2d(1,10,kernel_size=5)
之后進(jìn)入一個(gè)ReLU激活函數(shù)層,激活函數(shù)無需參數(shù),即F.relu()
然后再進(jìn)入一個(gè)核為2×2的MaxPool層,即torch.nn.MaxPool2d(2)

之后將通道數(shù)為10的特征參數(shù)再送入一個(gè)卷積層,卷積核大小為5×5,輸出特征通道數(shù)為20,即torch.nn.Conv2d(10,20,kernel_size=5)
之后進(jìn)入一個(gè)ReLU激活函數(shù)層,激活函數(shù)無需參數(shù),即F.relu()
然后再進(jìn)入一個(gè)核為2×2的MaxPool層,即torch.nn.MaxPool2d(2)

有第一張圖可知,最終的特征參數(shù)個(gè)數(shù)為20×4×4=320,將這320個(gè)特征參數(shù)通過線性層(全連接層),轉(zhuǎn)到10個(gè)維度上,即torch.nn.Linear(320,10),因?yàn)槭?0分類任務(wù),故需要轉(zhuǎn)到10個(gè)維度上

在模型參數(shù)函數(shù)(def __init__(self):)中,池化層操作都一樣,故定義一個(gè)即可,最終,卷積操作兩個(gè),一個(gè)池化操作,一個(gè)線性層(全連接)操作
在前向傳播函數(shù)(def forward(self,x):)中,數(shù)據(jù)集中x為[B,C,W,H],故通過x.size(0)取出batch_size,即B的值

class yNet(torch.nn.Module):
    def __init__(self):
        super(yNet,self).__init__()
        
        self.conv_1 = torch.nn.Conv2d(1,10,kernel_size=5)
        self.pooling = torch.nn.MaxPool2d(2)
        self.conv_2 = torch.nn.Conv2d(10,20,kernel_size=5)
        self.fc = torch.nn.Linear(320,10)
        
    def forward(self,x):
        batch_size = x.size(0)
        x = self.pooling(F.relu(self.conv_1(x)))
        x = self.pooling(F.relu(self.conv_2(x)))
        x = x.view(batch_size,-1)
        x = self.fc(x)
        
        return x

model = yNet()

GPU加速
只需要通過.to()方法,將模型、訓(xùn)練函數(shù)中數(shù)據(jù)集、測試函數(shù)中數(shù)據(jù)集調(diào)用該方法即可

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

④損失函數(shù)和優(yōu)化器

lossf = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr=0.0001,momentum=0.5)

⑤訓(xùn)練函數(shù)定義

for i, data in enumerate(train_loader,0):
train_loader這個(gè)DataLoader中進(jìn)行枚舉,0表示從DataLoader下標(biāo)為0處開始,train_loader返回兩個(gè)值,索引數(shù)據(jù),其中數(shù)據(jù)包括兩類,x和y
i接收索引、data接收數(shù)據(jù)
x,y = data,x和y分別接收data中的28×28=784個(gè)參數(shù),y為所對應(yīng)的某一個(gè)類別

測試

x,y = test_dataset[0]
x.shape
"""
torch.Size([1, 28, 28])
"""
y
"""
7
"""

完整代碼

def ytrain(epoch):
    loss_total = 0.0
    for batch_index ,data in enumerate(train_loader,0):
        x,y = data
        #x,y = x.to(device), y.to(device)#GPU加速
        optimizer.zero_grad()
        
        y_hat = model(x)
        loss = lossf(y_hat,y)
        loss.backward()
        optimizer.step()
        
        loss_total += loss.item()
        if batch_index % 300 == 299:# 每300epoch輸出一次
            print("epoch:%d, batch_index:%5d \t loss:%.3f"%(epoch+1, batch_index+1, loss_total/300))
            loss_total = 0.0 #每次epoch都將損失清零,方便計(jì)算下一次的損失

⑥測試函數(shù)定義

def ytest():
    correct = 0#模型預(yù)測正確的數(shù)量
    total = 0#樣本總數(shù)
    with torch.no_grad():#測試不需要梯度,減小計(jì)算量
        for data in test_loader:#讀取測試樣本數(shù)據(jù)
            images, labels = data
            #images, labels = images.to(device), labels.to(device) #GPU加速
            pred = model(images)#預(yù)測,每一個(gè)樣本占一行,每行有十個(gè)值,后續(xù)需要求每一行中最大值所對應(yīng)的下標(biāo)
            pred_maxvalue, pred_maxindex = torch.max(pred.data,dim=1)#沿著第一個(gè)維度,一行一行來,去找每行中的最大值,返回每行的最大值和所對應(yīng)下標(biāo)
            total += labels.size(0)#labels是一個(gè)(N,1)的向量,對應(yīng)每個(gè)樣本的正確答案
            correct += (pred_maxindex == labels).sum().item()#使用預(yù)測得到的最大值的索引和正確答案labels進(jìn)行比較,一致就是1,不一致就是0
        print("Accuracy on testset :%d %%"%(100*correct / total))#correct預(yù)測正確的樣本個(gè)數(shù) / 樣本總數(shù) * 100 = 模型預(yù)測正確率

⑦主函數(shù)調(diào)用

if __name__ == '__main__':
    for epoch in range(100):#訓(xùn)練10次
        ytrain(epoch)#訓(xùn)練一次
        if epoch%10 == 9:
            ytest()#訓(xùn)練10次,測試1次

⑧完整代碼

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #為了使用relu激活函數(shù)
import torch.optim as optim 

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),#把圖片變成張量形式
    transforms.Normalize((0.1307,),(0.3081,)) #均值和標(biāo)準(zhǔn)差進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化,這倆值都是經(jīng)過整個(gè)樣本集計(jì)算過的
])

train_dataset = datasets.MNIST(root='./',train=True,download=True,transform = transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root="./",train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

class yNet(torch.nn.Module):
    def __init__(self):
        super(yNet,self).__init__()
        
        self.conv_1 = torch.nn.Conv2d(1,10,kernel_size=5)
        self.pooling = torch.nn.MaxPool2d(2)
        self.conv_2 = torch.nn.Conv2d(10,20,kernel_size=5)
        self.fc = torch.nn.Linear(320,10)
        
    def forward(self,x):#傳入單張樣本x
        batch_size = x.size(0)
        x = self.pooling(F.relu(self.conv_1(x)))
        x = self.pooling(F.relu(self.conv_2(x)))
        x = x.view(batch_size,-1)
        x = self.fc(x)
        
        return x
    
model = yNet()   
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

lossf = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr=0.0001,momentum=0.5)

def ytrain(epoch):
    loss_total = 0.0
    for batch_index ,data in enumerate(train_loader,0):
        x,y = data
        x,y = x.to(device), y.to(device)#GPU加速
        optimizer.zero_grad()
        
        y_hat = model(x)
        loss = lossf(y_hat,y)
        loss.backward()
        optimizer.step()
        
        loss_total += loss.item()
        if batch_index % 300 == 299:# 每300epoch輸出一次
            print("epoch:%d, batch_index:%5d \t loss:%.3f"%(epoch+1, batch_index+1, loss_total/300))
            loss_total = 0.0
            

def ytest():
    correct = 0#模型預(yù)測正確的數(shù)量
    total = 0#樣本總數(shù)
    with torch.no_grad():#測試不需要梯度,減小計(jì)算量
        for data in test_loader:#讀取測試樣本數(shù)據(jù)
            images, labels = data
            images, labels = images.to(device), labels.to(device) #GPU加速
            pred = model(images)#預(yù)測,每一個(gè)樣本占一行,每行有十個(gè)值,后續(xù)需要求每一行中最大值所對應(yīng)的下標(biāo)
            pred_maxvalue, pred_maxindex = torch.max(pred.data,dim=1)#沿著第一個(gè)維度,一行一行來,去找每行中的最大值,返回每行的最大值和所對應(yīng)下標(biāo)
            total += labels.size(0)#labels是一個(gè)(N,1)的向量,對應(yīng)每個(gè)樣本的正確答案
            correct += (pred_maxindex == labels).sum().item()#使用預(yù)測得到的最大值的索引和正確答案labels進(jìn)行比較,一致就是1,不一致就是0
        print("Accuracy on testset :%d %%"%(100*correct / total))#correct預(yù)測正確的樣本個(gè)數(shù) / 樣本總數(shù) * 100 = 模型預(yù)測正確率
        

if __name__ == '__main__':
    for epoch in range(10):#訓(xùn)練10次
        ytrain(epoch)#訓(xùn)練一次
        if epoch%10 == 9:
            ytest()#訓(xùn)練10次,測試1次

⑨測試一下

x,y = train_dataset[9]#第9個(gè)數(shù)據(jù)x為圖片,對應(yīng)的結(jié)果為2
y
"""
2
"""
x = x.view(-1,1,28,28)#因?yàn)閠ensor需要格式為(B,C,W,H)轉(zhuǎn)換一下格式
y_hat = model(x)#放入模型中進(jìn)行預(yù)測,因?yàn)闀r(shí)十分類任務(wù),輸出十個(gè)值
y_hat 
"""
tensor([[-2.8711, -2.2891, -0.5218, -2.0884,  6.2099, -0.1559,  1.9904, -0.8938,
          1.3734,  2.9303]], grad_fn=<AddmmBackward0>)
"""


pred_maxvalue, pred_maxindex = torch.max(y_hat,dim=1)#選出值最大的,和相對于的下標(biāo)索引

pred_maxvalue#最大值
"""
tensor([6.2099], grad_fn=<MaxBackward0>)
"""
pred_maxindex#最大值所對應(yīng)的索引下標(biāo)值
"""
tensor([4])
"""

預(yù)測錯(cuò)了,得多訓(xùn)練幾輪

四、課后作業(yè)

十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)
除網(wǎng)絡(luò)模型外,其他的都可以復(fù)用

這里就不再贅述,直接對模型結(jié)構(gòu)進(jìn)行搭建

查看下官網(wǎng)給的卷積層padding的計(jì)算公式
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)
以下是我個(gè)人設(shè)計(jì)的網(wǎng)絡(luò)模型,接下來開始去實(shí)現(xiàn)模型架構(gòu)
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

①調(diào)試

加載數(shù)據(jù)集

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #為了使用relu激活函數(shù)
import torch.optim as optim 

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),#把圖片變成張量形式
    transforms.Normalize((0.1307,),(0.3081,)) #均值和標(biāo)準(zhǔn)差進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化,這倆值都是經(jīng)過整個(gè)樣本集計(jì)算過的
])

train_dataset = datasets.MNIST(root='./',train=True,download=True,transform = transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root="./",train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

#這里取測試集中的一個(gè)樣本
x,y = test_dataset[1]

x.shape
"""
torch.Size([1, 28, 28])
"""
y
"""
2
"""

第一個(gè)卷積層

因?yàn)閿?shù)據(jù)集中樣本shape是torch.Size([1, 28, 28]),而pytorch提供的接口都得適應(yīng)[B,C,W,H]形式,故需要先通過x = x.view(-1,1,28,28)轉(zhuǎn)換一下類型
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)
根據(jù)結(jié)構(gòu)需要,定義第一個(gè)卷積層,為了后續(xù)計(jì)算方便,這里加邊padding=1,保證輸入和輸出特征圖大小一致,這里僅為了測試,batch取1
conv_1 = torch.nn.Conv2d(1,5,kernel_size=3,padding=1)

x = x.view(-1,1,28,28)
x.shape
"""
torch.Size([1, 1, 28, 28])
"""
conv_1 = torch.nn.Conv2d(1,5,kernel_size=3,padding=1)
x1 = conv_1(x)
x1.shape
"""
torch.Size([1, 5, 28, 28])
"""

由輸出結(jié)果可知,通過第一個(gè)卷積層之后,特征圖x1[1,5,28,28]
x1傳入第一個(gè)最大池化層

第一個(gè)最大池化層

x1的形狀為[1,5,28,28]
定義最大池化層:pooling = torch.nn.MaxPool2d(2)
x1傳入最大池化層,得到特征x2
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

pooling = torch.nn.MaxPool2d(2)
x2 = pooling(x1)
x2.shape
"""
torch.Size([1, 5, 14, 14])
"""

輸出結(jié)果x2的形狀為[1, 5, 14, 14]
x2傳入第二個(gè)卷積層中

第二個(gè)卷積層

x2的形狀為[1, 5, 14, 14]
定義第二個(gè)卷積層:conv_2 = torch.nn.Conv2d(5,10,kernel_size=3,padding=1)
x2傳入第二個(gè)卷積層,得到特征x3
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

conv_2 = torch.nn.Conv2d(5,10,kernel_size=3,padding=1)
x3 = conv_2(x2)
x3.shape
"""
torch.Size([1, 10, 14, 14])
"""

輸出結(jié)果x3的形狀為[1, 10, 14, 14]
x3傳入第二個(gè)最大池化層中

第二個(gè)最大池化層

x3的形狀為[1, 10, 14, 14]
使用上述同樣的最大池化層:pooling = torch.nn.MaxPool2d(2)
x3傳入第二個(gè)最大池化層,得到特征x4
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

pooling = torch.nn.MaxPool2d(2)
x4 = pooling(x3)
x4.shape
"""
torch.Size([1, 10, 7, 7])
"""

輸出結(jié)果x4的形狀為[1, 10, 7, 7]
x4傳入第三個(gè)卷積層中

第三個(gè)卷積層

x4的形狀為[1, 10, 7, 7]
定義第三個(gè)卷積層:conv_3 = torch.nn.Conv2d(10,20,kernel_size=3,padding=1)
x4傳入第三個(gè)卷積層,得到特征x5
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

conv_3 = torch.nn.Conv2d(10,20,kernel_size=3,padding=1)
x5 = conv_3(x4)
x5.shape
"""
torch.Size([1, 20, 7, 7])
"""

輸出結(jié)果x5的形狀為[1, 20, 7, 7]
x5傳入第三個(gè)最大池化層中

第三個(gè)最大池化層

x5的形狀為[1, 20, 7, 7]
使用上述同樣的最大池化層:pooling = torch.nn.MaxPool2d(2)
x5傳入第二個(gè)最大池化層,得到特征x6

十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

pooling = torch.nn.MaxPool2d(2)
x6 = pooling(x5)
x6.shape
"""
torch.Size([1, 20, 3, 3])
"""

輸出結(jié)果x6的形狀為[1, 20, 3, 3]
x6傳入第一個(gè)線性層中

第一個(gè)全連接層

x6的形狀為[1, 20, 3, 3],此時(shí)特征圖x6共有1×20×3×3=180個(gè)參數(shù)
因?yàn)榫€性層傳入的特征是二維矩陣形式,每個(gè)batch占一行,每行存放單個(gè)樣本的所有參數(shù)信息,故需要將x6形狀進(jìn)行轉(zhuǎn)變,x6.size(0)獲取batch,這里的batch是1,剩下的,系統(tǒng)進(jìn)行自動排列,x_all = x6.view(x6.size(0),-1),此時(shí)的x_all的形狀為[1,180]
之后根據(jù)需求,定義第一個(gè)線性層:fc_1 = torch.nn.Linear(180,120),這里的輸入180,必須和最終的特征x_all吻合
x_all傳入第一個(gè)全連接層,得到特征x_x1
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

x6.shape
"""
torch.Size([1, 20, 3, 3])
"""
x6.size(0)
"""
1
"""

x_all = x6.view(x6.size(0),-1)
x_all.shape
"""
torch.Size([1, 180])
"""

fc_1 = torch.nn.Linear(180,120)
x_x1 = fc_1(x_all)
x_x1.shape
"""
torch.Size([1, 120])
"""

輸出結(jié)果x_x1的形狀為[1, 120]
x_x1傳入第二個(gè)全連接層中

第二個(gè)全連接層

x_x1的形狀為[1, 120]
根據(jù)需求,定義第二個(gè)全連接層,fc_2 = torch.nn.Linear(120,60)
x_x1傳入第二個(gè)全連接層,得到特征x_x2
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

fc_2 = torch.nn.Linear(120,60)
x_x2 = fc_2(x_x1)
x_x2.shape
"""
torch.Size([1, 60])
"""

輸出結(jié)果x_x2的形狀為[1, 60]
x_x2傳入第三個(gè)全連接層中

第三個(gè)全連接層

x_x2的形狀為[1, 60]
根據(jù)需求,定義第三個(gè)全連接層,fc_3 = torch.nn.Linear(60,10)
x_x2傳入第三個(gè)全連接層,得到特征x_x3
十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)

fc_3 = torch.nn.Linear(60,10)
x_x3 = fc_3(x_x2)
x_x3.shape
"""
torch.Size([1, 10])
"""

最終結(jié)果為x_x3,形狀為[1, 10],十分類任務(wù),十個(gè)概率值,取最大的,就是最終預(yù)測的結(jié)果

②模型構(gòu)建

class yNet(torch.nn.Module):
    def __init__(self):
        super(yNet,self).__init__()
        
        self.conv_1 = torch.nn.Conv2d(1,5,kernel_size=3,padding=1)
        self.pooling = torch.nn.MaxPool2d(2)
        self.conv_2 = torch.nn.Conv2d(5,10,kernel_size=3,padding=1)
        self.conv_3 = torch.nn.Conv2d(10,20,kernel_size=3,padding=1)
        
        self.fc_1 = torch.nn.Linear(180,120)
        self.fc_2 = torch.nn.Linear(120,60)
        self.fc_3 = torch.nn.Linear(60,10)
        
    def forward(self,x):
        batch_size = x.size(0)
        x = self.pooling(F.relu(self.conv_1(x)))
        x = self.pooling(F.relu(self.conv_2(x)))
        x = self.pooling(F.relu(self.conv_3(x)))
        x = x.view(batch_size,-1)
        x = self.fc_1(x)
        x = self.fc_2(x)
        x = self.fc_3(x)
        
        return x
       
model = yNet()   

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")#GPU加速
model.to(device)

③完整代碼

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #為了使用relu激活函數(shù)
import torch.optim as optim 

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),#把圖片變成張量形式
    transforms.Normalize((0.1307,),(0.3081,)) #均值和標(biāo)準(zhǔn)差進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化,這倆值都是經(jīng)過整個(gè)樣本集計(jì)算過的
])

train_dataset = datasets.MNIST(root='./',train=True,download=True,transform = transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root="./",train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

class yNet(torch.nn.Module):
    def __init__(self):
        super(yNet,self).__init__()
        
        self.conv_1 = torch.nn.Conv2d(1,5,kernel_size=3,padding=1)
        self.pooling = torch.nn.MaxPool2d(2)
        self.conv_2 = torch.nn.Conv2d(5,10,kernel_size=3,padding=1)
        self.conv_3 = torch.nn.Conv2d(10,20,kernel_size=3,padding=1)
        
        self.fc_1 = torch.nn.Linear(180,120)
        self.fc_2 = torch.nn.Linear(120,60)
        self.fc_3 = torch.nn.Linear(60,10)
        
    def forward(self,x):
        batch_size = x.size(0)
        x = self.pooling(F.relu(self.conv_1(x)))
        x = self.pooling(F.relu(self.conv_2(x)))
        x = self.pooling(F.relu(self.conv_3(x)))
        x = x.view(batch_size,-1)
        x = self.fc_1(x)
        x = self.fc_2(x)
        x = self.fc_3(x)
        
        return x
    
model = yNet()   
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

lossf = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr=0.0001,momentum=0.5)

def ytrain(epoch):
    loss_total = 0.0
    for batch_index ,data in enumerate(train_loader,0):
        x,y = data
        x,y = x.to(device), y.to(device)#GPU加速
        optimizer.zero_grad()
        
        y_hat = model(x)
        loss = lossf(y_hat,y)
        loss.backward()
        optimizer.step()
        
        loss_total += loss.item()
        if batch_index % 300 == 299:# 每300epoch輸出一次
            print("epoch:%d, batch_index:%5d \t loss:%.3f"%(epoch+1, batch_index+1, loss_total/300))
            loss_total = 0.0
            

def ytest():
    correct = 0#模型預(yù)測正確的數(shù)量
    total = 0#樣本總數(shù)
    with torch.no_grad():#測試不需要梯度,減小計(jì)算量
        for data in test_loader:#讀取測試樣本數(shù)據(jù)
            images, labels = data
            images, labels = images.to(device), labels.to(device) #GPU加速
            pred = model(images)#預(yù)測,每一個(gè)樣本占一行,每行有十個(gè)值,后續(xù)需要求每一行中最大值所對應(yīng)的下標(biāo)
            pred_maxvalue, pred_maxindex = torch.max(pred.data,dim=1)#沿著第一個(gè)維度,一行一行來,去找每行中的最大值,返回每行的最大值和所對應(yīng)下標(biāo)
            total += labels.size(0)#labels是一個(gè)(N,1)的向量,對應(yīng)每個(gè)樣本的正確答案
            correct += (pred_maxindex == labels).sum().item()#使用預(yù)測得到的最大值的索引和正確答案labels進(jìn)行比較,一致就是1,不一致就是0
        print("Accuracy on testset :%d %%"%(100*correct / total))#correct預(yù)測正確的樣本個(gè)數(shù) / 樣本總數(shù) * 100 = 模型預(yù)測正確率
        

if __name__ == '__main__':
    for epoch in range(10):#訓(xùn)練10次
        ytrain(epoch)#訓(xùn)練一次
        if epoch%10 == 9:
            ytest()#訓(xùn)練10次,測試1次

④測試一下

x,y = train_dataset[12]#第12個(gè)數(shù)據(jù)x為圖片,對應(yīng)的結(jié)果為3
y
"""
3
"""
x = x.view(-1,1,28,28)#因?yàn)閠ensor需要格式為(B,C,W,H)轉(zhuǎn)換一下格式
y_hat = model(x)#放入模型中進(jìn)行預(yù)測,因?yàn)闀r(shí)十分類任務(wù),輸出十個(gè)值
y_hat 
"""
tensor([[ 0.0953,  0.0728,  0.0505,  0.0618, -0.0512, -0.1338, -0.0261, -0.0677,
         -0.0265,  0.0236]], grad_fn=<AddmmBackward0>)
"""


pred_maxvalue, pred_maxindex = torch.max(y_hat,dim=1)#選出值最大的,和相對于的下標(biāo)索引

pred_maxvalue#最大值
"""
tensor([0.0953], grad_fn=<MaxBackward0>)
"""
pred_maxindex#最大值所對應(yīng)的索引下標(biāo)值
"""
tensor([0])
"""

好家伙,又預(yù)測錯(cuò)了,確實(shí)得多訓(xùn)練幾輪

又是動筆畫,又是單步調(diào)試,若各位客官姥爺有所收獲,還請點(diǎn)個(gè)小小的贊,這將是對我的最大的鼓勵,萬分感謝~文章來源地址http://www.zghlxwxcb.cn/news/detail-406697.html

到了這里,關(guān)于十、CNN卷積神經(jīng)網(wǎng)絡(luò)實(shí)戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包