使用TensorFlow Hub迁移学习
TensorFlow Hub是一种共享预训练模型组件的方法。参见TensorFlow Module Hub,获得预训练模型的可搜索列表。本教程演示了:
- 如何使用TensorFlow Hub Keras。
- 如何使用TensorFlow Hub进行图像分类。
- 如何做简单的迁移学习。
一个ImageNet分类器
下载分类器
使用layer_hub
加载一个移动网络,并将其包装为keras层。任何TensorFlow 2兼容的图像分类器URLtfhub.dev将在这里工作。
classifier_url =“https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/2”image_shape < -c(224 l、224 l, 3 l)分类器< -layer_hub(处理=classifier_url,input_shape =image_shape)
在一张图像上运行
下载一张图片来尝试模型。
image_url < -“https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg”img < -针::销(image_urlname =“grace_hopper”)% > %tensorflow::特遣部队$io$read_file()% > %tensorflow::特遣部队$图像$decode_image(dtype =特遣部队$float32)% > %tensorflow::特遣部队$图像$调整(大小=image_shape [-3.])
添加一个批处理维度,并将图像传递给模型。
结果是1001个logits元素向量,对图像的每个类的概率进行评级。
所以可以在argmax中找到最高类ID:
# # 653年[1]
学习简单的转移
使用TF Hub可以很容易地重新训练模型的顶层来识别数据集中的类。
花< -针::销(“https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz”,“flower_photos”)
将这些数据加载到模型中的最简单方法是使用image_data_generator
.
TensorFlow Hub的所有图像模块都期望在[0,1]范围内的浮点输入。使用image_data_generator
参数来实现此功能。
图像大小将在后面处理。
image_generator < -image_data_generator(重新调节=1/255)image_data < -花(1]% > %目录名()% > %目录名()% > %flow_images_from_directory(image_generatortarget_size =image_shape [-3.])
##找到了属于5类的3670张图片。
结果对象是一个返回image_batch、label_batch对的迭代器。我们可以用iter_next
从网状
:
## $: num[1:32, 1:224, 1:224, 1:3] 0.145 0.431 0.431 0.863 1…## $: num[1:32, 1:5] 1 0 0 0 0 0 0 0 0 0 0…
在一批图像上运行分类器
现在在图像批处理上运行分类器。
image_batch < -网状::iter_next(image_data)预测< -分类器(特遣部队$常数(image_batch [[1]],特遣部队$float32))predicted_classnames < -imagenet_labels [as.integer(特遣部队$argmax(预测,轴=1 l)+1 l)]
票面价值(mfcol =c(4,8),3月=代表(1,4),oma =代表(0.2,4))image_batch [[1]]% > %purrr::array_tree(1)% > %purrr::set_names(predicted_classnames)% > %purrr::地图(as.raster)% > %purrr::我走(~{情节(方式);标题(.y)})
看到LICENSE.txt
图像属性文件。
结果远非完美,但考虑到这些不是训练模型的类(除了“雏菊”),这是合理的。
下载无头模型
TensorFlow Hub还分发没有顶层分类层的模型。这些可以用来轻松地进行迁移学习。
任何Tensorflow 2兼容图像特征向量来自tfhub.dev的URL将在这里工作。
创建特征提取器。
feature_extractor_layer < -layer_hub(处理=feature_extractor_url,input_shape =image_shape)
它为每张图像返回一个1280长度的向量:
# #特遣部队。张量(##[[0.13427277 0.16856195 0.283491…0.00557477 0。0.8134863[0.00754159 0.49517953 0.18708485…]0.01621983 0。0.) # #(0。0.60116017 0。…0.0.05334444 0.00277256] ##… ## [0.6140208 1.3715637 0. ... 0.02907389 0.11318099 0.12228318] ## [1.2423071 1.0235544 0.170658 ... 0.51680547 0. 0. ] ## [0.5452022 0.2789958 0.16163555 ... 0.1076004 0.01267634 0. ]], shape=(32, 1280), dtype=float32)
冻结特征提取器层中的变量,以便训练只修改新的分类器层。
freeze_weights(feature_extractor_layer)
附加分类标头
现在,让我们使用特征提取层创建一个顺序模型,并添加一个新的分类层。
模型< -keras_model_sequential(列表(feature_extractor_layer,layer_dense(单位=image_data$num_classes,激活=“softmax”)))总结(模型)
# #模型:“顺序 " ## ___________________________________________________________________________ ## 输出层(类型)的形状参数 # ## =========================================================================== ## keras_layer_1 (KerasLayer)(没有,1280)2257984 ## ___________________________________________________________________________ ## 密度(密度)6405(没有,5) ## =========================================================================== ## 总参数:2264389 # #可训练的参数:6405 # # Non-trainable params: 2257984 ## ___________________________________________________________________________
火车模型
使用compile来配置训练过程:
现在使用的适合
方法训练模型。
为了使这个例子保持短小,只需2个epoch。
< -历史模型% > %fit_generator(image_data,时代=2,steps_per_epoch =image_data$n/image_data$batch_size,verbose =2)
##纪元1/2 ## 114/114 - 255s -损耗:0.6656 -精度:0.7567 ##纪元2/2 ## 114/114 - 250s -损耗:0.3308 -精度:0.8931
现在,在经过了一些训练迭代之后,我们已经可以看到模型在任务上取得了进展。
然后我们可以验证这些预测:
image_batch < -网状::iter_next(image_data)预测< -predict_classes(模型、image_batch [[1]])票面价值(mfcol =c(4,8),3月=代表(1,4),oma =代表(0.2,4))image_batch [[1]]% > %purrr::array_tree(1)% > %purrr::set_names(的名字(image_data$class_indices)[预测+1])% > %purrr::地图(as.raster)% > %purrr::我走(~{情节(方式);标题(.y)})
导出模型
现在你已经训练了模型,将它导出为一个已保存的模型:
save_model_tf(模型中,“mymodel /”,include_optimizer =假)
现在确认我们可以重新加载它,它仍然会给出相同的结果:
model_等< -load_model_tf(“mymodel /”)
x < -特遣部队$常数(image_batch [[1]],特遣部队$float32)all.equal(as.matrix(模型(x)),as.matrix(model_等(x)))
# # [1]