目录
1.tf.random.set_random_seed(seed)/tf.set_random_seed(seed)
5.print_tensors_in_checkpoint_file()
水平有限,有误烦请指正
1.tf.random.set_random_seed(seed)/tf.set_random_seed(seed)
源码给的注释是:Sets the graph-level random seed,设置图级别的随机种子
Tensorflow官网对于随机种子是这样解释的:
依赖随机种子的操作实际上是从两个种子派生出来的:图级和操作级种子。这将设置图级别种子。
它与操作级别种子的交互如下:
- 如果既未设置图级别也未设置操作种子:随机种子用于此操作。
- 如果设置了图级别种子,但操作种子不是:系统确定性地选择与图级别种子一起的操作种子,以便它获得唯一的随机序列。
- 如果未设置图级种子,但设置了操作种子:默认图级种子和指定的操作种子用于确定随机序列。
- 如果设置了图级别和操作种子:两个种子一起用于确定随机序列。
个人理解:图级随机种子的作用域大于操作级随机种子,只要其中一类种子设置,随机操作的结果就确定,下面是具体的验证例子:
# -*- coding: UTF-8 -*-
import tensorflow as tf
a = tf.random_uniform([1])
b = tf.random_normal([1])
print("Session 1")
with tf.Session() as sess1:
print(sess1.run(a)) # generates 'A1'
print(sess1.run(a)) # generates 'A2'
print(sess1.run(b)) # generates 'B1'
print(sess1.run(b)) # generates 'B2'
print("Session 2")
with tf.Session() as sess2:
print(sess2.run(a)) # generates 'A3'
print(sess2.run(a)) # generates 'A4'
print(sess2.run(b)) # generates 'B3'
print(sess2.run(b)) # generates 'B4'
a = tf.random_uniform([1], seed=1)
b = tf.random_normal([1])
# 使用相同的图重复运行,将生成相同内容a的值的序列,但b值序列不同。
print("Session 3")
with tf.Session() as sess1:
print(sess1.run(a)) # generates 'A1'
print(sess1.run(a)) # generates 'A2'
print(sess1.run(b)) # generates 'B1'
print(sess1.run(b)) # generates 'B2'
print("Session 4")
with tf.Session() as sess2:
print(sess2.run(a)) # generates 'A1'
print(sess2.run(a)) # generates 'A2'
print(sess2.run(b)) # generates 'B3'
print(sess2.run(b)) # generates 'B4'
tf.random.set_random_seed(1)
a = tf.random_uniform([1])
b = tf.random_uniform([1])
# 重复运行,a、b序列的值都分别相同
print("Session 5")
with tf.Session() as sess1:
print(sess1.run(a)) # generates 'A1'
print(sess1.run(a)) # generates 'A2'
print(sess1.run(b)) # generates 'B1'
print(sess1.run(b)) # generates 'B2'
print("Session 6")
with tf.Session() as sess2:
print(sess2.run(a)) # generates 'A1'
print(sess2.run(a)) # generates 'A2'
print(sess2.run(b)) # generates 'B3'
print(sess2.run(b)) # generates 'B4'
结果:
Session 1
[0.03599787]
[0.1143446]
[1.2009506]
[1.5053517]
Session 2
[0.70037806]
[0.91322744]
[0.3271622]
[1.0184267]
Session 3
[0.2390374]
[0.22267115]
[2.7396]
[-0.19089812]
Session 4
[0.2390374]
[0.22267115]
[-2.8374932]
[0.9382386]
Session 5
[0.94860196]
[0.05447376]
[0.07955194]
[0.9018984]
Session 6
[0.94860196]
[0.05447376]
[0.07955194]
[0.9018984]
2. tf.layers.dense()
tf.layers.dense(
inputs, units,
activation=None,
use_bias=True,
kernel_initializer=None,
bias_initializer=init_ops.zeros_initializer(),
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
bias_constraint=None,
trainable=True,
name=None,
reuse=None)
源码注释:Functional interface for the densely-connected layer
官网的解释是:
该层实现了操作: outputs = activation(inputs * kernel + bias) 其中activation作为activation 参数传递的激活函数(如果不是None),kernel是由层创建的权重矩阵,并且bias是由层创建的偏向量(仅当use_bias是True)。
参数:
inputs:张量输入。
units:整数或长整数,输出空间的维数。
activation:激活功能(可调用)。将其设置为“无”以保持线性激活。
use_bias:Boolean,该层是否使用偏差。
kernel_initializer:权重矩阵的初始化函数。如果None(默认),使用默认初始化程序初始化权重tf.get_variable。
bias_initializer:偏置的初始化函数。
kernel_regularizer:权重矩阵的正则化函数。
bias_regularizer:正规函数的偏差函数。
activity_regularizer:输出的正则化函数。 kernel_constraint:由a更新后应用于内核的可选投影函数Optimizer(例如,用于实现层权重的范数约束或值约束)。该函数必须将未投影的变量作为输入,并且必须返回投影变量(必须具有相同的形状)。在进行异步分布式培训时,使用约束是不安全的。
bias_constraint:由a更新后应用于偏置的可选投影函数Optimizer。
trainable:Boolean,如果True还将变量添加到图集合中 GraphKeys.TRAINABLE_VARIABLES(请参阅参考资料tf.Variable)。
name:String,图层的名称。
reuse:Boolean,是否使用相同名称重用前一层的权重。
返回:
输出张量与inputs最后一个尺寸的大小相同units。
个人理解:将添加hidden layer的操作进行了封装,传入需要的参数,即可获取output值
3.tf.placeholder()
tf.placeholder(
dtype,
shape=None,
name=None
)
个人理解:顾名思义就是一个占位符,当模型开始训练的时候才有明确的数据被传入,使用feed_dic进行赋值
4.tf.train.Saver()
__init__(
var_list=None,
reshape=False,
sharded=False,
max_to_keep=5,
keep_checkpoint_every_n_hours=10000.0,
name=None,
restore_sequentially=False,
saver_def=None,
builder=None,
defer_build=False,
allow_empty=False,
write_version=tf.train.SaverDef.V2,
pad_step_number=False,
save_relative_paths=False,
filename=None
)
参数意义:
var_list:Variable/ SaveableObject或列表映射名称到SaveableObjects的列表。如果None,默认为所有可保存对象的列表。
reshape:If True,允许从变量具有不同形状的检查点恢复参数。
sharded:如果True,将每个设备分成一个检查点。
max_to_keep:要保留的最近检查点的最大数量。默认为5。
keep_checkpoint_every_n_hours:保持检查站的频率。默认为10,000小时。
name:字符串。添加操作时用作前缀的可选名称。
restore_sequentially:A Bool,如果为true,则导致不同变量的恢复在每个设备中顺序发生。这可以在恢复非常大的模型时降低内存使用量。
saver_def:SaverDef使用可选的proto而不是运行构建器。这仅适用于想要Saver为先前构建的Graph具有a 的对象重新创建对象的专业代码Saver。该saver_def原型应该是返回一个 as_saver_def()的电话Saver说是为创建Graph。
builder:SaverBuilder如果saver_def未提供,则可以选择使用。默认为BulkSaverBuilder()。
defer_build:如果True,请将保存和恢复操作添加到 build()呼叫中。在这种情况下,build()应在最终确定图表或使用保护程序之前调用。
allow_empty:如果False(默认)如果图中没有变量则引发错误。否则,无论如何构建保护程序并使其成为无操作。
write_version:控制保存检查点时使用的格式。它还会影响某些文件路径匹配逻辑。V2格式是推荐的选择:它在恢复期间所需的内存和延迟方面比V1优化得多。无论此标志如何,Saver都能够从V2和V1检查点恢复。
pad_step_number:如果为True,则将检查点文件路径中的全局步骤编号填充到某个固定宽度(默认为8)。默认情况下这是关闭的。
save_relative_paths:如果True,将写入检查点状态文件的相对路径。如果用户想要复制检查点目录并从复制的目录重新加载,则需要这样做。
filename:如果在图形构造时已知,则用于变量加载/保存的文件名。
个人理解:调用构造函数传入参数获取一个Saver对象,该对象可以用来保存或者是从保存文件中恢复模型的状态,保存调用:
saver.save()
save(
sess,
save_path,
global_step=None,
latest_filename=None,
meta_graph_suffix='meta',
write_meta_graph=True,
write_state=True,
strip_default_attrs=False
)
参数意义:
sess:用于保存变量的会话。
save_path:字符串。为检查点创建的文件名的前缀。
global_step:如果提供,则附加全局步骤编号 save_path以创建检查点文件名。可选参数可以是a Tensor,Tensor名称或整数。
latest_filename:协议缓冲区文件的可选名称,其中包含最新检查点的列表。该文件与检查点文件保存在同一目录中,由保护程序自动管理,以跟踪最近的检查点。默认为“检查点”。
meta_graph_suffix:MetaGraphDef文件的后缀。默认为'meta'。
write_meta_graph:Boolean指示是否编写元图文件。
write_state:Boolean表示是否写入 CheckpointStateProto。
strip_default_attrs:布尔值。如果True,将从NodeDefs中删除默认值属性
恢复调用:
saver.restore()
restore(
sess,
save_path
)
5.print_tensors_in_checkpoint_file()
from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file
print_tensors_in_checkpoint_file(file_name, tensor_name, all_tensors,
all_tensor_names=False)
个人理解:打印出指定目录的检查点文件内容,'tensor_name' and 'all_tensors'是必填属性,tensor_name填None,all_tensors填True打印所有tensor及对应的值
输出效果:
tensor_name: bias
1.0
tensor_name: weight
2.0
6.tf.slice()
def slice(input_, begin, size, name=None)
这个方法真的是看得我头疼,先来看看源码里给的注释
Extracts a slice from a tensor.
This operation extracts a slice of size `size` from a tensor `input` starting
at the location specified by `begin`. The slice `size` is represented as a
tensor shape, where `size[i]` is the number of elements of the 'i'th dimension
of `input` that you want to slice. The starting location (`begin`) for the
slice is represented as an offset in each dimension of `input`. In other
words, `begin[i]` is the offset into the 'i'th dimension of `input` that you
want to slice from
begin代表提取的起始位置,size有两层意思,第一层意思是提取后的结果的shape,比如size为[1,1,3],表示提取出的结果的shape就为[1,1,3];第二层意思是从begin所在的维度开始提取,每个维度分别提取几个元素,与上文注释中的最后一句话对应。
在我们提取的时候主要关注size的第二层意思,因为按照指定的offset提取,最后结果的shape肯定就是对的。
举个栗子:
t = np.arange(1, 19).reshape([3, 2, 3])
# [[[1 2 3] [4 5 6]] [[7 8 9] [10 11 12]] [[13 14 15] [16 17 18]]]
s1 = tf.slice(t, [1, 0, 0], [1, 1, 3]) # [[[7 8 9]]]
s2 = tf.slice(t, [1, 0, 0], [1, 2, 3]) # [[[7 8 9][10 11 12]]]
s3 = tf.slice(t, [1, 0, 0], [2, 1, 3]) # [[[7 8 9]][[13 14 15]]]
我们先来确定t的shape,方括号的层数为3层,最外一层的元素数量为3(将最外一层的括号去掉,再看看现在最外层的括号一共有几个同级的),第二层为2,第三层为3,判断方法同第一层,所以shape为[3,2,3]。
先说s1:
begin为[1,0,0],那我们先找到这个起始的位置,在python数组中index是从0开始的,所以begin中的第一个数1就代表着最外一层的第二个元素,即: [[7 8 9] [10 11 12]],第二个数为0,即:[7 8 9],第三个数为0,即:7。所以begin就代表着从数字7开始抽取。
size为[1, 1, 3],第一个数为1,按照我们刚说的,第一个维度取1个元素,即为:[[7 8 9] [10 11 12]],但是具体取什么不知道,先暂定取[X];第二个数为1,第二个维度取1个元素,即为:[7 8 9],现在的结果为[[X]];第二个数为3,第,三个维度取3个元素,即为:[7 8 9],这是X就为7 8 9 。所以综合在一起来看就是[[[7 8 9]]]
再看s2:
begin与s1相同,所以其实位置也相同。
size为[1, 2, 3],第一个数为1,按照我们刚说的,第一个维度取1个元素,即为:[[7 8 9] [10 11 12]],但是具体取什么不知道,先暂定取[X];第二个数为1,第二个维度取2个元素,即为:[7 8 9] [10 11 12],现在的结果为[[X]];第二个数为3,第,三个维度取3个元素,即为:[7 8 9],这是X就为7 8 9 。所以综合在一起来看就是[[[7 8 9] [10 11 12]]]
s3就自己看吧,看看自己能不能得出上面的结果
7.tf.split()
def split(value, num_or_size_splits, axis=0, num=None, name="split")
老规矩,先看看源码注释说明:
Splits a tensor into sub tensors.
If `num_or_size_splits` is an integer type, then `value` is split
along dimension `axis` into `num_split` smaller tensors.
Requires that `num_split` evenly divides `value.shape[axis]`.
If `num_or_size_splits` is not an integer type, it is presumed to be a Tensor
`size_splits`, then splits `value` into `len(size_splits)` pieces. The shape
of the `i`-th piece has the same size as the `value` except along dimension
`axis` where the size is `size_splits[i]`
从注释上来看是说将tensor划分为几个子tensor,num_or_size_splits传入的值可以是数组(将tensor按某个维度进行划分),也可以是数字(将tensor几等分),axis是划分的维度,举两个栗子:
1、传入等分数,对axis=1的维度进行划分
t = np.arange(1, 25).reshape([4, 6])
a1, a2 = tf.split(t, 2, 1)
print(a1.shape)
print(a2.shape)
输出:
(4, 3)
(4, 3)
2、传入划分条件,对axis=0的维度进行划分
t = np.arange(1, 25).reshape([4, 6])
a1, a2 = tf.split(t, [1, 3], 0)
print(a1.shape)
print(a2.shape)
输出:
(1, 6)
(3, 6)
8.tf.stack()
def stack(values, axis=0, name="stack")
Packs the list of tensors in `values` into a tensor with rank one higher than
each tensor in `values`, by packing them along the `axis` dimension.
Given a list of length `N` of tensors of shape `(A, B, C)`;
if `axis == 0` then the `output` tensor will have the shape `(N, A, B, C)`.
if `axis == 1` then the `output` tensor will have the shape `(A, N, B, C)`.
字面意思就是,将两个tensor按照某一维度进行打包,打包后的结果的维度比原来的维度多1,注意,values是一个input tensor的list。老规矩,举个栗子
a1 = [[1, 2, 3], [4, 5, 6]] #[2,3]
a2 = [[10, 11, 12], [13, 14, 15]] # [2,3]
r1 = tf.stack([a1, a2])
b1 = [[[1, 2, 3], [4, 5, 6]]] # [1,2,3]
b2 = [[[10, 11, 12], [13, 14, 15]]] #[1,2,3]
r2 = tf.stack([b1, b2], axis=1)
with tf.Session() as sess:
print(sess.run(r1).shape, sess.run(r1))
print(sess.run(r2).shape, sess.run(r2))
输出:
(2, 2, 3) [[[ 1 2 3] [ 4 5 6]] [[10 11 12] [13 14 15]]]
(1, 2, 2, 3) [[[[ 1 2 3] [ 4 5 6]] [[10 11 12] [13 14 15]]]]
stack之后的维度比原数据的维度多1,多出的维度就是指定的axis的位置
9.tf.math.argmax()
def argmax(input,
axis=None,
name=None,
dimension=None,
output_type=dtypes.int64)
很神奇,这个function就没有源码注释了~
开始讲解,按照argmax字面意思来看,取出最大的参数,返回值的话不是直接返回最大的参数,而是返回最大值的index。
说得再多都不如来个例子形象
t = np.random.randint(1, 10, [3, 4])
max_z = tf.math.argmax(t, axis=0)
max_o = tf.math.argmax(t, axis=1)
with tf.Session() as sess:
print(t)
print('-------------')
print(sess.run(max_z))
print('-------------')
print(sess.run(max_o))
输出:
[[4 8 6 9]
[9 9 4 3]
[2 7 4 2]]
-------------
[1 1 0 0]
-------------
[3 0 1]
axis是指定比较的维度,如果是0的话,则在:[4 8 6 9],[9 9 4 3],[2 7 4 2]之间选择最大值的下标,但是怎么选呢?很明显就得根据数据每个下标值取值进行比较。
首先我们来看axis为0的情况
当index=0时,最大值为9,而9的index为1;当index=1时,最大值为9,而9的index为1;当index=2时,最大值为6,而6的index为0;当index=3时,最大值为9,而9的index为0。故输出值为[1,1,0,0]
axis为1的情况就留给你来分析了
10.tf.nn.conv2d()
tf.nn.conv2d(
input,
filter,
strides,
padding,
use_cudnn_on_gpu=True,
data_format='NHWC',
dilations=[1, 1, 1, 1],
name=None
)
input:输入的需要做卷积的图像,具有[batch, in_height, in_width, in_channels]的形状,即一个batch的图片数量、图片高度、图片宽度、图像的通道数
filter:卷积核。形状为 [filter_height, filter_width, in_channels, out_channels],卷积核的高度、宽度、输入通道数、输出通道数
strides:步长
padding:"SAME"表示填充边缘, "VALID"则表示不填充
use_cudnn_on_gpu:可选bool。默认为True。
data_format:可选string来自:"NHWC", "NCHW"。默认为"NHWC"。指定输入和输出数据的数据格式。使用默认格式“NHWC”,数据按以下顺序存储:[批次,高度,宽度,通道]。或者,格式可以是“NCHW”,数据存储顺序为:[批次,通道,高度,宽度]。
dilations:可选列表ints。默认为[1, 1, 1, 1]。长度的1-D张量4.每个维度的膨胀系数 input。如果设置为k> 1,则该维度上的每个滤镜元素之间将有k-1个跳过的单元格。维度顺序由值确定data_format,详见上文。批次和深度尺寸的扩张必须为1。
name:操作的名称