zoukankan      html  css  js  c++  java
  • TensorFlow Estimator实战

    TensorFlow Estimator

    1.泰坦尼克号示例:

    • 导包

      import matplotlib as mpl
      import matplotlib.pyplot as plt
      %matplotlib inline
      import numpy as np
      import sklearn
      import pandas as pd
      import os
      import sys
      import time
      import tensorflow as tf
      from tensorflow import keras
      # 打印版本
      print(tf.__version__)
      print(sys.version_info)
      for module in mpl,np,pd,sklearn,tf,keras:
          print(module.__name__, module.__version__)
      
    • 准备训练集和验证集数据

      train_file = "./data/train.csv"
      eval_file = "./data/eval.csv"
      # pandas读取csv数据
      train_df = pd.read_csv(train_file)
      eval_df = pd.read_csv(eval_file)
      print(train_df.head())
      print(eval_df.head())
      
    • 取出训练集,验证集特征值,survived为获救数

      # 取出训练集特征值:
      y_train = train_df.pop("survived")
      # 取出验证集特征值
      y_eval = eval_df.pop("survived")
      # 取出前5条数据看看
      print(train_df.head())
      print(eval_df.head())
      
    • 训练集统计

      # 训练结果统计量:数据量,均值 方差,最小值,最大值,25%,50%,75%,100%中位数
      train_df.describe()
      
    • 行数,列数打印

      # 行数,列数
      print(train_df.shape, eval_df.shape)
      # (627, 9) (264, 9)
      
    • 取出年龄,查看年龄分布 bins直方图分布份数

      # 取出年龄,查看年龄分布  bins直方图分布份数
      train_df.age.hist(bins=30)
      

    • 查看男性女性人数

      # 查看男性女性人数
      train_df.sex.value_counts().plot(kind="barh")
      

    • 查看仓位等级

      # 查看class等级
      train_df["class"].value_counts().plot(kind="barh")
      

    • 查看男,女有多少获救了

      # 查看男,女有多少获救了
      pd.concat([train_df, y_train],axis=1).groupby("sex").survived.mean().plot(kind="barh")
      

    • 离散型特征

      # 1.离散型特征: 特点有固定值
      # sex   性别
      # n_siblings_spouses  亲戚个数
      # parch  父母孩子是否在船上
      # class 仓位
      # embark_town 出发港口
      # deck  卧仓
      # alone 是否独自一人
      cate_gorical_columns = ["sex", "n_siblings_spouses","parch","class","deck", "embark_town", "alone"]
      
    • 连续特征

      # 2.连续特征
      # age 年龄
      # fare 票价
      numeric_columns = ["age", "fare"]
      
    • 离散特征处理

      # 离散特征处理
      feature_columns = []
      for categorical_column in cate_gorical_columns:
          # 获取所有离散特征值数据
          vocab = train_df[categorical_column].unique()
          print(categorical_column,vocab)
          # tf.feature_column.actegorical_column_with_vocabulary_list 将其定义成为feature_column
          # tf.feature_column.indicator_column 进行one-hot编码
          item = tf.feature_column.indicator_column(
              tf.feature_column.categorical_column_with_vocabulary_list(
          categorical_column, vocab))
          # 加入列表
          feature_columns.append(item)
          
      
    • 连续特征处理

      # 连续特征处理
      for categorical_column in numeric_columns:
          feature_columns.append(
              tf.feature_column.numeric_column(categorical_column, dtype=tf.float32)
          )
      
    • 构建dataset

      # 构建dataset 
      def make_dataset(data_df, label_df, epochs=10,shuffle=True,batch_size=32):
          """
          data_df  x
          label_df   y
          epochs  数据集遍历次数
          shuffle 是否需要混排
          batch_size
          """
          # Dataset 可以接收字典类型数据
          dataset = tf.data.Dataset.from_tensor_slices(
          (dict(data_df), label_df))
          # 打乱顺讯
          if shuffle:
              dataset = dataset.shuffle(10000)
          # repeat + batch
          dataset = dataset.repeat(epochs).batch(batch_size)
          return dataset
      train_dataset = make_dataset(train_df, y_train, batch_size=5)
      
    • 演示:使用keras.layers.DenseFeature 将 feature_columns应用在dadaset上

      # 演示:使用keras.layers.DenseFeature 将 feature_columns应用在dadaset上
      for x,y in train_dataset.take(1):
          # 
          age_column = feature_columns[7]
          gender_column = feature_columns[0]
          # age没有发生变化 因为是数值,保留原有密集特征
          print(keras.layers.DenseFeatures(age_column)(x).numpy())
          #  因性别是分为['male' 'female'], 不是数值, 它会进行one-hot编码变换
          print(keras.layers.DenseFeatures(gender_column)(x).numpy())
      
    • 模型构建

      # keras模型构建
      model = keras.models.Sequential([
          keras.layers.DenseFeatures(feature_columns),# 使用keras.layers.DenseFeature 将 feature_columns应用在dadaset上
          keras.layers.Dense(100, activation="relu"),#全连接层
          keras.layers.Dense(100, activation="relu"),#全连接层
          keras.layers.Dense(2, activation="softmax"),# 输出层
      ])
      
      model.compile(
          loss="sparse_categorical_crossentropy",
          optimizer = keras.optimizers.SGD(lr=0.01),
          metrics=["accuracy"],
      )
      
      
    • 训练模型:

      • 方式1
      # 1.训练模型
      # 方式1:
      train_dataset = make_dataset(train_df, y_train,epochs=100)
      eval_dataset = make_dataset(eval_df, y_eval, epochs=1, shuffle=False)
      # steps_per_epoch=627//32 627为训练集样本数, 32为batch_size 设置偏大会导致训练到后面数据不充足,训练失败
      # validation_steps=264//32 264为验证集样本数, 32为batch_size
      history = model.fit(
          train_dataset, 
          validation_data = eval_dataset, 
          steps_per_epoch=627//32, 
          validation_steps=264//32,
          epochs = 100
      )
      
      
      • 方式2:estimator
      # estimator 方式进行训练
      estimator = keras.estimator.model_to_estimator(model)
      # input_fn是一个函数或lambda匿名函数,返回值必须是:(features, labels)的元组 或 dataset->(feature,label)
      estimator.train(input_fn= lambda : make_dataset(train_df, y_train, epochs=100))
      
      
    • tf.estimator.BaselineClassifier

      # estimator进行训练
      output_dir = "baseline_model"
      if not os.path.exists(output_dir):
          os.mkdir(output_dir)
      #  tf.estimator.BaselineClassifier 2.0之后报错
      baseline_estimator = tf.compat.v1.estimator.BaselineClassifier(
          model_dir = output_dir,n_classes = 2)
      baseline_estimator.train(input_fn = lambda: make_dataset(
          train_df, y_train,epochs=100))
      # 验证
      baseline_estimator.evaluate(input_fn=lambda: make_dataset(
          eval_df,y_eval, epochs=1, shuffle=False, batch_size=20))
      """
      {'accuracy': 0.625,
       'accuracy_baseline': 0.625,
       'auc': 0.5,
       'auc_precision_recall': 0.6875,
       'average_loss': 0.66191846,
       'label/mean': 0.375,
       'loss': 12.481891,
       'precision': 0.0,
       'prediction/mean': 0.38796115,
       'recall': 0.0,
       'global_step': 3920}
      """
      
    • tf.LinearClassifier

      linear_output_dir = "linear_model"
      if not os.path.exists(linear_output_dir):
          os.mkdir(linear_output_dir)
      linear_estimator = tf.compat.v1.estimator.LinearClassifier(
          model_dir=linear_output_dir, n_classes=2, feature_columns=feature_columns)
      linear_estimator.train(input_fn = lambda:make_dataset(
          train_df, y_train, epochs=100))
      # 它不会像tf.keras打印输出训练情况,而是生成tensorborad 文件,里面记载训练情况
      
      # 验证
      linear_estimator.evaluate(input_fn=lambda: make_dataset(
          eval_df,y_eval, epochs=1, shuffle=False))
      """
      {'accuracy': 0.780303,
       'accuracy_baseline': 0.625,
       'auc': 0.83673096,
       'auc_precision_recall': 0.7801561,
       'average_loss': 0.4695529,
       'label/mean': 0.375,
       'loss': 13.773552,
       'precision': 0.69902915,
       'prediction/mean': 0.40130255,
       'recall': 0.72727275,
       'global_step': 3920}
      """
      
    • tf.DNNClassifier

      dnn_output_dir = "./dnn_model"
      if not os.path.exists(dnn_output_dir):
          os.mkdir(dnn_output_dir)
      # hidden_units需要定义每一层和每一层单元数  这里定义2层
      # activation_fn 激活函数
      # optimizer 优化器
      dnn_estimator = tf.compat.v1.estimator.DNNClassifier(
          model_dir=dnn_output_dir, 
          n_classes=2, 
          feature_columns=feature_columns,
          hidden_units=[128,128],
          activation_fn=tf.nn.relu,
          optimizer = "Adam"
      )
      # 训练
      dnn_estimator.train(input_fn = lambda:make_dataset(
          train_df, y_train, epochs=100))
      # 验证
      dnn_estimator.evaluate(input_fn=lambda: make_dataset(
          eval_df,y_eval, epochs=1, shuffle=False))
      """
      {'accuracy': 0.79545456,
       'accuracy_baseline': 0.625,
       'auc': 0.8303337,
       'auc_precision_recall': 0.81163746,
       'average_loss': 0.47359046,
       'label/mean': 0.375,
       'loss': 13.891987,
       'precision': 0.8,
       'prediction/mean': 0.33048365,
       'recall': 0.6060606,
       'global_step': 3920}
      """
      
    • 可以看到DNNClassifier比LinearClassifier 后期loss值要小,训练效果要好

    2.交叉特征(cross feature)使用

    • 对两个离散特征做笛卡尔积,比如上述age 有5个值, gender有2个值,进行笛卡尔积后会生成10个特征。

      # hash_bucket_size 当数据量特别大比如有10万个数据,全都加载模型数据量特别大,而 hash_bucket_size=100
      # 我们把 10万个值与100 进行hash,会分配到100个桶里,这样把10万个值分到100个桶中
      # 减少模型的size,因为这10万个值是稀疏的矩阵,一些位置值可以进行重用。
      
      # 转换 indicator_column 才能在 DNNClassifier比LinearClassifier 中使用
      
      feature_columns.append(
          tf.feature_column.indicator_column(
          tf.feature_column.crossed_column(["age","sex"], hash_bucket_size=100)
          )
      )
      
    • 再进行BaselineClassifier,DNNClassifier,LinearClassifier进行训练查看...

  • 相关阅读:
    SpringMVC---RequestMapping注解类的使用方法
    SpringMVC---简单登录例子
    SpringMVC---简介
    MyBatis---动态SQL
    Hive基本操作
    hive初识
    scala编码规范
    Spark2.x 与 Spark1.x 关系
    spark idea项目打jar包的两种方式
    SparkStreaming 对Window的reduce的方法解析(转载)
  • 原文地址:https://www.cnblogs.com/xujunkai/p/14375537.html
Copyright © 2011-2022 走看看