编辑:我看到有人给这个帖子投了反对票,请告诉我我做错了什么,以便我将来避免犯同样的错误。谢谢
我对深度学习非常新手,目前正在研究我的第一个非教程基础的RNN模型,但结果非常差。
我创建了一个由Anthony Fantano的专辑评论数据集,目标是评分在1到9之间(这里)。我的目标是使用情感分析基于输入文本预测一个分数。
首先,我使用keras的Tokenizer
工具类来预处理我的原始文本,然后我将基于token的文本填充/截断到最大尺寸np.mean(num_tokens) + 2 * np.std(num_tokens)
,接着我创建一个嵌入向量(使用keras的Embedding
类)。
我对目标数据使用了一热编码,编码向量的长度为10。
我的网络产生了一个长度为10的向量,并使用softmax
激活函数,我使用categorical_crossentropy
作为我的损失函数。我对GRU单元的大小选择(这是正确的术语吗?)是任意的,但我尝试调整它们并没有得到更好的结果。
model = Sequential()model.add(embedding)model.add(GRU(units=32, return_sequences=True))model.add(GRU(units=16))model.add(Dense(10, activation='softmax'))optimizer = SGD(lr=0.01)model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])model.summary()model.fit(x_pad, y_encoded, validation_split=0.05, epochs=5, batch_size=64)
这是我的网络在keras中的摘要
_________________________________________________________________Layer (type) Output Shape Param #=================================================================layer_embedding (Embedding) (None, 2290, 8) 8000_________________________________________________________________gru_1 (GRU) (None, 2290, 32) 3936_________________________________________________________________gru_2 (GRU) (None, 16) 2352_________________________________________________________________dense_1 (Dense) (None, 10) 170=================================================================Total params: 14,458Trainable params: 14,458Non-trainable params: 0_________________________________________________________________Train on 259 samples, validate on 14 samples
我的准确率在学习率为0.01时,总是收敛到0.3166,但我不知道为什么
259/259 [==============================] - 18s 68ms/step - loss: 2.2998 - acc: 0.2124 - val_loss: 2.2935 - val_acc: 0.4286Epoch 2/10259/259 [==============================] - 16s 63ms/step - loss: 2.2927 - acc: 0.2973 - val_loss: 2.2854 - val_acc: 0.3571Epoch 3/10259/259 [==============================] - 16s 61ms/step - loss: 2.2822 - acc: 0.2471 - val_loss: 2.2767 - val_acc: 0.3571Epoch 4/10259/259 [==============================] - 15s 58ms/step - loss: 2.2728 - acc: 0.2973 - val_loss: 2.2681 - val_acc: 0.4286Epoch 5/10259/259 [==============================] - 15s 58ms/step - loss: 2.2651 - acc: 0.3166 - val_loss: 2.2575 - val_acc: 0.4286Epoch 6/10259/259 [==============================] - 15s 58ms/step - loss: 2.2548 - acc: 0.3166 - val_loss: 2.2496 - val_acc: 0.4286Epoch 7/10259/259 [==============================] - 15s 57ms/step - loss: 2.2469 - acc: 0.3166 - val_loss: 2.2420 - val_acc: 0.4286Epoch 8/10259/259 [==============================] - 15s 58ms/step - loss: 2.2382 - acc: 0.3166 - val_loss: 2.2325 - val_acc: 0.4286Epoch 9/10259/259 [==============================] - 15s 58ms/step - loss: 2.2305 - acc: 0.3166 - val_loss: 2.2265 - val_acc: 0.4286Epoch 10/10259/259 [==============================] - 15s 58ms/step - loss: 2.2222 - acc: 0.3166 - val_loss: 2.2158 - val_acc: 0.4286
我能想到的两个可能原因,第一是我的学习率太大(因为准确率似乎有跳跃,表明超调)。我尝试将其降低到0.05,但在20个epoch后我的准确率无法超过0.2046。我还尝试使用随机梯度下降和Adam优化器,但都没有产生显著不同的结果。
我能想到的另一个可能原因是我的数据集太小(只有259个样本),但我甚至无法通过过拟合获得高准确率,所以我认为这不是问题?另外,我的实际特征数据(原始文本)非常大且详尽。
如果有帮助,我的完整源代码文件可在此处获取这里。
任何帮助都将不胜感激,无论是指引方向还是纠正我的理解。谢谢
回答:
我认为你对数据集的处理有误。你有从1到9的评分范围,尽管这不是连续范围,但它具有严格的总顺序,而你没有利用这一点。为了更清楚地说明我的观点,如果你的算法预测一个评论的得分为8,而真实标签是9,那么它可能是错误的,但只是稍微有些偏差。另一方面,如果它预测为1,那就大错特错了。你当前的系统无法区分这些,因为你将所有10个离散类别视为彼此同样遥远。我的建议是将目标函数切换到MSE,尽管你的数据是离散的,并使用一个包装器来测量准确率。这应该能帮助训练,你可以稍后再切换回交叉熵。
免责声明:我没有阅读你的代码,但我经常遇到类似的问题,并且我能够通过我描述的方式解决它们。