深度学习基本运算流程来了解一下

这里介绍一下具体的运算过程,这个是整体的运行机制,首先我们要定义计算图,有了图之后输入数据进行运算,我们输入数据进行计算,计算完了更新参数,更新参数后来了新的数据,进行预测,这就是TensorFlow的运行机制。

TensorFlow 运行机制

那我们怎么写这个程序,计算图由操作和向量组成,操作就是graph计算节点,tensor就是边的数据。

定义计算图

Graph = Operation + Tensor

Operation:Graph中的节点,表示计算

Tensor:Graph中的边,表示数据

张量(Tensor)

张量它是个多维数组,张量和多维数组对应,零阶张量--标量,一阶张量--向量,二阶张量--矩阵。每个张量有三个属性:名字、维度、类型。

>>> import tensorflow as tf
>>> a = tf.constant(1.0, name=“a”)
>>> a = tf.constant(2.0, name=“b”)
>>> add = tf.add(a, b, name=“add”)

上面代码中name对应的add和等号前面的add不要混淆,前面就是一个标识符,后边是用来管理变量的。

>>> print(add)
输出:Tensor("add:0", shape=(), dtype=float32)

张量只是计算结果的引用,并不存储数据。通过张量引用,可以方便地获取中间结果。

如何输出计算结果?

会话(Session)

会话(session)用于执行定义好的运算,会话拥有TensorFlow程序运行时所有的资源,因此计算完之后要回收资源。

TensorFlow里边有个会话概念,你要前面定义完了,你可以不用会话,定义完了运行时候一定要先创建一个会话,所有的运行都是在会话里边进行的。我们要运行哪个节点,我们就把对应节点的名称放入run()函数里边,这个会话是要申请资源的,需要关闭。利用python的上下文管理器会自动关闭。

>>> with tf.Session() as sess:
>>>result = sess.run(add)
>>>print(result)

线性回归

我们看如何用TensorFlow实现线性回归。下面是线性回归一个简单模型,有n个输入,经过权重和偏置后输出。

下面右边每一行是一个数据,意思就是输入为1,输出为1...,x和y在这里是一个标量,对应的W也是一个标量。

现在我们有好几条直线,来描绘怎么拟合这个给的数据。其实在这个例子我们可以用观察出来W为1,b为0,y=x曲线。那我们用TensorFlow怎么实现呢?

上面W和b都是参数,在模型训练过程中需要不断更新参数。

变量(Variable)

变量(Variable)用于保存神经网络模型中要训练的参数。Variable定义中包含变量数值类型和变量维度,使用前需要初始化。

在TensorFlow中有关这两个变量的定义,变量Variable。variable的参数如下:

W=tf.Variable(tf.random_normal([1]), name=‘weights’) # [1]表示维度

参数是怎么生成的?一般情况下,参数是都是通过随机初始化生成的,怎么随机初始化呢?下面是一些随机初始化的函数,随机也是根绝随机数分布随机的,我们一般希望参数是0或者0.几的。经常用的是正态分布,分布是很多的,你需要什么分布就用什么分布去进行采样,然后得到很多数值,用数值去得到随机初始化的向量。

正态分布*:如果随机出来的值偏离平均值超过2个标准差,那么这个数将被重新随机

我们通过这个可以将两个不断更新的参数(W和b)确定下来。偏置一般希望用零来初始化。

b = tf.Variable(tf.zeros([1]), name=‘bias’) # [1]表示维度

这里输入数据是固定的,x_train和y_train对应的输入数据和标签。我们用variable来进行初始化,前面的参数定义后,用之前一定要进行初始化,但有的时候参数比较多,所以TensorFlow中有一个函数global_variable_initializer()在运行函数的时候可以进行批量的初始化。

这里我们提出两个问题:

如何实现批处理?

如何避免生成大量常量?

placeholder + feed_dict

placeholder的使用避免的将输入数据声明成大量的常量,而是通过placeholder在程序运行时实时传入数据。数据类型必须指定,数据维度可以不给出。

x = tf.placeholder(tf.float32, name=‘input’)

feed_dict是一个字典,表示placeholder和对应取值的键值对,在程序运行的时候,通过给出每个placeholder对应的真实取值,输入到Placeholder对应的位置。

feed_dict={x:0.3}

我们来看看刚刚上面的代码:

输入数据部分是:placeholder

模型运行部分是:feed_dict

这里还没有完成批处理,这么多数据怎么让它自动的一批一批处理,在这里只给出了前馈计算,给x计算出y,具体的参数w和b怎么优化还没说呢?

输入数据和模型运行怎么批处理?怎么优化?

经典损失函数

怎么优化?肯定得有个目标,目标函数,也叫损失函数,这里两个经典的损失函数。

分类问题:交叉熵损失函数(cross entropy)

cross_entropy=tf.nn.softmax_cross_entropy_with_logits(labels=y_label, logits=y_out)

回归问题:均方误差损失函数(MSE,mean squared error)

mse=tf.reduce_mean(tf.square(y_label-y_out))

对上面参数做解释:

y_label:真实的值,答案。

y_out:预测出的结果。

这些损失函数直接用就行了。

优化方法

梯度下降方法

train=tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)

优化方法一般采用基于梯度下降的,这是非常经典的方法,优化方法也有很多种,这里说明用梯度下降方法,如果不理解什么是梯度下降的小伙伴,看前面的文章说明。就是不断的求梯度,往反方向走,不断循环,直到找到最优解。

 

TensorFlow里边也给出来了,learning_rate(学习速率),这个优化函数定义好之后,优化目标通过minimize()定义目标,要具体给出损失函数的定义。

看之前的代码,在这个基础上我们怎么定义优化函数?怎么对这个优化函数进行批处理的优化呢?

# 输入数据
# 模型结构
# 模型优化
mse=tf.reduce_mean(tf.square(y_-y))
opt=tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = opt.minimize(mse)
# 模型运行
sess.run(init_op) # 初始化
X_train = tf.constant([1, 2, 3,…]) # 真实训练集数据
Y_train = tf.constant([1, 2, 3,…]) # 真实训练集标签
steps=1000  # 训练次数
for i in range(steps):    # 下面这个end和start是切片的开始和结束    
start = (i * batch_size) % dataset_size    
end = min(start + batch_size, dataset_size)   
sess.run(train, feed_dict=(x:X_train[start:end],                              
y:Y_train[start:end]))
# 假设得到了开始和结束,我们可以得到当前的输入值x和当前的输出值y,用feed_dict()相当于把实参赋值给形参的过程,
# 最后run目标是train节点,就是一次优化操作的节点。

这里对切片进行详细介绍下:这个for循环还挺有意思的,有兴趣的可以看看

for i in range(steps):
    start = (i * batch_size) % dataset_size
    end = min(start + batch_size, dataset_size)
    sess.run(train, feed_dict=(x:X_train[start:end],      
    y:Y_train[start:end]))

现在有一些测试集,测试集怎么用来训练,如果测试集大的话,也可以进行分批。测试的过程只需要进行前馈过程,也就是说run函数里边输入的是y,我们不需要更新,后边运行train的时候是对模型的更新,先进行前馈,根据前馈算损失函数,再根据优化方法更新模型的过程,但是我们预测的话就默认模型训练好了。已经训练好的模型,参数,我们只需要进行前馈计算就好了。

# 输入数据
# 模型结构
# 模型优化
# 模型运行
# 模型预测
x_test = tf.constant([2, 1, 5,…]) # 真实训练集数据
steps=1000 # 训练次数
for i in range(steps):
    start = (i * batch_size) % dataset_size
    end = min(start + batch_size, dataset_size)
    Predicts = sess.run(y,feed_dict={x:X_test[start:end]})

小结

前面的知识还是有点绕的,从输入数据开始,我们可以将这些整个看成大的函数,函数有形参,输入数据通过placeholder就相当于把要输入的数据类型,数据的个数这些都定义好,有了这些之后,后边可以方便进行批处理,不需要整个数据集都输入。

模型结构通过variable定义训练的参数,这个参数一定要进行初始化才能使用,在session中一定要先运行这个,再运行其他节点。这个模型定义好,有了变量,然后我们这个输入如何通过变量一步步进行计算,然后得到我们的y值,也就是前馈计算过程。有了这个前馈的计算过程我们得到前馈的预测值,我们就可以进行损失函数的计算,通过预测值和答案我们可以计算损失函数,有了损失函数我们再通过定义优化方法,用优化方法来优化定义的损失函数,这个是模型优化那部分。

模型优化有了之后就可以进行模型运行不断优化,优化的时候数据有可能很大,造成内存泄漏,这里可以进行优化,对数据进行截取优化,run的时候是哪个train节点,也就是更新模型那个节点,不是y节点。

模型训练好了就可以进行模型预测,现在session里边run的是y节点,这里只进行前馈计算,得到最终预测结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值