基于 TextCNN 的分类模型
实验环境
- 操作系统:ubuntu 20.4.3
- 运行环境:Python 3.9
- 框架环境:TensorFlow 2.6.0
实验数据
- 训练数据集:57680
- 验证数据集:18003
- 测试数据集:14570
模型表现
- 训练集表现:loss: 0.0669 – acc: 0.9752
- 验证集表现:loss: 0.1563 – acc: 0.9475
- 测试集表现:loss: 0.1583 – acc: 0.9442
模型概览
代码实现
import sys
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
from keras.layers import Dense, Embedding, Conv1D, GlobalMaxPool1D, Dropout
sys.path.append("/home/laowang/PycharmProjects/DeepLearning/classification(RNN_TextCNN_BERT)/Untils")
from D_01_TxtEncoder import TextEncoder
word_size = 2117
out_txt_len = 512
word_dim = 128
cnn_filters = 50
dnn_units = 512
epochs_times = 10
droup_rate = 0.5
txtEncoder = TextEncoder("../Data/09_文本当中出现的所有字.txt", word_size, out_txt_len)
词库加载完成
['', '[UNK]', 'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a', '~', ';', ':', ',', ')', '(', '龚', '龙', '龄', '齿', '齐', '鼓', '鼎', '默', '黔', '黑', '黎', '黄', '麻', '麦', '麟', '麓', '麒', '鹿', '鹰', '鹤', '鹏', '鹄', '鸿', '鸥', '鸣', '鸡', '鸟', '鲲', '鲜', '鲍', '鲁', '鱼', '魔', '魏', '魁', '高', '骨', '骥', '骏', '验', '骆', '骅', '骄', '驿', '驾', '驻', '驶', '驱', '驰', '马', '馨', '香', '首', '馆', '饶', '饲', '饰', '饮', '饭', '餐', '食', '飞', '风', '额', '颜', '题']
data_train = pd.read_csv("../Data/10_文本数据_字分隔_Train.txt")
x_train = data_train.iloc[:, 1:2]
y_train = data_train.iloc[:, 2:]
data_val = pd.read_csv("../Data/10_文本数据_字分隔_Test.txt")
x_val = data_val.iloc[:, 1:2]
y_val = data_val.iloc[:, 2:]
data_test = pd.read_csv("../Data/05_验证数据_原数据.csv")
x_test = data_test.iloc[:, 0:1]
y_test = data_test.iloc[:, 1:]
print(f"训练集数量:{len(data_train)}")
print(f"验证集数量:{len(data_val)}")
print(f"测试集数量:{len(data_test)}")
print(f'x:{x_train.iloc[0][0]}, y:{y_train.iloc[0][0]}')
print(f'x:{x_train.iloc[1][0]}, y:{y_train.iloc[1][0]}')
print(f'x:{x_train.iloc[10][0]}, y:{y_train.iloc[10][0]}')
训练集数量:57680
验证集数量:18003
测试集数量:14570
x:曾 明 军 , 阿 贝 妮 创 始 人, y:0.0
x:3 0 年 乳 业 经 验 , 曾 就 业 于 利 乐 、 爱 克 林 、 阿 菲 金 等 公 司 。, y:1.0
x:1 9 8 3 年 7 月 生 , 中 国 国 籍 , 无 境 外 永 久 居 留 权 , 博 士 研 究 生 学 历 , 高 级 工 程 师 , 安 徽 省 战 略 性 新 兴 产 业 技 术 领 军 人 才 , “ 安 徽 省 特 支 计 划 ” 创 新 领 军 人 才 。 2 0 0 8 年 就 读 博 士 期 间 参 与 发 行 人 第 一 台 工 业 机 器 人 ( Q H 1 6 5 机 器 人 ) 的 研 制 , 主 要 负 责 机 器 人 本 体 正 向 设 计 及 机 器 人 控 制 算 法 的 研 究 与 开 发 。 2 0 1 1 年 1 1 月 正 式 入 职 埃 夫 特 , 2 0 1 1 年 1 1 月 至 2 0 1 4 年 1 2 月 担 任 机 器 人 事 业 部 总 工 程 师 ; 2 0 1 4 年 1 2 月 至 2 0 1 6 年 5 月 担 任 公 司 董 事 及 总 工 程 师 ; 2 0 1 6 年 5 月 至 2 0 1 9 年 4 月 担 任 公 司 董 事 、 常 务 副 总 经 理 及 总 工 程 师 ; 2 0 1 9 年 4 月 起 任 公 司 董 事 、 总 经 理 及 总 工 程 师 。 自 任 职 以 来 , 带 领 发 行 人 牵 头 承 接 了 发 改 委 、 工 信 部 、 科 技 部 等 多 个 部 委 的 科 研 和 产 业 化 项 目 。 2 0 1 4 年 作 为 项 目 首 席 专 家 主 持 了 国 家 8 6 3 计 划 先 进 制 造 技 术 领 域 “ 面 向 恶 劣 生 产 环 境 下 经 济 型 工 业 机 器 人 及 成 套 系 统 的 应 用 示 范 ” ( 2 0 1 4 A A 0 4 1 6 0 0 ) 主 题 项 目 。, y:3.0
y_train_one_hot = tf.keras.utils.to_categorical(y_train, dtype='int')
y_val_one_hot = tf.keras.utils.to_categorical(y_val, dtype='int')
y_test_one_hot = tf.keras.utils.to_categorical(y_test, dtype='int')
x_train = txtEncoder.encoder(x_train)
x_val = txtEncoder.encoder(x_val)
x_test = txtEncoder.encoder(x_test)
embedding = Embedding(txtEncoder.get_size(), word_dim)
cnn_layer1 = Conv1D(filters=cnn_filters,
kernel_size=2,
padding="valid",
activation="relu")
cnn_layer2 = Conv1D(filters=cnn_filters,
kernel_size=3,
padding="valid",
activation="relu")
cnn_layer3 = Conv1D(filters=cnn_filters,
kernel_size=4,
padding="valid",
activation="relu")
pool = GlobalMaxPool1D()
dense_1 = Dense(units=dnn_units, activation="relu")
dropout = Dropout(rate=droup_rate)
output_dense = Dense(units=4, activation="softmax")
inputs = tf.keras.Input(shape=(out_txt_len,))
layer = embedding(inputs)
l_1 = cnn_layer1(layer)
l_1 = pool(l_1)
l_2 = cnn_layer2(layer)
l_2 = pool(l_2)
l_3 = cnn_layer3(layer)
l_3 = pool(l_3)
concatenated = tf.concat([l_1, l_2, l_3], axis=-1)
concatenated = dense_1(concatenated)
concatenated = dropout(concatenated)
model_output = output_dense(concatenated)
model = tf.keras.Model(inputs=inputs, outputs=model_output)
model.summary()
Model: "model"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 512)] 0
__________________________________________________________________________________________________
embedding (Embedding) (None, 512, 128) 265984 input_1[0][0]
__________________________________________________________________________________________________
conv1d (Conv1D) (None, 511, 50) 12850 embedding[0][0]
__________________________________________________________________________________________________
conv1d_1 (Conv1D) (None, 510, 50) 19250 embedding[0][0]
__________________________________________________________________________________________________
conv1d_2 (Conv1D) (None, 509, 50) 25650 embedding[0][0]
__________________________________________________________________________________________________
global_max_pooling1d (GlobalMax (None, 50) 0 conv1d[0][0]
conv1d_1[0][0]
conv1d_2[0][0]
__________________________________________________________________________________________________
tf.concat (TFOpLambda) (None, 150) 0 global_max_pooling1d[0][0]
global_max_pooling1d[1][0]
global_max_pooling1d[2][0]
__________________________________________________________________________________________________
dense (Dense) (None, 512) 77312 tf.concat[0][0]
__________________________________________________________________________________________________
dropout (Dropout) (None, 512) 0 dense[0][0]
__________________________________________________________________________________________________
dense_1 (Dense) (None, 4) 2052 dropout[0][0]
==================================================================================================
Total params: 403,098
Trainable params: 403,098
Non-trainable params: 0
__________________________________________________________________________________________________
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
history = model.fit(x_train, y_train_one_hot, epochs=epochs_times, batch_size=1000,
validation_data=(x_val, y_val_one_hot))
Epoch 1/10
2023-09-13 16:00:31.064755: I tensorflow/stream_executor/cuda/cuda_dnn.cc:369] Loaded cuDNN version 8100
2023-09-13 16:00:31.956121: I tensorflow/stream_executor/cuda/cuda_blas.cc:1760] TensorFloat-32 will be used for the matrix multiplication. This will only be logged once.
58/58 [==============================] - 4s 46ms/step - loss: 0.6870 - acc: 0.7582 - val_loss: 0.4322 - val_acc: 0.8390
Epoch 2/10
58/58 [==============================] - 2s 40ms/step - loss: 0.3279 - acc: 0.8805 - val_loss: 0.2591 - val_acc: 0.9037
Epoch 3/10
58/58 [==============================] - 2s 40ms/step - loss: 0.2400 - acc: 0.9068 - val_loss: 0.2167 - val_acc: 0.9129
Epoch 4/10
58/58 [==============================] - 2s 40ms/step - loss: 0.1989 - acc: 0.9215 - val_loss: 0.1895 - val_acc: 0.9245
Epoch 5/10
58/58 [==============================] - 2s 40ms/step - loss: 0.1678 - acc: 0.9346 - val_loss: 0.1695 - val_acc: 0.9314
Epoch 6/10
58/58 [==============================] - 2s 40ms/step - loss: 0.1384 - acc: 0.9479 - val_loss: 0.1583 - val_acc: 0.9379
Epoch 7/10
58/58 [==============================] - 2s 40ms/step - loss: 0.1140 - acc: 0.9563 - val_loss: 0.1533 - val_acc: 0.9428
Epoch 8/10
58/58 [==============================] - 2s 40ms/step - loss: 0.0964 - acc: 0.9629 - val_loss: 0.1504 - val_acc: 0.9455
Epoch 9/10
58/58 [==============================] - 2s 39ms/step - loss: 0.0792 - acc: 0.9697 - val_loss: 0.1532 - val_acc: 0.9473
Epoch 10/10
58/58 [==============================] - 2s 39ms/step - loss: 0.0669 - acc: 0.9752 - val_loss: 0.1563 - val_acc: 0.9475
plt.title('loss')
plt.plot(history.epoch, history.history.get('loss'), color='red')
plt.plot(history.epoch, history.history.get('val_loss'), color='blue')
plt.legend(['train', 'validation'], loc='upper right')
plt.show()
plt.title('acc')
plt.plot(history.epoch, history.history.get('acc'), color='red')
plt.plot(history.epoch, history.history.get('val_acc'), color='blue')
plt.legend(['train', 'validation'], loc='upper right')
plt.show()
loss, accuracy = model.evaluate(x=x_test, y=y_test_one_hot)
print(f'测试集损失: {loss}')
print(f'测试集准确度: {accuracy}')
456/456 [==============================] - 1s 2ms/step - loss: 0.1583 - acc: 0.9443
测试集损失: 0.15834568440914154
测试集准确度: 0.944269061088562