<label id="jgr5k"></label>
    <legend id="jgr5k"><track id="jgr5k"></track></legend>

    <sub id="jgr5k"></sub>
  1. <u id="jgr5k"></u>
      久草国产视频,91资源总站,在线免费看AV,丁香婷婷社区,久久精品99久久久久久久久,色天使av,无码探花,香蕉av在线
      您正在使用IE低版瀏覽器,為了您的雷峰網賬號安全和更好的產品體驗,強烈建議使用更快更安全的瀏覽器
      此為臨時鏈接,僅用于文章預覽,將在時失效
      人工智能開發者 正文
      發私信給AI研習社
      發送

      1

      簡單實用的 TensorFlow 實現 RNN 入門教程

      本文作者: AI研習社 2017-05-07 19:31
      導語:手把手教你用 TensorFlow 實現 RNN。

      雷鋒網按:本文作者劉沖,原文載于作者個人博客,雷鋒網已獲授權。

      最近在看RNN模型,為簡單起見,本篇就以簡單的二進制序列作為訓練數據,而不實現具體的論文仿真,主要目的是理解RNN的原理和如何在TensorFlow中構造一個簡單基礎的模型架構。其中代碼參考了這篇博客。

      數據集

      首先我們看一下實驗數據的構造:

      輸入數據X:在時間t,Xt的值有50%的概率為1,50%的概率為0; 

      輸出數據Y:在實踐t,Yt的值有50%的概率為1,50%的概率為0,除此之外,如果`Xt-3 == 1`,Yt為1的概率增加50%, 如果`Xt-8 == 1`,則Yt為1的概率減少25%, 如果上述兩個條件同時滿足,則Yt為1的概率為75%。

      可知,Y與X有兩個依賴關系,一個是t-3,一個是t-8。我們實驗的目的就是檢驗RNN能否捕捉到Y與X之間的這兩個依賴關系。實驗使用交叉熵作為評價標準,則有下面三條理想的實驗結果:

      如果RNN沒有學習到任何一條依賴,那么Yt為1的概率就是0.625(0.5+0.5*0.5-0.5*0.25),所以所獲得的交叉熵應該是0.66(-(0.625 * np.log(0.625) + 0.375 * np.log(0.375)))。

      如果RNN學習到第一條依賴關系,即Xt-3為1時Yt一定為1。那么,所以最終的交叉熵應該是0.52(-0.5 * (0.875 * np.log(0.875) + 0.125 * np.log(0.125)) -0.5 * (0.625 * np.log(0.625) + 0.375 * np.log(0.375)))。

      如果RNN學習到了兩條依賴, 那么有0.25的概率全對,0.5的概率正確率是75%,還有0.25的概率正確率是0.5。所以其交叉熵為0.45(-0.50 * (0.75 * np.log(0.75) + 0.25 * np.log(0.25)) - 0.25 * (2 * 0.50 * np.log (0.50)) - 0.25 * (0))。

      數據預處理

      這部分主要是生成實驗數據,并將其按照RNN模型的輸入格式進行切分和batch化。代碼入下: 

      1,生成實驗數據:

      def gen_data(size=100000):

          X = np.array(np.random.choice(2, size=(size,)))

          Y = []

          for i in range(size):

              threshold = 0.5

              #判斷X[i-3]和X[i-8]是否為1,修改閾值

              if X[i-3] == 1:

                  threshold += 0.5

              if X[i-8] == 1:

                  threshold -= 0.25

              #生成隨機數,以threshold為閾值給Yi賦值

              if np.random.rand() > threshold:

                  Y.append(0)

              else:

                  Y.append(1)

          return X, np.array(Y)

      接下來將生成的數據按照模型參數設置進行切分,這里需要用得到的參數主要包括:batch_size和num_steps,分別是批量數據大小和RNN每層rnn_cell循環的次數,也就是下圖中Sn中n的大小。代碼入下:

      def gen_batch(raw_data, batch_size, num_steps):

          #raw_data是使用gen_data()函數生成的數據,分別是X和Y

          raw_x, raw_y = raw_data

          data_length = len(raw_x)


          # 首先將數據切分成batch_size份,0-batch_size,batch_size-2*batch_size。。。

          batch_partition_length = data_length // batch_size

          data_x = np.zeros([batch_size, batch_partition_length], dtype=np.int32)

          data_y = np.zeros([batch_size, batch_partition_length], dtype=np.int32)

          for i in range(batch_size):

              data_x[i] = raw_x[batch_partition_length * i:batch_partition_length * (i + 1)]

              data_y[i] = raw_y[batch_partition_length * i:batch_partition_length * (i + 1)]


          #因為RNN模型一次只處理num_steps個數據,所以將每個batch_size在進行切分成epoch_size份,每份num_steps個數據。注意這里的epoch_size和模型訓練過程中的epoch不同。 

          epoch_size = batch_partition_length // num_steps


          #x是0-num_steps, batch_partition_length -batch_partition_length +num_steps。。。共batch_size個

          for i in range(epoch_size):

              x = data_x[:, i * num_steps:(i + 1) * num_steps]

              y = data_y[:, i * num_steps:(i + 1) * num_steps]

              yield (x, y)


      #這里的n就是訓練過程中用的epoch,即在樣本規模上循環的次數

      def gen_epochs(n, num_steps):

          for i in range(n):

              yield gen_batch(gen_data(), batch_size, num_steps)

      根據上面的代碼我們可以看出來,這里的數據劃分并沒有將數據完全的按照原先的數據順序,而是每隔一段取num_steps個數據,這樣組成的batch進行訓練==這里是為了省事還是另有原因還有待后面學習中考證。

      模型構建

      RNN的具體原理我們就不再進行贅述,主要是隱層狀態和輸入連接后計算新的隱層狀態和輸出。這里用的是單層的RNN。公式和原理圖如下所示:

      St=tanh(W(Xt @ St?1)+bs) 

      Pt=softmax(USt+bp)

      簡單實用的 TensorFlow 實現 RNN 入門教程

      至于使用TensorFlow構建RNN模型,主要就是定義rnn_cell類型,然后將其復用即可。代碼如下所示:

      x = tf.placeholder(tf.int32, [batch_size, num_steps], name='input_placeholder')

      y = tf.placeholder(tf.int32, [batch_size, num_steps], name='labels_placeholder')

      #RNN的初始化狀態,全設為零。注意state是與input保持一致,接下來會有concat操作,所以這里要有batch的維度。即每個樣本都要有隱層狀態

      init_state = tf.zeros([batch_size, state_size])


      #將輸入轉化為one-hot編碼,兩個類別。[batch_size, num_steps, num_classes]

      x_one_hot = tf.one_hot(x, num_classes)

      #將輸入unstack,即在num_steps上解綁,方便給每個循環單元輸入。這里可以看出RNN每個cell都處理一個batch的輸入(即batch個二進制樣本輸入)

      rnn_inputs = tf.unstack(x_one_hot, axis=1)


      #定義rnn_cell的權重參數,

      with tf.variable_scope('rnn_cell'):

          W = tf.get_variable('W', [num_classes + state_size, state_size])

          b = tf.get_variable('b', [state_size], initializer=tf.constant_initializer(0.0))

      #使之定義為reuse模式,循環使用,保持參數相同

      def rnn_cell(rnn_input, state):

          with tf.variable_scope('rnn_cell', reuse=True):

              W = tf.get_variable('W', [num_classes + state_size, state_size])

              b = tf.get_variable('b', [state_size], initializer=tf.constant_initializer(0.0))

          #定義rnn_cell具體的操作,這里使用的是最簡單的rnn,不是LSTM

          return tf.tanh(tf.matmul(tf.concat([rnn_input, state], 1), W) + b)


      state = init_state

      rnn_outputs = []

      #循環num_steps次,即將一個序列輸入RNN模型

      for rnn_input in rnn_inputs:

          state = rnn_cell(rnn_input, state)

          rnn_outputs.append(state)

      final_state = rnn_outputs[-1]


      #定義softmax層

      with tf.variable_scope('softmax'):

          W = tf.get_variable('W', [state_size, num_classes])

          b = tf.get_variable('b', [num_classes], initializer=tf.constant_initializer(0.0))

      #注意,這里要將num_steps個輸出全部分別進行計算其輸出,然后使用softmax預測

      logits = [tf.matmul(rnn_output, W) + b for rnn_output in rnn_outputs]

      predictions = [tf.nn.softmax(logit) for logit in logits]


      # Turn our y placeholder into a list of labels

      y_as_list = tf.unstack(y, num=num_steps, axis=1)


      #losses and train_step

      losses = [tf.nn.sparse_softmax_cross_entropy_with_logits(labels=label, logits=logit) for \

                logit, label in zip(logits, y_as_list)]

      total_loss = tf.reduce_mean(losses)

      train_step = tf.train.AdagradOptimizer(learning_rate).minimize(total_loss)

      模型訓練

      定義好我們的模型之后,接下來就是將數據傳入,然后進行訓練,代碼入下:

      def train_network(num_epochs, num_steps, state_size=4, verbose=True):

          with tf.Session() as sess:

              sess.run(tf.global_variables_initializer())

              training_losses = []

              #得到數據,因為num_epochs==1,所以外循環只執行一次

              for idx, epoch in enumerate(gen_epochs(num_epochs, num_steps)):

                  training_loss = 0

                  #保存每次執行后的最后狀態,然后賦給下一次執行

                  training_state = np.zeros((batch_size, state_size))

                  if verbose:

                      print("\nEPOCH", idx)

                  #這是具體獲得數據的部分,應該會執行1000000//200//5 = 1000次,即每次執行傳入的數據是batch_size*num_steps個(1000),共1000000個,所以每個num_epochs需要執行1000次。

                  for step, (X, Y) in enumerate(epoch):

                      tr_losses, training_loss_, training_state, _ = \

                          sess.run([losses,

                                    total_loss,

                                    final_state,

                                    train_step],

                                        feed_dict={x:X, y:Y, init_state:training_state})

                      training_loss += training_loss_

                      if step % 100 == 0 and step > 0:

                          if verbose:

                              print("Average loss at step", step,

                                    "for last 250 steps:", training_loss/100)

                          training_losses.append(training_loss/100)

                          training_loss = 0


          return training_losses

      training_losses = train_network(1,num_steps)

      plt.plot(training_losses)

      plt.show()

      實驗結果如下所示: 

      簡單實用的 TensorFlow 實現 RNN 入門教程

      從上圖可以看出交叉熵最終穩定在0。52,按照我們上面的分析可以知道:RNN模型成功的學習到了第一條依賴關系,因為我們的循環步長選擇的是5,所以他只能學習到t-3的第一條依賴關系,而無法學習到t-8的第二條依賴。 
      接下來可以嘗試num_steps==10,區捕捉第二條依賴關系。最終的結果圖如下所示: 

      簡單實用的 TensorFlow 實現 RNN 入門教程

      從上圖可以看出,我們的RNN模型成功的學習到了兩條依賴關系。最終的交叉熵未定在0.46附近。

      幾點改進

      1,首先上面的代碼中,為了盡可能詳細的解釋TensorFlow中RNN模型的構造方法,將rnn_cell的定義寫的很詳細,其實這些工作tf已經封裝好了,我們只需要一行命令就可以實現,所以第一個要改進的地方就是將rnn_cell的定義和循環使用部分的代碼簡化:

      #定義rnn_cell的權重參數,

      with tf.variable_scope('rnn_cell'):

          W = tf.get_variable('W', [num_classes + state_size, state_size])

          b = tf.get_variable('b', [state_size], initializer=tf.constant_initializer(0.0))

      #使之定義為reuse模式,循環使用,保持參數相同

      def rnn_cell(rnn_input, state):

          with tf.variable_scope('rnn_cell', reuse=True):

              W = tf.get_variable('W', [num_classes + state_size, state_size])

              b = tf.get_variable('b', [state_size], initializer=tf.constant_initializer(0.0))

          #定義rnn_cell具體的操作,這里使用的是最簡單的rnn,不是LSTM

          return tf.tanh(tf.matmul(tf.concat([rnn_input, state], 1), W) + b)


      state = init_state

      rnn_outputs = []

      #循環num_steps次,即將一個序列輸入RNN模型

      for rnn_input in rnn_inputs:

          state = rnn_cell(rnn_input, state)

          rnn_outputs.append(state)

      final_state = rnn_outputs[-1]


      #----------------------上面是原始代碼,定義了rnn_cell,然后使用循環的方式對其進行復用,簡化之后我們可以直接調用BasicRNNCell和static_rnn兩個函數實現------------------------


      cell = tf.contrib.rnn.BasicRNNCell(state_size)

      rnn_outputs, final_state = tf.contrib.rnn.static_rnn(cell, rnn_inputs, initial_state=init_state)

      2,使用動態rnn模型,上面的模型中,我們將輸入表示成列表的形式,即rnn_inputs是一個長度為num_steps的列表,其中每個元素是[batch_size, features]的tensor(即每個rnn_cell要處理的數據),這樣做事比較麻煩的,我們還可以使用tf提供的dynamic_rnn函數,這樣做不僅會使編程更加簡單,還可以提高計算效率。使用dynamic_rnn 時,我們直接將輸入表示成[batch_size, num_steps, features]的三維Tensor即可。最終的動態RNN模型代碼如下所示:

      x = tf.placeholder(tf.int32, [batch_size, num_steps], name='input_placeholder')

      y = tf.placeholder(tf.int32, [batch_size, num_steps], name='labels_placeholder')

      init_state = tf.zeros([batch_size, state_size])


      rnn_inputs = tf.one_hot(x, num_classes)

      #注意這里去掉了這行代碼,因為我們不需要將其表示成列表的形式在使用循環去做。

      #rnn_inputs = tf.unstack(x_one_hot, axis=1)


      cell = tf.contrib.rnn.BasicRNNCell(state_size)

      #使用dynamic_rnn函數,動態構建RNN模型

      rnn_outputs, final_state = tf.nn.dynamic_rnn(cell, rnn_inputs, initial_state=init_state)


      with tf.variable_scope('softmax'):

          W = tf.get_variable('W', [state_size, num_classes])

          b = tf.get_variable('b', [num_classes], initializer=tf.constant_initializer(0.0))

      logits = tf.reshape(

                  tf.matmul(tf.reshape(rnn_outputs, [-1, state_size]), W) + b,

                  [batch_size, num_steps, num_classes])

      predictions = tf.nn.softmax(logits)


      losses = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)

      total_loss = tf.reduce_mean(losses)

      train_step = tf.train.AdagradOptimizer(learning_rate).minimize(total_loss)

      至此,我們就實現了一個很簡單的RNN模型的構造,在這個過程中,我們需要注意的主要有以下三點:

      • 如何將數據轉化成rnn所能接受的輸入格式,需要注意batch_size和num_steps之間的關系。

      • 定義rnn_cell,這里使用的是下面這條命令:cell = tf.contrib.rnn.BasicRNNCell(state_size)

      • 定義RNN模型,可以使用下面這兩條命令分別靜態和動態構建:

      rnn_outputs, final_state = tf.contrib.rnn.static_rnn(cell, rnn_inputs, initial_state=init_state)

      rnn_outputs, final_state = tf.nn.dynamic_rnn(cell, rnn_inputs, initial_state=init_state)

      雷鋒網(公眾號:雷鋒網)相關閱讀:

      從原理到實戰 英偉達教你用PyTorch搭建RNN(上)

      從原理到實戰 英偉達教你用PyTorch搭建RNN(下)

      雷峰網版權文章,未經授權禁止轉載。詳情見轉載須知

      簡單實用的 TensorFlow 實現 RNN 入門教程

      分享:
      相關文章

      編輯

      聚焦數據科學,連接 AI 開發者。更多精彩內容,請訪問:yanxishe.com
      當月熱門文章
      最新文章
      請填寫申請人資料
      姓名
      電話
      郵箱
      微信號
      作品鏈接
      個人簡介
      為了您的賬戶安全,請驗證郵箱
      您的郵箱還未驗證,完成可獲20積分喲!
      請驗證您的郵箱
      立即驗證
      完善賬號信息
      您的賬號已經綁定,現在您可以設置密碼以方便用郵箱登錄
      立即設置 以后再說
      主站蜘蛛池模板: 97人妻熟女成人免费视频色戒| 中文字幕日本六区小电影| 亚洲日本视频一区二区三区 | 天天躁日日躁狠狠躁欧美老妇| 成 人 色 网 站免费观看| 熟妇人妻无码中文字幕老熟妇| 亚洲色成人网站www永久四虎| 国产乱理伦片在线观看| 丁香花在线观看免费观看图片 | 性刺激的大陆三级视频| 日本国产制服丝袜一区| 天天躁夜夜躁狠狠综合2020| 日韩高清无码一卡二卡| 精品在免费线中文字幕久久| 狠狠色综合久久丁香婷婷| 亚洲无码五区| 老王av| 97国产精东麻豆人妻电影| 图片区小说区激情区偷拍区| 伊人久久大香线蕉av色婷婷色| 人妻中文字幕亚洲| 91茄子| 久久久噜噜噜久久中文字幕色伊伊| 日本熟妇浓毛| 亚洲无码资源| 日韩少妇内射免费播放18禁裸乳| 成人美女黄网站色大免费的| 少妇久久久久久被弄高潮| 日韩中文字幕一区二区| 97碰碰碰人妻视频无码| 济源市| 国产一区二区三区视频| 日韩有码中文字幕国产| 日韩精品人妻中文字幕不卡乱码| 丰满岳乱妇一区二区三区| www内射国产在线观看| 久久综合九色综合欧美就去吻| 国产成人亚洲综合色婷婷秒播 | 亚洲v在线| 97中文字幕在线观看| 内射视频福利在线观看|