Tensorflow——关于loss

Tensorflow——关于loss,第1张

结果:你会发现第一个输出与第三个一致,第二个输出和第四个一致

reduce_sum 是 tensor 内部求和的工具。其参数中:

其实在reduce_sum()中,是从维度上去考虑的(感觉这个Matlab中数据的概念比较像)

调用 reduce_sum(arg1, arg2) 时,参数 arg1 即为要求和的数据, arg2 有两个取值分别为 0 和 1 ,通常用 reduction_indices=[0] 或 reduction_indices=[1] 来传递参数。从上图可以看出,当 arg2 = 0 时,是纵向对矩阵求和,原来矩阵有几列就得到几个值;相似地,当 arg2 = 1 时,是横向对矩阵求和;当省略 arg2 参数时,默认对矩阵所有元素进行求和。

在 reduce_sum() 中就是按照求和的方式对矩阵降维。

计算张量的各个维度上的元素的平均值。

l2_loss一般用于优化目标函数中的正则项,防止参数太多复杂容易过拟合(所谓的过拟合问题是指当一个模型很复杂时,它可以很好的“记忆”每一个训练数据中的随机噪声的部分而忘记了要去“学习”训练数据中通用的趋势)

结果输出:

70

计算的过程:

题外话

正则化的基本思想是向损失函数添加一个惩罚项用于惩罚大的权重,隐式地减少自由参数的数量,所以可以达到d性地适用不同数据量训练的要求而不产生过拟合的问题。

正则化方法是将惩罚因子加入到各层的参数或激活函数中。其实现位置通常是在模型的optimization里,在计算损失函数时将该惩罚因子加进去。

( >

基本使用

使用 TensorFlow, 你必须明白 TensorFlow:

使用图 (graph) 来表示计算任务

在被称之为 会话 (Session) 的上下文 (context) 中执行图

使用 tensor 表示数据

通过 变量 (Variable) 维护状态

使用 feed 和 fetch 可以为任意的 *** 作(arbitrary operation) 赋值或者从其中获取数据

综述

TensorFlow 是一个编程系统, 使用图来表示计算任务 图中的节点被称之为 op

(operation 的缩写) 一个 op 获得 0 个或多个 Tensor, 执行计算,

产生 0 个或多个 Tensor 每个 Tensor 是一个类型化的多维数组

例如, 你可以将一小组图像集表示为一个四维浮点数数组,

这四个维度分别是 [batch, height, width, channels]

一个 TensorFlow 图描述了计算的过程 为了进行计算, 图必须在 会话 里被启动

会话 将图的 op 分发到诸如 CPU 或 GPU 之类的 设备 上, 同时提供执行 op 的方法

这些方法执行后, 将产生的 tensor 返回 在 Python 语言中, 返回的 tensor 是

numpy ndarray 对象; 在 C 和 C++ 语言中, 返回的 tensor 是

tensorflow::Tensor 实例

计算图

TensorFlow 程序通常被组织成一个构建阶段和一个执行阶段 在构建阶段, op 的执行步骤

被描述成一个图 在执行阶段, 使用会话执行执行图中的 op

例如, 通常在构建阶段创建一个图来表示和训练神经网络, 然后在执行阶段反复执行图中的训练 op

TensorFlow 支持 C, C++, Python 编程语言 目前, TensorFlow 的 Python 库更加易用,

它提供了大量的辅助函数来简化构建图的工作, 这些函数尚未被 C 和 C++ 库支持

三种语言的会话库 (session libraries) 是一致的

构建图

构建图的第一步, 是创建源 op (source op) 源 op 不需要任何输入, 例如 常量 (Constant) 源 op 的输出被传递给其它 op 做运算

Python 库中, op 构造器的返回值代表被构造出的 op 的输出, 这些返回值可以传递给其它

op 构造器作为输入

TensorFlow Python 库有一个默认图 (default graph), op 构造器可以为其增加节点 这个默认图对

许多程序来说已经足够用了 阅读 Graph 类 文档

来了解如何管理多个图

import tensorflow as tf

# 创建一个常量 op, 产生一个 1x2 矩阵 这个 op 被作为一个节点

# 加到默认图中

#

# 构造器的返回值代表该常量 op 的返回值

matrix1 = tfconstant([[3, 3]])

# 创建另外一个常量 op, 产生一个 2x1 矩阵

matrix2 = tfconstant([[2],[2]])

# 创建一个矩阵乘法 matmul op , 把 'matrix1' 和 'matrix2' 作为输入

# 返回值 'product' 代表矩阵乘法的结果

product = tfmatmul(matrix1, matrix2)

默认图现在有三个节点, 两个 constant() op, 和一个matmul() op 为了真正进行矩阵相乘运算, 并得到矩阵乘法的

结果, 你必须在会话里启动这个图

在一个会话中启动图

构造阶段完成后, 才能启动图 启动图的第一步是创建一个 Session 对象, 如果无任何创建参数,

会话构造器将启动默认图

欲了解完整的会话 API, 请阅读Session 类

# 启动默认图

sess = tfSession()

# 调用 sess 的 'run()' 方法来执行矩阵乘法 op, 传入 'product' 作为该方法的参数

# 上面提到, 'product' 代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回

# 矩阵乘法 op 的输出

#

# 整个执行过程是自动化的, 会话负责传递 op 所需的全部输入 op 通常是并发执行的

#

# 函数调用 'run(product)' 触发了图中三个 op (两个常量 op 和一个矩阵乘法 op) 的执行

#

# 返回值 'result' 是一个 numpy `ndarray` 对象

result = sessrun(product)

print result

# ==> [[ 12]]

# 任务完成, 关闭会话

sessclose()

Session 对象在使用完后需要关闭以释放资源 除了显式调用 close 外, 也可以使用 "with" 代码块

来自动完成关闭动作

with tfSession() as sess:

result = sessrun([product])

print result

在实现上, TensorFlow 将图形定义转换成分布式执行的 *** 作, 以充分利用可用的计算资源(如 CPU

或 GPU) 一般你不需要显式指定使用 CPU 还是 GPU, TensorFlow 能自动检测 如果检测到 GPU, TensorFlow

会尽可能地利用找到的第一个 GPU 来执行 *** 作

如果机器上有超过一个可用的 GPU, 除第一个外的其它 GPU 默认是不参与计算的 为了让 TensorFlow

使用这些 GPU, 你必须将 op 明确指派给它们执行 withDevice 语句用来指派特定的 CPU 或 GPU

执行 *** 作:

with tfSession() as sess:

with tfdevice("/gpu:1"):

matrix1 = tfconstant([[3, 3]])

matrix2 = tfconstant([[2],[2]])

product = tfmatmul(matrix1, matrix2)

设备用字符串进行标识 目前支持的设备包括:

"/cpu:0": 机器的 CPU

"/gpu:0": 机器的第一个 GPU, 如果有的话

"/gpu:1": 机器的第二个 GPU, 以此类推

阅读使用GPU章节, 了解 TensorFlow GPU 使用的更多信息

交互式使用

文档中的 Python 示例使用一个会话 Session 来

启动图, 并调用 Sessionrun() 方法执行 *** 作

为了便于使用诸如 IPython 之类的 Python 交互环境, 可以使用

InteractiveSession 代替

Session 类, 使用 Tensoreval()

和 Operationrun() 方法代替

Sessionrun() 这样可以避免使用一个变量来持有会话

# 进入一个交互式 TensorFlow 会话

import tensorflow as tf

sess = tfInteractiveSession()

x = tfVariable([10, 20])

a = tfconstant([30, 30])

# 使用初始化器 initializer op 的 run() 方法初始化 'x'

xinitializerrun()

# 增加一个减法 sub op, 从 'x' 减去 'a' 运行减法 op, 输出结果

sub = tfsub(x, a)

print subeval()

# ==> [-2 -1]

Tensor

TensorFlow 程序使用 tensor 数据结构来代表所有的数据, 计算图中, *** 作间传递的数据都是 tensor

你可以把 TensorFlow tensor 看作是一个 n 维的数组或列表 一个 tensor 包含一个静态类型 rank, 和

一个 shape 想了解 TensorFlow 是如何处理这些概念的, 参见

Rank, Shape, 和 Type

变量

Variables for more details

变量维护图执行过程中的状态信息 下面的例子演示了如何使用变量实现一个简单的计数器 参见

变量 章节了解更多细节

# 创建一个变量, 初始化为标量 0

state = tfVariable(0, name="counter")

# 创建一个 op, 其作用是使 state 增加 1

one = tfconstant(1)

new_value = tfadd(state, one)

update = tfassign(state, new_value)

# 启动图后, 变量必须先经过`初始化` (init) op 初始化,

# 首先必须增加一个`初始化` op 到图中

init_op = tfinitialize_all_variables()

# 启动图, 运行 op

with tfSession() as sess:

# 运行 'init' op

sessrun(init_op)

# 打印 'state' 的初始值

print sessrun(state)

# 运行 op, 更新 'state', 并打印 'state'

for _ in range(3):

sessrun(update)

print sessrun(state)

# 输出:

# 0

# 1

# 2

# 3

代码中 assign() *** 作是图所描绘的表达式的一部分, 正如 add() *** 作一样 所以在调用 run()

执行表达式之前, 它并不会真正执行赋值 *** 作

通常会将一个统计模型中的参数表示为一组变量 例如, 你可以将一个神经网络的权重作为某个变量存储在一个 tensor 中

在训练过程中, 通过重复运行训练图, 更新这个 tensor

Fetch

为了取回 *** 作的输出内容, 可以在使用 Session 对象的 run() 调用 执行图时, 传入一些 tensor,

这些 tensor 会帮助你取回结果 在之前的例子里, 我们只取回了单个节点 state, 但是你也可以取回多个

tensor:

input1 = tfconstant(30)

input2 = tfconstant(20)

input3 = tfconstant(50)

intermed = tfadd(input2, input3)

mul = tfmul(input1, intermed)

with tfSession() as sess:

result = sessrun([mul, intermed])

print result

# 输出:

# [array([ 21], dtype=float32), array([ 7], dtype=float32)]

需要获取的多个 tensor 值,在 op 的一次运行中一起获得(而不是逐个去获取 tensor)。

Feed

上述示例在计算图中引入了 tensor, 以常量或变量的形式存储 TensorFlow 还提供了 feed 机制, 该机制

可以临时替代图中的任意 *** 作中的 tensor 可以对图中任何 *** 作提交补丁, 直接插入一个 tensor

feed 使用一个 tensor 值临时替换一个 *** 作的输出结果 你可以提供 feed 数据作为 run() 调用的参数

feed 只在调用它的方法内有效, 方法结束, feed 就会消失 最常见的用例是将某些特殊的 *** 作指定为 "feed" *** 作,

标记的方法是使用 tfplaceholder() 为这些 *** 作创建占位符

input1 = tfplaceholder(tffloat32)

input2 = tfplaceholder(tffloat32)

output = tfmul(input1, input2)

with tfSession() as sess:

print sessrun([output], feed_dict={input1:[7], input2:[2]})

# 输出:

# [array([ 14], dtype=float32)]

for a larger-scale example of feeds

如果没有正确提供 feed, placeholder() *** 作将会产生错误

MNIST 全连通 feed 教程

(source code)

给出了一个更大规模的使用 feed 的例子

图像数据格式定义了一批数据的存储顺序。在调用 TensorFlow API 时会经常看到 data_format 参数:

data_format 默认值为 "NHWC",也可以手动设置为 "NCHW"。这个参数规定了 input Tensor 和 output Tensor 的排列方式。

data_format 设置为 "NHWC" 时,排列顺序为 [batch, height, width, channels];

设置为 "NCHW" 时,排列顺序为 [batch, channels, height, width]。

其中 N 表示这批图像有几张,H 表示图像在竖直方向有多少像素,W 表示水平方向像素数,C 表示通道数(例如黑白图像的通道数 C = 1,而 RGB 彩色图像的通道数 C = 3)。为了便于演示,我们后面作图均使用 RGB 三通道图像。

两种格式的区别如下图所示:

NCHW 中,C 排列在外层,每个通道内像素紧挨在一起,即 'RRRRRRGGGGGGBBBBBB' 这种形式。

NHWC 格式,C 排列在最内层,多个通道对应空间位置的像素紧挨在一起,即 'RGBRGBRGBRGBRGBRGB' 这种形式。

如果我们需要对图像做彩色转灰度计算,NCHW 计算过程如下:

即 R 通道所有像素值乘以 0299,G 通道所有像素值乘以 0587,B 通道所有像素值乘以 0114,最后将三个通道结果相加得到灰度值。

相应地,NHWC 数据格式的彩色转灰度计算过程如下:

输入数据分成多个(R, G, B) 像素组,每个像素组中 R 通道像素值乘以 0299,G 通道像素值乘以 0587,B 通道像素值乘以 0114 后相加得到一个灰度输出像素。将多组结果拼接起来得到所有灰度输出像素。

以上使用两种数据格式进行 RGB -> 灰度计算的复杂度是相同的,区别在于访存特性。通过两张图对比可以发现, NHWC 的访存局部性更好 (每三个输入像素即可得到一个输出像素), NCHW  则必须等所有通道输入准备好才能得到最终输出结果, 需要占用较大的临时空间 。

在 CNN 中常常见到 1x1 卷积(例如: 用于移动和嵌入式视觉应用的 MobileNets ),也是每个输入 channel 乘一个权值,然后将所有 channel 结果累加得到一个输出 channel。如果使用 NHWC 数据格式,可以将卷积计算简化为矩阵乘计算,即  1x1 卷积核实现了每个输入像素组到每个输出像素组的线性变换 。

TensorFlow 为什么选择 NHWC 格式作为默认格式?因为早期开发都是基于 CPU,使用 NHWC 比 NCHW 稍快一些(不难理解,NHWC 局部性更好,cache 利用率高)。

NCHW 则是 Nvidia cuDNN 默认格式,使用 GPU 加速时用 NCHW 格式速度会更快(也有个别情况例外)。

最佳实践 :设计网络时充分考虑两种格式,最好能灵活切换,在 GPU 上训练时使用 NCHW 格式,在 CPU 上做预测时使用 NHWC 格式。

参考:

1 >

以上就是关于Tensorflow——关于loss全部的内容,包括:Tensorflow——关于loss、CNN个人总结、tensorflow 训练好的模型,怎么 调用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/9773016.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存