深度学习笔记16:CNN经典论文研读之AlexNet及其Tensorflow实现

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介:

在 Yann Lecun 提出 Le-Net5 之后的十几年内,由于神经网络本身较差的可解释性以及受限于计算能力的影响,神经网络发展缓慢且在较长一段时间内处于低谷。2012年,深度学习三巨头之一、具有神经网络之父之称的 Geoffrey Hinton 的学生 Alex Krizhevsky 率先提出了 AlexNet,并在当年度的 ILSVRC(ImageNet大规模视觉挑战赛)以显著的优势获得当届冠军,top-5 的错误率降至了 16.4%,相比于第二名 26.2% 的错误率有了极大的提升。这一成绩引起了学界和业界的极大关注,计算机视觉也开始逐渐进入深度学习主导的时代。

AlexNet 继承了 LeCun 的 Le-Net5 思想,将卷积神经网络的发展到很宽很深的网络当中,相较于 Le-Net5 的六万个参数,AlexNet 包含了 6 亿三千万条连接,6000 万个参数和 65 万个神经元,其网络结构包括 5 层卷积,其中第一、第二和第五层卷积后面连接了最大池化层,然后是 3 个全连接层。AlexNet 的创新点在于:

 ●  首次成功使用 relu 作为激活函数,使其在较深的网络上效果超过传统的 sigmoid 激活函数,极大的缓解了梯度消失问题。
 ●  首次在实践中发挥了 dropout 的作用,为全连接层添加 dropout 防止过拟合。
 ●  相较于之前 Le-Net5 中采用的平均池化,AlexNet 首次采用了重叠的最大池化,避免了平均池化的模糊化效果。
 ●  提出了 LRN 层,对局部神经元的活动创建了竞争机制。
 ●  使用多 GPU 进行并行计算。

 ●  采用了一定的数据增强手段,一定程度上也缓解了过拟合。

AlexNet 网络结构

以上是 AlexNet 的基本介绍和创新点,下面我们看一下 AlexNet 的网络架构。

867362cba71f687367bbed30a5129eacf0699d29

AlexNet 不算池化层总共有 8 层,前 5 层为卷积层,其中第一、第二和第五层卷积都包含了一个最大池化层,后三层为全连接层。所以 AlexNet 的简略结构如下:
输入>卷积>池化>卷积>池化>卷积>卷积>卷积>池化>全连接>全连接>全连接>输出

各层的结构和参数如下:
C1层是个卷积层,其输入输出结构如下:
输入: 227 x 227 x 3 滤波器大小: 11 x 11 x 3 滤波器个数:96
输出: 55 x 55 x 96

P1层是C1后面的池化层,其输入输出结构如下:
输入: 55 x 55 x 96 滤波器大小: 3 x 3 滤波器个数:96
输出: 27 x 27 x 96

C2层是个卷积层,其输入输出结构如下:
输入: 27 x 27 x 96 滤波器大小: 5 x 5 x 96 滤波器个数:256
输出: 27 x 27 x 256

P2层是C2后面的池化层,其输入输出结构如下:
输入: 27 x 27 x 256 滤波器大小: 3 x 3 滤波器个数:256
输出: 13 x 13 x 256

C3层是个卷积层,其输入输出结构如下:
输入: 13 x 13 x 256 滤波器大小: 3 x 3 x 256 滤波器个数:384
输出: 13 x 13 x 384

C4层是个卷积层,其输入输出结构如下:
输入: 13 x 13 x 384 滤波器大小: 3 x 3 x 384 滤波器个数:384
输出: 13 x 13 x 384

C5层是个卷积层,其输入输出结构如下:
输入: 13 x 13 x 384 滤波器大小: 3 x 3 x 384 滤波器个数:256
输出: 13 x 13 x 256

P5层是C5后面的池化层,其输入输出结构如下:
输入: 13 x 13 x 256 滤波器大小: 3 x 3 滤波器个数:256
输出: 6 x 6 x 256

F6层是个全连接层,其输入输出结构如下:
输入:6 x 6 x 256
输出:4096

F7层是个全连接层,其输入输出结构如下:
输入:4096
输出:4096

F8层也是个全连接层,即输出层,其输入输出结构如下:
输入:4096
输出:1000

在论文中,输入图像大小为 224 x 224 x 3,实际为 227 x 227 x 3。各层输出采用 relu 进行激活。前五层卷积虽然计算量极大,但参数量并不如后三层的全连接层多,但前五层卷积层的作用却要比全连接层重要许多。

AlexNet 在验证集和测试集上的分类错误率表现:

599eac0c806a71524bb688c50ced33a1d21e815b

AlexNet 的 tensorflow 实现

我们继续秉持前面关于利用 tensorflow 构建卷积神经网络的基本步骤和方法:定义创建输入输出的占位符变量模块、初始化各层参数模块、创建前向传播模块、定义模型优化迭代模型,以及在最后设置输入数据。

 ●  定义卷积过程
 

def conv(x, filter_height, filter_width, num_filters, stride_y, stride_x, name,
padding='SAME', groups=1):
# Get number of input channels
input_channels = int(x.get_shape()[-1])
# Create lambda function for the convolution
convolve = lambda i, k: tf.nn.conv2d(i, k,
padding=padding)
strides=[1, stride_y, stride_x, 1],
with tf.variable_scope(name) as scope:
# Create tf variables for the weights and biases of the conv layer
weights = tf.get_variable('weights', shape=[filter_height,
biases = tf.get_variable('biases', shape=[num_filters])
filter_width,
input_channels/groups,
num_filters])
if groups == 1:
conv = convolve(x, weights)
# In the cases of multiple groups, split inputs & weights and
else:
# Split input and weights and convolve them separately
input_groups = tf.split(axis=3, num_or_size_splits=groups, value=x)
weight_groups = tf.split(axis=3, num_or_size_splits=groups,
output_groups = [convolve(i, k) for i, k in zip(input_groups, weight_groups)]
value=weights)
# Concat the convolved output together again
conv = tf.concat(axis=3, values=output_groups)
# Add biases
bias = tf.reshape(tf.nn.bias_add(conv, biases), tf.shape(conv))
# Apply relu function
relu_result = tf.nn.relu(bias, name=scope.name)
return relu_result
●  定义全连接层
 

def fc(x, num_in, num_out, name, relu=True):
with tf.variable_scope(name) as scope:
# Create tf variables for the weights and biases
weights = tf.get_variable('weights', shape=[num_in, num_out],
trainable=True)
biases = tf.get_variable('biases', [num_out], trainable=True)
# Matrix multiply weights and inputs and add bias
act = tf.nn.xw_plus_b(x, weights, biases, name=scope.name)
if relu:
relu = tf.nn.relu(act)
return relu
else:
return act

 ●  定义最大池化过程

 

def max_pool(x, filter_height, filter_width, stride_y, stride_x, name,
padding='SAME'):
return tf.nn.max_pool(x, ksize=[1, filter_height, filter_width, 1],
strides=[1, stride_y, stride_x, 1],
padding=padding, name=name)

 ●  定义 LRN

 

def lrn(x, radius, alpha, beta, name, bias=1.0):
return tf.nn.local_response_normalization(x, depth_radius=radius,
alpha=alpha, beta=beta,
bias=bias, name=name)

 ●  定义 dropout 操作

def dropout(x, keep_prob): 
return tf.nn.dropout(x,keep_prob)
 以上关于搭建 AlexNet 的各个组件我们都已准备好,下面我们利用这些组建创建一个 AlexNet 类来实现 AlexNet。

class AlexNet(object):
 def __init__(self, x, keep_prob, num_classes, skip_layer,
 weights_path='DEFAULT'):
 self.NUM_CLASSES = num_classes
 # Parse input arguments into class variables
 self.X = x
 if weights_path == 'DEFAULT':
 self.KEEP_PROB = keep_prob
 self.SKIP_LAYER = skip_layer

 # Call the create function to build the computational graph of AlexNet
 self.WEIGHTS_PATH = 'bvlc_alexnet.npy'
 else:
 self.create()
 self.WEIGHTS_PATH = weights_path


 conv1 = conv(self.X, 11, 11, 96, 4, 4, padding='VALID', name='conv1')
 def create(self):
 # 1st Layer: Conv (w ReLu) -> Lrn -> Pool
 norm1 = lrn(conv1, 2, 1e-04, 0.75, name='norm1')
 # 2nd Layer: Conv (w ReLu) -> Lrn -> Pool with 2 groups
 pool1 = max_pool(norm1, 3, 3, 2, 2, padding='VALID', name='pool1')

 conv2 = conv(pool1, 5, 5, 256, 1, 1, groups=2, name='conv2')
 conv3 = conv(pool2, 3, 3, 384, 1, 1, name='conv3')
 norm2 = lrn(conv2, 2, 1e-04, 0.75, name='norm2')
 pool2 = max_pool(norm2, 3, 3, 2, 2, padding='VALID', name='pool2')

 # 3rd Layer: Conv (w ReLu)

 conv5 = conv(conv4, 3, 3, 256, 1, 1, groups=2, name='conv5')
 # 4th Layer: Conv (w ReLu) splitted into two groups
 conv4 = conv(conv3, 3, 3, 384, 1, 1, groups=2, name='conv4')

 # 5th Layer: Conv (w ReLu) -> Pool splitted into two groups
 fc6 = fc(flattened, 6*6*256, 4096, name='fc6')
 pool5 = max_pool(conv5, 3, 3, 2, 2, padding='VALID', name='pool5')

 # 6th Layer: Flatten -> FC (w ReLu) -> Dropout
 dropout6 = dropout(fc6, self.KEEP_PROB)
 flattened = tf.reshape(pool5, [-1, 6*6*256])

 # 7th Layer: FC (w ReLu) -> Dropout
 def load_initial_weights(self, session):
 fc7 = fc(dropout6, 4096, 4096, name='fc7')
 dropout7 = dropout(fc7, self.KEEP_PROB)

 # 8th Layer: FC and return unscaled activations
 self.fc8 = fc(dropout7, 4096, self.NUM_CLASSES, relu=False, name='fc8')

 with tf.variable_scope(op_name, reuse=True):
 # Load the weights into memory
 weights_dict = np.load(self.WEIGHTS_PATH, encoding='bytes').item()
 for op_name in weights_dict:

 # Loop over all layer names stored in the weights dict

 if op_name not in self.SKIP_LAYER:
 # Check if layer should be trained from scratch


 session.run(var.assign(data))
 # Assign weights/biases to their corresponding tf variable
 for data in weights_dict[op_name]:
 if len(data.shape) == 1:

 # Biases
 var = tf.get_variable('biases', trainable=False)
 session.run(var.assign(data))

 # Weights
 else:
 var = tf.get_variable('weights', trainable=False)

在上述代码中,我们利用了之前定义的各个组件封装了前向计算过程,从http://www.cs.toronto.edu/~guerzhoy/tf_alexnet/上导入了预训练好的模型权重。这样一来,我们就将 AlexNet 基本搭建好了。


原文发布时间为:2018-09-28

本文作者:louwill

本文来自云栖社区合作伙伴“Python爱好者社区”,了解相关信息可以关注“Python爱好者社区”。

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
9天前
|
机器学习/深度学习 算法 测试技术
深度学习环境搭建笔记(二):mmdetection-CPU安装和训练
本文是关于如何搭建深度学习环境,特别是使用mmdetection进行CPU安装和训练的详细指南。包括安装Anaconda、创建虚拟环境、安装PyTorch、mmcv-full和mmdetection,以及测试环境和训练目标检测模型的步骤。还提供了数据集准备、检查和网络训练的详细说明。
44 5
深度学习环境搭建笔记(二):mmdetection-CPU安装和训练
|
9天前
|
机器学习/深度学习 数据可视化 计算机视觉
目标检测笔记(五):详细介绍并实现可视化深度学习中每层特征层的网络训练情况
这篇文章详细介绍了如何通过可视化深度学习中每层特征层来理解网络的内部运作,并使用ResNet系列网络作为例子,展示了如何在训练过程中加入代码来绘制和保存特征图。
28 1
目标检测笔记(五):详细介绍并实现可视化深度学习中每层特征层的网络训练情况
|
10天前
|
机器学习/深度学习 Web App开发 编解码
论文精度笔记(四):《Sparse R-CNN: End-to-End Object Detection with Learnable Proposals》
Sparse R-CNN是一种端到端的目标检测方法,它通过使用一组可学习的稀疏提议框来避免传统目标检测中的密集候选框设计和多对一标签分配问题,同时省去了NMS后处理步骤,提高了检测效率。
25 0
论文精度笔记(四):《Sparse R-CNN: End-to-End Object Detection with Learnable Proposals》
|
9天前
|
机器学习/深度学习 Web App开发 人工智能
轻量级网络论文精度笔(一):《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》
《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》这篇论文提出了一种基于YOLOv3-Tiny的轻量级目标检测模型Micro-YOLO,通过渐进式通道剪枝和轻量级卷积层,显著减少了参数数量和计算成本,同时保持了较高的检测性能。
18 2
轻量级网络论文精度笔(一):《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》
|
9天前
|
机器学习/深度学习
深度学习笔记(十二):普通卷积、深度可分离卷积、空间可分离卷积代码
本文探讨了深度可分离卷积和空间可分离卷积,通过代码示例展示了它们在降低计算复杂性和提高效率方面的优势。
23 2
深度学习笔记(十二):普通卷积、深度可分离卷积、空间可分离卷积代码
|
9天前
|
机器学习/深度学习 并行计算 PyTorch
深度学习环境搭建笔记(一):detectron2安装过程
这篇博客文章详细介绍了在Windows环境下,使用CUDA 10.2配置深度学习环境,并安装detectron2库的步骤,包括安装Python、pycocotools、Torch和Torchvision、fvcore,以及对Detectron2和PyTorch代码的修改。
30 1
深度学习环境搭建笔记(一):detectron2安装过程
|
9天前
|
机器学习/深度学习 算法 PyTorch
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
这篇文章详细介绍了多种用于目标检测任务中的边界框回归损失函数,包括IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU和WIOU,并提供了它们的Pytorch实现代码。
20 1
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
|
4天前
|
机器学习/深度学习 算法 数据挖掘
【深度学习】经典的深度学习模型-02 ImageNet夺冠之作: 神经网络AlexNet
【深度学习】经典的深度学习模型-02 ImageNet夺冠之作: 神经网络AlexNet
10 2
|
6天前
|
机器学习/深度学习 SQL 数据采集
基于tensorflow、CNN网络识别花卉的种类(图像识别)
基于tensorflow、CNN网络识别花卉的种类(图像识别)
11 1
|
8天前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
22 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练