Python 用于复杂文本分类的CNN超参数微调

Python 用于复杂文本分类的CNN超参数微调,python,keras,deep-learning,text-classification,cnn,Python,Keras,Deep Learning,Text Classification,Cnn,我正在开发一个用于复杂文本分类(主要是电子邮件和消息)的CNN模型。该数据集包含分布在10个不同类上的大约10万个条目。我的实际Keras序列模型具有以下结构: model = Sequential( [ Embedding( input_dim=10000, output_dim=150, input_length=400), Conv

我正在开发一个用于复杂文本分类(主要是电子邮件和消息)的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优化器分类交叉熵损失,将标签平滑设置为0.2

在模型拟合中,我使用30个纪元批量大小设置为512。我还使用EarlyStoping来监控val_损失和耐心设置为8个时期。测试大小设置为数据集的25%

实际上,训练在16/18个纪元后停止,在6/7个纪元后,数值开始略有波动,然后继续进行,直到被提前停止。平均值如下所示:

损失:1.1673-精度:0.9674-瓦尔_损失:1.2464-瓦尔_精度:0.8964

测试精度达到:

损失:1.2461-准确度:0.8951

现在我想提高我的CNN的准确度,我尝试了不同的超参数,但到目前为止,我无法得到更高的值。因此,我试图弄明白:

  • 如果还有改进的余地(我敢打赌)
  • 如果解决方案是微调超参数,如果是,我应该更改哪些超参数
  • 如果通过向模型中添加层来进行更深入的研究有任何用处,如果有,如何改进我的模型
  • 除了CNN之外,还有其他深度学习/神经网络方法可以带来更好的结果吗

  • 非常感谢任何愿意帮忙的人!:)

    有很多库,但我觉得这一个非常灵活

    只需使用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)
    
    您可以尝试用LSTM层替换Conv1D层,并观察是否获得更好的性能

    LSTM(单位=512)

    如果您想提取更有意义的特征,我发现一种很有希望的方法是提取预训练的伯特特征,然后使用CNN/LSTM进行训练

    这是一个很好的入门知识库-


    一旦你从BERT/XLNet获得了句子嵌入,你就可以使用这些功能来训练另一个与你正在使用的CNN相似的CNN,只是可能会因为嵌入层太贵而去掉它。

    考虑使用网格搜索或通过超参数的高斯过程进行贝叶斯优化来调整你的模型。此外,你可以考虑使用LSTM神经网络来完成这类任务,非常感谢!明天我要试试这种方法!我会让你知道它的性能!:)@如果答案有助于您投票/接受,请致电奥德曼。