Tensorflow学习笔记

前言

关于TensorFlow

TenrFlow 是一个开源的、基于 Python 的机器学习框架,它由 Google 开发,并在图形分类、音频处理、推荐系统和自然语言处理等场景下有着丰富的应用,是目前最热门的机器学习框架。

除了 Python,TensorFlow 也提供了 C/C++、Java、Go、R 等其它编程语言的接口。

个人配置:电脑上已经安装好了anaconda,python版本3.7.6

下载安装

国内直接下载TensorFlow速度慢,直接换清华源,清华园也挂了,再换豆瓣源,配置到pycharm,Spyder先不配置了。

TensorFlow学习笔记

Keras

可以用get_weights()set_weights()方法,获取神经层的所有参数。对于紧密层,参数包括连接权重和偏置项

fit()方法会返回History对象,包含:训练参数(history.params)、周期列表(history.epoch)、以及最重要的包含训练集和验证集的每个周期后的损失和指标的字典(history.history)。如果用这个字典创建一个 pandas 的DataFrame,然后使用方法plot(),就可以画出学习曲线

可以看到,训练准确率和验证准确率稳步提高,训练损失和验证损失持续下降。另外,验证曲线和训练曲线靠的很近,意味着没有什么过拟合。在这个例子中,在训练一开始时,模型在验证集上的表现由于训练集。但实际情况是,验证误差是在每个周期结束后算出来的,而训练误差在每个周期期间,用流动平均误差算出来的。所以训练曲线(译者注,图中橙色的那条)实际应该向左移动半个周期。移动之后,就可以发现在训练开始时,训练和验证曲线几乎是完美重合起来的。

本章末尾还会调节超参数。当对验证准确率达到满意之后,就可以用测试集评估泛化误差。只需使用evaluate()方法(evaluate()方法包含参数batch_sizesample_weight):

测试集的表现通常比验证集上低一点,这是因为超参数根据验证集而不是测试集调节的(但是在这个例子中,我们没有调节过超参数,所以准确率下降纯粹是运气比较差而已)。一定不要在测试集上调节超参数,否则会影响泛化误差。

使用顺序 API 是很方便的。但是,尽管Sequential十分常见,但用它搭建复杂拓扑形态或多输入多输出的神经网络还是不多。所以,Keras 还提供了函数式 API。

使用函数式 API 搭建复杂模型

每个输出都要有自己的损失函数。因此在编译模型时,需要传入损失列表(如果只传入一个损失,Keras 会认为所有输出是同一个损失函数)。Keras 默认计算所有损失,将其求和得到最终损失用于训练。主输出比辅助输出更值得关心,所以要提高它的权重

Model类划分子类,在构造器中创建需要的层,调用call()进行计算。

class WideAndDeepModel(keras.Model):
    def __init__(self, units=30, activation="relu", **kwargs):
        super().__init__(**kwargs) # handles standard args (e.g., name)
        self.hidden1 = keras.layers.Dense(units, activation=activation)
        self.hidden2 = keras.layers.Dense(units, activation=activation)
        self.main_output = keras.layers.Dense(1)
        self.aux_output = keras.layers.Dense(1)

    def call(self, inputs):
        input_A, input_B = inputs
        hidden1 = self.hidden1(input_B)
        hidden2 = self.hidden2(hidden1)
        concat = keras.layers.concatenate([input_A, hidden2])
        main_output = self.main_output(concat)
        aux_output = self.aux_output(hidden2)
        return main_output, aux_output

model = WideAndDeepModel() 

保存和恢复模型

Keras 使用 HDF5 格式保存模型架构(包括每层的超参数)和每层的所有参数值(连接权重和偏置项)。还保存了优化器(包括超参数和状态)。

通常用脚本训练和保存模型,一个或更多的脚本(或 web 服务)来加载模型和做预测。

model.save("my_keras_model.h5") 

model = keras.models.load_model("my_keras_model.h5") 

警告:这种加载模型的方法只对顺序 API 或函数式 API 有用,不适用于子类化 API。对于后者,可以用save_weights()load_weights()保存参数,其它的就得手动保存恢复了。

使用调回

fit()方法接受参数callbacks,可以让用户指明一个 Keras 列表,让 Keras 在训练开始和结束、每个周期开始和结束、甚至是每个批次的前后调用。

checkpoint_cb = keras.callbacks.ModelCheckpoint("my_keras_model.h5") history = model.fit(X_train, y_train, epochs=10, callbacks=[checkpoint_cb]) 
''''''
checkpoint_cb = keras.callbacks.ModelCheckpoint("my_keras_model.h5",
                                                save_best_only=True)
history = model.fit(X_train, y_train, epochs=10,
                    validation_data=(X_valid, y_valid),
                    callbacks=[checkpoint_cb])
model = keras.models.load_model("my_keras_model.h5") # roll back to best model 
""""""
early_stopping_cb = keras.callbacks.EarlyStopping(patience=10,
                                                  restore_best_weights=True)
history = model.fit(X_train, y_train, epochs=100,
                    validation_data=(X_valid, y_valid),
                    callbacks=[checkpoint_cb, early_stopping_cb]) 

另外,如果训练时使用了验证集,可以在创建检查点时设定save_best_only=True,只有当模型在验证集上取得最优值时才保存模型。这么做可以不必担心训练时间过长和训练集过拟合:只需加载训练好的模型,就能保证是在验证集上表现最好的模型。

另一种实现早停的方法是使用EarlyStopping调回。当检测到经过几个周期(周期数由参数patience确定),验证集表现没有提升时,就会中断训练,还能自动滚回到最优模型。可以将保存检查点(避免宕机)和早停(避免浪费时间和资源)结合起来


使用 TensorBoard 进行可视化

ensorBoard 是一个强大的交互可视化工具,使用它可以查看训练过程中的学习曲线、比较每次运行的学习曲线、可视化计算图、分析训练数据、查看模型生成的图片、可视化投射到 3D 的多维数据,等等。TensorBoard 是 TensorFlow 自带的。

要使用 TensorBoard,必须修改程序,将要可视化的数据输出为二进制的日志文件event files。每份二进制数据称为摘要summary,TensorBoard 服务器会监测日志文件目录,自动加载更新并可视化:这样就能看到实时数据(稍有延迟),比如训练时的学习曲线。通常,将 TensorBoard 服务器指向根日志目录,程序的日志写入到它的子目录,这样一个 TensorBoard 服务就能可视化并比较多次运行的数据,而不会将其搞混。

我们先定义 TensorBoard 的根日志目录,还有一些根据当前日期生成子目录的小函数。你可能还想在目录名中加上其它信息,比如超参数的值,方便知道查询的内容:

    def get_run_logdir():
        import time
        run_id = time.strftime("run_%Y_%m_%d-%H_%M_%S")
        return os.path.join(root_logdir, run_id)


    run_logdir = get_run_logdir()  # e.g., './my_logs/run_2019_06_07-15_15_22'

每次运行都会创建一个目录,每个目录都有一个包含训练日志和验证日志的子目录。两者都包括事件文件,训练日志还包括分析追踪信息:它可以让 TensorBoard 展示所有设备上的模型的各个部分的训练时长,有助于定位性能瓶颈。

然后就可以启动 TensorBoard 服务了。一种方式是通过运行命令行。如果是在虚拟环境中安装的 TensorFlow,需要激活虚拟环境。接着,在根目录(也可以是其它路径,但一定要指向日志目录)运行下面的命令:

$ tensorboard --logdir=./my_logs --port=6006

还可以对全图、权重(投射到 3D)或其它信息做可视化。TensorBoard()调回还有选项可以记录其它数据的日志,比如嵌入(见第 13 章)。另外,TensorBoard 在tf.summary包中还提供了低级 API。下面的代码使用方法create_file_writer()创建了SummaryWriter,TensorBoard 使用SummaryWriter作为记录标量、柱状图、图片、音频和文本的上下文,所有这些都是可以可视化的!

资料

带你少走弯路:强烈推荐的TensorFlow快速入门资料和翻译(可下载)

《机器学习实战:基于Scikit-Learn和TensorFlow》

  • 本书作者公开了配套的源代码:

https://github.com/ageron/handson-ml

  • 国内一个公益组织对原版英文书进行了翻译,制作成markdown文件(md文件推荐使用typora阅读),可以在github下载:

https://github.com/apachecn/hands-on-ml-zh

针对国内下载速度慢,本站对两个资源进行打包,可以在百度云下载:

链接:

https://pan.baidu.com/s/1jihUZrXblxhrVA5FBGU3RQ

提取码:0xye

若被和谐请留言。

——黄海广老师

附录

关于Python的其他常见操作

python路径拼接os.path.join()函数的用法

os.path.join()函数:连接两个或更多的路径名组件

  1. 如果各组件名首字母不包含’/’,则函数会自动加上

  2. 如果有一个组件是一个绝对路径,则在它之前的所有组件均会被舍弃

  3. 如果最后一个组件为空,则生成的路径以一个’/’分隔符结尾


参考资料

TensorFlow教程:TensorFlow快速入门教程(非常详细)

tensorflow安装全解(全解萌新向/CPU/下载快/自选新旧版本/GPU安装简述/报错解决)

win10中anaconda安装tensorflow时报错Traceback (most recent call last): File “E:\Anaconda3\lib\site-packag


   转载规则


《Tensorflow学习笔记》 Henry-Avery 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录