create_class_mlpT_create_class_mlpCreateClassMlpCreateClassMlpcreate_class_mlp创建类多层感知器(算子)

名称

create_class_mlpT_create_class_mlpCreateClassMlpCreateClassMlpcreate_class_mlp — 创建一个用于分类或回归的多层感知器。

签名

create_class_mlp( : : NumInput, NumHidden, NumOutput, OutputFunction, Preprocessing, NumComponents, RandSeed : MLPHandle)

Herror T_create_class_mlp(const Htuple NumInput, const Htuple NumHidden, const Htuple NumOutput, const Htuple OutputFunction, const Htuple Preprocessing, const Htuple NumComponents, const Htuple RandSeed, Htuple* MLPHandle)

void CreateClassMlp(const HTuple& NumInput, const HTuple& NumHidden, const HTuple& NumOutput, const HTuple& OutputFunction, const HTuple& Preprocessing, const HTuple& NumComponents, const HTuple& RandSeed, HTuple* MLPHandle)

void HClassMlp::HClassMlp(Hlong NumInput, Hlong NumHidden, Hlong NumOutput, const HString& OutputFunction, const HString& Preprocessing, Hlong NumComponents, Hlong RandSeed)

void HClassMlp::HClassMlp(Hlong NumInput, Hlong NumHidden, Hlong NumOutput, const char* OutputFunction, const char* Preprocessing, Hlong NumComponents, Hlong RandSeed)

void HClassMlp::HClassMlp(Hlong NumInput, Hlong NumHidden, Hlong NumOutput, const wchar_t* OutputFunction, const wchar_t* Preprocessing, Hlong NumComponents, Hlong RandSeed)   ( Windows only)

void HClassMlp::CreateClassMlp(Hlong NumInput, Hlong NumHidden, Hlong NumOutput, const HString& OutputFunction, const HString& Preprocessing, Hlong NumComponents, Hlong RandSeed)

void HClassMlp::CreateClassMlp(Hlong NumInput, Hlong NumHidden, Hlong NumOutput, const char* OutputFunction, const char* Preprocessing, Hlong NumComponents, Hlong RandSeed)

void HClassMlp::CreateClassMlp(Hlong NumInput, Hlong NumHidden, Hlong NumOutput, const wchar_t* OutputFunction, const wchar_t* Preprocessing, Hlong NumComponents, Hlong RandSeed)   ( Windows only)

static void HOperatorSet.CreateClassMlp(HTuple numInput, HTuple numHidden, HTuple numOutput, HTuple outputFunction, HTuple preprocessing, HTuple numComponents, HTuple randSeed, out HTuple MLPHandle)

public HClassMlp(int numInput, int numHidden, int numOutput, string outputFunction, string preprocessing, int numComponents, int randSeed)

void HClassMlp.CreateClassMlp(int numInput, int numHidden, int numOutput, string outputFunction, string preprocessing, int numComponents, int randSeed)

def create_class_mlp(num_input: int, num_hidden: int, num_output: int, output_function: str, preprocessing: str, num_components: int, rand_seed: int) -> HHandle

描述

create_class_mlpcreate_class_mlpCreateClassMlpCreateClassMlpCreateClassMlpcreate_class_mlp 创建一个多层感知器(MLP)形式的神经网络,可用于分类或回归(函数逼近),具体取决于 OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function 的设置方式。该 MLP 由三层组成:包含 NumInputNumInputNumInputNumInputnumInputnum_input 个输入变量(单元/神经元)的输入层、包含 NumHiddenNumHiddenNumHiddenNumHiddennumHiddennum_hidden 个单元的隐藏层,以及包含 NumOutputNumOutputNumOutputNumOutputnumOutputnum_output 个输出变量的输出层。MLP 通过以下步骤从输入数据 (即特征向量)计算隐藏单元的激活值 在此,矩阵 和向量 是 MLP 输入层(第一层)的权重。在隐藏层(第二层)中,激活值 首先通过变量的线性组合进行转换,其方式与上述类似: 此处,矩阵 和向量 是 MLP 第二层的权重。

输出层使用的激活函数可通过设置 OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function 来确定。当 OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function = 'linear'"linear""linear""linear""linear""linear" 时,数据将被简单复制: 此类激活函数应用于回归问题(函数逼近)。该激活函数不适用于分类问题。

OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function = 'logistic'"logistic""logistic""logistic""logistic""logistic" 时,激活值按以下方式计算: 此类激活函数应用于具有多个(NumOutputNumOutputNumOutputNumOutputnumOutputnum_output)独立逻辑属性作为输出的分类问题。此类分类问题在实际应用中较为罕见。

OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function = 'softmax'"softmax""softmax""softmax""softmax""softmax" 时,激活值按以下方式计算:

此类激活函数适用于具有多个(NumOutputNumOutputNumOutputNumOutputnumOutputnum_output)互斥类别作为输出的常见分类问题。特别地,在使用 classify_image_class_mlpclassify_image_class_mlpClassifyImageClassMlpClassifyImageClassMlpClassifyImageClassMlpclassify_image_class_mlp 进行像素数据分类时,必须设置 OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function = 'softmax'"softmax""softmax""softmax""softmax""softmax"

参数 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessingNumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 可用于指定特征向量的预处理方式。当 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'none'"none""none""none""none""none" 时,特征向量将未经修改地传递至 MLP。此时 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 将被忽略。

对于 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing 的其他所有值,训练数据集在训练过程中以及后续分类或评估阶段均用于计算特征向量的变换。

对于 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'normalization'"normalization""normalization""normalization""normalization""normalization",特征向量通过减去训练向量的均值,并将结果除以训练向量各成分的标准差来进行归一化。因此,转换后的特征向量具有均值为 0、标准差为 1的特性。归一化操作不会改变特征向量的长度。此时 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 将被忽略。当特征向量的均值与标准差显著偏离 0 和 1 时,或特征向量各成分采用不同计量单位(例如部分数据为灰度值特征,部分为区域特征;或区域特征混合使用不同单位,如圆度 'circularity' (单位:标量)与面积 'area' (单位:平方像素))时,可采用此转换方法。此类情况下,相较于未进行归一化的训练,网络通常所需迭代次数更少。

PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'principal_components'"principal_components""principal_components""principal_components""principal_components""principal_components" 时,将执行主成分分析。首先对特征向量进行归一化处理(参见上文)。随后计算正交变换(即特征空间中的旋转),以消除训练向量间的关联性。变换后,训练向量的均值为 0,其协方差矩阵成为对角矩阵。该变换的选取原则是:将包含最大变异性的特征集中于变换后特征向量的前几个主成分。由此可省略特征向量末端主成分(通常主要受噪声影响)的变换特征,而不会丢失大量信息。参数 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 用于确定应采用多少个转换后的特征向量成分。最多可选取 NumInputNumInputNumInputNumInputnumInputnum_input 个成分。算子 get_prep_info_class_mlpget_prep_info_class_mlpGetPrepInfoClassMlpGetPrepInfoClassMlpGetPrepInfoClassMlpget_prep_info_class_mlp 可用于确定每个转换后的成分包含多少信息。从而辅助选择 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 的值。与数据归一化类似,当特征向量的均值和标准差分别显著偏离 0 和 1 时,或特征向量中数据成分采用不同计量单位时,均可采用此转换方式。此外,若特征间存在高度相关性,该转换同样具有实用价值。

与上述三种适用于所有 MLP 类型的转换不同,当 MLP 作为分类器使用且 OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function = 'softmax'"softmax""softmax""softmax""softmax""softmax" 时,才可使用 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'canonical_variates'"canonical_variates""canonical_variates""canonical_variates""canonical_variates""canonical_variates" 指定的转换。典型变量的计算也称为线性判别分析。在此情况下,系统将计算一种先对训练向量进行归一化,再通过所有类别平均值消除训练向量相关性的转换。该转换同时最大化分离各类别的均值。与 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'principal_components'"principal_components""principal_components""principal_components""principal_components""principal_components" 类似,转换后的成分按信息含量排序,因此可省略信息含量较低的转换成分。对于典型变量法,最多可选取 min(NumOutputNumOutputNumOutputNumOutputnumOutputnum_output - 1, NumInputNumInputNumInputNumInputnumInputnum_input) 个成分。同样可通过 get_prep_info_class_mlpget_prep_info_class_mlpGetPrepInfoClassMlpGetPrepInfoClassMlpGetPrepInfoClassMlpget_prep_info_class_mlp 获取各变换成分的信息含量。与主成分分析类似,典型变量法既能减少数据量而不丢失大量信息,又能优化降维后类别的可分离性。

对于最后两种变换类型('principal_components'"principal_components""principal_components""principal_components""principal_components""principal_components"'canonical_variates'"canonical_variates""canonical_variates""canonical_variates""canonical_variates""canonical_variates"),MLP 的实际输入单元数量由 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 决定,而 NumInputNumInputNumInputNumInputnumInputnum_input 则决定输入数据的维度(即未转换特征向量的长度)。因此,通过采用这两种变换中的任意一种,可减少输入变量数量,通常也能相应降低隐藏层单元数量。由此,训练 MLP 所需的时间以及特征向量评估与分类的时间通常都会缩短。

通常,NumHiddenNumHiddenNumHiddenNumHiddennumHiddennum_hidden 应选择在 NumInputNumInputNumInputNumInputnumInputnum_inputNumOutputNumOutputNumOutputNumOutputnumOutputnum_output 的数量级范围内。在多数情况下,较小的 NumHiddenNumHiddenNumHiddenNumHiddennumHiddennum_hidden 已能获得非常好的分类结果。若 NumHiddenNumHiddenNumHiddenNumHiddennumHiddennum_hidden 选择过大,MLP 可能对训练数据过拟合,这通常导致泛化性能变差——即模型虽能很好地学习训练数据,但在未知数据上却无法取得理想效果。

create_class_mlpcreate_class_mlpCreateClassMlpCreateClassMlpCreateClassMlpcreate_class_mlp 使用随机数初始化上述权重。为确保 train_class_mlptrain_class_mlpTrainClassMlpTrainClassMlpTrainClassMlptrain_class_mlp 训练分类器时结果可重复,需通过 RandSeedRandSeedRandSeedRandSeedrandSeedrand_seed 传递随机数生成器的种子值。若训练结果误差较大,有时可通过调整 RandSeedRandSeedRandSeedRandSeedrandSeedrand_seed 值并重新训练 MLP 来获得更小的误差。

创建 MLP 后,通常通过反复调用 add_sample_class_mlpadd_sample_class_mlpAddSampleClassMlpAddSampleClassMlpAddSampleClassMlpadd_sample_class_mlpread_samples_class_mlpread_samples_class_mlpReadSamplesClassMlpReadSamplesClassMlpReadSamplesClassMlpread_samples_class_mlp 向 MLP 添加训练样本。随后,通常使用 train_class_mlptrain_class_mlpTrainClassMlpTrainClassMlpTrainClassMlptrain_class_mlp 对 MLP 进行训练。训练完成后,可通过 write_class_mlpwrite_class_mlpWriteClassMlpWriteClassMlpWriteClassMlpwrite_class_mlp 保存 MLP。训练后的 MLP 也可立即用于数据评估:使用 evaluate_class_mlpevaluate_class_mlpEvaluateClassMlpEvaluateClassMlpEvaluateClassMlpevaluate_class_mlp 进行评估;若将 MLP 作为分类器使用(即 OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function = 'softmax'"softmax""softmax""softmax""softmax""softmax"),则可通过 classify_class_mlpclassify_class_mlpClassifyClassMlpClassifyClassMlpClassifyClassMlpclassify_class_mlp 进行数据分类。

多层感知器的训练通常会在不同类别之间形成非常尖锐的边界,即某个类别的置信度会在特征空间中一个非常窄的“带状区域”内,从接近1(在该类别区域内)骤降至接近0(在其他类别区域内)。若类别不重叠,这种过渡发生在类别间的合适位置;若类别重叠,则发生在重叠区域内的合适位置。虽然这种锐利过渡在许多应用中是理想的,但在某些应用中,更平滑的类别间过渡(即特征空间内更宽“带”范围内的过渡)更可取,以反映类别间特征空间区域内的不确定性程度。此外,如前所述,需避免多层感知机对训练数据的过拟合。为此可通过 set_regularization_params_class_mlpset_regularization_params_class_mlpSetRegularizationParamsClassMlpSetRegularizationParamsClassMlpSetRegularizationParamsClassMlpset_regularization_params_class_mlp 对 MLP 进行正则化处理。

如上所述,MLP 本身不具备新颖性检测能力,即它会将随机特征向量分类到某个类别中,且置信度接近 1(除非该随机特征向量恰好位于特征空间中不同类别训练样本重叠的区域)。但在某些应用场景中,需要拒绝那些与任何类别均不接近的特征向量——此处“接近度”由特征向量与训练集特征向量集合的距离定义。为赋予 MLP 新颖性检测能力(即拒绝不属于任何类别的特征向量),可通过将 NumOutputNumOutputNumOutputNumOutputnumOutputnum_output 设为实际类别数加 1 来创建显式拒绝类。随后使用 set_rejection_params_class_mlpset_rejection_params_class_mlpSetRejectionParamsClassMlpSetRejectionParamsClassMlpSetRejectionParamsClassMlpset_rejection_params_class_mlp 配置 train_class_mlptrain_class_mlpTrainClassMlpTrainClassMlpTrainClassMlptrain_class_mlp,使其自动为该拒绝类生成样本。

正则化与自动生成拒绝类相结合的方法在许多应用中颇具价值,因为它能在实际类别之间以及实际类别与拒绝类之间实现平滑过渡。这反映了这些应用程序的要求:只有位于特征空间中与各类训练样本对应区域内的特征向量才应具有接近 1 的置信度,而属于任何类的随机特征向量应具有接近 0 的置信度;类与类之间的过渡应平滑,反映出特征向量离相应类越远,不确定性程度就越高。特别是 OCR 应用有时会提出此要求(参见 create_ocr_class_mlpcreate_ocr_class_mlpCreateOcrClassMlpCreateOcrClassMlpCreateOcrClassMlpcreate_ocr_class_mlp)。

MLP 与支持向量机(SVM)(参见 create_class_svmcreate_class_svmCreateClassSvmCreateClassSvmCreateClassSvmcreate_class_svm)的对比通常表明:SVMs 在训练速度上普遍更胜一筹,尤其面对海量训练集时表现更为突出,且其识别率略优于 MLPs。而 MLP 在分类速度方面更具优势,因此在时间敏感型应用中应优先选用。请注意,此建议基于参数已进行最优调优的前提。

执行信息

此算子返回一个句柄。请注意,即使该句柄被用作特定算子的输入参数,这些算子仍可能改变此句柄类型的实例状态。

参数

NumInputNumInputNumInputNumInputnumInputnum_input (输入控制)  integer HTupleintHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

MLP 的输入变量(特征)数量。

默认值: 20

建议值: 1, 2, 3, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100

限制: NumInput >= 1

NumHiddenNumHiddenNumHiddenNumHiddennumHiddennum_hidden (输入控制)  integer HTupleintHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

MLP 中隐藏层的单元数量。

默认值: 10

建议值: 1, 2, 3, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 150

限制: NumHidden >= 1

NumOutputNumOutputNumOutputNumOutputnumOutputnum_output (输入控制)  integer HTupleintHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

MLP 的输出变量(类别)数量。

默认值: 5

建议值: 1, 2, 3, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 150

限制: NumOutput >= 1

OutputFunctionOutputFunctionOutputFunctionOutputFunctionoutputFunctionoutput_function (输入控制)  string HTuplestrHTupleHtuple (string) (string) (HString) (char*)

MLP 输出层中激活函数的类型。

默认值: 'softmax' "softmax" "softmax" "softmax" "softmax" "softmax"

值列表: 'linear'"linear""linear""linear""linear""linear", 'logistic'"logistic""logistic""logistic""logistic""logistic", 'softmax'"softmax""softmax""softmax""softmax""softmax"

PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing (输入控制)  string HTuplestrHTupleHtuple (string) (string) (HString) (char*)

用于转换特征向量的预处理类型。

默认值: 'normalization' "normalization" "normalization" "normalization" "normalization" "normalization"

值列表: 'canonical_variates'"canonical_variates""canonical_variates""canonical_variates""canonical_variates""canonical_variates", 'none'"none""none""none""none""none", 'normalization'"normalization""normalization""normalization""normalization""normalization", 'principal_components'"principal_components""principal_components""principal_components""principal_components""principal_components"

NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components (输入控制)  integer HTupleintHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

预处理参数:转换特征的数量(当 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'none'"none""none""none""none""none"PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'normalization'"normalization""normalization""normalization""normalization""normalization" 时忽略此参数)。

默认值: 10

建议值: 1, 2, 3, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100

限制: NumComponents >= 1

RandSeedRandSeedRandSeedRandSeedrandSeedrand_seed (输入控制)  integer HTupleintHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

用于将 MLP 初始化为随机值的随机数生成器的种子值。

默认值: 42

MLPHandleMLPHandleMLPHandleMLPHandleMLPHandlemlphandle (输出控制)  class_mlp HClassMlp, HTupleHHandleHTupleHtuple (handle) (IntPtr) (HHandle) (handle)

MLP 句柄。

示例(HDevelop)

* Use the MLP for regression (function approximation)
create_class_mlp (1, NumHidden, 1, 'linear', 'none', 1, 42, MLPHandle)
* Generate the training data
* D = [...]
* T = [...]
* Add the training data
for J := 0 to NumData-1 by 1
    add_sample_class_mlp (MLPHandle, D[J], T[J])
endfor
* Train the MLP
train_class_mlp (MLPHandle, 200, 0.001, 0.001, Error, ErrorLog)
* Generate test data
* X = [...]
* Compute the output of the MLP on the test data
for J := 0 to N-1 by 1
    evaluate_class_mlp (MLPHandle, X[J], Y)
endfor

* Use the MLP for classification
create_class_mlp (NumIn, NumHidden, NumOut, 'softmax', \
                  'normalization', NumIn, 42, MLPHandle)
* Generate and add the training data
for J := 0 to NumData-1 by 1
    * Generate training features and classes
    * Data = [...]
    * Class = [...]
    add_sample_class_mlp (MLPHandle, Data, Class)
endfor
* Train the MLP
train_class_mlp (MLPHandle, 100, 1, 0.01, Error, ErrorLog)
* Use the MLP to classify unknown data
for J := 0 to N-1 by 1
    * Extract features
    * Features = [...]
    classify_class_mlp (MLPHandle, Features, 1, Class, Confidence)
endfor

结果

如果参数有效,算子 create_class_mlpcreate_class_mlpCreateClassMlpCreateClassMlpCreateClassMlpcreate_class_mlp 返回值 2 (H_MSG_TRUE)。如有必要,则抛出异常。

可能的后继

add_sample_class_mlpadd_sample_class_mlpAddSampleClassMlpAddSampleClassMlpAddSampleClassMlpadd_sample_class_mlp, set_regularization_params_class_mlpset_regularization_params_class_mlpSetRegularizationParamsClassMlpSetRegularizationParamsClassMlpSetRegularizationParamsClassMlpset_regularization_params_class_mlp, set_rejection_params_class_mlpset_rejection_params_class_mlpSetRejectionParamsClassMlpSetRejectionParamsClassMlpSetRejectionParamsClassMlpset_rejection_params_class_mlp

替代

read_dl_classifierread_dl_classifierReadDlClassifierReadDlClassifierReadDlClassifierread_dl_classifier, create_class_svmcreate_class_svmCreateClassSvmCreateClassSvmCreateClassSvmcreate_class_svm, create_class_gmmcreate_class_gmmCreateClassGmmCreateClassGmmCreateClassGmmcreate_class_gmm

另见

clear_class_mlpclear_class_mlpClearClassMlpClearClassMlpClearClassMlpclear_class_mlp, train_class_mlptrain_class_mlpTrainClassMlpTrainClassMlpTrainClassMlptrain_class_mlp, classify_class_mlpclassify_class_mlpClassifyClassMlpClassifyClassMlpClassifyClassMlpclassify_class_mlp, evaluate_class_mlpevaluate_class_mlpEvaluateClassMlpEvaluateClassMlpEvaluateClassMlpevaluate_class_mlp

参考文献

Christopher M. Bishop: “Neural Networks for Pattern Recognition”; Oxford University Press, Oxford; 1995.
Andrew Webb: “Statistical Pattern Recognition”; Arnold, London; 1999.

模块

基础