乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      圖解機器學習:神經網絡和 TensorFlow 的文本分類

       silence_33 2017-08-03


      開發(fā)人員經常說,如果你想開始機器學習,你應該首先學習算法。但是我的經驗則不是。


      我說你應該首先了解:應用程序如何工作。一旦了解了這一點,深入探索算法的內部工作就會變得更加容易。


      那么,你如何 開發(fā)直覺學習,并實現理解機器學習這個目的?一個很好的方法是創(chuàng)建機器學習模型。


      假設您仍然不知道如何從頭開始創(chuàng)建所有這些算法,您可以使用一個已經為您實現所有這些算法的庫。那個庫是 TensorFlow。


      在本文中,我們將創(chuàng)建一個機器學習模型來將文本分類到類別中。我們將介紹以下主題:


      1. TensorFlow 的工作原理

      2. 什么是機器學習模型

      3. 什么是神經網絡

      4. 神經網絡如何學習

      5. 如何操作數據并將其傳遞給神經網絡

      6. 如何運行模型并獲得預測結果


      你可能會學到很多新東西,所以讓我們開始吧!


      TensorFlow


      TensorFlow 是一個機器學習的開源庫,由 Google 首創(chuàng)。庫的名稱幫助我們理解我們怎樣使用它:tensors 是通過圖的節(jié)點流轉的多維數組。


      tf.Graph


      在 TensorFlow 中的每一個計算都表示為數據流圖,這個圖有兩類元素:


      • 一類 tf.Operation,表示計算單元

      • 一類 tf.Tensor,表示數據單元


      要查看這些是怎么工作的,你需要創(chuàng)建這個數據流圖:



      (計算x+y的圖)


      你需要定義 x = [1,3,6] 和 y = [1,1,1]。由于圖用 tf.Tensor 表示數據單元,你需要創(chuàng)建常量 Tensors:


      import tensorflow as tf

      x = tf.constant([1,3,6])

      y = tf.constant([1,1,1])


      現在你將定義操作單元:


      import tensorflow as tf

      x = tf.constant([1,3,6])

      y = tf.constant([1,1,1])

      op = tf.add(x,y)


      你有了所有的圖元素?,F在你需要構建圖:


      import tensorflow as tf

      my_graph = tf.Graph()

      with my_graph.as_default():

          x = tf.constant([1,3,6])

          y = tf.constant([1,1,1])

          op = tf.add(x,y)


      這是 TensorFlow 工作流的工作原理:你首先要創(chuàng)建一個圖,然后你才能計算(實際上是用操作‘運行’圖節(jié)點)。你需要創(chuàng)建一個 tf.Session 運行圖。


      tf.Session


      tf.Session 對象封裝了 Operation 對象的執(zhí)行環(huán)境。Tensor 對象是被計算過的(從文檔中)。為了做到這些,我們需要在 Session 中定義哪個圖將被使用到:


      import tensorflow as tf

      my_graph = tf.Graph()

      with tf.Session(graph=my_graph) as sess:

          x = tf.constant([1,3,6])

          y = tf.constant([1,1,1])

          op = tf.add(x,y)


      為了執(zhí)行操作,你需要使用方法 tf.Session.run()。這個方法通過運行必要的圖段去執(zhí)行每個 Operation 對象并通過參數 fetches 計算每一個 Tensor 的值的方式執(zhí)行 TensorFlow 計算的一’步’:


      import tensorflow as tf

      my_graph = tf.Graph()

      with tf.Session(graph=my_graph) as sess:

          x = tf.constant([1,3,6])

          y = tf.constant([1,1,1])

          op = tf.add(x,y)

          result = sess.run(fetches=op)

          print(result)

      >>> [2 4 7]


      預測模型


      現在你知道了 TensorFlow 的工作原理,那么你得知道怎樣創(chuàng)建預測模型。簡而言之


      機器學習算法+數據=預測模型


      構建模型的過程就是這樣:



      (構建預測模型的過程)


      正如你能看到的,模型由數據“訓練過的”機器學習算法組成。當你有了模型,你就會得到這樣的結果:



      (預測工作流)


      你創(chuàng)建的模型的目的是對文本分類,我們定義了:


      input: text, result: category


      我們有一個使用已經標記過的文本(每個文本都有了它屬于哪個分類的標記)訓練的數據集。在機器學習中,這種任務的類型是被稱為監(jiān)督學習。


       “我們知道正確的答案。該算法迭代的預測訓練數據,并由老師糾正

      ”?—?Jason Brownlee



      你會把數據分成類,因此它也是一個分類任務。


      為了創(chuàng)建這個模型,我們將會用到神經網絡。


      神經網絡


      神經網絡是一個計算模型(一種描述使用機器語言和數學概念的系統的方式)。這些系統是自主學習和被訓練的,而不是明確編程的。


      神經網絡是也從我們的中樞神經系統受到的啟發(fā)。他們有與我們神經相似的連接節(jié)點。


      感知器是第一個神經網絡算法。這篇文章 很好地解釋了感知器的內部工作原理(“人工神經元內部” 的動畫非常棒)。


      為了理解神經網絡的工作原理,我們將會使用 TensorFlow 建立一個神經網絡架構。在這個例子中,這個架構被 Aymeric Damien 使用過。


      神經網絡架構


      神經網絡有兩個隱藏層(你得選擇 網絡會有多少隱藏層,這是結構設計的一部分)。每一個隱藏層的任務是 把輸入的東西轉換成輸出層可以使用的東西。


      隱藏層 1


      (輸入層和第一個隱藏層)


      你也需要定義第一個隱藏層會有多少節(jié)點。這些節(jié)點也被稱為特征或神經元,在上面的例子中我們用每一個圓圈表示一個節(jié)點。


      輸入層的每個節(jié)點都對應著數據集中的一個詞(之后我們會看到這是怎么運行的)


      如 這里 所述,每個節(jié)點(神經元)乘以一個權重。每個節(jié)點都有一個權重值,在訓練階段,神經網絡會調整這些值以產生正確的輸出(過會,我們將會學習更多關于這個的信息)


      除了乘以沒有輸入的權重,網絡也會增加一個誤差 (在神經網絡中誤差的角色)。


      在你的架構中,將輸入乘以權重并將值與偏差相加,這些數據也要通過激活函數傳遞。這個激活函數定義了每個節(jié)點的最終輸出。比如說:想象一下,每一個節(jié)點是一盞燈,激活函數決定燈是否會亮。


      有很多類型的激活函數。你將會使用 Rectified Linear Unit (ReLu)。這個函數是這樣定義的:


      f(x) = max(0,x)  [輸出 x 或者 0(零)中最大的數]


      例如:如果 x = -1,  f(x) = 0(zero); 如果 x = 0.7, f(x) = 0.7.


      隱藏層 2


      第二個隱藏層做的完全是第一個隱藏層做的事情,但現在第二層的輸入是第一層的輸出。


      (第一和第二隱藏層)


      輸出層


      現在終于到了最后一層,輸出層。你將會使用 One-Hot 編碼 得到這個層的結果。在這個編碼中,只有一個比特的值是 1,其他比特的值都是 0。例如,如果我們想對三個分類編碼(sports, space 和computer graphics)編碼:



      因此輸出節(jié)點的編號是輸入的數據集的分類的編號。


      輸出層的值也要乘以權重,并我們也要加上誤差,但是現在激活函數不一樣。


      你想用分類對每一個文本進行標記,并且這些分類相互獨立(一個文本不能同時屬于兩個分類)??紤]到這點,你將使用 Softmax 函數而不是 ReLu 激活函數。這個函數把每一個完整的輸出轉換成 0 和 1 之間的值,并且確保所有單元的和等于一。這樣,輸出將告訴我們每個分類中每個文本的概率。


      | 1.2                             0.46|

      | 0.9   -> [softmax] ->  0.34|

      | 0.4                             0.20|


      現在有了神經網絡的數據流圖。把我們所看到的都轉換為代碼,結果是:


      # Network Parameters

      n_hidden_1 = 10        # 1st layer number of features

      n_hidden_2 = 5         # 2nd layer number of features

      n_input = total_words  # Words in vocab

      n_classes = 3          # Categories: graphics, space and baseball

      def multilayer_perceptron(input_tensor, weights, biases):

          layer_1_multiplication = tf.matmul(input_tensor, weights['h1'])

          layer_1_addition = tf.add(layer_1_multiplication, biases['b1'])

          layer_1_activation = tf.nn.relu(layer_1_addition)

      # Hidden layer with RELU activation

          layer_2_multiplication = tf.matmul(layer_1_activation, weights['h2'])

          layer_2_addition = tf.add(layer_2_multiplication, biases['b2'])

          layer_2_activation = tf.nn.relu(layer_2_addition)

      # Output layer with linear activation

          out_layer_multiplication = tf.matmul(layer_2_activation, weights['out'])

          out_layer_addition = out_layer_multiplication + biases['out']return out_layer_addition


      (我們將會在后面討論輸出層的激活函數)


      神經網絡怎么學習


      就像我們前面看到的那樣,神經網絡訓練時會更新權重值?,F在我們將看到在 TensorFlow 環(huán)境下這是怎么發(fā)生的。


      tf.Variable


      權重和誤差存儲在變量(tf.Variable)中。這些變量通過調用 run() 保持在圖中的狀態(tài)。在機器學習中我們一般通過 正太分布 來啟動權重和偏差值。


      weights = {

          'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),

          'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),

          'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes]))

      }

      biases = {

          'b1': tf.Variable(tf.random_normal([n_hidden_1])),

          'b2': tf.Variable(tf.random_normal([n_hidden_2])),

          'out': tf.Variable(tf.random_normal([n_classes]))

      }


      當我們第一次運行神經網絡的時候(也就是說,權重值是由正態(tài)分布定義的):


      input values: x

      weights: w

      bias: b

      output values: z

      expected values: expected


      為了知道網絡是否正在學習,你需要比較一下輸出值(Z)和期望值(expected)。我們要怎么計算這個的不同(損耗)呢?有很多方法去解決這個問題。因為我們正在進行分類任務,測量損耗的最好的方式是 交叉熵誤差。


      James D. McCaffrey 寫了一個精彩的解釋,說明為什么這是這種類型任務的最佳方法。


      通過 TensorFlow 你將使用 tf.nn.softmax_cross_entropy_with_logits() 方法計算交叉熵誤差(這個是 softmax 激活函數)并計算平均誤差 (tf.reduced_mean())。


      # Construct model

      prediction = multilayer_perceptron(input_tensor, weights, biases)

      # Define loss

      entropy_loss = tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=output_tensor)

      loss = tf.reduce_mean(entropy_loss)


      你希望通過權重和誤差的最佳值,以便最小化輸出誤差(實際得到的值和正確的值之間的區(qū)別)。要做到這一點,將需使用 梯度下降法。更具體些是,需要使用 隨機梯度下降。



      (梯度下降。源: https:///faq/docs/closed-form-vs-gd.html)


      為了計算梯度下降,將要使用 Adaptive Moment Estimation (Adam)。要在 TensorFlow 中使用此算法,需要傳遞 learning_rate 值,該值可確定值的增量步長以找到最佳權重值。


      方法 tf.train.AdamOptimizer(learning_rate).minimize(loss) 是一個 語法糖,它做了兩件事情:


      1. compute_gradients(loss, )

      2. apply_gradients()


      這個方法用新的值更新了所有的 tf.Variables ,因此我們不需要傳遞變量列表。現在你有了訓練網絡的代碼:


      learning_rate = 0.001

      # Construct model

      prediction = multilayer_perceptron(input_tensor, weights, biases)

      # Define loss

      entropy_loss = tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=output_tensor)

      loss = tf.reduce_mean(entropy_loss)

      optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)


      數據操作


      將要使用的數據集有很多英文文本,我們需要操作這些數據將其傳遞給神經網絡。要做到這一點,需要做兩件事:


      1. 為每一個工作創(chuàng)建索引

      2. 為每一個文本創(chuàng)建矩陣,在矩陣里,如果單詞在文本中則值為 1,否則值為 0


      讓我們看著代碼來理解這個過程:


      import numpy as np    #numpy is a package for scientific computing

      from collections import Counter

      vocab = Counter()

      text = 'Hi from Brazil'#Get all wordsfor word in text.split(' '):

          vocab[word]+=1

              #Convert words to indexes

      def get_word_2_index(vocab):

          word2index = {}    for i,word in enumerate(vocab):

              word2index[word] = i        

          return word2index

      #Now we have an index

      word2index = get_word_2_index(vocab)

      total_words = len(vocab)

      #This is how we create a numpy array (our matrix)

      matrix = np.zeros((total_words),dtype=float)

      #Now we fill the valuesfor word in text.split():

          matrix[word2index[word]] += 1print(matrix)

      >>> [ 1.  1.  1.]


      上面例子中的文本是‘Hi from Brazil’,矩陣是 [ 1. 1. 1.]。如果文本僅是‘Hi’會怎么樣?


      matrix = np.zeros((total_words),dtype=float)

      text = 'Hi'for word in text.split():

          matrix[word2index[word.lower()]] += 1print(matrix)

      >>> [ 1.  0.  0.]


      將會與標簽(文本的分類)相同,但是現在得使用獨熱編碼(one-hot encoding):


      y = np.zeros((3),dtype=float)if category == 0:

          y[0] = 1.        # [ 1.  0.  0.]

      elif category == 1:

          y[1] = 1.        # [ 0.  1.  0.]else:

           y[2] = 1.       # [ 0.  0.  1.]


      運行圖并獲取結果


      現在進入最精彩的部分:從模型中獲取結果。先仔細看看輸入的數據集。


      數據集


      對于一個有 18.000 個帖子大約有 20 個主題的數據集,將會使用到 20個新聞組。要加載這些數據集將會用到 scikit-learn 庫。我們只使用 3 種類別:comp.graphics, sci.space 和 rec.sport.baseball。scikit-learn 有兩個子集:一個用于訓練,另一個用于測試。建議不要查看測試數據,因為這可能會在創(chuàng)建模型時干擾你的選擇。你不會希望創(chuàng)建一個模型來預測這個特定的測試數據,因為你希望創(chuàng)建一個具有很好的泛化性能的模型。


      這里是如何加載數據集的代碼:


      from sklearn.datasets import fetch_20newsgroups

      categories = ['comp.graphics','sci.space','rec.sport.baseball']

      newsgroups_train = fetch_20newsgroups(subset='train', categories=categories)

      newsgroups_test = fetch_20newsgroups(subset='test', categories=categories


      訓練模型


      在 神經網絡的術語里,一次 epoch = 一個向前傳遞(得到輸出的值)和一個所有訓練示例的向后傳遞(更新權重)。


      還記得 tf.Session.run() 方法嗎?讓我們仔細看看它:


      tf.Session.run(fetches, feed_dict=None, options=None, run_metadata=None)


      在這篇文章開始的數據流圖里,你用到了和操作,但是我們也可以傳遞一個事情的列表用于運行。在這個神經網絡運行中將傳遞兩個事情:損耗計算和優(yōu)化步驟。


      feed_dict 參數是我們?yōu)槊坎竭\行所輸入的數據。為了傳遞這個數據,我們需要定義tf.placeholders(提供給 feed_dict)


      正如 TensorFlow 文檔中說的:


       “占位符的存在只作為輸入的目標,它不需要初始化,也不包含數據?!?—?Source


      因此將要像這樣定義占位符:


      n_input = total_words # Words in vocab

      n_classes = 3         # Categories: graphics, sci.space and baseball

      input_tensor = tf.placeholder(tf.float32,[None, n_input],name='input')

      output_tensor = tf.placeholder(tf.float32,[None, n_classes],name='output')


      還將要批量分離你的訓練數據:


      “如果為了能夠輸入而使用占位符,可通過使用 tf.placeholder(…, shape=[None, …]) 創(chuàng)建占位符來指定變量批量維度。shape 的 None 元素對應于大小可變的維度?!?—?Source


      在測試模型時,我們將用更大的批處理來提供字典,這就是為什么需要定義一個可變的批處理維度。


      get_batches() 函數為我們提供了批處理大小的文本數?,F在我們可以運行模型:


      training_epochs = 10# Launch the graph

      with tf.Session() as sess:

          sess.run(init) #inits the variables (normal distribution, remember?)

          # Training cycle    for epoch in range(training_epochs):

              avg_cost = 0.

              total_batch = int(len(newsgroups_train.data)/batch_size)

              # Loop over all batches        for i in range(total_batch):

                  batch_x,batch_y = get_batch(newsgroups_train,i,batch_size)

                  # Run optimization op (backprop) and cost op (to get loss value)

                  c,_ = sess.run([loss,optimizer], feed_dict={input_tensor: batch_x, output_tensor:batch_y})


      現在有了這個經過訓練的模型。為了測試它,還需要創(chuàng)建圖元素。我們將測量模型的準確性,因此需要獲取預測值的索引和正確值的索引(因為我們使用的是獨熱編碼),檢查它們是否相等,并計算所有測試數據集的平均值:


          # Test model

          index_prediction = tf.argmax(prediction, 1)

          index_correct = tf.argmax(output_tensor, 1)

          correct_prediction = tf.equal(index_prediction, index_correct)

          # Calculate accuracy

          accuracy = tf.reduce_mean(tf.cast(correct_prediction, 'float'))

          total_test_data = len(newsgroups_test.target)

          batch_x_test,batch_y_test = get_batch(newsgroups_test,0,total_test_data)

          print('Accuracy:', accuracy.eval({input_tensor: batch_x_test, output_tensor: batch_y_test}))

      >>> Epoch: 0001 loss= 1133.908114347

          Epoch: 0002 loss= 329.093700409

          Epoch: 0003 loss= 111.876660109

          Epoch: 0004 loss= 72.552971845

          Epoch: 0005 loss= 16.673050320

          Epoch: 0006 loss= 16.481995190

          Epoch: 0007 loss= 4.848220565

          Epoch: 0008 loss= 0.759822878

          Epoch: 0009 loss= 0.000000000

          Epoch: 0010 loss= 0.079848485

          Optimization Finished!

          Accuracy: 0.75


      就是這樣!你使用神經網絡創(chuàng)建了一個模型來將文本分類到不同的類別中。恭喜!


      可在 這里(https://github.com/dmesquita/understanding_tensorflow_nn) 看到包含最終代碼的筆記本。


      提示:修改我們定義的值,以查看更改如何影響訓練時間和模型精度。



        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多