从零开始搭建自己的卷积神经网络:day.1

  我为什么要自己从头写,因为论文复现的代码无法帮助我清晰条理的认识CNN或者其它的网络结构,其实没什么不好意思的我看不懂太复杂了。就比如要实现最简单最基本的CNN,首先我们要知道最简单最基本的CNN包含哪些结构,比如输入部分?输出部分?优化部分?等等。大家读论文不同的论文的框架结构是不同的,每个网络都有自己的创新点各不相同,但是最基本的大框架结构应该是一样的吧,直接看论文的代码是无法提炼出框架和作者的创新点的,所以自己写一写就知道了,知道哪些结构是必须的,哪些是修饰部分。
  对于我的研究方向不管是基于何种框架比如残差,循环,GAN,密集,对称等,网络的组成在我看来就是由三部分组成的:

  • 输入
  • 中间处理
  • 输出

  就这三部分,不能再多了,简单明了,顺着这三个部分我来捋一下卷积神经网络的整个过程:首先是经过各种预处理的训练数据的输入,接着就是对输入的训练数据的处理,这个中间处理是整个网络的核心,其中可能包括了激活,池化,上采样等各种操作,这就是中间处理核心精确概括?当然不是,这些只是这个中间处理过程对数据的操作,我们知道不管是何种神经网络一定要经历的一个过程就是迭代epoch,那么这个迭代从何而来?迭代嘛,有来有回,来来回回,反反复复。所谓“来”就是输入的训练数据在人为根据经验给定一个初始化的值之后开始向着输出层方向传播,这个过程叫做前向传播,前向传播中就包括了上面提到的激活,池化等操作。输入的训练数据数据经过这一连串的操作传播已经到了中间处理部分的门口了,难道要通过输出部分输出吗?当然不是,经过一个“来”所得到的模型一定是不合格的,如果用测试数据来检验模型的性能结果一定是相当的糟糕,怎么办?再让它往回传播,所谓“回”就是数据再从中间处理部分的门口反向传播回去,这时就是一个来回,然后就是根据任务和设备具体情况设置epoch的大小来得到较好的模型。这里假设只有一个数据且不对数据batch,所以一来一回就是一个epoch.为防止混淆给出它们的区别:
在这里插入图片描述
还不清楚三者关系的童鞋自行百度吧。

TensorFlow

  我被打败了,先简单了解一下TensorFlow到底是个什么东西吧,天天张嘴TensorFlow闭嘴TensorFlow别人听了都觉得很懂,其实啥球都不知道,尽在那装13了。

定义

网上关于tensorflow是什么众说纷纭,但万变不离其宗,我找了很多的解释进行汇总,总有一种你能理解:
1. Tensorflow是一个通过计算图的形式来表述计算的编程系统,计算图也叫数据流图,可以把计算图看做是一种有向图,Tensorflow中的每一个计算都是计算图上的一个节点,而节点之间的边描述了计算之间的依赖关系。计算图是由计算节(node)构成的图。
  计算图是一幅图,其中每个节点对应于一个操作或一个变量。变量可以将其值输入操作,操作可以将其结果输入其他操作。通常,节点被绘制为圆圈,其内部包含变量名或操作,当一个节点的值是另一个节点的输入时,箭头从一个节点指向另一个节点。可以存在的最简单的图是只有单个节点的图,节点中只有一个变量。(请记住,节点可以是变量或操作。)
2. TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。
3. TensorFlow是Google开源的第二代用于数字计算(numerical computation)的软件库。它是基于数据流图的处理框架,图中的节点表示数学运算(mathematical operations),边表示运算节点之间的数据交互。TensorFlow从字面意义上来讲有两层含义,一个是Tensor,它代表的是节点之间传递的数据,通常这个数据是一个多维度矩阵(multidimensional data arrays)或者一维向量;第二层意思Flow,指的是数据流,形象理解就是数据按照流的形式进入数据运算图的各个节点。
  不管怎么解释,TensorFlow你可以把它看做一个框架,软件库,工具等等等等,你看作什么不重要,重要的是你要知道TensorFlow = tensor + flow ,这就是它的命门七寸,怎么理解?看图:
在这里插入图片描述
tensorflow = tensor(张量) + flow(流动)=> tensorflow的计算图每个节点的输入输出都是tensor,而连接节点的有向线段就是flow,表示从一个tensor状态到另一个tensor状态。

设计理念

(1)将图的定义和运行完全分开。TensorFlow采用符号式编程。
  符号式计算一般是先定义各种变量,然后建立一个数据流图,在数据流图中规定各个变量之间的计算关系,最后需要对数据流图进行编译,但这时的数据流图是一个空壳,里面没有实际数据,只有把需要的输入放进去后,才能在整个模型中形成数据流,从而形成输出值。
(2)TensorFlow涉及的运算都放在图中,图的运行只发生在会话(session)中。   开启会话后,就可以用数据去填充节点,进行运算。关闭会话后,就不能进行计算了。

TensorFlow为什么要使用Graph?

一个很直观的解释就是下面这张图:
在这里插入图片描述
神经元就相当于数据流图的节点node,神经元之间的连线就是数据流图的边,这个很形象直观,有木有?接下来从理论征服它。tensorflow使用graph结构的主要原因我认为就是俩点:

  1. 异步和并行:通过使用明确的边缘来表示操作之间的依赖关系,系统可以轻松识别能够并行执行的操作。通过使用明确的边缘来表示操作之间流动的值,TensorFlow 可以将您的程序划分到连接至不同机器的多台设备上(CPU、GPU 和 TPU)。TensorFlow 将在这些设备之间进行必要的通信和协调。
  2. 方便梯度计算:为什么Tensorflow需要使用"图计算"来表示计算过程

在这里插入图片描述

TensorFlow的使用

运行流程主要有2步:构造模型和训练。构造模型阶段,需构建一个图(Graph)来描述我们的模型。所谓的图,可认为是流程图,即将数据的输入–> 中间处理–> 输出的过程表示出来,如下图:
在这里插入图片描述
这时候是不会发生实际运算的,在模型构建完毕之后,进入训练步骤。此时才会有实际的数据输入,梯度计算等操作。
构建抽象的模型的几个重要概念:Tensor,Variable,placeholder
训练阶段的重要概念:session

  • 将计算流程表示成图;
  • 通过Sessions(会话)来执行图计算;
  • 将数据表示为tensors(多维数据,节点);
  • 使用Variables来保持状态信息;
  • 分别使用feeds和fetches来填充数据和抓取任意的操作结果;

简单的来说就是构建图,session运行图。 下面这个也比较好理解:

  • 使用 tensor 表示数据.
  • 使用图 (graph) 来表示计算任务.
  • 在会话(session)中运行图

下面先熟悉一下构建模型的三个概念,如下:

Tensor

先给出网上各种关于tensor的理解:
1. 它是对标量和向量概念的延伸,TensorFlow用张量这种数据结构来表示所有的数据.
2. 在TensorFlow中,变量(Variable)是特殊的张量(Tensor),它的值可以是一个任何类型和形状的张量。与其他张量不同,变量存在于单个 session.run 调用的上下文之外,也就是说,变量存储的是持久张量,当训练模型时,用变量来存储和更新参数。除此之外,在调用op之前,所有变量都应被显式地初始化过。
1)单个的数值叫Scalar。也就是一个数字。比如说250这样的自然数。也可以是实数。下同。
2)一维的数组叫Vector,也就是向量。比如 {a1,a2,a3…an}。这里a1,a2…的值都是Scalar。
3)二维的数组叫Matrix,也就是矩阵。
4)三维以上的都叫Tensor,也就是张量。
深度学习/人工智能,为了方便,也经常会把N维数组都统称为tensor:
在这里插入图片描述
3. 张量是就是神经网络里的数组,叫它张量而不是数组是因为它有自己的特质,它是神经网络计算的基本单元,tensor可以轻易地进行卷积,激活,上下采样,微分求导等操作,而numpy数组就不行,普通的数组要先转化为tensor格式才行。
4. 张量是根据一共具有多少坐标轴来定义。
关于张量可参考这篇文章:[张量的通俗理解](https://www.cnblogs.com/abella/p/10142935.html)
  tf.constant创建的是常数,tf. Variable创建的是变量。变量属于可训练参数,在训练过程中其值会持续变化,也可以人工重新赋值,而常数的值自创建起就无法改变。
  tensorflow将张量定义为多维数组。它可以表示任意维度的数组,维度 rank(阶)表示。它在深度学习中存在的意义是创造更高维度的矩阵、向量。
  Tensor是一个代表计算操作的句柄,它不保存数据,只是提供一个计算数据的方法。使用Tensor主要有两个目的,一个是Tensor可以把不同的操作连接起来,从而去构建一个计算图,支持Tensorflow去进行大规模多步的计算,另一个是当Tensor被一个会话Session启用的时候,就可以计算出该操作对应产出的数据。
  可以说,Tensorflow计算的过程就是利用Tensor来建立一个计算图,然后使用Session会话来启动计算,最后得到结果的过程。

tf.Variable():创建变量

  本质也是一个tensor张量,但variable主要用于数据存储。Variable 用于构建一个变量,在计算图的运算过程中,其值会一直保存到程序运行结束,而一般的tensor张量在tensorflow运行过程中只是在计算图中流过,并不会保存下来。因此Varibale主要用来保存tensorflow构建的一些结构中的参数,这些参数才不会随着运算的消失而消失,才能最终得到一个模型。比如神经网络中的权重和bias等,在训练过后,总是希望这些参数能够保存下来,而不是直接就消失了,所以这个时候要用到Variable。所有和varible有关的操作在计算的时候都要使用session会话来控制,包括计算,打印等等。
主要是用于训练变量之类的。比如我们经常使用的网络权重,偏置。值得注意的是Variable在声明是必须赋予初始值。在训练过程中该值很可能会进行不断的加减操作变化。

参数及含义

  • initial_value:Tensor或可转换为Tensor的Python对象,它是Variable的初始值。除非validate_shape设置为False,否则初始值必须具有指定的形状。
  • trainable:默认为True,可以后期被算法优化的。如果不想该变量被优化,改为False。
  • validate_shape:默认为True,形状不接受更改,如果需要更改,validate_shape=False。
  • name:变量的可选名称。默认为“Variable”并自动获取。
  • seed:随机数种子,是一个整数,当设置之后,每次生成的随机数都一样。

tf.assign():赋值

  函数完成了将value赋值给ref的作用。其中:ref 必须是tf.Variable创建的tensor,如果ref=tf.constant()会报错!同时,shape(value)==shape(ref)

语法格式

tf.assign(
    ref,
    value,
    validate_shape=None,
    use_locking=None,
    name=None
)

实例

第一次运行报错RuntimeError: Attempted to use a closed Session是因为代码格式不规范!!!

import tensorflow as tf;
A = tf.Variable([1,2,3])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print ('改变之前的值:',sess.run(A))# [1,2,3]
    sess.run(tf.assign(A, [1,2,5]))
    print ('改变之后的值:',sess.run(A))

结果

在这里插入图片描述

tf.placeholder():暂存变量,占位符

Tensorflow 如果想要从外部传入data, 那就需要用到 tf.placeholder(), 然后以这种形式传输数据。

语法格式

tf.placeholder(
    dtype,
    shape=None,
    name=None
)

参数意义

  • dtype:常用的是tf.float32,tf.float64等数值类型
  • shape:数据形状。默认是None,就是一维值,也可以是多维(比如[2,3], [None, 3]表示列是3,行不定)
  • name:名称。

实例一

import tensorflow as tf
x = tf.placeholder(tf.float32, shape=(None, 2))
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))

a = tf.matmul(x,w1)
y = tf.matmul(a,w2)

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    print(sess.run(y, feed_dict={
    
    x:[[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]}))
    print(sess.run(w1))
    print(sess.run(w2))

结果

在这里插入图片描述

实例二

import tensorflow as tf
x= tf.placeholder(tf.float32,shape=[2,3],name='new')
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(x,feed_dict={
    
    x:[[1,1,1],[2,2,2]]}))

结果

在这里插入图片描述

实例三

import tensorflow as tf
x=tf.placeholder(tf.float32,shape=None,name='x')
y=tf.placeholder(tf.float32,shape=None,name='y')
sum = tf.add(x,y)
with tf.Session() as sess:
    # sess.run(tf.global_variables_initializer)
    # 这句话只有其前边的程序使用tf.variable()定义变量才加这一句
    print('俩个数的和sum=',sess.run(sum,feed_dict={
    
    x:[5.],y:[9.]}))

结果

在这里插入图片描述

variable和placeholder的区别

tf.Variable: 主要在于一些可训练变量(trainable variables),比如模型的权重(weights,W)或者偏执值(bias),声明时,必须提供初始值;名称的真实含义,在于变量,也即在真实训练时,其值是会改变的,自然事先需要指定初始值;
tf.placeholder: 用于得到传递进来的真实的训练样本,不必指定初始值,可在运行时,通过 Session.run 的函数的 feed_dict 参数指定;这也是其命名的原因所在,仅仅作为一种占位符;
  简言之,tf.Variable适合一些需要初始化或被训练而变化的权重或参数,而tf.placeholder适合通常不会改变的被训练的数据集。
  具体要熟悉还是要不断地使用,其它的细节在以后的实验中体会吧,虽然是day.1但是写了好几天,效率低下,有几个概念理解起来比较困难,查找自己想要的答案很费时,可能内容冗余顺序不当但通过查找的过程理解了不少,接下来继续加油!
参考文献:
1.《搭建神经网络的基本步骤》
2.《Tensorflow学习笔记----基础(3)》

猜你喜欢

转载自blog.csdn.net/weixin_44825185/article/details/107280805
今日推荐