卷积神经网络(2)----Vgg16

一、VGG net介绍                                                                                                                                                 点击此处返回总目录

二、常用的函数

三、VGG16网络结构

四、VGG16代码

 

 

 

一、VGG 介绍

今天分享一下,如何复现已有网络,实现特定应用。我们以VGG net为例,讲解图片识别的源代码。

这套代码可以对输入的图片进行识别,比如把左边的图片输入网络,VGG net会输出斑马。

                         卷积神经网络(2)----Vgg16

VGG net介绍:

          卷积神经网络(2)----Vgg16

 

 

二、常用的函数

在讲解代码前,先和大家分享几个函数的用法。

       卷积神经网络(2)----Vgg16

复现神经网络时,需要用tf.placeholder()给输入占位。卷积计算要求输入的图片按照4个维度喂入网络,第0个维度表示一次喂入几张图,第1、2、3维度是对输入图片的描述,由于已有网络对输入的要求是224*244的分辨率,是红绿蓝3通道信息。所以这里写[1,224,224,3]。

在后面的代码中会用feed_dict{x:}把输入图片x按照[1,224,224,3]的维度整理后,喂入求分类评估值的节点。

 

  卷积神经网络(2)----Vgg16

    卷积神经网络(2)----Vgg16

 

 

 np.load()和np.save()是将数组以二进制格式读出或写入磁盘,默认保存的扩展名为.npy。

.item()表示遍历其内的每一个。

如果把他们连起来用,可以把事先保存在vgg16.npy中的数组和对应的名字,以键值对的形式赋给data_dict。data_dict是字典类型。这样就可以读出提前训练好的神经网络参数了。

 

                         卷积神经网络(2)----Vgg16

数据的维度,可以方便我们了解存在npy文件中的各层参数的数据结构。可以使用tf.shape()获得张量、列表、数组的维度。

 

                 卷积神经网络(2)----Vgg16

 

tf.nn.bias_add()可以把偏置项bias加到乘加和上。

tf.reshape(tensor,[n行, m列])可以把张量变成需要的维度。n为-1,表示根据其他维度自动调整。

np.argsort(列表)可以把列表从小到大排序。注意返回的是列表索引值。

os.getcwd()可以返回当前的工作目录。

os.path.join(, , ...)可以把后面的路径文件拼接。比如,这句话实现了把当前路径和"vgg16.npy"拼接为一个路径。这样就可以通过vgg16_path所引到vgg16.npy文件。

 

    卷积神经网络(2)----Vgg16

tf.split()是切分数据用的。可以把输入切成指定大小或份数,在哪个维度切。比如,value是个5行30列的张量。tf.split(value,[4,5,11],1)可以把value在第1个维度,分为4,15,11三份。切分后分别是5行4列、5行15列和5行11列。

也可以指定切成几份。比如tf.split(value,num_or_size_splits=3,axis=1)表示把value在第一个维度切成3份,平均切。每一份是5行10列。

tf.concat()可以实现粘贴。把张量t1和t2,按照第0个维度粘,是上面的结果。按照第1个维度粘是下面的结果。

 

在这里和大家分享一下,通用的学习方法,在以后的学习中,会有大量的源代码阅读,不可能每个函数都记得用法,这个时候需要查找相关的参考资料,对于TensorFlow,推荐大家使用Google官方文档查询网网页:https://tensorflow.google.cn

 

  卷积神经网络(2)----Vgg16

有时候,我们需要把运行的结果可视化。

用fig = plt.figure("图名字")实例化图对象。

img = io.imread()可以把图片读入到img.

用fig.add_subplot()给出这幅图片包含几行几列个子图,当前是第几个子图。

用bar()函数可以画柱状图。分别给出柱子的个数,柱子所表示的数值大小,柱子的名字,柱子的宽度,柱子的颜色。

用set_ylabel()给出y轴的名字。以字符串的形式给出。如果是中文,有时候需要在前面加个"u"。

用set_title()给子图加名字。

用text()添加文字,需要给出文字的x、y坐标,文字的内容,横向、纵向位置,字号大小。

 

以上这些描述完成后,用imshow()把子图画出来。

 

 

三、VGG16 网络结构

                                 卷积神经网络(2)----Vgg16

我们使用的是论文中编号为D的网络结构。

 

 

 

四、VGG代码

我们这一讲的代码一共有5个文件。

app.py          //应用程序,实现图片识别功能。

vgg16.py      //读取了模型参数,并搭建模型。

utils.py          //是一些辅助函数。包括读取一张输入图片,计算百分比形式的概率。

Nclasses.py  //是一个标签字典。通过神经网络识别出来的是一个编号,这个编号就是Nclasses.py中的字典labels的键,可以根据键找    到对应的值。

       卷积神经网络(2)----Vgg16

 

vgg16.npy       //是个500M+的文件。包含了神经网络的所有参数。代码中我们会用类初始化函数 __init__()读入vgg16.npy里面保存的模型参数,参数以字典形式存入data_dict,我们可以用for循环打印data_dict中的键。

        卷积神经网络(2)----Vgg16

data_dict中的每个键对应卷积或全连接对应的参数:

                                                             卷积神经网络(2)----Vgg16

比如,conv1_1 对应了第一个conv3-64,包含了64个3*3*3的卷积核参数和64个偏置。

conv1_2对应下一个conv3-64,包含了64个3*3*3的卷积核参数和64个偏置。

conv2_1对应第一个conv3-128,包含了128个3*3*3的卷积核参数和128个偏置。

conv2_2对应下一个conv3-128,包含了128个3*3*3的卷积核参数和128个偏置。

......

fc6对应FC-4096,包含第一层全连接参数w和偏置b

...

fc8对应FC-1000,包含了4096*1000个参数w和1000个偏置b

评估输出的是千分类评估值,前分类评估值经过softmax函数便满足了概率分布。

 

下面开始看详细的代码:

代码app.py可以读入一张待识别图片,输出可视化的识别结果。load_image读取图片。为了输出图片识别结果,要复现前向传播过程,sess.run()执行softmax函数会得到预测的1000个分类各自出现的概率,保存到probability[[]]中,probability[0][i]可以遍历每一个概率值,probability列表的索引值对应着Nclasses.py中标签的键。可以通过键找到分类名称。

top5[]提取了probability列表中5个最高概率的索引值,这个索引值就是Nclasses.py中标签的键。

    卷积神经网络(2)----Vgg16

 

vgg16.py包括两部分内容,__init__()加载参数到data_dict,forward()函数构建了前向传播网络,包括卷积计算、最大池化计算和全连接计算。在卷积计算中,包括读取卷积核参数的函数,读取偏置项参数的函数。在全连接计算中,包括了读取全连接线上的参数w和偏置项b的函数。

                    卷积神经网络(2)----Vgg16

 

 //