一、LeNet网络(1998)
LeNet网络有五层。两个卷积层,三个全连接层。这里说的卷积层包括激活层和池化层,全连接层包括连接层和激活层。
self.conv = torch.nn.Sequential(
torch.nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5,stride=1,padding=0),
torch.nn.Sigmoid(),
torch.nn.MaxPool2d(kernel_size=(2,2),stride=2),
torch.nn.Conv2d(in_channels=6,out_channels=16,kernel_size=5,stride=1,padding=0),
torch.nn.Sigmoid(),
torch.nn.MaxPool2d(kernel_size=(2,2),stride=2)
)
self.fc = torch.nn.Sequential(
torch.nn.Linear(16*4*4,120),
torch.nn.Sigmoid(),
torch.nn.Linear(120,84),
torch.nn.Sigmoid(),
torch.nn.Linear(84,10)
)
二、AlexNet网络(2012)
AlexNet网络一共有八层,前有五个卷积层,后面为三个全连接层。
self.conv = nn.Sequential(
nn.Conv2d(1, 96, 11, 4),
nn.ReLU(),
nn.MaxPool2d(3, 2),
nn.Conv2d(96, 256, 5, 1, 2),
nn.ReLU(),
nn.MaxPool2d(3, 2),
nn.Conv2d(256, 384, 3, 1, 1),
nn.ReLU(),
nn.Conv2d(384, 384, 3, 1, 1),
nn.ReLU(),
nn.Conv2d(384, 256, 3, 1, 1),
nn.ReLU(),
nn.MaxPool2d(3, 2)
)
self.fc = nn.Sequential(
nn.Linear(256*5*5, 4096),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(4096, 4096),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(4096, 10),
)
激活函数的选取和区别:
1、sigmoid函数:
f
(
x
)
=
1
/
(
1
+
e
(
−
x
)
)
f(x)={1}/{(1+e^{(-x)})}
f(x)=1/(1+e(−x))
(1)sigmoid函数当值特别大或者特别小,会是梯度趋于0,即sigmoid函数饱和使梯度消失。
(2)sigmoid函数输出不是“零为中心”
(3)指数函数的计算是比较消耗计算资源的。
2、tanh函数
t
a
n
h
(
x
)
=
(
1
−
e
−
2
x
)
/
(
1
+
e
−
2
x
)
tanh(x) = {(1-e^{-2x})/(1+e^{-2x})}
tanh(x)=(1−e−2x)/(1+e−2x)
(1)tanh解决了sigmoid的输出非“零为中心”的问题
(2)依然有过饱和的问题
(3)依然进行的是指数运算
3、ReLU函数
f
(
x
)
=
m
a
x
(
0
,
x
)
f(x)=max(0,x)
f(x)=max(0,x)
(1)解决了梯度消失的问题,至少x在正区间内,神经元不会饱和;
(2)由于ReLU线性、非饱和的形式,在SGD中能够快速收敛;
(3)运算速度要快很多。ReLU函数只有线性关系,不需要指数计算,不管前向传播还是反向传播,计算速度都比sigmoid和tanh快。
还有几种类似ReLU函数的激活函数,这里不详细说了