使用 TensorFlow 實現神經網絡的簡介

CleGabriele 9年前發布 | 95K 次閱讀 神經網絡 TensorFlow

介紹

如果你一直在關注 數據科學 / 機器學習 ,你不能錯過深度學習和神經網絡的嗡嗡聲。 組織正在尋找有深度學習技能的人,無論他們在哪里。 從運行競爭到開源采購項目和支付大額獎金,人們正在盡一切可能的事情來挖掘這個有限的人才庫。 自行車工程師正在被汽車行業的大槍獵殺,因為行業處于過去幾十年最大的破壞的邊緣!

如果你對潛在客戶的深度學習感到興奮,但還沒有開始你的旅程 - 我在這里啟用它。 從本文開始, 我將撰寫一系列關于深度學習的文章,涵蓋流行的深度學習圖書館及其實踐實施。

在本文中,我將向您介紹 TensorFlow。 閱讀本文后,您將能夠理解神經網絡的應用,并使用 TensorFlow 來解決現實生活中的問題。 這篇文章將需要你知道神經網絡的基礎知識和熟悉編程。 雖然本文中的代碼是在 python 中,我已經關注的概念,并保持作為語言不可知的盡可能。 讓我們開始吧!

什么時候應用神經網絡?

對于神經網絡和深度學習上這里有更詳細的解釋 點擊閱讀 。 其“更深”的版本在許多領域都有取得巨大的突破,如圖像識別,語音和自然語言處理等。

主要的問題在如何用好神經網絡? 這個領域就像一個金礦,現在,每天都會有許多新發現。 為了成為這個“淘金熱”的一部分,你必須記住幾件事:

  • 首先,神經網絡需要明確和翔實的數據(主要是與大數據)訓練, 試著想象神經網絡作為一個孩子。 它首先觀察它的父母走路。 然后它試圖自己走,并且每一步,孩子學習如何執行一個特定的任務。 它可能會下降幾次,但經過幾次不成功的嘗試,它學會如何走路。 如果你不 ’ 噸讓它走,它可能不會永遠學習如何走路。 你可以為孩子提供更多的曝光,越好。

  • 謹慎的做法是利用神經網絡的復雜問題,如圖像處理,神經網絡屬于一類稱為算法代表學習算法。 這些算法分解復雜的問題分為簡單的形式,使他們成為可以理解的(或 “ 可表示 ”)。 認為它是咀嚼食物之前你吞咽。 這對于傳統(非表示學習)算法將更難。

  • 當有適當類型的神經網絡,以解決這個問題,每個問題都有自己的曲折。 所以數據決定你解決問題的方式。 例如,如果問題是序列生成的問題,遞歸神經網絡更合適。 然而,如果它是圖像相關的問題,你可能會更好地采取卷積神經網絡的變化。

  • 最后但并非最不重要的, 硬件 要求是運行了深刻的神經網絡模型的關鍵。神經網被 “ 發現 ” 很久以前,但他們在近年來的主要的原因是計算資源更好,更強大的光亮。 如果你想解決這些網絡的現實生活中的問題,準備購買一些高端的硬件!

通常神經網絡解決的問題

神經網絡是一種特殊類型的機器學習(ML)算法。 因此,作為每個 ML 算法,它遵循數據預處理,模型建立和模型評估的通常 ML 工作流。 為了簡明起見,我列出了如何處理神經網絡問題的 TO DO 列表。

  • 檢查是否就是神經網絡 使您隆起比傳統的算法 有問題 (參見清單中的部分上方)
  • 做一個調查哪個神經網絡架構最適合所需的問題
  • 定義神經網絡架構,通過它選擇任何語言/庫。
  • 將數據轉換為正確的格式并分批分割
  • 根據您的需要預處理數據
  • 增強數據以增加大小并制作更好的訓練模型
  • 批次供給到神經網絡
  • 訓練和監測培訓和驗證數據集的變化
  • 測試您的模型,并保存以備將來使用

對于本文,我將專注于圖像數據。 所以讓我們明白,首先我們深入到TensorFlow。

了解圖像數據和流行的庫來解決它

圖像大多排列為 3-D 陣列,尺寸指高度、寬度和顏色通道。 例如,如果你在這一刻截取你的電腦, 它將首先轉換成一個 3-D 數組,然后壓縮它 ‘.jpeg’ 或 ‘.png’ 文件格式。

雖然這些圖像對于人類來說很容易理解,但計算機很難理解它們。 這種現象稱為“語義空隙”。 我們的大腦可以看看圖像,并在幾秒鐘內了解完整的圖片。 另一方面,計算機將圖像看作一個數字數組。 所以問題是我們如何解釋這個圖像到機器?

在早期,人們試圖將圖像分解為機器的“可理解”格式,如“模板”。 例如,面部總是具有在每個人中有所保留的特定結構,例如眼睛,鼻子或我們的臉的形狀。 但是這種方法將是乏味的,因為當要識別的對象的數量將增加,“模板”將不成立。

快進到2012年,一個深層神經網絡架構贏得了 ImageNet 的挑戰,一個著名的挑戰,從自然場景中識別對象。 它繼續在所有即將到來的 ImageNet 挑戰中統治其主權,從而證明了解決圖像問題的有用性。 人們通常使用哪些庫/語言來解決圖像識別問題?其中 最近的一次調查 我這樣做,最流行的深度學習圖書館有接口的 Python ,其次是 Lua 中, Java 和 Matlab 的。 最流行的圖書館,僅舉幾例,是:

  • Caffe
  • DeepLearning4j
  • TensorFlow
  • Theano
  • Torch

現在,您了解了圖像的存儲方式以及使用的常用庫,讓我們看看 TensorFlow 提供的內容。

什么是 TensorFlow?

讓我們從官方定義開始.

“TensorFlow 是一個開源軟件庫,用于使用數據流圖進行數值計算。 圖中的節點表示數學運算,而圖邊表示在它們之間傳遞的多維數據陣列(也稱為張量)。 靈活的架構允許您使用單一 API 將計算部署到桌面,服務器或移動設備中的一個或多個 CPU 或 GPU 。

如果這聽起來有點可怕 - 不要擔心。 這里是我簡單的定義 - 看看 TensorFlow 作為沒有什么,只是 numpy 與扭曲。 如果你以前工作過 numpy ,理解 TensorFlow 將是一塊蛋糕! numpy 和 TensorFlow 之間的主要區別是 TensorFlow 遵循惰性編程范例。 它首先構建一個所有操作的圖形,然后當調用“會話”時,它“運行”圖形。 它通過將內部數據表示更改為張量(也稱為多維數組)來構建為可擴展的。 構建計算圖可以被認為是 TensorFlow 的主要成分。 

很容易將 TensorFlow 分類為神經網絡庫,但它不僅僅是這樣。 是的,它被設計成一個強大的神經網絡庫。 但它有能力做更多的事情。 您可以在其上構建其他機器學習算法,如決策樹或 k-最近鄰 。 你可以從字面上做你通常會做的一切 numpy ! 它適當地稱為“類固醇上的 numpy”

使用 TensorFlow 的優點是:

  • 它有一個直觀的結構  ,因為顧名思義它有 “張量流”, 你可以輕松地可視每圖的每一個部分。
  • 輕松地在 cpu / gpu 上進行分布式計算
  • 平臺的靈活性  。 您可以隨時隨地運行模型,無論是在移動,服務器還是 PC 上。

TensorFlow 的典型 “流”

每個庫都有自己的“實現細節”,即一種寫其遵循其編碼范例的方式。 例如,當實現 scikit-learn 時,首先創建所需算法的對象,然后在列車上構建一個模型并獲得測試集的預測,如下所示:

define hyperparamters of ML algorithm

clf = svm.SVC(gamma=0.001, C=100.)

train

clf.fit(X, y)

test

clf.predict(X_test)</pre>

正如我前面所說,TensorFlow 遵循一種懶惰的方法。 在 TensorFlow 中運行程序的通常工作流程如下:

  • 建立一個計算圖 , 這可以是任何的數學運算 TensorFlow 支撐。
  • 初始化變量 , 編譯預先定義的變量
  • 創建會話 , 這是 神奇的開始的 地方 !
  • 在會話中運行圖 , 編譯圖形被傳遞到會話,它開始執行它。
  • 關閉會話 , 結束這次使用。

TensoFlow 中使用的術語很少

placeholder:將數據輸入圖形的一種方法
feed_dict:將數值傳遞到計算圖的字典

讓我們寫一個小程序來添加兩個數字!

import tensorflow

import tensorflow as tf

build computational graph

a = tf.placeholder(tf.int16) b = tf.placeholder(tf.int16)

addition = tf.add(a, b)

initialize variables

init = tf.initialize_all_variables()

create session and run the graph

with tf.Session() as sess: sess.run(init) print "Addition: %i" % sess.run(addition, feed_dict={a: 2, b: 3})

close session

sess.close()</pre>

在 TensorFlow 中實現神經網絡

注意:我們可以使用不同的神經網絡體系結構來解決這個問題,但是為了簡單起見,我們在深入實施中討論了前饋多層感知器。

讓我們記住我們對神經網絡的了解。

神經網絡的典型實現如下:

  • 定義要編譯的神經網絡體系結構
  • 將數據傳輸到模型
  • 在引擎蓋下,數據首先被分成批次,以便它可以被攝取。 首先對批次進行預處理,擴增,然后送入神經網絡進行訓練
  • 然后,模型被逐步地訓練
  • 顯示特定數量的時間步長的精度
  • 訓練后保存模型供將來使用
  • 在新數據上測試模型并檢查其運行方式

在這里,我們解決了我們深刻的學習實踐中的問題 - 確定數字 。 讓我們花一點時間看看我們的問題陳述。

我們的問題是圖像識別,以識別來自給定的 28×28 圖像的數字。 我們有一個圖像子集用于訓練,其余的用于測試我們的模型。 所以首先,下載火車和測試文件。 數據集包含數據集中所有圖像的壓縮文件, train.csv 和 test.csv 都有相應的列車和測試圖像的名稱。 數據集中不提供任何其他功能,只是原始圖像以 “.png” 格式提供。

正如你所知道的,我們將使用 TensorFlow 來創建一個神經網絡模型。 所以你應該首先在你的系統中安裝 TensorFlow 。 

我們將按照上述模板

  • 讓我們來 導入所有需要的模塊
%pylab inline

import os import numpy as np import pandas as pd from scipy.misc import imread from sklearn.metrics import accuracy_score import tensorflow as tf</pre>

  • 讓我們來 設置一個種子值,這樣我們就可以控制我們的模型隨機性

To stop potential randomness

seed = 128 rng = np.random.RandomState(seed)</pre>

  • 第一步是設置目錄路徑,以便保管!
root_dir = os.path.abspath('../..')
data_dir = os.path.join(root_dir, 'data')
sub_dir = os.path.join(root_dir, 'sub')

check for existence

os.path.exists(root_dir) os.path.exists(data_dir) os.path.exists(sub_dir)</pre>

  • 現在讓我們讀取我們的數據集。 這些是.csv格式,并有一個文件名以及相應的標簽
train = pd.read_csv(os.path.join(data_dir,'Train','train.csv'))
test = pd.read_csv(os.path.join(data_dir,'Test.csv'))
sample_submission = pd.read_csv(os.path.join(data_dir,'Sample_Submission.csv'))
train.head()
  文件名 標簽
0 0.png 4
1 1.png 9
2 2.png 1
3 3.png 7
4 4.png 3
  • 讓我們看看我們的數據是什么樣子! 我們讀取我們的形象并顯示出來。
img_name = rng.choice(train.filename)
filepath = os.path.join(data_dir, 'Train', 'Images', 'train', img_name)

img = imread(filepath, flatten=True)

pylab.imshow(img, cmap='gray') pylab.axis('off') pylab.show()</pre>

上面的圖像表示為 numpy 數組,如下所示

  • 為了方便數據操作,讓我們 的存儲作為 numpy 的陣列的所有圖片
temp = []
for img_name in train.filename:
    image_path = os.path.join(data_dir, 'Train', 'Images', 'train', img_name)
    img = imread(image_path, flatten=True)
    img = img.astype('float32')
    temp.append(img)

train_x = np.stack(temp)

temp = [] for img_name in test.filename: image_path = os.path.join(data_dir, 'Train', 'Images', 'test', img_name) img = imread(image_path, flatten=True) img = img.astype('float32') temp.append(img)

test_x = np.stack(temp)</pre>

  • 由于這是典型的 ML 問題,為了測試我們的模型的正確功能,我們創建一個驗證集。 讓我們 以 70:30 的分割大小車組 VS 驗證集
split_size = int(train_x.shape[0]*0.7)

train_x, val_x = train_x[:split_size], train_x[split_size:] train_y, val_y = train.label.values[:split_size], train.label.values[split_size:]</pre>

  • 現在我們定義一些輔助函數,我們稍后在我們的程序中使用
def dense_to_one_hot(labels_dense, num_classes=10):
    """Convert class labels from scalars to one-hot vectors"""
    num_labels = labels_dense.shape[0]
    index_offset = np.arange(num_labels) * num_classes
    labels_one_hot = np.zeros((num_labels, num_classes))
    labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1

return labels_one_hot

def preproc(unclean_batch_x): """Convert values to range 0-1""" temp_batch = unclean_batch_x / unclean_batch_x.max()

return temp_batch

def batch_creator(batch_size, dataset_length, dataset_name): """Create batch with random samples and return appropriate format""" batch_mask = rng.choice(dataset_length, batch_size)

batch_x = eval(dataset_name + '_x')[[batch_mask]].reshape(-1, 784)
batch_x = preproc(batch_x)

if dataset_name == 'train':
    batch_y = eval(dataset_name).ix[batch_mask, 'label'].values
    batch_y = dense_to_one_hot(batch_y)

return batch_x, batch_y</pre> 

  • 現在是主要部分! 讓我們定義我們的神經網絡架構。 我們定義一個神經網絡具有 3 層; 輸入,隱藏和輸出。 輸入和輸出中的神經元數目是固定的,因為輸入是我們的 28×28 圖像,并且輸出是表示類的 10×1 向量。 我們在隱藏層中取 500 神經元。 這個數字可以根據您的需要變化。 我們也 值 賦給 其余變量。 

set all variables

number of neurons in each layer

input_num_units = 28*28

hidden_num_units = 500

output_num_units = 10

define placeholders

x = tf.placeholder(tf.float32, [None, input_num_units]) y = tf.placeholder(tf.float32, [None, output_num_units])

set remaining variables

epochs = 5 batch_size = 128 learning_rate = 0.01

define weights and biases of the neural network (refer this article if you don't understand the terminologies)

weights = { 'hidden': tf.Variable(tf.random_normal([input_num_units, hidden_num_units], seed=seed)), 'output': tf.Variable(tf.random_normal([hidden_num_units, output_num_units], seed=seed)) }

biases = { 'hidden': tf.Variable(tf.random_normal([hidden_num_units], seed=seed)), 'output': tf.Variable(tf.random_normal([output_num_units], seed=seed)) }</pre>

  • 現在創建我們的神經網絡計算圖
hidden_layer = tf.add(tf.matmul(x, weights['hidden']), biases['hidden'])
hidden_layer = tf.nn.relu(hidden_layer)

output_layer = tf.matmul(hidden_layer, weights['output']) + biases['output']</pre>

  • 此外,我們需要定義神經網絡的成本
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output_layer, y))
  • 并設置優化器,即我們的反向傳播算法。 這里我們使用  Adam  ,這是梯度下降算法的高效變體。
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
  • 定義我們的神經網絡結構后,讓我們來 初始化所有的變量
init = tf.initialize_all_variables()
  • 現在讓我們創建一個會話,并在會話中運行我們的神經網絡。 我們還驗證我們創建的驗證集的模型準確性
with tf.Session() as sess:

# create initialized variables
sess.run(init)

### for each epoch, do:
###   for each batch, do:
###     create pre-processed batch
###     run optimizer by feeding batch
###     find cost and reiterate to minimize

for epoch in range(epochs):
    avg_cost = 0
    total_batch = int(train.shape[0]/batch_size)
    for i in range(total_batch):
        batch_x, batch_y = batch_creator(batch_size, train_x.shape[0], 'train')
        _, c = sess.run([optimizer, cost], feed_dict = {x: batch_x, y: batch_y})

        avg_cost += c / total_batch

    print "Epoch:", (epoch+1), "cost =", "{:.5f}".format(avg_cost)

print "\nTraining complete!"


# find predictions on val set
pred_temp = tf.equal(tf.argmax(output_layer, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(pred_temp, "float"))
print "Validation Accuracy:", accuracy.eval({x: val_x.reshape(-1, 784), y: dense_to_one_hot(val_y.values)})

predict = tf.argmax(output_layer, 1)
pred = predict.eval({x: test_x.reshape(-1, 784)})</pre> 

這將是上面代碼的輸出

Epoch: 1 cost = 8.93566
Epoch: 2 cost = 1.82103
Epoch: 3 cost = 0.98648
Epoch: 4 cost = 0.57141
Epoch: 5 cost = 0.44550

Training complete!
Validation Accuracy: 0.952823
  • 為了測試我們用我們自己的眼睛的模式, 讓我們來 想象它的預言
img_name = rng.choice(test.filename)
filepath = os.path.join(data_dir, 'Train', 'Images', 'test', img_name)

img = imread(filepath, flatten=True)

test_index = int(img_name.split('.')[0]) - 49000

print "Prediction is: ", pred[test_index]

pylab.imshow(img, cmap='gray')
pylab.axis('off')
pylab.show()
Prediction is:  8

  • 我們看到我們的模型性能是相當不錯! 現在 ,讓我們 創建一個提交
sample_submission.filename = test.filename

sample_submission.label = pred

sample_submission.to_csv(os.path.join(sub_dir, 'sub01.csv'), index=False)

并做了! 我們剛剛創建了我們自己的訓練神經網絡!

TensorFlow 的限制

  • 盡管 TensorFlow 是強大的, 它 仍然 是 一個低水平庫。 例如,它可以被認為是機器級語言。 但對于大多數功能,您需要自己去模塊化和高級接口,如 keras
  • 它仍然在繼續開發和維護,這是多么迷人啊!
  • 它取決于你的硬件規格,越牛越好
  • 仍然不是許多語言的 API。
  • TensorFlow 中仍然有很多庫需要手動包括在內,比如 OpenCL 支持。

上面提到的大多數是在TensorFlow開發人員的藍圖, 他們已經制定了一個路線圖,指定庫未來應該如何開發。

TensorFlow 與其他庫

TensorFlow 建立在類似的原理,如使用數學計算圖表的 Theano 和 Torch 。 但是隨著分布式計算的額外支持,TensorFlow 更好地解決復雜的問題。 此外,TensorFlow模型的部署已經被支持,這使得它更容易用于工業目的,打開商業圖書館,如 Deeplearning4j ,H2O 和 Turi。 TensorFlow 有用于 Python,C ++ 和 Matlab 的 API 。 最近還出現了對 Ruby 和 R 等其他語言的支持。因此,TensorFlow 試圖獲得通用語言支持。

從這里去哪里?

以上你看到了如何用 TensorFlow 構建一個簡單的神經網絡。 這段代碼是為了讓人們了解如何開始實現 TensorFlow,所以帶上一點鹽。 記住,要解決更復雜的現實生活中的問題,你必須調整代碼一點。

許多上述功能可以被抽象為給出無縫的端到端工作流。 如果你使用 scikit-learn ,你可能知道一個高級庫如何抽象“底層”實現,給終端用戶一個更容易的界面。 盡管 TensorFlow 已經提取了大多數實現,但是出現了高級庫,如 TF-slim 和 TFlearn。

 

來自:http://talkingdata.me/2016/11/20/neural_networks_using_TensorFlow/

 

 本文由用戶 CleGabriele 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!