使用Python和Keras进行主成分分析、神经网络构建图像重建的自动编码器

如今,几乎我们使用的每个应用程序中都有大量数据- 听音乐, 浏览朋友的图像,或者 观看新的预告片 

由Kaizong Ye,Coin Ge撰写

对于单个用户来说这不是问题。但是,想象一下同时处理成千上万的请求(如果不是上百万)具有大数据的请求。必须以某种方式减少这些数据流,以便我们能够物理上将其提供给用户-这就是数据压缩的开始

压缩技术很多,它们的用法和兼容性也各不相同。

压缩有两种主要类型:

  • 无损:即使我们不太“精打细算”,数据完整性和准确性也是首选
  • 有损:数据完整性和准确性并不像我们提供服务的速度那么重要-想象一下实时视频传输,其中“实时”传输比拥有高质量视频更为重要

×


通过物体外部测量的数据,经数字处理获得三维物体的形状信息的技术。图像重建技术开始是在放射医疗设备中应用,显示人体各部分的图像,即计算机断层摄影技术,简称CT技术,后逐渐在许多领域获得应用。主要有投影重建、明暗恢复形状、立体视觉重建和激光测距重建。
    1.1投影重建
    利用X射线、超声波透过被遮挡物体(如人体内脏、地下矿体)的透视投影图,计算恢复物体的断层图。利用断层图或直接从物体的二维透视投影图重建物体的形状。这种重建技术是通过某种射线的照射,射线在穿过组织时吸收不同,引起在成像面上投射强度的不同,反演求得组织内部分布的图像。X光CT技术就是应用了这种重建,为医学诊断提供了手段。投影重建还用于地矿探测,在探测井中,用超声波源发射超声,用相关的仪器接收不同地层和矿体反射的超声。按照超声波在媒质的透射率和反射规律,用有关技术得到的透射投影图进行分析计算,即可恢复重建埋在地下的矿体形状。
    1.2明暗恢复形状
    单张照片不含图像中的深度信息,利用物体表面对光照的反射模型可以对图像灰度数据进行分析计算恢复物体的形状。
    物体的成像是由于光源的分布、物体表面的形状、反射特性,以及观察者(照相机、摄像机)相对于物体的几何位置等因素确定。用计算机图形学方法可以生成不同观察角度时的图像。在计算机辅助设计中得到应用,可以演示设计物体从不同角度观察的外形,如房屋建筑、机械零件、服装造型等。反过来的处理,则可以通过图像中各个像素明暗程度,并且根据经验假设光源的分布,物体表面的反射性质以及摄像时几何位置,计算物体的三维形状。这种重建方法计算复杂,计算量也相当大,目前主要用于遥感图像中的地形重建中。
    1.3立体视觉重建
    用两个照相机(或摄像机)在左右两边对同一景物摄下两幅照片(或摄像图像),利用双目成像的立体视觉模型恢复物体的形状,提取物体的三维信息,也称三维图像重建。这种方法是对人类视觉的模仿。先从两幅图像提取出物体的边沿线条、角点等特征。物体的同一边沿和角点由于立体视差在两幅图中的位置略有不同,经匹配处理找出两幅图中的对应线和对应点,经几何坐标换算得到物体的形状。主要应用于工业自动化和机器人领域,也用于地图测绘。
    1.4激光测距重建
    应用扫描激光对物体测距,获得物体的三维数据,经过坐标换算,恢复物体的三维形状数据。激光测距的特点是准确。一种方法是固定激光源,让物体转动,并作升降,就可以录取物体在各个剖面的三维数据,重建物体在各个方向上的图像。另一种方法是激光源在一个锥形区域进行前视扫描.获得前方物体的三维数据。这种方法在行走机器人中得到应用,可以发现前方障碍,计算出障碍的区域,绕道行走。图像重建在通信领域也得到重要的应用,例如,利用图像重建技术获得非常直观的无线电场强的三维空间分布图像;通过极高压缩比的人脸图像传输用图像重建技术可在接收端恢复原始人脸图像。

    例如,使用Autoencoders,我们可以分解此图像并将其表示为下面的32矢量代码。使用它,我们可以重建图像。

    当然,这是有损压缩的一个示例,因为我们已经丢失了很多信息。

    不过,我们可以使用完全相同的技术,通过为表示分配更多的空间来更精确地做到这一点:


    课程

    R语言数据分析挖掘必知必会

    从数据获取和清理开始,有目的的进行探索性分析与可视化。让数据从生涩的资料,摇身成为有温度的故事。

    立即参加

    Keras是一个Python框架,可简化神经网络的构建。 

    首先,让我们使用pip安装Keras:

    $ pip install keras
    

    预处理数据

    同样,我们将使用LFW数据集。像往常一样,对于此类项目,我们将对数据进行预处理 。

    为此,我们将首先定义几个路径 :

     ATTRS_NAME = "lfw_attributes.txt"
     
     IMAGES_NAME = "lfw-deepfunneled.tgz"
     
     RAW_IMAGES_NAME = "lfw.tgz"

    然后,我们将使用两个函数-一个将原始矩阵转换为图像并将颜色系统更改为RGB:

    def decode_image_from_raw_bytes(raw_bytes):
        img = cv2.imdecode(np.asarray(bytearray(raw_bytes), dtype=np.uint8), 1)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        return img

    另一个是实际加载数据集并使其适应我们的需求:

    实施

     

    我们的数据X以3D矩阵的形式存在于矩阵中,这是RGB图像的默认表示形式。通过提供三个矩阵-红色,绿色和蓝色,这三个矩阵的组合产生了图像颜色。

    这些图像的每个像素将具有较大的值,范围从0到255。通常,在机器学习中,我们倾向于使值较小,并以0为中心,因为这有助于我们的模型更快地训练并获得更好的结果,因此让我们对图像进行归一化:

    X = X.astype('float32') / 255.0 - 0.5
    

    现在,如果我们测试X数组的最小值和最大值,它将是-.5.5,您可以验证:

    print(X.max(), X.min())
    
    0.5 -0.5
    

    为了能够看到图像,让我们创建一个show_image函数。0.5由于像素值不能为负,它将添加到图像中:

     

    现在,让我们快速浏览一下我们的数据:

    show_image(X[6])
    
    面对

     现在让我们将数据分为训练和测试集:

     

    sklearn train_test_split()函数能够通过给它测试比率来分割数据,其余的当然是训练量。的random_state,你会看到很多机器学习,用来产生相同的结果,不管你有多少次运行代码。

    现在该模型了:

      

    此函数将image_shape(图像尺寸)和code_size(输出表示的大小)作为参数。 

    从逻辑上讲,该值越小code_size,图像将压缩得越多,但是保存的功能就越少,并且所复制的图像与原始图像的差异会更大。

    由于网络体系结构不接受3D矩阵,因此该Flatten层的工作是将(32,32,3)矩阵展平为一维数组(3072)。

    现在,将它们连接在一起并开始我们的模型:

     之后,我们通过Model使用inpreconstruction参数创建一个链接它们,并使用adamax优化器和mse损失函数对其进行编译。

    在这里编译模型意味着定义其目标以及达到目标的方式。在我们的上下文中,目标是最小化,mse并通过使用优化程序来达到此目的-从本质上讲,这是一种经过调整的算法,可以找到全局最小值。

     结果:

    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    input_6 (InputLayer)         (None, 32, 32, 3)         0
    _________________________________________________________________
    sequential_3 (Sequential)    (None, 32)                98336
    _________________________________________________________________
    sequential_4 (Sequential)    (None, 32, 32, 3)         101376
    =================================================================
    Total params: 199,712
    Trainable params: 199,712
    Non-trainable params: 0
    _________________________________________________________________

    在这里我们可以看到输入是32,32,3。 

    隐藏层是32  ,您看到的解码器输出是(32,32,3)

     模型:

    
    
    
    
    

    在本例中,我们将比较构造的图像和原始图像,因此xy都等于X_train。理想情况下,输入等于输出。

    epochs变量定义多少次,我们要训练数据通过模型过去了,validation_data是我们用来评估训练后的模型验证组:

    Train on 11828 samples, validate on 1315 samples
    Epoch 1/20
    11828/11828 [==============================] - 3s 272us/step - loss: 0.0128 - val_loss: 0.0087
    Epoch 2/20
    11828/11828 [==============================] - 3s 227us/step - loss: 0.0078 - val_loss: 0.0071
    .
    .
    .
    Epoch 20/20
    11828/11828 [==============================] - 3s 237us/step - loss: 0.0067 - val_loss: 0.0066

    我们可以将 损失可视化,以获得 概述。

    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.title('model loss')
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.legend(['train', 'test'], loc='upper left')
    plt.show()
    损失/时代

    我们可以看到,在第三个时期之后,损失没有明显的进展。 

    这也可能导致模型过度拟合,从而使其在训练和测试数据集之外的新数据上的表现不佳。

    现在,最令人期待的部分-让我们可视化结果:

    def visualize(img,encoder,decoder):
    ”“绘制原始,编码和解码的图像”“”
         #img [None]的形状为(1、32、32、3),与模型输入相同
        code = encoder.predict(img[None])[0]
        reco = decoder.predict(code[None])[0]
     
        plt.subplot(1,3,1)
        plt.title("Original")
        show_image(img)
     
        plt.subplot(1,3,2)
        plt.title("Code")
        plt.imshow(code.reshape([code.shape[-1]//2,-1]))
     
        plt.subplot(1,3,3)
        plt.title("Reconstructed")
        show_image(reco)
        plt.show()
     
    for i in range(5):
        img = X_test[i]
        visualize(img,encoder,decoder)
    pca编码器结果
    pca编码器结果2
    pca编码器结果3
    pca编码器结果4
    pca编码器结果5

     现在,让我们增加code_size1000

    pca 1000结果
    pca 1000结果
    pca 1000结果
    pca 1000结果
    pca 1000结果

    我们刚刚做的就是主成分分析(PCA),这是一种降维技术。我们可以通过生成较小的新功能来使用它来减小功能集的大小,但是仍然可以捕获重要信息。

    主成分分析是 一种非常流行的用法。

    图像去噪

     另一种流行用法是去噪。让我们在图片中添加一些随机噪声:

    def apply_gaussian_noise(X, sigma=0.1):
        noise = np.random.normal(loc=0.0, scale=sigma, size=X.shape)
        return X + noise

    在这里,我们从标准正态分布中添加了一些随机噪声,其大小为sigma,默认为0.1

    作为参考,这是具有不同sigma值的噪声的样子:

    plt.subplot(1,4,1)
    show_image(X_train[0])
    plt.subplot(1,4,2)
    show_image(apply_gaussian_noise(X_train[:1],sigma=0.01)[0])
    plt.subplot(1,4,3)
    show_image(apply_gaussian_noise(X_train[:1],sigma=0.1)[0])
    plt.subplot(1,4,4)
    show_image(apply_gaussian_noise(X_train[:1],sigma=0.5)[0])
    噪声

    正如我们所看到的,几乎看不到图像的sigma增加0.5。我们将尝试从σ为的嘈杂图像中再生原始图像0.1

    我们将为此生成的模型与之前的模型相同,尽管我们将进行不同的训练。这次,我们将使用原始和相应的噪点图像对其进行训练:

    
    
    
    
    

    现在让我们看一下模型结果:

    
    
    
    
    
    去噪
    去噪

     

    结论

     主成分分析,这是一种降维技术,图像去噪等。


    可下载资源

    关于作者

    Kaizong Ye拓端研究室(TRL)的研究员。在此对他对本文所作的贡献表示诚挚感谢,他在上海财经大学完成了统计学专业的硕士学位,专注人工智能领域。擅长Python.Matlab仿真、视觉处理、神经网络、数据分析。

    本文借鉴了作者最近为《R语言数据分析挖掘必知必会 》课堂做的准备。

    ​非常感谢您阅读本文,如需帮助请联系我们!

     
    QQ在线咨询
    售前咨询热线
    15121130882
    售后咨询热线
    0571-63341498

    关注有关新文章的微信公众号


    永远不要错过任何见解。当新文章发表时,我们会通过微信公众号向您推送。

    技术干货

    最新洞察

    This will close in 0 seconds