精华内容
下载资源
问答
  • 使用LSTM自动编码器检测异常并对稀有事件进行分类。 如此多次,实际上是现实生活中的大多数数据,我们都有不平衡的数据。 数据是我们最感兴趣的事件,很少见,不像正常情况下那么频繁。 例如,在欺诈检测中。 ...
  • Wi-Fi室内定位的基于CSI的自动编码器分类
  • 主要介绍了keras自动编码器实现系列之卷积自动编码器操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 实现堆叠降噪自编码器功能,以tensorflow中的mnist数据集为例,python2.7
  • 问题描述:老师让用自编码器做一个多分类的问题,但是自编码器是无监督学习,那么在提取特征之后怎么分类呢? 像CNN的话,就可以直接把标签当最后一层的输出去分类,但是自编码器输入的数据应该是没有标签的,而且...
  • MATLAB给出了堆栈自编码器的实现Train Stacked Autoencoders for Image Classification ,本文对其进行分析 堆栈自编码器Stacked Autoencoders 堆栈自编码器是 具有多个隐藏层的神经网络可用于解决图像等复杂数据的...

    在前面两篇博客的基础上,可以实现单层自编码器网络(一个解码器+一个解码器)。对于多层自编码器的实现,MATLAB给出了堆栈自编码器用于图像分类的网页Train Stacked Autoencoders for Image Classification
    ,本文对其进行翻译和学习。

    堆栈自编码器Stacked Autoencoders

    具有多个隐藏层的神经网络可用于解决图像等复杂数据的分类问题。每个层都可以在不同的抽象级别学习特性。然而,训练具有多个隐藏层的神经网络在实践中可能是困难的。一种有效训练多层神经网络的方法是一次训练一层。可以通过为每个隐藏层训练一种称为自编码器的特殊网络来实现这一点。

    下面的例子展示了如何训练具有两个隐藏层的神经网络来对数字图像进行分类。首先,使用自编码器以无监督的方式单独训练隐藏层。然后训练最后一个softmax层,并将这些层连接在一起,形成一个堆叠的网络,在有监督的情况下对其进行最后一次训练。

    代码实现

    代码较长,因此注释也比较多,但是其基本思想并不复杂,实现的过程也容易理解。

    %% Train Stacked Autoencoders for Image Classification训练用于图像分类的堆栈自编码器
    %% 导入训练集
    % 此示例始终使用合成数据进行训练和测试。已通过对使用不同字体创建的数字图像应用随机仿射变换来生成合成图像
    % 每个数字图像为 28×28 像素,共有 5000 个训练样本。您可以加载训练数据,并查看其中一些图像
    % Load the training data into memory 加载自带的手写数字数据集
    clear;
    clc;
    [xTrainImages,tTrain] = digitTrainCellArrayData;
    % 展示图像
    clf
    for i = 1:20
        subplot(4,5,i);
        imshow(xTrainImages{i});
    end
    %% Training the first autoencoder 训练第一个自编码器
    % 首先在不使用标签的情况下基于训练数据训练稀疏自编码器。
    % 自编码器是一种神经网络,该网络会尝试在其输出端复制其输入。因此,其输入的大小将与其输出的大小相同。
    % 当隐含层中的神经元数量小于输入的大小时,自编码器将学习输入的压缩表示。
    % 神经网络在训练前具有随机初始化的权重。因此,每次训练的结果都不同。为避免此行为,请显式设置随机数生成器种子。
    rng('default')%确保随机数
    hiddenSize1 = 100;%设置自编码器的隐含层的大小。对于要训练的自编码器,最好使隐含层的大小小于输入大小。
    % 训练设置
    autoenc1 = trainAutoencoder(xTrainImages,hiddenSize1, ... 
        'MaxEpochs',400, ...    % 最大训练轮次400'L2WeightRegularization',0.004, ...   % L2正则项对网络权重的影响,通常非常小
        'SparsityRegularization',4, ...       % 稀疏正则项的系数
        'SparsityProportion',0.15, ...        % 稀疏比例
        'ScaleData', false);     %输入数据不进行缩放
    % 查看第一个自编码器的结构
    view(autoenc1)   
    % 可视化第一个自编码器的权重
    % 自编码器的编码器部分所学习的映射可用于从数据中提取特征。
    % 编码器中的每个神经元都具有一个与之相关联的权重向量,该向量将进行相应调整以响应特定可视化特征。您可以查看这些特征的表示。
    figure()
    plotWeights(autoenc1);
    % 可以看到,自编码器学习的特征代表了数字图像中的弯曲和笔划图案。
    % 自编码器的隐含层的 100 维输出是输入的压缩版本,它汇总了对上面可视化特征的响应。
    % 基于从训练数据中提取的一组向量训练下一个自编码器。首先,必须使用经过训练的自编码器中的编码器生成特征。
    feat1 = encode(autoenc1,xTrainImages); % 自编码器1的输出
    %% Training the second autoencoder  训练第二个自编码器
    % 以相似的方式训练第二个自编码器,主要区别在于使用第一个自编码器的输出作为第二个自编码器的输入。
    % 还需要将隐含表示的大小减小到 50,以便第二个自编码器中的编码器学习输入数据的更小表示。
    hiddenSize2 = 50; 
    autoenc2 = trainAutoencoder(feat1,hiddenSize2, ...
        'MaxEpochs',100, ...
        'L2WeightRegularization',0.002, ...
        'SparsityRegularization',4, ...
        'SparsityProportion',0.1, ...
        'ScaleData', false);
    % 查看第二个自编码器的结构
    view(autoenc2)
    % 自编码器2的输出
    feat2 = encode(autoenc2,feat1);
    %% Training the final softmax layer 训练最后的分类层softmax
    % 训练数据中的原始向量具有 784 个维度。原始数据通过第一个编码器后,维度减小到 100 维。
    % 应用第二个编码器后,维度进一步减小到 50 维。
    % 训练最后一层softmax层以对 50 维特征向量进行分类。
    % 与自编码器不同,这里使用训练数据的标签以有监督方式训练 softmax 层。
    softnet = trainSoftmaxLayer(feat2,tTrain,'MaxEpochs',400);%trainSoftmaxLayer(输入特征,输出标签,参数(循环次数),参数值)
    % 显示softmax网络
    view(softnet)
    % 将自编码器中的编码器与 softmax 层堆叠在一起,以形成用于分类的堆叠网络
    deepnet = stack(autoenc1,autoenc2,softnet);%网络合成
    view(deepnet) % 深度网络的显示
    %% 构建测试集并进行测试
    % 在搭建了完整网络之后,可以基于测试集计算结果。要将图像用于堆叠网络,必须将测试图像重构为矩阵。
    % 这可以通过先堆叠图像的各列以形成向量,然后根据这些向量形成矩阵来完成。
    % 获取每个图像中的像素数
    imageWidth = 28;
    imageHeight = 28;
    inputSize = imageWidth*imageHeight; % 输入矩阵的大小
    % 载入测试图像
    [xTestImages,tTest] = digitTestCellArrayData;
    % 图像转换为向量并放在矩阵中
    xTest = zeros(inputSize,numel(xTestImages)); %生成一个0矩阵,numel计算图像中的元素个数
    for i = 1:numel(xTestImages)
        xTest(:,i) = xTestImages{i}(:);
    end
    % 网络测试
    y = deepnet(xTest); %测试结果输出
    plotconfusion(tTest,y); % 测试结果对比,使用混淆矩阵来可视化结果
    %% Fine tuning the deep neural network 微调深度神经网络
    % 通过对整个多层网络执行反向传播,可以改进堆叠神经网络的结果,此过程通常称为微调。
    % 通过以有监督方式基于训练数据重新训练网络来进行微调。在执行此操作之前,必须将训练图像重构为矩阵,就像对测试图像所做的那样。
    xTrain = zeros(inputSize,numel(xTrainImages));
    for i = 1:numel(xTrainImages)
        xTrain(:,i) = xTrainImages{i}(:);
    end
    % 进行微调
    deepnet = train(deepnet,xTrain,tTrain);
    %再次显示结果并对比
    y = deepnet(xTest);
    plotconfusion(tTest,y); 
    
    
    展开全文
  • 堆栈式自编码器的原理请看: https://blog.csdn.net/hjimce/article/details/49106869 这里直接进行代码的实现 代码结构分为:1.mnist的读取,2.数据预处理,3.模型的训练过程。 1.mnist的读取 ''' 采用keras的堆栈...

    堆栈式自编码器的原理请看:
    https://blog.csdn.net/hjimce/article/details/49106869
    这里直接进行代码的实现
    代码结构分为:1.mnist的读取,2.数据预处理,3.模型的训练过程。

    1.mnist的读取

    ''' 采用keras的堆栈式Autoencode 将mnist的图片进行分类'''
    import numpy as np
    import os
    import struct
    np.random.seed(2018)
    
    from keras.datasets import mnist
    from keras.models import Model
    from keras.layers import Dense,Input
    from keras.utils.np_utils import to_categorical
    import matplotlib.pyplot as plt
    
    # 训练集 shape (60,000,28*28) 测试集 shape (10000,)
    def load_mnist(path,kind='train'):
        ''' load MNIST data from path'''
        labels_path=os.path.join(path,'%s-labels.idx1-ubyte' % kind)
        images_path=os.path.join(path,'%s-images.idx3-ubyte' % kind)
    
        with open(labels_path,'rb') as lbpath:
            magic,n=struct.unpack('>II',lbpath.read(8))
            labels=np.fromfile(lbpath,dtype=np.uint8)
        with open(images_path,'rb') as impath:
            magic,num,rows,cols=struct.unpack('>IIII',impath.read(16))
            images=np.fromfile(impath,dtype=np.uint8).reshape(len(labels),784)
        return images,labels
    
    X_train,y_train=load_mnist('F:\pycharm\MNIST_dataset','train')
    X_test,y_test=load_mnist('F:\pycharm\MNIST_dataset','test')
    y_train_cate= to_categorical(y_train, num_classes=10)
    y_test_cate= to_categorical(y_test, num_classes=10)
    
    # 显示mnist图片
    # 图形2*5 灰度值
    fig,ax=plt.subplots(nrows=2,ncols=5,sharex=True,sharey=True)
    ax=ax.flatten()
    for i in range(10):
        img=X_train[y_train==i][1].reshape(28,28)
        ax[i].imshow(img,cmap='Greys',interpolation='nearest')
    
    ax[0].set_xticks([])
    ax[0].set_yticks([])
    plt.tight_layout()
    plt.show()
    
    

    当然也可以直接采用keras中的函数 mnist.load_data()获取数据,但是由于数据量比较大,有可能直接下载不成功,所以我们直接采用将数据下载到本地文件夹中,然后再进行读取。数据下载链接:http://yann.lecun.com/exdb/mnist/
    在数据读取过程中,需要特别注意的地方数据格式是idx1-ubyte,idx3-ubyte的格式,需要进行转换。
    详细解释代码:
    load_mnist 函数返回两个数组, 第一个是一个 n x m 维的 NumPy array(images), 这里的 n 是样本数(行数), m 是特征数(列数). 训练数据集包含 60,000 个样本, 测试数据集包含 10,000 样本. 在 MNIST 数据集中的每张图片由 28 x 28 个像素点构成, 每个像素点用一个灰度值表示. 在这里, 我们将 28 x 28 的像素展开为一个一维的行向量, 这些行向量就是图片数组里的行(每行 784 个值, 或者说每行就是代表了一张图片). load_mnist 函数返回的第二个数组(labels) 包含了相应的目标变量, 也就是手写数字的类标签(整数 0-9).
    为了理解这两行代码, 我们先来看一下 MNIST 网站上对数据集的介绍:

    TRAINING SET LABEL FILE (train-labels-idx1-ubyte):
    
    [offset] [type]          [value]          [description] 
    0000     32 bit integer  0x00000801(2049) magic number (MSB first) 
    0004     32 bit integer  60000            number of items 
    0008     unsigned byte   ??               label 
    0009     unsigned byte   ??               label 
    ........ 
    xxxx     unsigned byte   ??               label
    The labels values are 0 to 9.
    

    通过使用上面两行代码, 我们首先读入 magic number, 它是一个文件协议的描述, 也是在我们调用 fromfile 方法将字节读入 NumPy array 之前在文件缓冲中的 item 数(n). 作为参数值传入 struct.unpack 的 >II 有两个部分:

    : 这是指大端(用来定义字节是如何存储的); 如果你还不知道什么是大端和小端, Endianness 是一个非常好的解释. (关于大小端, 更多内容可见<<深入理解计算机系统 – 2.1 节信息存储>>)
    I: 这是指一个无符号整数.
    通过执行下面的代码, 我们将会从刚刚解压 MNIST 数据集后的 mnist 目录下加载 60,000 个训练样本和 10,000 个测试样本.

    为了了解 MNIST 中的图片看起来到底是个啥, 让我们来对它们进行可视化处理. 从 feature matrix 中将 784-像素值 的向量 reshape 为之前的 28*28 的形状, 然后通过 matplotlib 的 imshow 函数进行绘制。

    2.数据预处理

    # 数据预处理
    X_train=X_train.astype('float32')/255-0.5 # minmax_normalized(归一化在(-0.5,0.5))之间
    X_test=X_test.astype('float32')/255-0.5 # minmax_normalized
    X_train_len=X_train.shape[0]
    X_test_len=X_test.shape[0]
    
    X_train=X_train.reshape((X_train_len,-1))
    X_test=X_test.reshape((X_test_len,-1))
    
    print(X_train.shape,X_test.shape)
    

    主要是将灰度图像值进行(-0.5,0。5)的归一化

    3.模型训练

    自编码网路结构采用(784,128,64,10,10,64,128,684)的结构进行无监督训练。

    nput_img=Input(shape=(784,))
    # 编码层
    encoded=Dense(128,activation='relu',name='encoded_hidden1')(input_img)
    encoder_output=Dense(64,activation='relu',name='encoded_hidden2')(encoded)
    LR=Dense(10,activation='softmax',name='LR')(encoder_output)
    
    # 解码层
    decoded=Dense(64,activation='relu',name='decoded_hidden2')(encoder_output)
    decoded=Dense(128,activation='relu',name='decoded_hidden3')(decoded)
    decoded=Dense(784,activation='tanh',name='decoded_output')(decoded)
    
    # 构建自编码模型
    autoencoder=Model(inputs=input_img,outputs=decoded)
    
    # complile autoencoder 设置自编码的优化参数
    autoencoder.compile(optimizer='adam',loss='mse')
    # train
    hist=autoencoder.fit(X_train,X_train,epochs=20,batch_size=250,shuffle=True)
    

    中间设置一个LR层,进行后面的多分类输出层。
    下面是多分类的模型训练过程:

    采用编码层的网络结构,从新构成一个新的model,此model的参数跟原来autoencode的训练的参数一样。
    encoder=Model(inputs=input_img,outputs=LR)
    encoder.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['categorical_accuracy'])
    encoder.fit(X_train,y_train_cate,epochs=20,batch_size=250,shuffle=True)
    core=encoder.evaluate(X_test,y_test_cate)
    print(score)
    print(encoder.summary())
    

    评估结果与网络参数如下:

    score:
    [0.09663939199754969, 0.9704]
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    input_1 (InputLayer)         (None, 784)               0         
    _________________________________________________________________
    encoded_hidden1 (Dense)      (None, 128)               100480    
    _________________________________________________________________
    encoded_hidden2 (Dense)      (None, 64)                8256      
    _________________________________________________________________
    LR (Dense)                   (None, 10)                650       
    =================================================================
    Total params: 109,386
    Trainable params: 109,386
    Non-trainable params: 0
    

    可以看出准确率与loss都很好。
    参考链接:
    http://yann.lecun.com/exdb/mnist/
    https://www.cnblogs.com/wzdLY/p/9683657.html
    https://blog.csdn.net/simple_the_best/article/details/75267863
    https://blog.csdn.net/hjimce/article/details/49106869

    展开全文
  • 我们使用异常检测的概念为这些过程构建了一个自动编码器分类器。 但是,我们拥有的数据是一个时间序列。但是之前我们使用了Dense层自动编码器,它不使用数据中的时间特征。因此,在这篇文章中,我们将通过构建LSTM...

    在这里,我们将学习LSTM模型的数据准备细节,并构建用于稀有事件分类的LSTM Autoencoder。

    这篇文章是我之前使用Autoencoders发布极端罕见事件分类的延续。在上一篇文章中,我们讨论了极少数事件数据中的挑战,其中正面标记数据少于1%。我们使用异常检测的概念为这些过程构建了一个自动编码器分类器。

    但是,我们拥有的数据是一个时间序列。但是之前我们使用了Dense层自动编码器,它不使用数据中的时间特征。因此,在这篇文章中,我们将通过构建LSTM Autoencoder来改进我们的方法。

    在这里,我们将学习:

    LSTM模型的数据准备步骤,
    构建和实现LSTM自动编码器,以及
    使用LSTM自动编码器进行罕见事件分类。
    快速回顾LSTM:

    LSTM是一种递归神经网络(RNN)。一般而言,RNN和LSTM特别用于顺序或时间序列数据。
    这些模型能够自动提取过去事件的影响。
    LSTM因其能够提取过去事件的长期和短期影响而闻名。
    在下文中,我们将直接开发LSTM Autoencoder。关于数据问题,我们有关于纸张制造的纸张断裂的实际数据。我们的目标是提前预测休息时间。有关数据,问题和分类方法的详细信息,请参阅使用自动编码器的极端罕见事件分类。

    LSTM多变量数据自动编码器

    在这里插入图片描述
    在我们的问题中,我们有一个多变量的时间序列数据。 多变量时间序列数据包含在一段时间内观察到的多个变量。 我们将在此多变量时间序列上构建LSTM自动编码器,以执行罕见事件分类。 如[1]中所述,这是通过使用异常检测方法实现的:

    我们在正常(负标记)数据上构建自动编码器,
    用它来重建一个新的样本,
    如果重建错误很高,我们将其标记为换页符。
    LSTM几乎不需要特殊的数据预处理步骤。 在下文中,我们将充分注意这些步骤。

    让我们来实现。

    Libraries

    I like to put together the libraries and global constants first.

    %matplotlib inline
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    import pandas as pd
    import numpy as np
    from pylab import rcParams
    
    import tensorflow as tf
    from keras import optimizers, Sequential
    from keras.models import Model
    from keras.utils import plot_model
    from keras.layers import Dense, LSTM, RepeatVector, TimeDistributed
    from keras.callbacks import ModelCheckpoint, TensorBoard
    
    from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import confusion_matrix, precision_recall_curve
    from sklearn.metrics import recall_score, classification_report, auc, roc_curve
    from sklearn.metrics import precision_recall_fscore_support, f1_score
    
    from numpy.random import seed
    seed(1)
    from tensorflow import set_random_seed
    set_random_seed(123)
    from sklearn.model_selection import train_test_split
    
    SEED = 123 #used to help randomly select the data points
    DATA_SPLIT_PCT = 0.2
    
    rcParams['figure.figsize'] = 8, 6
    LABELS = ["Normal","Break"]
    

    数据准备

    如前所述,LSTM需要在数据准备中采取一些具体步骤。 LSTM的输入是根据时间序列数据创建的三维阵列。 这是一个容易出错的步骤,因此我们将查看详细信息。

    Read data
    The data is taken from [2]. The link to the data is here.

    df = pd.read_csv("data/processminer-rare-event-mts - data.csv") 
    df.head(n=5)  # visualize the data.
    

    在这里插入图片描述

    Curve Shifting

    正如[1]中所提到的,这种罕见事件的目的是在片断发生之前预测片断。 我们将尝试提前预测4分钟。 对于此数据,这相当于将标签向上移动两行。 可以使用df.y = df.y.shift(-2)直接完成。 但是,这里我们要求执行以下操作,

    对于带有标签1的任何行n,make(n-2)? n-1)为1.这样,我们教导分类器预测最多4分钟。 和,
    删除行n。 行n被删除,因为我们不想教分类器来预测已经发生的中断。
    我们开发了以下功能来执行此曲线移位。

    sign = lambda x: (1, -1)[x < 0]
    
    def curve_shift(df, shift_by):
        '''
        This function will shift the binary labels in a dataframe.
        The curve shift will be with respect to the 1s. 
        For example, if shift is -2, the following process
        will happen: if row n is labeled as 1, then
        - Make row (n+shift_by):(n+shift_by-1) = 1.
        - Remove row n.
        i.e. the labels will be shifted up to 2 rows up.
        
        Inputs:
        df       A pandas dataframe with a binary labeled column. 
                 This labeled column should be named as 'y'.
        shift_by An integer denoting the number of rows to shift.
        
        Output
        df       A dataframe with the binary labels shifted by shift.
        '''
    
        vector = df['y'].copy()
        for s in range(abs(shift_by)):
            tmp = vector.shift(sign(shift_by))
            tmp = tmp.fillna(0)
            vector += tmp
        labelcol = 'y'
        # Add vector to the df
        df.insert(loc=0, column=labelcol+'tmp', value=vector)
        # Remove the rows with labelcol == 1.
        df = df.drop(df[df[labelcol] == 1].index)
        # Drop labelcol and rename the tmp col as labelcol
        df = df.drop(labelcol, axis=1)
        df = df.rename(columns={labelcol+'tmp': labelcol})
        # Make the labelcol binary
        df.loc[df[labelcol] > 0, labelcol] = 1
    
        return df
    

    我们现在将移动数据并验证移位是否正确。 在随后的部分中,我们还有更多的测试步骤。 建议使用它们以确保数据准备步骤按预期工作。

    print('Before shifting')  # Positive labeled rows before shifting.
    one_indexes = df.index[df['y'] == 1]
    display(df.iloc[(np.where(np.array(input_y) == 1)[0][0]-5):(np.where(np.array(input_y) == 1)[0][0]+1), ])
    
    # Shift the response column y by 2 rows to do a 4-min ahead prediction.
    df = curve_shift(df, shift_by = -2)
    
    print('After shifting')  # Validating if the shift happened correctly.
    display(df.iloc[(one_indexes[0]-4):(one_indexes[0]+1), 0:5].head(n=5))
    
    

    在这里插入图片描述

    如果我们在这里注意,我们将正面标签在5/1/99 8:38移动到n-1和n-2个时间戳,并且删除了行n。 此外,中断行和下一行之间的时间差超过2分钟。 这是因为,当发生中断时,机器会暂停状态一段时间。 在此期间,连续行的y = 1。 在提供的数据中,删除这些连续的中断行以防止分类器在已经发生之后学习预测中断。 有关详细信息,请参阅[2]。

    在继续之前,我们通过删除时间和其他两个分类列来清理数据。

    # Remove time column, and the categorical columns
    df = df.drop(['time', 'x28', 'x61'], axis=1)
    

    Prepare Input Data for LSTM

    LSTM比其他型号要求更高。 准备适合LSTM的数据可能需要大量的时间和精力。 但是,这通常是值得的。

    LSTM模型的输入数据是三维数组。 数组的形状是样本x回溯x特征。 让我们理解他们,

    samples:这只是观察的数量,换句话说,就是数据点的数量。
    回顾:LSTM模型旨在回顾过去。 意思是,在时间t,LSTM将处理数据直到(t-lookback)进行预测。
    特征:它是输入数据中存在的特征数。
    首先,我们将提取功能和响应。

    input_X = df.loc[:, df.columns != 'y'].values  # converts the df to a numpy array
    input_y = df['y'].values
    
    n_features = input_X.shape[1]  # number of features
    

    这里的input_X是大小样本x特征的二维数组。 我们希望能够将这样的2D数组转换为大小的3D数组:samples x lookback x features。 请参阅上面的图1以获得视觉理解。

    为此,我们开发了一个函数temporalize。

    def temporalize(X, y, lookback):
        X = []
        y = []
        for i in range(len(input_X)-lookback-1):
            t = []
            for j in range(1,lookback+1):
                # Gather past records upto the lookback period
                t.append(input_X[[(i+j+1)], :])
            X.append(t)
            y.append(input_y[i+lookback+1])
        return X, y
    

    为了测试和演示此函数,我们将使用lookback = 5查看下面的示例。

    print('First instance of y = 1 in the original data')
    display(df.iloc[(np.where(np.array(input_y) == 1)[0][0]-5):(np.where(np.array(input_y) == 1)[0][0]+1), ])
    lookback = 5  # Equivalent to 10 min of past data.
    # Temporalize the data
    X, y = temporalize(X = input_X, y = input_y, lookback = lookback)
    print('For the same instance of y = 1, we are keeping past 5 samples in the 3D predictor array, X.')
    display(pd.DataFrame(np.concatenate(X[np.where(np.array(y) == 1)[0][0]], axis=0 )))
    
    

    在这里插入图片描述

    我们在这里寻找的是,

    在原始数据中,第257行y = 1。
    使用lookback = 5,我们希望LSTM查看第257行(包括其自身)之前的5行。
    在3D阵列X中,X [i,:,]处的每个2D块表示对应于y [i]的预测数据。 为了得出类比,在回归中y [i]对应于1D向量X [i,:]; 在LSTM中,y [i]对应于2D阵列X [i,:,]。
    这个2D块X [i,:,]应该在input_X [i,:]处具有预测变量,并且前面的行应该具有给定的回溯。
    正如我们在上面的输出中所看到的,底部的X [i,:,]块与顶部显示的y = 1的前五行相同。
    同样,这适用于所有y的整个数据。 此处的示例显示为y = 1的实例,以便于可视化。### Split into train, valid, and test
    This is straightforward with the sklearn function.

    X_train, X_test, y_train, y_test = train_test_split(np.array(X), np.array(y), test_size=DATA_SPLIT_PCT, random_state=SEED)
    X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=DATA_SPLIT_PCT, random_state=SEED)
    

    为了训练自动编码器,我们将使用仅来自负标记数据的X. 因此,我们将对应于y = 0的X分开。

    X_train_y0 = X_train[y_train==0]
    X_train_y1 = X_train[y_train==1]
    X_valid_y0 = X_valid[y_valid==0]
    X_valid_y1 = X_valid[y_valid==1]
    

    我们将把X重塑为所需的3D维度:样本x回溯x特征。

    X_train = X_train.reshape(X_train.shape[0], lookback, n_features)
    X_train_y0 = X_train_y0.reshape(X_train_y0.shape[0], lookback, n_features)
    X_train_y1 = X_train_y1.reshape(X_train_y1.shape[0], lookback, n_features)
    X_valid = X_valid.reshape(X_valid.shape[0], lookback, n_features)
    X_valid_y0 = X_valid_y0.reshape(X_valid_y0.shape[0], lookback, n_features)
    X_valid_y1 = X_valid_y1.reshape(X_valid_y1.shape[0], lookback, n_features)
    X_test = X_test.reshape(X_test.shape[0], lookback, n_features)
    

    Standardize the Data

    通常最好使用标准化数据(转换为高斯,平均值为0,标准差为1)用于自动编码器。

    一个常见的标准化错误是:我们将整个数据标准化,然后分成列车测试。 这是不正确的。 在建模过程中,测试数据应该完全看不到任何东西。 因此,我们应该对训练数据进行标准化,并使用其摘要统计数据来规范化测试数据(对于标准化,这些统计数据是每个特征的均值和方差)。
    标准化这些数据有点棘手。 这是因为X矩阵是3D,我们希望标准化相对于原始2D数据发生。

    为此,我们将需要两个UDF。

    flatten:此函数将重新创建从中创建3D阵列的原始2D阵列。 该函数是temporalize的倒数,意味着X = flatten(temporalize(X))。
    scale:此函数将缩放我们创建的3D数组作为LSTM的输入。

    def flatten(X):
        '''
        Flatten a 3D array.
        
        Input
        X            A 3D array for lstm, where the array is sample x timesteps x features.
        
        Output
        flattened_X  A 2D array, sample x features.
        '''
        flattened_X = np.empty((X.shape[0], X.shape[2]))  # sample x features array.
        for i in range(X.shape[0]):
            flattened_X[i] = X[i, (X.shape[1]-1), :]
        return(flattened_X)
    
    def scale(X, scaler):
        '''
        Scale 3D array.
    
        Inputs
        X            A 3D array for lstm, where the array is sample x timesteps x features.
        scaler       A scaler object, e.g., sklearn.preprocessing.StandardScaler, sklearn.preprocessing.normalize
        
        Output
        X            Scaled 3D array.
        '''
        for i in range(X.shape[0]):
            X[i, :, :] = scaler.transform(X[i, :, :])
            
        return X
    

    为什么我们不首先规范原始2D数据然后创建3D数组? 因为,要做到这一点,我们将:将数据拆分为训练和测试,然后进行标准化。 但是,当我们在测试数据上创建3D数组时,我们会丢失最初的样本行直到回顾。 拆分为train-valid-test将导致验证和测试集。
    我们将从sklearn中安装标准化对象。 此功能将数据标准化为Normal(0,1)。 请注意,我们需要展平X_train_y0数组以传递给fit函数。

    # Initialize a scaler using the training data.
    scaler = StandardScaler().fit(flatten(X_train_y0))
    

    We will use our UDF, scale, to standardize X_train_y0 with the fitted transform object scaler.

    X_train_y0_scaled = scale(X_train_y0, scaler)
    

    Make sure the scale worked correctly?

    X_train的正确转换将确保扁平X_train的每列的均值和方差分别为0和1。 我们测试一下。

    a = flatten(X_train_y0_scaled)
    print('colwise mean', np.mean(a, axis=0).round(6))
    print('colwise variance', np.var(a, axis=0))
    

    在这里插入图片描述

    上面输出的所有均值和方差分别为0和1。 因此,缩放是正确的。 我们现在将扩展验证和测试集。 我们将再次在这些集合上使用缩放器对象。

    X_valid_scaled = scale(X_valid, scaler)
    X_valid_y0_scaled = scale(X_valid_y0, scaler)
    X_test_scaled = scale(X_test, scaler)
    

    LSTM Autoencoder Training

    We will, first, initialize few variables.

    timesteps =  X_train_y0_scaled.shape[1] # equal to the lookback
    n_features =  X_train_y0_scaled.shape[2] # 59, the number of variables
    
    epochs = 500
    batch = 64
    lr = 0.0001
    

    We, now, develop a simple architecture.

    lstm_autoencoder = Sequential()
    # Encoder
    lstm_autoencoder.add(LSTM(timesteps, activation='relu', input_shape=(timesteps, n_features), return_sequences=True))
    lstm_autoencoder.add(LSTM(16, activation='relu', return_sequences=True))
    lstm_autoencoder.add(LSTM(1, activation='relu'))
    lstm_autoencoder.add(RepeatVector(timesteps))
    # Decoder
    lstm_autoencoder.add(LSTM(timesteps, activation='relu', return_sequences=True))
    lstm_autoencoder.add(LSTM(16, activation='relu', return_sequences=True))
    lstm_autoencoder.add(TimeDistributed(Dense(n_features)))
    
    lstm_autoencoder.summary()
    

    在这里插入图片描述
    从summary()中,参数总数为5,331。 这大约是培训规模的一半。 因此,这是一个合适的模型。 要拥有更大的架构,我们需要添加正则化,例如 辍学,将在下一篇文章中介绍。

    现在,我们将训练自动编码器。

    adam = optimizers.Adam(lr)
    lstm_autoencoder.compile(loss='mse', optimizer=adam)
    
    cp = ModelCheckpoint(filepath="lstm_autoencoder_classifier.h5",
                                   save_best_only=True,
                                   verbose=0)
    
    tb = TensorBoard(log_dir='./logs',
                    histogram_freq=0,
                    write_graph=True,
                    write_images=True)
    
    lstm_autoencoder_history = lstm_autoencoder.fit(X_train_y0_scaled, X_train_y0_scaled, 
                                                    epochs=epochs, 
                                                    batch_size=batch, 
                                                    validation_data=(X_valid_y0_scaled, X_valid_y0_scaled),
                                                    verbose=2).history
    

    在这里插入图片描述
    Plotting the change in the loss over the epochs.

    plt.plot(lstm_autoencoder_history['loss'], linewidth=2, label='Train')
    plt.plot(lstm_autoencoder_history['val_loss'], linewidth=2, label='Valid')
    plt.legend(loc='upper right')
    plt.title('Model loss')
    plt.ylabel('Loss')
    plt.xlabel('Epoch')
    plt.show()
    

    在这里插入图片描述

    Classification

    Similar to the previous post [1],
    这里我们展示了如何使用自动编码器重建错误进行稀有事件分类。 我们遵循这个概念:自动编码器有望重建一个重建错误很高的noif,我们将其归类为一个分页符。

    我们需要确定这个门槛。 另请注意,这里我们将使用包含y = 0或1的整个验证集。

    valid_x_predictions = lstm_autoencoder.predict(X_valid_scaled)
    mse = np.mean(np.power(flatten(X_valid_scaled) - flatten(valid_x_predictions), 2), axis=1)
    error_df = pd.DataFrame({'Reconstruction_error': mse,
                            'True_class': y_valid.tolist()})
    precision_rt, recall_rt, threshold_rt = precision_recall_curve(error_df.True_class, error_df.Reconstruction_error)
    plt.plot(threshold_rt, precision_rt[1:], label="Precision",linewidth=5)
    plt.plot(threshold_rt, recall_rt[1:], label="Recall",linewidth=5)
    plt.title('Precision and recall for different threshold values')
    plt.xlabel('Threshold')
    plt.ylabel('Precision/Recall')
    plt.legend()
    plt.show()
    

    Note that we have to flatten the arrays to compute the mse.

    在这里插入图片描述

    图3. 0.8的阈值应该在精确度和召回率之间提供合理的权衡,因为我们希望更高的召回率。
    现在,我们将对测试数据进行分类。

    我们不应该从测试数据估计分类阈值。 这会导致过度拟合。

    threshold_fixed = 0.7
    groups = error_df.groupby('True_class')
    fig, ax = plt.subplots()
    for name, group in groups:
        ax.plot(group.index, group.Reconstruction_error, marker='o', ms=3.5, linestyle='',
                label= "Fraud" if name == 1 else "Normal")
    ax.hlines(threshold_fixed, ax.get_xlim()[0], ax.get_xlim()[1], colors="r", zorder=100, label='Threshold')
    ax.legend()
    plt.title("Reconstruction error for different classes")
    plt.ylabel("Reconstruction error")
    plt.xlabel("Data point index")
    plt.show();
    

    在这里插入图片描述

    图4.使用阈值= 0.8进行分类。 阈值线上方的橙色和蓝色点分别代表真阳性和假阳性。
    在图4中,阈值线上方的橙色和蓝色点分别代表真阳性和假阳性。 我们可以看到,我们有很多误报。

    让我们看看准确性结果。

    Test Accuracy

    Confusion Matrix
    pred_y = [1 if e > threshold_fixed else 0 for e in error_df.Reconstruction_error.values]
    conf_matrix = confusion_matrix(error_df.True_class, pred_y)
    plt.figure(figsize=(12, 12))
    sns.heatmap(conf_matrix, xticklabels=LABELS, yticklabels=LABELS, annot=True, fmt="d");
    plt.title("Confusion matrix")
    plt.ylabel('True class')
    plt.xlabel('Predicted class')
    plt.show()
    

    在这里插入图片描述
    Figure 5. Confusion matrix showing the True Positives and False Positives.

    ROC Curve and AUC

    false_pos_rate, true_pos_rate, thresholds = roc_curve(error_df.True_class, error_df.Reconstruction_error)
    roc_auc = auc(false_pos_rate, true_pos_rate,)
    plt.plot(false_pos_rate, true_pos_rate, linewidth=5, label='AUC = %0.3f'% roc_auc)
    plt.plot([0,1],[0,1], linewidth=5)
    plt.xlim([-0.01, 1])
    plt.ylim([0, 1.01])
    plt.legend(loc='lower right')
    plt.title('Receiver operating characteristic curve (ROC)')
    plt.ylabel('True Positive Rate')
    plt.xlabel('False Positive Rate')
    plt.show()
    

    在这里插入图片描述

    图6. ROC曲线。
    与[1]中的密集层自动编码器相比,我们看到AUC提高了约10%。 从图5中的Confusion Matrix,我们可以预测39个中断实例中的10个。 正如[1]中所讨论的,这对造纸厂来说意义重大。 然而,与密集层自动编码器相比,我们实现的改进很小。

    主要原因是LSTM模型有更多的参数来估算。 使用LSTM正则化变得很重要。 正规化和其他模型改进将在下一篇文章中讨论。

    Github repository

    What can be done better?

    In the next article, we will learn tuning an Autoencoder. We will go over,

    CNN LSTM Autoencoder,
    Dropout layer,
    LSTM Dropout (Dropout_U and Dropout_W)
    Gaussian-dropout layer
    SELU activation, and
    alpha-dropout with SELU activation.

    Conclusion

    这篇文章继续在[1]中关于极端罕见事件二进制标记数据的工作。 为了利用时间模式,LSTM Autoencoders用于为多变量时间序列过程构建罕见的事件分类器。 讨论了有关LSTM模型的数据预处理步骤的详细信息。 训练简单的LSTM自动编码器模型并用于分类。 发现了对密集自动编码器的准确性的一些改进。 为了进一步改进,我们将在下一篇文章中探讨使用Dropout和其他技术改进Autoencoder的方法。

    References

    
    
    
    
    
    
    
    
    
    
    
    
    展开全文
  • 结合自编码器技术和改进的K-means聚类技术针对网络流量实现了未知协议的分类识别。利用自编码器对网络流量进行降维和特征提取,使用聚类技术对降维后数据进行无监督的分类,最终实现对网络流量的无监督识别分类。...
  • 自编码器是深度学习中的一种非常重要的无监督学习方法,能够从大量无标签的数据中自动学习,得到蕴含在数据中的有效特征。因此,编码方法近年来受到了广泛的关注,已成功应用于很多领域,例如数据分类、模式识别、...
  • 【翻译: Autoencoder Feature Extraction for Classification】 【说明:Jason BrownleePhD大神...编码器压缩输入,而解码器尝试根据编码器提供的压缩版本重新创建输入。训练后,将保存编码器模型,并丢弃解码...

           【翻译自: Autoencoder Feature Extraction for Classification

          【说明:Jason Brownlee PhD大神的文章个人很喜欢,所以闲暇时间里会做一点翻译和学习实践的工作,这里是相应工作的实践记录,希望能帮到有需要的人!】

         自动编码器是一种神经网络,可用于学习原始数据的压缩表示。自动编码器由编码器和解码器子模型组成。编码器压缩输入,而解码器尝试根据编码器提供的压缩版本重新创建输入。训练后,将保存编码器模型,并丢弃解码器。然后,编码器可用作数据准备技术,对原始数据执行特征提取,以用于训练不同的机器学习模型。

         在本教程中,您将发现如何开发和评估用于分类预测建模的自动编码器。完成本教程后,您将知道:

    自动编码器是一种神经网络模型,可用于学习原始数据的压缩表示形式。
    如何在训练数据集上训练自动编码器模型,并仅保存模型的编码器部分。
    训练机器学习模型时如何使用编码器作为数据准备步骤。

    教程概述

          本教程分为三个部分: 他们是:

    用于特征提取的自动编码器
    分类自动编码器
    编码器作为预测模型的数据准备


    用于特征提取的自动编码器

           自动编码器是一种神经网络模型,旨在学习输入的压缩表示形式。它们是一种无监督的学习方法,尽管从技术上讲,它们是使用有监督的学习方法(称为自我监督)进行训练的。自动编码器通常被训练为尝试重新创建输入的更广泛模型的一部分。

         例如:   X = model.predict(X)

        自动编码器模型的设计通过将体系结构限制在模型中点的瓶颈处来故意使此挑战变得困难,从该瓶颈执行输入数据的重构。自动编码器的类型很多,其用途各不相同,但也许更常见的用途是作为学习型或自动特征提取模型。在这种情况下,一旦模型适合,就可以放弃模型的重构方面,可以使用直至瓶颈的模型。 模型在瓶颈处的输出是固定长度的向量,该向量提供输入数据的压缩表示。

         然后,可以将来自域的输入数据提供给模型,并且可以将瓶颈处的模型输出用作监督学习模型中的特征向量,以进行可视化,或更普遍地用于降维。接下来,让我们探讨如何针对分类预测建模问题开发用于特征提取的自动编码器。

    分类自动编码器

        在本节中,我们将开发一种自动编码器,以学习用于分类预测建模问题的输入特征的压缩表示。首先,让我们定义分类预测建模问题。我们将使用make_classification()scikit-learn函数定义具有100个输入要素(列)和1,000个示例(行)的合成二进制(2类)分类任务。 重要的是,我们将以大多数输入变量都是冗余的(100个中的90个或90%)的方式定义问题,以便以后自动编码器可以学习有用的压缩表示形式。

          下面的示例定义了数据集并总结了其形状。

    # synthetic classification dataset
    from sklearn.datasets import make_classification
    # define dataset
    X, y = make_classification(n_samples=1000, n_features=100, n_informative=10, n_redundant=90, random_state=1)
    # summarize the dataset
    print(X.shape, y.shape)

         运行示例将定义数据集并打印数组的形状,从而确认行数和列数。

    (1000, 100) (1000,)

          接下来,我们将开发一个多层感知器(MLP)自动编码器模型。该模型将采用所有输入列,然后输出相同的值。它将学习准确地重新创建输入模式。自动编码器由两部分组成:编码器和解码器。编码器学习如何解释输入并将其压缩为瓶颈层定义的内部表示。解码器获取编码器的输出(瓶颈层),并尝试重新创建输入。一旦对自动编码器进行了训练,解码器将被丢弃,我们仅保留编码器并将其用于将输入示例压缩为瓶颈层输出的矢量。在第一个自动编码器中,我们将完全不压缩输入,而将使用与输入大小相同的瓶颈层。这应该是一个容易解决的问题,该模型将几乎完美地学习并且旨在确认我们的模型已正确实现。

         我们将使用功能性API定义模型;如果这对您来说是新手,我建议您学习本教程:

       如何使用Keras功能API进行深度学习
       在定义和拟合模型之前,我们将数据分为训练集和测试集,并通过将值归一化为0-1范围来缩放输入数据,这是MLP的一种良好做法。

    # split into train test sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
    # scale data
    t = MinMaxScaler()
    t.fit(X_train)
    X_train = t.transform(X_train)
    X_test = t.transform(X_test)

         我们将编码器定义为具有两个隐藏层,第一层具有两倍的输入数量(例如200),第二层具有相同的输入数量(100),其次是瓶颈层,具有与输入相同数量的输入。 数据集(100)。为确保模型学习良好,我们将使用批处理规范化和泄漏性ReLU激活。

    # define encoder
    visible = Input(shape=(n_inputs,))
    # encoder level 1
    e = Dense(n_inputs*2)(visible)
    e = BatchNormalization()(e)
    e = LeakyReLU()(e)
    # encoder level 2
    e = Dense(n_inputs)(e)
    e = BatchNormalization()(e)
    e = LeakyReLU()(e)
    # bottleneck
    n_bottleneck = n_inputs
    bottleneck = Dense(n_bottleneck)(e)

          解码器将以类似的结构定义,尽管相反。它将具有两个隐藏层,第一层具有数据集中的输入数量(例如100),第二层具有两倍的输入数量(例如200)。 输出层的节点数与输入数据中的列数相同,并将使用线性激活函数输出数值。

    # define decoder, level 1
    d = Dense(n_inputs)(bottleneck)
    d = BatchNormalization()(d)
    d = LeakyReLU()(d)
    # decoder level 2
    d = Dense(n_inputs*2)(d)
    d = BatchNormalization()(d)
    d = LeakyReLU()(d)
    # output layer
    output = Dense(n_inputs, activation='linear')(d)
    # define autoencoder model
    model = Model(inputs=visible, outputs=output)

            考虑到重构是多输出回归问题的一种,该模型将使用高效的随机随机梯度下降法进行拟合,并最小化均方误差。

    # compile autoencoder model
    model.compile(optimizer='adam', loss='mse')

          我们可以在自动编码器模型中绘制图层,以了解数据如何流过模型。

    # plot the autoencoder
    plot_model(model, 'autoencoder_no_compress.png', show_shapes=True)

           下图显示了自动编码器的图。

           接下来,我们可以训练模型以重现输入,并在保持测试集上跟踪模型的性能。

    # fit the autoencoder model to reconstruct input
    history = model.fit(X_train, X_train, epochs=200, batch_size=16, verbose=2, validation_data=(X_test,X_test))

           训练后,我们可以绘制训练和测试集的学习曲线,以确认模型很好地学习了重建问题。

    # plot loss
    pyplot.plot(history.history['loss'], label='train')
    pyplot.plot(history.history['val_loss'], label='test')
    pyplot.legend()
    pyplot.show()

            最后,如果需要,我们可以保存编码器模型供以后使用。

    # define an encoder model (without the decoder)
    encoder = Model(inputs=visible, outputs=bottleneck)
    plot_model(encoder, 'encoder_no_compress.png', show_shapes=True)
    # save the encoder to file
    encoder.save('encoder.h5')

          作为保存编码器的一部分,我们还将绘制编码器模型,以了解瓶颈层输出的形状,例如 100元素向量。下面提供了该图的示例。

           综上所述,下面列出了自动编码器的完整示例,该示例可用于重构分类数据集的输入数据,而无需在瓶颈层进行任何压缩。

    # train autoencoder for classification with no compression in the bottleneck layer
    from sklearn.datasets import make_classification
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.model_selection import train_test_split
    from tensorflow.keras.models import Model
    from tensorflow.keras.layers import Input
    from tensorflow.keras.layers import Dense
    from tensorflow.keras.layers import LeakyReLU
    from tensorflow.keras.layers import BatchNormalization
    from tensorflow.keras.utils import plot_model
    from matplotlib import pyplot
    # define dataset
    X, y = make_classification(n_samples=1000, n_features=100, n_informative=10, n_redundant=90, random_state=1)
    # number of input columns
    n_inputs = X.shape[1]
    # split into train test sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
    # scale data
    t = MinMaxScaler()
    t.fit(X_train)
    X_train = t.transform(X_train)
    X_test = t.transform(X_test)
    # define encoder
    visible = Input(shape=(n_inputs,))
    # encoder level 1
    e = Dense(n_inputs*2)(visible)
    e = BatchNormalization()(e)
    e = LeakyReLU()(e)
    # encoder level 2
    e = Dense(n_inputs)(e)
    e = BatchNormalization()(e)
    e = LeakyReLU()(e)
    # bottleneck
    n_bottleneck = n_inputs
    bottleneck = Dense(n_bottleneck)(e)
    # define decoder, level 1
    d = Dense(n_inputs)(bottleneck)
    d = BatchNormalization()(d)
    d = LeakyReLU()(d)
    # decoder level 2
    d = Dense(n_inputs*2)(d)
    d = BatchNormalization()(d)
    d = LeakyReLU()(d)
    # output layer
    output = Dense(n_inputs, activation='linear')(d)
    # define autoencoder model
    model = Model(inputs=visible, outputs=output)
    # compile autoencoder model
    model.compile(optimizer='adam', loss='mse')
    # plot the autoencoder
    plot_model(model, 'autoencoder_no_compress.png', show_shapes=True)
    # fit the autoencoder model to reconstruct input
    history = model.fit(X_train, X_train, epochs=200, batch_size=16, verbose=2, validation_data=(X_test,X_test))
    # plot loss
    pyplot.plot(history.history['loss'], label='train')
    pyplot.plot(history.history['val_loss'], label='test')
    pyplot.legend()
    pyplot.show()
    # define an encoder model (without the decoder)
    encoder = Model(inputs=visible, outputs=bottleneck)
    plot_model(encoder, 'encoder_no_compress.png', show_shapes=True)
    # save the encoder to file
    encoder.save('encoder.h5')

         运行示例符合模型,并报告沿途训练和测试集上的损失。

         注意:如果在创建模型图时遇到问题,可以注释掉导入并调用plot_model()函数。

         注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。 考虑运行该示例几次并比较平均结果。

        在这种情况下,我们看到损失变低了,但是在瓶颈层没有压缩的情况下,损失并没有达到零(正如我们可能预期的那样)。 也许需要进一步调整模型架构或学习超参数。

    ...
    42/42 - 0s - loss: 0.0032 - val_loss: 0.0016
    Epoch 196/200
    42/42 - 0s - loss: 0.0031 - val_loss: 0.0024
    Epoch 197/200
    42/42 - 0s - loss: 0.0032 - val_loss: 0.0015
    Epoch 198/200
    42/42 - 0s - loss: 0.0032 - val_loss: 0.0014
    Epoch 199/200
    42/42 - 0s - loss: 0.0031 - val_loss: 0.0020
    Epoch 200/200
    42/42 - 0s - loss: 0.0029 - val_loss: 0.0017

          创建了一条学习曲线图,表明该模型在重构输入时取得了很好的拟合,在整个训练过程中保持稳定,而不是过度拟合。  到现在为止还挺好。 我们知道如何开发无压缩的自动编码器。接下来,让我们更改模型的配置,以使瓶颈层的节点数减少一半(例如50个)。

    # bottleneck
    n_bottleneck = round(float(n_inputs) / 2.0)
    bottleneck = Dense(n_bottleneck)(e)

          完整代码实例如下:

    # train autoencoder for classification with with compression in the bottleneck layer
    from sklearn.datasets import make_classification
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.model_selection import train_test_split
    from tensorflow.keras.models import Model
    from tensorflow.keras.layers import Input
    from tensorflow.keras.layers import Dense
    from tensorflow.keras.layers import LeakyReLU
    from tensorflow.keras.layers import BatchNormalization
    from tensorflow.keras.utils import plot_model
    from matplotlib import pyplot
    # define dataset
    X, y = make_classification(n_samples=1000, n_features=100, n_informative=10, n_redundant=90, random_state=1)
    # number of input columns
    n_inputs = X.shape[1]
    # split into train test sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
    # scale data
    t = MinMaxScaler()
    t.fit(X_train)
    X_train = t.transform(X_train)
    X_test = t.transform(X_test)
    # define encoder
    visible = Input(shape=(n_inputs,))
    # encoder level 1
    e = Dense(n_inputs*2)(visible)
    e = BatchNormalization()(e)
    e = LeakyReLU()(e)
    # encoder level 2
    e = Dense(n_inputs)(e)
    e = BatchNormalization()(e)
    e = LeakyReLU()(e)
    # bottleneck
    n_bottleneck = round(float(n_inputs) / 2.0)
    bottleneck = Dense(n_bottleneck)(e)
    # define decoder, level 1
    d = Dense(n_inputs)(bottleneck)
    d = BatchNormalization()(d)
    d = LeakyReLU()(d)
    # decoder level 2
    d = Dense(n_inputs*2)(d)
    d = BatchNormalization()(d)
    d = LeakyReLU()(d)
    # output layer
    output = Dense(n_inputs, activation='linear')(d)
    # define autoencoder model
    model = Model(inputs=visible, outputs=output)
    # compile autoencoder model
    model.compile(optimizer='adam', loss='mse')
    # plot the autoencoder
    plot_model(model, 'autoencoder_compress.png', show_shapes=True)
    # fit the autoencoder model to reconstruct input
    history = model.fit(X_train, X_train, epochs=200, batch_size=16, verbose=2, validation_data=(X_test,X_test))
    # plot loss
    pyplot.plot(history.history['loss'], label='train')
    pyplot.plot(history.history['val_loss'], label='test')
    pyplot.legend()
    pyplot.show()
    # define an encoder model (without the decoder)
    encoder = Model(inputs=visible, outputs=bottleneck)
    plot_model(encoder, 'encoder_compress.png', show_shapes=True)
    # save the encoder to file
    encoder.save('encoder.h5')

        运行示例符合模型,并报告沿途训练和测试集上的损失。

       注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。 考虑运行该示例几次并比较平均结果。

        在这种情况下,我们看到的损失与上述示例类似,没有压缩,并且损失很小,这表明该模型在瓶颈只有一半的情况下也能表现出色。

    42/42 - 0s - loss: 0.0029 - val_loss: 0.0010
    Epoch 196/200
    42/42 - 0s - loss: 0.0029 - val_loss: 0.0013
    Epoch 197/200
    42/42 - 0s - loss: 0.0030 - val_loss: 9.4472e-04
    Epoch 198/200
    42/42 - 0s - loss: 0.0028 - val_loss: 0.0015
    Epoch 199/200
    42/42 - 0s - loss: 0.0033 - val_loss: 0.0021
    Epoch 200/200
    42/42 - 0s - loss: 0.0027 - val_loss: 8.7731e-04

          创建了一条学习曲线图,再次表明该模型在重构输入时取得了很好的拟合,在整个训练过程中保持稳定,而不是过度拟合。

        经过训练的编码器将保存到文件“ encoder.h5”中,我们以后可以加载和使用。接下来,让我们探讨如何使用训练有素的编码器模型。

    编码器作为预测模型的数据准备

          在本节中,我们将使用自动编码器中训练有素的编码器来压缩输入数据并训练不同的预测模型。首先,让我们为该问题建立性能基准。 这很重要,因为压缩的编码无法改善模型的性能,那么压缩的编码不会为项目增加价值,因此不应使用。我们可以直接在训练数据集上训练逻辑回归模型,并在保留测试集上评估模型的性能。下面列出了完整的示例。

    # baseline in performance with logistic regression model
    from sklearn.datasets import make_classification
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.preprocessing import LabelEncoder
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import accuracy_score
    # define dataset
    X, y = make_classification(n_samples=1000, n_features=100, n_informative=10, n_redundant=90, random_state=1)
    # split into train test sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
    # scale data
    t = MinMaxScaler()
    t.fit(X_train)
    X_train = t.transform(X_train)
    X_test = t.transform(X_test)
    # define model
    model = LogisticRegression()
    # fit model on training set
    model.fit(X_train, y_train)
    # make prediction on test set
    yhat = model.predict(X_test)
    # calculate accuracy
    acc = accuracy_score(y_test, yhat)
    print(acc)

          运行示例将逻辑回归模型拟合到训练数据集上,并在测试集上对其进行评估。

         注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。 考虑运行该示例几次并比较平均结果。

         在这种情况下,我们可以看到该模型实现了约89.3%的分类精度。

         我们希望并期望逻辑回归模型适合输入的编码版本,从而为认为有用的编码实现更高的准确性。

    0.8939393939393939

          我们可以更新示例,以使用上一节中训练的编码器模型首先对数据进行编码。首先,我们可以从文件中加载经过训练的编码器模型。

    # load the model from file
    encoder = load_model('encoder.h5')

          然后,我们可以使用编码器将原始输入数据(例如100列)转换为瓶颈向量(例如50个元素向量)。该过程可以应用于训练和测试数据集。

    # encode the train data
    X_train_encode = encoder.predict(X_train)
    # encode the test data
    X_test_encode = encoder.predict(X_test)

          然后,我们可以像以前一样使用此编码数据来训练和评估逻辑回归模型。

    # define the model
    model = LogisticRegression()
    # fit the model on the training set
    model.fit(X_train_encode, y_train)
    # make predictions on the test set
    yhat = model.predict(X_test_encode)

            完整实例如下所示:

    # evaluate logistic regression on encoded input
    from sklearn.datasets import make_classification
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.preprocessing import LabelEncoder
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import accuracy_score
    from tensorflow.keras.models import load_model
    # define dataset
    X, y = make_classification(n_samples=1000, n_features=100, n_informative=10, n_redundant=90, random_state=1)
    # split into train test sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
    # scale data
    t = MinMaxScaler()
    t.fit(X_train)
    X_train = t.transform(X_train)
    X_test = t.transform(X_test)
    # load the model from file
    encoder = load_model('encoder.h5')
    # encode the train data
    X_train_encode = encoder.predict(X_train)
    # encode the test data
    X_test_encode = encoder.predict(X_test)
    # define the model
    model = LogisticRegression()
    # fit the model on the training set
    model.fit(X_train_encode, y_train)
    # make predictions on the test set
    yhat = model.predict(X_test_encode)
    # calculate classification accuracy
    acc = accuracy_score(y_test, yhat)
    print(acc)

          运行示例时,首先使用编码器对数据集进行编码,然后将逻辑回归模型拟合到训练数据集上,并在测试集上进行评估。

         注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。 考虑运行该示例几次并比较平均结果。

         在这种情况下,我们可以看到该模型实现了约93.9%的分类精度。

         这比原始数据集上评估的同一模型具有更好的分类精度,这表明编码对于我们选择的模型和测试工具很有帮助。

    0.9393939393939394

     

    相关接口参考

     

     

     

     

     

     

     

     

     

    展开全文
  • 深度学习之卷积自编码器

    万次阅读 多人点赞 2018-10-31 10:49:48
    一、自编码器 自编码器(Autoencoder)是一种旨在将它们的输入复制到的输出的神经网络。他们通过将输入压缩成一种隐藏空间表示(latent-space representation),然后这种重构这种表示的输出进行工作。这种网络由两...
  • 针对这一问题,提出一种基于一维堆叠卷积自编码器分类检测方法.该方法具有噪声鲁棒性强、提取特征可判别性高等优势.首先,通过布置光纤传感器获取结构表面应变数据,对光纤应变数据进行标准化预处理,并划分应变...
  • 深度学习:自动编码器基础和类型

    千次阅读 2018-12-21 14:37:34
    本文转载《机器之心》,原文链接:...Mobibit 创始人兼 CEO Pramod Chandrayan 近日在 codeburst.io 上发文对自动编码器的基础知识和类型进行了介绍并给出了代码实例。机器之心对本文进行了...
  • 为降低人工成本,提出了一种基于稀疏自编码器的烟叶成熟度分类算法,从计算机视觉角度自动识别烟叶的成熟度。首先对烟叶数字图像进行去除背景、归一化等预处理操作;其次从无监督学习算法入手,利用稀疏自编码器构建特征...
  • 文章目录一、自编码器(Autoencoder, AE)自编码器的结构和思想结构思想自编码器的作用与类型作用类型二、Tensorflower代码实现普通自编码器多层自编码器卷积自编码器稀疏自编码器 一、自编码器(Autoencoder, AE) ...
  • 基于深度自动编码器的多标签分类研究
  • 最先提出深度学习算法hinton的自动编码器matlab代码,内容是:利用多层rbm进行自动编码的多层特征训练,然后使用梯度算法进行fine turn。可以进行特征提取,也可以进行分类
  • 堆栈自编码器 Stacked AutoEncoder

    千次阅读 2019-10-18 13:45:02
    堆叠自编码器(Stacked Autoencoder,SAE)实际上就是做这样的事情,如前面的自编码器,稀疏自编码器和降噪自编码器都是单个自编码器,它们通过虚构一个x−>h−>xx−>h−>x的三层网络,...
  • 生活中经常使用的电梯是如何精确的把人们送到指定楼层的?机床又是如何做到精确切割物料的?伺服电机又是如何保证旋转位置精度的?这一切都要归功于一种神器——编码器,... 二、编码器分类  按照工作原理编码器可分为
  • 自编码器及其变形很多,本篇博客目前主要基于普通自编码器、欠完备自编码器、稀疏自编码器和去噪自编码器,会提供理论+实践(有的理论本人没有完全理解,就先没有写上,后更)。另外,关于收缩自编码器、变分自编码...
  • Keras实现各类自编码器

    千次阅读 2016-12-16 18:31:59
    Keras实现各类自编码器及遇到的问题小结
  • 一、卷积自编码器 1、读入图像,并可视化 %matplotlib inline import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.examples.tutorials.mnist import input_data ...
  • 基于堆叠稀疏自动编码器(SSAE)的乳腺癌组织病理学核补丁分类框架
  • 正则自编码器之稀疏自编码器

    千次阅读 2019-09-10 12:39:48
    编码维数小于输入维数的欠完备自编码器可以学习数据分布最显著的特征,但如果这类自编码器的容量过大,将会专注于复制任务进而学习不到任何有益信息。 如果隐藏编码的维数与输入相等或者大于输入的过完备自编码器...
  • 自动编码器—Autoencoder

    万次阅读 多人点赞 2017-12-28 17:18:02
    自动编码器 Deep Learning最简单的一种方法是利用人工神经网络的特点,人工神经网络(ANN)本身就是具有层次结构的系统,如果给定一个神经网络,我们假设其输出与输入是相同的,然后训练调整其参数,得到每...
  • 深度学习:自编码进行模式分类

    千次阅读 2017-11-27 16:47:43
    知道了自编码学习其实就是学习到了输入数据的隐含特征,通过新的特征来表征原始数据,本节将介绍如何使用这些隐含特征进行模式分类;  还是以前面的三层自编码网络:    抽象一下如下:    其中学习到的...
  • 多自动编码器文本分类模型设计,苏峰,王旭,在文本挖掘研究中,通常采用向量空间模型。然而,向量空间模型带来的高维稀疏矩阵运算是影响文本分类准确率的重要因素之一。近年��
  • 本文主要讲了编码器分类及工作原理,下面一起来学习一下
  • Pytorch实现自编码器

    千次阅读 2020-02-26 09:08:22
    什么是编码器 有一中数据压缩的、降维的意思 举个例子来说明,同一张图片,高清的和标清的我们都能识别出图片中的内容(这里就考虑识别这一个需求,其他需求暂不考虑),这是因为即使是标清的图片,也保留了进行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 173,336
精华内容 69,334
关键字:

自编码器分类