Transfer Learning对于没有大量计算资源,并且需要快速构造现有模型的人而言是极大的福音。我们可以将已经学到的模型参数(也可理解为模型学到的知识)通过某种方式来分享给新模型(对于结构或许有微调)从而加快并优化模型的学习效率不用像大多数网络那样从零开始学习。
而Fine-tuning则属于Transfer Learning下的一个小小的分支。和字面意思一样,就是微调,但是什么才算微调呢?调整输入的结构?调整输出的结构?这并没有确切的概念,但主流观点还是认为调整并重新训练末尾几层的参数属于Fine-tuning。当然,绝大多数时候输入层也是需要微调的。
实现Fine-tuning的方式有很多,以TensorFlow作为基础而言,大致可以分为三种(从难到易):
- 利用TensorFlow(目前稳定版本在2.2)重建官方给定的.pb文件或者.ckpt文件重建结构和参数。再对结构进行调整,再使用新的数据集进行训练。
- 利用TensorFlow-hub库进行Fine-tuning。目前的Tf-hub非常的人性化,是基于Keras进行封装的,这使得代码的可读性大大增加,并且非常易于获得模型文件,只需要利用一行代码下载你所需要的模型即可,无需手动下载。
import tensorflow-hub as hub
MODULE_HANDLE ="https://hub.tensorflow.google.cn/google/imagenet/mobilenet_v2_100_224/classification/4"
model=hub.load(MODULE_HANDLE)
MODULE_HANDLE就是模型的在线地址,可以去这个网址查看有哪些模型,如果被墙了,换成这个查看。里面包含了很多主流的模型,各取所需,适用得到任务也很多。
- 最简单的就是直接基于Keras对模型进行Fine-tuning,Keras的高度封装与易读性使得它对Fine-tuning的友好程度高于前面两个。但是缺点就是没办法对一些比较细致的地方进行调整
先从最简单的说起,去年使用keras进行Fine-tuning时,出现了诡异的问题:网络根本学习不到内容。在StackOverflow找了一圈发现是keras内部机制的问题(trainable机制出了问题)。好在更新的版本解决了这个bug。
#首先肯定是准备数据,可以自行下载或者使用
#自行下载的数据集的按照文件夹分类并且每个文件夹的名字最好就是类名,这可以省去之后的转换步骤;同时记得制作labels
tensorflow_dataset自带数据
import tensorflow_datasets as tfds
tfds.disable_progress_bar()
train_ds, validation_ds, test_ds = tfds.load(
"cats_vs_dogs", #可选其他,具体见使用文档
split=["train[:40%]", "train[40%:50%]", "train[50%:60%]"],
as_supervised=True, # 设置为True可以带上标签,免得自己去打标
)
#变更数据的大小
size = (150, 150) #取决于用得到什么网络,如果用的224的输入,那么输入端的size必须变为224*224
train_ds = train_ds.map(lambda x, y: (tf.image.resize(x, size), y))
validation_ds = validation_ds.map(lambda x, y: (tf.image.resize(x, size), y))
test_ds = test_ds.map(lambda x, y: (tf.image.resize(x, size), y))
未完待续......