Python基于TensorFlow接口实现深度学习神经网络回归

目录
  • 1 写在前面
  • 2 代码分解介绍
    • 2.1 准备工作
    • 2.2 参数配置
    • 2.3 原有模型删除
    • 2.4 数据导入与数据划分
    • 2.5 Feature Columns定义
    • 2.6 模型优化方法构建与模型结构构建
    • 2.7 模型训练
    • 2.8 模型验证与测试
    • 2.9 精度评定、拟合图像绘制与模型参数与精度结果保存
  • 3 详细代码

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_split

2.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 NormalizingBatch 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%进行测试时,所得结果也全都为第一类;所以要打乱。其中的1000buffer_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()操作;而测试时.predictInputFun函数则是新的,其只需要输入自变量、无需输入因变量。

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)

以上就是Python基于TensorFlow接口实现深度学习神经网络回归的详细内容,更多关于Python TensorFlow深度学习神经网络回归的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python数据分析之双色球基于线性回归算法预测下期中奖结果示例

    本文实例讲述了Python数据分析之双色球基于线性回归算法预测下期中奖结果.分享给大家供大家参考,具体如下: 前面讲述了关于双色球的各种算法,这里将进行下期双色球号码的预测,想想有些小激动啊. 代码中使用了线性回归算法,这个场景使用这个算法,预测效果一般,各位可以考虑使用其他算法尝试结果. 发现之前有很多代码都是重复的工作,为了让代码看的更优雅,定义了函数,去调用,顿时高大上了 #!/usr/bin/python # -*- coding:UTF-8 -*- #导入需要的包 import pan

  • python人工智能算法之线性回归实例

    目录 线性回归 使用场景 分析: 总结: 线性回归 是一种常见的机器学习算法,也是人工智能中常用的算法.它是一种用于预测数值型输出变量与一个或多个自变量之间线性关系的方法.例如,你可以使用线性回归模型来预测房价,根据房屋的面积.地理位置.周围环境等. 主要思想是通过构建一个线性模型,来描述自变量和输出变量之间的关系.模型可以表示为: y = a0 + a1*x1 + a2*x2 + - + an*xn 其中,y是输出变量(也称为响应变量),x1.x2.….xn是自变量(也称为特征),a0.a1.

  • python数据分析之线性回归选择基金

    目录 1 前言 2 基金趋势分析 3 数据抓取与分析 3.1 基金数据抓取 3.2 数据分析 4 总结 1 前言 在前面的章节中我们牛刀小试,一直在使用python爬虫去抓取数据,然后把数据信息存放在数据库中,至此已经完成了基本的基本信息的处理,接下来就来处理高级一点儿的内容,今天就从基金的趋势分析开始. 2 基金趋势分析 基金的趋势,就是选择一些表现强势的基金,什么样的才是强势呢?那就是要稳定的,逐步的一路北上.通常情况下,基金都会沿着一条趋势线向上或者向下,基金的趋势形成比股票的趋势更加确定

  • Python利用keras接口实现深度神经网络回归

    目录 1 写在前面 2 代码分解介绍 2.1 准备工作 2.2 参数配置 2.3 数据导入与数据划分 2.4 联合分布图绘制 2.5 因变量分离与数据标准化 2.6 原有模型删除 2.7 最优Epoch保存与读取 2.8 模型构建 2.9 训练图像绘制 2.10 最优Epoch选取 2.11 模型测试.拟合图像绘制.精度验证与模型参数与结果保存 3 完整代码 1 写在前面 前期一篇文章Python TensorFlow深度学习回归代码:DNNRegressor详细介绍了基于TensorFlow 

  • 如何用Python进行回归分析与相关分析

    目录 一.前言 1.1 回归分析 1.2 相关分析 二.代码的编写 2.1 前期准备 2.2 编写代码 2.2.1 相关分析 2.2.2 一元线性回归分析 2.2.3 多元线性回归分析 2.2.4 广义线性回归分析 2.2.5 logistic回归分析 三.代码集合 一.前言 1.1 回归分析 是用于研究分析某一变量受其他变量影响的分析方法,其基本思想是以被影响变量为因变量,以影响变量为自变量,研究因变量与自变量之间的因果关系. 1.2 相关分析 不考虑变量之间的因果关系而只研究变量之间的相关关

  • Python实现随机森林回归与各自变量重要性分析与排序

    目录 1 代码分段讲解 1.1 模块与数据准备 1.2 特征与标签分离 1.3 RF模型构建.训练与预测 1.4 预测图像绘制.精度衡量指标计算与保存 1.5 决策树可视化 1.6 变量重要性分析 2 完整代码 本文介绍在Python环境中,实现随机森林(Random Forest,RF)回归与各自变量重要性分析与排序的过程. 其中,关于基于MATLAB实现同样过程的代码与实战,大家可以点击查看MATLAB实现随机森林(RF)回归与自变量影响程度分析这篇文章. 本文分为两部分,第一部分为代码的分

  • Python反向传播实现线性回归步骤详细讲解

    目录 1. 导入包 2. 生成数据 3. 训练数据 4. 绘制图像 5. 代码 1. 导入包 我们这次的任务是随机生成一些离散的点,然后用直线(y = w *x + b )去拟合 首先看一下我们需要导入的包有 torch 包为我们生成张量,可以使用反向传播 matplotlib.pyplot 包帮助我们绘制曲线,实现可视化 2. 生成数据 这里我们通过rand随机生成数据,因为生成的数据在0~1之间,这里我们扩大10倍. 我们设置的batch_size,也就是数据的个数为20个,所以这里会产生维

  • Python深度学习神经网络残差块

    目录 ResNet模型 训练模型 ResNet沿用VGG完整的KaTeX parse error: Undefined control sequence: \time at position 2: 3\̲t̲i̲m̲e̲3卷积层设计.残差块里首先有2个相同输出通道数的KaTeX parse error: Undefined control sequence: \time at position 2: 3\̲t̲i̲m̲e̲3卷积层.每个卷积层后接一个批量归一化层和ReLU激活函数.然后我们通过跨

  • Python深度学习神经网络基本原理

    目录 神经网络 梯度下降法 神经网络 梯度下降法 在详细了解梯度下降的算法之前,我们先看看相关的一些概念. 1. 步长(Learning rate):步长决定了在梯度下降迭代的过程中,每一步沿梯度负方向前进的长度.用上面下山的例子,步长就是在当前这一步所在位置沿着最陡峭最易下山的位置走的那一步的长度. 2.特征(feature):指的是样本中输入部分,比如2个单特征的样本(x(0),y(0)),(x(1),y(1))(x(0),y(0)),(x(1),y(1)),则第一个样本特征为x(0)x(0

  • win10+RTX3050ti+TensorFlow+cudn+cudnn配置深度学习环境的方法

    避坑1:RTX30系列显卡不支持cuda11.0以下版本,具体上限版本可自行查阅: 方法一,在cmd中输入nvidia-smi查看 方法二: 由此可以看出本电脑最高适配cuda11.2.1版本: 注意需要版本适配,这里我们选择TensorFlow-gpu = 2.5,cuda=11.2.1,cudnn=8.1,python3.7 接下来可以下载cudn和cundnn: 官网:https://developer.nvidia.com/cuda-toolkit-archive 下载对应版本exe文件

  • PyTorch的深度学习入门之PyTorch安装和配置

    前言 深度神经网络是一种目前被广泛使用的工具,可以用于图像识别.分类,物体检测,机器翻译等等.深度学习(DeepLearning)是一种学习神经网络各种参数的方法.因此,我们将要介绍的深度学习,指的是构建神经网络结构,并且运用各种深度学习算法训练网络参数,进而解决各种任务.本文从PyTorch环境配置开始.PyTorch是一种Python接口的深度学习框架,使用灵活,学习方便.还有其他主流的深度学习框架,例如Caffe,TensorFlow,CNTK等等,各有千秋.笔者认为,初期学习还是选择一种

  • 理解深度学习之深度学习简介

    机器学习 在吴恩达老师的课程中,有过对机器学习的定义: ML:<P T E> P即performance,T即Task,E即Experience,机器学习是对一个Task,根据Experience,去提升Performance: 在机器学习中,神经网络的地位越来越重要,实践发现,非线性的激活函数有助于神经网络拟合分布,效果明显优于线性分类器: y=Wx+b 常用激活函数有ReLU,sigmoid,tanh: sigmoid将值映射到(0,1): tanh会将输入映射到(-1,1)区间: #激活

  • Python深度学习TensorFlow神经网络基础概括

    目录 一.基础理论 1.TensorFlow 2.TensorFlow过程 1.构建图阶段 2.执行图阶段(会话) 二.TensorFlow实例(执行加法) 1.构造静态图 1-1.创建数据(张量) 1-2.创建操作(节点) 2.会话(执行) API: 普通执行 fetches(多参数执行) feed_dict(参数补充) 总代码 一.基础理论 1.TensorFlow tensor:张量(数据) flow:流动 Tensor-Flow:数据流 2.TensorFlow过程 TensorFlow

  • Python深度学习之实现卷积神经网络

    一.卷积神经网络 Yann LeCun 和Yoshua Bengio在1995年引入了卷积神经网络,也称为卷积网络或CNN.CNN是一种特殊的多层神经网络,用于处理具有明显网格状拓扑的数据.其网络的基础基于称为卷积的数学运算. 卷积神经网络(CNN)的类型 以下是一些不同类型的CNN: 1D CNN:1D CNN 的输入和输出数据是二维的.一维CNN大多用于时间序列. 2D CNNN:2D CNN的输入和输出数据是三维的.我们通常将其用于图像数据问题. 3D CNNN:3D CNN的输入和输出数

  • Python深度学习理解pytorch神经网络批量归一化

    目录 训练深层网络 为什么要批量归一化层呢? 批量归一化层 全连接层 卷积层 预测过程中的批量归一化 使用批量归一化层的LeNet 简明实现 争议 训练深层神经网络是十分困难的,特别是在较短的实践内使他们收敛更加棘手.在本节中,我们将介绍批量归一化(batch normalization),这是一种流行且有效的技术,可持续加速深层网络的收敛速度.在结合之后将介绍的残差快,批量归一化使得研究人员能够训练100层以上的网络. 训练深层网络 为什么要批量归一化层呢? 让我们回顾一下训练神经网络时出现的

  • Python深度学习pytorch神经网络图像卷积运算详解

    目录 互相关运算 卷积层 特征映射 由于卷积神经网络的设计是用于探索图像数据,本节我们将以图像为例. 互相关运算 严格来说,卷积层是个错误的叫法,因为它所表达的运算其实是互相关运算(cross-correlation),而不是卷积运算.在卷积层中,输入张量和核张量通过互相关运算产生输出张量. 首先,我们暂时忽略通道(第三维)这一情况,看看如何处理二维图像数据和隐藏表示.下图中,输入是高度为3.宽度为3的二维张量(即形状为 3 × 3 3\times3 3×3).卷积核的高度和宽度都是2. 注意,

随机推荐