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进行训练查看...

  • 相关阅读:
    AcWing 157. 树形地铁系统 (hash判断树同构)打卡
    AcWing 156. 矩阵 (哈希二维转一维查询)打卡
    AcWing 144. 最长异或值路径 01字典树打卡
    AcWing 143. 最大异或对 01字典树打卡
    AcWing 142. 前缀统计 字典树打卡
    AcWing 139. 回文子串的最大长度 hash打卡
    AcWing 138. 兔子与兔子 hash打卡
    常用C库函数功能及用法
    编程实现C库函数
    C语言面试题5
  • 原文地址:https://www.cnblogs.com/xujunkai/p/14375537.html
Copyright © 2011-2022 走看看