tensorflow svm回归(Python TensorFlow深度学习回归代码:DNNRegressor)
本文介绍基于Python语言中TensorFlow的tf.estimator接口 ,实现深度学习神经网络回归的具体方法 。
1 写在前面
1. 本文介绍的是基于TensorFlow tf.estimator接口的深度学习网络 ,而非TensorFlow 2.0中常用的Keras接口;关于Keras接口实现深度学习回归 ,我们将在下一篇博客中介绍 。
2. 本文代码以DNNRegressor回归为例;而由于基于 tf.estimator接口的深度学习回归与分类整体较为类似 ,因此二者具有触类旁通的效果 。
3. 本文第二部分为代码的分解介绍 ,第三部分为完整代码 。
4. 相关版本信息:Python版本:3.8.5;TensorFlow版本:2.4.1;编译器版本:Spyder 4.1.5 。
2 代码分解介绍
2.1 准备工作
首先需要引入相关的库与包 。
import os import openpyxl import numpy as np import pandas as pd import tensorflow as tf import scipy.stats as stats import matplotlib.pyplot as plt from sklearn import metrics from sklearn.model_selection import train_test_split其次 ,基于TensorFlow的代码往往会输出较多的日志信息 ,从而使得我们对代码执行情况的了解受到一定影响 。代码输出的日志信息有四种 ,依据严重程度由低到高排序:INFO(通知)<WARNING(警告)<ERROR(错误)<FATAL(致命的);我们可以通过如下代码来对TensorFlow的输出日志信息加以约束 。
os.environ[TF_CPP_MIN_LOG_LEVEL]=3其中 ,3代表只输出FATAL信息 。但要注意 ,这句代码需要放在import tensorflow的前面:
import os os.environ[TF_CPP_MIN_LOG_LEVEL]=3 import openpyxl import numpy as np import pandas as pd import tensorflow as tf import scipy.stats as stats import matplotlib.pyplot as plt from sklearn import metrics from sklearn.model_selection import train_test_split2.2 参数配置
深度学习代码一大特点即为具有较多的参数需要我们手动定义 。为避免调参时上下翻找 ,我们可以将主要的参数集中在一起 ,方便我们后期调整 。
其中,具体参数的含义在本文后续部分详细介绍 。
# 将各类变量放在一个位置集中定义 ,十分有利于机器学习等变量较多的代码 MyModelPath="G:/CropYield/03_DL/02_DNNModle" # 确定每一次训练所得模型保存的位置 MyDataPath="G:/CropYield/03_DL/00_Data/AllDataAll.csv" # 确定输入数据的位置 MyResultSavePath="G:/CropYield/03_DL/03_OtherResult/EvalResult54.xlsx" # 确定模型精度结果(RMSE等)与模型参数保存的位置 TestSize=0.2 # 确定数据中测试集所占比例 RandomSeed=np.random.randint(low=24,high=25) # 确定划分训练集与测试集的随机数种子 OptMethod=Adam # 确定模型所用的优化方法 LearningRate=0.01 # 确定学习率 DecayStep=200 # 确定学习率下降的步数 DecayRate=0.96 # 确定学习率下降比率 HiddenLayer=[64,128] # 确定隐藏层数量与每一层对应的神经元数量 ActFun=tf.nn.relu # 确定激活函数 Dropout=0.3 # 确定Dropout的值 LossReduction=tf.compat.v1.ReductionV2.SUM_OVER_BATCH_SIZE # 指定每个批次训练误差的减小方法 BatchNorm=False # 确定是否使用Batch Normalizing TrainBatchSize=110 # 确定训练数据一个Batch的大小 TrainStep=3000 # 确定训练数据的Step数量 EvalBatchSize=1 # 确定验证数据一个Batch的大小 PredictBatchSize=1 # 确定预测数据(即测试集)一个Batch的大小2.3 原有模型删除
DNNRegressor每执行一次 ,便会在指定路径中保存当前运行的模型。为保证下一次模型保存时不受上一次模型运行结果干扰,我们可以将模型文件夹内的全部文件删除 。
# DeleteOldModel函数 ,删除上一次运行所保存的模型 def DeleteOldModel(ModelPath): AllFileName=os.listdir(ModelPath) # 获取ModelPath路径下全部文件与文件夹 for i in AllFileName: NewPath=os.path.join(ModelPath,i) # 分别将所获取的文件或文件夹名称与ModelPath路径组合 if os.path.isdir(NewPath): # 若组合后的新路径是一个文件夹 DeleteOldModel(NewPath) # 递归调用DeleteOldModel函数 else: os.remove(NewPath) # 若不是一个新的文件夹 ,而是一个文件 ,那么就删除 # 调用DeleteOldModel函数 ,删除上一次运行所保存的模型 DeleteOldModel(MyModelPath)需要注意 ,以上代码仅删除指定路径下的文件 ,文件夹不删除 。大家如果需要将文件夹也同时删除 ,修改以上代码函数中的后面几句即可。
2.4 数据导入与数据划分
我的数据已经保存在了.csv文件中 ,因此可以用pd.read_csv直接读取 。
其中 ,数据的每一列是一个特征 ,每一行是全部特征与因变量(就是下面的Yield)组合成的样本 。
# LoadData函数 ,加载全部数据 def LoadData(DataPath): MyData=pd.read_csv(DataPath,names=[EVI0610,EVI0626,EVI0712,EVI0728,EVI0813,EVI0829, EVI0914,EVI0930,EVI1016,Lrad06,Lrad07,Lrad08, Lrad09,Lrad10,Prec06,Prec07,Prec08,Prec09, Prec10,Pres06,Pres07,Pres08,Pres09,Pres10, SIF161,SIF177,SIF193,SIF209,SIF225,SIF241, SIF257,SIF273,SIF289,Shum06,Shum07,Shum08, Shum09,Shum10,SoilType,Srad06,Srad07,Srad08, Srad09,Srad10,Temp06,Temp07,Temp08,Temp09, Temp10,Wind06,Wind07,Wind08,Wind09,Wind10, Yield],header=0) # 加载DataPath路径所指定的数据 ,names中的内容为各列的名称 return MyData # 初始数据处理 AllXY=LoadData(MyDataPath) # 调用LoadData函数,获取数据 Label={"Yield":AllXY.pop("Yield")} # 将因变量从全部数据中提取出 AllX,AllY=AllXY,(pd.DataFrame(Label)) # 将自变量与因变量分离 # 划分数据训练集与测试集 TrainX,TestX,TrainY,TestY=train_test_split(AllX, AllY, test_size=TestSize, # 指定数据中测试集所占比例 random_state=RandomSeed # 指定划分训练集与测试集的随机数种子 )2.5 Feature Columns定义
Feature Columns就是一个桥梁 ,联系你的初始数据与模型;其好比一个名单 ,模型拿着这个名单到你的数据(即本文2.4部分你导入的数据)中按列的名称一一搜索,若初始数据中的某列名称在Feature Columns里 ,那么模型就会把初始数据中这一列的数据全部拿到自己这里 ,进行训练 。
因为我们是希望导入数据的全部特征 ,那么可以直接在全部数据的自变量中循环 ,将全部特征的名称导入Feature Columns 。
在这里需要注意的是 ,只有连续数值变量才可以用tf.feature_column.numeric_column处理;若是类别变量可以对其加以独热编码等操作 。
# estimator接口中的模型需要用“Feature columns ”对象作为输入数据 ,只有这样模型才知道读取哪些数据 FeatureColumn=[] # 定义一个新的“Feature columns ”对象 for key in AllX.keys(): FeatureColumn.append(tf.feature_column.numeric_column(key=key)) # 将全部因变量数据(需要均为连续变量)导入2.6 模型优化方法构建与模型结构构建
模型优化方法即模型中的optimizer ,其可以在模型结构构建时输入;但有时优化方法较为复杂(例如引入了学习率下降) ,那么在构建模型时配置优化方法的话就会有些不方便 。因此我们首先构建模型优化方法 。
# 定义模型优化方法 # Optimizer=OptMethod # 优化方法选用OptMethod所指定的方法 Optimizer=lambda:tf.keras.optimizers.Adam( learning_rate=tf.compat.v1.train.exponential_decay(learning_rate=LearningRate, # 初始学习率 global_step=tf.compat.v1.train.get_global_step(), # 全局步数 ,用以计算已经衰减后的学习率 # get_global_step()函数自动获取当前的已经执行的步数 decay_steps=DecayStep, # 学习率下降完成的指定步数 decay_rate=DecayRate # 衰减率 ) # 选用基于学习率指数下降的Adam方法 ,此举有助于降低过拟合风险 # 这一函数返回每次对应的学习率 )以上代码中有两个Optimizer= ,第一个是直接输入优化方法的名称即可 ,名称包括:Adagrad, Adam, Ftrl, RMSProp, SGD;默认为Adagrad 。
第二个是在选择了优化方法的基础上,配置其他信息 。例如第二个 ,其代表着学习率指数下降的Adam优化方法 。其中 ,tf.compat.v1.train.exponential_decay可视作一个计算每次训练学习率的函数,他返回的是每一次对应的学习率 。可能这么说不太好理解 ,看这个公式:其返回值为learning_rate *decay_rate ^ (global_step / decay_steps) ,是不是就明白啦 。
我们选择第二个优化方法 ,因此把第一个注释掉。
随后 ,我们定义模型的结构 。
# 基于DNNRegressor构建深度学习模型 DNNModel=tf.estimator.DNNRegressor(feature_columns=FeatureColumn, # 指定模型所用的“Feature columns ”对象 hidden_units=HiddenLayer, # 指定隐藏层数量与每一层对应的神经元数量 optimizer=Optimizer, # 指定模型所用的优化方法 activation_fn=eval(ActFun), # 指定激活函数 dropout=Dropout, # 指定Dropout的值 label_dimension=1, # 输出数据的维度 ,即因变量的个数 model_dir=MyModelPath, # 指定每一次训练所得模型保存的位置 # loss_reduction=eval(LossReduction), # 指定每个批次训练误差的减小方法 batch_norm=eval(BatchNorm) # 指定是否使用Batch Normalizing )模型的构建 ,对照着代码上的注释 ,就比较好理解了;其中 ,我把loss_reduction注释掉 ,是因为可能由于TensorFlow版本的问题 ,其总是报错 ,所以就用默认的值就好;而最后一个batch_norm ,决定了是否进行Batch Normalizing 。Batch Normalizing可以保持深度神经网络在每一层保持相同分布,从而加快网络收敛与增强网络稳固性。
其它参数可以参考官方网站 ,这里暂时不再赘述 。
2.7 模型训练
训练模型这一部分 ,我认为反而比模型的构建可能还难理解一些 。我们先看代码:
# 基于训练数据训练模型 DNNModel.train(input_fn=lambda:InputFun(TrainX, TrainY, True, TrainBatchSize ), # 调用InputFun函数;InputFun函数返回“tf.data.Dataset ”对象,这个对象才可以被 # train函数识别并带入模型;由于InputFun函数每次返回BatchSize大小的数据个数 , # 因此需要多次执行 ,前面需要加lambda steps=TrainStep # 指定模型训练的步数 )我们可以这么理解:在train函数中 ,只有一个参数input_fn;而这个参数的输入 ,又是一个新的函数——这个新的函数就是大名鼎鼎的input function了 。
他长这个样子:
# InputFun函数 ,训练数据与验证数据所用的Input函数 def InputFun(Features,Labels,Training,BatchSize): Datasets=tf.data.Dataset.from_tensor_slices((dict(Features),Labels)) # 对数据加以加载 if Training: Datasets=Datasets.shuffle(1000).repeat() # 对于训练数据 ,需要打乱(shuffle) 、重复(repeat) return Datasets.batch(BatchSize) # 将经过上述处理后的数据以每次BatchSize个输出那我们首先就看input function——也就是代码中的InputFun函数 。其实这个函数的用处很简单 ,用官网的话说 ,其就是用来输入模型支持的数据类型的——只有经过input function处理后 ,数据才可以被DNNRegressor识别 。听上去这么厉害 ,它到底是如何操作的呢?
很简单 ,它只需要将初始的数据转换为特定的格式即可 ,这个格式是一个元组(tuple),这个元组有两个元素:
一就是features ,是一个字典 。这个字典的每一个键是每一个特征的名称 ,就比如用植物特性对花的种类加以区分,那么花的“叶长 ”“叶片厚度 ”等等就是一个个特征的名称 ,也就是这里的一个个“键 ”;而这个字典的值 ,就是这个特征对应的全部样本的数值组成的数组 。
二就是label ,是全部样本对应的label ,也就是因变量 。
不知道大家有没有理解 ,我们就举一个简单的例子 。假如我们用两个地方的温度与降水预测这两个地方的作物产量:其温度分别为10 ℃ 、20 ℃ ,降水分别为15 mm ,25 mm ,作物产量分别为100千克每公顷 ,150千克每公顷——那么tuple由两个部分组成:
tuple=(features,label) features={温度:np.array([10 ,20]),降水:np.array([15,25])} label=np.array([100,150])怎么样 ,是不是明白啦 。
理解了之后 ,我们继续看InputFun函数 。首先,tf.data.Dataset.from_tensor_slices用来将输入的数据加载并转换为Datase的形式;随后 ,如果是训练状态下 ,那么数据会进行打乱.shuffle(1000)——相当于对数据加以洗牌,防止初始数据具有一定的趋势 。例如如果我们做分类 ,其中初始数据的前80%都是第一类 ,后20%都是第二类 ,那么如果我们不打乱数据 ,会使得用前80%数据训练出来的结果都是第一类(即模型只认识第一类) ,在后20%进行测试时 ,所得结果也全都为第一类;所以要打乱。其中的1000是buffer_size参数 ,这个数据必须要比你的数据样本个数大 。至于.shuffle(1000)这个函数的原理我一直没有搞明白 ,大家感兴趣的话可以加以进一步了解 。
.repeat()则是对数据集加以重复 ,之所以要重复 ,是因为我们需要对全部数据训练好几轮(即好几个Epoch) ,因此要对初始数据加以重复。
随后 ,用.batch()函数输出BatchSize个数据,也就是一批数据;其中BatchSize就是每一批数据的个数 。
这个就是InputFun函数 。再看train函数函数:大家也看出来了 ,这个InputFun函数是每次输出一批(BatchSize个)数据;而我们训练的时候 ,肯定是要一批一批不停输入数据的,因此这就解释了为什么InputFun函数前有一个lambda——因为InputFun函数要把处理后的数据分多次传给train 。
2.8 模型验证与测试
理解了以上内容 ,接下来就好理解多了 。我们需要进行验证与测试的操作——其实验证也就是利用了测试集数据 ,之所以我还进行了测试 ,是因为希望可以获取测试集预测结果 ,从而更直观地了解模型精度水平 。
# InputFunPredict函数 ,测试数据所用的Input函数 def InputFunPredict(Features,BatchSize): return tf.data.Dataset.from_tensor_slices(dict(Features)).batch(BatchSize) # 对数据加以加载,以每次BatchSize个输出 # 验证模型并保存验证结果 EvalResult=DNNModel.evaluate(input_fn=lambda:InputFun(TestX, TestY, False, EvalBatchSize ) ) # 打印验证结果 print(ev:{}.format(EvalResult)) # 基于测试数据测试模型精度结果 PredictValues=DNNModel.predict(input_fn=lambda:InputFunPredict(TestX, PredictBatchSize ) )其中 ,验证时.evaluate所用的InputFun函数其实和训练集所用的是一样的函数 ,只不过验证时不需要进行打乱.shuffle(1000)和重复.repeat()操作;而测试时.predict的InputFun函数则是新的 ,其只需要输入自变量 、无需输入因变量 。
2.9 精度评定 、拟合图像绘制与模型参数与精度结果保存
精度评定与拟合图像就不用过多说啦~最终 ,我们最好将模型参数与精度衡量指标结果保存在Excel表格中 ,这样子方便之后的调参过程 。这里就不再一一介绍啦 ,大家对照代码中的注释即可 。
# AccuracyVerification函数 ,进行精度验证指标的计算与绘图 def AccuracyVerification(PredictLabels,TestLabels): value=0 PredictValuesList=[] for k in PredictLabels: value=k.get(predictions)[0] PredictValuesList.append(value) TestLabels=TestLabels.values.tolist() TestYList=sum(TestLabels,[]) # 以上为获取测试数据的因变量与模型预测所得的因变量 Pearsonr=stats.pearsonr(TestYList,PredictValuesList) # 计算皮尔逊相关系数 R2=metrics.r2_score(TestYList,PredictValuesList) # 计算R方 RMSE=metrics.mean_squared_error(TestYList,PredictValuesList)**0.5 # 计算RMSE plt.cla() plt.plot(TestYList,PredictValuesList,r*) plt.xlabel(Actual Values) plt.ylabel(Predicted Values) # 以上为绘制拟合图像 print(Pearson correlation coefficient is {0}, and RMSE is {1}..format(Pearsonr[0],RMSE)) return (Pearsonr[0],R2,RMSE,PredictValuesList) # WriteAccuracy函数,将模型所涉及的参数与最终精度结果保存 def WriteAccuracy(*WriteVar): ExcelData=openpyxl.load_workbook(WriteVar[0]) SheetName=ExcelData.get_sheet_names() # 获取全部Sheet WriteSheet=ExcelData.get_sheet_by_name(SheetName[0]) # 获取指定Sheet WriteSheet=ExcelData.active # 激活指定Sheet MaxRowNum=WriteSheet.max_row # 获取指定Sheet对应第一个空行 for i in range(len(WriteVar)-1): exec("WriteSheet.cell(MaxRowNum+1,i+1).value=WriteVar[i+1]") # 用exec执行语句 ,写入信息 ExcelData.save(WriteVar[0]) # 保存文件 # 调用AccuracyVerification函数 ,进行精度验证指标的计算与绘图 AccuracyResult=AccuracyVerification(PredictValues,TestY) PearsonR,R2,RMSE,PredictY=AccuracyResult[0],AccuracyResult[1],AccuracyResult[2],AccuracyResult[3] # 调用WriteAccuracy函数,将模型所涉及的参数与最终精度结果保存 WriteAccuracy(MyResultSavePath,PearsonR,R2,RMSE,TestSize,RandomSeed,OptMethod,LearningRate,DecayStep, DecayRate,,.join(%s %i for i in HiddenLayer),ActFun,Dropout,LossReduction, BatchNorm,TrainBatchSize,TrainStep,EvalBatchSize,PredictBatchSize)至此 ,全部的代码分解介绍都结束啦~
3 详细代码
# -*- coding: utf-8 -*- """ Created on Tue Feb 23 16:13:21 2021 @author: Chutj """ # 加载必要的库 、包等 import os os.environ[TF_CPP_MIN_LOG_LEVEL]=3 import openpyxl import numpy as np import pandas as pd import tensorflow as tf import scipy.stats as stats import matplotlib.pyplot as plt from sklearn import metrics from sklearn.model_selection import train_test_split # ===============*** 函数声明区域 ***=============== # DeleteOldModel函数 ,删除上一次运行所保存的模型 def DeleteOldModel(ModelPath): AllFileName=os.listdir(ModelPath) # 获取ModelPath路径下全部文件与文件夹 for i in AllFileName: NewPath=os.path.join(ModelPath,i) # 分别将所获取的文件或文件夹名称与ModelPath路径组合 if os.path.isdir(NewPath): # 若组合后的新路径是一个文件夹 DeleteOldModel(NewPath) # 递归调用DeleteOldModel函数 else: os.remove(NewPath) # 若不是一个新的文件夹 ,而是一个文件 ,那么就删除 # LoadData函数 ,加载全部数据 def LoadData(DataPath): MyData=pd.read_csv(DataPath,names=[EVI0610,EVI0626,EVI0712,EVI0728,EVI0813,EVI0829, EVI0914,EVI0930,EVI1016,Lrad06,Lrad07,Lrad08, Lrad09,Lrad10,Prec06,Prec07,Prec08,Prec09, Prec10,Pres06,Pres07,Pres08,Pres09,Pres10, SIF161,SIF177,SIF193,SIF209,SIF225,SIF241, SIF257,SIF273,SIF289,Shum06,Shum07,Shum08, Shum09,Shum10,SoilType,Srad06,Srad07,Srad08, Srad09,Srad10,Temp06,Temp07,Temp08,Temp09, Temp10,Wind06,Wind07,Wind08,Wind09,Wind10, Yield],header=0) # 加载DataPath路径所指定的数据 ,names中的内容为各列的名称 return MyData # InputFun函数 ,训练数据与验证数据所用的Input函数 def InputFun(Features,Labels,Training,BatchSize): Datasets=tf.data.Dataset.from_tensor_slices((dict(Features),Labels)) # 对数据加以加载 if Training: Datasets=Datasets.shuffle(1000).repeat() # 对于训练数据 ,需要打乱(shuffle) 、重复(repeat) return Datasets.batch(BatchSize) # 将经过上述处理后的数据以每次BatchSize个输出 # InputFunPredict函数 ,测试数据所用的Input函数 def InputFunPredict(Features,BatchSize): return tf.data.Dataset.from_tensor_slices(dict(Features)).batch(BatchSize) # 对数据加以加载,以每次BatchSize个输出 # AccuracyVerification函数 ,进行精度验证指标的计算与绘图 def AccuracyVerification(PredictLabels,TestLabels): value=0 PredictValuesList=[] for k in PredictLabels: value=k.get(predictions)[0] PredictValuesList.append(value) TestLabels=TestLabels.values.tolist() TestYList=sum(TestLabels,[]) # 以上为获取测试数据的因变量与模型预测所得的因变量 Pearsonr=stats.pearsonr(TestYList,PredictValuesList) # 计算皮尔逊相关系数 R2=metrics.r2_score(TestYList,PredictValuesList) # 计算R方 RMSE=metrics.mean_squared_error(TestYList,PredictValuesList)**0.5 # 计算RMSE plt.cla() plt.plot(TestYList,PredictValuesList,r*) plt.xlabel(Actual Values) plt.ylabel(Predicted Values) # 以上为绘制拟合图像 print(Pearson correlation coefficient is {0}, and RMSE is {1}..format(Pearsonr[0],RMSE)) return (Pearsonr[0],R2,RMSE,PredictValuesList) # WriteAccuracy函数 ,将模型所涉及的参数与最终精度结果保存 def WriteAccuracy(*WriteVar): ExcelData=openpyxl.load_workbook(WriteVar[0]) SheetName=ExcelData.get_sheet_names() # 获取全部Sheet WriteSheet=ExcelData.get_sheet_by_name(SheetName[0]) # 获取指定Sheet WriteSheet=ExcelData.active # 激活指定Sheet MaxRowNum=WriteSheet.max_row # 获取指定Sheet对应第一个空行 for i in range(len(WriteVar)-1): exec("WriteSheet.cell(MaxRowNum+1,i+1).value=WriteVar[i+1]") # 用exec执行语句 ,写入信息 ExcelData.save(WriteVar[0]) # 保存文件 # ===============*** 代码由此开始执行 ***=============== # ++++++++++--- 建议由这里开始看 ---++++++++++ # 将各类变量放在一个位置集中定义,十分有利于机器学习等变量较多的代码 MyModelPath="G:/CropYield/03_DL/02_DNNModle" # 确定每一次训练所得模型保存的位置 MyDataPath="G:/CropYield/03_DL/00_Data/AllDataAll.csv" # 确定输入数据的位置 MyResultSavePath="G:/CropYield/03_DL/03_OtherResult/EvalResult54.xlsx" # 确定模型精度结果(RMSE等)与模型参数保存的位置 TestSize=0.2 # 确定数据中测试集所占比例 RandomSeed=np.random.randint(low=24,high=25) # 确定划分训练集与测试集的随机数种子 OptMethod=Adam # 确定模型所用的优化方法 LearningRate=0.01 # 确定学习率 DecayStep=200 # 确定学习率下降的步数 DecayRate=0.96 # 确定学习率下降比率 HiddenLayer=[64,128] # 确定隐藏层数量与每一层对应的神经元数量 ActFun=tf.nn.relu # 确定激活函数 Dropout=0.3 # 确定Dropout的值 LossReduction=tf.compat.v1.ReductionV2.SUM_OVER_BATCH_SIZE # 指定每个批次训练误差的减小方法 BatchNorm=False # 确定是否使用Batch Normalizing TrainBatchSize=110 # 确定训练数据一个Batch的大小 TrainStep=3000 # 确定训练数据的Step数量 EvalBatchSize=1 # 确定验证数据一个Batch的大小 PredictBatchSize=1 # 确定预测数据(即测试集)一个Batch的大小 # 调用DeleteOldModel函数 ,删除上一次运行所保存的模型 DeleteOldModel(MyModelPath) # 初始数据处理 AllXY=LoadData(MyDataPath) # 调用LoadData函数 ,获取数据 Label={"Yield":AllXY.pop("Yield")} # 将因变量从全部数据中提取出 AllX,AllY=AllXY,(pd.DataFrame(Label)) # 将自变量与因变量分离 # 划分数据训练集与测试集 TrainX,TestX,TrainY,TestY=train_test_split(AllX, AllY, test_size=TestSize, # 指定数据中测试集所占比例 random_state=RandomSeed # 指定划分训练集与测试集的随机数种子 ) # estimator接口中的模型需要用“Feature columns ”对象作为输入数据,只有这样模型才知道读取哪些数据 FeatureColumn=[] # 定义一个新的“Feature columns ”对象 for key in AllX.keys(): FeatureColumn.append(tf.feature_column.numeric_column(key=key)) # 将全部因变量数据(需要均为连续变量)导入 # 定义模型优化方法 # Optimizer=OptMethod # 优化方法选用OptMethod所指定的方法 Optimizer=lambda:tf.keras.optimizers.Adam( learning_rate=tf.compat.v1.train.exponential_decay(learning_rate=LearningRate, # 初始学习率 global_step=tf.compat.v1.train.get_global_step(), # 全局步数 ,用以计算已经衰减后的学习率 # get_global_step()函数自动获取当前的已经执行的步数 decay_steps=DecayStep, # 学习率下降完成的指定步数 decay_rate=DecayRate # 衰减率 ) # 选用基于学习率指数下降的Adam方法 ,此举有助于降低过拟合风险 # 这一函数返回每次对应的学习率 ) # 基于DNNRegressor构建深度学习模型 DNNModel=tf.estimator.DNNRegressor(feature_columns=FeatureColumn, # 指定模型所用的“Feature columns ”对象 hidden_units=HiddenLayer, # 指定隐藏层数量与每一层对应的神经元数量 optimizer=Optimizer, # 指定模型所用的优化方法 activation_fn=eval(ActFun), # 指定激活函数 dropout=Dropout, # 指定Dropout的值 label_dimension=1, # 输出数据的维度 ,即因变量的个数 model_dir=MyModelPath, # 指定每一次训练所得模型保存的位置 # loss_reduction=eval(LossReduction), # 指定每个批次训练误差的减小方法 batch_norm=eval(BatchNorm) # 指定是否使用Batch Normalizing ) # tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.INFO) # 将INFO级别的日志信息显示到屏幕 # 基于训练数据训练模型 DNNModel.train(input_fn=lambda:InputFun(TrainX, TrainY, True, TrainBatchSize ), # 调用InputFun函数;InputFun函数返回“tf.data.Dataset ”对象 ,这个对象才可以被 # train函数识别并带入模型;由于InputFun函数每次返回BatchSize大小的数据个数 , # 因此需要多次执行 ,前面需要加lambda steps=TrainStep # 指定模型训练的步数 ) # 验证模型并保存验证结果 EvalResult=DNNModel.evaluate(input_fn=lambda:InputFun(TestX, TestY, False, EvalBatchSize ) ) # 打印验证结果 print(ev:{}.format(EvalResult)) # 基于测试数据测试模型精度结果 PredictValues=DNNModel.predict(input_fn=lambda:InputFunPredict(TestX, PredictBatchSize ) ) # 调用AccuracyVerification函数 ,进行精度验证指标的计算与绘图 AccuracyResult=AccuracyVerification(PredictValues,TestY) PearsonR,R2,RMSE,PredictY=AccuracyResult[0],AccuracyResult[1],AccuracyResult[2],AccuracyResult[3] # 调用WriteAccuracy函数 ,将模型所涉及的参数与最终精度结果保存 WriteAccuracy(MyResultSavePath,PearsonR,R2,RMSE,TestSize,RandomSeed,OptMethod,LearningRate,DecayStep, DecayRate,,.join(%s %i for i in HiddenLayer),ActFun,Dropout,LossReduction, BatchNorm,TrainBatchSize,TrainStep,EvalBatchSize,PredictBatchSize)至此 ,大功告成 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!