为复杂文本分类微调 CNN 超参数
Fine tuning CNN hyperparameters for complex text classification
我正在研究用于复杂文本分类(主要是电子邮件和消息)的 CNN 模型。该数据集包含分布在 10 个不同 类 上的大约 10 万个条目。我实际的 Keras 顺序模型具有以下结构:
model = Sequential(
[
Embedding(
input_dim=10000,
output_dim=150,
input_length=400),
Convolution1D(
filters=128,
kernel_size=4,
padding='same',
activation='relu'),
BatchNormalization(),
MaxPooling1D(),
Flatten(),
Dropout(0.4),
Dense(
100,
activation='relu'),
Dropout(0.4),
Dense(
len(y_train[0]),
activation='softmax')])
在编译模型时,我使用 Nadam 优化器、categorical_crossentropy 损失和 LabelSmoothing 设置为 0.2 。
在模型拟合中,我使用 30 个时期 和 批量大小 设置为 512.我还使用 EarlyStopping 来监控 val_loss 并将耐心设置为 8 个时期。测试大小设置为数据集的 25%。
实际上训练在 16/18 个 epoch 后停止,值在 6/7 epoch 后开始稍微波动,然后继续直到被 EarlyStopping 停止。这些值平均如下:
损失:1.1673 - 精度:0.9674 - val_loss:1.2464 - val_accuracy:0.8964
测试准确率达到:
损失:1.2461 - 精度:0.8951
现在我想提高我的 CNN 的准确性,我尝试了不同的超参数,但就目前而言,我无法获得更高的值。因此我想弄清楚:
- 如果还有改进的余地(我敢打赌)
- 如果解决方案是微调我的超参数,如果是这样,我应该更改哪些?
- 如果通过向模型添加层来更深入可能有任何用处,如果是这样,如何改进我的模型
- 是否有任何其他 deep-learning/Neural 网络方法而不是 CNN 可以产生更好的结果?
非常感谢任何愿意提供帮助的人! :)
有很多库,但我发现这个非常灵活。 https://github.com/keras-team/keras-tuner
用pip安装即可。
您更新的模型,请随意选择搜索范围。
from tensorflow import keras
from tensorflow.keras import layers
from kerastuner.tuners import RandomSearch
def build_model(hp):
model = keras.Sequential()
model.add(layers.Embedding(input_dim=hp.Int('input_dim',
min_value=5000,
max_value=10000,
step = 1000),
output_dim=hp.Int('output_dim',
min_value=200,
max_value=800,
step = 100),
input_length = 400))
model.add(layers.Convolution1D(
filters=hp.Int('filters',
min_value=32,
max_value=512,
step = 32),
kernel_size=hp.Int('kernel_size',
min_value=3,
max_value=11,
step = 2),
padding='same',
activation='relu')),
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling1D())
model.add(layers.Flatten())
model.add(layers.Dropout(0.4))
model.add(layers.Dense(units=hp.Int('units',
min_value=64,
max_value=256,
step=32),
activation='relu'))
model.add(layers.Dropout(0.4))
model.add(layers.Dense(y_train[0], activation='softmax'))
model.compile(
optimizer=keras.optimizers.Adam(
hp.Choice('learning_rate',
values=[1e-2, 1e-3, 1e-4])),
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
tuner = RandomSearch(
build_model,
objective='val_accuracy',
max_trials=5,
executions_per_trial=3,
directory='my_dir',
project_name='helloworld')
tuner.search_space_summary()
## The following lines are based on your model
tuner.search(x, y,
epochs=5,
validation_data=(val_x, val_y))
models = tuner.get_best_models(num_models=2)
您可以尝试将 Conv1D 层替换为 LSTM 层并观察是否获得更好的性能。
LSTM(units = 512)
https://keras.io/layers/recurrent/
如果您想提取更有意义的特征,我发现一种很有前途的方法是提取预训练的 BERT 特征,然后使用 CNN/LSTM.
进行训练
这是一个很好的入门知识库 -
https://github.com/UKPLab/sentence-transformers
一旦你从 BERT/XLNet 中得到句子嵌入,你就可以使用这些特征来训练另一个与你正在使用的 CNN 相似的 CNN,除了可能会去掉嵌入层,因为它很昂贵。
我正在研究用于复杂文本分类(主要是电子邮件和消息)的 CNN 模型。该数据集包含分布在 10 个不同 类 上的大约 10 万个条目。我实际的 Keras 顺序模型具有以下结构:
model = Sequential(
[
Embedding(
input_dim=10000,
output_dim=150,
input_length=400),
Convolution1D(
filters=128,
kernel_size=4,
padding='same',
activation='relu'),
BatchNormalization(),
MaxPooling1D(),
Flatten(),
Dropout(0.4),
Dense(
100,
activation='relu'),
Dropout(0.4),
Dense(
len(y_train[0]),
activation='softmax')])
在编译模型时,我使用 Nadam 优化器、categorical_crossentropy 损失和 LabelSmoothing 设置为 0.2 。
在模型拟合中,我使用 30 个时期 和 批量大小 设置为 512.我还使用 EarlyStopping 来监控 val_loss 并将耐心设置为 8 个时期。测试大小设置为数据集的 25%。
实际上训练在 16/18 个 epoch 后停止,值在 6/7 epoch 后开始稍微波动,然后继续直到被 EarlyStopping 停止。这些值平均如下:
损失:1.1673 - 精度:0.9674 - val_loss:1.2464 - val_accuracy:0.8964
测试准确率达到:
损失:1.2461 - 精度:0.8951
现在我想提高我的 CNN 的准确性,我尝试了不同的超参数,但就目前而言,我无法获得更高的值。因此我想弄清楚:
- 如果还有改进的余地(我敢打赌)
- 如果解决方案是微调我的超参数,如果是这样,我应该更改哪些?
- 如果通过向模型添加层来更深入可能有任何用处,如果是这样,如何改进我的模型
- 是否有任何其他 deep-learning/Neural 网络方法而不是 CNN 可以产生更好的结果?
非常感谢任何愿意提供帮助的人! :)
有很多库,但我发现这个非常灵活。 https://github.com/keras-team/keras-tuner
用pip安装即可。
您更新的模型,请随意选择搜索范围。
from tensorflow import keras
from tensorflow.keras import layers
from kerastuner.tuners import RandomSearch
def build_model(hp):
model = keras.Sequential()
model.add(layers.Embedding(input_dim=hp.Int('input_dim',
min_value=5000,
max_value=10000,
step = 1000),
output_dim=hp.Int('output_dim',
min_value=200,
max_value=800,
step = 100),
input_length = 400))
model.add(layers.Convolution1D(
filters=hp.Int('filters',
min_value=32,
max_value=512,
step = 32),
kernel_size=hp.Int('kernel_size',
min_value=3,
max_value=11,
step = 2),
padding='same',
activation='relu')),
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling1D())
model.add(layers.Flatten())
model.add(layers.Dropout(0.4))
model.add(layers.Dense(units=hp.Int('units',
min_value=64,
max_value=256,
step=32),
activation='relu'))
model.add(layers.Dropout(0.4))
model.add(layers.Dense(y_train[0], activation='softmax'))
model.compile(
optimizer=keras.optimizers.Adam(
hp.Choice('learning_rate',
values=[1e-2, 1e-3, 1e-4])),
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
tuner = RandomSearch(
build_model,
objective='val_accuracy',
max_trials=5,
executions_per_trial=3,
directory='my_dir',
project_name='helloworld')
tuner.search_space_summary()
## The following lines are based on your model
tuner.search(x, y,
epochs=5,
validation_data=(val_x, val_y))
models = tuner.get_best_models(num_models=2)
您可以尝试将 Conv1D 层替换为 LSTM 层并观察是否获得更好的性能。
LSTM(units = 512)
https://keras.io/layers/recurrent/
如果您想提取更有意义的特征,我发现一种很有前途的方法是提取预训练的 BERT 特征,然后使用 CNN/LSTM.
进行训练这是一个很好的入门知识库 - https://github.com/UKPLab/sentence-transformers
一旦你从 BERT/XLNet 中得到句子嵌入,你就可以使用这些特征来训练另一个与你正在使用的 CNN 相似的 CNN,除了可能会去掉嵌入层,因为它很昂贵。