TF2 常用命令

  • 1、模型保存
    • 1.1、方式一:直接save为tf2.0版本的模型
    • 1.2、变量Checkpoint格式的保存和恢复
      • 1.2.1 tf.train.Checkpoint(optimizer=optimizer, model=model)
      • 1.2.2 tf.train.CheckpointManager
    • 1.3 Checkpoint 中变量参数的获取
    • 1.4 已建立TF2模型的变量获取
  • 2、模型创建
  • 3、模型训练
  • 4、模型评估
  • 5、tf.strings
  • 6、GPU使用
  • 7、tf.xx方法【工具包】
    • 7.1 常用整理
    • 7.2 tf.concat
    • 7.3 tf.stack
    • 7.4 tf.split
    • 7.5 tf.unstack
    • 7.6 tf.transpose
    • 7.7 tf.constant
    • 7.8 tf.range
    • 7.9 tf.linspace
    • 7.10 tf.zeros
    • 7.10 tf.zeros_like
    • 7.11 tf.gather
    • 7.12 tf.gather_nd
    • 7.13 tf.boolean_mask
    • 7.14 tf.scatter_nd
    • 7.15 tf.where
  • 8、tf.data.xx
    • 8.0 tf.data.Dataset
    • 8.1 tf.data.TextLineDataset()
  • 9、tf.keras.layers.experimental.preprocessing.xx
    • 9.1 tf.keras.layers.experimental.preprocessing.TextVectorization
  • 10、tf.keras.losses.xx
    • 10.1 tf.keras.losses.BinaryCrossentropy
  • 11、tf.keras.metrics.xx
    • 11.1 tf.keras.metrics.Accuracy
    • 11.2、tf.keras.metrics.Mean
  • 12、tf.keras.utils.xx
    • 12.1 keras.utils.to_categorical(labels, num_classes=10)
  • 13、tf.keras.layers.xx
    • 13.1 tf.keras.layers.LSTM
  • 14、tf.keras.callbacks.xx
    • 14.1 tf.keras.callbacks.TensorBoard
    • 14.2 tf.keras.callbacks.EarlyStopping
    • 14.3 tf.keras.callbacks.ModelCheckPoint
    • 14.4 tf.keras.callbacks.ReduceLROnPlateau
  • 15、Tensor
    • 15.1 类型详解
    • 15.2 属性和方法
    • 15.3 常量和变量
      • 15.3.1 常量:
      • 15.3.2 变量:
  • 16、计算Graph
    • 16.1 静态计算图
      • 16.1.1 tf1.0+静态计算图
      • 16.1.2 tf2.0+中调用tf1.0+静态计算图
    • 16.2 动态计算图
      • 16.2.1 tf2.0+中的动态计算图
    • 16.2 静态计算图Autograph
  • 17、自动微分GradientTape-自动前向反向传播
    • 17.1 求导数
    • 17.2 和优化器配合使用
  • 18、tf.random.xx
    • 18.1 tf.random.uniform
    • 18.2 tf.random.set_seed
    • 18.3 tf.random.truncated_normal
  • 19、tf.linalg.xx
    • 19.1 常用方法
  • 20、数据-预处理
    • 20.1 序列预处理
    • 20.2 转换为tf_record
  • 21、TF版本,CUDA版本,Cudnn版本对应

1、模型保存

1.1、方式一:直接save为tf2.0版本的模型

model.save(【model_save_path】, save_format='tf')

1.2、变量Checkpoint格式的保存和恢复

1.2.1 tf.train.Checkpoint(optimizer=optimizer, model=model)

参考:https://tf.wiki/zh_hans/basic/tools.html#zh-hans-chechpoint

1.2.2 tf.train.CheckpointManager
 tf.train.CheckpointManager(checkpoint, directory='./save', checkpoint_name='model.ckpt', max_to_keep=k)

directory 参数为文件保存的路径, checkpoint_name 为文件名前缀(不提供则默认为 ckpt ),
max_to_keep 为保留的 Checkpoint 数目

1.3 Checkpoint 中变量参数的获取

from tensorflow.python.training import py_checkpoint_reader
# load checkpoint
checkpoint_path = '../1pretrain_models/albert_zh_tiny/albert_model.ckpt'
# print(path.getcwdu())
print(checkpoint_path)
# read data from checkpoint file
reader = py_checkpoint_reader.NewCheckpointReader(checkpoint_path)
var_to_shape_map = reader.get_variable_to_shape_map() # 变量映射map

1.4 已建立TF2模型的变量获取

from transformers import BertTokenizer,TFAlbertModel,AlbertConfig, AlbertTokenizer
tfalbert = TFAlbertModel(albert_config)
tf.convert_to_tensor([[1, 2, 3, 4]])
tfalbert.summary()
print(tfalbert.variables)   # 输出所有变量
for var in tfalbert.variables:print(var.name, end=',')print(var.shape)print(var)   # var 即为当前变量对象本身

变量赋值:

# 这里综合了上述1.3 和1.4的例子
tfablert_variables.get('tf_extend_albert_model/albert/embeddings/token_type_embeddings/embeddings:0').assign(reader.get_tensor('bert/embeddings/token_type_embeddings'))

2、模型创建

3、模型训练

4、模型评估

5、tf.strings

tf.strings.lower(text) # 文本转换为小写
tf.strings.regex_replace(text, '<br />', ' ') # 正则替换,将<br />替换为空格。
tf.strings.split(line, '\t') # 按照\t切分文本
tf.strings.to_number('1')   # 将字符串转换为数值,应该是float,可借助tf.cast(a, int32)进行转化

6、GPU使用

1、系统层面设置可用显卡

os.environ['CUDA_VISIBLE_DEVICES'] = '5, 6'
gpus = tf.config.experimental.list_physical_devices(device_type='GPU')
tf.config.experimental.set_visible_devices(devices=gpus[0:2], device_type='GPU')

7、tf.xx方法【工具包】

7.1 常用整理

7-1  常用整理
1) tf.expand_dims(【矩阵数据】, axis=0)     # 扩展维度,axis位置处增加一维
2) tf.eye(num_rows, num_columns=None, batch_shape=None, dtype=dtypes.float32, name=None)示例:tf.eye(3, 4)>> <tf.Tensor: shape=(3, 4), dtype=float32, numpy=array([[1., 0., 0., 0.],[0., 1., 0., 0.],[0., 0., 1., 0.]], dtype=float32)>3) tf.Variable(self,initial_value=None,trainable=None,validate_shape=True,caching_device=None,name=None,variable_def=None,dtype=None,import_scope=None,constraint=None,synchronization=VariableSynchronization.AUTO,aggregation=VariableAggregation.NONE,shape=None)解释:tf中变量的声明,参数挺多。示例:x = tf.Variable([[1,2], [3, 4]], dtype=tf.float32)>> <tf.Variable 'Variable:0' shape=(2, 2) dtype=float32, numpy=array([[1., 2.],[3., 4.]], dtype=float32)>方法:x.numpy()    # 获取变量值,结果是numpy中的类型的。
4) tf.reshape(tensor, shape, name=None)解释:reshape一个tensor,改变张量的形状。示例:t1 = [[1, 2, 3],[4, 5, 6]]tf.reshape(t1, [6])>> <tf.Tensor: shape=(6,), dtype=int32, numpy=array([1, 2, 3, 4, 5, 6], dtype=int32)>注:`tf.reshape其本质上不会改变张量元素的存储顺序,所以,该操作实际上非常迅速,并且是可逆的。`5) tf.squeeze (input, axis=None, name=None)解释:移除input中维度为1维度。也可以通过axis指定某个为1的维度。示例:a shape: [1, 2, 1, 3, 4]tf.squeeze(a)a.shape>> TensorShape([2, 3, 4])注:`tf.squeeze 其本质上不会改变张量元素的存储顺序,所以,该操作实际上非常迅速,并且是可逆的。`6) tf.expand_dims(input, axis, name=None)解释:在input的axis维处,扩增一个维度。示例:a shape: [1, 2, 1, 3, 4]tf.expand_dims(a, axis=0)a.shape>> TensorShape([1, 1, 2, 3, 4])tf.expand_dims(a, axis=2)a.shape>> TensorShape([1, 1, 1, 2, 3, 4])注:`tf.expand_dims其本质上不会改变张量元素的存储顺序,所以,该操作实际上非常迅速,并且是可逆的。``tf.transpose可以交换张量的维度,与tf.reshape,tf.squeeze,tf.expand_dims不同,它会改变张量元素的存储顺序。`

7.2 tf.concat

7-2  tf.concat(values, axis, name='concat') 解释:矩阵的拼接,这和numpy中的np.concatenate()用法是一样的。如下示例,axis=0,表示在第一个维度的拼接;axis=1,表示在第二个维度的拼接;axis=-1,表示在最后一个维度的拼接。通过结果可以发现,张量维度的变化都是在axis维的变化,比如a为(2, 3, 4, 5),经过axis=0的拼接后,结果的shape为(6, 3, 4, 5)即(a.shape[0]+b.shape[0]+c.shape[0], 3, 4, 5)可参考:https://sixiangdefairy.blog.csdn.net/article/details/89390832--values 矩阵,一般为张量--axis   拼接维度--name    拼接操作名示例讲解:a shape:(2, 3, 4, 5),b shape:(2, 3, 4, 5),c shape:(2, 3, 4, 5)那么:tf.concat([a, b, c], axis=0)    axis = -4 >> [2*3, 3, 4, 5]解释:其实将正常的单个列表的维度上,将下标为axis的维度 乘以 需要拼接张量的数量即可。tf.concat([a, b, c], axis=1)  axis = -3 >> [2, 3*3, 4, 5]tf.concat([a, b, c], axis=2) axis = -2 >> [2, 3, 4*3, 5]tf.concat([a, b, c], axis=3) axis = -1 >> [2, 3, 4, 5*3]综上所述,tf.concat其实相对于原数组中元素并没有改变原矩阵的维度大小,同时确定了axis的取值为[-4, 4)注意:其实,当a,b,c的中间维度不一致时,下列的表达方式更为准确:tf.concat([a, b, c], axis=0)    axis = -4 >> [a.shape[0]+b.shape[0]+c.shape[0], 3, 4, 5]tf.concat([a, b, c], axis=1)  axis = -3 >> [2, a.shape[1]+b.shape[1]+c.shape[1], 4, 5]...

7.3 tf.stack

7-3   stack(values, axis=0, name="stack")解释:其实和tf.concat都是对多个张量进行合并,但是tf.stack是堆叠,会增加维度;而tf.concat是拼接,不会增加维度。其实,大家对于tf.concat和tf.stack的维度变换其实很不理解,大家其实可以参考下:https://sixiangdefairy.blog.csdn.net/article/details/89388103就很简单的理解了。示例讲解:a shape:(2, 3, 4, 5),b shape:(2, 3, 4, 5),c shape:(2, 3, 4, 5)那么:tf.stack([a, b, c], axis=0)   或 axis = -5    >> [3, 2, 3, 4, 5]解释:其实正常把最外层列表加上的维度是[3, 2, 3, 4, 5], 然后其实本函数的本质就是将列表维度3放到下标为axis的位置。tf.stack([a, b, c], axis=1)   或 axis = -4     >> [2, 3, 3, 4, 5]tf.stack([a, b, c], axis=2)   或 axis = -3  >> [2, 3, 3, 4, 5]tf.stack([a, b, c], axis=3)   或 axis = -2  >> [2, 3, 4, 3, 5]tf.stack([a, b, c], axis=4)   或 axis = -1  >> [2, 3, 4, 5, 3]综上所述,tf.stack其实是相对于原数组中的每个元素是增加了一个维度的,同时确定了axis的取值为:[-5, 5)

7.4 tf.split

7-4   split(value, num_or_size_splits, axis=0, num=None, name="split")解释:tf.split是tf.concat的逆运算,可以指定分割份数平均分割,也可以通过指定每份的记录数量进行分割。可参考:https://sixiangdefairy.blog.csdn.net/article/details/89388140示例讲解:a shape:(4, 5, 6, 10)那么:tf.split(a, 2, axis=0)  或 axis = -4 >> 2 * [4/2, 5, 6, 10]tf.split(a, 5, axis=1)  或 axis = -3 >> 5 * [4, 5/5, 6, 10]tf.split(a, 2, axis=2)  或 axis = -2 >> 2 * [4, 5, 6/2, 10]tf.split(a, 2, axis=3)  或 axis = -2 >> 2 * [4, 5, 6, 10/2]综上所述,tf.split其实和tf.concat一样,并没有改变维度大小,同时确定了axis的取值为:[-4, 4),结果其实是:num_or_size_splits * [维度1, 维度2/num_or_size_splits , 维度3, 维度4],这儿假设axis=1或-3这儿主要解释了tf.split的维度变换,其实num_or_size_splits还可以使用列表的方式,指定分割的数量,比如:split0, split1, split2 = tf.split(a, [2, 5, 4], axis=3)注:该方法,返回的是一个列表,列表的数量为num_or_size_splits if type(num_or_size_splits)==int else len(num_or_size_splits)每个元素的维度,均与原维度保持一致。

7.5 tf.unstack

7-5   unstack(value, num=None, axis=0, name="unstack")解释:很明显,这个正好和unstack相反,同时解析结果会进行降1维。-- axis 表示需要分解的维度示例:a shape: [2, 3, 4, 5]那么:a.unstack(a, axis=0) 或  axis = -4  >> [2, 3, 4, 5] >> 2 * [3, 4, 5]解释:其实就是将shape中维度为axis的值提前,其他shape顺延即可。a.unstack(a, axis=1) 或  axis = -3  >> [3, 2, 4, 5] >> 3 * [2, 4, 5]a.unstack(a, axis=2) 或  axis = -2  >> [4, 2, 3, 5] >> 4 * [2, 3, 5]a.unstack(a, axis=3) 或  axis = -1  >> [5, 2, 3, 4] >> 5 * [2, 3, 4]综上所述,tf.stack其实是降低了一个维度的,同时确定了axis的取值为:[-4, 4)注意:最终返回的结果是一个列表,每个元素的维度相对于原维度都降了一维。

7.6 tf.transpose

7-6  tf.transpose(a, perm=None, conjugate=False, name="transpose")解释:矩阵的维度转换。可参考:https://sixiangdefairy.blog.csdn.net/article/details/89388060底层实现原理:       # 通过底层实现tf.transpose()效果test_data = np.arange(1, 121).reshape([2, 3, 4, 5])a, b, c, d = test_data.shapeprint(a, b, c, d)# 底层遍历实现各维度转置perm = [0, 1, 3, 2]target_data = np.zeros([2, 3, 5, 4])for i in range(c):for j in range(d):target_data[:, :, j, i] = test_data[:, :, i, j]print('', target_data)print(target_data.shape)# through tf.transpose() to get the resulttr_0_1_3_2 = tf.transpose(test_data, perm)tr_0_1_3_2 = sess.run(tr_0_1_3_2)print(target_data == tr_0_1_3_2)    # 通过比较底层实现结果和tf.transpose验证结果# [[[[ True  True  True  True]#    [ True  True  True  True]#    [ True  True  True  True]#    [ True  True  True  True]#    [ True  True  True  True]] 。。。]]通过上面的维度变换,应该首先明白任何矩阵的任何维度,只有最后一个维度是有数据的,那就好理解了,通过perm指定维度结构,然后通过两两维度变换,保证最后一维指定位置的数据不变即可。大家可能现在有疑问,举个例子,[3,2][2,3]的数据是一样的,是不是就可以理解了。示例解释:主要辅助理解维度变换a shape: [2, 3, 4, 5]a.transpose(a, perm=[0, 1, 2, 3]) >> [2, 3, 4, 5]解释:原理其实很简单,就是把perm中的数字当做a.shape的下标,然后再perm中按照a.shape下标的值进行赋值,是不是就简单明了了。a.transpose(a, perm=[1, 0, 2, 3]) >> [3, 2, 4, 5]a.transpose(a, perm=[1, 2, 0, 3]) >> [3, 4, 2, 5]a.transpose(a, perm=[1, 2, 3, 0]) >> [3, 4, 5, 2]...这些变换很多,其实是一组下标值的全排列。综上所述,首先变换前后维度没有变换,其次大家如果了解tf.stack其实,两者有相似之处,可参考:https://sixiangdefairy.blog.csdn.net/article/details/89388103# 总结:#     tf.stack() 中 stacks shape: 2 * (维1,维2, 维3, 维4)可理解为:(2, 维1,维2,# 维3, 维4)#     当axis=0时, 就相当于tf.transpose(stacks, [0, 1, 2, 3, 4])#     当axis=1时, 就相当于tf.transpose(stacks, [1, 0, 2, 3, 4])#     当axis=2时, 就相当于tf.transpose(stacks, [1, 2, 0, 3, 4])#     当axis=3时, 就相当于tf.transpose(stacks, [1, 2, 3, 0, 4])#     当axis=0时, 就相当于tf.transpose(stacks, [1, 2, 3, 4, 0])这儿值都是一样的,大家可以运行验证一下。注:`tf.transpose可以交换张量的维度,与tf.reshape不同,它会改变张量元素的存储顺序。`

7.7 tf.constant

7-7  constant(value, dtype=None, shape=None, name="Const")解释:创建一个常量的张量。可以作为将numpy或者数组等转为张量的方法。示例:tf.constant([1, 2, 3, 4, 5, 6])>> <tf.Tensor: shape=(6,), dtype=int32,numpy=array([1, 2, 3, 4, 5, 6], dtype=int32)>

7.8 tf.range

7-8  range(start, limit=None, delta=1, dtype=None, name="range")解释:创建一个数序列的张量。取值范围[start, limit)-- start : 序列的开始-- limit : 序列的结束,不包括-- delta : 序列中数值之间的间隔示例:tf.range(start=3, limit=18, delta=3)>> <tf.Tensor: shape=(5,), dtype=int32, numpy=array([ 3,  6,  9, 12, 15], dtype=int32)>tf.range(start=3, limit=1, delta=-0.5)>>     <tf.Tensor: shape=(4,), dtype=float32, numpy=array([3. , 2.5, 2. , 1.5], dtype=float32)>

7.9 tf.linspace

7-9  lin_space(start, stop, num, name=None)解释:将start到stop划分为num等份。取值范围[start, stop]-- start : 序列的开始-- stop  : 序列的结束,包括-- num   : 序列划分等份的数量注:start和stop的数据类型必须是`bfloat16`, `half`, `float32`, `float64`其中之一。num的数据类型必须是`int32`, `int64`其中之一。示例:tf.linspace(10.0, 12.0, 3, name="linspace") >> [ 10.0  11.0  12.0]

7.10 tf.zeros

7-9  zeros(shape, dtype=dtypes.float32, name=None)解释:创建一个所有元素都是零的矩阵。示例:tf.zeros([3, 4], tf.int32)>> <tf.Tensor: shape=(3, 4), dtype=int32, numpy=array([[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]], dtype=int32)>

7.10 tf.zeros_like

7-9  zeros_like(input, dtype=None, name=None)解释:创建一个所有元素都是零的矩阵, 其shape和input的shape保持一致。示例:tensor = tf.constant([[1, 2, 3], [4, 5, 6]])tf.zeros_like(tensor)>> <tf.Tensor: shape=(2, 3), dtype=int32, numpy=array([[0, 0, 0],[0, 0, 0]], dtype=int32)>

7.11 tf.gather

7-9  tf.gather(params, indices, validate_indices=None, axis=None, batch_dims=0, name=None)解释:不规则切片的一种。示例:a shape: [5, 6, 7, 8]同时获取:[0, :, :, :],[2, :, :, :],[4, :, :, :]使用:tf.gather(a, [0, 2, 4], axis=0)同时获取:[:, 0, :, :],[:, 2, :, :],[:, 4, :, :]使用:tf.gather(a, [0, 2, 4], axis=1)---------------------也可以同时获取:[0, :, 1, :], [1, :, 1, :], [2, :, 1, :][0, :, 2, :], [1, :, 2, :], [2, :, 2, :][0, :, 4, :], [1, :, 4, :], [2, :, 4, :]即:tf.gather(tf.gather(scores, [0, 1, 2], axis=0), [1, 2, 4], axis=-2)答疑:为什么不直接使用a[:, 0:3, :, :]?确实张量是可以直接通过切片的方式获取值的,但是他有局限性,即只能获取固定区间列的或者固定值列的内容,对于上述示例要求获取0, 2, 4,并不可以实现。综上所述,通过`tf.gather获取的数据的维度和原维度保持一致`,所以可以实现嵌套使用的方式。

7.12 tf.gather_nd

7-12  tf.gather_nd(params, indices, batch_dims=0, name=None)解释:不规则切片的一种。为了弥补tf.gather的缺点。示例:a shape: [5, 6, 7, 8]同时获取:[0, 1, :, :], [1, 2, :, :], [2, 3, :, :]即:b = tf.gather_nd(scores, indices=[(0, 1), (1, 2), (2, 3)])b.shape>> TensorShape([3, 7, 8])`答疑`:为什么不直接使用tf.gather?通过当前示例和tf.gather的示例2可以发现,tf.gather只能局限的获取到保持一个维度不同,另外的维度必须是相同的,而tf.gather_nd就解决了这个问题,直接录入对应下标即可。`缺陷`:通过上述例子,虽然说解决了tf.gather的部分问题,其实,对于维度跳跃式的数据获取,并不能实现。比如:需要获取[0, 1, :, 3], [1, 2, :, 3], [2, 3, :, 4],比较无力。所以,这儿就需要引入下面的tf.boolean_mask,虽然解决,但是使用不太方便。综上所述,通过`tf.gather_nd获取的维度会改变,结果维度是 a.dims - len(indices[0]) + 1`,即和indices中需要获取的定位数据有关。

7.13 tf.boolean_mask

7-13  tf.boolean_mask(tensor, mask, axis=None, name="boolean_mask")解释:不规则切片的一种。为了弥补tf.gather和tf.gather_nd的缺点,其实这个方式像是一种保底策略,比较笨重。示例:a shape: [4, 10, 7]同时获取:[0, 0, :], [2, 4, :], [3, 6, :]即:s = tf.boolean_mask(scores,[[True,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,True,False,False,False,False,False],[False,False,False,False,False,False,True,False,False,False]])tf.shape>> TensorShape([3, 7])综上所述,通过`tf.boolean_mask获取的维度会改变,结果维度是 a.dims - len(mask.shape) + 1`,即和mask维度大小有关,通过这个方法可以获取所有的需求数据,但是我有个大胆的想法:我都能知道Ture,False了,我复制粘贴可能比这个还快,所以啊,这玩意儿就是个兜底的方法。

7.14 tf.scatter_nd

7-14  tf.scatter_nd(indices, updates, shape, name=None)解释:不规则切片的一种。这个和tf.gather_nd有些相反,tf.gather_nd用于手机张量的给定位置的元素,而tf.scatter_nd可以将某些值插入到一个给定shape的全0的张量的指定位置处。-- indices : 需要置换数据的位置-- updates : 被替换的数据,与tensor的位置一一对应-- shape   : 生成该shape的零矩阵示例:经典示例:c = tf.constant([[-1,1,-1],[2,2,-2],[3,-3,3]],dtype=tf.float32)indices = tf.where(c<0)res = tf.scatter_nd(indices,tf.gather_nd(c,indices),c.shape)res>> <tf.Tensor: shape=(3, 3), dtype=float32, numpy=array([[-1.,  0., -1.],[ 0.,  0., -2.],[ 0., -3.,  0.]], dtype=float32)>-----------简单示例:d = c - tf.scatter_nd([[0,0],[2,1]], [c[0,0],c[2,1]], c.shape)解释:将张量的第[0,0][2,1]两个位置元素替换为0得到新的张量综上所述,通过`tf.scatter_nd获取的维度和参数中的shape保持一致`

7.15 tf.where

7-15  tf.where(condition, x=None, y=None, name=None)解释:返回满足条件condition的所有元素。返回结果是一个满足结果的位置列表。示例:tf.where([True, False, False, True])>> <tf.Tensor: shape=(2, 1), dtype=int64, numpy=array([[0],[3]])>tf.where([[[True, False], [False, True], [True, True]]])>> <tf.Tensor: shape=(4, 3), dtype=int64, numpy=array([[0, 0, 0],[0, 1, 1],[0, 2, 0],[0, 2, 1]])>其实,返回的结果都是2维的,axis=1中的列表数据中,每个数据代表满足condition条件的维度位置。综上所述,通过tf.where获取的`维度是2维`的,即[None, None]

8、tf.data.xx

8.0 tf.data.Dataset

  1. 底层对应的类为tf.python.data.ops.dataset_ops.DatasetV2
  2. 常用方法:
2-1 xx.map(map_func, num_parallel_calls=None, deterministic=None )>>> dataset = Dataset.range(1, 6)  # ==> [ 1, 2, 3, 4, 5 ]>>> dataset = dataset.map(lambda x: x + 1)>>> list(dataset.as_numpy_iterator())[2, 3, 4, 5, 6]-- num_parallel_calls = tf.data.experimental.AUTOTUNE # 让tensorflow自动选择合适的cpu处理数量值为-1,术语tensorflow的并行化策略。
2-2 xx.buffer(buffer_size, seed=None, reshuffle_each_iteration=None)shuffle是防止数据过拟合的重要手段buffer_size: A tf.int64 scalar tf.Tensor, representing the number of elements from this dataset from which the new dataset will sample.reference:https://blog.csdn.net/weixin_43593330/article/details/103243455解释:tf会每次将buffer_size个数据抽放到缓冲区,然后随机去掉一个数据,用没被选中的item替换或填充【我的理解】,最后选出来的数据不会重复。不过若进行过batch_size,那么每次取出的结果会按照batch_size进行分组。示例:dataset = tf.data.Dataset.from_tensor_slices(np.array([1, 2, 3, 4, 5, 6, 7]))dataset = dataset.shuffle(3)for ele in dataset:print(ele.numpy())3251647dataset = dataset.batch(3)for ele in dataset:print(ele.numpy())[3 4 5][2 7 1][6]
2-3 xx.batch(batch_size, drop_remainder=False)Combines consecutive elements of this dataset into batches.将此数据集的连续元素组合成批。示例:>>> dataset = tf.data.Dataset.range(8)>>> dataset = dataset.batch(3)>>> list(dataset.as_numpy_iterator())[array([0, 1, 2]), array([3, 4, 5]), array([6, 7])]>>> dataset = tf.data.Dataset.range(8)>>> dataset = dataset.batch(3, drop_remainder=True)>>> list(dataset.as_numpy_iterator())[array([0, 1, 2]), array([3, 4, 5])]reference:https://blog.csdn.net/zkbaba/article/details/103206468-- drop_remainder 如果为True,那么最后不够成批量及batch_size将会被舍弃。若为False,则也会保留。
2-4 xx.pretetch(buffer_size)使用 Dataset.prefetch() 方法进行数据预加载后的训练流程,在 GPU 进行训练的同时 CPU 进行数据预加载,提高了训练效率。-- buffer_size = tf.data.experimental.AUTOTUNE  # 同map,让tensorflow自动选择合适的数值。
2-5 xx.as_numpy_iterator()获取该Dataset的真实数据,为一个迭代器。示例:for i in ds_data.as_numpy_iterator():print(i)
2-6 xx.window(size, shift=None, stride=1, drop_remainder=False)将数据按照窗格分割,一版跟在刚转换的Tensor对象后示例1:import tensorflow as tfdataset = tf.data.Dataset.from_tensor_slices(tf.range(10))dataset = dataset.window(5,drop_remainder=True)dataset = dataset.flat_map(lambda window: window.batch(5))dataset = dataset.map(lambda window: (window[:-1],window[-1:]))for X,y in dataset:print("Input:",X.numpy(),"Target:",y.numpy())>>> Input: [0 1 2 3] Target: [4]>>>   Input: [1 2 3 4] Target: [5]>>>    Input: [2 3 4 5] Target: [6]>>>    Input: [3 4 5 6] Target: [7]>>>    Input: [4 5 6 7] Target: [8]>>>    Input: [5 6 7 8] Target: [9]    示例2:def batch_dataset(dataset):dataset_batched = dataset.batch(window_size,drop_remainder=True)return dataset_batcheddef trans_to_dataset(df_x, df_y, window_size):ds_data = tf.data.Dataset.from_tensor_slices(tf.constant(df_x.values[:-1],dtype =\tf.float32)).window(window_size,shift=1).flat_map(batch_dataset) # the latest data has no label, so ignore itds_label = tf.data.Dataset.from_tensor_slices(tf.one_hot(tf.constant(df_y.values\[window_size:]), depth=3))# 在组合到一起之前,应该是可以进行分割!!但是这里先不这样用了dataset = tf.data.Dataset.zip((ds_data,ds_label)).batch(128).cache()return datasetwindow_size = 20train_db = trans_to_dataset(train_df, train_label,window_size)train_db = train_db.shuffle(240620).repeat(2)详解:# 第1步: tf.constant()可以将numpy.arry类型转化为tensor, df.values正是np.array# 第2步: tf.data.Dataset.from_tensor_slices()是可以把数据转化为tensor的另一种形式,貌似是做成了一个迭代器?(可不可以直接从array过来)# 第3步:用这个可迭代的tensor,的window方法,按照(window_size, shift)把原始数据扩展为目标数据集应有的元素# 第4步:继续对上面的数据批量批处理,.flat_map(),处理目的是按照我们的window_size把数据集分割小窗口后用[]括起来,实现方法是第5步# 第5步:定义分割窗口并括起来的功能函数dataset_batched = dataset.batch(window_size,drop_remainder=True),记得drop掉最后不整齐的数据# 第6步:把X和标签数据Y分别处理成可迭代并且已经[]括起来的数据后,tf.data.Dataset.zip组合到一起,变成训练集。
2-7 tf.timestamp()解释:从1970年开始计算的时间戳示例:【规范】def printbar():today_ts = tf.timestamp()  # 时间戳print('today_ts:', today_ts)hour = tf.cast(today_ts // 3600 % 24 + 8, tf.int32)  # 小时,和北京时间差8个时差minite = tf.cast((today_ts % 3600) // 60, tf.int32)  # 分钟second = tf.cast(tf.floor(today_ts % 60), tf.int32)  # 秒钟def timeformat(m):if tf.strings.length(tf.strings.format("{}", m)) == 1:return (tf.strings.format('0{}', m))else:return (tf.strings.format('{}', m))timestring = tf.strings.join([timeformat(hour), timeformat(minite), timeformat(second)], separator=':')tf.print('====' * 8 + timestring)
2-8 tf.cast(x, dtype, name=None)解释:改变张量的数据类型输入或者需要改变的数据类型为:uint8, uint16, uint32, uint64, int8, int16, `int32`, int64, float16, `float32`, float64, complex64, complex128, bfloat16示例:x = tf.constant([1.8, 2.2], dtype=tf.float32)tf.dtypes.cast(x, tf.int32)  # [1, 2], dtype=tf.int32
2-9 tf.constant(value, dtype=None, shape=None, name="Const")解释:tensorflow中的常量转换,value可以是数值,可以是数值列表-- dtype 指定数值类型方法:xx.numpy() # 获取对应numpy数据tf.rank(xx) # 获取到xx的维度大小,也是tf.Tensor类型返回:tf.Tensor()示例:i = tf.constant(1) # tf.int32 类型常量l = tf.constant(1,dtype = tf.int64) # tf.int64 类型常量f = tf.constant(1.23) #tf.float32 类型常量d = tf.constant(3.14,dtype = tf.double) # tf.double 类型常量s = tf.constant("hello world") # tf.string类型常量b = tf.constant(True) #tf.bool类型常量print(tf.int64 == np.int64) print(tf.bool == np.bool)print(tf.double == np.float64)print(tf.string == np.unicode) # tf.string类型和np.unicode类型不等价>> True>> True>> True>> False
2-10 tf.rank(input, name=None)解释:获取input的维度大小,返回tf.Tensor类型相当于numpy.ndim示例:t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]])tf.rank(t)  # <tf.Tensor: shape=(), dtype=int32, numpy=3>tf.rank(t).numpy()  # 3

8.1 tf.data.TextLineDataset()

官方原话:
class TextLineDataset(dataset_ops.Dataset):"""A `Dataset` comprising lines from one or more text files."""def __init__(self, filenames, compression_type=None, buffer_size=None):Creates a `TextLineDataset`.Args:filenames: A `tf.string` tensor containing one or more filenames.compression_type: (Optional.) A `tf.string` scalar evaluating to one of`""` (no compression), `"ZLIB"`, or `"GZIP"`.buffer_size: (Optional.) A `tf.int64` scalar denoting the number of bytesto buffer. A value of 0 results in the default buffering values chosenbased on the compression type.

中文含义:

参数:--filenames:                         单个或者多个string格式的文件名或者目录--compression_type:                  可选!!!格式是ZLIB或者GZIP--buffer_size:                      可选!!!决定缓冲字节数多少tf.data.TextLineDataset 接口提供了一种方法从数据文件中读取。我们提供只需要提供文件名(1个或者多个)。
这个接口会自动构造一个dataset,类中保存的元素:文中一行,就是一个元素,是string类型的tensor。

举例:

# 文件路径可以用list包括起来,多个路径
input_files = ['./input_file11', './input_file22']
dataset = tf.data.TextLineDataset(input_files)

9、tf.keras.layers.experimental.preprocessing.xx

9.1 tf.keras.layers.experimental.preprocessing.TextVectorization

     def __init__(self,max_tokens=None,   # 输入的文本最大长度standardize=LOWER_AND_STRIP_PUNCTUATION,  # 小写并去除标点符号和首尾空格split=SPLIT_ON_WHITESPACE,   # 按照空格切割ngrams=None,output_mode=INT,output_sequence_length=None, # 输出序列长度,也是输出向量的长度pad_to_max_tokens=True,**kwargs):...If desired, the user can call this layer's adapt() method on a dataset.When this layer is adapted, it will analyze the dataset, determine thefrequency of individual string values, and create a 'vocabulary' from them.This vocabulary can have unlimited size or be capped, depending on theconfiguration options for this layer; if there are more unique values in theinput than the maximum vocabulary size, the most frequent terms will be usedto create the vocabulary.The processing of each sample contains the following steps:1) standardize each sample (usually lowercasing + punctuation stripping)2) split each sample into substrings (usually words)3) recombine substrings into tokens (usually ngrams)4) index tokens (associate a unique int value with each token)5) transform each sample using this index, either into a vector of ints ora dense float vector.将文本数据处理为文本向量,生成长度为output_sequence_length的向量。示例:vectorize_layer = TextVectorization(output_sequence_length=15)vectorize_layer.adapt(tf.data.Dataset.from_tensor_slices([['1 2', '2 3', '3 4' , 'a b', 'c d']]))    # adapt 中的数据需要时二维的(None, 1)vectorize_layer([['1 2 c']]).numpy()>>> Out[67]: array([[9, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

10、tf.keras.losses.xx

损失类选择

10.1 tf.keras.losses.BinaryCrossentropy

二分类交叉熵:loss =  z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x))多分类使用

11、tf.keras.metrics.xx

11.1 tf.keras.metrics.Accuracy

计算预测值 与 真实值的准确度

tf.keras.metrics.Accuracy
(name='accuracy',dtype=None
)xx.update_state
(y_true,y_pred,sample_weight=None
)用法:m = tf.keras.metrics.Accuracy()m.update_state([1, 2, 3, 4], [0, 2, 3, 4])# Out[4]: <tf.Variable 'UnreadVariable' shape=() dtype=float32, numpy=4.0>m.result().numpy()# Out[5]: 0.75m.reset_states()m.update_state([1, 2, 3, 4], [0, 2, 3, 4], sample_weight = [1, 1, 0, 0])# Out[7]: <tf.Variable 'UnreadVariable' shape=() dtype=float32, numpy=2.0>m.result().numpy()# Out[8]: 0.5

11.2、tf.keras.metrics.Mean

计算给定值的(加权)平均数

tf.keras.metrics.Mean
(name='mean',dtype=None
)用法:m = tf.keras.metrics.Mean()m.update_state([1, 3, 5, 7])# Out[10]: <tf.Variable 'UnreadVariable' shape=() dtype=float32, numpy=4.0>m.result().numpy()# Out[11]: 4.0m.reset_states()m.update_state([1, 3, 5, 7], sample_weight=[1, 1, 0, 0])# Out[13]: <tf.Variable 'UnreadVariable' shape=() dtype=float32, numpy=2.0>m.result().numpy()# Out[14]: 2.0

12、tf.keras.utils.xx

12.1 keras.utils.to_categorical(labels, num_classes=10)

将分类的标签,转换为one-hot的形式

二分类:
keras.utils.to_categorical(np.random.randint(2, size=(1000, 1)), num_classes=10)多分类:
keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)

13、tf.keras.layers.xx

13.1 tf.keras.layers.LSTM

 LSTM(3,return_sequences = True,input_shape=(None,3))详解:输入:LSTM的输入一定是3维的,分别是(Batch, 时间序列,属性维度)。输出:return_sequences = False时,输出是2维的,分别是(Batch, lstm_units)。return_sequences = True时,输出是3维的,分别是(Batch, 时间序列,lstm_units),可进行多次调用。所以,LSTM可以直接连接Dense层。但是Conve层必须先flat才能Dense层。

14、tf.keras.callbacks.xx

如何使用回调函数呢,其实实在model.fit中添加参数即可:

#使用回调函数
#tensorBoard、EarlyStopping、ModelCheckPoint
logdir = os.path.join("callbacks")
if not os.path.exists(logdir):os.mkdir(logdir)
output_model_file = os.path.join(logdir,"fashion_mnist_model.h5")callbacks = [keras.callbacks.TensorBoard(log_dir=logdir), #log_dir将输出的日志保存在所要保存的路径中keras.callbacks.ModelCheckpoint(output_model_file, save_best_only = True), keras.callbacks.EarlyStopping(patience=5, min_delta=1e-3),
]
#训练模型会,返回一个结果保存在history中
history = model.fit(x_train_scaled, y_train, epochs=50, validation_data=(x_valid_scaled, y_valid), callbacks=callbacks) #使用回调函数

14.1 tf.keras.callbacks.TensorBoard

 tf.keras.callbacks.TensorBoard(log_dir='logs', histogram_freq=0, write_graph=True, write_images=False,update_freq='epoch', profile_batch=2, embeddings_freq=0,embeddings_metadata=None, **kwargs)-- log_dir: 保存可视化目录-- histogram_freq: 按照epochs为单位,保存数据的频率。-- write_graph: 是否可视化图形,当为True时,日志文件会非常大。-- write_images: 是否写入模型权重,并在tb中可视化为图形。-- update_freq: 和histogram_greq时配合使用的,即保存tb基于什么为单位。-- profile_batch : [不懂]。-- embeddings_freq: 可视化嵌入层,[不太懂]。-- embeddings_metadata: []。
详解:
TensorBoard:是Tensorflow自带的一个强大的可视化工具,也是一个web应用程序套件,它通过将tensorflow程序输出
的日志文件的信息可视化使得tensorflow程序的理解、调试和优化更加简单高效。Tensorboard的可视化依赖于
tensorflow程序运行输出的日志文件,因而tensorboard和tensorflow程序在不同的进程中运行。示例:logdir = str(Path('./data/autograph/' + stamp))tb_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)可视化TB图:tensorboard --logdir=path_to_your_logs图示包含内容有:直方图 HISTOGRAMS折线图 DISTRIBUTIONSGRAPHS面板 SCALARS面板OVERVIEW

14.2 tf.keras.callbacks.EarlyStopping

 tf.keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto',baseline=None, restore_best_weights=False)-- monitor: 需要监视的量,val_loss,val_acc。-- patience: 当early stop被激活(如发现loss相比上一个epoch训练没有下降),则经过patience个epoch后停止训练。-- mode: ‘auto’,‘min’,'max’之一,在min模式训练,如果检测值停止下降则终止训练。在max模式下,当检测值不再上升的时候则停止训练。-- min_delta:阈值。
详解:
为了获得性能良好的神经网络,网络定型过程中需要进行许多关于所用设置(超参数)的决策。超参数之一是定型周期
(epoch)的数量:亦即应当完整遍历数据集多少次(一次为一个epoch)?如果epoch数量太少,网络有可能发生欠拟合
(即对于定型数据的学习不够充分);如果epoch数量太多,则有可能发生过拟合(即网络对定型数据中的“噪声”而非信号拟
合)。早停法旨在解决epoch数量需要手动设置的问题。它也可以被视为一种能够避免网络发生过拟合的正则化方法(与
L1/L2权重衰减和丢弃法类似)。根本原因就是因为继续训练会导致测试集上的准确率下降。那继续训练导致测试准确率下降
的原因猜测可能是1. 过拟合 2. 学习率过大导致不收敛。示例:#当loss在200个epoch后没有提升,则提前终止训练。stop_callback = tf.keras.callbacks.EarlyStopping(monitor = "loss", patience= 200)

14.3 tf.keras.callbacks.ModelCheckPoint

 tf.keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False,save_weights_only=False, mode='auto', save_freq='epoch', options=None, **kwargs)解释:在训练中途进行模型的保存。--filepath: 保存到的文件路径-- monitor: 判断的依据-- verbose: [不清楚]-- save_best_only: 只保存最好的模型-- mode: 与monitor配合使用,按照最大或者最小monitor值进行最好模型的判断-- save_weights_only: 如果为True,model.save_weights(filepath),如果为False,model.save(filepath)-- save_freq: 默认是'epoch',如果为integer则表示多少个batches。示例:EPOCHS = 10checkpoint_filepath = '/tmp/checkpoint'model_checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_filepath,save_weights_only=True,monitor='val_acc',mode='max',save_best_only=True)# Model weights are saved at the end of every epoch, if it's the best seen# so far.model.fit(epochs=EPOCHS, callbacks=[model_checkpoint_callback])# The model weights (that are considered the best) are loaded into the model.model.load_weights(checkpoint_filepath)

14.4 tf.keras.callbacks.ReduceLROnPlateau

 tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto',min_delta=0.0001, cooldown=0, min_lr=0, **kwargs)解释:自动调整学习率-- monitor: 被监控的数据对象-- factor: 学习率降低值为:new_lr = lr * factor-- patience: 多少个epoches后,monitor值没变,那么则更新学习率lr-- verbose: 0:quiet,1:update_messages-- mode: {'auto', 'min', 'max'},auto自动会按照monitor标准监测,如果是min则低于一个值没有再降低,则改变学习率,max则相反,不能再升高,那么就更改学习率。-- min_delta: [不清楚]threshold for measuring the new optimum, to only focus on significant changes.-- cooldown: [不清楚]-- min_lr: 学习率的下界示例:#如果loss在100个epoch后没有提升,学习率减半。lr_callback = tf.keras.callbacks.ReduceLROnPlateau(monitor="loss",factor = 0.5, patience = 100)

15、Tensor

15.1 类型详解

15.2 属性和方法

ts = tf.Tensor() # 假设ts.dtype   # 数据类型
ts.shape    # 数据尺寸ts.numpy()   # 获取对应的numpy结果
tf.rank(ts)   # 获取对应的维度,返回结果仍是tf.Tensor
tf.rank(ts).numpy 和 ts.numpy().ndim 和 np.ndim(ts.numpy()) 一样的结果

15.3 常量和变量

15.3.1 常量:

常量数据的改变,会开辟新的内存空间。可用id(xx)验证内存hash地址。

tf.constant()
15.3.2 变量:

变量数据的改变,不会开辟新的内存空间。一般被设置为被训练的参数。

v = tf.Variable([1.0,2.0],name = "v")方法:v.assign_add([1.0, 1.0])    # 变量加法

16、计算Graph

Tensorflow2 共有三种计算图: 静态计算图,动态计算图,Autograph

tf1.0+ 使用的是静态计算图,执行计算图,需要开启会话Session。
tf2.0+ 采用的是动态图,无需开启Session,可立即执行逻辑。优点:方便程序的调试,容易使用。缺点:运行效率低,因为动态图需要多次使用python进程和tf中的c++进程的通信,而静态图构建完后几乎全部是在tf内核上的c++代码执行,效率更高。那么,如果在tf2.0+中使用静态图,可以通过 @tf.function 装饰器将Python函数转换为对应的tf计算图构建代码,即相当于在tf1.0+中使用Session执行代码。那使用tf.function构建静态图的方式就是AutoGraph

16.1 静态计算图

使用静态计算图分两步,第一步定义计算图,第二步在会话中执行计算图。

16.1.1 tf1.0+静态计算图
import tensorflow as tf#定义计算图
g = tf.Graph()
with g.as_default():#placeholder为占位符,执行会话时候指定填充对象x = tf.placeholder(name='x', shape=[], dtype=tf.string)  y = tf.placeholder(name='y', shape=[], dtype=tf.string)z = tf.string_join([x,y],name = 'join',separator=' ')#执行计算图
with tf.Session(graph = g) as sess:print(sess.run(fetches = z,feed_dict = {x:"hello",y:"world"}))
16.1.2 tf2.0+中调用tf1.0+静态计算图

tf2.0 中在 tf.compat.v1子模块中保留了对TensorFlow1.0静态图的API。

import tensorflow as tfg = tf.compat.v1.Graph()
with g.as_default():x = tf.compat.v1.placeholder(name='x', shape=[], dtype=tf.string)y = tf.compat.v1.placeholder(name='y', shape=[], dtype=tf.string)z = tf.strings.join([x,y],name = "join",separator = " ")with tf.compat.v1.Session(graph = g) as sess:# fetches的结果非常像一个函数的返回值,而feed_dict中的占位符相当于函数的参数序列。result = sess.run(fetches = z,feed_dict = {x:"hello",y:"world"})print(result)

16.2 动态计算图

动态计算图已经不区分计算图的定义和执行了,而是定义后立即执行。因此称之为 Eager Excution.

16.2.1 tf2.0+中的动态计算图
# 动态计算图在每个算子处都进行构建,构建后立即执行x = tf.constant("hello")
y = tf.constant("world")
z = tf.strings.join([x,y],separator=" ")tf.print(z)
>> hellow world
# 可以将动态计算图代码的输入和输出关系封装成函数def strjoin(x,y):z =  tf.strings.join([x,y],separator = " ")tf.print(z)return zresult = strjoin(tf.constant("hello"),tf.constant("world"))
print(result)>> hello world
>> tf.Tensor(b'hello world', shape=(), dtype=string)

16.2 静态计算图Autograph

解决:动态计算图运行效率相对较低。
使用@tf.function装饰器转换tf2.0+中的动态图为tf1.0+中的动态图。在tf1.0+中,构建计算图,第一步定义计算图,第二步创建会话,第三步是执行计算图。在tf2.0+中,如果采用@tf.function 装饰器的方式,即Autograph,第一步定义函数,第二步调用函数即可。
应用场景:后台开发的时候,使用动态图方式进行代码调试,应用到线上的时候,使用Autograph会更快速,我在一个小模型下测试过两种方式的执行速度,Autograph方式是动态图方式的4+倍。

import tensorflow as tf# 使用autograph构建静态图@tf.function
def strjoin(x,y):z =  tf.strings.join([x,y],separator = " ")tf.print(z)return zresult = strjoin(tf.constant("hello"),tf.constant("world"))
print(result)>> hello world
>> tf.Tensor(b'hello world', shape=(), dtype=string)

Autograph编码规范

  • 1,被@tf.function修饰的函数应尽可能使用TensorFlow中的函数而不是Python中的其他函数。例如使用tf.print而不是print,使用tf.range而不是range,使用tf.constant(True)而不是True.

  • 2,避免在@tf.function修饰的函数内部定义tf.Variable.

  • 3,被@tf.function修饰的函数不可修改该函数外部的Python列表或字典等数据结构变量。

1,被@tf.function修饰的函数应尽量使用TensorFlow中的函数而不是Python中的其他函数。import numpy as np
import tensorflow as tf@tf.function
def np_random():a = np.random.randn(3,3)tf.print(a)@tf.function
def tf_random():a = tf.random.normal((3,3))tf.print(a)
#np_random每次执行都是一样的结果。
np_random()
np_random()#tf_random每次执行都会有重新生成随机数。
tf_random()
tf_random()
2,避免在@tf.function修饰的函数内部定义tf.Variable.# 避免在@tf.function修饰的函数内部定义tf.Variable.x = tf.Variable(1.0,dtype=tf.float32)
@tf.function
def outer_var():x.assign_add(1.0)tf.print(x)return(x)# 正确运行
outer_var()
outer_var()@tf.function
def inner_var():x = tf.Variable(1.0,dtype = tf.float32)x.assign_add(1.0)tf.print(x)return(x)#执行将报错
#inner_var()
#inner_var()
3,被@tf.function修饰的函数不可修改该函数外部的Python列表或字典等结构类型变量。tensor_list = []#@tf.function #加上这一行切换成Autograph结果将不符合预期!!!
def append_tensor(x):tensor_list.append(x)return tensor_listappend_tensor(tf.constant(5.0))
append_tensor(tf.constant(6.0))
print(tensor_list)
>> [<tf.Tensor: shape=(), dtype=float32, numpy=5.0>, <tf.Tensor: shape=(), dtype=float32, numpy=6.0>]tensor_list = []@tf.function #加上这一行切换成Autograph结果将不符合预期!!!
def append_tensor(x):tensor_list.append(x)return tensor_listappend_tensor(tf.constant(5.0))
append_tensor(tf.constant(6.0))
print(tensor_list)
>> [<tf.Tensor 'x:0' shape=() dtype=float32>]

Autograph基本原理
第一件事情是创建计算图。

即创建一个静态计算图,跟踪执行一遍函数体中的Python代码,确定各个变量的Tensor类型,并根据执行顺序将算子添加到计算图中。 在这个过程中,如果开启了autograph=True(默认开启),会将Python控制流转换成TensorFlow图内控制流。 主要是将if语句转换成 tf.cond算子表达,将while和for循环语句转换成tf.while_loop算子表达,并在必要的时候添加 tf.control_dependencies指定执行顺序依赖关系。

第二件事情是执行计算图。

需要注意的是,如果调用被@tf.function装饰的函数时输入的参数不是Tensor类型,则每次都会重新创建计算图。

reference: AutoGraph的机制原理

17、自动微分GradientTape-自动前向反向传播

在我们刚入门深度学习的时候,我们就直接接触到了如何让结果更准确,那就是让loss最小,那么每次需要更新的变量值是如何改变的,其实就是通过数学公式的反向传播求梯度的方式确定的。
tf2.0+中提供了tf.GradientTape来记录正向的运算过程,自动对变量值微分。

17.1 求导数

变量求导:

import tensorflow as tf
import numpy as np # f(x) = a*x**2 + b*x + c的导数x = tf.Variable(0.0,name = "x",dtype = tf.float32)
a = tf.constant(1.0)
b = tf.constant(-2.0)
c = tf.constant(1.0)with tf.GradientTape() as tape:y = a*tf.pow(x,2) + b*x + cdy_dx = tape.gradient(y,x)
print(dy_dx)>> tf.Tensor(-2.0, shape=(), dtype=float32)

常量求导:

# 对常量张量也可以求导,需要增加watch
x = tf.Variable(0.0,name = "x",dtype = tf.float32)
a = tf.constant(1.0)
b = tf.constant(-2.0)
c = tf.constant(1.0)with tf.GradientTape() as tape:tape.watch([a,b,c])y = a*tf.pow(x,2) + b*x + cdy_dx,dy_da,dy_db,dy_dc = tape.gradient(y,[x,a,b,c])
print(dy_da)
print(dy_dc)>> tf.Tensor(0.0, shape=(), dtype=float32)
>> tf.Tensor(1.0, shape=(), dtype=float32)

二阶导数

# 可以求二阶导数,但需要记录多个运行过程
with tf.GradientTape() as tape2:with tf.GradientTape() as tape1:   y = a*tf.pow(x,2) + b*x + cdy_dx = tape1.gradient(y,x)
dy2_dx2 = tape2.gradient(dy_dx,x)print(dy2_dx2)>> tf.Tensor(2.0, shape=(), dtype=float32)

在Autograph中使用

@tf.function
def f(x):   a = tf.constant(1.0)b = tf.constant(-2.0)c = tf.constant(1.0)# 自变量转换成tf.float32x = tf.cast(x,tf.float32)with tf.GradientTape() as tape:tape.watch(x)y = a*tf.pow(x,2)+b*x+cdy_dx = tape.gradient(y,x) return((dy_dx,y))tf.print(f(tf.constant(0.0)))
tf.print(f(tf.constant(1.0)))
>> (-2, 1)
>> (0, 0)

17.2 和优化器配合使用

# 求f(x) = a*x**2 + b*x + c的最小值
# 使用optimizer.apply_gradientsx = tf.Variable(0.0,name = "x",dtype = tf.float32)
a = tf.constant(1.0)
b = tf.constant(-2.0)
c = tf.constant(1.0)optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
for _ in range(1000):with tf.GradientTape() as tape:y = a*tf.pow(x,2) + b*x + cdy_dx = tape.gradient(y,x)optimizer.apply_gradients(grads_and_vars=[(dy_dx,x)])tf.print("y =",y,"; x =",x)>> y = 0 ; x = 0.999998569

使用结构为:

# 给x应用计算的导数:dy_dx
tf.keras.optimizers.SGD(learning_rate=0.01).apply_gradients(grads_and_vars=[(dy_dx,x)])
# optimizer.minimize相当于先用tape求gradient,再apply_gradient
tf.keras.optimizers.SGD(learning_rate=0.01).minimize(function,[x])     

18、tf.random.xx

18.1 tf.random.uniform

 tf.random.uniform(shape, minval=0, maxval=None, dtype=tf.dtypes.float32, seed=None, name=None)解释:生成shape大小的,最小值为minval,最大值为maxval,数据类型为dtype的均匀分布的值。

18.2 tf.random.set_seed

 tf.random.set_seed(seed)解释:赋值随机种子

18.3 tf.random.truncated_normal

 tf.random.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.dtypes.float32, seed=None, name=None)解释:从截断的正态分布中输出随机值。生成的值服从具有指定平均值和标准偏差的正态分布,如果生成的值大于平均值2个标准偏差的值则丢弃重新选
择。在正态分布的曲线中,横轴区间(μ-σ,μ+σ)内的面积为68.268949%。横轴区间(μ-2σ,μ+2σ)内的面积为95.449974%。横轴区间(μ-3σ,μ+3σ)内的面积为99.730020%。X落在(μ-3σ,μ+3σ)以外的概率小于千分之三,在实际问题中常认为相应的事件是不会发生的,基本上可以把
区间(μ-3σ,μ+3σ)看作是随机变量X实际可能的取值区间,这称之为正态分布的“3σ”原则。在tf.random.truncated_normal中如果x的取值在区间(μ-2σ,μ+2σ)之外则重新进行选择。这样保证了生成的值都
在均值附近。-- shape 形状-- mean  均值-- stddev 标准差,平方是方差-- seed 同tf.random.set_seed设置随机种子,当设置随机种子以后,生成的数据是一样的。

19、tf.linalg.xx

19.1 常用方法

1) tf.linalg.diag(diagonal,name="diag",k=0,num_rows=-1,num_cols=-1,padding_value=0,align="RIGHT_LEFT")解释:创建对角矩阵。示例:tf.linalg.diag([1, 2, 3, 5, 5, 5])>> <tf.Tensor: shape=(6, 6), dtype=int32, numpy=array([[1, 0, 0, 0, 0, 0],[0, 2, 0, 0, 0, 0],[0, 0, 3, 0, 0, 0],[0, 0, 0, 5, 0, 0],[0, 0, 0, 0, 5, 0],[0, 0, 0, 0, 0, 5]], dtype=int32)>2) 

20、数据-预处理

20.1 序列预处理

keras.preprocessing.sequence.pad_sequences(sequences,maxlen=None,dtype='int32',padding='pre',truncating='pre', value=0.)

解释: sequences:浮点数或整数构成的两层嵌套列表
maxlen:None或整数,为序列的最大长度。大于此长度的序列将被截短,小于此长度的序列将在后部填0.在命名实体识别任务中,主要是指句子的最大长度
dtype:返回的numpy array的数据类型 padding:‘pre’或‘post’,确定当需要补0时,在序列的起始还是结尾补
truncating:‘pre’或‘post’,确定当需要截断序列时,从起始还是结尾截断
value:浮点数,此值将在填充时代替默认的填充值0

20.2 转换为tf_record

参考:
tf_record详解
csv.reader详解
unicodedata库执行英文数据标准化

21、TF版本,CUDA版本,Cudnn版本对应

https://www.tensorflow.org/install/source#common_installation_problems

一、TF2 常用命令相关推荐

  1. Kubectl 常用命令, 开发人员常用k8s命令

    Kubectl 常用命令: 什么是常用,我用的,就是常用的

  2. docker常用命令详解

    docker常用命令详解 本文只记录docker命令在大部分情境下的使用,如果想了解每一个选项的细节,请参考官方文档,这里只作为自己以后的备忘记录下来. 根据自己的理解,总的来说分为以下几种: Doc ...

  3. 客快物流大数据项目(十五):DockeFile常用命令

    目录 DockeFile常用命令 一.FROM 二.​​​​​​​MAINTAINER 三.​​​​​​​RUN

  4. 客快物流大数据项目(九):Docker常用命令

    目录 Docker常用命令 一.帮助命令 二.镜像命令 1.搜索镜像

  5. linux常用命令(转载)

    Linux常用命令大全(非常全!!!) 最近都在和Linux打交道,感觉还不错.我觉得Linux相比windows比较麻烦的就是很多东西都要用命令来控制,当然,这也是很多人喜欢linux的原因,比较短 ...

  6. maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

    maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository. ...

  7. linux kvm虚拟化命令,Linux系统下kvm虚拟化(三)日常管理常用命令和配置说明

    根据我们之前创建和一些操作可以知道,KVM虚拟机的管理主要是通过virsh命令对环境下kvm虚拟机进行管理,下边这里整理一些常用的配置说明以及如何进行日常管理维护. 1,查看KVM虚拟机配置文件 KV ...

  8. kubectl常用命令_《蹲坑学kubernetes》之十五:kubectl命令详解

    kubectl用于运行Kubernetes集群命令的管理工具.本章节主要讲了kubectl基本语法和使用方法.在以后的实际工作中,使用越来越多,也会越来越熟悉. 1.kubectl语法 kubectl ...

  9. 计算机网络管理的常用命令,网络管理常用命令图文详解.pdf

    网络工程师必备 – 网络管理常用命令图文详解 网络工程师必备 网络管理常用命令 图文详解 V1.0 V1.0 包含 ping.ipconfig.netstat.nbtstat.tracert. pat ...

最新文章

  1. The Innovation | Volume 2 Issue 4 正式出版
  2. mysql ib_logfile 数量_Mysql 事务日志(Ib_logfile)
  3. 启动hive报错:java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang
  4. 阿里与珠海横琴新区达成战略合作,阿里云助力打造横琴智能岛
  5. mysql有没有实现高可用_MySQL高可用架构:mysql+keepalived实现
  6. 删除60天之前的elasticsearch索引
  7. 怎样把word文档里的html格式去掉,word文档去除格式
  8. 中国计算机学会推荐国际学术会议和期刊(A类)2019年
  9. 数据库MySQL创库、创表基本命令
  10. 学术论文中常用简写(缩写)汇总
  11. 【English】十一、一般疑问句
  12. [置顶] 我读《海底两万里》
  13. 下载王者荣耀皮肤高清图片
  14. Python输入一个字符串,输出其中每个字符的出现次数。要求使用标准库collotections中的Counter类...
  15. Dynamips和Vmware完成CCVP试验(3)
  16. 梯度下降原理(SGD,Adam,BGD,momentum,Adagrad,NAG)
  17. 骡友们推荐的各个学习英文网站的汇总。
  18. 在 Python 中使用蒙特卡罗方法预测股票价格,使用蒙特卡罗模拟确定明年 SPY 最有可能的价格
  19. 迅为iMX6ULL开发板-创建 ap 热点
  20. Python按照拼音顺序给数组排序

热门文章

  1. ECharts 源码解读 二
  2. matlab中设置数据长度,excel表格长宽设置/如何检查excel单元格内数字长度
  3. 不讲武德!小伙陪大爷下棋靠手机开挂艰难获胜:我选的是天人合一难度
  4. 红米2a android5,红米手机/小米手机2S/2A三机对比图赏
  5. 警察规范执法案例_警察改革沉浸式技术可以改变执法方式
  6. SMTP与POP的默认端口号
  7. 踩过一个FM24C64与FM24CL64的坑
  8. TDH添加自定义参数
  9. AI模型训练部署:在CSK6芯片上运行AI模型
  10. Springboot Application 集成 OSGI 框架开发