《TensorFlow2学习十二、使用预训练CNN进行迁移学习识别猫和狗.docx》由会员分享,可在线阅读,更多相关《TensorFlow2学习十二、使用预训练CNN进行迁移学习识别猫和狗.docx(9页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、TensorFlow2学习十二、使用预训练CNN进行迁移学习识别猫和狗一、讲明本文学习资源来自tensorflow官网测试环境使用tensorconlab。1.本文内容学习怎么使用预训练cnn进展猫、狗分类。预训练模型是一个使用大量数据训练好并保存好的网络模型典型的是大量图像数据的分类工作。我们可以使用本文中的预训练模型可以以针对一个任务使用迁移学习客制化模型。当一个模型是基于足够大的、足够有代表性的数据集训练出来的那么它可以有效的工作在机器视觉中。我们可以利用这些学习好的特征而不用再基于大量数据集重复进展训练。本文使用两种方式客制化预训练模型特征展开使用之前模型从新的数据集中提取有用的特征。
2、只需要在预训练模型顶部简单的添加分类器不需要重新训练整个模型。根底cnn已经包含了有用的分类特征。微调从一个冻结模型解除顶部的层连接新添加的分类层以及后面的根底模型。2.步骤理解数据导入包以及数据使用KerasImageDataGenerator处理数据构建模型加载预训练模型以及预置权重把新的分类层堆叠到顶部训练模型评估模型二、实现1.引入包from_future_importabsolute_import,division,print_function,unicode_literalsimportosimportnumpyasnpimportmatplotlib.pyplotasplt#%t
3、ensorflow_versiononlyexistsinColab.%tensorflow_version2.xexceptException:passimporttensorflowastfkerastf.keras2.数据处理使用tensorflow_datasets加载数据importtensorflow_datasetsastfdstfds.disable_progress_bar()#训练集验证集测试集比例8:1:1SPLIT_WEIGHTS(8,1,1)splitstfds.Split.TRAIN.subsplit(weightedSPLIT_WEIGHTS)(raw_train
4、,raw_validation,raw_test),metadatatfds.load(cats_vs_dogs,splitlist(splits),with_infoTrue,as_supervisedTrue)print(raw_train)print(raw_validation)print(raw_test)显示前2个图片看看get_label_namemetadata.featureslabel.int2strforimage,labelinraw_train.take(2):plt.figure()plt.imshow(image)plt.title(get_label_name(
5、label)格式化数据使用tf.image格式化数据。图片缩放到160*160输入通道值转换为-1,1IMG_SIZE160#Allimageswillberesizedto160x160defformat_example(image,label):imagetf.cast(image,tf.float32)image(image/127.5)-1imagetf.image.resize(image,(IMG_SIZE,IMG_SIZE)returnimage,label#数据集中每一项都使用该函数处理trainraw_train.map(format_example)validationra
6、w_validation.map(format_example)testraw_test.map(format_example)数据集分批BATCH_SIZE32SHUFFLE_BUFFER_SIZE1000train_batchestrain.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE)validation_batchesvalidation.batch(BATCH_SIZE)test_batchestest.batch(BATCH_SIZE)forimage_batch,label_batchintrain_batches.take(1):p
7、assimage_batch.shape3.从预训练cnn里创立根底模型下面加载google创立的MobileNet模型这个模型基于ImageNet由李飞飞团队创立的大型数据集。这个数据集有1400多万数据以及超过2万多个标注与超过百万的边界框标注。这个模型有助于从我们的数据集里分辨狗以及猫。如今要确定模型哪个层用于特征提取。大多数机器学习模型是从下往上的最后一个分类器顶部不是很有用。我们将遵循常规做法转而依赖展平操作之前的最后一层。这个层被称为“瓶颈层。与最终/顶层相比瓶颈层特性保存了许多通用性。首先实例化一个MobileNetV2模型该模型预先加载了在ImageNet上训练的权重。通过指定
8、include_topFalse参数可以加载一个不包括顶局部类层的网络这是特征提取的理想选择。IMG_SHAPE(IMG_SIZE,IMG_SIZE,3)#Createthebasemodelfromthepre-trainedmodelMobileNetV2base_modeltf.keras.applications.MobileNetV2(input_shapeIMG_SHAPE,include_topFalse,weightsimagenet)feature_batchbase_model(image_batch)print(feature_batch.shape)特征提取操作将每个1
9、60x160x3转换成5x5x1280特征块.#冻结层防止在训练期间更新给定层中的权重base_model.trainableFalsebase_model.summary()4.全局池化层GAPGAP被认为是可以替代全连接层的一种新技术。在keras发布的经典模型中可以看到不少模型甚至抛弃了全连接层转而使用GAP。在支持迁移学习方面各个模型几乎都支持使用GlobalAveragePooling以及GlobalMaxPooling(GMP)。这里使用tf.keras.layers.GlobalAveragePooling2D将每个图片以5x5空间位置转成单个1280元素向量。global_av
10、erage_layertf.keras.layers.GlobalAveragePooling2D()feature_batch_averageglobal_average_layer(feature_batch)print(feature_batch_average.shape)#tf.keras.layers.Dense层将每个特征输入预测器预测器训练使用logit所以这里不需要指定激活函数。#正向数值预测分类1负向数值预测分类0prediction_layerkeras.layers.Dense(1)prediction_batchprediction_layer(feature_bat
11、ch_average)print(prediction_batch.shape)5.创立模型modeltf.keras.Sequential(base_model,global_average_layer,prediction_layer6.编译模型base_learning_rate0.0001modelpile(optimizertf.keras.optimizers.RMSprop(lrbase_learning_rate),lossbinary_crossentropy,metricsaccuracy)model.summary()len(model.trainable_variabl
12、es)#22.5MMobileNet的变量冻结了但还有1.2k全连接层还有2.5M训练参数被分成权重以及偏置两个tf变量对象.7.训练模型num_train,num_val,num_test(metadata.splitstrain.num_examples*weight/10forweightinSPLIT_WEIGHTSinitial_epochs10steps_per_epochround(num_train)/BATCH_SIZEvalidation_steps20loss0,accuracy0model.evaluate(validation_batches,stepsvalidat
13、ion_steps)print(initialloss:.2f.format(loss0)print(initialaccuracy:.2f.format(accuracy0)8.拟合historymodel.fit(train_batches,epochsinitial_epochs,validation_datavalidation_batches)9.学习曲线可视化acchistory.historyaccuracyval_acchistory.historyval_accuracylosshistory.historylossval_losshistory.historyval_los
14、splt.figure(figsize(8,8)plt.subplot(2,1,1)plt.plot(acc,labelTrainingAccuracy)plt.plot(val_acc,labelValidationAccuracy)plt.legend(loclowerright)plt.ylabel(Accuracy)plt.ylim(min(plt.ylim(),1)plt.title(TrainingandValidationAccuracy)plt.subplot(2,1,2)plt.plot(loss,labelTrainingLoss)plt.plot(val_loss,lab
15、elValidationLoss)plt.legend(locupperright)plt.ylabel(CrossEntropy)plt.ylim(0,1.0)plt.title(TrainingandValidationLoss)plt.xlabel(epoch)plt.show()这里验证指标明显优于培训指标主要原因是像tf.keras.layers.BatchNormalization以及tf.keras.layers.Dropout这样的层会影响训练期间的准确性。它们在计算验证丧失时被关闭。在较小程度上这也是因为训练度量报告了一个epoch的平均值而验证度量在epoch之后进展评估因
16、此验证度量看到的模型训练的时间稍长。三、微调模型上面的特征提取操作只在MobileNetV2根底模型上训练了几层。训练经过中未更新训练网络的权值。进一步进步性能的一种方法是在训练添加的分类器的同时训练或者“微调预训练模型顶层的权重。训练经过将强迫将权重从通用特征映射调整到与我们的数据集特定关联的特征。注意只有在将预先训练的模型设置为不可训练的顶级分类器之后才能尝试此操作。假如在预先训练的模型上添加一个随机初始化的分类器并尝试结合训练所有层那么梯度更新的幅度将过大由于来自分类器的随机权重并且预先训练的模型将忘记它所学到的内容。此外应该尝试微调少数顶层而不是整个MobileNet模型。在大多数卷积
17、网络中一层越高它就越专业。前几层学习非常简单以及通用的特征这些特征可以概括为几乎所有类型的图像。当你往上走的时候这些特性对模型所训练的数据集越来越详细。微调的目的是使这些专门特性适应新数据集而不是覆盖泛型学习。base_model.trainableTrue#Letstakealooktoseehowmanylayersareinthebasemodelprint(Numberoflayersinthebasemodel:,len(base_model.layers)#Finetunefromthislayeronwardsfine_tune_at100#Freezeallthelayersb
18、eforethefine_tune_atlayerforlayerinbase_model.layers:fine_tune_at:layer.trainableFalsemodelpile(lossbinary_crossentropy,optimizertf.keras.optimizers.RMSprop(lrbase_learning_rate/10),metricsaccuracy)fine_tune_epochs10total_epochsinitial_epochsfine_tune_epochshistory_finemodel.fit(train_batches,epochs
19、total_epochs,initial_epochhistory.epoch-1,validation_datavalidation_batches)#微调后准确率可以到达98%左右acchistory_fine.historyaccuracyval_acchistory_fine.historyval_accuracylosshistory_fine.historylossval_losshistory_fine.historyval_lossplt.figure(figsize(8,8)plt.subplot(2,1,1)plt.plot(acc,labelTrainingAccurac
20、y)plt.plot(val_acc,labelValidationAccuracy)plt.ylim(0.8,1)plt.plot(initial_epochs-1,initial_epochs-1,plt.ylim(),labelStartFineTuning)plt.legend(loclowerright)plt.title(TrainingandValidationAccuracy)plt.subplot(2,1,2)plt.plot(loss,labelTrainingLoss)plt.plot(val_loss,labelValidationLoss)plt.ylim(0,1.0
21、)plt.plot(initial_epochs-1,initial_epochs-1,plt.ylim(),labelStartFineTuning)plt.legend(locupperright)plt.title(TrainingandValidationLoss)plt.xlabel(epoch)plt.show()总结使用预先训练的模型进展特征提取在处理小数据集时通常会利用在同一域中的较大数据集上训练的模型所学习的特征。这是通过实例化预先训练的模型并在上面添加一个完全连接的分类器来完成的。训练前的模型被冻结训练经过中只更新分类器的权值。在这种情况下卷积基提取了与每个图像相关联的所有特征只需训练一个分类器该分类器根据提取的特征集确定图像类别。微调预先训练的模型为了进一步进步性能可能需要通过微调将预先训练的模型的顶层重新调整到新的数据集。在本例中我们调整了权重以便模型学习特定于数据集的高级特性。当训练数据集很大且与训练前模型所用的原始数据集非常相似时通常建议使用此技术。