机器学习实践—鸢尾花数据集
鸢尾花的分类——TensorFlow下的实验
导入和解析数据集
-
下载数据集
tf.keras.utils.get_file
函数下载训练数据及文件,并返回下载文件的文件路径:train_dataset_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv" #下载路径 train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url), origin=train_dataset_url) #文件保存路径 print("本地文件路径: {}".format(train_dataset_fp))
-
检查数据
!head -n5 {train_dataset_fp}
函数提取样本基本信息。- 第一行是表头,有数据集数量,label种类。
- 后面几行是样本,含有数据特征信息和一个标签名称。
120,4,setosa,versicolor,virginica 6.4,2.8,5.6,2.2,2 5.0,2.3,3.3,1.0,1 4.9,2.5,4.5,1.7,2 4.9,3.1,1.5,0.1,0
-
将数据用
python
列表存储下来根据之前
head
查看到的数据格式,分别创建feature_name, label_name, class_names
列表# column order in CSV file column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'] #包含feature和label的值 feature_names = column_names[:-1] label_name = column_names[:-1]
-
创建一个
tf.data.Dataset
-
TF的
dataset API
可以处理在向模型加载数据时遇到的各种常见情况,是一种高阶API
-
由于数据集是
CSV
文件,我们要通过make_csv_dataset
将其变为适合训练模型使用的数据形式这里
feature
字典的意思是说,我们对一个feature
来说,这个字典内包含了所有样本的对应该feature
的值,这样显然不利于我们构建模型。我们要的是对一个样本来说,将它的所有
feature
按序保存在一个数组里,并且每个样本feature
数组与一个label
对应。
""""make_csv_dataset返回一个(features, label)对, 其中features是一个字典:{'feature_name': value}""" ---> train_dataset = tf.data.experimental.make_csv_dataset( train_dataset_fp, batch_size, column_names=column_names, label_name=label_name, num_epochs=1, ) ---> print(features) print(labels) ---> #具有相同特征的样本被分到了同一个字典内,不利于我们构建模型 OrderedDict([('sepal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy= array([5.1, 6.8, 5. , 5.6, 5. , 5.7, 5. , 5.4, 4.9, 5.5, 4.6, 5. , 6.4, 5. , 6.2, 6.7, 6. , 6.1, 6. , 5.8, 6.3, 7.7, 6.6, 5.1, 4.6, 4.8, 6.4, 6.4, 5.7, 5.8, 6.8, 5.2], dtype=float32)>), ('sepal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy= array([3.8, 3.2, 3.5, 2.5, 3.6, 2.9, 3.4, 3.9, 3. , 2.6, 3.2, 3. , 3.2, 3.5, 3.4, 3.3, 3. , 2.9, 2.2, 4. , 3.3, 3. , 2.9, 3.8, 3.6, 3. , 2.8, 2.7, 4.4, 2.7, 3. , 3.5], dtype=float32)>), ('petal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy= array([1.5, 5.9, 1.6, 3.9, 1.4, 4.2, 1.6, 1.3, 1.4, 4.4, 1.4, 1.6, 4.5, 1.3, 5.4, 5.7, 4.8, 4.7, 5. , 1.2, 6. , 6.1, 4.6, 1.9, 1. , 1.4, 5.6, 5.3, 1.5, 5.1, 5.5, 1.5], dtype=float32)>), ('petal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy= array([0.3, 2.3, 0.6, 1.1, 0.2, 1.3, 0.4, 0.4, 0.2, 1.2, 0.2, 0.2, 1.5, 0.3, 2.3, 2.1, 1.8, 1.4, 1.5, 0.2, 2.5, 2.3, 1.3, 0.4, 0.2, 0.1, 2.2, 1.9, 0.4, 1.9, 2.1, 0.2], dtype=float32)>)]) tf.Tensor([0 2 0 1 0 1 0 0 0 1 0 0 1 0 2 2 2 1 2 0 2 2 1 0 0 0 2 2 0 2 2 0], shape=(32,), dtype=int32)
-
将该
feature
字典转换格式为(feature, label)
形式的数组#调用tf.stack方法,从张量列表中获取值,并创建指定维度的组合张量 ---> def pack_features_vector(features, labels): """Pack the features into a single array.""" features = tf.stack(list(features.values()), axis=1) return features, labels ---> #调用map方法,将每个 (features,label) 对中的 features 打包到训练数据集中: ---> train_dataset = train_dataset.map(pack_features_vector) features, labels = next(iter(train_dataset)) print(features[0:len(features)]) ---> tf.Tensor( [[6.7 3.1 4.4 1.4] [5.6 2.9 3.6 1.3] [6. 2.2 5. 1.5] [6.1 3. 4.9 1.8] ......
至此我们的解析数据工作完成。
-
关于
Dataset
中的参数batch_size
:对于一个有 2000 个训练样本的数据集。将 2000 个样本分成大小为 500 的batch
,那么完成一个epoch
需要 4 个iteration
。
-
构建模型与训练
-
模型类型
- 使用
keras
创建模型 - 在模型最后一层使用
softmax
操作子
-
训练模型构建
-
定义损失函数和梯度函数
#损失函数 loss_object = tf.keras.losses.XXX #定义梯度函数从而计算梯度来优化模型 def grad(model, inputs, targets): with tf.GradientTape() as tape: loss_value = loss(model, inputs, targets, training=True) return loss_value, tape.gradient(loss_value, model.trainable_variables)
-
创建优化器
由于神经网络参数数量极大,结构复杂,传统的
gradient desent
由于要遍历整个数据集,因此不适用于神经网络的额参数学习,相似的有随机梯度下降。优化器会将计算出的梯度应用于模型的变量,以使
loss
函数最小化。我们可以用优化器来优化我们的每一步
-
-
模型训练循环
- 迭代每个周期。通过一次数据集即为一个周期。其中
epoch
是遍历数据集合的次数。 - 在一个周期中,遍历训练 Dataset 中的每个样本,并获取样本的特征
(x)
和标签(y)
。 - 根据样本的特征进行预测,并比较预测结果和标签。衡量预测结果的不准确性,并使用所得的值计算模型的损失和梯度。
- 使用
optimizer
更新模型的变量。 - 跟踪一些统计信息以进行可视化。
- 对每个周期重复执行以上步骤。
- 迭代每个周期。通过一次数据集即为一个周期。其中
-
可视化损失函数随时间推移而变化的情况
TensorBoard
是与TensorFlow
封装在一起的出色可视化工具,不过我们可以使用matplotlib
模块创建基本图表。
评估模型的效果
-
建立测试数据集
按照与下载训练集相同的方法,将测试集的数据转变为向量形式即可。
-
根据测试数据集评估模型
我们会遍历测试集中的每个样本,然后将模型的预测结果与实际标签进行比较。