深層学習の実践 3 - テキスト畳み込みニューラル ネットワーク (TextCNN) ニュース テキスト分類

記事ディレクトリ

1. 事前作業
1. GPUの設定
2. 前処理レキシコンクラスのインポート
2. 前処理レキシコンクラスのインポート
3. パラメータ設定
4. モデルの作成
5. 学習モデル関数
6. モデル関数のテスト
7. 学習モデルと予測

今日は、TextCNN モデルをトレーニングに使用した、シンプルな中国語ニュース分類モデルを紹介します。TextCNN の主なプロセスは次のとおりです: テキストの局所特徴を取得する: さまざまなコンボリューション カーネル サイズを通じてテキストの N グラム情報を抽出するプーリング操作は、各畳み込み操作によって抽出された最も重要な情報を強調表示するために使用されます。スプライシング後、特徴は全結合層を通じて結合され、最後にモデルはクロスエントロピー損失関数を通じてトレーニングされます。

                                                                 textCNNのモデル アーキテクチャ
注: N-Gram は、大語彙の連続音声認識で一般的に使用される言語モデルです。一次マルコフ連鎖とも呼ばれます。その基本的な考え方は、バイトに従ってテキストのコンテンツに対してサイズ N のスライディング ウィンドウ操作を実行し、長さ N のバイト フラグメントのシーケンスを形成することです。各バイト セグメントはグラムと呼ばれ、すべてのグラムの出現頻度がカウントされ、事前に設定されたしきい値に従ってフィルタリングされて、このテキストのベクトル特徴空間であるキー グラムのリストが形成されます。リスト内の各グラムは特徴ベクトルの次元です。

1. 事前作業

1.GPUをセットアップする

CPU を使用している場合は、コードのこの部分をコメント アウトできます。

import tensorflow as tf
gpus = tf.config.list_physical_devices("GPU")

if gpus:
    gpu0 = gpus[0] #如果有多个GPU,仅使用第0个GPU
    tf.config.experimental.set_memory_growth(gpu0, True) #设置GPU显存用量按需使用
    tf.config.set_visible_devices([gpu0],"GPU")

#导入库包
import tensorflow.keras as keras
from config import Config
import os
from sklearn import metrics
import numpy as np
from keras.models import Sequential
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Embedding,Dropout,Conv1D,ReLU,GlobalMaxPool1D,InputLayer

2. 前処理シソーラスクラスのインポート

trainingSet_path = "cnews.train.txt"
valSet_path = "cnews.val.txt"
model_save_path = "CNN_model.h5"
testingSet_path = "cnews.test.txt"


#创建 文本处理类:preprocesser
class preprocesser(object):
    def __init__(self):
        self.config = Config()

    # 读取文本txt 函数
    def read_txt(self, txt_path):
        with open(txt_path, "r", encoding='utf-8') as f:
            data = f.readlines()
        labels = []
        contents = []
        for line in data:
            label, content = line.strip().split('\t')
            labels.append(label)
            contents.append(content)
        return labels, contents
    # 读取分词文档
    def get_vocab_id(self):

        vocab_path = "cnews.vocab.txt"
        with open(vocab_path, "r", encoding="utf-8") as f:
            infile = f.readlines()
        vocabs = list([word.replace("\n", "") for word in infile])
        vocabs_dict = dict(zip(vocabs, range(len(vocabs))))
        return vocabs, vocabs_dict

    # 获取新闻属性id 函数
    def get_category_id(self):
     
        categories = ["体育", "财经", "房产", "家居", "教育", "科技", "时尚", "时政", "游戏", "娱乐"]
        cates_dict = dict(zip(categories, range(len(categories))))
        return cates_dict

    #将语料中各文本转换成固定max_length后返回各文本的标签与文本tokens
    def word2idx(self, txt_path, max_length):

        # vocabs:分词词汇表
        # vocabs_dict:各分词的索引
        vocabs, vocabs_dict = self.get_vocab_id()
        # cates_dict:各分类的索引
        cates_dict = self.get_category_id()

        # 读取语料
        labels, contents = self.read_txt(txt_path)
        # labels_idx:用来存放语料中的分类
        labels_idx = []
        # contents_idx:用来存放语料中各样本的索引
        contents_idx = []

        # 遍历语料
        for idx in range(len(contents)):
            # tmp:存放当前语句index
            tmp = []
            # 将该idx(样本)的标签加入至labels_idx中
            labels_idx.append(cates_dict[labels[idx]])
            # contents[idx]:为该语料中的样本遍历项
            # 遍历contents中各词并将其转换为索引后加入contents_idx中
            for word in contents[idx]:
                if word in vocabs:
                    tmp.append(vocabs_dict[word])
                else:
                    # 第5000位设置为未知字符
                    tmp.append(5000)
            # 将该样本index后结果存入contents_idx作为结果等待传回
            contents_idx.append(tmp)

        # 将各样本长度pad至max_length
        x_pad = keras.preprocessing.sequence.pad_sequences(contents_idx, max_length)
        y_pad = keras.utils.to_categorical(labels_idx, num_classes=len(cates_dict))

        return x_pad, y_pad
    
    def word2idx_for_sample(self, sentence, max_length):
        # vocabs:分词词汇表
        # vocabs_dict:各分词的索引
        vocabs, vocabs_dict = self.get_vocab_id()
        result = []
        # 遍历语料
        for word in sentence:
            # tmp:存放当前语句index
                if word in vocabs:
                    result.append(vocabs_dict[word])
                else:
                    # 第5000位设置为未知字符,实际中为vocabs_dict[5000],使得vocabs_dict长度变成len(vocabs_dict+1)
                    result.append(5000)

        x_pad = keras.preprocessing.sequence.pad_sequences([result], max_length)
        return x_pad

pre = preprocesser() # 实例化preprocesser()类

データセットのスタイル:

 2.パラメータ設定

num_classes = 10     # 类别数
vocab_size = 5000    #语料词大小
seq_length = 600     #词长度

conv1_num_filters = 128   # 第一层输入卷积维数
conv1_kernel_size = 1     # 卷积核数

conv2_num_filters = 64   # 第二层输入卷维数
conv2_kernel_size = 1    # 卷积核数

hidden_dim = 128         # 隐藏层维度
dropout_keep_prob = 0.5  # dropout层丢弃0.5

batch_size = 64     # 每次训练批次数  

4. モデルを作成する

def TextCNN():
    #创建模型序列
    model = Sequential()
    model.add(InputLayer((seq_length,)))
    model.add(Embedding(vocab_size+1, 256, input_length=seq_length))
    model.add(Conv1D(conv1_num_filters, conv1_kernel_size, padding="SAME"))
    model.add(Conv1D(conv2_num_filters, conv2_kernel_size, padding="SAME"))
    model.add(GlobalMaxPool1D())
    model.add(Dense(hidden_dim))
    model.add(Dropout(dropout_keep_prob))
    model.add(ReLU())
    model.add(Dense(num_classes, activation="softmax"))
    model.compile(loss="categorical_crossentropy",
                  optimizer="adam",
                  metrics=["acc"])
    print(model.summary())

    return model

5. 学習モデル機能

def train(epochs):

    model = TextCNN()
    model.summary()

    x_train, y_train = pre.word2idx(trainingSet_path, max_length=seq_length)
    x_val, y_val = pre.word2idx(valSet_path, max_length=seq_length)

    model.fit(x_train, y_train,batch_size=batch_size,epochs=epochs,validation_data=(x_val, y_val))

    model.save(model_save_path, overwrite=True)

 6. テストモデル機能

def test():

    if os.path.exists(model_save_path):
        model = keras.models.load_model(model_save_path)
        print("-----model loaded-----")
        model.summary()

    x_test, y_test = pre.word2idx(testingSet_path, max_length=seq_length)
    print(x_test.shape)
    print(type(x_test))
    print(y_test.shape)
    # print(type(y_test))
    pre_test = model.predict(x_test)
    # print(pre_test.shape)
    # metrics.classification_report(np.argmax(pre_test, axis=1), np.argmax(y_test, axis=1), digits=4, output_dict=True)
    print(metrics.classification_report(np.argmax(pre_test, axis=1), np.argmax(y_test, axis=1)))

7. トレーニングモデルと予測

if __name__ == '__main__':

    train(20)  # 训练模型

Epoch 1/20
782/782 [==============================] - 119s 152ms/step - loss: 0.7380 - accuracy: 0.7696 - val_loss: 0.5568 - val_accuracy: 0.8334
Epoch 2/20
782/782 [==============================] - 122s 156ms/step - loss: 0.3898 - accuracy: 0.8823 - val_loss: 0.4342 - val_accuracy: 0.8588
Epoch 3/20
782/782 [==============================] - 121s 154ms/step - loss: 0.3382 - accuracy: 0.8979 - val_loss: 0.4154 - val_accuracy: 0.8648
Epoch 4/20
782/782 [==============================] - 116s 148ms/step - loss: 0.3091 - accuracy: 0.9055 - val_loss: 0.4408 - val_accuracy: 0.8688
Epoch 5/20
782/782 [==============================] - 117s 150ms/step - loss: 0.2904 - accuracy: 0.9116 - val_loss: 0.3880 - val_accuracy: 0.8844
Epoch 6/20
782/782 [==============================] - 119s 153ms/step - loss: 0.2724 - accuracy: 0.9153 - val_loss: 0.4412 - val_accuracy: 0.8664
Epoch 7/20
782/782 [==============================] - 117s 149ms/step - loss: 0.2601 - accuracy: 0.9206 - val_loss: 0.4217 - val_accuracy: 0.8726
Epoch 8/20
782/782 [==============================] - 116s 149ms/step - loss: 0.2423 - accuracy: 0.9243 - val_loss: 0.4205 - val_accuracy: 0.8760
Epoch 9/20
782/782 [==============================] - 117s 150ms/step - loss: 0.2346 - accuracy: 0.9275 - val_loss: 0.4022 - val_accuracy: 0.8808
Epoch 10/20
782/782 [==============================] - 116s 148ms/step - loss: 0.2249 - accuracy: 0.9301 - val_loss: 0.4297 - val_accuracy: 0.8726
....
   
    model = keras.models.load_model(model_save_path)
    print("-----model loaded-----")
    model.summary()
    test = preprocesser()

    # 测试文本
    x_test = '5月6日,上海莘庄基地田径特许赛在第二体育运动学校鸣枪开赛。男子110米栏决赛,19岁崇明小囡秦伟搏以13.35秒的成绩夺冠,创造本赛季亚洲最佳。谢文骏迎来赛季首秀,以13.38秒获得亚军'
    x_test = test.word2idx_for_sample(x_test, 600)

    categories = ["体育", "财经", "房产", "家居", "教育", "科技", "时尚", "时政", "游戏", "娱乐"]

    pre_test = model.predict(x_test)

    index = int(np.argmax(pre_test, axis=1)[0])

    print('该新闻为:', categories[index])

20 回トレーニングした後、トレーニング セットの損失関数の損失: 0.1635、トレーニング セットの精度: 精度: 0.9462

検証セット関数: val_loss: 0.4554 検証セット精度 val_accuracy: 0.8820

走行結果: ニュースは: スポーツ

 過去の作品:

ディープラーニング実践プロジェクト

1. ディープラーニングの実践 1-(keras フレームワーク) エンタープライズ データの分析と予測

2. ディープラーニングの実践 2 - (keras フレームワーク) 企業の信用格付けと予測

3. 深層学習の実践 3 テキスト畳み込みニューラル ネットワーク (TextCNN) ニュース テキスト分類

4. ディープ ラーニング コンバット 4 - 畳み込みニューラル ネットワーク (DenseNet) 数学的グラフィック認識 + トピック パターン認識

5. 深層学習の実践 5-畳み込みニューラル ネットワーク (CNN) 中国語 OCR 認識プロジェクト

6. ディープラーニング戦闘 6 - 畳み込みニューラル ネットワーク (Pytorch) + クラスター分析で大気質と天気予測を実現

7. ディープラーニングの実践 7 - 電子商取引商品レビューの感情分析

8. Deep Learning Combat 8​​ - Life Photo Transformation Comic Photo アプリケーション

9. ディープラーニング実践9-テキスト生成画像-ローカルコンピュータでtext2imgを実現

10. ディープラーニング演習10 ~数式認識~画像のLatex化(img2Latex)

11. ディープラーニング実践11(上級編) - BERTモデルの微調整適用 - テキスト分類の場合

12. ディープラーニング演習 12 (上級編) - Dewarp を使用してテキストの歪みを修正する

13. ディープラーニング実践編13(上級編) - 文字誤り訂正機能、よく誤字を書く友人には頑張ってください

14. ディープラーニング実践14(上級編) - 手書き文字OCR認識、手書きメモも認識可能

15. Deep Learning Combat 15 (Advanced Edition) - 読解は機械に任せる + 質問者になって質問できる

16. ディープラーニング実践16(上級編) - 仮想スクリーンショット認識テキスト - 紙の契約書やフォームの認識も可能

17. ディープラーニング演習17(上級編) - インテリジェントアシスタント編集基盤システムの構築・開発事例

18. Deep Learning Combat 18 (Advanced Edition) - 市販されているNLPタスクを実現できるNLP融合システムの15タスク

19. Deep Learning 実践 19 (上級編) - ChatGPT のローカル実装展開テスト、ChatGPT を独自のプラットフォームに実装可能

...(アップグレード保留中)

おすすめ

転載: blog.csdn.net/weixin_42878111/article/details/124668371