各种网络模型:来源《动手学深度学习》

一,卷积神经网络(LeNet)

LeNet分为卷积层块和全连接层块两个部分。下面我们分别介绍这两个模块。

卷积层块里的基本单位是卷积层后接最大池化层:卷积层用来识别图像里的空间模式,如线条和物体局部,之后的最大池化层则用来降低卷积层对位置的敏感性。卷积层块由两个这样的基本单位重复堆叠构成。在卷积层块中,每个卷积层都使用 5×5 的窗口,并在输出上使用sigmoid激活函数。第一个卷积层输出通道数为6,第二个卷积层输出通道数则增加到16。这是因为第二个卷积层比第一个卷积层的输入的高和宽要小,所以增加输出通道使两个卷积层的参数尺寸类似。卷积层块的两个最大池化层的窗口形状均为 2×2 ,且步幅为2。由于池化窗口与步幅形状相同,池化窗口在输入上每次滑动所覆盖的区域互不重叠。

卷积层块的输出形状为(批量大小, 通道, 高, 宽)。当卷积层块的输出传入全连接层块时,全连接层块会将小批量中每个样本变平(flatten)。也就是说,全连接层的输入形状将变成二维,其中第一维是小批量中的样本,第二维是每个样本变平后的向量表示,且向量长度为通道、高和宽的乘积。全连接层块含3个全连接层。它们的输出个数分别是120、84和10,其中10为输出的类别个数。

下面我们通过Sequential类来实现LeNet模型。

net = nn.Sequential()
net.add(nn.Conv2D(channels=6, kernel_size=5, activation='sigmoid'),nn.MaxPool2D(pool_size=2, strides=2),nn.Conv2D(channels=16, kernel_size=5, activation='sigmoid'),nn.MaxPool2D(pool_size=2, strides=2),# Dense会默认将(批量大小, 通道, 高, 宽)形状的输入转换成# (批量大小, 通道 * 高 * 宽)形状的输入nn.Dense(120, activation='sigmoid'),nn.Dense(84, activation='sigmoid'),nn.Dense(10))

二,深度卷积神经网络(AlexNet)

AlexNet与LeNet的设计理念非常相似,但也有显著的区别。

第一,与相对较小的LeNet相比,AlexNet包含8层变换,其中有5层卷积和2层全连接隐藏层,以及1个全连接输出层。下面我们来详细描述这些层的设计。

AlexNet第一层中的卷积窗口形状是 11×11 。因为ImageNet中绝大多数图像的高和宽均比MNIST图像的高和宽大10倍以上,ImageNet图像的物体占用更多的像素,所以需要更大的卷积窗口来捕获物体。第二层中的卷积窗口形状减小到 5×5 ,之后全采用 3×3 。此外,第一、第二和第五个卷积层之后都使用了窗口形状为 3×3 、步幅为2的最大池化层。而且,AlexNet使用的卷积通道数也大于LeNet中的卷积通道数数十倍。

紧接着最后一个卷积层的是两个输出个数为4,096的全连接层。这两个巨大的全连接层带来将近1 GB的模型参数。由于早期显存的限制,最早的AlexNet使用双数据流的设计使一块GPU只需要处理一半模型。幸运的是,显存在过去几年得到了长足的发展,因此通常我们不再需要这样的特别设计了。

第二,AlexNet将sigmoid激活函数改成了更加简单的ReLU激活函数。一方面,ReLU激活函数的计算更简单,例如它并没有sigmoid激活函数中的求幂运算。另一方面,ReLU激活函数在不同的参数初始化方法下使模型更容易训练。这是由于当sigmoid激活函数输出极接近0或1时,这些区域的梯度几乎为0,从而造成反向传播无法继续更新部分模型参数;而ReLU激活函数在正区间的梯度恒为1。因此,若模型参数初始化不当,sigmoid函数可能在正区间得到几乎为0的梯度,从而令模型无法得到有效训练。

第三,AlexNet通过丢弃法(参见“丢弃法”一节)来控制全连接层的模型复杂度。而LeNet并没有使用丢弃法。

第四,AlexNet引入了大量的图像增广,如翻转、裁剪和颜色变化,从而进一步扩大数据集来缓解过拟合。我们将在后面的“图像增广”一节详细介绍这种方法。

下面我们实现稍微简化过的AlexNet。

net = nn.Sequential()
# 使用较大的11 x 11窗口来捕获物体。同时使用步幅4来较大幅度减小输出高和宽。这里使用的输出通
# 道数比LeNet中的也要大很多
net.add(nn.Conv2D(96, kernel_size=11, strides=4, activation='relu'),nn.MaxPool2D(pool_size=3, strides=2),# 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数nn.Conv2D(256, kernel_size=5, padding=2, activation='relu'),nn.MaxPool2D(pool_size=3, strides=2),# 连续3个卷积层,且使用更小的卷积窗口。除了最后的卷积层外,进一步增大了输出通道数。# 前两个卷积层后不使用池化层来减小输入的高和宽nn.Conv2D(384, kernel_size=3, padding=1, activation='relu'),nn.Conv2D(384, kernel_size=3, padding=1, activation='relu'),nn.Conv2D(256, kernel_size=3, padding=1, activation='relu'),nn.MaxPool2D(pool_size=3, strides=2),# 这里全连接层的输出个数比LeNet中的大数倍。使用丢弃层来缓解过拟合nn.Dense(4096, activation="relu"), nn.Dropout(0.5),nn.Dense(4096, activation="relu"), nn.Dropout(0.5),# 输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000nn.Dense(10))

三,使用重复元素的网络(VGG)

VGG块

VGG块的组成规律是:连续使用数个相同的填充为1、窗口形状为 3×3 的卷积层后接上一个步幅为2、窗口形状为 2×2 的最大池化层。卷积层保持输入的高和宽不变,而池化层则对其减半。我们使用vgg_block函数来实现这个基础的VGG块,它可以指定卷积层的数量num_convs和输出通道数num_channels。

VGG网络

与AlexNet和LeNet一样,VGG网络由卷积层模块后接全连接层模块构成。卷积层模块串联数个vgg_block,其超参数由变量conv_arch定义。该变量指定了每个VGG块里卷积层个数和输出通道数。全连接模块则与AlexNet中的一样。

现在我们构造一个VGG网络。它有5个卷积块,前2块使用单卷积层,而后3块使用双卷积层。第一块的输出通道是64,之后每次对输出通道数翻倍,直到变为512。因为这个网络使用了8个卷积层和3个全连接层,所以经常被称为VGG-11。

def vgg(conv_arch):net = nn.Sequential()# 卷积层部分for (num_convs, num_channels) in conv_arch:net.add(vgg_block(num_convs, num_channels))# 全连接层部分net.add(nn.Dense(4096, activation='relu'), nn.Dropout(0.5),nn.Dense(4096, activation='relu'), nn.Dropout(0.5),nn.Dense(10))return netnet = vgg(conv_arch)

四,网络中的网络(NiN)

NiN块

NiN块是NiN中的基础块。它由一个卷积层加两个充当全连接层的 1×1 卷积层串联而成。其中第一个卷积层的超参数可以自行设置,而第二和第三个卷积层的超参数一般是固定的。

def nin_block(num_channels, kernel_size, strides, padding):blk = nn.Sequential()blk.add(nn.Conv2D(num_channels, kernel_size,strides, padding, activation='relu'),nn.Conv2D(num_channels, kernel_size=1, activation='relu'),nn.Conv2D(num_channels, kernel_size=1, activation='relu'))return blk

NiN模型

NiN是在AlexNet问世不久后提出的。它们的卷积层设定有类似之处。NiN使用卷积窗口形状分别为 11×11 、 5×5 和 3×3 的卷积层,相应的输出通道数也与AlexNet中的一致。每个NiN块后接一个步幅为2、窗口形状为 3×3 的最大池化层。

除使用NiN块以外,NiN还有一个设计与AlexNet显著不同:NiN去掉了AlexNet最后的3个全连接层,取而代之地,NiN使用了输出通道数等于标签类别数的NiN块,然后使用全局平均池化层对每个通道中所有元素求平均并直接用于分类。这里的全局平均池化层即窗口形状等于输入空间维形状的平均池化层。NiN的这个设计的好处是可以显著减小模型参数尺寸,从而缓解过拟合。然而,该设计有时会造成获得有效模型的训练时间的增加。

net = nn.Sequential()
net.add(nin_block(96, kernel_size=11, strides=4, padding=0),nn.MaxPool2D(pool_size=3, strides=2),nin_block(256, kernel_size=5, strides=1, padding=2),nn.MaxPool2D(pool_size=3, strides=2),nin_block(384, kernel_size=3, strides=1, padding=1),nn.MaxPool2D(pool_size=3, strides=2), nn.Dropout(0.5),# 标签类别数是10nin_block(10, kernel_size=3, strides=1, padding=1),# 全局平均池化层将窗口形状自动设置成输入的高和宽nn.GlobalAvgPool2D(),# 将四维的输出转成二维的输出,其形状为(批量大小, 10)nn.Flatten())

五,含并行连结的网络(GoogLeNet)

Inception 块

Inception块里有4条并行的线路。前3条线路使用窗口大小分别是 1×1 、 3×3 和 5×5 的卷积层来抽取不同空间尺寸下的信息,其中中间2个线路会对输入先做 1×1 卷积来减少输入通道数,以降低模型复杂度。第四条线路则使用 3×3 最大池化层,后接 1×1 卷积层来改变通道数。4条线路都使用了合适的填充来使输入与输出的高和宽一致。最后我们将每条线路的输出在通道维上连结,并输入接下来的层中去。

Inception块中可以自定义的超参数是每个层的输出通道数,我们以此来控制模型复杂度。

class Inception(nn.Block):# c1 - c4为每条线路里的层的输出通道数def __init__(self, c1, c2, c3, c4, **kwargs):super(Inception, self).__init__(**kwargs)# 线路1,单1 x 1卷积层self.p1_1 = nn.Conv2D(c1, kernel_size=1, activation='relu')# 线路2,1 x 1卷积层后接3 x 3卷积层self.p2_1 = nn.Conv2D(c2[0], kernel_size=1, activation='relu')self.p2_2 = nn.Conv2D(c2[1], kernel_size=3, padding=1,activation='relu')# 线路3,1 x 1卷积层后接5 x 5卷积层self.p3_1 = nn.Conv2D(c3[0], kernel_size=1, activation='relu')self.p3_2 = nn.Conv2D(c3[1], kernel_size=5, padding=2,activation='relu')# 线路4,3 x 3最大池化层后接1 x 1卷积层self.p4_1 = nn.MaxPool2D(pool_size=3, strides=1, padding=1)self.p4_2 = nn.Conv2D(c4, kernel_size=1, activation='relu')def forward(self, x):p1 = self.p1_1(x)p2 = self.p2_2(self.p2_1(x))p3 = self.p3_2(self.p3_1(x))p4 = self.p4_2(self.p4_1(x))return nd.concat(p1, p2, p3, p4, dim=1)  # 在通道维上连结输出

GoogLeNet模型

GoogLeNet跟VGG一样,在主体卷积部分中使用5个模块(block),每个模块之间使用步幅为2的 3×3 最大池化层来减小输出高宽。第一模块使用一个64通道的 7×7 卷积层。

b1 = nn.Sequential()
b1.add(nn.Conv2D(64, kernel_size=7, strides=2, padding=3, activation='relu'),nn.MaxPool2D(pool_size=3, strides=2, padding=1))

第二模块使用2个卷积层:首先是64通道的 1×1 卷积层,然后是将通道增大3倍的 3×3 卷积层。它对应Inception块中的第二条线路。

b2 = nn.Sequential()
b2.add(nn.Conv2D(64, kernel_size=1, activation='relu'),nn.Conv2D(192, kernel_size=3, padding=1, activation='relu'),nn.MaxPool2D(pool_size=3, strides=2, padding=1))

第三模块串联2个完整的Inception块。第一个Inception块的输出通道数为 64+128+32+32=256 ,其中4条线路的输出通道数比例为 64:128:32:32=2:4:1:1 。其中第二、第三条线路先分别将输入通道数减小至 96/192=1/2 和 16/192=1/12 后,再接上第二层卷积层。第二个Inception块输出通道数增至 128+192+96+64=480 ,每条线路的输出通道数之比为 128:192:96:64=4:6:3:2 。其中第二、第三条线路先分别将输入通道数减小至 128/256=1/2 和 32/256=1/8 。

b3 = nn.Sequential()
b3.add(Inception(64, (96, 128), (16, 32), 32),Inception(128, (128, 192), (32, 96), 64),nn.MaxPool2D(pool_size=3, strides=2, padding=1))

第四模块更加复杂。它串联了5个Inception块,其输出通道数分别是 192+208+48+64=512 、 160+224+64+64=512 、 128+256+64+64=512 、 112+288+64+64=528 和 256+320+128+128=832 。这些线路的通道数分配和第三模块中的类似,首先是含 3×3 卷积层的第二条线路输出最多通道,其次是仅含 1×1 卷积层的第一条线路,之后是含 5×5 卷积层的第三条线路和含 3×3 最大池化层的第四条线路。其中第二、第三条线路都会先按比例减小通道数。这些比例在各个Inception块中都略有不同。

b4 = nn.Sequential()
b4.add(Inception(192, (96, 208), (16, 48), 64),Inception(160, (112, 224), (24, 64), 64),Inception(128, (128, 256), (24, 64), 64),Inception(112, (144, 288), (32, 64), 64),Inception(256, (160, 320), (32, 128), 128),nn.MaxPool2D(pool_size=3, strides=2, padding=1))

第五模块有输出通道数为 256+320+128+128=832 和 384+384+128+128=1024 的两个Inception块。其中每条线路的通道数的分配思路和第三、第四模块中的一致,只是在具体数值上有所不同。需要注意的是,第五模块的后面紧跟输出层,该模块同NiN一样使用全局平均池化层来将每个通道的高和宽变成1。最后我们将输出变成二维数组后接上一个输出个数为标签类别数的全连接层。

b5 = nn.Sequential()
b5.add(Inception(256, (160, 320), (32, 128), 128),Inception(384, (192, 384), (48, 128), 128),nn.GlobalAvgPool2D())net = nn.Sequential()
net.add(b1, b2, b3, b4, b5, nn.Dense(10))

六,残差网络(ResNet)

残差块


ResNet沿用了VGG全 3×3 卷积层的设计。残差块里首先有2个有相同输出通道数的 3×3 卷积层。每个卷积层后接一个批量归一化层和ReLU激活函数。然后我们将输入跳过这2个卷积运算后直接加在最后的ReLU激活函数前。这样的设计要求2个卷积层的输出与输入形状一样,从而可以相加。如果想改变通道数,就需要引入一个额外的 1×1 卷积层来将输入变换成需要的形状后再做相加运算。

残差块的实现如下。它可以设定输出通道数、是否使用额外的 1×1 卷积层来修改通道数以及卷积层的步幅。

class Residual(nn.Block):  # 本类已保存在d2lzh包中方便以后使用def __init__(self, num_channels, use_1x1conv=False, strides=1, **kwargs):super(Residual, self).__init__(**kwargs)self.conv1 = nn.Conv2D(num_channels, kernel_size=3, padding=1,strides=strides)self.conv2 = nn.Conv2D(num_channels, kernel_size=3, padding=1)if use_1x1conv:self.conv3 = nn.Conv2D(num_channels, kernel_size=1,strides=strides)else:self.conv3 = Noneself.bn1 = nn.BatchNorm()self.bn2 = nn.BatchNorm()def forward(self, X):Y = nd.relu(self.bn1(self.conv1(X)))Y = self.bn2(self.conv2(Y))if self.conv3:X = self.conv3(X)return nd.relu(Y + X)

ResNet模型

ResNet的前两层跟之前介绍的GoogLeNet中的一样:在输出通道数为64、步幅为2的 7×7 卷积层后接步幅为2的 3×3 的最大池化层。不同之处在于ResNet每个卷积层后增加的批量归一化层。

net = nn.Sequential()
net.add(nn.Conv2D(64, kernel_size=7, strides=2, padding=3),nn.BatchNorm(), nn.Activation('relu'),nn.MaxPool2D(pool_size=3, strides=2, padding=1))

GoogLeNet在后面接了4个由Inception块组成的模块。ResNet则使用4个由残差块组成的模块,每个模块使用若干个同样输出通道数的残差块。第一个模块的通道数同输入通道数一致。由于之前已经使用了步幅为2的最大池化层,所以无须减小高和宽。之后的每个模块在第一个残差块里将上一个模块的通道数翻倍,并将高和宽减半。

下面我们来实现这个模块。注意,这里对第一个模块做了特别处理。

def resnet_block(num_channels, num_residuals, first_block=False):blk = nn.Sequential()for i in range(num_residuals):if i == 0 and not first_block:blk.add(Residual(num_channels, use_1x1conv=True, strides=2))else:blk.add(Residual(num_channels))return blk

接着我们为ResNet加入所有残差块。这里每个模块使用2个残差块。

net.add(resnet_block(64, 2, first_block=True),resnet_block(128, 2),resnet_block(256, 2),resnet_block(512, 2))

最后,与GoogLeNet一样,加入全局平均池化层后接上全连接层输出。

net.add(nn.GlobalAvgPool2D(), nn.Dense(10))

七,稠密连接网络(DenseNet)

DenseNet与ResNet的主要区别在于,DenseNet里模块 B 的输出不是像ResNet那样和模块 A 的输出相加,而是在通道维上连结。这样模块 A 的输出可以直接传入模块 B 后面的层。在这个设计里,模块 A 直接跟模块 B 后面的所有层连接在了一起。这也是它被称为“稠密连接”的原因。

DenseNet的主要构建模块是稠密块(dense block)和过渡层(transition layer)。前者定义了输入和输出是如何连结的,后者则用来控制通道数,使之不过大。

稠密块

DenseNet使用了ResNet改良版的“批量归一化、激活和卷积”结构,我们首先在conv_block函数里实现这个结构。

def conv_block(num_channels):blk = nn.Sequential()blk.add(nn.BatchNorm(), nn.Activation('relu'),nn.Conv2D(num_channels, kernel_size=3, padding=1))return blkclass DenseBlock(nn.Block):def __init__(self, num_convs, num_channels, **kwargs):super(DenseBlock, self).__init__(**kwargs)self.net = nn.Sequential()for _ in range(num_convs):self.net.add(conv_block(num_channels))def forward(self, X):for blk in self.net:Y = blk(X)X = nd.concat(X, Y, dim=1)  # 在通道维上将输入和输出连结return X

过渡层

由于每个稠密块都会带来通道数的增加,使用过多则会带来过于复杂的模型。过渡层用来控制模型复杂度。它通过 1×1 卷积层来减小通道数,并使用步幅为2的平均池化层减半高和宽,从而进一步降低模型复杂度。


def transition_block(num_channels):blk = nn.Sequential()blk.add(nn.BatchNorm(), nn.Activation('relu'),nn.Conv2D(num_channels, kernel_size=1),nn.AvgPool2D(pool_size=2, strides=2))return blk

DenseNet模型

我们来构造DenseNet模型。DenseNet首先使用同ResNet一样的单卷积层和最大池化层。

net = nn.Sequential()
net.add(nn.Conv2D(64, kernel_size=7, strides=2, padding=3),nn.BatchNorm(), nn.Activation('relu'),nn.MaxPool2D(pool_size=3, strides=2, padding=1))

类似于ResNet接下来使用的4个残差块,DenseNet使用的是4个稠密块。同ResNet一样,我们可以设置每个稠密块使用多少个卷积层。这里我们设成4,从而与上一节的ResNet-18保持一致。稠密块里的卷积层通道数(即增长率)设为32,所以每个稠密块将增加128个通道。

ResNet里通过步幅为2的残差块在每个模块之间减小高和宽。这里我们则使用过渡层来减半高和宽,并减半通道数。

num_channels, growth_rate = 64, 32  # num_channels为当前的通道数
num_convs_in_dense_blocks = [4, 4, 4, 4]for i, num_convs in enumerate(num_convs_in_dense_blocks):net.add(DenseBlock(num_convs, growth_rate))# 上一个稠密块的输出通道数num_channels += num_convs * growth_rate# 在稠密块之间加入通道数减半的过渡层if i != len(num_convs_in_dense_blocks) - 1:num_channels //= 2net.add(transition_block(num_channels))

同ResNet一样,最后接上全局池化层和全连接层来输出

net.add(nn.BatchNorm(), nn.Activation('relu'), nn.GlobalAvgPool2D(),nn.Dense(10))

八,批量归一化

从零开始实现

下面我们通过NDArray来实现批量归一化层。

def batch_norm(X, gamma, beta, moving_mean, moving_var, eps, momentum):# 通过autograd来判断当前模式是训练模式还是预测模式if not autograd.is_training():# 如果是在预测模式下,直接使用传入的移动平均所得的均值和方差X_hat = (X - moving_mean) / nd.sqrt(moving_var + eps)else:assert len(X.shape) in (2, 4)if len(X.shape) == 2:# 使用全连接层的情况,计算特征维上的均值和方差mean = X.mean(axis=0)var = ((X - mean) ** 2).mean(axis=0)else:# 使用二维卷积层的情况,计算通道维上(axis=1)的均值和方差。这里我们需要保持# X的形状以便后面可以做广播运算mean = X.mean(axis=(0, 2, 3), keepdims=True)var = ((X - mean) ** 2).mean(axis=(0, 2, 3), keepdims=True)# 训练模式下用当前的均值和方差做标准化X_hat = (X - mean) / nd.sqrt(var + eps)# 更新移动平均的均值和方差moving_mean = momentum * moving_mean + (1.0 - momentum) * meanmoving_var = momentum * moving_var + (1.0 - momentum) * varY = gamma * X_hat + beta  # 拉伸和偏移return Y, moving_mean, moving_var

接下来,我们自定义一个BatchNorm层。它保存参与求梯度和迭代的拉伸参数gamma和偏移参数beta,同时也维护移动平均得到的均值和方差,以便能够在模型预测时被使用。BatchNorm实例所需指定的num_features参数对于全连接层来说应为输出个数,对于卷积层来说则为输出通道数。该实例所需指定的num_dims参数对于全连接层和卷积层来说分别为2和4。

class BatchNorm(nn.Block):def __init__(self, num_features, num_dims, **kwargs):super(BatchNorm, self).__init__(**kwargs)if num_dims == 2:shape = (1, num_features)else:shape = (1, num_features, 1, 1)# 参与求梯度和迭代的拉伸和偏移参数,分别初始化成1和0self.gamma = self.params.get('gamma', shape=shape, init=init.One())self.beta = self.params.get('beta', shape=shape, init=init.Zero())# 不参与求梯度和迭代的变量,全在内存上初始化成0self.moving_mean = nd.zeros(shape)self.moving_var = nd.zeros(shape)def forward(self, X):# 如果X不在内存上,将moving_mean和moving_var复制到X所在显存上if self.moving_mean.context != X.context:self.moving_mean = self.moving_mean.copyto(X.context)self.moving_var = self.moving_var.copyto(X.context)# 保存更新过的moving_mean和moving_varY, self.moving_mean, self.moving_var = batch_norm(X, self.gamma.data(), self.beta.data(), self.moving_mean,self.moving_var, eps=1e-5, momentum=0.9)return Y

接口实现

与我们刚刚自己定义的BatchNorm类相比,Gluon中nn模块定义的BatchNorm类使用起来更加简单。它不需要指定自己定义的BatchNorm类中所需的num_features和num_dims参数值。在Gluon中,这些参数值都将通过延后初始化而自动获取。下面我们用Gluon实现使用批量归一化的LeNet。


net = nn.Sequential()
net.add(nn.Conv2D(6, kernel_size=5),nn.BatchNorm(),nn.Activation('sigmoid'),nn.MaxPool2D(pool_size=2, strides=2),nn.Conv2D(16, kernel_size=5),nn.BatchNorm(),nn.Activation('sigmoid'),nn.MaxPool2D(pool_size=2, strides=2),nn.Dense(120),nn.BatchNorm(),nn.Activation('sigmoid'),nn.Dense(84),nn.BatchNorm(),nn.Activation('sigmoid'),nn.Dense(10))

卷积神经网络——各种网络的简洁介绍和实现相关推荐

  1. 2020-12-09 深度学习 卷积神经网络中感受野的详细介绍

    卷积神经网络中感受野的详细介绍 1. 感受野的概念 在卷积神经网络中,感受野(Receptive Field)的定义是卷积神经网络每一层输出的特征图(feature map)上的像素点在输入图片上映射 ...

  2. 卷积神经网络resent网络实践

    文章目录 前言 一.技术介绍 二.实现途径 三.总结 前言 上篇文章,讲了经典卷积神经网络-resnet,这篇文章通过resnet网络,做一些具体的事情. 一.技术介绍 总的来说,第一步首先要加载数据 ...

  3. 深度学习卷积神经网络——经典网络VGG-16网络的搭建与实现

    一.VGG-16网络框架介绍 VGGNet是牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司的研究员一起研发的深度卷积神经网络. VGGNet探索 ...

  4. 深度学习卷积神经网络——经典网络LeNet-5、AlexNet、ZFNet网络的搭建与实现

    一.CNN卷积神经网络的经典网络综述 下面图片参照博客:http://blog.csdn.net/cyh_24/article/details/51440344 二.LeNet-5网络 输入尺寸:32 ...

  5. 卷积神经网络(CNN)详细介绍及其原理详解

    文章目录 前言 一.什么是卷积神经网络 二.输入层 三.卷积层 四.池化层 五.全连接层 六.输出层 七.回顾整个过程 总结 前言 本文总结了关于卷积神经网络(CNN)的一些基础的概念,并且对于其中的 ...

  6. 深度学习之卷积神经网络经典网络LeNet-5简介

    1. LeNet-5简介 LeNet5卷积神经网络源于Yann LeCun在1998年发表的论文:Gradient-based Learning Applied to Document Recogni ...

  7. tensorflow实现卷积神经网络——经典网络(LeNet5、AlexNet、VGG-16、ResNet)

    网络介绍: https://blog.csdn.net/loveliuzz/article/details/79131131 https://blog.csdn.net/jiaoyangwm/arti ...

  8. 卷积神经网络——vgg16网络及其python实现

    1.介绍      VGG-16网络包括13个卷积层和3个全连接层,网络结构较LeNet-5等网络变得十分复杂,但同时也有不错的效果.VGG16有强大的拟合能力在当时取得了非常的效果,但同时VGG也有 ...

  9. 卷积神经网络——残差网络(ResNet)

    在实际的试验中发现,随着卷积层和池化层的叠加,不但没有出现学习效果越来越好的情况,反而两种问题: 梯度消失和梯度爆炸 梯度消失:若每一层的误差梯度小于1,反向传播时,网络越深,梯度越趋近于0 梯度爆炸 ...

最新文章

  1. 【opencv4】opencv视频教程 C++(opencv教程)2、加载imread()(以灰度加载),修改,保存图像
  2. Postman——导出测试接口集合的Collection文件
  3. Python学习心得(二) : 更新列表
  4. Java黑皮书课后题第7章:*7.11(统计:计算标准差)编程练习题5.45计算数字的标准差。本题…计算标准差,使用一个数组存储x的每个数。编写测试程序,提示用户输入10个数字,显示平均值和标准差
  5. 图片去字工具_这些免费工具轻松提取图片中的文字,别再傻傻地手工去输了
  6. mysql 数据结构设计_MYSQL 设计数据结构需注意问题
  7. 【渝粤教育】电大中专市场营销管理 (2)作业 题库
  8. 软件测试实验1:为三角形问题编写一个Java程序,并用Junit测试程序
  9. 美团点评Kubernetes集群管理实践
  10. PHP笔记-PHP中Web Service.
  11. 昨天,JetBrains 推出“下一代 IDE”,对标VS Code?快看看有哪些值得期待的功能!...
  12. Atitit 减少财政支出----普通人如何蹭政府补贴措施 attilax大总结.docx
  13. 计算机绘画社团活动教案,电脑绘画社团教案
  14. 百度地图标记点加点击事件和鼠标移入事件并添加数据
  15. NDT算法的匹配流程
  16. 数据、变量、内存三者之间的关系
  17. word文档另存为pdf格式,如何设置导航栏
  18. 词根vol/volve/vor/vid/vis/等衍生出单词
  19. 基于SSM开发实现校园疫情防控管理系统
  20. poj 1151 Atlantis

热门文章

  1. 【Java学习笔记四】Java中的包
  2. Python3OS文件/方法
  3. 700. 二叉搜索树中的搜索
  4. 透彻解析!字节跳动Android实习面试凉凉经,年薪超过80万!
  5. fiddler抓包1-抓小程序https包
  6. 关于反射Assembly.Load(程序集).CreateInstance(命名空间.类)
  7. hdu 1087 Super Jumping! Jumping! Jumping!
  8. SQL2005中row_number()等函数的用法
  9. C# 函数 传入 C++动态库中 做回调函数
  10. BABOK - 开篇:业务分析知识体系介绍