Tensorflow-iris-模型的保存与恢复-案例教程

作者:jcmp      发布时间:2021-05-14      浏览量:0
首先请阅读和完成 Te

首先请阅读和完成
Tensorflow-iris-案例教程-零基础-机器学习
在上篇文章中我们每次运行iris.py都会重新训练和测试模型,这很不科学。能不能把训练好的模型保存起来,下次直接使用呢?

--

checkpoints和SavedModel

Tensorflow可以将训练好的模型以两种形式保存:

修改iris.py文件中创建评估器/分类器的代码,添加model_dir保存模型的目录:

#选定估算器:深层神经网络分类器models_path=os.path.join(dir_path,'models/')classifier = tf.estimator.DNNClassifier(   feature_columns=feature_columns,   hidden_units=[10, 10],   n_classes=3,   model_dir=models_path)

保存需要往硬盘写入文件,所以需要操作系统的管理员权限才能运行,在windows下需要右键名利提示符工具选择【以管理员权限运行】:

python desktop/iris/iris.py

在MacOS下需要加sodu运行,回车后输入系统登陆密码:

 sudo python3 ~/desktop/iris/iris.py

运行起来后稍等一下模型训练train完成,就可以在桌面iris文件夹下看到一个models文件夹,打开它看起来类似下图的一些文件:


注意到model.ckpt-1和-1000表示在我们训练的第1步step和第1000步都进行了保存,还记得classifier.train(input_fn=lambda:train_input_fn(train_x, train_y,batch_size),steps=1000)中的steps吗?

Tensorflow默认每10分钟保存一次,最多保留最近5次,训练第一步step和最后一步step时候一定会保存。

我们可以调整代码修改这个规则,先设定新规则ckpt_config,然后添加到train方法的括号里面config=ckpt_config:

#选定估算器:深层神经网络分类器ckpt_config= tf.estimator.RunConfig(    save_checkpoints_secs = 60,  # 每60秒保存一次    keep_checkpoint_max = 10,       # 保留最近的10次)models_path=os.path.join(dir_path,'models/')classifier = tf.estimator.DNNClassifier(    feature_columns=feature_columns,    hidden_units=[10, 10],    n_classes=3,    model_dir=models_path,    config=ckpt_config) #

--

恢复使用

从数据文件(data files)输入到估算器训练(estimator,train),到保存检查点集checkpoints,然后利用保存好的检查点集再进行评估evaluate或应用模型进行预测predict,整个的流程如下图所示:


model_dir设置了模型存储的路径,同时,如果已经存储了,那么这也是自动读取模型的路径。
我们把train一行注释掉,然后再运行iris.py,可以发现可以更快速的开始预测,这是因为并没有重新用数据进行训练,而是读取了models文件夹已经存储的模型。

#classifier.train(input_fn=lambda:train_input_fn(train_x, train_y,batch_size),steps=1000)

--

整理文件

当然我们可以将整个iris文件拆分成2个文件
iris.load

import osimport pandas as pdimport tensorflow as tfFUTURES = ['SepalLength', 'SepalWidth','PetalLength', 'PetalWidth', 'Species']SPECIES = ['Setosa', 'Versicolor', 'Virginica']    #格式化数据文件的目录地址dir_path = os.path.dirname(os.path.realpath(__file__))train_path=os.path.join(dir_path,'iris_training.csv')test_path=os.path.join(dir_path,'iris_test.csv')    #载入数据函数def load():        #载入训练数据    train = pd.read_csv(train_path, names=FUTURES, header=0)    train_x, train_y = train, train.pop('Species')    #载入测试数据    test = pd.read_csv(test_path, names=FUTURES, header=0)    test_x, test_y = test, test.pop('Species')         return (train_x, train_y),(test_x, test_y)        #针对训练的喂食函数def train_input_fn(features, labels, batch_size):    dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))    dataset = dataset.shuffle(1000).repeat().batch(batch_size) #每次随机调整数据顺序    return dataset#针对测试的喂食函数def eval_input_fn(features, labels, batch_size):    features=dict(features)    inputs=(features,labels)    dataset = tf.data.Dataset.from_tensor_slices(inputs)    dataset = dataset.batch(batch_size)    return dataset

iris_premade.py

import osimport tensorflow as tfimport iris_load as dtsimport shutil#利用iris_load.py读取训练数据和测试数据(train_x, train_y), (test_x, test_y) = dts.load()    #设定特征值的名称feature_columns = []for key in train_x:    feature_columns.append(tf.feature_column.numeric_column(key=key))   #估算器存储路径dir_path = os.path.dirname(os.path.realpath(__file__))models_path=os.path.join(dir_path,'models/')#估算器存储设置选项ckpt_config= tf.estimator.RunConfig(    save_checkpoints_secs = 60,  #每60秒保存一次    keep_checkpoint_max = 10,    #保留最近的10次)#估算器预设my_cfg=dict() my_cfg['layer1'],my_cfg['layer2'],my_cfg['batch_size'],my_cfg['steps']=10,10,100,1000#生产估算器函数:深层神经网络分类器def estimator():    classifier = tf.estimator.DNNClassifier(        feature_columns=feature_columns,        hidden_units=[my_cfg['layer1'], my_cfg['layer2']],        n_classes=3,        model_dir=models_path,        config=ckpt_config)    return classifier #训练模型函数def train():    print('Please input:layer1 nodes,layer2 nodes,batch_size,steps')    params=input().split(',')    if len(params)>3:        if os.path.exists(models_path):            print('Removing models folder...')            shutil.rmtree(models_path) #移除models目录                    my_cfg['layer1'],my_cfg['layer2'],my_cfg['batch_size'],my_cfg['steps'] = map(int, params)            print('Training...')    classifier=estimator()       classifier.train(input_fn=lambda:dts.train_input_fn(            train_x,            train_y,            my_cfg['batch_size']),         steps=my_cfg['steps'])    print('Train OK')                 #评估模型函数def evalute():    print('Evaluating...')     classifier=estimator()      eval_result = classifier.evaluate(        input_fn=lambda:dts.eval_input_fn(test_x, test_y,my_cfg['batch_size']))    print('Evaluate result:',eval_result)    def predict():    print('Please enter features: SepalLength,SepalWidth,PetalLength,PetalWidth;0 for exit.')    params=input().split(',');    if len(params)>3:        predict_x = {            'SepalLength': [float(params[0])],            'SepalWidth': [float(params[1])],            'PetalLength': [float(params[2])],            'PetalWidth': [float(params[3])],        }            #进行预测        classifier=estimator()                predictions = classifier.predict(                input_fn=lambda:dts.eval_input_fn(predict_x,                                                labels=[0],                                                batch_size=my_cfg['batch_size']))        #预测结果是数组,尽管实际我们只有一个        for pred_dict in predictions:            class_id = pred_dict['class_ids'][0]            probability = pred_dict['probabilities'][class_id]            print('Predict result:',dts.SPECIES[class_id],100 * probability)    else:        print('Input format error,ignored.')#定义入口主函数def main(args):    while 1==1:        print('Please enter train,evalute or predict:')        cmd = input() #捕获用户输入的数字        if cmd=='train':            train()        elif cmd=='evalute':            evalute()        elif cmd=='predict':            predict()        elif cmd=='retrain':            retrain()            #运行主函数            if __name__ == '__main__':    tf.logging.set_verbosity(tf.logging.INFO)    tf.app.run(main)

注意my_cfg=dict() 这个字典数据用法,它和下面一行生成类似下面这种数据结构

my_dict={  'layer1':10,  'layer2':10,  'batch_size':100,  'steps':1000}

然后我们才能在def定义的函数中修改它并使其在estimator()方法中生效。

a=100def change():    a=99print(a)
n=100def estimator():    b=n+1    print(b)    def train():    n=10def evalute():    estimator()    train() #这行并不能真正改变nevalute()

如果遇到问题,您也可以点击 这里 直接下载代码
提取密码: 83qe


探索人工智能的新边界

如果您发现文章错误,请不吝留言指正;
如果您觉得有用,请点喜欢;
如果您觉得很有用,感谢转发~


END