TensorFlow的框架

本文详细探讨了TensorFlow这一强大的深度学习框架,包括其核心概念、数据流图、会话执行以及模型构建和优化的实践技巧。通过实例解析,帮助读者深入掌握TensorFlow在神经网络中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、张量                                                                                                                                     点击返回总目录

二、计算图

三、会话

四、参数

五、神经网络的训练过程

六、前向传播

七、反向传播

八、总结:神经网络搭建的八股

 

 

使用TensorFlow搭建神经网络时,我们经常:

使用张量表示数据;使用计算图搭建神经网络;使用会话执行计算图,再优化神经网络中的参数,获得更准确的模型。

 

 

一、张量

首先介绍什么是张量。其实,张量就是多维数组,就是列表。用阶表示张量的维度。

 

              

0阶张量,就是标量,比如123。一阶张量,叫做向量,表示的是一个一维数组,比如列表[1,2,3]。二阶张量叫做矩阵,表示的是一个二维数组。

判断张量是几阶的,就看黄色框框这个地方有几个"["。有n个就是n阶。所以,张量可以表示0阶到n阶数组。

 

例:实现两个张量的加法

import tensorflow as tf                    #导入TensorFlow模块

 

a=tf.constant([1.0,2.0])                   #定义一个张量a等于常数[1.0,2,0]。tf.constant表示定义常数。
b=tf.constant([3.0,4.0])

result =a+b
print(result)

运行结果:

Tensor("add:0", shape=(2,), dtype=float32)

 

意思是result是一个名字叫“add:0”的张量。shape=(2,):括号中有一个数,表示维度是1;2表示第1个维度里有两个元素。

dtype=float32表示数据是浮点型的。TensorFlow的数据类型有tf.float32(32位的浮点)、tf.int32(32位的整型)等等。

 

                      

 

 

 

 

二、计算图

 

其实上面的例子所描述的,就是一个计算过程,就是一张计算图。从print输出的内容,我们可以看到,只显示出这个结果是个张量,并没有实际运算张量具体的值。所以计算图只描述了计算过程,不计算运算结果。

所谓计算图(Graph),就是搭建神经网络的计算过程,他是承载一个或多个下面这种节点(整个方框里面的是一个节点)的一张图,只搭建网络,不运算。

 

                                    

 

神经元的基本模型就是上面图中这个样子,其实就是数学里的乘加运算。我们用张量运算描述这个神经元为:

import tensorflow as tf

 

x=tf.constant([[1.0,2.0]])         #x是一行两列的矩阵。
w=tf.constant([[3.0],[4.0]])      #w是两行一列的矩阵。

y=tf.matmul(x,w)                     #矩阵乘法。

print(y)

运行结果:

Tensor("MatMul:0", shape=(1, 1), dtype=float32)     #结果为二维,一行一列的矩阵。

我们从print的结果可以看到,y是个张量,只承载了搭建计算过程的计算图,并没有运算。

 

 

三、会话

如果我们想得到运算结果,就要用到会话了。

所谓会话(session),是执行运算图中节点运算的。我们用with结构实现。

 

例:

import tensorflow as tf

 

x=tf.constant([[1.0,2.0]])        #x是一行两列的矩阵。
w=tf.constant([[3.0],[4.0]])      #w是两行一列的矩阵。

y=tf.matmul(x,w)                  #矩阵乘法。

print(y)
with tf.Session() as sess:
    print(sess.run(y))

运行结果:

Tensor("MatMul_1:0", shape=(1, 1), dtype=float32)
[[11.]]

 

 

四、神经网络的参数

神经网络的参数是神经元线上的权重w,用变量表示。一般会先随机生成。常常这样写:

 

         

 

tf.Variable()表示生成变量,生成的方式写在括号里。比如tf.random_normal表示生成正态分布的随机数,形状是2行3列,标准差是2,均值为0,随机数种子为1。如果把随机数种子去掉,则每次生成的随机数不一样。标准差、均值、随机种子三个如果没有特殊要求,可以不写。

tf.random_normal()函数可以用tf.truncated_normal()函数替换,表示去掉过大偏离点的正态分布,也就是如果随机出来的数据偏离平均值超过两个标准差,这个数据将重新生成。

同样,tf.random_normal()函数可以用tf.random_uniform()函数替换。

 

         

 

除了生成随机数,还可以生成常量,比如:

        

 

 

 

 

五、神经网络实现过程

当我们知道了张量、计算图、会话和参数之后,我们可以学习神经网络实现过程了。

 

          

其实,神经网络的实现只要4步。

第1步,准备数据集,提取特征,作为输入喂给神经网络。

第2步是前向传播,数据从输入到输出,走过搭建好的神经网络,可以计算得到输出。

第3步是反向传播,把大量数据喂给神经网络得到大量输出,把每一次的输出与标准答案的差反向传回神经网络,调整神经网络的参数,直到模型达到要求。

第4步,当模型达到要求后,可以使用这个优化好参数的模型,将新数据送入前向传播网络,便可以实现预测和分类了。

 

可见,基于神经网络的机器学习,主要分为两个过程,即训练过程和使用过程。训练过程步骤1、2、3的循环迭代,使用过程是第4步,一旦参数优化完成,便可以固定这些参数,实现应用了。

 

很多实际应用中,会先使用已有的成熟网络结构,喂入数据,训练相应模型,判断能对喂入的从未见过的新数据做出正确的相应;再适当更改网络结构,反复迭代,让机器自动训练参数,找出最优结构和参数,以固定专用网络。

 

 

下面分别介绍前向传播和反向传播

 

六、前向传播

所谓前向传播,就是搭建网络结构,让模型具有推理能力,可以针对一组输入给出相应的输出。

 

举例,假如一批零件,将体积和重量作为特征输入。前向传播过程如下:

        

 

前向过程如下:

         

 

Tensorf的矩阵乘法为:

        a=tf.matmul(x,W1)

        y=tf.matmul(a,W2)

 

因为要计算结果,所以要用到会话。所有变量的初始化、计算图节点的运算都要放到sess.run()函数中。

对于变量初始化,在sess.run()函数中写入tf.global_variables_initializer()实现对所有变量的初始化,也就是赋初值。

          

 

对于运算节点,我们直接把运算节点填入sess.run()即可。

          

 

在实际应用中,我们可以一次喂入一组或多组数据。

可以先用tf.placeholder占位。如果喂入一组数据,则shape的第一个参数写1。第二个参数看有几个输入特征,比如零件的体积和重量是两个特征,则在第二个参数的位置填入2。

然后用feed_dict把x喂入神经网络,求得y值。

 

如果一次想喂入多组数据,shape的第一个参数可以下None,表示先空着。第二个参数还是表示有几个特征。这样在feed_dict中可以写入多组数据。下面的例子写入了4组数据。

 

          

 

 

实现一:通过TensorFlow实现以上神经网络的前向传播过程。

#coding:utf-8                                                            #如果代码有中文,应该在第一行以注释的形式告知utf-8
import tensorflow as tf

 

 

#定义输入和参数
x=tf.constant([[0.7,0.5]])                                                                #x是一行两列的矩阵。
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)
    result = sess.run(y)
    print(result)

 

运行结果:

[[3.0904665]]

 

实现二:使用placeholder占位一次输入一组特征:

#coding:utf-8
import tensorflow as tf

 

#定义变量和参数
x=tf.placeholder(tf.float32,shape=(1,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)
    result = sess.run(y,feed_dict={x:[[0.7,0.5]]})
    print(result)

运行结果为神经网络推算出来的值:

[[3.0904665]]

 

实现三:使用placeholder一次输入多组特征

#coding:utf-8
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)
    result = sess.run(y,feed_dict={X:[[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})
    print(result)

运行结果:

      

run()会根据输入的四组特征,返回四组结果。

 

 

七、反向传播

反向传播的目的是为了优化模型参数,使用梯度下降的方法,使模型在训练数据上的损失函数最小。

所谓损失函数,就是计算得到的预测值"y"与已知答案"y_"(也就是预先提供的标签)的差距。损失函数的计算有很多方法,均方误差是比较常用的方法之一。

 

          

 

对于反向传播的训练方法,我们以减小loss值为目标,可以使用梯度下降、Momentum优化器、Adam优化器等优化方法。训练时选择一个就可以了。

          

 

这些优化器中都需要一个叫做学习率的参数,学习率是指每次参数更新的幅度。使用时我们可以选一个比较小的值先填进去,比如0.001。

 

我们通过代码来进一步看神经网络的实现过程:

#coding:utf-8               

#############0 导入模块,生成模拟数据集##################
import tensorflow as tf
import numpy as np            #python的科学计算模块
BATCH_SIZE = 8                 #一次喂入神经网络多少组数据,这个数值不可以过大,一次吃一大口,神经网络会被噎到。
seed = 23455                     #为了教学方便,设置了seed值,这样大家的结果都一样,方便debug

 

#基于seed产生随机数
rng=np.random.RandomState(seed)
#随机数返回32*2的矩阵。表示32组,每组2个特征分别是体积和重量。作为输入数据集。
X=rng.rand(32,2)      

 

#用Y生成训练集对应的标签。我们人为给出一个零件合格与否的评判标准。
#体积+重量小于1的人为是合格的,标记为1。其余人为不合格,标记为0。
#这是因为我们没有数据集,虚拟的样本和标签,神经网络通过这些数据进行训练。
Y=[[int(x0+x1<1)] for (x0,x1) in X] 
print("X:")
print(X)
print("Y:")
print(Y)

 

 

##############1 定义神经网络的输入、参数、输出,定义前向传播过程############
x=tf.placeholder(tf.float32,shape=[None,2])        #只知道有两个特征:体积和重量。不知道拿到多少组特征,所以写None。
y_=tf.placeholder(tf.float32,shape=[None,1])      #标准答案。一共有多少个这样的标签,我们也不知道,同样用None占位。

                                                                            #每个标签只有一个元素,合格还是不合格。

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)

 

 

##############2 定义损失函数及反向传播方法################################
loss = tf.reduce_mean(tf.square(y_-y))                                                #使用均方误差计算loss
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)   #使用梯度下降实现训练过程,学习率为0.001

 

 

##############3 生成会话,训练STEPS轮************************************
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    #输出未经训练的参数值
    print("W1:\n")
    print(sess.run(W1))
    print("W2:\n")
    print(sess.run(W2))
    
    STEPS=3000                                                          #训练3000轮
    for i in range(STEPS):
        start = (i*BATCH_SIZE) %32
        end = start +BATCH_SIZE
        sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})  #每轮从X和Y中抽取相应的数据,喂入神经网络
        if i%500 ==0:                                                                              #每500轮打印一次loss值
            total_loss = sess.run(loss,feed_dict={x:X,y_:Y})
            print("after %d training steps,loss is %g"%(i,total_loss))
    
    #输出训练后的值
    print("\n")
    print("W1:")
    print(sess.run(W1))
    print("W2:")
    print(sess.run(W2))
    

 

运行结果:

X:
[[0.83494319 0.11482951]
 [0.66899751 0.46594987]
 [0.60181666 0.58838408]
 [0.31836656 0.20502072]
 [0.87043944 0.02679395]
 [0.41539811 0.43938369]
 [0.68635684 0.24833404]
 [0.97315228 0.68541849]
 [0.03081617 0.89479913]
 [0.24665715 0.28584862]
 [0.31375667 0.47718349]
 [0.56689254 0.77079148]
 [0.7321604  0.35828963]
 [0.15724842 0.94294584]
 [0.34933722 0.84634483]
 [0.50304053 0.81299619]
 [0.23869886 0.9895604 ]
 [0.4636501  0.32531094]
 [0.36510487 0.97365522]
 [0.73350238 0.83833013]
 [0.61810158 0.12580353]
 [0.59274817 0.18779828]
 [0.87150299 0.34679501]
 [0.25883219 0.50002932]
 [0.75690948 0.83429824]
 [0.29316649 0.05646578]
 [0.10409134 0.88235166]
 [0.06727785 0.57784761]
 [0.38492705 0.48384792]
 [0.69234428 0.19687348]
 [0.42783492 0.73416985]
 [0.09696069 0.04883936]]
Y:
[[1], [0], [0], [1], [1], [1], [1], [0], [1], [1], [1], [0], [0], [0], [0], [0], [0], [1], [0], [0], [1], [1], [0], [1], [0], [1], [1], [1], [1], [1], [0], [1]]
W1:

[[-0.8113182   1.4845988   0.06532937]
 [-2.4427042   0.0992484   0.5912243 ]]
W2:

[[-0.8113182 ]
 [ 1.4845988 ]
 [ 0.06532937]]
after 0 training steps,loss is 5.13118
after 500 training steps,loss is 0.429111
after 1000 training steps,loss is 0.409789
after 1500 training steps,loss is 0.399923
after 2000 training steps,loss is 0.394146
after 2500 training steps,loss is 0.390597


W1:
[[-0.7000663   0.9136318   0.08953571]
 [-2.3402493  -0.14641264  0.5882305 ]]
W2:
[[-0.06024266]
 [ 0.91956186]
 [-0.06820708]]

 

 

八、总结:神经网络搭建的八股

神经网络的搭建分四步完成:准备工作、前向传播、反向传播、循环迭代

在准备阶段:我们需要import相关模块,要给出常量,有些情况需要更改、优化甚至生成数据集。

在前向传播中,要定义输入、参数和输出。比如:

       x=

       y_=

 

       w1=

       w2=

 

       a=

       y=

在反向传播中,要定义损失函数和反向传播算法。比如:

       loss =

       train_step=

 

最后,要在with结构中,完成迭代。

       with tf.Session() as sess:

             init_op = tf.global_variable_initializer()

             sess.run(init_op)

             STEPS = 

             for i in range(STEPS):

                  start=

                  end=

                  sess.run(train_step,feed_dict={})

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值