神经网络的基本骨架

1 简介

本文就是简单介绍一下各个层次,并给出一个小demo,最后会以CIFAR10数据集为例构建一个简单的神经网络。

所有代码均放在我的仓库中,如果需要请访问:https://github.com/Guoxn1/ai

如果给到您帮助,请给我一个star,这将成为我持续创作的动力。

2 卷积层

卷积操作,对CIFAR10的测试集图片进行了卷积操作,另外使用tensorboard展示出来。

卷积层主要用来提取特征,比如轮廓,cv2中有很多操作,卷积层通常也会引入激活函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 取测试集数据,并将其转换为tensor数据类型
dataset = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=64)

# 所有的类必须继承nn.modules
class Juanji(nn.Module):
def __init__(self):
super(Juanji,self).__init__()
self.conv1 = Conv2d(3,6,3,stride=1,padding=0)

def forward(self,x):
x = self.conv1(x)
return x

juanji = Juanji()
print(juanji)
step = 1
writer = SummaryWriter("logs")
for data in dataloader:
imgs,targets = data
output = juanji(imgs)

output = torch.reshape(output,(-1,3,30,30 ))
print(output.shape)
writer.add_images("test",output,step)

step += 1
writer.close()


image-20231020221350623

3 池化层

也称之为采样层,这里采用最大池化,池化层就是来保留原始输入的信息,但是又减少数据的维度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d,MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 取测试集数据,并将其转换为tensor数据类型
dataset = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=16)

class Chihua(nn.Module):
def __init__(self):
super(Chihua,self).__init__()
self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)

def forward(self,x):
x = self.maxpool1(x)
return x

chihua = Chihua()
step = 1
writer = SummaryWriter("logs")
for data in dataloader:
imgs,targets = data
output = chihua(imgs)
writer.add_images("imgs",imgs,step)
print(output.shape)
step += 1

writer.close()
image-20231020223755871

可以看到图片确实模糊了。

4 非线性激活层(非必须最好有)

非线性的作用是使得神经网络能更具有鲁棒性,减少过拟合。

比较常用的Relu、sigmod等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import torch
import torchvision
from torch import nn
from torch.nn import ReLU,Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 取测试集数据,并将其转换为tensor数据类型
dataset = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=64)

class Jihuo(nn.Module):
def __init__(self):
super(Jihuo,self).__init__()
self.relu = ReLU()
self.sigmod = Sigmoid()


def forward(self,x):
x = self.sigmod(x)
return x

jihuo = Jihuo()
step = 1
writer = SummaryWriter("logs")
for data in dataloader:
imgs,targets = data
output = jihuo(imgs)
writer.add_images("imgs",output,step)
print(output.shape)
step += 1

writer.close()

sigmod非线性激活:

image-20231020223827415

5 全连接层(线性层)

输出最后结果的层。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import torch
import torchvision
from torch import nn
from torch.nn import ReLU,Sigmoid,Linear
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 取测试集数据,并将其转换为tensor数据类型
dataset = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=64)

class Line(nn.Module):
def __init__(self):
super(Line,self).__init__()
self.Line = Linear(196608,10)

def forward(self,x):
x = self.Line(x)
return x

line = Line()
step = 1

for data in dataloader:
imgs,targets = data
input = torch.reshape(imgs,(1,1,1,-1))

output = jihuo(input)

print(output.shape)
step += 1


6 其他层

只做简单介绍,比较进阶了。

6.1 归一化层

归一化数据。

6.2 正则化层

正则化层通过在损失函数中引入正则化项,限制模型的复杂性,从而提高模型的泛化能力,防止过拟合。

6.3 recurrent层

特定的网络结构,比如lstm。

6.4 transfrom层

特定的神经网络层。

6.5 dropout 层

失活层,防止过拟合。

7 使用sequential搭建一个完整的神经网络

使用CIFAR10 model的结构。

image-20231021133852299

可以看到先进行5*5卷积,从3通道换成了32通道,再进行2*2池化,再进行5*5卷积,再进行2*2池化,再进行5*5卷积,再进行2*2池化,最后把64*4*4转换为64向量,在转换为10向量输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import torch
import torchvision
from torch import nn
from torch.nn import ReLU,Sigmoid,Linear,Sequential,Conv2d,MaxPool2d,Flatten
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 取测试集数据,并将其转换为tensor数据类型
dataset = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=64)

class Seq(nn.Module):
def __init__(self):
super(Seq,self).__init__()
self.model = nn.Sequential(
Conv2d(3,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,64,5,padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024,64),
Linear(64,10)
)

def forward(self,x):
x = self.model(x)
return x

seq = Seq()
step = 1

for data in dataloader:
imgs,targets = data

output = seq(imgs)

#print(output.shape)
step += 1
writer = SummaryWriter("logs")
writer.add_graph(seq,torch.ones((64,3,32,32)))
writer.close() ~~~import torchimport torchvisionfrom torch import nnfrom torch.nn import ReLU,Sigmoid,Linear,Sequential,Conv2d,MaxPool2d,Flattenfrom torch.utils.data import DataLoaderfrom torch.utils.tensorboard import SummaryWriter# 取测试集数据,并将其转换为tensor数据类型dataset = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)dataloader = DataLoader(dataset,batch_size=64)class Seq(nn.Module): def __init__(self): super(Seq,self).__init__() self.model = nn.Sequential( Conv2d(3,32,5,padding=2), MaxPool2d(2), Conv2d(32,32,5,padding=2), MaxPool2d(2), Conv2d(32,64,5,padding=2), MaxPool2d(2), Flatten(), Linear(1024,64), Linear(64,10) ) def forward(self,x): x = self.model(x) return x seq = Seq()step = 1for data in dataloader: imgs,targets = data output = seq(imgs) #print(output.shape) step += 1writer = SummaryWriter("logs")writer.add_graph(seq,torch.ones((64,3,32,32)))writer.close()
image-20231021135206401

8 反向传播和优化器

反向传播计算损失值并反向传播计算梯度,优化器利用损失值,使其逼近targets。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import torch
import torchvision
from torch import nn
from torch.nn import ReLU,Sigmoid,Linear,Sequential,Conv2d,MaxPool2d,Flatten
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 取测试集数据,并将其转换为tensor数据类型
dataset = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=1)

class Seq(nn.Module):
def __init__(self):
super(Seq,self).__init__()
self.model = nn.Sequential(
Conv2d(3,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,64,5,padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024,64),
Linear(64,10)
)

def forward(self,x):
x = self.model(x)
return x

seq = Seq()
step = 1
loss = nn.CrossEntropyLoss()
optim = torch.optim.SGD(seq.parameters(),lr=0.01)

for j in range(10):
losssum = 0.0
for data in dataloader:
imgs,targets = data

output = seq(imgs)

# 反向传播
# 交叉熵

result = loss(output,targets)
losssum += result
# 计算梯度

optim.zero_grad()
result.backward()
optim.step()
step += 1
print(losssum)

image-20231021141457601

可见损失值一直在减小,符合我们的预期。


神经网络的基本骨架
http://example.com/2023/10/21/神经网络的基本骨架/
作者
Guoxin
发布于
2023年10月21日
许可协议