Análisis de red de AlexNet
Directorio de artículos
reflejos
-
Por primera vez, se introduce GPU para entrenamiento de aceleración de red, entre los cuales, la siguiente figura muestra el uso de dos GPU para entrenamiento
-
Uso de la función de activación de ReLU
-
En las dos primeras capas de la capa completamente conectada, Dropout se usa para desactivar neuronas aleatoriamente para reducir el sobreajuste
estructura de red
La fórmula para calcular el tamaño de la matriz después de la convolución es:
N = (W-F+P1+P2)/S+1
W
-El tamaño de la imagen de entrada W*W F
-El tamaño del kernel de convolución FxF;
P1
: El número de relleno encima de la imagen; P2
: El número de relleno debajo de la imagen; S
: Tamaño de paso
Conv1
Entrada: (3,224,224)
W=224,F=11,P=[1,2],S=4,N=(224-11+1+2)/4+1=55
Salida: (96,55,55)
maxpool1
Entrada: (96,55,55)
W=55,F=3,P=[0,0],S=2,N=(55-3)/2+1=27
Salida: (96,27,27)
Conv2
Entrada: (96,27,27)
W=27,F=5,P=[2,2],S=1,N=(27-5+4)/1+1=27
Salida: (256,27,27)
maxpool2
Entrada: (256,27,27)
W=27,F=3,P=[0,0],S=2,N=(27-3)/2+1=13
Salida: (256,13,13)
Conv3
Entrada: (256,13,13)
W=13,F=3,P=[1,1],S=1,N=(13-3+1+1)/1+1=13
Salida: (384,13,13)
Conv4
Entrada: (384,13,13)
W=13,F=3,P=[1,1],S=1,N=(13-3+1+1)/1+1=13
Salida: (384,13,13)
Conv5
Entrada: (384,13,13)
W=13,F=3,P=[1,1],S=1,N=(13-3+1+1)/1+1=13
Salida: (256,13,13)
reproducción de código
class AlexNet(nn.Module):
def __init__(self,num_classes=1000,init_weights=False):
super(AlexNet, self).__init__()
# nn.Sequential 简化步骤
self.features = nn.Sequential(
# 特征提取层
# Input[3,224,224] output[48,55,55]
nn.Conv2d(3,48,kernel_size=11,stride=4,padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3,stride=2),
nn.Conv2d(48,128,kernel_size=5,padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3,stride=2),
nn.Conv2d(128,192,kernel_size=3,padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(192, 192, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(192, 128, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(
# 全连接层
nn.Dropout(p=0.5), # p:神经元随机失活的比例
nn.Linear(128*6*6,2048),
nn.ReLU(inplace=True),
nn.Dropout(p=0.5),
nn.Linear(2048,2048),
nn.ReLU(inplace=True),
nn.Linear(2048,num_classes) # num_classes:分类的类别数
)
if init_weights:
self._initialize_weights()
def forward(self,x):
x = self.features(x)
x = torch.flatten(x,start_dim=1)
x = self.classifier(x)
return x
# 初始化权重
def _initialize_weights(self):
# 遍历整个modules
for m in self.modules():
# 发现有nn.Conv2d这个结构
if isinstance(m,nn.Conv2d):
# 凯明初始化权重
nn.init.kaiming_normal_(m.weight,mode='fan_out', nonlinearity='relu')
if m.bias is not None:
nn.init.constant_(m.bias,0)
# 发现有nn.Linear,则使用正态分布初始化函数
elif isinstance(m,nn.Linear):
nn.init.normal_(m.weight,0,0.01)
nn.init.constant_(m.bias,0)