Python 深度学习实战:人工智能艺术
1.背景介绍
计算机视觉、自然语言处理以及强化学习等AI领域的最新研究和应用需要庞大的机器学习算法与技术支持。近年来,在计算能力的大幅提升下, 深度学习(Deep Learning)已取得显著进展. 同时, 它广泛应用于图像识别、文本理解等多个领域.
本文将以书籍《Python 深度学习实战:原理、算法、应用与拓展》(第2版)为内容基础,并从计算机视觉、自然语言处理及强化学习等多个领域进行全面解析。此外,在理论阐述的基础上会结合实际案例展开完整的Python编程实践环节。所涉及的知识点将涵盖多个前沿领域。
- 图像分类任务及相关技术包括图像分类、目标检测和图像分割。
- 自然语言处理相关技术涵盖情感分析技术(如情感分析)、自然语言理解技术(如自然语言理解)、词性标注(如词性标注)、命名实体识别(如命名实体识别)以及短语级意图推断。
- 强化学习算法及其应用包括Q-Learning算法(如Q-Learning)、Deep Q-Network(如DQN)、Deep Deterministic Policy Gradient(如DDPG)以及AlphaGo算法(如AlphaGo)等。
- 常见深度学习框架包括TensorFlow框架(如TensorFlow)、PyTorch框架(如PyTorch)以及Keras工具(如Keras),它们广泛应用于深度学习模型开发。
- 数据科学工作流涉及数据集构建过程(包括数据收集与整理)、数据清洗步骤以及数据预处理阶段。
- 常见Web开发框架包括Flask框架及其应用场景和Django框架及其应用场景。
深入阅读本文后,读者将掌握利用Python从零基础应对深度学习问题的方法,并学会采用高效且便于验证的方式搭建属于自己的AI应用系统。
2.核心概念与联系
2.1 AI基本概念
人工智能(Artificial Intelligence, AI),是指智能体对环境和任务的模拟、预测与决策行为。其区别于其他技术的核心特征在于它是系统性地整合了多学科知识并长期运行的一项综合科技体系,并具备一套复杂且严密的计算机制构成的基础架构。该体系不仅能够进行自主学习与推理运算,并能在动态变化中持续进化以适应新的挑战需求。
自然语言理解与生成:基于非结构化/半结构化数据提取抽象语义信息,并借助对话机制输出富有人情味的内容。
人类行为的理解与决策过程主要依赖于丰富的经验数据。通过分析大量复杂的社会现象和自然规律,在智能化的基础上完成判断与决策任务。从而让人们能够更深入地认识社会运行机制并作出更为明智的行动。
- 问题求解与规划:主要应用数学方法、逻辑推理以及统计分析等工具和技术手段,在系统性地研究各种复杂的问题及其潜在的解决方案的基础上进行建模与分析工作;通过系统性的搜索、推理以及优化计算等手段寻求最优解或其近似解
机器学习赋予机器强大的自主学习能力,并通过数据挖掘出有益的模式和规律来应对新的挑战。其核心包括充足的训练样本、高效的优化算法、精准的损失计算以及合理的模型结构与科学的参数调节策略等关键要素。
- 知识库表示与推理:通过知识库积累大量的先验知识,并将各种异构知识源进行融合与整合,从而完成对多种客观事物的有效推理。
就目前而言,AI技术是一个既模糊又复杂的领域;其不同的人工智能研究分支均致力于解决不同的问题,如图像识别、语音识别等技术所涉及。
2.2 机器学习的定义
The field of machine learning, abbreviated as Machine Learning (ML), represents a specialized discipline within artificial intelligence. Its primary objective is to develop systems that can autonomously identify patterns and relationships within data. Machine learning models, through continuous exposure to vast datasets, are designed to make predictions and decisions with minimal human intervention.
在机器学习的过程中(机制),系统会从给定的输入数据中提取出一系列模型参数(变量)。这些参数能够反映变量间的关联性,并且通过分析这些关联性(模式),系统能够实现对未知样本的有效识别与分类。此外,在现有的研究领域中(分支),如回归分析、聚类分析等技术均致力于利用数据分析的方法自动生成解决方案以应对不同应用场景。
传统的机器学习方法主要依赖人工设计的特征工程、基于统计的学习方法以及核技巧等多种手段。然而近年来随着深度学习与强化学习等新兴技术的不断涌现,其理论体系与技术框架也取得了显著的进步。
3.核心算法原理和具体操作步骤以及数学模型公式详细讲解
3.1 图像分类算法
3.1.1 CIFAR-10数据集
(1)CIFAR-10数据集简介
CIFAR-10数据集被广泛认为是计算机视觉领域的基准数据集之一。它包含总计6万张图像,分为1O个类别,并按比例分配了训练和测试样本:每个类别包含6千张图像;其中约五千用于训练样本和一千用于测试样本。这些分类包括飞机、汽车、鸟类等动物以及一些特殊动物如鹿。此外,在设计上采用了固定尺寸设置:图像尺寸设定为32×32像素以确保一致性
Figure 1 CIFAR-10 data set.
(2)CIFAR-10数据集准备
import keras
from keras.datasets import cifar10
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
print('Training samples:', X_train.shape[0])
print('Testing samples:', X_test.shape[0])
代码解读
输出:
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170500096/170498071 [==============================] - 1s 0us/step
Training samples: 50000
Testing samples: 10000
代码解读
(3)CIFAR-10数据集加载
经过处理后生成的数据集X_train具有形状(54,768×168×168×3),其中包含了来自不同类别的图像数据。具体来说,在这一数据集中共有54,768张图像样本等待进一步分析和分类处理。与此同时,在同一存储空间中还包含了与这些图像相对应的一系列标签信息y_train。这些标签用于对每张图像进行分类识别,并且其取值范围是从零到九之间的整数值,并分别代表十个不同的类别
在载入后的数据集中,X_test呈现出一个维度结构为(10000, 32, 32, 3)的空间分布特征,其中10000代表了测试集中的样本数量。与此相对应的是y_test作为一个长度为10000的一维列表,在本场景中未提供任何标签信息,因为我们仅通过测试集来验证模型性能。
def plot_images(images, cls_true, cls_pred=None):
assert len(images) == len(cls_true) == 9
# Create figure with sub-plots.
fig, axes = plt.subplots(3, 3)
for i, ax in enumerate(axes.flat):
# Plot image.
ax.imshow(images[i], cmap='binary')
# Show true and predicted classes.
if cls_pred is None:
xlabel = "True: {0}".format(cls_true[i])
else:
xlabel = "True: {0}, Pred: {1}".format(cls_true[i], cls_pred[i])
ax.set_xlabel(xlabel)
# Remove ticks from the plot.
ax.set_xticks([])
ax.set_yticks([])
# Ensure the plot is shown correctly with multiple plots
# in a single Notebook cell.
plt.show()
# Get the first images from the test set.
images = X_test[0:9]
# Get the true classes for those images.
cls_true = y_test[0:9]
# Load the CIFAR-10 dataset.
(X_train, y_train), (X_test, _) = cifar10.load_data()
# Plot the images and labels using our helper function.
plot_images(images, cls_true)
代码解读
Figure 2 Example of CIFAR-10 images.
(4)图像分类算法实现——卷积神经网络(CNN)
一种卷积神经网络(Convolutional Neural Network, 简称 CNN)由多个卷积层和池化层依次组合构成。该网络架构通过独特的局部感受野机制实现对目标物体关键部位的有效识别,并能在保证整体图像信息完整性的同时大幅减少模型参数量。其中,在 CNN 模型中, 卷积操作主要用于从图像中提取具有判别性的低级特征, 而 pooling 操作则用于降低空间分辨率, 从而有效防止模型过度拟合训练数据
下面使用keras实现一个简单的CNN来进行图像分类。
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
# Define the CNN architecture.
model = Sequential([
Conv2D(filters=32, kernel_size=(3,3), activation='relu', input_shape=(32,32,3)),
MaxPooling2D(pool_size=(2,2)),
Conv2D(filters=64, kernel_size=(3,3), activation='relu'),
MaxPooling2D(pool_size=(2,2)),
Flatten(),
Dense(units=128, activation='relu'),
Dropout(rate=0.5),
Dense(units=10, activation='softmax')])
# Compile the model.
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Print the model summary.
model.summary()
代码解读
该模型的第一层采用Conv2D层(Convolutional Neural Network),该层包含32个滤波器单元,并且每个滤波器的尺寸为3×3像素,并采用ReLU激活函数进行计算。随后一层是MaxPooling2D池化层(Maximum pooling layer),其池化窗口设置为2×2像素,并在每次池化操作后会将特征图的空间维度减半以降低计算复杂度。第三和第四层采用了与第一层相同的结构设计。第五层引入Flatten层(Fully Connected Layer),其功能是将多维特征向量转换为一维向量以便后续全连接计算处理。第六层设置为128个神经元的全连接层(Dense layer),同样采用了ReLU激活函数以增强非线性表达能力。第七层配置Dropout机制(Dropout layer)以防止模型过拟合问题,并随机移除部分神经元节点以提高模型泛化能力。最后一层也是一个128个神经元的全连接输出层(Output Dense layer),并使用Softmax激活函数进行归一化处理后输出一个长度为10的一维概率向量(Vector),表示输入图像属于10个类别之一的概率分布。
# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes=10)
y_test = keras.utils.to_categorical(y_test, num_classes=10)
# Train the model.
history = model.fit(X_train / 255.0, y_train, batch_size=32, epochs=20, validation_split=0.2)
# Evaluate the model on the test set.
score = model.evaluate(X_test / 255.0, y_test, verbose=0)
print("Test accuracy:", score[1])
代码解读
运行结束后,模型在测试集上的准确率约为92%左右。
loss, acc = history.history['loss'], history.history['acc']
val_loss, val_acc = history.history['val_loss'], history.history['val_acc']
plt.figure(figsize=(10,6))
epochs_range = range(len(acc))
plt.subplot(2,1,1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(2,1,2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
代码解读
Figure 3 Training curve of convolutional neural network.
3.2 情感分析算法
3.2.1 情感分析简介
情感分析(sentiment analysis)是计算机领域中涉及自然语言处理(natural language processing, NLP)这一技术的重要方向。该方法运用这一技术手段对包含情绪色彩或明显倾向性语言的文字信息进行识别与评估。基于多样化的应用场景需求, 情感分析功能能够为企业提供有效的品牌声誉评估工具, 并能帮助提升市场推广效果的同时塑造良好的企业形象
情感分析方法主要包含两类:一类是基于规则的方法,另一类则是基于统计模型的方法。其中, 基于规则的方法具有简明性,然而容易受到固有规则以及停用词等因素的限制;而基于统计模型的方法相对复杂,其构建基础是海量的真实数据,因此通常能够达到较高的识别精度。
3.2.2 AFINN-165英文情感词典
AFINN是一种英文情感词典,在其构建过程中将每个单词与一个分数相关联;这种关系体系能够直观地反映该单词所蕴含的情感强度等级;该系统总计收录了2,677个不同类型的英文单词;每个词语都被赋予了一个具体的评分范围在-5到+5之间;为了提高系统适用性并降低数据量需求;开发出了一个较为简化的版本即AFINN-165;该简化版仅包含其中256个常见使用的英文情感词汇及其对应的评分体系;而整个系统所形成的数据库总条目数达到了165条记录;具体的数据架构可以通过下图来进行直观理解;
Table 1 Common English sentiment words and their values.
3.2.3 情感分析算法实现——Bag-of-Words模型
一种 Bag-of-Words 模型是基于频率的一种简单的文本特征提取体系。它能够迅速且简便地应用于多种自然语言处理任务如信息检索与数据挖掘等场景。该模型将每个待分析的文本转换为一个多维向量空间中的点,在此空间中每个维度对应着特定的文字词汇而向量坐标则反映相应词汇在该段文字中的出现频率。具体而言,在 Bag-of-Words 模型中每个具体的文档会被量化为一个精确计算出各关键词频次的矩阵其中每一行都代表着独立的一个词汇而每一列则对应着一段具体的文档这样通过这种量化过程就可以方便地对大量文档进行分类聚类以及其他相关分析工作
下图呈现了一个典型的Bag-of-Words模型示例。假设我们有一个待分类的一组文本数据,在这些数据中每个样本都由三个关键词特征构成。对于每一个样本数据点而言,在其特征空间中我们可以建立一个词频索引矩阵(如表1所示)。
Table 2 Bag-of-Words example.
根据表格所示,在信息处理领域中,Bag-of-Words模型能够清晰地体现某个关键词在其对应文本中的出现频率。这种表示方法在多种应用场景下被广泛应用
在进行情感分析时,在对原始句子进行预处理过程中(包括但不仅限于)去除停用词、标点符号以及数字等无关字符,并将所有的单词统一为小写字母形式(以便于后续的词频统计工作顺利开展)。接下来我们可以利用scikit-learn库中的CountVectorizer类工具来进行这一操作
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from nltk.corpus import stopwords
# Read the data into Pandas dataframe.
df = pd.read_csv('SentimentAnalysisDataset.txt', delimiter='\t', names=['Text','Label'])
# Select only positive or negative examples.
pos_df = df[df['Label']=='+'].reset_index().drop(['index'], axis=1)
neg_df = df[df['Label']=='-'].reset_index().drop(['index'], axis=1)
# Combine all examples together.
all_df = pos_df.append(neg_df).sample(frac=1, random_state=42).reset_index().drop(['index'], axis=1)
# Extract text data from all examples and combine them into one string.
texts =''.join(list(all_df['Text']))
# Tokenize the texts by word and remove punctuation marks and numbers.
stop_words = set(stopwords.words('english'))
texts = [''.join(c for c in s if c not in ',.:;?!' + '"' + "'" + '-@#$%^&*_+=\ <>') for s in texts.lower().split()]
texts = [' '.join(word for word in tokens if word not in stop_words) for tokens in texts]
# Use CountVectorizer to convert the list of texts into a matrix where each row represents a document and each column represents a token.
vectorizer = CountVectorizer()
matrix = vectorizer.fit_transform(texts)
# Split the dataset into training and testing sets.
num_train = int(len(all_df)*0.8)
train_mat = matrix[:num_train,:]
train_labels = np.array(all_df['Label'][:num_train])
test_mat = matrix[num_train:,:]
test_labels = np.array(all_df['Label'][num_train:])
代码解读
将训练与测试数据按80%至20%的比例进行划分,并分别用于不同的功能:其中用于模型训练的部分占80%,另一部分则用于评估模型性能。我们采用了scikit-learn库中的CountVectorizer对文本进行特征提取,在此过程中系统会自动生成唯一索引标识并生成对应的向量表示;这些向量的元素数值反映了相应词汇在样本中的出现频率。
接着,我们能够灵活运用各种机器学习模型(包括但不限于逻辑回归模型、支持向量机(SVM)等)来进行分类任务。同时,在Python环境中,我们还可以选择scikit-learn库中的Naïve Bayes模块来训练朴素贝叶斯分类器。
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
# Train logistic regression classifier.
clf = LogisticRegression(random_state=42)
clf.fit(train_mat, train_labels)
log_pred = clf.predict(test_mat)
log_acc = accuracy_score(test_labels, log_pred)
# Train support vector machine classifier.
clf = SVC(kernel='linear', probability=True, random_state=42)
clf.fit(train_mat, train_labels)
svc_pred = clf.predict(test_mat)
svc_probas = clf.predict_proba(test_mat)[:,1]
svc_acc = accuracy_score(test_labels, svc_pred)
print('Logistic Regression accuracy:', round(log_acc, 4))
print('Support Vector Machine accuracy:', round(svc_acc, 4))
代码解读
输出:
Logistic Regression accuracy: 0.8449
Support Vector Machine accuracy: 0.8454
代码解读
3.3 序列到序列模型算法
3.3.1 序列到序列模型简介
序列到序列模型(Sequence to Sequence Model, Seq2seq)主要被定义为一种强大的深度学习架构,在两个互相沟通的实体之间建立起了一个双向的信息传递机制,并通过这种机制实现数据的有效转换与理解。该模型不仅广泛应用于机器翻译等自然语言处理任务中,还涵盖了包括翻译、摘要生成以及手写字符识别等多种序列预测场景。
该模型由编码器与解码器两个关键组件构成。其中编码器负责接收输入序列并将其转换为固定长度的上下文向量(context vector),此向量随后传递给解码er进行处理。通过这种机制使得后续生成的任务得以实现。该架构适用于多种复杂应用场景如机器翻译视频描述及自动化问答系统等
3.3.2 Encoder-Decoder模型
Seq2seq模型中的Encoder-Decoder模型由三种组件组成:
- 多个编码层:经过多个编码层对输入序列的不同时间点数据进行处理后生成隐藏状态向量,并被称为编码过程。
- 上下文向量:通过整合各隐藏状态信息形成上下文向量,并将其传递给解码器进行后续处理。
- 另一个解码阶段:将上一步骤生成的上下文信息传递至解码器,并完成输出序列的生成过程。
Figure 4 The structure of an encoder-decoder model.
3.3.3 Seq2seq模型的训练
Seq2seq模型的训练主要采用以下两种方法:一是传统的end-to-end(端到端)策略;二是基于注意力机制的方法(Attention Mechanism)。在传统end-to-end策略中,整个序列编码器-解码器网络将被完全进行参数优化与微调学习过程,在这一过程中无需依赖中间变量的存在即可完成输入序列与输出序列之间的映射关系建立;而注意力机制则允许模型在进行培训时利用中间变量提供的辅助信息,在此过程中不仅能够实现更为灵活高效的特征提取能力,并且还能够显著提高模型性能。
3.3.3.1 端到端训练
该方法通过直接实现输入序列与输出序列之间的映射关系,在常见的Seq2seq架构中无需引入任何中间变量即可完成整个过程。具体而言,在该框架下,输入序列会被首先馈入编码器进行处理后生成固定的长度的上下文表示;随后经过解码阶段的信息传递后可逐步生成完整的输出序列;其中交叉熵损失函数通常会被选作衡量预测结果与真实标签之间差异的标准以指导模型优化过程
端到端训练模式的一个主要缺陷在于其对长文本处理能力的不足。由于模型必须完整地遍历整个输入序列才能生成相应的输出序列。此外,在输入数据中若存在噪声或错误信息时,模型可能会受到影响。
3.3.3.2 注意力机制训练
注意力机制训练主要体现在模型在训练过程中能够辅助中间变量发挥其作用。在Seq2seq架构中,每个时间段步上的输出结果不仅由前几个输入时间段步以及当前时间段步共同生成,而且主要通过引入额外的关注权重来提升预测结果的质量。具体而言,该方法通过在计算每个时间段步输出值时,综合考虑前几个时间段步所包含的关键信息,从而避免了仅依赖当前时间段步信息所带来的局限性
注意力机制训练具备处理长度较长文本的优势。这是因为模型能通过不同时间步共享信息,并且不受噪声或错误信息的影响。然而,在复杂度方面与普通Seq2seq模型相比有所提升,在这种情况下,端到端训练的方法更为普遍。
3.3.4 Seq2seq模型的实现——LSTM Seq2seq模型
LSTM Seq2seq模型是一种典型的Seq2seq架构,在编码器与解码器之间采用了基于长短期记忆单元(LSTM)的设计方案以实现信息传递功能。该模型结构具备优异的长时记忆能力,在处理复杂序列数据时展现出较强的适应性与泛化性能。
LSTM Seq2seq模型的实现如下:
from keras.models import Model
from keras.layers import Input, LSTM, Embedding, Dense
# Define the input sequence and its length.
input_seq = Input(shape=(max_len,), dtype='int32')
input_length = Input(shape=(1,), dtype='int32')
# Initialize embedding layer that turns integer sequences into dense vectors of fixed size.
embedding = Embedding(input_dim=vocab_size, output_dim=embedding_dim)(input_seq)
# Apply the LSTM layers to the embedded sequences.
lstm = LSTM(units=hidden_dim, return_sequences=False)(embedding)
# Add additional layers for attention mechanism.
attn_weights = Dense(1, activation='tanh')(lstm)
attn_weights = Dense(max_len, activation='softmax')(attn_weights)
context_vec = Multiply()([attn_weights, lstm])
# Concatenate context vector with decoder inputs before applying final dense layers.
decoder_inputs = Input(shape=(target_len,))
decoder_embedding = Embedding(input_dim=output_vocab_size, output_dim=embedding_dim)(decoder_inputs)
merged = Concatenate()([decoder_embedding, context_vec])
# Apply final dense layers to generate target sequences.
dense1 = Dense(units=hidden_dim, activation='relu')(merged)
outputs = Dense(units=target_vocab_size, activation='softmax')(dense1)
# Build and compile the Seq2seq model.
model = Model([input_seq, input_length, decoder_inputs], outputs)
model.compile(optimizer='rmsprop', loss='sparse_categorical_crossentropy')
model.summary()
代码解读
在LSTM Seq2seq模型的设计过程中,首先明确了输入序列及其长度。随后初始化嵌入层(Embedding layer),将整数序列转化为固定维度的连续向量表示。接着通过LSTM层完成编码过程,在后续计算中整合了前面的信息以实现注意力机制的功能。随后通过乘积运算后将上下文向量与解码器输入进行融合处理。最后阶段,则应用一层全连接层来生成目标序列。编译完成后,则可直观地呈现模型架构信息。
# Define the maximum number of sentences we want to process at once.
batch_size = 128
# Preprocess the data so that it matches the requirements of the Seq2seq model.
train_dataset = tf.data.Dataset.from_tensor_slices((train_sequences, train_sequence_lengths, train_targets)).shuffle(BUFFER_SIZE).batch(batch_size, drop_remainder=True)
validation_dataset = tf.data.Dataset.from_tensor_slices((valid_sequences, valid_sequence_lengths, valid_targets)).batch(batch_size, drop_remainder=True)
# Fit the Seq2seq model on the training data.
model.fit(train_dataset,
epochs=num_epochs,
steps_per_epoch=steps_per_epoch,
validation_data=validation_dataset,
validation_steps=validation_steps)
代码解读
在构建Seq2seq模型的过程中,首先确定了批量处理的数量,并对训练数据按照模型需求进行了格式转换。随后将这些数据集合传递给Seq2seq模型用于其拟合过程。
# Generate predictions on the test set.
predicted_ids = []
for seq_idx, seq in enumerate(test_sequences):
print('\nProcessing sequence', seq_idx+1, '/', len(test_sequences))
# Encode the input sequence into a context vector.
context_vector = model.predict([[seq], [len(seq)], [[start_token]]])[0][0]
# Start generating the output sequence one element at a time.
generated_seq = start_token
while True:
# Decode the current output step and add it back to the sequence.
encoded_generated_seq = tokenizer_pt.texts_to_sequences([generated_seq])[0]
encoded_generated_seq = pad_sequences([encoded_generated_seq], maxlen=max_len, truncating='pre')
predicted = np.argmax(model.predict([encoded_generated_seq, [1], [np.reshape(context_vector, (1, hidden_dim))]])[0, -1, :])
sampled_token = reverse_target_char_index[predicted]
generated_seq += sampled_token
# Stop when we reach the end symbol or when we have reached the maximum allowed length.
if sampled_token == stop_token or len(generated_seq) >= max_gen_len:
break
# Append the generated sequence to the list of predictions.
predicted_ids.append(generated_seq)
# Join the list of predicted strings into a single string.
predicted_string =''.join(predicted_ids)
# Write the predicted string to file.
with open('predicted_sentences.txt', 'w') as f:
f.write(predicted_string)
代码解读
在测试环节中进行预测时,在此过程中遵循以下步骤展开:第一步是利用训练数据集中的每一个输入片段对其进行编码操作;随后系统会提取出统一维度的上下文表示;接着系统开始逐步产生输出序列中的每一个元素;每次迭代均执行解码操作;在解码过程中系统会将当前的状态信息与部分解码结果相结合;基于此计算出当前时间点对应的解码结果;当系统的累计解码长度达到预先设定的最大值或者检测到结束标记出现时,则停止继续运算;最终将所有预测结果整合后保存至指定文件路径。
