TensorFlow¶
构建计算图¶
OPS¶
切片¶
Tensorflow 提供了方法对 Tensor 进行切片:
tf.strided_slice(
input_,
begin,
end,
strides=None,
begin_mask=0,
end_mask=0,
ellipsis_mask=0,
new_axis_mask=0,
shrink_axis_mask=0,
var=None,
name=None
)
start
与 end
的长度应与 Tensor 的维度相同, 代表某个维度从多少到多少.
乘法¶
与 Numpy 相同, tensorflow 的乘法也有普通乘法与矩阵乘法.
- 普通乘法
tf.multiply(a, b, name=None)
普通乘法与 Numpy 的普通乘法一样, element-wise
乘法, 也有广播机制, 只不过是对 Tensor 操作.
>>> a = tf.constant(np.arange(12), dtype=np.int32, shape=[3,4])
>>> b = tf.constant(np.arange(4), dtype=np.int32, shape=[1,4])
>>> a * b
<tf.Tensor 'mul:0' shape=(3, 4) dtype=int32>
小技巧
对 Tensor 操作会自动重载 *
乘法操作符.
- 矩阵乘法
tf.matmul(a, b, name=None)
矩阵乘法也与 numpy.dot()
相同. 有二维矩阵乘法与三维矩阵乘法.
二维矩阵 乘法就是正常的矩阵乘法 [m, n] * [n, p] = [m, p]
.
三维矩阵 乘法要求第 0 维大小相同, 相当于在第 0 维进行 metric-wise
批量矩阵相乘.
>>> a = tf.constant(np.ones([2,3,4]))
>>> b = tf.constant(np.ones([2,4,5]))
>>> a @ b
<tf.Tensor 'matmul:0' shape=(2, 3, 5) dtype=float64>
小技巧
Python 3.5 版本加入 @
矩阵乘法操作符, Tensorflow也已实现重载.
TensorFlow 优化¶
显存占用¶
增加环境变量, 控制可见GPU
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
随着进程逐渐增加显存占用, 而不是再初始化 Session
时一下占用所有空闲显存:
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
## tf.Session()
tf.Session(config = config)
日志级别¶
TimeLine 查看运行时间线¶
使用 timeline
查看一个 step
的运行时间线, 并保存为 json
文件, 使用 chrome
查看时间线:
from tensorflow.python.client import timeline
运行计算图之前定义 metadata
和 options
:
run_metadata = tf.RunMetadata()
run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
运行计算图时, 加上 metadata
和 options
:
with tf.Session() as sess:
result = sess.run(fetch, feed, options=run_options, run_metadata=run_metadata)
运行后, 创建 Timeline
对象, 并将数据写入 json
文件:
fetched_timeline = timeline.Timeline(run_metadata.step_stats)
# Chrome Trace 格式
chrome_trace = fetched_timeline.generate_chrome_trace_format()
# 保存, step 是当前的步数.
with open('timeline_%d.json' % step, 'w') as f:
f.write(chrome_trace)
保存后, 在 Chrome
输入:
chrome://tracing/
最后点击 load
加载 timeline
文件.
TensorBoard¶
TensorBoard
是 TensorFlow
提供的可视化平台, 可以将训练模型时的各种数据以网页应用的方式直观的展示出来.
包括计算图, 运行时的标量, 变量, 嵌入层的映射等等.
使用方法¶
首先定义一个 FileWriter
, 用来将 summary
数据写入文件:
with tf.Session() as sess:
writer = tf.summary.FileWriter(save_path, sess.graph)
常用参数:
logdir: | 保存路径 |
---|---|
graph: | 一个图对象, 例如 sess.graph . |
max_queue: | 整数. 记录 summary 的队列大小. |
flush_secs: | 多少秒将队列中的数据写入硬盘. |
注意
FileWriter
需要定义在初始化 Session()
以后.
然后在每次运行计算图并获得 summary
的结果时, 将结果写入到文件:
# summ 是运行 summary op 得到的结果
writer.add_summary(summ, global_step=step)
在训练完成以后, save_path
目录下会出现 events
文件, 在命令行使用以下命令打开 TensorBoard
服务:
tensorboard --logdir=save_path --host=127.0.0.1
--logdir | summary 保存路径 |
--host | 主机IP地址 |
如果默认 host
地址即为 127.0.0.1
可以不添加 host
参数.
Summaries¶
TensorFlow
的 summary
是用来在 TensorBoard
中直观显示标量或者变量的.
重要
summary
也是计算图里的一个 operation
.
词嵌入映射¶
词嵌入映射可以将 TensorFlow
的嵌入层学习到的变量降维后以 2D 或着 3D 的形式在
TensorBoard
中展示出来.
提示
TensorBoard
中提供的降维方式有 PCA
与 t-SNE
.
首先从 tensorboard
插件中导入 projector
:
from tensorflow.contrib.tensorboard.plugins import projector
创建 projector_config
并增加 embedding
层, 通过名称指定 Tensor
变量:
proj_config = projector.ProjectorConfig()
embed = proj_config.embeddings.add()
embed.tensor_name = train_model.embedding.name
如果需要显示单词在嵌入空间点上, 则需要指定单词表:
embed.metadata_path = "vocab.tsv"
然后指定 writer
与 proj_config
, 即 summary
的 FileWriter
, 写入文件.
重要
proj_config
会以文件形式写入 FileWriter
的相同目录下, 所以单词表的路径应该是 FileWriter
的相对路径.
将以上信息配置好以后, 就可以在 tensorboard
的 PROJECTOR
标签内查看映射.
保存与恢复¶
变量¶
变量的保存与恢复使用 Saver
类.
首先实例化一个 Saver
类:
saver = tf.train.Saver(vars)
# vars 为要保存的变量, 默认保存所有全局变量
max_to_keep: | 最大保存个数, 默认为 5 |
---|
保存变量¶
保存通过 saver.save()
:
path = os.path.join(save_path, 'after-epoch')
saver.save(sess, path, global_step=i+1)
path: | 保存变量的文件名称 |
---|---|
global_step: | 文件名后缀 |
提示
可以使用当前的 epoch
作为文件的后缀, 如上.
保存后, 在保存目录下会出现四个文件, 其中:
data: | 变量数据 |
---|---|
index: | 变量索引 |
meta: | 模型数据 |
checkpoint: | 最新检查点 |
恢复变量¶
恢复变量通过:
saver.restore(sess, restore_path)
restore_path: | 保存点的文件 |
---|
如果 restore_path
是目录, 则需要首先使用 tf.train.latest_checkpoint(restore_path)
获取最新的检查点文件.
可以在开始训练前恢复上一次训练的变量, 继续训练.
# Reload weights if exits
if os.path.exists(restore_path):
print("Restoring parameters from {}".format(restore_path))
if os.path.isdir(restore_path):
restore_path = tf.train.latest_checkpoint(restore_path)
# Begin at epoch
bae = int(restore_path.split('-')[-1])
saver.restore(sess, restore_path)
bae: | Begin of epoch, 开始的 epoch |
---|
注意
使用这段代码时, 循环 epoch
应该使用 range(bae, bae+num_epoch)
.