网站外包建设,宁波网站建设公司制作网站,如何做网站评估分析,wordpress 老萨描述
残差网络是现代卷积神经网络的一种#xff0c;有效的抑制了深层神经网络的梯度弥散和梯度爆炸现象#xff0c;使得深度网络训练不那么困难。
下面以cifar-10-batches-py数据集#xff0c;实现一个ResNet18的残差网络#xff0c;通过继承nn.Module实现残差块#xff0…描述残差网络是现代卷积神经网络的一种有效的抑制了深层神经网络的梯度弥散和梯度爆炸现象使得深度网络训练不那么困难。下面以cifar-10-batches-py数据集实现一个ResNet18的残差网络通过继承nn.Module实现残差块Residual Block网络模型类。定义BlockResNetBlock派生至nn.Module需要自己实现forward函数。torch.nn.Module是nn中十分重要的类包含网络各层的定义及forward方法可以从这个类派生自己的模型类。nn.Module重要的函数forward(self,*input)forward函数为前向传播函数需要自己重写它用来实现模型的功能并实现各个层的连接关系__call__(self, *input, **kwargs) __call__()的作用是使class实例能够像函数一样被调用以“对象名()”的形式使用__repr__(self)__repr__函数为Python的一个内置函数它能把一个对象用字符串的形式表达出来__init__(self)构造函数自定义模型的网络层对象一般在这个函数中定义。classResNetBlock(nn.Module):def__init__(self,input_channels,num_channels,stride1): 构造函数定义网络层 super().__init__()self.conv1nn.Conv2d(input_channels,num_channels,kernel_size3,padding1,stridestride)self.btn1nn.BatchNorm2d(num_channels)self.conv2nn.Conv2d(num_channels,num_channels,kernel_size3,padding1,stride1)self.btn2nn.BatchNorm2d(num_channels)ifstride!1:self.downsamplenn.Conv2d(input_channels,num_channels,kernel_size1,stridestride)else:self.downsamplelambdax:xdefforward(self,X): 实现反向传播 Yself.btn1(self.conv1(X))Ynn.functional.relu(Y)Yself.btn2(self.conv2(Y))Yself.downsample(X)returnnn.functional.relu(Y)定义模型ResNet同样派生于nn.Module与ResNetBlock类似需要实现forward。torch.nn.Sequential是PyTorch 中一个用于构建顺序神经网络模型的容器类它将多个神经网络层或模块按顺序组合在一起简化模型搭建过程。Sequential器会严格按照添加的顺序执行内部的子模块前向传播时自动传递数据适用于简单神经网络的构建。classResNet(nn.Module):def__init__(self,layer_dism,num_class10): 构造函数定义预处理model构建block层 super(ResNet,self).__init__()# 预处理self.stemnn.Sequential(nn.Conv2d(3,64,3,1),# 3x30x30nn.BatchNorm2d(64),nn.ReLU(),nn.MaxPool2d(2,2)# 64x15x15)self.layer1self.build_resblock(64,64,layer_dism[0])self.layer2self.build_resblock(64,128,layer_dism[1],2)self.layer3self.build_resblock(128,256,layer_dism[2],2)self.layer4self.build_resblock(256,512,layer_dism[3],2)self.avgpoolnn.AvgPool2d(1,1)self.btnnn.Flatten()self.fcnn.Linear(512,num_class)defbuild_resblock(self,input_channels,num_channels,block,stride1):res_blocknn.Sequential()res_block.append(ResNetBlock(input_channels,num_channels,stride))for_inrange(1,block):res_block.append(ResNetBlock(num_channels,num_channels,stride))returnres_blockdefforward(self,X):outself.stem(X)outself.layer1(out)outself.layer2(out)outself.layer3(out)outself.layer4(out)outself.avgpool(out)returnself.fc(self.btn(out))模型训练加载数据使用torchvision.datasets加载本地数据如果本地没有数据可以设置downloadTrue自动下载。# 定义数据转换transformtransforms.Compose([transforms.ToTensor(),# 将PIL图像转换为Tensortransforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))# 归一化])# 加载CIFAR-10训练集trainsettorchvision.datasets.CIFAR10(rootrD:\dwload,trainTrue,downloadFalse,transformtransform)trainloaderth.utils.data.DataLoader(trainset,batch_size16,shuffleFalse,num_workers2)# 加载CIFAR-10测试集testsettorchvision.datasets.CIFAR10(rootrD:\dwload,trainFalse,downloadFalse,transformtransform)testloaderth.utils.data.DataLoader(testset,batch_size16,shuffleFalse,num_workers2)模型初始化模型初始化是确保网络能够有效学习的关键步骤一个好的初始值会使模型收敛速度提高使模型准确率更精确。torch.nn.init模块提供了一系列的权重初始化函数torch.nn.init.uniform_ 均匀分布torch.nn.init.normal_ 正态分布torch.nn.init.constant_初始化为指定常数torch.nn.init.kaiming_uniform_凯明均匀分布torch.nn.init.kaiming_normal_凯明正态分布torch.nn.init.xavier_uniform_Xavier均匀分布torch.nn.init.xavier_normal_Xavier正态分布在初始化时最好不要将模型的参数初始化为0因为这样会导致梯度消失进而影响训练效果。可以将模型初始化为一个很小的值如0.010.001等。definitialize_weight(m):ifisinstance(m,nn.Conv2d)orisinstance(m,nn.Linear):nn.init.kaiming_normal_(m.weight,modefan_out,nonlinearityrelu)# mode权重方差计算方式可选 fan_in 或 fan_out输入、输出神经元数量# nonlinearity激活函数类型用于调整计算公式 一般是relu、leaky_reluifm.biasisnotNone:nn.init.constant_(m.bias,0)[2,2,2,2] 参数分别代表四个block的中的残差块数量可以仔细看一下build_resblock函数resnet_18ResNet([2,2,2,2])resnet_18.apply(initialize_weight)# 初始化模型loss_crossnn.CrossEntropyLoss()trainerth.optim.SGD(resnet_18.parameters())训练训练过程比较漫长这里训练只有20轮测试精度0.51。如果有N卡加持的话可以适当调高epoch精度能进一步提高。forepochinrange(0,20):running_loss0.0forinputs,labelsintrainloader:trainer.zero_grad()outputsresnet_18(inputs)lossloss_cross(outputs,labels)loss.backward()trainer.step()running_lossloss.item()print(f[{epoch1}] ev loss:{running_loss/3125})running_loss0.0