Tensorflow lstm 用于情感分析而不是学习。更新
Tensorflow lstm for sentiment analysis not learning. UPDATED
更新:
我正在为我的期末项目构建一个神经网络,我需要一些帮助。
我正在尝试构建一个 rnn 来对西班牙语文本进行情感分析。我有大约 200,000 条带标签的推文,我使用带有西班牙语嵌入的 word2vec 将它们矢量化
数据集和矢量化:
- 我删除了重复项并将数据集拆分为训练集和测试集。
- 向量化时应用填充、未知和句尾标记。
- 我将 @mentions 映射到 word2vec 模型中的已知名称。示例:@iamthebest => "John"
我的模型:
- 我的数据张量的形状 = (batch_size, 20, 300).
- 我有 3 个 类:中性的、正的和负的,所以我的目标张量的形状是 = (batch_size, 3)
- 我使用 BasicLstm 单元和动态 rnn 构建网络。
- 我使用 Adam 优化器,softmax_cross 熵用于损失计算
- 我使用 dropout wrapper 来减少过度拟合。
上次运行:
- 我尝试过不同的配置,但没有一个似乎有效。
- 上次设置:2 层,512 批量大小,15 轮和 0.001 lr。
我的弱点:
我担心 dynamic_rnn
中的最后一层和最终状态的处理
代码:
# set variables
num_epochs = 15
tweet_size = 20
hidden_size = 200
vec_size = 300
batch_size = 512
number_of_layers= 1
number_of_classes= 3
learning_rate = 0.001
TRAIN_DIR="/checkpoints"
tf.reset_default_graph()
# Create a session
session = tf.Session()
# Inputs placeholders
tweets = tf.placeholder(tf.float32, [None, tweet_size, vec_size], "tweets")
labels = tf.placeholder(tf.float32, [None, number_of_classes], "labels")
# Placeholder for dropout
keep_prob = tf.placeholder(tf.float32)
# make the lstm cells, and wrap them in MultiRNNCell for multiple layers
def lstm_cell():
cell = tf.contrib.rnn.BasicLSTMCell(hidden_size)
return tf.contrib.rnn.DropoutWrapper(cell=cell, output_keep_prob=keep_prob)
multi_lstm_cells = tf.contrib.rnn.MultiRNNCell([lstm_cell() for _ in range(number_of_layers)], state_is_tuple=True)
# Creates a recurrent neural network
outputs, final_state = tf.nn.dynamic_rnn(multi_lstm_cells, tweets, dtype=tf.float32)
with tf.name_scope("final_layer"):
# weight and bias to shape the final layer
W = tf.get_variable("weight_matrix", [hidden_size, number_of_classes], tf.float32, tf.random_normal_initializer(stddev=1.0 / math.sqrt(hidden_size)))
b = tf.get_variable("bias", [number_of_classes], initializer=tf.constant_initializer(1.0))
sentiments = tf.matmul(final_state[-1][-1], W) + b
prob = tf.nn.softmax(sentiments)
tf.summary.histogram('softmax', prob)
with tf.name_scope("loss"):
# define cross entropy loss function
losses = tf.nn.softmax_cross_entropy_with_logits(logits=sentiments, labels=labels)
loss = tf.reduce_mean(losses)
tf.summary.scalar("loss", loss)
with tf.name_scope("accuracy"):
# round our actual probabilities to compute error
accuracy = tf.to_float(tf.equal(tf.argmax(prob,1), tf.argmax(labels,1)))
accuracy = tf.reduce_mean(tf.cast(accuracy, dtype=tf.float32))
tf.summary.scalar("accuracy", accuracy)
# define our optimizer to minimize the loss
with tf.name_scope("train"):
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)
#tensorboard summaries
merged_summary = tf.summary.merge_all()
logdir = "tensorboard/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + "/"
writer = tf.summary.FileWriter(logdir, session.graph)
# initialize any variables
tf.global_variables_initializer().run(session=session)
# Create a saver for writing training checkpoints.
saver = tf.train.Saver()
# load our data and separate it into tweets and labels
train_tweets = np.load('data_es/train_vec_tweets.npy')
train_labels = np.load('data_es/train_vec_labels.npy')
test_tweets = np.load('data_es/test_vec_tweets.npy')
test_labels = np.load('data_es/test_vec_labels.npy')
**HERE I HAVE THE LOOP FOR TRAINING AND TESTING, I KNOW ITS FINE**
我已经解决了我的问题。在阅读了一些论文和更多的尝试和错误之后,我弄清楚了我的错误所在。
1) 数据集:我有一个很大的数据集,但我没有正确格式化它。
- 我检查了推文标签的分布(中性、正面和负面),意识到所述推文的分布存在差异并将其标准化。
- 我通过删除 url 主题标签和不必要的标点符号进一步清理了它。
- 我在向量化之前洗牌了。
2)初始化:
- 我用零初始化了 MultiRNNCell,并将我的自定义最终层更改为 tf.contrib.fully_connected。我还添加了偏置和权重矩阵的初始化。 (通过解决这个问题,我开始在 Tensorboard 中看到更好的损失和准确度图)
3) 辍学:
- 我读了这篇论文,Recurrent Dropout without Memory Loss,我相应地改变了我的辍学;我开始看到损失和准确性有所改善。
4) 衰减学习率:
- 我在 10,000 步后添加了一个指数衰减率来控制过拟合。
最终结果:
应用所有这些更改后,我的测试准确率达到了 84%,这是可以接受的,因为我的数据集仍然很糟糕。
我的最终网络配置是:
- num_epochs = 20
- tweet_size = 20
- hidden_size = 400
- vec_size = 300
- batch_size = 512
- number_of_layers= 2
- number_of_classes=3
- start_learning_rate = 0.001
更新:
我正在为我的期末项目构建一个神经网络,我需要一些帮助。
我正在尝试构建一个 rnn 来对西班牙语文本进行情感分析。我有大约 200,000 条带标签的推文,我使用带有西班牙语嵌入的 word2vec 将它们矢量化
数据集和矢量化:
- 我删除了重复项并将数据集拆分为训练集和测试集。
- 向量化时应用填充、未知和句尾标记。
- 我将 @mentions 映射到 word2vec 模型中的已知名称。示例:@iamthebest => "John"
我的模型:
- 我的数据张量的形状 = (batch_size, 20, 300).
- 我有 3 个 类:中性的、正的和负的,所以我的目标张量的形状是 = (batch_size, 3)
- 我使用 BasicLstm 单元和动态 rnn 构建网络。
- 我使用 Adam 优化器,softmax_cross 熵用于损失计算
- 我使用 dropout wrapper 来减少过度拟合。
上次运行:
- 我尝试过不同的配置,但没有一个似乎有效。
- 上次设置:2 层,512 批量大小,15 轮和 0.001 lr。
我的弱点:
我担心 dynamic_rnn
中的最后一层和最终状态的处理代码:
# set variables
num_epochs = 15
tweet_size = 20
hidden_size = 200
vec_size = 300
batch_size = 512
number_of_layers= 1
number_of_classes= 3
learning_rate = 0.001
TRAIN_DIR="/checkpoints"
tf.reset_default_graph()
# Create a session
session = tf.Session()
# Inputs placeholders
tweets = tf.placeholder(tf.float32, [None, tweet_size, vec_size], "tweets")
labels = tf.placeholder(tf.float32, [None, number_of_classes], "labels")
# Placeholder for dropout
keep_prob = tf.placeholder(tf.float32)
# make the lstm cells, and wrap them in MultiRNNCell for multiple layers
def lstm_cell():
cell = tf.contrib.rnn.BasicLSTMCell(hidden_size)
return tf.contrib.rnn.DropoutWrapper(cell=cell, output_keep_prob=keep_prob)
multi_lstm_cells = tf.contrib.rnn.MultiRNNCell([lstm_cell() for _ in range(number_of_layers)], state_is_tuple=True)
# Creates a recurrent neural network
outputs, final_state = tf.nn.dynamic_rnn(multi_lstm_cells, tweets, dtype=tf.float32)
with tf.name_scope("final_layer"):
# weight and bias to shape the final layer
W = tf.get_variable("weight_matrix", [hidden_size, number_of_classes], tf.float32, tf.random_normal_initializer(stddev=1.0 / math.sqrt(hidden_size)))
b = tf.get_variable("bias", [number_of_classes], initializer=tf.constant_initializer(1.0))
sentiments = tf.matmul(final_state[-1][-1], W) + b
prob = tf.nn.softmax(sentiments)
tf.summary.histogram('softmax', prob)
with tf.name_scope("loss"):
# define cross entropy loss function
losses = tf.nn.softmax_cross_entropy_with_logits(logits=sentiments, labels=labels)
loss = tf.reduce_mean(losses)
tf.summary.scalar("loss", loss)
with tf.name_scope("accuracy"):
# round our actual probabilities to compute error
accuracy = tf.to_float(tf.equal(tf.argmax(prob,1), tf.argmax(labels,1)))
accuracy = tf.reduce_mean(tf.cast(accuracy, dtype=tf.float32))
tf.summary.scalar("accuracy", accuracy)
# define our optimizer to minimize the loss
with tf.name_scope("train"):
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)
#tensorboard summaries
merged_summary = tf.summary.merge_all()
logdir = "tensorboard/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + "/"
writer = tf.summary.FileWriter(logdir, session.graph)
# initialize any variables
tf.global_variables_initializer().run(session=session)
# Create a saver for writing training checkpoints.
saver = tf.train.Saver()
# load our data and separate it into tweets and labels
train_tweets = np.load('data_es/train_vec_tweets.npy')
train_labels = np.load('data_es/train_vec_labels.npy')
test_tweets = np.load('data_es/test_vec_tweets.npy')
test_labels = np.load('data_es/test_vec_labels.npy')
**HERE I HAVE THE LOOP FOR TRAINING AND TESTING, I KNOW ITS FINE**
我已经解决了我的问题。在阅读了一些论文和更多的尝试和错误之后,我弄清楚了我的错误所在。
1) 数据集:我有一个很大的数据集,但我没有正确格式化它。
- 我检查了推文标签的分布(中性、正面和负面),意识到所述推文的分布存在差异并将其标准化。
- 我通过删除 url 主题标签和不必要的标点符号进一步清理了它。
- 我在向量化之前洗牌了。
2)初始化:
- 我用零初始化了 MultiRNNCell,并将我的自定义最终层更改为 tf.contrib.fully_connected。我还添加了偏置和权重矩阵的初始化。 (通过解决这个问题,我开始在 Tensorboard 中看到更好的损失和准确度图)
3) 辍学:
- 我读了这篇论文,Recurrent Dropout without Memory Loss,我相应地改变了我的辍学;我开始看到损失和准确性有所改善。
4) 衰减学习率:
- 我在 10,000 步后添加了一个指数衰减率来控制过拟合。
最终结果:
应用所有这些更改后,我的测试准确率达到了 84%,这是可以接受的,因为我的数据集仍然很糟糕。
我的最终网络配置是:
- num_epochs = 20
- tweet_size = 20
- hidden_size = 400
- vec_size = 300
- batch_size = 512
- number_of_layers= 2
- number_of_classes=3
- start_learning_rate = 0.001