博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
训练并导出tensorflow Lite模型中的一些问题 及解决办法
阅读量:3917 次
发布时间:2019-05-23

本文共 14915 字,大约阅读时间需要 49 分钟。

环境配置

1.ubuntu18.04连接镜像autonist.iso

安装ubuntu或者centos时,vmware提示"快速安装,然后会使用一个autonist.iso文件来快速安装,并且装完系统重启了,它插入一个操作:安装vm-tools"。

断开autonist的连接出现的问题:终端中使用apt-get安装时总是出现各种错误,一味的百度也解决不了,只有连接autonist.iso

2.ubunto14.04安装python

安装python3.5,tensorflow目前支持python2.7,python3.5

#sudo apt-get updata

#sudo apt-get install python-dev python-pip

卸载默认python后的重新安装

#sudo apt-get uninstall python

#python --version
#cd /usr/bin
#ls
#cd /
#sudo install python3.5

将默认的python设置为python3.5

先删除默认的python软链接

#sudo rm /usr/bin/python

然后创建一个新的软连接指向需要的python版本

#sudo ln -s /usr/bin/python3.5 /usr/bin/python

3.升级python版本之后pip升级及pip升级之后不能用的办法

#sudo apt-get install python-pip -y

创建pip软连接:

#sudo ln -s /usr/local/bin /usr/bin/pip

#pip --version

4.安装tensorflow

如果tensorflow安装失败就是pip有问题,参考上面pip问题的解决

#sudo pip2 install tensorflow==1.9.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

5.给文件添加权限的办法

#chomd 777 文件

6.虚拟机里全屏的问题

百度这个问题总是需要装什么vm-tools,可是并没有什么用

在终端执行:

#xrandr

#xrandr -s 1920x1440

7.ubuntu18.04安装vmtools

若是没有什么特殊的问题,可以参考百度。but,总是会有特殊问题的,vm tools是灰色的怎么解决。

第一种:百度常见的解决办法

第二种:
1、打开默认存在的那个小虚拟光驱, 发现里面有一个upgra64(或32)的可执行文件. 将这个小光驱里的文件都复制到有执行权限的目录, 执行upgra64

#./upgra64

2、此时WMware会提示你是否断开当前光驱的连接, 选择是.

3、然后会发现原先的小光驱不见了, 取而代之的是一个Vmware-Tools的光驱
4.对vmtools解压缩

#sudo tar -zxvf VMwareTools-9.6.1-1378637.tar.gz

进入解压后的文件夹执行安装

#sudo ./vmware-install.pl

之后一路回车何输入Y就可以解决了(一般是没有必要安装百度上的某些说法再去建立路径的,除非某一步实在过不去),具体流程可灵活些,有些步骤我可能忘了。出现

Enjoy

–the VMware tam

说明安装成功。可以参考以下连接

到此为之,ubuntu中的环境就弄好了。

代码

1.数据集预处理

新建data_preprocessing.py文件,撰写代码实现自动对原始数据集进行大小裁剪以及分集(训练集、验证集、测试集)的处理,首先导入模块,然后,构造处理图像尺寸的函数image_split()。参数:

original_path——图片所在文件夹的原始路径
species——植物名字
stardand_path——保存路径
set——集名
inds——图片序列号:

from PIL import Imageimport os#如果不加以下两行可能会报错OSError.image file is truncated(8 bytes not processed)import PIL import ImageFileImageFile.LOAD_TRUNCATED_IMAGES=Trueimport randomdef image_split(original_path,species,stardand_path,set,inds):for img in inds:        # 以原始路径 植物名字 序列号为图片路径打开图片        plant_path  = os.path.join(original_path,species,img)        in_img = Image.open(plant_path)        in_img = in_img.convert('RGB')        out_img = in_img.resize((224,224))        #以原始路径 集名 植物名字为该文件集路径        set_path = os.path.join(stardand_path,set,species)        if not os.path.exists(set_path):            os.makedirs(set_path)        out_img.save(os.path.join(set_path,img))#构造主函数def main():    #读取图片    original_path = 'bjfu_plants'#图片原始路径    stardand_path = 'PlantsData'#图片分集后的路径    for species in os.listdir(original_path):#植物名list        files = sorted(os.listdir(os.path.join(original_path,species)))        img_num = len(files)        test_num = int(img_num/10*2)#测试数量        valid_num = int((img_num-test_num)/10*2)#验证数量        train_num = int(img_num-test_num-valid_num)#训练数量        print('%s:%d,train:%d,valid:%d,test:%d' %(species,img_num,train_num,valid_num,test_num))        random.shuffle(files)#打乱图片顺序        image_split(original_path,species,stardand_path ,"train",files[0:train_num])        print("%s finish!"%os.path.join(stardand_path,'train',species))#训练集        image_split(original_path,species,stardand_path,'valid',files[train_num:train_num+valid_num])        print("%s finish!"% os.path.join(stardand_path,'valid',species))#验证集        image_split(original_path, species, stardand_path, 'test', files[train_num + valid_num:])        print("%s finish!"%os.path.join(stardand_path,'test',species))#测试集if __name__=='__main__':    main()

运行程序结果:

在这里插入图片描述运行程序后,图片的存储样式为:
在这里插入图片描述
在这里插入图片描述

2.训练与验证

注意:使用的数据集只能由jpg格式的

本次实验使用retrain.py文件重训练一个MobileNet

MobileNet是一个轻量高效的卷积神经网络,它可以通过两种方式配置:

  1. 输入图像尺寸:128,160,192或224像素。输入像素越高,分类精确率越高;
  2. 模型相对大小:1.0,0.75,0.5或0.25;
  3. 本次试验中我们选用224,0.5的组合。
    新建retrain.py文件,导入模块及设置一些全局变量:
import osimport tensorflow as tffrom tensorflow.keras.applications.mobilenet import MobileNetfrom tensorflow.keras import Model,optimizersfrom tensorflow.keras import Densespecies_num =5#植物种类learning_rate = 0.001#学习率batch_size=32#每个batch的大小nb_epoch=50#迭代次数data_path='PlantsData'#数据集路径

构造加载数据集的load_data()函数,参数:

path——数据集路径
set——数据集名
filename——图片路径
label——标签

def load_data(path,set):    def _parse_function(filename,label):        image_string = tf.read_file(filename)        image_decoded = tf.cast(tf.image.decode_image(image_string),                               dtype=tf.float32) / tf.constant(255,dtype= tf.float32)        label = tf.one_hot(label,species_num)        return image_decoded,label    file_name = []    labels = []    for inds,species in enumerate(sorted(os.listdir(os.path.join(path,set)))):        for img in os.listdir(os.path.join(path,set,species)):            file_name.append(os.path.join(path,set,species,img))            labels.append(inds)    #创建一个数据集,其元素是切片张量    dataset = tf.data.Dataset.from_tensor_slices((tf.constant(file_name),tf.constant(labels)))    #map函数会更具提供的函数对指定序列做映射    dataset = dataset.map(_parse_function)    return dataset,len(file_name)#构造主函数def main():    train_dataset, train_num = load_data(data_path,'train')    train_dataset = train_dataset.shuffle(train_num).batch(batch_size).repeat()    valid_dataset,valid_num = load_data(data_path,'valid')    valid_dataset = valid_dataset.batch(1).repeat()    print('data prepared! train:%d,valid:%d'%(train_num,valid_num))    #input_shape是图像的输入尺寸,Include_top=false表示模型不保留顶层的全连接网络    init_model = tf.keras.applications.mobilenet.MobileNet(input_shape=(224,224,3),include_top = False,                                                           weights = 'imagenet',                                                           pooling = 'avg')    #添加模型输入输出    x = tf.keras.layers.Dense(512,activation='relu')(init_model.output)    output = tf.keras.layers.Dense(species_num,activation='softmax')(x)    model = tf.keras.Model(inputs = init_model.input, outputs = output)    #使训练参数不断更新,加快训练速度    for layer in init_model.layers:        layer.trainable = False    #优化算法    optimizer = tf.keras.optimizers.SGD(learning_rate,momentum=0.9,nesterov=True,decay= 0.0003)    #编译模型    model.compile(optimizer = optimizer,loss='categorical_crossentropy',                   metrics =['accuracy'])    #运行模型    model.fit(train_dataset,epochs = nb_epoch,              steps_per_epoch=int(train_num/batch_size +1 ),              shuffle=True,              validation_data=valid_dataset,              validation_steps=valid_num)    if not os.path.exists('./models/checkpoints'):        os.makedirs('./models/checkpoints')    model.save_weights('./models/checkpoints/model')    model.save_weights('./models/checkpoints/model_weights_keras.h5',save_format='h5')if __name__ == '__main__':    main()
报错情况:

URL fetch failure on https://github.com/fchollet/deep-learning-model/releases/download/v0.6/mobilenet_1_0_224_tf_no_top.h5:None --[SSL:CERTIFICATE_VERIFY_FAILED]certificate verify falled…

解决:
有可能是网不好,或者参考以下链接:
keras离线下载模型的存储位置
另一种数据集格式问题的报错情况如图所示:只要将图片只保留jpg格式的就能解决:
tensorflow.python.framework.errors_impl.InvalidArgumentError:Cannot batch tensors with different shapes in conponent 0,First elemen had shape [224,224,3] and element 12 had shape [224,224,4]…
在这里插入图片描述

运行出现以下界面,说明正在训练模型:

在这里插入图片描述
训练好的模型存储在’./models/checkpoints’下面,分别包括checkpoint文件、model.data-00000-of-00001文件、model.index文件,并在该文件夹下保存model_weights_keras.h5文件:

3.模型评估

新建eval.py文件,模块导入和全局变量的设置与“5. 训练与验证”的相同。

构造加载数据的load_data()函数,代码与“5. 训练与验证”的相同。
构造主函数main():

import osimport tensorflow as tffrom tensorflow.keras.applications.mobilenet import MobileNetfrom tensorflow.keras import Model,optimizersfrom tensorflow.keras import Densespecies_num =5#植物种类learning_rate = 0.001#学习率batch_size=32#每个batch的大小nb_epoch=50#迭代次数data_path='PlantsData'#数据集路径def load_data(path,set):    def _parse_function(filename,label):        image_string = tf.read_file(filename)        image_decoded = tf.cast(tf.image.decode_image(image_string),                               dtype=tf.float32) / tf.constant(255,dtype= tf.float32)        label = tf.one_hot(label,species_num)        return image_decoded,label    file_name = []    labels = []    for inds,species in enumerate(sorted(os.listdir(os.path.join(path,set)))):        for img in os.listdir(os.path.join(path,set,species)):            file_name.append(os.path.join(path,set,species,img))            labels.append(inds)    #创建一个数据集,其元素是切片张量    dataset = tf.data.Dataset.from_tensor_slices((tf.constant(file_name),tf.constant(labels)))    #map函数会更具提供的函数对指定序列做映射    dataset = dataset.map(_parse_function)    return dataset,len(file_name)def main():    init_model = tf.keras.applications.mobilenet.MobileNet(input_shape=(224,224,3),include_top=False,                                                           weights = 'imagenet',                                                           pooling = 'avg')    x = tf.keras.layers.Dense(512,activation='relu')(init_model.output)    output = tf.keras.layers.Dense(species_num, activation='softmax')(x)    model = tf.keras.Model(inputs=init_model.input, outputs=output)    optimizer = tf.keras.optimizers.SGD(learning_rate, momentum=0.9, nesterov=True, decay=0.0003)    model.compile(optimizer=optimizer, loss='categorical_crossentropy',                   metrics=['accuracy'])    model.load_weights('./models/checkpoints/model')#读取模型权重    test_dataset, test_num = load_data(data_path, 'test')#读取测试集数据    test_dataset = test_dataset.batch(1)    print('data prepasred! test: %d'%(test_num))    result = model.evaluate(test_dataset,steps=test_num,verbose= 0)#测试模型    print('test_loss: %0.4f, test_acc: %0.4f' % (result[0],result[1]))if __name__=='__main__':    main()

测试集上的结果如下:

在这里插入图片描述

4.分类测试

同时从测试集中随机挑选一张进行分类测试,设置好图片路径

使用data_preprocessing.py中的一部分进行图像尺寸变化,
新建inference.py文件进行分类测试:

import osimport tensorflow as tffrom tensorflow.keras.applications.mobilenet import MobileNetfrom tensorflow.keras import Model,optimizersfrom tensorflow.keras import Densespecies_num =5#植物种类learning_rate = 0.001#学习率batch_size=32#每个batch的大小nb_epoch=50#迭代次数data_path='PlantsData'#数据集路径def load_data(path,set):    def _parse_function(filename,label):        image_string = tf.read_file(filename)        image_decoded = tf.cast(tf.image.decode_image(image_string),                               dtype=tf.float32) / tf.constant(255,dtype= tf.float32)        label = tf.one_hot(label,species_num)        return image_decoded,label    file_name = []    labels = []    for inds,species in enumerate(sorted(os.listdir(os.path.join(path,set)))):        for img in os.listdir(os.path.join(path,set,species)):            file_name.append(os.path.join(path,set,species,img))            labels.append(inds)    #创建一个数据集,其元素是切片张量    dataset = tf.data.Dataset.from_tensor_slices((tf.constant(file_name),tf.constant(labels)))    #map函数会更具提供的函数对指定序列做映射    dataset = dataset.map(_parse_function)    return dataset,len(file_name)def main(path):    train_path = 'bjfu_plants'    species=[]    for spe in sorted(os.listdir(train_path)):        species.append(spe)    init_model = tf.keras.applications.mobilenet.MobileNet(input_shape = (224,224,3),                                                            include_top = False,                                                            pooling = 'avg')    x = tf.keras.layers.Dense(128, activation='relu')(init_model.output)    output = tf.keras.layers.Dense(species_num, activation='softmax')(x)    model = tf.keras.Model(inputs=init_model.input, outputs=output)    model.load_weights('./models/checkpoints/model')    image = tf.cast(tf.image.decode_image(tf.read_file(path)),                    dtype = tf.float32)/tf.constant(255,dtype=tf.float32)    image_decoded = tf.expand_dims(image,axis=0)    start = time.time()    #对单张图片进行预测并输出结果    result = model.predict(image_decoded,steps = 1)[0]    print("evaluation time for 1 image:  %0.2f s"  % (time.time()-start))    for specie, conf in zip(species,result):        print('\t%s:%0.4f'%(specie,conf))if __name__ == '__main__':    img_path = 'PlantsData/test/狼尾草/P1000318_1.jpg'#单张图片的路径    main(img_path)

测试结果:(分别测试了三张玫瑰的图片)

在这里插入图片描述

5. 使用TOCO进行模型转换

 TOCO(TensorFlow Lite Optimizing Converter)可以将训练好的各种神经网络模型转化为TensorFlow Lite模型(FlatBuffer格式)。

 TOCO现在已经支持SavedModel,frozen graph和tf.Keras模型文件,生成的TensorFlow Lite FlatBuffer文件可以发送到客户端设备(一般是移动设备),客户端上的TensorFlow Lite解释器就可以对其进行设备级(on-device)的处理,流程图如下所示。
在这里插入图片描述

1. 在进行转换前,需要将.h5文件转换为pb文件,新建一个model_to_pb.py文件。
import tensorflow as tfspecies_num = 5tf.keras.backend.set_learning_phase(0)init_model = tf.keras.applications.mobilenet.MobileNet(    input_shape=(224,224,3),    include_top = False,    pooling = 'avg')x = tf.keras.layers.Dense(512,activation='relu')(init_model.output)output = tf.keras.layers.Dense(species_num,activation = 'softmax')(x)model  = tf.keras.Model(inputs = init_model.input, outputs = output)model.load_weights('./models/checkpoints/model')from tensorflow.python.framework import  graph_utilfrom tensorflow.python.framework import graph_iosess = tf.keras.backend.get_session()constant_graph = graph_util.convert_variables_to_constants(    sess,    sess.graph.as_graph_def(),    [model.outputs[0].name.split(':')[0]])graph_io.write_graph(constant_graph,'/models/checkpoints/','model.pb',as_text=False)print(constant_graph)

转换为pb文件后保存到./models/checkpoints/文件中,并在该文件中打开终端,在终端输入以下命令:

#toco --graph_def_file model.pb --output_file optimized_graph.lite --input_arrays input_1 --output_arrays dense_1/Softmax --input_shapes 1,224,224,3

生成的optimized_graph.lite存储于该文件夹下,用于下次实验移动端上的模型使用。

2. 生成标签文件retrained_labels.txt,需要新建一个create_labels.py.运行此脚本,将在./models文件下,生成retrained_labels.txt
import osdef create_label(path,set):    files=os.listdir(os.path.join(path,set))    #排序后的文件夹名列表    orderedfiles=sorted(files)    with open('./models/retrained_label.txt','w') as f:    for i,file in enumerate(orderedfiles):        f.writelines(file)        #最后一项不加        if i!=len(orderedfiles)-1:        f.writelines('\n')if __name__=='__main__'    create_label('./PlantsData','train')

对代码基本的理解

batch_size:一次训练所选取的样本数,批量大小,批量大小将决定一次训练的样本数,影响模型的优化程度和速度。batchsize的正确选择是为了在内存效率和内存容量之间寻找最佳平衡。

epoch:一个epoch指代所有的数据送入网络中完成一次前向计算及反向传播的过程。由于一个epoch常常太大,计算机无法负荷,我们会将它分成几个较小的batches。

Interations:完成一次epoch所需要的batch个数

input_shape=(224,224,3)mobilenet模型初始化的时候,keras给出的模型输入图像尺寸是(224,224),也就是图片格式jpg

参数分析:

include_top=False:表示模型不保留顶层的全连接网络,表示这个网络只能进行特征提取. 不能在进行新的训练或者在已有权重上fine-tune(微调).
softmax:概率转换函数(soft max). 其实soft max的作用就是将输出转换为各类别的概率,并计算loss.
weights=‘imagenet’:表示加载imagenet与训练的网络权重,如果 weight = ‘imagenet’, 则输入尺寸必须严格等于(224,224), 权重的规模和结构有出入唯一决定, 使用了imagenet的权重,就必须使用训练时所对应的输入, 否则第一个全连接层的输入对接不上.
pooling:当include_top = False(网络被用于特征提取时该参数有效) 。pooling = ‘avg’, 表示对最后一个卷基层的输出一个4D的向量在M维度进行平均, 最终得到的是一个(1,1,w’,h’)的特征输出.

损失函数loss:训练的损失值

acc:模型训练的精度

val_acc:模型在验证集上的精度
通常来说,确定模型的好坏是需要利用acc和val_acc返回情况确定好模型之后,在另一个独立的test集上测试test_acc来最后算精度。若是只判断收敛的话只用看loss,但是通常情况下需要观测是否过拟合,若是出现loss和acc都有进度,但是val_acc没有进展,这个时候基本就是过拟合了。

x = tf.keras.layers.Dense(512,activation=‘relu’)(init_model.output)

output = tf.keras.layers.Dense(species_num,activation=‘softmax’)(x)
model = tf.keras.Model(inputs = init_model.input, outputs = output)
将layers分组为具有训练和推理特征的对象,实例化的方式:使用“API”,从开始,链接层调用以指定模型的正向传递,最后从输入和输出创建模型:
更详细的理解参考论文。

转载地址:http://bpcrn.baihongyu.com/

你可能感兴趣的文章
初识ABP vNext(11):聚合根、仓储、领域服务、应用服务、Blob储存
查看>>
chrome禁止三方cookie,网站登录不了怎么办
查看>>
Git 图形化操作之合并提交记录
查看>>
Istio Pilot 源码分析(二)
查看>>
BeetleX框架详解-小结
查看>>
打造钉钉事件分发平台之钉钉审批等事件处理
查看>>
2020 中国开源年会(COSCon'20)再启程:开源向善(Open Source for Good)
查看>>
拥抱.NET 5,从自研微服务框架开始
查看>>
开源特训营 - Lesson 4 - 如何运营社区
查看>>
C# 中的 is 真的是越来越强大,越来越语义化
查看>>
简单理解CAP-BASE
查看>>
gRPC-微服务间通信实践
查看>>
Firefox 18周岁
查看>>
IdentityServer4系列 | 初识基础知识点
查看>>
自由软件基金会庆祝成立35周年
查看>>
网络知识 | 《图解TCP/IP》读书笔记(下)
查看>>
国产化之路-统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作
查看>>
面试 .NET 开发,为什么也要考算法?
查看>>
BeetleX之TCP消息通讯Protobuf/TLS
查看>>
AA.Dapper升级了
查看>>