TensorFlow入門教程

摘要: 谷歌開源的AI開發工具TensorFlow,瞭解一下?html

谷歌的AI技術獨步天下,從即將商業化運營的無人駕駛汽車Waymo,到天下無敵的圍棋大師AlphaGo,再到以假亂真的電話助理Duplex...python

若是你想學習AI技術的話,神經網絡是個不錯的學習方向,由於它是最神奇也是如今最有效的機器學習算法;若是你想學習神經網絡的話,最好的起點是實現一個簡單的神經網絡,由於你能夠在實現的過程當中發現問題,思考問題以及解決問題;若是你想實現一個簡單的神經網絡的話,本文將教你使用TensorFlow來實現;至少,你能夠直接運行本文給出的例子,感覺一下神經網絡的神奇。git

TensorFlow簡介

TensorFlow是谷歌開源的AI開發工具,能夠用於實現普通的機器學習算法(linear regression,logistic regression),也能夠用於實現深度學習算法(各類不一樣類型的神經網絡)。TensorFlow爲深度學習進行了大量優化,使用TensorFlow提供的API,AI開發者可以更加簡單地實現神經網絡算法。github

鳶尾花分類

下圖是3種不一樣的鳶尾花,從左至右分別是setosa, virginica和versicolor。3種鳶尾花的花萼和花瓣的長寬各有不一樣。算法

iris_training.csv是訓練數據,它提供了120個鳶尾花的花萼和花瓣的長寬數據,而且標記了所屬的鳶尾花類別。docker

根據訓練數據,你能夠總結出鳶尾花的花萼和花瓣的長寬與其所屬類別的關係嗎?120個數據不算太多,可是對人來講並不簡單。bash

在本文中,咱們將使用TesorFlow訓練一個簡單的神經網絡,來識別鳶尾花的類別。網絡

代碼解釋

train.py訓練神經網絡的代碼:app

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function
import os
import tensorflow as tf
import tensorflow.contrib.eager as tfe
from parse_csv import parse_csv

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
tf.enable_eager_execution()


# 導入訓練數據
TRAIN_DATASET = tf.data.TextLineDataset("/tensorflow-101/data/iris_training.csv")
TRAIN_DATASET = TRAIN_DATASET.skip(1)             # skip the first header row
TRAIN_DATASET = TRAIN_DATASET.map(parse_csv)      # parse each row
TRAIN_DATASET = TRAIN_DATASET.shuffle(buffer_size=1000)  # randomize
TRAIN_DATASET = TRAIN_DATASET.batch(32)


# 定義神經網絡
MODEL = tf.keras.Sequential([
    tf.keras.layers.Dense(10, activation="relu", input_shape=(4,)),  # input shape required
    tf.keras.layers.Dense(10, activation="relu"),
    tf.keras.layers.Dense(3)
])


# 損失計算函數
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)


def train():

    print("訓練:")

    num_epochs = 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)

        if epoch % 50 == 0:
            print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch, epoch_loss_avg.result(), epoch_accuracy.result()))

    return MODEL
複製代碼

由代碼可知,從導入訓練數據,到定義神經網絡模型的層數以及激勵函數,再到定義損失計算函數、梯度計算函數和優化器,都使用了TensorFlow提供的API。這樣,開發者再也不須要去實現底層的細節,能夠根據須要靈活地調整神經網絡的結構以及所使用的各類函數。dom

其中,定義神經網絡的代碼以下:

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)
])
複製代碼

可知,這是一個4層的神經網絡,包含1個輸入層,2個隱藏層和1個輸出層,2個隱藏層都有10個神經元,使用RELU做爲激勵函數,以下圖所示:

訓練代碼最核心的是部分train函數:

def train():

    print("訓練:")

    num_epochs = 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)

        if epoch % 50 == 0:
            print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch, epoch_loss_avg.result(), epoch_accuracy.result()))

    return MODEL
複製代碼

train函數的算法是這樣的:

  • 迭代計算200個epoch,每個epoch迭代都會掃描整個訓練數據集;
  • 每一個epoch中,會iterate整個訓練數據集中的120個樣本,其batch size爲32,因此一個epoch須要4個iteration;
  • 每一個iteration中,根據樣本的特徵值(花萼和花瓣的長寬),使用神經網絡作出預測(所屬鳶尾花類別),與真實的標記值進行比較,計算損失及梯度。
  • 每一個iteration中,根據所計算的梯度,使用優化器修改神經網絡中的參數值。
  • 通過200個epoch,神經網絡中的參數將會調整到最優值,使得其預測結果偏差最低。

基於Docker運行TensorFlow

將TensorFlow以及代碼都打包到Docker鏡像中,就能夠在Docker容器中運行TensorFlow。這樣,開發者僅須要安裝Docker,而不須要安裝TensorFlow;同時,Docker保證了代碼必定能夠在任何Docker主機上正確執行,由於它所依賴的運行環境所有打包在Docker鏡像中。Docker鏡像使用Dockerfile定義。

克隆代碼

git clone https://github.com/Fundebug/tensorflow-101.git
cd tensorflow-101
複製代碼

構建鏡像

sudo docker build -t tensorflow .
複製代碼

運行容器

sudo docker run -i tensorflow python src/main.py
複製代碼

運行結果

訓練:
Epoch 000: Loss: 1.142, Accuracy: 29.167%
Epoch 050: Loss: 0.569, Accuracy: 78.333%
Epoch 100: Loss: 0.304, Accuracy: 95.833%
Epoch 150: Loss: 0.186, Accuracy: 97.500%
Epoch 200: Loss: 0.134, Accuracy: 98.333%

測試:
Test set accuracy: 96.667%

預測:
Example 0 prediction: Iris setosa
Example 1 prediction: Iris versicolor
Example 2 prediction: Iris virginica
複製代碼

由結果可知,對於測試數據集iris_test.csv,所訓練的神經網絡的準確率高達96.667%,是否是很神奇呢?

參考

相關文章
相關標籤/搜索