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进行训练查看...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库