当前位置: 首页 > news >正文

网站怎么加内容吗男女做的那些事情的网站

网站怎么加内容吗,男女做的那些事情的网站,爱网站黄,长春网站设计文章目录 前言五、深度学习计算5.1层和块5.2 参数管理5.3 延后初始化5.4 自定义层5.5读写文件5.6 GPU 二、卷积神经网络6.2图像卷积6.2填充和步幅6.2多输入和多输出通道6.2.1多输入通道6.2.2多输出通道1*1卷积 6.3池化6.4 卷积神经网络Lenet 五、现代卷积神经网络5.1 Alex net5… 文章目录 前言五、深度学习计算5.1层和块5.2 参数管理5.3 延后初始化5.4 自定义层5.5读写文件5.6 GPU 二、卷积神经网络6.2图像卷积6.2填充和步幅6.2多输入和多输出通道6.2.1多输入通道6.2.2多输出通道1*1卷积 6.3池化6.4 卷积神经网络Lenet 五、现代卷积神经网络5.1 Alex net5.2 VGG网络5.3 NiN网络5.4 GoogleNET5.5批量规范换5.7 残差网络 总结 前言 这篇是我的读书笔记记录第5到10章内容 五、深度学习计算 5.1层和块 这里开始介绍Pytorch的一些代码框架这里net是一个类大示例net后接一个元组会调用这个类的net.call(X)方法call(X)方法在pytorch中会调用模块的forward方法 import torch from torch import nn from torch.nn import functional as F net nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10)) X torch.rand(2, 20) net(X)这里self._modules[str(idx)]是一个有序字典在模块参数初始化过程中系统会在这里self._modules[str(idx)]里查找模块并初始化。net MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))比如MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10)会被顺序的保存在有序字典里并在net.parameters()中桉顺序查找各个模块的参数。 class MySequential(nn.Module):def __init__(self, *args):super().__init__()for idx, module in enumerate(args):# 这里module是Module子类的一个实例。我们把它保存在Module类的成员# 变量_modules中。_module的类型是OrderedDictself._modules[str(idx)] moduledef forward(self, X):# OrderedDict保证了按照成员添加的顺序遍历它们for block in self._modules.values():X block(X)return X模块或者层的forward方法可以嵌入一些python运算自己定义写复杂功能并且可以指定那些参数是不能更新的也就是常数比如这里的self.rand_weight就是常数我们指定它不需要计算梯度。 class FixedHiddenMLP(nn.Module):def __init__(self):super().__init__()# 不计算梯度的随机权重参数。因此其在训练期间保持不变self.rand_weight torch.rand((20, 20), requires_gradFalse)self.linear nn.Linear(20, 20)def forward(self, X):X self.linear(X)# 使用创建的常量参数以及relu和mm函数X F.relu(torch.mm(X, self.rand_weight) 1)# 复用全连接层。这相当于两个全连接层共享参数X self.linear(X)# 控制流while X.abs().sum() 1:X / 2return X.sum()注意self.module_的嵌套格式将来参数初始化的时候也是递归初始化的。 class NestMLP(nn.Module):def __init__(self):super().__init__()self.net nn.Sequential(nn.Linear(20, 64), nn.ReLU(),nn.Linear(64, 32), nn.ReLU())self.linear nn.Linear(32, 16)def forward(self, X):return self.linear(self.net(X))chimera nn.Sequential(NestMLP(), nn.Linear(16, 20), FixedHiddenMLP()) chimera(X)Sequential( (0): NestMLP( (net): Sequential( (0): Linear(in_features20, out_features64, biasTrue) (1): ReLU() (2): Linear(in_features64, out_features32, biasTrue) (3): ReLU() ) (linear): Linear(in_features32, out_features16, biasTrue) ) (1): Linear(in_features16, out_features20, biasTrue) (2): FixedHiddenMLP( (linear): Linear(in_features20, out_features20, biasTrue) ) ) 5.2 参数管理 import torch from torch import nn net nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1)) X torch.rand(size(2, 4)) print(net.state_dict())#参数通过有序字典来管理 next(iter(net[0].named_parameters()))#net[0].named_parameters()返回的是一个生成器一次返回一个元组(名称数值) net.state_dict()[2.bias].data#在net.state_dict()我们应该观察到其返回值是一个生成器一次生成一个元组包含名字和值这名字是更具层的嵌套和参数的索引生成的比如这里2.bias #这里生成一个嵌套层 def block1():return nn.Sequential(nn.Linear(4, 8), nn.ReLU(),nn.Linear(8, 4), nn.ReLU()) def block2():net nn.Sequential()for i in range(4):# 在这里嵌套net.add_module(fblock {i}, block1())return net rgnet nn.Sequential(block2(), nn.Linear(4, 1)) rgnet(X) print(*[(name, param.shape) for name, param in rgnet.named_parameters()])#这里的生成器一次就会返回(0.block 0.0.weight, torch.Size([8, 4])) 这样的一个元组名字是各个层的名字和参数的嵌套 #参数初始化方法 nn.init.normal_(m.weight, mean0, std0.01) nn.init.zeros_(m.bias) nn.init.constant_(m.weight, 1) nn.init.xavier_uniform_(m.weight) nn.init.constant_(m.weight, 42) nn.init.uniform_(m.weight, -10, 10) #层的权重是可以直接访问和更新的 net[0].weight.data[:] 1 # 我们需要给共享层一个名称以便可以引用它的参数 #可以建立共享层也就是用同一套权重和偏执这在后面防止过拟合时会用到。 shared nn.Linear(8, 8) net nn.Sequential(nn.Linear(4, 8), nn.ReLU(),shared, nn.ReLU(),shared, nn.ReLU(),nn.Linear(8, 1)) net(X) # 检查参数是否相同 print(net[2].weight.data[0] net[4].weight.data[0]) net[2].weight.data[0, 0] 100 # 确保它们实际上是同一个对象而不只是有相同的值 print(net[2].weight.data[0] net[4].weight.data[0]) #类似于引用梯度时由于在两个位置出现share层的权重和梯度要加和的。5.3 延后初始化 这个技术挺实用的可以等到输入数据X并从X中推断输入层的输入端数量并初始化网络。识别出第一层的形状后框架处理第二层依此类推直到所有形状都已知为止。 注意在这种情况下只有第一层需要延迟初始化但是框架仍是按顺序初始化的。 等到知道了所有的参数形状框架就可以初始化参数。 5.4 自定义层 class MyLinear(nn.Module):def __init__(self, in_units, units):super().__init__()self.weight nn.Parameter(torch.randn(in_units, units))self.bias nn.Parameter(torch.randn(units,))def forward(self, X):linear torch.matmul(X, self.weight.data) self.bias.datareturn F.relu(linear)linear MyLinear(5, 3) linear.weight#可以通过传统方法也就时变量名字的方式直接访问 next(iter(linear.named_parameters())) #也可以通过生成器访问 #结合这个类体会一下.named_parameters()这个生成器在类的初始化过程中参数需要通过nn.Parameter(torch.randn(in_units, units))进行实例化这个过程中会生成一个变量名字和变量值的键值对5.5读写文件 import torch from torch import nn from torch.nn import functional as F x torch.arange(4) torch.save(x, x-file) #文件名字x-file x2 torch.load(x-file) #一个文件可以存一个张量列表 y torch.zeros(4) torch.save([x, y],x-files) x2, y2 torch.load(x-files) #一个文件存一个张量字典 mydict {x: x, y: y} torch.save(mydict, mydict) mydict2 torch.load(mydict) ##存一个模型也就是存模型参数 class MLP(nn.Module):def __init__(self):super().__init__()self.hidden nn.Linear(20, 256)self.output nn.Linear(256, 10)def forward(self, x):return self.output(F.relu(self.hidden(x))) net MLP() X torch.randn(size(2, 20)) Y net(X) torch.save(net.state_dict(), mlp.params) clone MLP() clone.load_state_dict(torch.load(mlp.params))#初始化一个训练好的模型 clone.eval() 5.6 GPU nvidia-smi黑窗口查询英伟达GPU是否安装好驱动和cuda import torch from torch import nn torch.device(cpu), torch.device(cuda), torch.device(cuda:1) #pytorch的device支持cpu和GPU以及多个GPU torch.cuda.device_count()#返回GPU数量 x torch.tensor([1, 2, 3]) x.device#查找张量位置CPU还是GPU X torch.ones(2, 3, devicetorch.device(cuda:0)) #指定张量位置 Z X.cuda(1) #将GPU0上X复制到GPU1上变量Z Y torch.ones(2, 3, torch.device(cuda:1) YZ#同一个device才能相加 net nn.Sequential(nn.Linear(3, 1)) net net.to(devicetorch.device(cuda:0)) #指定net在那个deivice 二、卷积神经网络 6.2图像卷积 下面的代码很重要解释了pytorch中卷积或者相关是如何计算的简单结论是pytorch的卷积是在input_channel,kernel_h,kernel_w)这三个维度上相乘求和的代码如下 import torch from torch import nn from d2l import torch as d2l X torch.arange(2*3*4,dtypetorch.float).reshape(1,2,3,4) #这里batchinput_channel,h,w这里重要讲解一下input_channel我们后面卷积网络的weight的input_channel必须和X这里一致 conv2d nn.Conv2d(2,1, kernel_size(1, 2), biasFalse)#nn.conv2d(input_channel,output_channel,...)这里input_channel需要和输入X的input_channel一致也就是说卷积或者相关是在input_channel,kernel_h,kernel_w)这三个维度上相乘求和的。 nn.init.constant_(conv2d.weight,2)#将卷积核初始化成常数方便检查卷积的运算规律 X,conv2d(X), conv2d(X).shape,conv2d.weight.data.shape #打印结果印证猜想这里有个训练求解卷积核的代码如下 # 构造一个二维卷积层它具有1个输出通道和形状为12的卷积核 X torch.ones((2*6, 8)) K torch.tensor([[1.0, -1.0]]) #这个是我们目标卷积核,形状是1,2)这里容易误解我们pytorch里还有一个维度通道 Y corr2d(X, K)# X X.reshape((2, 1, 6, 8))#恢复成batchchannelhw这个pytorch的格式 Y Y.reshape((2, 1, 6, 7))#目标数据 conv2d nn.Conv2d(1,1, kernel_size(1, 2), biasFalse) #这里由于X是一个输入通道所以输入通道为1其实目标核本质也是一个通道# 这个二维卷积层使用四维输入和输出格式批量大小、通道、高度、宽度 # 其中批量大小和通道数都为1lr 3e-2 # 学习率for i in range(10):Y_hat conv2d(X)l (Y_hat - Y) ** 2conv2d.zero_grad()#清零l.sum().backward()#反向传播计算梯度# 迭代卷积核conv2d.weight.data - lr * conv2d.weight.grad #更新权重if (i 1) % 2 0:print(fepoch {i1}, loss {l.sum():.3f})6.2填充和步幅 import torch from torch import nn X torch.ones(size(1,1,8, 8)) conv2d nn.Conv2d(1, 1, kernel_size(3, 5), padding(0, 1), stride(3, 4)) conv2d(X).shape #torch.Size([1, 1, 2, 2])#这里分析h原始X有8行padding0行-kernel3hang/stride_3行11起始位置行6.2多输入和多输出通道 6.2.1多输入通道 这个图很好的解释了多输入通道内核内核时(c,h,w)三个维度的 6.2.2多输出通道 多输出通道不要看他的公式反而容易被误导多输出意思会提供不同的卷积核由于多输入通道数据和多通道卷积核在通道维度上时降维的所以只需要将不同卷积核降维结果重新在通道上堆叠stack即可。 1*1卷积 其实1*1卷积的唯一计算发生在通道上只在通道上加和降维。下面这个图很形象演示了第一个输出通道浅色的第一个元素和第二个输出通道的最后一个元素输入时三个通道。 6.3池化 X torch.arange(16, dtypetorch.float32).reshape((1, 1, 4, 4)) pool2d nn.MaxPool2d((2, 3), stride(2, 3), padding(0, 1)) #可以指定h和w上的补充和步幅 pool2d nn.MaxPool2d(3, padding1, stride2)#省略情况下h和w一致 pool2d nn.MaxPool2d(3)#超级省略hw3零填充步幅和池化高和宽一致 X torch.cat((X, X 1), 1)#X的shape变成(1,2,4,4) pool2d nn.MaxPool2d(3, padding1, stride2)#池化是在每个输入通道上单独运算也就是池化层输出和输入的通道数是一样的 6.4 卷积神经网络Lenet import torch from torch import nn from d2l import torch as d2l #这里输入图片是黑白图片像素为28*28黑白图像意味着输入通道数为一 net nn.Sequential(nn.Conv2d(1, 6, kernel_size5, padding2), #输入通道为1输出通道为6意味着有6个卷积核也意味着从这一层输出的数据通道数为6也就是shape为batch,6,28,28)nn.Sigmoid(),#不改变数据shape batchsize,6,28,28)nn.AvgPool2d(kernel_size2, stride2),#输入batchsize,6,28,28)pool不改变通道数28-2(kernel_size)/2(stride)1(起始位置)所以输出形状为(batchsize,6,14,14)nn.Conv2d(6, 16, kernel_size5), #输入(batchsize,6,14,14)输出通道数16也就是16个内核14-5110,所以输出batchsize,16,1010nn.Sigmoid(),#不改变数据shape batchsize,16,1010nn.AvgPool2d(kernel_size2, stride2), #输入batchsize,16,1010pool不改变通道数量10-2/215,输出batchsize,6,55nn.Flatten(), #batchsize,16*5*5400)nn.Linear(16 * 5 * 5, 120), #400输入120输出全连接层nn.Sigmoid(), #不改变形状nn.Linear(120, 84), #输入120输出84nn.Sigmoid(),nn.Linear(84, 10)) #输入84输出10Lenet用来识别手写数字的#检查每层张量输出的形状 def init_weights(m):if type(m) nn.Linear or type(m) nn.Conv2d:nn.init.xavier_uniform_(m.weight) net.apply(init_weights) #prepare the dataset trans[transforms.ToTensor()] transtransforms.Compose(trans) mnist_train torchvision.datasets.FashionMNIST(root../data, trainTrue, transformtrans, downloadTrue) mnist_test torchvision.datasets.FashionMNIST(root../data, trainFalse, transformtrans, downloadTrue) train_itertorch.utils.data.DataLoader(mnist_train, batch_size, shuffleTrue, num_workers4) test_itertorch.utils.data.DataLoader(mnist_test, batch_size, shuffleFalse, num_workers4) #parameters and optimizer batch_size,lr, num_epochs 256,0.9, 10 optimizer torch.optim.SGD(net.parameters(), lrlr) loss nn.CrossEntropyLoss() #很好的画图工具 animator d2l.Animator(xlabelepoch, xlim[1, num_epochs],legend[train loss, train acc, test acc]) metric_traind2l.Accumulator(3) metric_testd2l.Accumulator(2) for epoch in range(num_epochs): # 训练损失之和训练准确率之和样本数 net.train()for X, y in train_iter:optimizer.zero_grad()y_hat net(X)l loss(y_hat, y)#这里是样本batchsize上的平均损失l.backward()optimizer.step()metric_train.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])with torch.no_grad():net.eval() for X, y in train_iter:metric_test.add(d2l.accuracy(net(X), y), X.shape[0]) train_l metric_train[0] / metric_train[2]train_acc metric_train[1] / metric_train[2]test_acc metric_test[0] / metric_test[1]animator.add(epoch 1, (train_l, train_acc, test_acc)) 五、现代卷积神经网络 5.1 Alex net AlexNet是参考Lenet网络这里是神经网络的起点指望卷积神经网络自动提取特征值为了兼容特征值的视野需要多层卷积但是多层卷积会导致参数数量多层数多了以后会导致梯度消失或者梯度爆炸。2012年AlexNet横空出世。它首次证明了学习到的特征可以超越手工设计的特征。它一举打破了计算机视觉研究的现状意义重大的网路。 import torch from torch import nn from d2l import torch as d2l import torchvision from torchvision import transforms net nn.Sequential(# 这里使用一个11*11的更大窗口来捕捉对象。# 同时步幅为4以减少输出的高度和宽度。# 另外输出通道的数目远大于LeNetnn.Conv2d(1, 96, kernel_size11, stride4, padding1), nn.ReLU(), #output shape floor((224-112)//4)153154,output(batchsize,96,54,54)nn.MaxPool2d(kernel_size3, stride2), #floor((54-3)/2)126,output shape(batchsize,96,26,26)# 减小卷积窗口使用填充为2来使得输入与输出的高和宽一致且增大输出通道数nn.Conv2d(96, 256, kernel_size5, padding2), nn.ReLU(), #input channel number is 96,26-52*2126,output(batchsize,256,26,26)nn.MaxPool2d(kernel_size3, stride2),#floor((26-3)/2)112,output(batchsize,256,12,12)# 使用三个连续的卷积层和较小的卷积窗口。# 除了最后的卷积层输出通道的数量进一步增加。# 在前两个卷积层之后汇聚层不用于减少输入的高度和宽度nn.Conv2d(256, 384, kernel_size3, padding1), nn.ReLU(), #padding(kernel_size-1)/2,不改变形状nn.Conv2d(384, 384, kernel_size3, padding1), nn.ReLU(), #padding(kernel_size-1)/2,不改变形状nn.Conv2d(384, 256, kernel_size3, padding1), nn.ReLU(), #padding(kernel_size-1)/2,不改变形状nn.MaxPool2d(kernel_size3, stride2), #(batchsize,256,floor((12-3)/2)15,5)nn.Flatten(),# 这里全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合nn.Linear(6400, 4096), nn.ReLU(),nn.Dropout(p0.5),nn.Linear(4096, 4096), nn.ReLU(),nn.Dropout(p0.5),# 最后是输出层。由于这里使用Fashion-MNIST所以用类别数为10而非论文中的1000nn.Linear(4096, 10)) def init_weights(m):if type(m) nn.Linear or type(m) nn.Conv2d:nn.init.xavier_uniform_(m.weight) net.apply(init_weights) #prepare the dataset trans[transforms.Resize(size(224, 224)) ,transforms.ToTensor()] transtransforms.Compose(trans) mnist_train torchvision.datasets.FashionMNIST(root../data, trainTrue, transformtrans, downloadTrue) mnist_test torchvision.datasets.FashionMNIST(root../data, trainFalse, transformtrans, downloadTrue) train_itertorch.utils.data.DataLoader(mnist_train, batch_size, shuffleTrue, num_workers4) test_itertorch.utils.data.DataLoader(mnist_test, batch_size, shuffleFalse, num_workers4) #parameters and optimizer batch_size,lr, num_epochs 256,0.9, 10 optimizer torch.optim.SGD(net.parameters(), lrlr) loss nn.CrossEntropyLoss() #很好的画图工具 animator d2l.Animator(xlabelepoch, xlim[1, num_epochs],legend[train loss, train acc, test acc]) metric_traind2l.Accumulator(3) metric_testd2l.Accumulator(2) for epoch in range(num_epochs): # 训练损失之和训练准确率之和样本数 net.train()for X, y in train_iter:optimizer.zero_grad()y_hat net(X)l loss(y_hat, y)#这里是样本batchsize上的平均损失l.backward()optimizer.step()metric_train.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])with torch.no_grad():net.eval() for X, y in train_iter:metric_test.add(d2l.accuracy(net(X), y), X.shape[0]) train_l metric_train[0] / metric_train[2]train_acc metric_train[1] / metric_train[2]test_acc metric_test[0] / metric_test[1]animator.add(epoch 1, (train_l, train_acc, test_acc))c5.2 VGG网络 VGG网络和AlexNet网络一样靠堆叠卷积层缺点也是层深后难于训练。 def vgg_block(num_convs, in_channels, out_channels):layers []for _ in range(num_convs): #这里卷积层不过多少层这里out_channels不变kernel_size3, padding1导致h和w也不变layers.append(nn.Conv2d(in_channels, out_channels,kernel_size3, padding1))layers.append(nn.ReLU())in_channels out_channelslayers.append(nn.MaxPool2d(kernel_size2,stride2))#注意通过MaxPoolh和W降为一半但是out_channels不变return nn.Sequential(*layers) def vgg(conv_arch):conv_blks []in_channels 1# 卷积层部分for (num_convs, out_channels) in conv_arch:conv_blks.append(vgg_block(num_convs, in_channels, out_channels))in_channels out_channels #上一级的out_channels是下一级in_channels,这里channel和hw不要搞混return nn.Sequential(*conv_blks, nn.Flatten(),# 全连接层部分nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),nn.Linear(4096, 10))5.3 NiN网络 NiN网络相对于前两种网络在数学或者直觉上是有创新的可以借助于线性代数的概念NiN最大的创新是引入了11卷积核11卷积核允许我们对h和w维度上的单点数据表征与某个卷积核相关量的大小进行类似全连接网络的对空间进行非线性分割或者分类这增加了NiN网络的非线性或者增加了NiN分类的能力下面结合代码进行详细介绍。 def nin_block(in_channels, out_channels, kernel_size, strides, padding):return nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding), #这里如果是第一个NiN那么这就是第一个特征提取的卷积层这里生成out_channels个特征也可以理解将图像投影到out_channels为维度里在out_channels维度里进行分类并自动求解坐标这就是神经网络的魅力nn.ReLU(),nn.Conv2d(out_channels, out_channels, kernel_size1), nn.ReLU(), #这里在hw维度看的话到这里h,w都不是像素了而是特征向量大小的表征这里是卷积之后的结果应该是单特征点含量的大小或者相关程度这里我们借助于通道c维的单点卷积在通道维度上实现了全连接变换想想一下在上一次一共有out_channels个卷积核因为我们期望是在维度为out_channels空间里解决分类问题每个卷积核能看到kernel_size个像素点理论上在低纬度空间里混杂的数据在高纬度里确实是能够被仔细区分的。nn.Conv2d(out_channels, out_channels, kernel_size1), nn.ReLU()) #这里和上一行一样期望在高维度进行线性变化获得好的分类界限所以经过nin_block之后的h,w再称为像素就不合适了甚至是错误的应该称为系数高纬度坐标系数。 net nn.Sequential( #先用96个kernel_size11的卷积核不同的卷积核会提取图像的不同的特征同时我们也可以认为这些不同的特征是相互独立的不同维度对像素进行求相关或者求解特征也相当于将一小块图像kernel_size投影到一个96维度空间里再这个96空间里应用全连接网络进行分类nin_block(1, 96, kernel_size11, strides4, padding0),nn.MaxPool2d(3, stride2),nin_block(96, 256, kernel_size5, strides1, padding2),nn.MaxPool2d(3, stride2),nin_block(256, 384, kernel_size3, strides1, padding1),nn.MaxPool2d(3, stride2),nn.Dropout(0.5),# 标签类别数是10nin_block(384, 10, kernel_size3, strides1, padding1),nn.AdaptiveAvgPool2d((1, 1)), #这里最后是一个10维空间也就是我们最终数据集的种类NiN在直觉上是非常合理的提出NiN的人很牛逼。# 将四维的输出转成二维的输出其形状为(批量大小,10)nn.Flatten())5.4 GoogleNET 看了NiN相对于ALexNet解决的问题是利用11卷积核增加了卷积核之间的信息组合或者卷积核之间的分类信息提取 AlexNet没有单11卷积核NiN展现了11卷积核的必要性NiN是11卷积核和普通卷积核交替运算GoogleNet增加了11卷积核和普通卷积核同时进行运行的能力增加了数据的自由度理论上应该是网络分类能力会有增强。 如上图所示最左边是NiN网络的11卷积核经典路径左边第二路径是11卷积核之后串联33卷积核其实深入详细理解每个卷积核在分类中的作用是很难的原因可能是因为我们生活着3维空间中对高纬度空间只能利用相关值大小理解不同维度的关系比如相关值为零那么这两个向量是相互垂直的。所以11卷积核之后33卷积核具体是什么作用应该都是试出来的没有闭环理论公式进行推导。直觉理解的话就是11卷积层是不同通道不同卷积核的相关量的线性组合33又是在11卷积核输出结果之上进行特征提取相当于左边是输出是原始数据那么左2和左3是特征提取后结果右边是相当于对最大值进行跨卷积核或者在通道上进行特征提取GoogleNet的创新是通道合并层4条路经的数据在通道层串联成一个打输出数据信息更加丰富。我的个人一个感受如果能让信息自由流动往往会使神经网路更强大。这里总结一下11卷积是空间划分其他卷积是特征提取构建新的坐标系。 import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2l#这里要结合上图看代码看神经网络架构还是要画图的 class Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):super(Inception, self).__init__(**kwargs)# 线路1单1x1卷积层self.p1_1 nn.Conv2d(in_channels, c1, kernel_size1)#这里卷积核的尺寸是(in_channels,h,w)一共有c1个卷积核也就是输出通道数是c1# 线路21x1卷积层后接3x3卷积层self.p2_1 nn.Conv2d(in_channels, c2[0], kernel_size1)#输出通道c2[0]self.p2_2 nn.Conv2d(c2[0], c2[1], kernel_size3, padding1)#最终输出通道数或者说卷积核数c2[1]# 线路31x1卷积层后接5x5卷积层self.p3_1 nn.Conv2d(in_channels, c3[0], kernel_size1)self.p3_2 nn.Conv2d(c3[0], c3[1], kernel_size5, padding2)# 线路43x3最大汇聚层后接1x1卷积层self.p4_1 nn.MaxPool2d(kernel_size3, stride1, padding1)self.p4_2 nn.Conv2d(in_channels, c4, kernel_size1)def forward(self, x):p1 F.relu(self.p1_1(x))p2 F.relu(self.p2_2(F.relu(self.p2_1(x))))p3 F.relu(self.p3_2(F.relu(self.p3_1(x))))p4 F.relu(self.p4_2(self.p4_1(x)))# 在通道维度上连结输出return torch.cat((p1, p2, p3, p4), dim1)#在通道维度上合并数据b1 nn.Sequential(nn.Conv2d(1, 64, kernel_size7, stride2, padding3),nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2, padding1))#第一层普通卷积层64个卷积核输出通道数64(batchsize, out_channels,h,w) b2 nn.Sequential(nn.Conv2d(64, 64, kernel_size1),nn.ReLU(),nn.Conv2d(64, 192, kernel_size3, padding1),nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2, padding1)) #kernel_size,stride,padding都是在h和w维度上。 b3 nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32),#输入通道数192对照Inception网络最左边1*1卷积输出64通道左二是两级卷积第一级1*1输出96通道第二级3*3是128通道也就是最终128通道其他类似。Inception(256, 128, (128, 192), (32, 96), 64),nn.MaxPool2d(kernel_size3, stride2, padding1))#h,w降维度 b4 nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64),Inception(512, 160, (112, 224), (24, 64), 64),Inception(512, 128, (128, 256), (24, 64), 64),Inception(512, 112, (144, 288), (32, 64), 64),Inception(528, 256, (160, 320), (32, 128), 128),nn.MaxPool2d(kernel_size3, stride2, padding1))b5 nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),Inception(832, 384, (192, 384), (48, 128), 128),nn.AdaptiveAvgPool2d((1,1)),nn.Flatten()) b5 nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),Inception(832, 384, (192, 384), (48, 128), 128),nn.AdaptiveAvgPool2d((1,1)),nn.Flatten())net nn.Sequential(b1, b2, b3, b4, b5, nn.Linear(1024, 10)) 5.5批量规范换 本节将介绍批量规范化batch normalization这是一种流行且有效的技术可持续加速深层网络的收敛速度。 批量规范化应用于单个可选层也可以应用到所有层其原理如下在每次训练迭代中我们首先规范化输入即通过减去其均值并除以其标准差其中两者均基于当前小批量处理。 接下来我们应用比例系数和比例偏移。 正是由于这个基于批量统计的标准化才有了批量规范化的名称。从形式上来说用 x ∈ B \mathbf{x} \in \mathcal{B} x∈B表示一个来自小批量 B \mathcal{B} B的输入批量规范化 B N \mathrm{BN} BN根据以下表达式转换 x \mathbf{x} x B N ( x ) γ ⊙ x − μ ^ B σ ^ B β . \mathrm{BN}(\mathbf{x}) \boldsymbol{\gamma} \odot \frac{\mathbf{x} - \hat{\boldsymbol{\mu}}_\mathcal{B}}{\hat{\boldsymbol{\sigma}}_\mathcal{B}} \boldsymbol{\beta}. BN(x)γ⊙σ^B​x−μ^​B​​β. 这里发明批量标准化的也是一个天才尤其引入两个系数 拉伸参数scale γ \boldsymbol{\gamma} γ和偏移参数shift β \boldsymbol{\beta} β让神经网络去学习另外批量规范化层在”训练模式“通过小批量统计数据规范化和“预测模式”通过数据集统计规范化中的功能不同。 在训练过程中我们无法得知使用整个数据集来估计平均值和方差所以只能根据每个小批次的平均值和方差不断训练模型。 而在预测模式下可以根据整个数据集精确计算批量规范化所需的平均值和方差。 这里重点讲解卷积层的批量规范化对于卷积层我们可以在卷积层之后和非线性激活函数之前应用批量规范化。当卷积有多个输出通道时我们需要对这些通道的“每个”输出执行批量规范化每个通道都有自己的拉伸参数scale γ \boldsymbol{\gamma} γ和偏移参数shift β \boldsymbol{\beta} β这两个参数都是标量。 假设我们的小批量包含 m m m个样本并且对于每个通道卷积的输出具有高度 p p p和宽度 q q q。 那么对于卷积层我们在每个输出通道的 m ⋅ p ⋅ q m \cdot p \cdot q m⋅p⋅q个元素上同时执行每个批量规范化。 因此在计算平均值和方差时我们会收集所有空间位置的值然后在给定通道内应用相同的均值和方差以便在每个空间位置对值进行规范化。正如我们前面提到的批量规范化在训练模式和预测模式下的行为通常不同这里对应net.train()和net.eval()。首先将训练好的模型用于预测时我们不再需要样本均值中的噪声以及在微批次上估计每个小批次产生的样本方差了。其次例如我们可能需要使用我们的模型对逐个样本进行预测。一种常用的方法是通过移动平均估算整个训练数据集的样本均值和方差并在预测时使用它们得到确定的输出。可见和暂退法一样批量规范化层在训练模式和预测模式下的计算结果也是不一样的。 这里有个简单代码只考虑全连接层和卷积层 import torch from torch import nn from d2l import torch as d2l def batch_norm(X, gamma, beta, moving_mean, moving_var, eps, momentum):# 通过is_grad_enabled来判断当前模式是训练模式还是预测模式if not torch.is_grad_enabled():#区分net.train()和net.eval()# 如果是在预测模式下直接使用传入的移动平均所得的均值和方差X_hat (X - moving_mean) / torch.sqrt(moving_var eps)else:assert len(X.shape) in (2, 4)#判断是全连接层(batchsize,feature)还是卷积层(cin,cout,h,w)if len(X.shape) 2:# 使用全连接层的情况计算特征维上的均值和方差mean X.mean(dim0)var ((X - mean) ** 2).mean(dim0)#全连接层均值和var计算else:# 使用二维卷积层的情况计算通道维上axis1的均值和方差。# 这里我们需要保持X的形状以便后面可以做广播运算mean X.mean(dim(0, 2, 3), keepdimTrue)var ((X - mean) ** 2).mean(dim(0, 2, 3), keepdimTrue)#卷积层是在每个通道上计算所有元素的均值和方差# 训练模式下用当前的均值和方差做标准化X_hat (X - mean) / torch.sqrt(var eps)# 更新移动平均的均值和方差moving_mean momentum * moving_mean (1.0 - momentum) * meanmoving_var momentum * moving_var (1.0 - momentum) * varY gamma * X_hat beta # 缩放和移位这两个参数将通过nn.Parameters进行定义并在训练时被更新。return Y, moving_mean.data, moving_var.data #一个简单示例实现 class BatchNorm(nn.Module):# num_features完全连接层的输出数量或卷积层的输出通道数。# num_dims2表示完全连接层4表示卷积层def __init__(self, num_features, num_dims):super().__init__()if num_dims 2:shape (1, num_features)else:shape (1, num_features, 1, 1)# 参与求梯度和迭代的拉伸和偏移参数分别初始化成1和0并在训练过程中被更新。self.gamma nn.Parameter(torch.ones(shape))self.beta nn.Parameter(torch.zeros(shape))# 非模型参数的变量初始化为0和1self.moving_mean torch.zeros(shape)self.moving_var torch.ones(shape)def forward(self, X):# 如果X不在内存上将moving_mean和moving_var# 复制到X所在显存上if self.moving_mean.device ! X.device:self.moving_mean self.moving_mean.to(X.device)self.moving_var self.moving_var.to(X.device)# 保存更新过的moving_mean和moving_varY, self.moving_mean, self.moving_var batch_norm(X, self.gamma, self.beta, self.moving_mean,self.moving_var, eps1e-5, momentum0.9)return Y很喜欢作者个这段话“虽然深度神经网络的概念非常简单——将神经网络堆叠在一起。但由于不同的网络架构和超参数选择这些神经网络的性能会发生很大变化。 本章介绍的神经网络是将人类直觉和相关数学见解结合后经过大量研究试错后的结晶。”AI有时候都是在靠直觉设计架构怎么让数据更自由怎么少丢信息怎么样减少训练量这真是一个门槛低天花板极高的行业。 5.7 残差网络 作者放这个图的意思当我们往新架构中添加层期望是神经网络比添加之前更强大那么就必须保证原有数据的路径不变或者新添加的层存在某组权重或系数能使添加新层变成恒等网络也就是只要我们愿意这个新加层的神经网络可以和老网络一模一样。对于深度神经网络如果我们能将新添加的层训练成恒等映射identity function f ( x ) x f(\mathbf{x}) \mathbf{x} f(x)x新模型和原模型将等效。一句话扩层要增加函数映射功能不能减少网络的变换功能。**残差网络的核心思想是每个附加层都应该更容易地包含原始函数作为其元素之一。**新加的层不能减少原始网络的变换能力。 这个图理解一如果f(x)是真实的目标函数那么右图虚框只要拟合出f(x)-x也可以最终拟合出f(x)-x只是一个线性变化。理解二这个层的加入完全不会限制之前神经网络的能力因为x可以直接旁路我们新加的层这是残差网络的核心新加的层不能改变原有神经网络的变换能力。第三反向误差传播时x路径提供了以更加准确的梯度不会梯度消失。 每个残差网络内部如下 这里讲解代码 def resnet_block(input_channels, num_channels, num_residuals,first_blockFalse):blk []for i in range(num_residuals):if i 0 and not first_block:#第一个残差网络blk.append(Residual(input_channels, num_channels,use_1x1convTrue, strides2))#后续第二个残差网络起strides2,代表h,w减半else:blk.append(Residual(num_channels, num_channels)) #第一个残差网络h,w分辨率不变return blk总结 这是我的读书笔记潦草不成体系如果要学习还是要参考原著。
http://www.w-s-a.com/news/676129/

相关文章:

  • 信息产业部icp备案中心网站织梦做双语网站
  • 爱站网站长seo综合查询工具局网站信息内容建设 自查报告
  • 我想建一个网站怎么建淄博网站推广那家好
  • 做网站和app需要多久河南自助建站建设代理
  • 大连做企业网站的公司宣传平台有哪些类型
  • 如何用微信做网站免费设计logo网站有哪些
  • 服务平台型网站余姚网站定制
  • 网站搭建联系方式太平阳电脑网网站模板
  • 请简述网站制作流程html5网络公司网站模板
  • 海尔集团企业网站建设分析重庆市建设银行网站
  • 介绍公司的网站有哪些广西壮族自治区
  • 网站做rss wordpress9 1短视频安装软件
  • 网站建设价格西安室内设计网站排行榜前十名知乎
  • 用nas建设服务器网站用vs做音乐网站
  • 天津市武清区住房建设网站网站自适应框架
  • 制作移动网站公司网站开发职业规划
  • 网站头部怎样做有气势wordpress 页面 锚
  • 秦皇岛网站建设系统推荐个人网站免费制作
  • 我做夫人那些年网站登录wordpress 扫码付费
  • 网站关键词代码怎么做公司 网站建设
  • 哈尔滨多语言网站建设wordpress分类链接
  • 购物网站项目介绍软件开发流程的五大步骤
  • 做的网站怎么放在网上2008 iis搭建网站
  • 网站维护服务公司上海兼职网站制作
  • 企业做网站需要多少钱湘潭九华网站
  • 嘉兴建站服务微营销官网
  • 比较好的网页模板网站浦项建设(中国)有限公司网站
  • 有趣的个人网站网页设计与制作的岗位职责
  • 有建设网站的软件吗长沙做网站的公司对比
  • 网站的外链接数中铝长城建设有限公司网站