Eager模式简介以及运用

  • 1、什么是Eager模式?
  • 2、Eager模式下的基本运算
    • 1)基本运算
    • 2)当做python运算的时候,tensor自动的变成一个python对象去参与运算
    • 3)有关于变量的相关操作
  • 3、如何自动求解微分
    • 1)对于变量情况:
    • 2)对于常量来说:
    • 3)对于多次微分:
  • 4、自定义训练
    • 1)导入数据,创建Dataset
    • 2)创建模型
    • 3)自定义训练

1、什么是Eager模式?

使用过TensorFlow的大家都会知道, TF通过计算图将计算的定义和执行分隔开, 这是一种声明式(declaretive)的编程模型. 确实, 这种静态图的执行模式优点很多,但是在debug时确实非常不方便(类似于对编译好的C语言程序调用,此时是我们无法对其进行内部的调试), 因此有了Eager Execution, 这在TensorFlow v1.5首次引入.
引入的Eager Execution模式后, TensorFlow就拥有了类似于Pytorch一样动态图模型能力, 我们可以不必再等到see.run(*)才能看到执行结果, 可以方便在IDE随时调试代码,查看OPs执行结果.
tf.keras封装的太好了 。不利于适用于自定义的循环与训练,添加自定义的循环
是一个命令式的编程环境,它使得我们可以立即评估操作产生的结果,而无需构建计算图。

图运算模式:把一系列的操作搭建好,然后再进行操作,某一步出现错误的话,很难排查,不利于自定义的动作
eager模式:做一步,就能看到结果,交互模式(命令行模式),增加了网络调试的灵活程度,在TensorFlow2的时候,默认的使用了eager模式

首先声明一个比较常见的问题:
至于为什么要导入除了第一行意外的另外几行,我在训练的时候遇到了一个问题,问题如下:
“Failed to get convolution algorithm. This is probably because cuDNN failed to initialize”
网上大多数人说什么tf和cuDNN的版本不匹配啊啥的,最后发现可能是GPU内存不足造成的。需要在程序前加以下一段代码:————参考了这篇博客 “Failed to get convolution algorithm. This is probably because cuDNN failed to initialize”错误的解决办法.成功的解决了问题。意思是对GPU进行按需分配。主要原因是我的图像比较大,消耗GPU资源较多。但我的显卡(GTX1060TI)显存只有6GB,所以会出现这个错误。这个错误提示有很大的误导性,让人一直纠结CUDA和CuDNN的版本问题。

#先导入必要的库
import tensorflow as tf
#下面就是加入的部分
from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSessionconfig = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)

2、Eager模式下的基本运算

1)基本运算

x=[[2,]] #返回[[2]]
m=tf.matmul(x,x)  #两个X相乘  返回一个tensor  <tf.Tensor: shape=(1, 1), dtype=int32, numpy=array([[4]])>
m.numpy()   #将tensor转化为numpy数组 #例如定义一个二维数组
a=tf.constant([[1,2],[3,4]])
a.numpy()   #array([[1, 2],[3, 4]])c=tf.multiply(a,m)
#  c返回值:<tf.Tensor: shape=(2, 2), dtype=int32, numpy=array([[ 4,  8],[12, 16]])>
# 再看一个例子
num=tf.convert_to_tensor(10)  #将numpy数字转化为tensor _——> <tf.Tensor: shape=(), dtype=int32, numpy=10>

2)当做python运算的时候,tensor自动的变成一个python对象去参与运算

for i in range(num.numpy()):i=tf.convert_to_tensor(i)if int(i%2)==0:  #当做int运算的时候,tensor自动的变成一个python对象print(str(i.numpy())+":even")else:print(str(i.numpy())+":odd")
#再例如
g=tf.convert_to_tensor(10)   #  ——>>>   <tf.Tensor: shape=(), dtype=int32, numpy=10>
float(g)   #——>  10.0

3)有关于变量的相关操作

记住下面的这几个API方法即可

v=tf.Variable(0.0)#创建一个变量(v+1).numpy()  #对于这个变量,可以直接使用他的值 返回:1.0v.assign(5)   #通过这个方法 直接改变变量的值   返回:<tf.Variable 'UnreadVariable' shape=() dtype=float32, numpy=5.0>v.assign_add(1)  #增加变量的值  返回:<tf.Variable 'UnreadVariable' shape=() dtype=float32, numpy=6.0>v.read_value()  #直接读取变量的值,读取出来的结果是一个tensor  返回:<tf.Tensor: shape=(), dtype=float32, numpy=6.0>

总结:可以看到在eager执行下,每个操作后的返回值是tf.Tensor,其包含具体值,不再像Graph模式下那样只是一个计算图节点的符号句柄。由于可以立即看到结果,这非常有助于程序debug。更进一步地,调用tf.Tensor.numpy()方法可以获得Tensor所对应的numpy数组。

3、如何自动求解微分

使用tape来记录我们的运算过程,进一步求解微分。不管对于变量还是常量的跟踪运算,都要求一种float的数据运算类型

1)对于变量情况:

w=tf.Variable([[1.0]])
with tf.GradientTape() as t:loss=w*w                    #来记录我们的运算,GradientTape()——>上下文管理器    自动的跟踪变量的运算,如果是个常量,那么就需要人工的去规定他,让这个磁带去跟踪常量的计算过程
grad=t.gradient(loss,w)   #t.gradient()这个方法:求解loss对w的微分 <tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[2.]], dtype=float32)>

2)对于常量来说:

v=tf.constant([[3.0]])
with tf.GradientTape() as t:t.watch(v)  #让t去跟踪常量的运算,因为v是一个常量loss=v*v  dloss_dv=t.gradient(loss,v)
dloss_dv.numpy()   #——>>>  array([[6.]], dtype=float32)

3)对于多次微分:

注意:对于GradientTape()持有的资源,记录的这些运算,在调用了t.gradient() 这个方法之后会立即释放,在同一运算中,计算多个微分的话是不行的,如果要如此,需要在里面添加一个参数。具体如下:

v=tf.Variable([[3.0]])
with tf.GradientTape(persistent=True) as t:t.watch(v)  y=v*v  z=y*y
dy_dv=t.gradient(y,v)  #<tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[6.]], dtype=float32)>
dz_dv=t.gradient(z,v)  #<tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[108.]], dtype=float32)>

4、自定义训练

这次的自定义训练,参考数据集是手写数字mnist,模型也比较简单,主要是掌握具体的方法。

1)导入数据,创建Dataset

import tensorflow as tf
import matplotlib.pyplot as plt(train_images,train_labels),_=tf.keras.datasets.mnist.load_data()  #下载数据
train_images=tf.expand_dims(train_images,-1)  #卷积神经网络图片输入的时候要求有通道数 扩张维度 等同于numpy的用法 np.expand_dims(img,-1)#刚刚说过,自定义训练的时候,输入类型要求为float类型
train_images=tf.cast(train_images/255,tf.float32) #图片转为float类型
train_labels=tf.cast(train_labels,tf.int64)#建立数据集
dataset=tf.data.Dataset.from_tensor_slices((train_images,train_labels))dataset=dataset.shuffle(10000).batch(32)    #这里的dataset是一个可迭代的对象

2)创建模型

model=tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(16,(3,3),activation="relu",input_shape=(28,28,1)))#通道数为1的任意大小的图片都能够输入进来
model.add(tf.keras.layers.Conv2D(32,(3,3),activation="relu"))
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(10,activation="softmax"))

3)自定义训练

1、自定义训练的时候,我要先定义他的优化函数,在tf2里面,优化函数全部归到了optimizers里面。

optimizer=tf.keras.optimizers.Adam()

2、定义loss的函数,计算损失值,SparseCategoricalCrossentropy()是一个可调用的对象

loss_func=tf.keras.losses.SparseCategoricalCrossentropy()

—————————————————————————————————
(可忽略)中间先来一个没有经过训练的情况,直接通过model调用:

features,labels=next(iter(dataset))  #iter(dataset) 将dataset迭代出来 next()取出下一个数据
predictions=model(features)   # TensorShape([32, 10])
tf.argmax(predictions,axis=1)
print(labels)

输出结果:


上面之所以不准,是因为没有经过训练

至于下面这两个代码,我查询了一下它的具体用法:
features,labels=next(iter(dataset))
tf.argmax(predictions,axis=1)
///tf.argmax(predictions,axis=1)
这个函数的主要功能是返回最大值所在的坐标。主要用在分类的时候,如果只是简单的输出,只是对于每一类可能性的预测的输出,但是我要要的输出必须是确定的哪一类,所以需要确定里面的最大的值(也就是说最可能是哪一类)。
///dataset是一个可迭对象,用iter对他进行迭代,然后用next方法取出列表里面的下一个数据 next(it,’-1’) 这个-1是默认值,从-1的下一个也就是0开始取,其实还是列表的第一个。

—————————————————————————————————

3、定义损失函数

#定义损失函数
def loss(model,x,y):y_=model(x)  #y_是预测的label   y是实际的labelreturn loss_func(y,y_)

4、定义每一个批次的训练

#这是一个训练批次(batch)所需做的事情,怎么训练的?
def train_step(model,images,labels):#在这一步当中,要计算我们的损失值与可训练参数的梯度值,需要建立一个gradient tapewith tf.GradientTape() as t:  #tf.GradientTape()跟踪运算——>loss_step的值对于可训练参数的变化,追踪损失函数loss_step=loss(model,images,labels)#计算loss值和可训练参数的梯度grads=t.gradient(loss_step,model.trainable_variables)  #model.trainable_variables()模型的可训练参数#怎么去优化呢?运用之前写好的optimizers,来改变我们的变量值,使得我们的梯度下降的最快optimizer.apply_gradients(zip(grads,model.trainable_variables))#通过这个优化器,对变量进行一定的修改

5、定义训练的函数

def train():for epoch in range(10): #对所有的数据训练10次#对dataset进行迭代for (batch,(images,label)) in enumerate(dataset):  #batch就是那个enumerate,给它加上了序号0/1/2/3...train_step(model,images,labels)   #进行一步训练>>>这里的images,labels就是从上一个语句中迭代出来的print("Epoch{}is finshed".format(epoch))

6、开始训练

train()

——————————————
总结:主要是了解Eager模式的下面的一些操作,最重要的是学会如何的自定义训练。分为哪几步?
定义优化器
定义损失函数
定义每一个批次的训练
定义训练函数
开始训练

Tensorflow2——Eager模式简介以及运用相关推荐

  1. 深度学习-Tensorflow2.2-Eager模式与自定义训练{4}-微分运算训练练习-16

    Eager模式简介 Tensorflow 发布了新的 TF 2.0 Beta 版本我们可以通过以下命令安装:pip install tensorflow==2.0.0-beta1 TensorFlow ...

  2. 【小白学PyTorch】扩展之Tensorflow2.0 | 20 TF2的eager模式与求导

    [机器学习炼丹术]的学习笔记分享 <<小白学PyTorch>> 扩展之Tensorflow2.0 | 19 TF2模型的存储与载入 扩展之Tensorflow2.0 | 18 ...

  3. 19.Eager模式

    Eager模式每进行一步输入就可以得出一步结果,我们下面直接用代码举例子 首先我们导入库,查看此时是否是eager模式,tensorflow2.0及以上的版本,默认开启eager模式 我们之前的项目均 ...

  4. WPF MVVM从入门到精通1:MVVM模式简介

    WPF MVVM从入门到精通1:MVVM模式简介 原文:WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录 ...

  5. 【设计模式】建造者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

    文章目录 一.建造者模式简介 二.建造者模式适用场景 三.建造者模式优缺点 四.建造者模式与工厂模式 五.建造者模式代码示例 1.学生类 2.建造者抽象类 3.建造者实现类 4.教师类 ( 非必须 ) ...

  6. 【设计模式】抽象工厂模式 ( 简介 | 适用场景 | 优缺点 | 产品等级结构和产品族 | 代码示例 )

    文章目录 一.抽象工厂模式简介 二.抽象工厂模式适用场景 三.抽象工厂模式优缺点 四.产品等级结构和产品族 五.抽象工厂模式代码示例 1.冰箱抽象类 2.美的冰箱实现类 3.格力冰箱实现类 4.空调抽 ...

  7. 【设计模式】组合模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

    文章目录 一.组合模式简介 二.组合模式适用场景 三.组合模式优缺点 四.组合模式和访问者模式 五.组合模式代码示例 1.书籍和目录的抽象父类 2.书籍类 3.目录类 4.测试类 一.组合模式简介 组 ...

  8. 【设计模式】模板方法模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

    文章目录 一.模板方法模式简介 二.模板方法模式适用场景 三.模板方法模式优缺点 四.模板方法扩展 五.模板方法模式相关设计模式 六.模板方法模式代码示例 1.模板方法抽象类 2.模板方法实现类 1 ...

  9. 【设计模式】迭代器模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

    文章目录 一.迭代器模式简介 二.迭代器模式适用场景 三.迭代器模式优缺点 四.迭代器模式和访问者模式 五.迭代器模式代码示例 1.迭代器接口 2.迭代器实现 3.集合元素实例类 4.集合管理接口 5 ...

最新文章

  1. 意想不到!WordPress安全漏洞98%来自插件
  2. Asp.Net上传组件
  3. jmeter生成优美的压力测试报告,jmeter生成html压测报告,jmeter压力测试
  4. python网络通信编程实例_python网络编程之数据传输UDP实例分析
  5. 零基础学习WinCE开发
  6. python ssh
  7. python中none是什么类型_如何在Python中”测试”None类型?
  8. 蚂蚁Service Mesh大规模落地实践与展望
  9. java随机抽题系统_什么样的考试场景需要使用随机试卷模式?
  10. hadoop的伪分布环境配置(2.5.2)
  11. ORA-06502: PL/SQL: numeric or value error: character to number conversion error 错误的解决方法...
  12. GIS基础软件及操作(十二)
  13. 使用谷歌统计来跟踪网页加载时间
  14. 亿乐社区最新版开源无后源码
  15. css网页设计qq彩贝
  16. 电商后台管理系统--笔记
  17. 绕坐标轴以及任意轴的旋转矩阵的推导
  18. FireFox新标签页打开搜索和书签
  19. ETA4322耐压30V,线性充1000mA,充电电流可调,双灯指示
  20. 【Spring MVC】mvc详解

热门文章

  1. 推荐 25 个优雅的 jQuery Tooltip 插件
  2. 悟空CRM9从零开始搭建详细步骤——肯定成功
  3. 【Gitlab】配置、运行Gitlab容器实例及简单使用测试
  4. python伪原创工具开发_现在有哪些好用的伪原创工具?
  5. hacker vip教程
  6. 【算法竞赛进阶指南】POJ 3349 —— SnowflakeSnowSnowflakes
  7. iframe标签(页面嵌套)
  8. springboot的jsp应该放在哪_SpringBoot 在项目中使用JSP
  9. Unity中抛物线的实现
  10. 关于SBUF读两次的问题