纯净、安全、绿色的下载网站

首页

当前位置:首页IT学院IT技术

机器学习-TensorFlow建模过程 Linear Regression线性拟合应用

HappyPuppy   2020-01-29 我要评论

TensorFlow是咱们机器学习领域非常常用的一个组件它在数据处理模型建立模型验证等等关于机器学习方面的领域都有很好的表现前面的一节我已经简单介绍了一下TensorFlow里面基础的数据结构即:Tensor和Dataset 这里咱们开始介绍TensorFlow的建模过程以及验证模型的一些简单方法其实无论是sklearn还是TensorFlow他们的模型建立过程都是相似的都是经历columns类型声明模型定义数据训练validation等等几个步骤前面的几节内容我已经简单的介绍了如何用sklearn建立tree_based模型这里我主要是想演示TensorFlow的应用所以我就用linear regressor来当做例子来演示TensorFlow是如何从数据加载一直到数据验证的阶段至于线性拟合的实现的具体细节我在下一节的内容会从数学的角度具体解释的本节内容所使用的数据都是来自于网络中大家可以忽略具体的数据的意思主要的了解TensorFlow的应用过程不必过于纠结于模型的细节部分模型的细节我会在随后的章节解释好了那么咱们现在开始吧

第一步:数据准备

顾名思义就是咱们准备数据的过程这里包括有missing value handling categorical data encodingdata split data permutation等等内容这一步咱们要将咱们将来模型训练所用到的数据都能准备好这个准备过程无非也就是上面的这些步骤咱们可以看下面的代码演示

cali_housing_dataset_original = pd.read_csv("https:/https://p.download-x.com/download.mlcc.google.com/mledu-datasets/california_housing_train.csv")
cali_housing_dataset_original["median_house_value"] /= 1000.0
#create a random generator
generator = np.random.Generator(np.random.PCG64())
#permutate the data frame
cali_housing_dataset_permutation = cali_housing_dataset_original.reindex(
        generator.permutation(cali_housing_dataset_original.index)
        )
cali_housing_dataset_permutation.describe()

#select the features that we will use in the model trainning process
my_feature = cali_housing_dataset_permutation[["total_rooms"]]
#select the targets of the dataset
targets = cali_housing_dataset_permutation[["median_house_value"]]

这里我就不演示那些feature engineering的过程那些内容太多大家可以看我之前的博客这里主要是想向大家演示一下permutation的过程因为最新的numpy对于randomize的过程已经有更新了不再使用的那些老的API了numpy中最新的randomize的过程是通过创建2个generator来实现随机过程和随机数的生成了这两个generator一个个是bit generator, 就如咱们上面代码中的PCG64(), 它能产生一个随机的bit stream, 根据numpy的官方文档虽然有很多种bit generator但是PCG64是最稳定的一种另外一个就是Generator, 它是通过np.random.Generator()函数来实例化一个对象的它能将bit generator产生的bit stream转化成数字这里的数据咱们就选择一个最最简单的linear regression的方式那就是只选择一个feature那就是total_rooms; 咱们的target是median_house_value

第二步:定义feature 类型 和 optimizer

 既然咱们的数据都准备好了那么之后那么得定义一下咱们数据的类型(每一个column的类型都得定义)将来在咱们定义模型的时候咱们也得将columns的信息传递给咱们的模型对象以及用什么optimizer将来来训练咱们的模型这个optimizer将来也得传递给咱们的模型对象 具体optimizer是什么我下面会慢慢讲的为了方便演示还是先上代码给大家看

#indicates what is the data type of the feature to tensorflow
feature_columns = [tf.feature_column.numeric_column("total_rooms")]
#using stochastic gradient descent as the optimizer for our model #to ensure the magtitute of gradient do not become too large, we apply clipping_norm to our optimizer my_optimizer = tf.optimizers.SGD(learning_rate = 0.0000001, clipnorm=5.0)

从上面的代码可以看出第一句是声明咱们feature_columns里面只有一个numeric_column记住每一个column都有一个feature_column对象这里因为咱们只选取了一个feature是total_rooms所以咱们这里就一个tf.feature_column对象这里的第二行代码是咱们的重点也是以后优化模型中经常要调整的部分这里咱们可以看出这里的optimizer是一个SGD SGD是stochastic gradient descent的缩写就是每一次计算咱们的gradient descent的时候咱们只选取一组数据进行计算如果每一次计算gradient descent的时候咱们都用整个数据进行计算那么咱们的计算机是负担不起的消耗的存储空间和计算能力都太大了因为在实际中咱们的数据集的数量经常都是以万为单位的具体计算gradient descent的过程我会在下一节中讲述模型训练过程中演示的咱们可以看出来SGD中还有两个参数分别是learning_rate和clipnorm, 咱们知道当我们在训练我们的模型的时候我们需要逐步的训练很多次知道咱们的gradient descent趋于0是才停止咱们的每一步的大小都要合理如果learning_rate太小咱们训练的步数就会太多影响咱们的效率如果learning_rate太大则可能导致咱们训练模型的过程不能converge就是永远找不到那个最小值从而导致训练的模型失败为了防止咱们咱们的gradient太大我们这里不单单用learning_rate来限制咱们还加了一个clipnorm来限制咱们的gradient magtitute大小防止咱们fail to converge, 这相当于一个双重保险

第三步:定义一个模型model

将上面的参数都定义完成后咱们就得定义一下咱们的模型啦TensorFlow提供了大量的模型可供使用几乎所有主流的机器学习的模型和深度学习相关的模型TensorFlow几乎实现全覆盖了具体咱们可以去他的官网查询, 他的官网地址是:https://www.tensorflow.org/api_docs/python/tf  记住在TensorFlow中他的模型都在tf.estimator这个模块中因为这里是咱们讲述用TensorFlow开发机器学习应用的入门咱们就选一个最简单的模型linear regressor模型来演示

linear_regressor = tf.estimator.LinearRegressor(
        feature_columns = feature_columns,
        optimizer = my_optimizer
        )

这里咱们可以看出是如何初始化一个LinearRegressor对象的同样的咱们可以看出来它初始化的时候也是需要传递feature_columns和optimizer这2个参数的而这两个参数正是咱们第二步中所初始化的可以说是环环相扣啊哈哈也可以看出咱们前面定义初始化的一个对象都是没有多余的都是要用到的这两个参数分别告诉了咱们的模型咱们数据columns的类型以及用什么optimizer来训练这2个信息

第四步:数据源input_fn

既然咱们的原始数据准备好了模型也都定义好了如果需要训练咱们的模型咱们还差什么呢?对了就是将咱们的原始数据(这里的例子是dataframe)转化成TensorFlow中的dataset并将转化后的data传递给咱们的模型让咱们之前定义的模型用这些数据去训练这里应该也是咱们用TensorFlow来建模的一个核心部分了咱们先看代码演示然后我会逐个详细解释的

def my_input(features, targets, batch_size=500, shuffle=True, num_epochs=None):
    
    """
    epochs: while trainning, in the case of steps is larger than the length of dataset, we set the epochs to None, which means repeat forever. However,
    in trainning process, we have the steps to control the total number of iterations.  While in the case of making predictions of a given dataset, we must
    set epochs to 1 and shuffle to False. Because we only want the input function return the dataset once, otherwise the function will keep returnning the 
    results forvere once and once again.
    
    shuffle: in the trainning process, in order to balance the dataset, we set it to True. However while in prediction process, we have to set it to False, which
    could help us to evaluate the outputs. For example, if the outputs are shuffled, we have no way to compare the outputs to our original lables.
    
    """
    
    #convert panda dataframe to a dict of Numpy array
    features = {key:tf.multiply(np.array(value),1) for key,value in dict(features).items()}
    #construct a dataset
    ds = tf.data.Dataset.from_tensor_slices((features,targets))
    ds = ds.batch(batch_size).repeat(num_epochs)
    
    if shuffle:
        ds = ds.shuffle(buffer_size = 10000)    
    return ds

这里有几个核心的参数我需要解释一下首先features和target两个参数很明显就是咱们第一步中获取的数据分别是用来训练这个模型的特征变量和label重点这里解释一下batch_size, shuffle 和 num_epochs这三个参数这三个参数在咱们TensorFlow的整个学习过程中都得用到绝对的重点不容怀疑首先咱们来看batch_size, 因为SGD每一次都只会选用一条数据来计算咱们的gradient(训练模型)而咱们的数据具有很强的随机性那么就会导致咱们的模型最后很可能不可用但是如果咱们每一个step都选用整个dataset来训练模型又会导致咱们的训练过程非常漫长那么聪明的人类就自然而然的想到了咱们可以每一次选用一定数量的数据来训练模型一般的数据量咱们大致的范围都是在10-10000之间这种方式就成为mini-batch SGD, 在这里咱们就是采用了这种方式咱们每一次选用500条数据来训练咱们的模型这是通过设置batch_size的值来实现的对于shuffle这个参数呢也是为了打乱咱们的数据来进行训练最终的目的也是为了能帮助咱们训练出更加精确的模型防止咱们的数据分布不合理导致模型有偏差它里面的buffer_size的意思是先从ds中选中buffer_size个数据(这些数据暂时还是有序的顺序和ds中一样)然后iterate的时候呢就从这个buffer中随机的选择数据(这个选择数据的过程就是无序的选择了实现了随机的目的)最后还有这个repeat(num_epochs)的函数首先repeat函数在training的过程中一定需要的因为当咱们设置steps步数参数的时候如果steps的总数要多余整个dataset的数据量的时候那么这时候咱们一定得重复利用咱们的dataset来达到训练的目的否则咱们的数据源的数据量不够了会出错的这就是为什么需要repeat的原因至于num_epochs是来控制重复的次数的一般在training阶段咱们将它设置成None, 意思就是无限循环知道training中的steps全部走完位置如果在predict阶段咱们一般就设置成1因为咱们验证阶段不需要重复的同样的在predict的时候数据源函数中的shuffle也要设置成False的否则predict的结果都是乱序的无法跟原来的数据进行对比了前面几个参数在咱们模型训练过程中可以说是最重要的参数了这里说的也比较多所以一点得用心搞明白

第五步:训练模型 training

既然上面咱们把模型的参数都设置好了数据源也定义好了那么接下来咱们的任务就是训练咱们定义的模型了这个过程在代码中是很简单的但它内部做的工作是很多的它需要计算在每个维度(feature)上的gradient descent知道它趋于0为止它的计算细节我会在接下来的一个章节中展示出来咱们先看代码

linear_regressor.train(
        input_fn = lambda:my_input(my_feature, targets),
        steps = 1000
        )

是不是很简单咱们只需要将数据源函数作为参数传递给他并且设置一个steps就可以了这里input_fn我就不解释了简单说一下stepssteps指的是咱们训练的步数咱们每计算一次gradient descent就算一步这里指咱们最多计算1000次即使1000的时候gradient descent不等于0咱也停止咱的训练过程然后咱们可以重新设置optimizer中的learning_rate来重新训练

第六步:predict和evaluate

经过前面五步后咱们已经训练出来了一个模型那么接下来咱们需要用这个模型来预测一下数据并且看看它的效果去evaluate一下这个模型正常的情况下咱们会将数据split成training data 和 validation data这里我为了方便咱就直接用training data来演示如何predict还有如何evaluate咱们的模型简单的代码如下

#create a input function for prediction
prediction_input_fn = lambda:my_input(my_feature,targets,shuffle=False,num_epochs=1)
#prediction
predictions = linear_regressor.predict(input_fn = prediction_input_fn)
predictions = np.array([item["predictions"][0] for item in predictions])

#errors MSE
mean_squared_error(targets,predictions)

在咱们做prediction的时候咱们也是需要数据源input_fn的在prediction的时候shuffle=False, num_epochs=1; 然后调用这个模型linear_regressor的predict方法将数据源函数传递给他 它返回的结果是一个list这个list里面的element是一个dictionary这个dictionary的key值“predictions”, value也是一个一个list并且只有一个元素element此element就是咱们要的结果最后咱们要evaluate这个模型预测的结果咱们有很多种方式可以验证这里只展示了一个最简单的方式就是计算咱们的target和prediction的方差其实有很多很多种方式在后面的章节我会慢慢介绍

第七步:data visualization

好了最后咱们来看一下根据咱们的学习的模型咱们想看看它的具体的拟合的效果这里就需要用一点之前咱们学习的数据可视化的内容了这里比较简单咱们通过模型学习到的参数画一条拟合线然后在将数据画到画布上坐标分别是"total_rooms"和"house_median_price",然后通过scatter plot展示出来代码如下

sample = cali_housing_dataset_permutation.sample(n=300)
x_0 = sample["total_rooms"].min()
x_1 = sample["total_rooms"].max()
linear_regressor.get_variable_names()#retrieve the name of the variable
weights = linear_regressor.get_variable_value("linear/linear_model/total_rooms/weights")[0]#returns the value of variable given by name
bias = linear_regressor.get_variable_value("linear/linear_model/bias_weights")#retruns the value of bias
y_0 = weights*x_0+bias
y_1 = weights*x_1+bias
plt.plot([x_0,x_1],[y_0,y_1])#plot our regression line
plt.ylabel("median_house_value")#label the y Axes
plt.xlabel("total_rooms")#label the x Axes
plt.scatter(sample["total_rooms"],sample["median_house_value"])#plot a scatter plot from the sample
plt.show()

结果如下

 

 可以看得出来拟合的还不错嘿嘿关于模型训练过程的可视化后面还有很多种以后我慢慢说例如:x坐标是steps, y坐标是loss, 也是非常常见的一种方式

总结

今天完整的展示了用TensorFlow创建模型的整个过程一直从data preparation到最后的evaluation可以说贯穿了TensorFlow开发机器学习应用的整个过程今天先用一个最简单的线性拟合例子展示这个过程后面我还会展示更多的更加复杂的模型例如:Logistic Regression, DNN, LSTM等等等等但是万变不离其宗他们的基础步骤都是上面的七个步骤最后 祝武汉加油!!!!!!!!


相关文章

网友评论

Copyright 2022 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们