[機器學習]利用TensorFlow訓練一個簡單的神經網路
利用TensorFlow訓練一個簡單的神經網路
我們在這裡利用TensorFlow的Eager Execution 來構建模型,這樣不用像以前一樣建立Graph和Session了,可以使神經網路的訓練更加方便快捷,下面以Iris資料集為例來訓練一個神經網路,程式碼來自谷歌的教程。
#先匯入相關的庫
from __future__ import absolute_import,division,print_function
import os
import matplotlib.pyplot as plt
import tensorflow as tf
import tensorflow.contrib.eager as tfe
tf.enable_eager_execution() #採用eager_execution
#檢視版本資訊並檢查採用eager_execution是否開啟
print('TensorFlow Version:{}'.format(tf.VERSION))
print('Eager execution:{}'.format(tf.executing_eagerly()))
TensorFlow Version:1.8.0
Eager execution:True
#獲取資料集並顯示在本地的儲存位置
train_dataset_url='http://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('Local copy of the dataset file:{}'.format(train_dataset_fp))
Downloading data from http://download.tensorflow.org/data/iris_training.csv
8192/2194 [================================================================================================================] - 0s 0us/step
Local copy of the dataset file:C:\Users\Frank.keras\datasets\iris_training.csv
#對錶格檔案中的每一行進行解析,每行有5個元素,前面4個是特徵,最後一個是標記
def parse_csv(line):
example_defaults=[[0.],[0.],[0.],[0.],[0]]
parsed_line=tf.decode_csv(line,example_defaults)
features=tf.reshape(parsed_line[:-1],shape=(4,))
label=tf.reshape(parsed_line[-1],shape=())
return features,label
train_dataset=tf.data.TextLineDataset(train_dataset_fp) #讀取csv轉換為dataset
train_dataset=train_dataset.skip(1) #跳過標題行
train_dataset=train_dataset.map(parse_csv) #對每一行都進行對映
train_dataset=train_dataset.shuffle(buffer_size=1000) #隨機打亂
train_dataset=train_dataset.batch(32) #分批
#列印一組訓練資料
features,label=iter(train_dataset).next()
print('example features:',features[0])
print('example label:',label[0])
example features: tf.Tensor([6.8 3. 5.5 2.1], shape=(4,), dtype=float32)
example label: tf.Tensor(2, shape=(), dtype=int32)
#建立神經網路模型,兩個隱藏層
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)
])
#定義損失函式為softmax後的cross_entropy,返回一個損失函式的物件
def loss(model,x,y):
y_=model(x)
return tf.losses.sparse_softmax_cross_entropy(labels=y,logits=y_)
#返回一個梯度物件
def grad(model,inputs,targets):
with tf.GradientTape() as tape:
loss_value=loss(model,inputs,targets)
return tape.gradient(loss_value,model.variables) #返回梯度物件,傳入損失函式和優化物件作為建構函式的引數
optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.01)
train_loss_results=[]
train_accuracy_results=[]
num_epochs=201
#優化過程迭代201次
for epoch in range(num_epochs):
epoch_loss_avg=tfe.metrics.Mean() #交叉熵的平均誤差物件
epoch_accuracy=tfe.metrics.Accuracy() #準確率物件
for x,y in train_dataset:
grads=grad(model,x,y)
optimizer.apply_gradients(zip(grads, model.variables), #將梯度對應的模型變數分組
global_step=tf.train.get_or_create_global_step())
epoch_loss_avg(loss(model,x,y))
epoch_accuracy(tf.argmax(model(x),axis=1,output_type=tf.int32),y)
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()
Epoch 000: Loss: 1.217, Accuracy: 30.833%
Epoch 050: Loss: 0.524, Accuracy: 93.333%
Epoch 100: Loss: 0.261, Accuracy: 96.667%
Epoch 150: Loss: 0.169, Accuracy: 97.500%
Epoch 200: Loss: 0.133, Accuracy: 97.500%
#訓練過程損失函式和準確率的視覺化
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 = "http://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.TextLineDataset(test_fp)
test_dataset = test_dataset.skip(1)
test_dataset = test_dataset.map(parse_csv)
test_dataset = test_dataset.shuffle(1000)
test_dataset = test_dataset.batch(32)
test_accuracy = tfe.metrics.Accuracy()
for (x, y) in test_dataset:
prediction = tf.argmax(model(x), axis=1, output_type=tf.int32)
test_accuracy(prediction, y)
print("Test set accuracy: {:.3%}".format(test_accuracy.result()))
Test set accuracy: 100.000%
#使用模型來進行預測
class_ids = ["Iris setosa", "Iris versicolor", "Iris virginica"]
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()
name = class_ids[class_idx]
print("Example {} prediction: {}".format(i, name))
Example 0 prediction: Iris setosa
Example 1 prediction: Iris versicolor
Example 2 prediction: Iris virginica