全连接网络:相邻两层任意两个节点之间都有权重连接

对于图像来说,会丧失空间结构信息 ,因此需要卷积操作

卷积的操作实际是特征提取的过程,最后需要通过分类层

卷积操作时,左上角为(0,0)

1通道:每个位置用卷积核的对应元素与input相乘再求和

多通道:每一通道输入对应一个卷积核(可以不同),再将卷积输入对应位置相加

相当于对输入图像中一个3*3*3的张量,做卷积核为3*3*3的操作,得到channel=1输出

可准备多个卷积核,改变输出的channel数量,最后按顺序排列

需保持以下要求:每个卷积核的channel数与输入channel数相同;卷积核个数与输出channel数相同

用下列代码检验

import torch
in_channels,out_channels=5,10
width,height=100,100
kernel_size=3
batch_size=1

input=torch.randn(batch_size,in_channels,width,height)

conv_layer=torch.nn.Conv2d(in_channels,out_channels,kernel_size=kernel_size)

output=conv_layer(input)

print(input.shape)
print(output.shape)
print(conv_layer.weight.shape)

padding操作:想保持output和input形状相同,则需要给input外围添一圈0

stride(步长):每次卷积移动的距离

下采样:根据步长做池化操作-->通道数不变

下面仍旧以手写数字识别为例

import torch
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import torch.nn as nn
import matplotlib.pyplot as plt
import torch.nn.functional as F
import torch.optim as optim
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])#均值,标准差
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=1, shuffle=True)
testloader = DataLoader(testset, batch_size=1, shuffle=False)
class Net(torch.nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv1=torch.nn.Conv2d(1,10,kernel_size=5)
        self.conv2=torch.nn.Conv2d(10,20,kernel_size=5)
        self.pooling=torch.nn.MaxPool2d(2)
        self.fc=torch.nn.Linear(320,10)

    def forward(self,x):
        batch_size=x.size(0)
        x=F.relu(self.conv1(x))
        x=self.pooling(x)
        x=F.relu(self.conv2(x))
        x = self.pooling(x)
        x=x.view(batch_size,-1)#flatten
        x=self.fc(x)
        return x
model=Net()
criterion = nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(model.parameters(),lr=0.01,momentum=0.5)
device=torch.device('cuda:0'if torch.cuda.is_available() else"cpu")
model.to(device)

def train(epoch):
    running_loss=0
    for batch_idx,data in enumerate(trainloader,0):
        inputs,target=data
        inputs,target=inputs.to(device),target.to(device)
        optimizer.zero_grad()

        outputs=model(inputs)
        loss=criterion(outputs,target)
        loss.backward()
        optimizer.step()

        running_loss+=loss.item()
        if batch_idx%300==299:
            print('[%d,%5d] loss:%3f'%(epoch+1,batch_idx+1,running_loss/300))
            running_loss=0

def test():
    correct=0
    total=0
    with torch.no_grad():
        for data in testloader:
            images,labels=data
            images, labels = images.to(device), labels.to(device)
            outputs=model(images)
            _,predicted=torch.max(outputs.data,dim=1)#沿第一个维度找最大值的下标
            total+=labels.size(0)
            correct+=(predicted==labels).sum().item()
    print('accuracy on test:%d%%'%(100*correct/total))


if __name__=='__main__':
    for epoch in range(10):
        train(epoch)
        test()

更多推荐