通过 TensorFlow 对鸢尾花进行分类
鸢尾花有300多种类别,主要分为三个大类分别为:
- Iris setosa
- Iris virginica
- Iris versicolor
模块导入
from __future__ import absolute_import, division, print_function, unicode_literals
import os
import matplotlib.pyplot as plt
import tensorflow as tf
训练数据下载
使用tf.keras.utils.get_file函数下载训练数据集文件。 这将返回下载文件的文件路径。
rain_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('下载数据至:', train_dataset_fp)
查看数据
使用head -n5命令查看数据
!head -n5 {train_dataset_fp}
column_names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’]
获取特征和标签名
feature_name = column_names[:-1]
label_name = column_names[-1]
创建ensorFlow的数据集
batch_size=32
train_dataset = tf.data.experimental.make_csv_dataset(
train_dataset_fp,
batch_size,
column_names=column_names,
label_name=label_name,
num_epochs=1
)
features, labels = next(iter(train_dataset)) print(features)
数据可视化
plt.scatter(features['petal_length'],
features['sepal_length'],
c=labels,
cmap='viridis')
plt.xlabel("Petal length")
plt.ylabel("Sepal length")
plt.show()
def pack_features_vector(features, labels):
features = tf.stack(list(features.values()), axis=1)
return features, labels
使用tf.data.Dataset.map将重构函数运用到每条数据中。
train_dataset = train_dataset.map(pack_features_vector)
features, labels = next(iter(train_dataset))
print(features[:5])
使用Keras创建模型
# 构建线性模型
model = tf.keras.Sequential([
tf.keras.layers.Dense(10, activation='relu',input_shape=(4,)),
tf.keras.layers.Dense(10, activation='relu'),
tf.keras.layers.Dense(3)
])
测试模型结构
prediction = model(features) prediction[:5]
多分类任务需要使用softmax进行归一化
tf.nn.softmax(prediction)[:5]
使用tf.argmax获取概率最大的类标签
print('prediction:', tf.argmax(prediction, axis=1))
print('label:', labels)
创建训练模型
# 损失函数*
loss_object=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
使用tf.GradientTape计算loss对所有变量的梯度
def grad(model, inputs, targets):
with tf.GradientTape() as tape:
loss_value = loss(model, inputs, targets)
return loss_value, tape.gradient(loss_value, model.trainable_variables)
创建优化器
optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)
# 使用优化器
loss_value, grads = grad(model, features, labels)
print('步数:{}, 初始loss值:{}'.format(optimizer.iterations.numpy(),loss_value.numpy()))
optimizer.apply_gradients(zip(grads, model.trainable_variables))
print('步数:{}, loss值:{}'.format(optimizer.iterations.numpy(),loss(model,features, labels).numpy()))
训练循环
# 保存loss和acc
train_loss_results=[]
train_accuracy_results=[]
num_epochs =201
for epoch in range(num_epochs):
# 用于记录loss和acc的类
epoch_loss_avg = tf.keras.metrics.Mean()
epoch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
# 训练循环
for x, y in train_dataset:
# 获取loss和梯度
loss_value, grads = grad(model, x, y)
# 梯度优化
optimizer.apply_gradients(zip(grads, model.trainable_variables))
# 记录loss均值
epoch_loss_avg(loss_value)
# 记录准确率
epoch_accuracy(y, model(x))
# 保存每个epoch的loss和acc
train_loss_results.append(epoch_loss_avg.result())
train_accuracy_results.append(epoch_accuracy.result())
if epoch % 50 == 0:
print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch,
epoch_loss_avg.result(),
epoch_accuracy.result()))
可视化训练过程
fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))
fig.suptitle('Training Metrics')
axes[0].set_ylabel("Loss", fontsize=14)
axes[0].plot(train_loss_results)
axes[1].set_ylabel("Accuracy", fontsize=14)
axes[1].set_xlabel("Epoch", fontsize=14)
axes[1].plot(train_accuracy_results)
plt.show()
评估模型
test_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv"
test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url),
origin=test_url)
test_dataset = tf.data.experimental.make_csv_dataset(
test_fp,
batch_size,
column_names=column_names,
label_name='species',
num_epochs=1,
shuffle=False)
test_dataset = test_dataset.map(pack_features_vector)
# 准确率统计类
test_accuracy = tf.keras.metrics.Accuracy()
for (x,y) in test_dataset:
logits = model(x)
prediction = tf.argmax(logits, axis=1, output_type=tf.int32)
test_accuracy(prediction, y)
print('测试集准确率:', test_accuracy.result())
结果对比
tf.stack([y, prediction], axis=1)
使用训练的模型进行预测
predict_dataset = tf.convert_to_tensor([
[5.1, 3.3, 1.7, 0.5,],
[5.9, 3.0, 4.2, 1.5,],
[6.9, 3.1, 5.4, 2.1]
])
predictions = model(predict_dataset)
for i, logits in enumerate(predictions):
class_idx = tf.argmax(logits).numpy()
p = tf.nn.softmax(logits)[class_idx]
name = class_names[class_idx]
print("Example {} prediction: {} ({:4.1f}%)".format(i, name, 100*p))