Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么使用for循环实现RNN中的慢速学习? 问题设置_Python_Tensorflow - Fatal编程技术网

Python 为什么使用for循环实现RNN中的慢速学习? 问题设置

Python 为什么使用for循环实现RNN中的慢速学习? 问题设置,python,tensorflow,Python,Tensorflow,作为RNN的初学者,我目前正在为4个字母的单词构建一个3对1自动补全RNN模型,其中输入是一个3个字母的不完整单词,输出是一个完成单词的单个字母。例如,我希望有以下模型预测: 输入:“C”、“A”、“F” 输出:“E” 代码-生成数据集 为了从RNN模型中获得所需的结果,我制作了一个(不平衡)数据集,如下所示: import string import numpy as np import tensorflow as tf import matplotlib.pyplot a

作为RNN的初学者,我目前正在为4个字母的单词构建一个3对1自动补全RNN模型,其中输入是一个3个字母的不完整单词,输出是一个完成单词的单个字母。例如,我希望有以下模型预测:

  • 输入:“C”、“A”、“F”
  • 输出:“E”

代码-生成数据集 为了从RNN模型中获得所需的结果,我制作了一个(不平衡)数据集,如下所示:

import string
import numpy as np       
import tensorflow as tf
import matplotlib.pyplot as plt

alphList  = list(string.ascii_uppercase) # Define a list of alphabets
alphToNum = {n: i for i, n in enumerate(alphList)} # dic of alphabet-numbers

# Make dataset
# define words of interest
fourList = ['CARE', 'CODE', 'COME', 'CANE', 'COPE', 'FISH', 'JAZZ', 'GAME', 'WALK', 'QUIZ']

# (len(Sequence), len(Batch), len(Observation)) following tensorflow-style
first3Data = np.zeros((3, len(fourList), len(alphList)), dtype=np.int32)
last1Data  = np.zeros((len(fourList), len(alphList)), dtype=np.int32)

for idxObs, word in enumerate(fourList):
    # Make an array of one-hot vectors consisting of first 3 letters
    first3 = [alphToNum[n] for n in word[:-1]]
    first3Data[:,idxObs,:] = np.eye(len(alphList))[first3]
    # Make an array of one-hot vectors consisting of last 1 letter
    last1  = alphToNum[word[3]]
    last1Data[idxObs,:]    = np.eye(len(alphList))[last1]
tf.nn.tanh(iX @ W_in + (h_state @ W_rec + b_rec))
因此,
fourList
包含训练数据信息,
first3Data
包含训练数据的前3个热编码字母,
last1Data
包含训练数据的最后1个热编码字母


代码-构建模型 按照3:1RNN模型的标准设置,我编写了以下代码

# Hyperparameters
n_data        = len(fourList)
n_input       = len(alphList)  # number of input units
n_hidden      = 128            # number of hidden units
n_output      = len(alphList)  # number of output units
learning_rate = 0.01
total_epoch   = 100000

# Variables (separate version)
W_in  = tf.Variable(tf.random_normal([n_input, n_hidden]))
W_rec = tf.Variable(tf.random_normal([n_hidden, n_hidden]))
b_rec = tf.Variable(tf.random_normal([n_hidden]))
W_out = tf.Variable(tf.random_normal([n_hidden, n_output]))
b_out = tf.Variable(tf.random_normal([n_output]))

# Manual calculation of RNN output
def RNNoutput(Xinput):
    h_state    = tf.random_normal([1,n_hidden]) # initial hidden state

    for iX in Xinput:
        h_state = tf.nn.tanh(iX @ W_in + (h_state @ W_rec + b_rec))

    rnn_output = h_state @ W_out + b_out
    return(rnn_output)
请注意,
手动计算RNN输出
部分基本上使用矩阵乘法和
tanh
激活功能精确滚动隐藏状态4次,如下所示:

import string
import numpy as np       
import tensorflow as tf
import matplotlib.pyplot as plt

alphList  = list(string.ascii_uppercase) # Define a list of alphabets
alphToNum = {n: i for i, n in enumerate(alphList)} # dic of alphabet-numbers

# Make dataset
# define words of interest
fourList = ['CARE', 'CODE', 'COME', 'CANE', 'COPE', 'FISH', 'JAZZ', 'GAME', 'WALK', 'QUIZ']

# (len(Sequence), len(Batch), len(Observation)) following tensorflow-style
first3Data = np.zeros((3, len(fourList), len(alphList)), dtype=np.int32)
last1Data  = np.zeros((len(fourList), len(alphList)), dtype=np.int32)

for idxObs, word in enumerate(fourList):
    # Make an array of one-hot vectors consisting of first 3 letters
    first3 = [alphToNum[n] for n in word[:-1]]
    first3Data[:,idxObs,:] = np.eye(len(alphList))[first3]
    # Make an array of one-hot vectors consisting of last 1 letter
    last1  = alphToNum[word[3]]
    last1Data[idxObs,:]    = np.eye(len(alphList))[last1]
tf.nn.tanh(iX @ W_in + (h_state @ W_rec + b_rec))
在这里,每次传递整个数据时,就完成一个历元。因此,每次传递数据时,我都会初始化h_状态。另外,请注意,我并没有使用占位符,这可能是导致学习不稳定的原因之一


代码-列车 我使用了以下代码来训练网络

# Cost / optimizer definition
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=RNNoutput(first3Data),
                                                                 labels=last1Data))
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)

# Train and keep track of the loss history
sess = tf.Session()
sess.run(tf.global_variables_initializer())

lossHistory = []
for epoch in range(total_epoch):
    _, loss = sess.run([optimizer, cost])
    lossHistory.append(loss)

问题 由此产生的学习曲线如下所示。事实上,它显示出指数衰减

然而,对我来说,对于这种简单的例子来说,它看起来太不稳定了,甚至在学习的后期也表现出一些不稳定性

plt.plot(range(total_epoch), lossHistory)
plt.show()


可能的解释? 我认为使用
tensorflow
内置函数(*),学习曲线应显示出预期的方形稳定衰减模式。但我认为这种不稳定性可以合理地解释如下:

  • 参数随机初始化的不稳定性
  • 定义
    RNNoutput
  • 不对循环使用
    张量,而是直接在数据中使用for循环
但我认为这些都没有起到关键作用还有其他解决方案可以帮助我吗



(*)对于简单RNN,我使用
tensorflow
内置函数看到了近似方形的损耗衰减。但很抱歉,我没有包括要比较的结果,因为我没有时间。。。我想我很快就可以编辑了

初始状态设置为零的修改似乎解决了问题

# Variables (separate version)
W_in  = tf.Variable(tf.random_normal([n_input, n_hidden]))
W_rec = tf.Variable(tf.random_normal([n_hidden, n_hidden]))
b_rec = tf.Variable(tf.random_normal([n_hidden]))
W_out = tf.Variable(tf.random_normal([n_hidden, n_output]))
b_out = tf.Variable(tf.random_normal([n_output]))
h_init = tf.zeros([1,n_hidden])

# Manual calculation of RNN output
def RNNoutput(Xinput):
    h_state    =  h_init # initial hidden state

    for iX in Xinput:
        h_state = tf.nn.tanh(iX @ W_in + (h_state @ W_rec + b_rec))

    rnn_output = h_state @ W_out + b_out
    return(rnn_output)

您是否每次将数据传递到RNN时都将初始的
h_状态
随机化?@openseasure是的,因为在这里每次传递数据时,一个历元就完成了。每次一个历元完成时,我们都会随机化初始h_状态,这不是真的吗?通常不是。你应该始终保持它为零,或者始终保持一个固定的数字(每个历元都相同)。你可以在训练中优化这个固定数字。@OpenSeason谢谢,有趣的是我还没有意识到。然后,
tensorflow
内置函数(例如
tf.nn.rnn\u cell.basicrncell()
)是否会自动将初始h\u状态保持为零或一个优化的数字。我没有使用这个函数,但这个想法并不新鲜,即使在Ilya Sutskever第10页的论文中,也有关于如何计算可学习初始状态的梯度的描述
h0
非常感谢!