最近两年深度学习真的是火的不要不要的,关于深度学习,每个人都有自己的看法。有人说就是炼丹,得个准确率召回率什么的,拿到实际中,问问为什么,都答不上来。各种连代码都没写过的人,也纷纷表示这东西就是小孩堆积木,然后整个大功耗的服务器跑上几天,调调参数。然后每个实验室招生,都说自己是做什么深度学习,机器 学习,大数据分析的,以此来吸引学生。可是可是,他们实验室很可能连一块 GPU 都没有。
小时候,我把两个5号电池连在一块,然后用导线把正负极连起来,在正极的地方接个小灯泡,然后灯泡就亮了,这时候我就会高兴的不行。家里的电风扇坏了,把风扇拆开后发现里边的线断了,接起来后又可以工作了,妈妈觉得我很了不起。其实我就是找到线断了接起来而已。有时候,动手实现是一件很有趣的,也很有成就感的事。深度学习,我想就是这样。我鄙视那些连代码都没写过,一点细节都不懂的人在那里瞎吹。在传统的学科中,比如数学,物理这些基础学科或者建筑,土木这样的基础应用中,也许一个硕士生,博士生苦苦研究很久都比不上他们的导师。但是在深度学习中,很多情况下,学生要比导师会得更多,特别是整天就想着拉项目赚钱,论文都没看过,每天就看那么几 kb 推送的一些老师。
对于像我这样的渣渣来说,深度学习的乐趣不在于推导那么几个公式,而在于你在做情感分析的时候,RMSE小了,准确率高了;你在做机器翻译的时候,英文句子准确地变成了地地道道的中文;在你做行人检测的时候,那个方框准确无误的跟着人移动。。。所以 talk is cheap, show me your code.
Tensorflow-Tutorial
项目代码: https://github.com/yongyehuang/Tensorflow-Tutorial
我是从2月份才开始学习 Tensorflow 的,因为去年年底老师才终于肯买一台服务器。总体来说,TensorFlow更新的速度还是比较快的,但是用的是 1.0 版本,7个月过去,出了1.1, 1.2, 现在是 1.3 。 而且每个版本都有不少更新。比较坑的一点是官方文档很不齐全,有些东西虽然能够实现得比较好,但是文档里边一个字都不提,只能自己哭瞎然后继续寻找。下面是我学习过程中做的一些笔记。前面部分主要参考官方教程,后面则是自己在项目中的一些总结。因为时间跨度较大,代码中存在不少版本兼容的问题,可能会出错,但是思路还是没问题的~
TensorFlow入门(一)基本用法
介绍 TensorFlow 变量定义,加减操作等基本知识。理解tensorflow的工作机制:首先创建一个个节点,这些节点构成以图的结构相互作用;建立好的“图”就像一个空壳,你需要启动会话(Session)才能运行这些节点,这就像往这个空壳里边注入血液,让它们循环活动起来。可直接参考官方教程。TensorFlow入门(二)简单前馈网络实现 mnist 分类
从第一次接触深度学习开始,你就应该知道感知器这个东西,说白了就是个线性加权,也就是求特征向量和权重向量的点积。从编程的角度来说就是两个向量对应位相乘,最后求和。全连接网络就是有一个个这样的感知器拼成的。
在这个例子中讲的是简单的全连接网络实现手写字符分类,这个例子虽然简单,但是实际上各种分类任务也就这样。一般来说,都是包括三个部分:1.搭建网络, 2. 计算损失和梯度, 3. 设置优化器选择合适的学习率更新权值。 可直接参考官方教程。TensorFlow入门(三)多层 CNNs 实现 mnist分类
在前面简单全连接网络的基础上,本例子主要介绍怎么用TensorFlow来写一个卷积层。然后计算损失,梯度,优化器和前面简单全连接网络没有什么区别。可直接参考官方教程。此外,我添加了查看网络中间层权值的代码。TensorFlow入门(四) name / variable_scope 的使用
一般来说,神经网络的参数都是非常多的,这么繁多的结构,参数,代码写起来乱得跟麻团一样。 tf.name_scope 和 tf.variable_scope 这两个东西主要作用就是用于命名管理,把乱糟糟的代码管理的井然有序。对于 tf.variable_scope 更有一个作用就是实现权重共享的功能。TensorFlow入门(五)多层 LSTM 通俗易懂版
在第一次听说 LSTM 这个名字的时候就是一种高大上的感觉,后来确实也是非常好用,谁用谁知道。不会LSTM都不好意思说自己做文本的,做序列分析的。和前面的 CNN 比较起来,感觉 LSTM 确实是要复杂一些,当时也是整了好久才弄明白其中的各个细节。不得不说,Understanding LSTM Networks这篇文章讲得真是棒得不行。关于 TensorFlow 实现 LSTM,在每次版本更新的时候都做了一些调整,所以老是出错,不想 CNN 那样一直都没变。不过好在现在TensorFlow讨论的人越来越多了,所以很多问题谷歌一下或者到 stack overflow 上面都能找到。TensorFlow入门(六)双端 LSTM 实现序列标注(分词)
这个例子是根据别人写的一个分词例子改过来的,原版使用 keras 写的,然后我改成了 TensorFlow 版本。最大的变化就是,WTF,keras中一小段代码,我竟然写了这么多。但是自己实现几个例子,确实能够很好地帮助自己理解网络原理和代码细节。TensorFlow入门(七)充分理解 name / variable_scope
之前已经说过了 name/variable_scope,但是对于一个初学者来说,要想好好地理解这两个东西还真是不太容易,也许是我自己太菜了,但我确实是没有好好地掌握它们的精髓。然后代码写多了,才渐渐地理解。我一般的习惯是对于变量部分,我都喜欢使用 tf.variable_scope 包起来,结合 tf.get_variable() 使用,一方面是方便实现变量共享,另外一方面是有时候需要单独初始化,或者使用不同的优化器,或者是模型融合,利用 variable_scope 帮助很大。而对于 tf.name_scope, 用来管理命名就好。TensorFlow入门(八)tensorboard 的一个简单示例
tensorboard 真的很好用,特别是在做比较复杂任务的时候,一方面你可以通过里边的graph检查自己的网络结构写对了没有;另外一方面,通过观察 loss 和 accuracy 的变化情况,辅助自己进行参数调优。TensorFlow入门(九)使用 tf.train.Saver()保存模型
这个例子介绍了怎么保存模型和重新导入模型,像这样的例子到处都有,但是有一点需要明白,就是:你要导入某个变量的值,这个变量名称,就是 tf.get_variable(‘nvar_ame’) 或者是 tf.Variable(name=’var_name’) 定义变量时的这个 scope name 和 name 一定要完全一致,否则会报错。TensorFlow入门(十)【迁移学习】往一个已经保存好的模型添加新的变量并进行微调
在迁移学习中,通常我们已经训练好一个模型,现在需要修改模型的部分结构,用于我们的新任务。比如:
在一个图片分类任务中,我们使用别人训练好的网络来提取特征,但是我们的分类数目和原模型不同,这样我们只能取到 fc 层,后面的分类层需要重新写。这样我们就需要添加新的变量。那么这些新加入的变量必须得初始化才能使用。可是我们又不能使用 ‘tf.global_variables_initializer()’ 来初始化,否则原本训练好的模型就没用了。Tensorflow入门(十一) 【模型联合】如何利用tf.train.saver()把多个预训练好的模型联合起来fine-tune
实际上把多个模型联合起来训练这种方式用得并不多,就个人经验来说,多个模型融合训练并没有单模型训好以后再做融合效果好。但是但是,联合的模型再加到模型融合中,还是会有提升的哈。那么在进行模型联合训练的时候,有些细节就需要注意了。Tensorflow入门(十二)使用 tfrecord 读取数据
在 tf1.3 中,推出了 Dataset API,好像还挺好用的。但是因为TensorFlow一直没更新,所以还没尝试。如果数据量比较大的话,我们就需要考虑一下数据读取的问题了,而不是简单粗暴的每次都把整个数据集导入到内存中。从我的个人经验来说,对于训练数据,我会生成 tfrecord 文件保存,对于验证集和测试集,我会使用 npz 文件进行保存。
对于训练数据,使用 tfrecord 保存的好处就是我们可以调整batch的大小,而且提供了非常便捷的shuffle功能。对于验证集和测试集,一是不需要shuffle,而是我们完全可以根据网络大小固定batchsize。
在这个例子中,讲了两种数据生成 tfrecord 的方式:数据维度相同和数据维度不同两种数据。前者比如固定大小的特征矩阵,数组,图片等,比较简单,可以使用 tf.train.Example() 进行打包;后者比如文本数据,每个序列的长度都是不固定的。可以使用 tf.train.SequenceExample() 进行打包。这里没有说到直接把图片存成tfrecord格式的方法。因为网络这个教程最多,而且我自己也不做图像,所以就不讲了。
后来我还是做了图片的项目,不试不知道,图片打包 tfrecord 也不是随随便便在网上找个例子就可以了。如果方法不正确的话,生成的 tfrecord 可能要大几百倍,打包速度要慢上千倍,所以一定要选择合适的方式。Tensorflow入门(十三)最基础的 seq2seq 机器翻译模型
这个例子也是根据网友的例子改动了一下,原例子在 https://github.com/NELSONZHAO/zhihu/tree/master/basic_seq2seq 。
对于 seq2seq,很早之前就觉得非常有趣,然后也看了一些论文,了解一些细节,但是一直没有代码实现,所以一些概念还是比较含糊。所以自己实现过一遍以后,很多细节的东西才了解了。另外,seq2seq 确实很有趣,但是模型实在是太大,特别是你想实现一个可用的翻译模型之类的,显卡一定要充足。所以真正搞这个的,感觉都是有钱人。我的这个例子还有些数据处理的代码没有放上去,所以跑不通,感兴趣的可以看上面连接中网友的例子。等后期我整个项目完成了,再把整个代码开源。
其他资源
- aymericdamien/TensorFlow-Examples 这个项目对于 TensorFlow 入门者来说真是非常非常好。
- models/tutorials/ 这是官方提供的例子,包括 mnist, cifar10, ptb(讲 LSTM), translate(讲 seq2seq) 等。
- models/research/slim/ 这是官方slim 的例子,里边提供了 ImageNet 的各个经典模型,而且提供训练好的 ckpt 文件,如果需要 fine-tune 的话可以直接用这个。
- brightmart/text_classification 这里提供了很多文本分类的模型。
- tensorflow/nmt 这里提供了比较全的 机器翻译的模型。
暂时先写这么多,有补充的欢迎联系我。