精华内容
下载资源
问答
  • 文章目录1 根轨迹法基础知识什么是根轨迹根轨迹有什么用什么是根轨迹法2 根轨迹图幅值和幅角条件手绘根轨迹经验和特性3 用MATLAB绘制根轨迹画一个简单的根轨迹指定K的取值范围绘制根轨迹绘制极网格根轨迹法的...

    1 根轨迹法基础知识

    什么是根轨迹

    随着开环增益K的改变,闭环极点也将发生改变,从而在平面上产生一系列的点,这些点的轨迹,就叫做根轨迹。

    根轨迹有什么用

    闭环系统瞬态响应的基本特性和闭环极点位置密切相关。

    在设计中,常常利用增益调整,将闭环极点移动到需要的位置上。

    什么是根轨迹法

    根轨迹法是一种图解法,由W.R.伊凡斯(Evans)提出,图像反应了特征方程的根和系统中某一个参数数值关系的方法。通常这个参数取开环增益,并命令这个参数在0到无穷大之间进行变化。

    2 根轨迹图

    幅值和幅角条件

    在这里插入图片描述

    构造系统的闭环传递函数,得到闭环系统的特征方程(即分母为0),然后分解成幅度值和幅度角两个方程。

    {KG(s)H(s)}=±180(2k+1)\{KG(s) H(s)\}=\pm 180^{\circ}(2 k+1)

    KG(s)H(s)=1|\mathrm{KG}(\mathrm{s}) \mathrm{H}(\mathrm{s})|=1

    满足这两个方程的s值,就是特征方程的根,就是闭环极点。

    只满足幅角条件的点构成的图形就是根轨迹(同时满足满足幅值条件就变成了特定的点)。

    手绘根轨迹图

    根轨迹的几个性质:

    1. K=0对应的特征方程根,就是根轨迹的起点。
    2. 根轨迹的数量,就是特征方程的阶数,也就是s的最高次数。

    具体步骤

    1. 确定实轴上的根轨迹。(尝试把试验点放在实轴上)
    2. 确定根轨迹的渐近线。(尝试将s设定为无穷大)
    3. 确定分离点。分离点就是s平面上特征方程有重根的点,随着K的增大,根轨迹点将脱离实轴,向复平面运动。
    4. 确定根轨迹和虚轴的交点。(利用劳斯稳定判据)

    如果极点是一对共轭复数根,则需要确定出射角和汇合点,出射角决定了根轨迹是向实轴运动,还是向复平面运动。

    经验和特性

    1. 根轨迹分支起始于开环极点,终止于开环零点,分支数等于特征方程根的数目。
    2. 根轨迹在s平面中,上下对称,对称轴为实轴。
    3. 在根轨迹图上任取一点,可以求出K值。K值是s点到各极点距离乘积,与s到各零点距离的乘积的比值。
    4. 如果开环极点数目,比有限开环零点数目多3个或以上,必定存在一个K,当增益超过K时,根轨迹进入右半平面。

    3 用MATLAB绘制根轨迹

    基本命令是rlocus

    rlocus(num,den)
    rlocus(A,B,C,D)
    

    使用符号画图可以先把计算结果保存起来,然后使用plot

    r = rlocus(num, den)
    plot(r, 'o')
    plot(r, 'x')
    

    设定绘图区域和长宽比

    v = [-6 6 -6 6];
    axis(v);
    axis('square')
    

    画一个简单的根轨迹图

    a = [1 1 0];
    b = [1 4 16];
    c = conv(a,b);
    den = c;
    num = [1 3];
    rlocus(num,den)
    v = [-6 6 -6 6];	# 确定可视区间
    axis(v);
    axis('square');		# 拉伸成正方形
    grid;				# 画出网格
    

    在这里插入图片描述

    指定K的取值范围绘制根轨迹

    num = [1];
    den = [1 1.1 10.3 5 0];
    K1 = 0 : 0.2 : 20;			
    K2 = 20 : 0.1 : 30;
    K3 = 30: 5 : 1000;
    K = [K1 K2 K3]					# 对不同的区间,取不同的密度
    r = rlocus(num, den, K);
    plot(r, 'o')
    

    在这里插入图片描述

    绘制极网格

    sgrid命令可以把定常阻尼比和定常自然频率圆覆盖到根轨迹图上。

    num = [1];
    den = [1 4 5 0];
    K = 0:0.01:1000;
    r = rlocus(num,den,K);
    plot(r,'-');
    v = [-3 1 -2 2];
    axis(v);
    axis('square');
    sgrid([0.5,0.707],[0.5,1,2]);		# 分别是射线和半圆
    

    在这里插入图片描述

    根轨迹法的分析

    条件稳定系统

    什么是条件稳定系统?

    如果系统仅在有限的K值范围内是稳定的,称为条件稳定系统。

    如何消除条件稳定性?

    增加适当的校正网络,可以消除条件稳定性。例如增加一个零点,可以根轨迹向左边弯曲(因为根轨迹最终需要结束于0点)。

    非最小相位系统

    什么是最小相位系统?

    如果系统的极点和零点都在左半平面,则称为最小相位系统。

    如果至少有一个极点或者零点在s右半平面,就是非最小相位系统。

    求任意根轨迹点上的增益K值

    [K,r] = rlocfind(num,den)
    
    展开全文
  • 如果这时发出一条绘图命令(plt.plot(randn(50).cumsum(),'k--')),matplotlib就会在最后一个用过的subplot(如果没有则创建一个)上进行绘制 from numpy.random import randn plt.plot(randn(50).cumsum...

    matplotlib AIP入门

    1.Figure和Subplot

    matplotlib的图像都位于Figure对象中。你可以用plt.figure创建一个新的Figure:

    fig=plt.figure()

    这时会弹出一个空窗口。plt.figure有一些选项,特别是figsize,它用于确保图片保存到磁盘时具有一定大小和纵横比。matplotlib中的Figure还支持一种MATLAB式的编号架构(例如plt.figure(2))。通过plt.gcf()即可得到当前Figure的引用。

    不能通过空Figure绘图。必须用add_subplot创建一个或多个subplot才行

    ax1=fig.add_subplot(2,2,1)

    这段代码的意思是:图像应该是2*2的,且当前选中的是4个subplot中的第一个(编号从1开始)。如果再把后面两个subplot也创建出来,最终得到的图像如图所示

    ax2=fig.add_subplot(2,2,2)
    ax3=fig.add_subplot(2,2,3)

    如果这时发出一条绘图命令(plt.plot(randn(50).cumsum(),'k--')),matplotlib就会在最后一个用过的subplot(如果没有则创建一个)上进行绘制

    from numpy.random import randn

    plt.plot(randn(50).cumsum(),'k--')

    结果为:

    ‘k--’是一个线型选项,用于告诉matplotlib绘制黑色虚线图。上面那些由fig.add_subplot所返回的对象是AxesSubplot对象,直接调用它们的实例方法就可以在其它空着的格子里画图了

    _=ax1.hist(randn(100),bins=20,color='k',alpha=0.3)
    ax2.scatter(np.arange(30),np.arange(30)+3*randn(30))

    结果为:

    由于根据特定布局创建Figure和subplot是一件非常常见的任务,于是便出现了一个更为方便的方法(plt.subplots),它可以创建一个新的Figure,并返回一个含有已创建的subplot对象的NumPy数组

    fig,axes=plt.subplots(2,3)
    print axes

    结果为:

    [[<matplotlib.axes._subplots.AxesSubplot object at 0x0000000009062BA8>
      <matplotlib.axes._subplots.AxesSubplot object at 0x0000000009291080>
      <matplotlib.axes._subplots.AxesSubplot object at 0x00000000099A0F98>]
     [<matplotlib.axes._subplots.AxesSubplot object at 0x000000000A68FD30>
      <matplotlib.axes._subplots.AxesSubplot object at 0x0000000009A406A0>
      <matplotlib.axes._subplots.AxesSubplot object at 0x000000000928FCC0>]]

    你可以轻松地对axes数组进行索引,就好像一个二维数组一样,例如,axes[0,1]。你还可以通过sharex和sharey指定subplot应该具有相同的X轴或Y轴。

    2.调整subplot周围的间距

    利用Figure的subplots_adjust方法可以轻而易举地修改间距,它是个顶级函数

    subplots_adjust(left=None,bottom=None,right=None,top=None,wspace=None,hspace=None)

    wspace和hspace用于控制宽度和高度的百分比,可以用作subplot之间的间距

    fig,axes=plt.subplots(2,2,sharex=True,sharey=True)
    for i in range(2):
        for j in range(2):
            axes[i,j].hist(randn(500),bins=50,color='k',alpha=0.5)
    plt.subplots_adjust(wspace=0,hspace=0)

    结果为:

    3.颜色、标记和线型

    例如,要根据x和y绘制绿色虚线,可以执行如下代码

    ax.plot(x,y,'g--')

    通过下面这种更为明确的方式也能得到同样的效果

    ax.plot(x,y,linesytle='--',clolor='g')

    使用颜色也可以指定其RGB值的形式使用,如#CECECE

    线形图还可以加上一些标记,以强调实际的数据点。标记也可以放到格式化字符串中,但标记类型和线型必须放在颜色后面

    plt.plot(randn(30).cumsum(),'ko--')

    结果为:

    还可以将其写成更为明确的形式

    plt.plot(randn(30).cumsum(),color='k',linestyle='dashed',marker='o')

    在线型图中,非实际数据点默认按线性方式插值的。可以通过drawstyle选项修改

    plt.plot(data,'k--',label='Default')

    结果为:

    plt.plot(data,'k-',drawstyle='steps-post',label='steps-post')

    结果为:

    plt.legend(loc='best')

    结果为:


    4.刻度、标签和图例

    对于大多数图表装饰项,其主要实现方式有二:使用过程型的pyplot接口(MATLAB用户非常熟悉)以及面向对象的原生matplotlib API

    pyplot接口其主要使用方式有以下两种:

    a.调用时不带参数,则返回当前的参数值。例如,plt.xlim()返回当前的X轴绘图范围。

    b.调用时带参数,则设置参数值。因此,plt.xlim([0,10])会将X轴的范围设置为0到10

    所有这些方法都是对当前或最近创建的AxesSubplot起作用的。它们各自对应subplot对象上的两个方法,以xlim为例,就是ax.get_xlim和ax.set_xlim。

    设置标题、轴标签、刻度以及刻度标签

    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)
    ax.plot(randn(1000).cumsum())
    ticks=ax.set_xticks([0,250,500,750,1000])
    labels=ax.set_xticklabels(['one','two','three','four','five'],
                              rotation=30,fontsize='small')
    ax.set_title('My first matplotlib plot')
    ax.set_xlabel('Stages')

    结果为:

    添加图例

    添加图例的方式有两种。最简单的是在添加subplot的时候传入label参数

    fig1=plt.figure()
    ax1=fig1.add_subplot(1,1,1)
    ax1.plot(randn(1000).cumsum(),'k',label='one')
    ax1.plot(randn(1000).cumsum(),'k--',label='two')
    ax1.plot(randn(1000).cumsum(),'k.',label='three')
    ax1.legend(loc='best')

    结果为:

    loc告诉matplotlib要将图例放在哪。要从图例中去除一个或多个元素,不传入label或label='_nolegned_'即可


    4.注解以及在Subplot上绘图

    注解可以通过text、arrow和annotate等函数进行添加

    ax.text(x,y,'Hello world!',family='monospace',fontsize=10)

    实际案例

    import matplotlib.pyplot as plt
    from numpy.random import randn
    import numpy as np
    from datetime import datetime
    import pandas as pd

    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)
    data=pd.read_csv('data/spx.csv',index_col=0,parse_dates=True)
    spx=data['SPX']
    spx.plot(ax=ax,style='k-')

    crisis_data=[
        (datetime(2007,10,11),'Peak of bull market'),
        (datetime(2008,3,12),'Bear Stearns Fails'),
        (datetime(2008,9,15),'Lehman Bankruptcy')
    ]

    for date,label in crisis_data:
        ax.annotate(label,xy=(date,spx.asof(date)+50),
                    xytext=(date,spx.asof(date)+200),
                    arrowprops=dict(facecolor='black'),
                    horizontalalignment='left',verticalalignment='top')
                    
    ax.set_xlim(['1/1/2007','1/1/2011'])
    ax.set_ylim([600,1800])
    ax.set_title('Import dates in 2008-2009 financial crisis')

    结果为:

    要在图表中添加一个图形,你需要创建一个块对象shp,然后通过ax.add_patch(shp)将其添加到subplot中

    fig1=plt.figure()
    ax1=fig1.add_subplot(1,1,1)
    rect=plt.Rectangle((0.2,0.75),0.4,0.15,color='k',alpha=0.3)
    circ=plt.Circle((0.7,0.2),0.15,color='b',alpha=0.3)
    pgon=plt.Polygon([[0.15,0.15],[0.35,0.4],[0.2,0.6]],color='g',alpha=0.5)
    ax1.add_patch(rect)
    ax1.add_patch(circ)
    ax1.add_patch(pgon)

    结果为:


    5.将图表保存到文件

    利用plt.savefig可以将当前图表保存到文件。该方法相当于Figure对象的实例方法savefig。

    在发布图片时最常用到两个最重要的选项是dpi(控制“每英寸点数”分辨率)和bbox_inches(可以剪除当前表周围的空白部分)

    plt.savefig('figpath.png',dpi=400,bbox_inches='tight')

    savefig并非一定要写入磁盘,也可以写入任何文件型对象,比如StirngIO

    from io import StringIO

    buffer=StringIO()

    plt.savefig(buffer)

    plot_data=buffer.getvalue()


    6.matplotlib配置

    操作matplotlib配置系统的方式主要有两种。第一种是Python编程方式,即利用rc方法。如:plt.rc('figure',figsize=(10,10))

    rc的第一个参数是希望自定义的对象

    font_options={'family':'monospace',

                           'weight':'bold',

                           'size':'small'}

    plt.rc('font',**font_options)

    展开全文
  • 利用深度学习进行医疗图像分析【全】

    万次阅读 多人点赞 2018-08-09 12:20:00
    凭借深度学习,我们开始对图像和视频进行分析,并将其应用于各种各样的设备,比如自动驾驶汽车、无人驾驶飞机,等等。 A Neural Algorithm of Artistic Style 是一篇最新发表的研究性论文,论文向我们介绍了如何...

    https://www.leiphone.com/news/201706/xwSoWmhNgkn34iGS.html

    https://www.leiphone.com/news/201706/UvZxrlbedfT7Meid.html

    https://www.leiphone.com/news/201707/Sm39kRgkg28iwv9s.html

     

     

    近年来,深度学习技术一直都处于科研界的前沿。凭借深度学习,我们开始对图像和视频进行分析,并将其应用于各种各样的设备,比如自动驾驶汽车、无人驾驶飞机,等等。

    A Neural Algorithm of  Artistic  Style是一篇最新发表的研究性论文,论文向我们介绍了如何将一种风格和气质从艺术家身上转移至一张图像,并由此创建出另一张新图像。其他的一些论文,比如Generative Adversarial  Networks和Wasserstein GAN,也已经为开发模型铺平了道路,这个模型能够创建出与输入数据相似的新数据。由此,“半监督学习”世界的大门被打开了,未来“无监督学习”的发展也将更加顺利。

    尽管这些调查研究的对象现在仅限于一般的图像,但我们的目标是将这些研究运用到医学图像中,帮助医疗保健的发展。在本文中,我将从图像处理和医学图像格式数据入手,并对一些医学数据进行可视化处理。在下一篇文章中,我将进深入剖析一些卷积神经网络,并将其与Keras联合,预测肺癌。

    使用Python进行基本的图像处理

    OpenCV(开源计算机视觉库)凭借其大量社区支持,以及对C++,Java和Python的可兼容性,在琳琅满目的图像处理库中脱颖而出,成为了图像处理库的主流。深度学习下的医学图像分析(一)

    现在,打开你的Jupyter笔记本,并且确定cv2是能够导入至笔记本的。你还需要numpy和matplotlib来查看笔记本内的细节内容。

    深度学习下的医学图像分析(一)

    现在,我们来看一下你能不能打开图片,能不能用下面的代码在你的笔记本上查看图片。

    深度学习下的医学图像分析(一)

    基本的人脸检测

    接下来,我们要玩些有趣的——检测人脸。我们将使用一个开源的正脸检测器来进行人脸检测,这个检测器最初是由Rainer Lienhart创建的。下图这个帖子详细地介绍了级联检测的细节:

    深度学习下的医学图像分析(一)

    在下面的文档中还有很多使用OpenCV进行图像处理的例子(点击链接查看文档http://docs.opencv.org/trunk/d6/d00/tutorial_py_root.html),读者们可以任意查看。了解了基本的图像处理以后,接下来我们将开始了解“医学图像格式”。

    医学图像数据格式

    医学图像与“数字影像和通讯”(DICOM)一样,是一个储存和交换医学图像数据的标准解决方案。该标准自1985年第一版发布以来,已经被修改了好几次。该标准使用的是一个文件格式和一个通讯协议。

    • 文件格式——所有病人的医学图像都被保存在DICOM文件格式里。这个格式中保存着病人的受保护健康信息,比如:病人姓名、性别、年龄,还有一些医疗图像的数据。“医学成像设备”创建了DICOM文件。医生们使用DICOM阅读器和能够显示DICOM图像的电脑软件应用程序来查看医学图像,并且根据图像的信息作出诊断。

    • 通讯协议——DICOM通讯协议是用来在档案中搜索影像研究,并将影像研究还原显示的。所有连接了医院网络的医学成像应用程序都会使用DICOM协议交换信息,这些信息中的大部分是DICOM图像,不过还包括了一些患者信息和治疗方案。还有一些网络要求是用于控制和跟踪手术、安排手术日程、报告状态,以及分担医生和成像设备之间的工作量的。

    下面的博客详细地介绍了DICOM标准:

    分析DICOM图像

    Pydicom是一个相当不错的、用于分析DICOM图像的Python工具包。在这个部分,我们将会看到DICOM图像是如何在Jupyter笔记本上呈现的。

    使用pip安装pydicom下载安装OpenCV

    Pydicom工具包安装完毕以后,回到Jupyter笔记本。将dicom工具包和下图中的其他工具包导入笔记本中。

    深度学习下的医学图像分析(一)

    在处理和分析数据时,我们还会用到其他的工具包,比如pandas,scipy,skimage和mpl_toolkit,等等。

    深度学习下的医学图像分析(一)

    网上有很多免费的DICOM数据库,下面的这些数据库可能对你有所帮助:

    • Kaggle竞赛和数据库:这是我个人最喜欢的数据库。这里面有关于肺癌和糖尿病视网膜病变的数据。

    • Dicom数据库:DICOM数据库是一个免费的线上医学DICOM图像或视频分享的服务器,它主要是以教学和科研为目的的。

    • Osirix数据库:这个数据库向我们提供了大量通过各种成像方式获得的人类数据。

    • 可视化人体数据集:“可视人计划”的某些部分是分布于这个数据集的,但是这个数据集中的数据是需要收费的。

    • Zubal幻影:这个网站提供了关于两名男性CT和MRI图像的多个数据库。

    下载dicom文件,并将其上传至你的jupyter笔记本。

    深度学习下的医学图像分析(一)

    现在,将DICOM图像加载到一个列表中。

    深度学习下的医学图像分析(一)

    第一步:在Jupyter笔记本上查看DICOM图像

    深度学习下的医学图像分析(一)

    在第一行,我们加载第一个DICOM文件,然后提取文件名在列表中排第一的元数据。深度学习下的医学图像分析(一)

    接下来,我们要计算3DNumpy数组的总维数,它等于片中像素的行数x、片中像素的列数x,还有x,y,z轴。最后,我们要用“像素空间”和“SliceThickness”来计算三个轴上像素间的空间距离。我们需要将数组维度保存在ConstPixelDims中,并将空间保存在ConstPixelSpacing中。深度学习下的医学图像分析(一)

    深度学习下的医学图像分析(一)深度学习下的医学图像分析(一)

    第二步:进一步研究DICOM格式的细节

    CT扫描测量的单元是“胡斯菲尔德单元”(HU),这个单元测量的是放射性密度。为了得到精确的测量结果,CT扫描仪经过了严格的校准。下面是关于CT扫描测量的细节内容:

    每个像素都会被分配一个数值(CT数),这个数值是相应的voxel内所有衰减值的平均值。这个数字是与水的衰减值相比较得出的,而且是以任意单元的规模显示的,这个任意单元叫做“胡斯菲尔德单元”(HU),是以Godfrey Hounsfield先生的名字命名的。

    这个任意单元的规模将水的衰减值定为零。CT数字的范围是2000HU,尽管有一些现代扫描仪的HU范围达到了4000。每个数值都代表了一种灰色阴影,在光谱两端有+1000白色和-1000黑色。

    深度学习下的医学图像分析(一)

    胡斯菲尔德规模(图片来自《CT的介绍》)

    有些扫描仪是有柱状扫描边界的,但是其输出的图像确实方形的。在扫描边界之外的像素将被赋予-2000的定值。

    深度学习下的医学图像分析(一)

    CT扫描仪图像(图片来自《CT的介绍》)

    第一步通常是将这些值设置为零。接着,我们把得到的数值与重新调节的斜率相乘,再加上截距(通常是记录在扫描的元数据中的),然后回到HU单元。

    在接下来的部分,我们将会使用Kaggle的肺癌数据库和Keras的卷积神经网络。我们将根据本文提供的信息,构建下一部分的内容。


     

     在《深度学习下的医学图像分析》系列的第一篇文章中,我们介绍了一些使用OpenCV和DICOM图像基础知识进行图像处理的过程。本文,我们将从“卷积神经网络”的角度讨论深度学习。在系列的第三部分,我们将利用Kaggle的肺癌数据库,重新查看肺癌DICOM图像中的关键内容和信息,并且利用Kera开发一个肺癌预测模型。

    • “卷积神经网络”(CNN)

    在了解“卷积神经网络”之前,我们要先知道什么是“卷积”。

    何为“卷积”?

    维基百科对“卷积”的定义是:一个关于两个函数的数学运算。这个数学运算将会产生两个原始函数之外的第三个函数,这个函数通常被看作是两个原始函数之一的修正版,实际上是这两个原始函数的点乘式相乘的积分。我们可以简单地将第三个函数理解为“一个矩阵上的滑动窗口函数”。深度学习下的医学图像分析(二)

    图片来源:deeplearning.stanford.edu/wiki/index.php/Feature_extraction_using_convolution

    如上图所示,绿色表示的是滑动窗口,红色的是滑动窗口矩阵,输出的结果是带有卷积特性的矩阵。下图是两个方形脉冲的卷积及其输出结果。

    深度学习下的医学图像分析(二)

    图片来源:维基百科

    Jeremy Howard在他的MOOC课程里,利用一个Excel表格很好地解释了“卷积”。f和g两个矩阵的卷积输出是第三个矩阵卷积的第一层,也是这两个矩阵的点乘结果。这两个矩阵的点乘结果是下图所示的“标量矩阵”,也是一个数学函数的来源

    深度学习下的医学图像分析(二)

    两个矩阵的点乘结果

    像Jeremy一样,我们也来利用Excel表格。我们输入的矩阵是函数f(),滑动窗口矩阵是函数g()。两个函数的点乘结果是表格中的两个矩阵的和积,如下图所示:深度学习下的医学图像分析(二)

    两个矩阵的卷积

    接下来,我们把这个规律用到大写字母A的一张图像。大家都知道,所有图像都是由像素构成的。因此,我们输入的矩阵f是“A”,把滑动窗口函数定为任意的矩阵g。然后,我们就得到了两个函数的点乘结果,如下图:深度学习下的医学图像分析(二)

    何为“卷积神经网络”?

    深度学习下的医学图像分析(二)

    图片来源: cs231n.github.io/convolutional-networks/

    在我看来,一个简单的卷积神经网络CNN是所有层的一个序列。每一层都有一些特定的函数。每个卷积层都是三维的,所以我们用体积来作为度量标准。再进一步,卷积神经网络的每一层都会通过一个可微函数来将激活量转化为另一个,这个函数叫做“激活”或者“转化函数”。

    “卷积神经网络”包含的不同实体分别是:输入层、过滤器(或内核)、卷积层、激活层、聚积层、批处理层。虽然这些层的组合排列各异,但是在不同的排列中还是存在一些规律的,给我们提供了不同的深度学习架构。
    输入层:一般情况下,我们输入至“卷积神经网络”的通常是一个n维数组。如果是一张图像,我们有彩色通道的三维输入——长、宽、高。

    深度学习下的医学图像分析(二)

    图片来源: http://xrds.acm.org/blog/2016/06/convolutional-neural-networks-cnns-illustrated-explanation/

    过滤器(或内核):如下图所示,一个过滤器或内核会滑动到图像的所有位置,将一个新像素作为所有像素的加权总和来进行计算。正如上面Excel表格的示例,我们的过滤器g移动到了输入的矩阵f处。

    深度学习下的医学图像分析(二)

    来源: intellabs.github.io/RiverTrail/tutorial/

    卷积层:输入矩阵的点乘结果与内核共同创造出的新矩阵就是“卷积矩阵”,也被称作“卷积层”。

    深度学习下的医学图像分析(二)

    来源: https://docs.gimp.org/en/plug-in-convmatrix.html

    下面这张非常清晰的视觉图表能够帮助你能更好地了解卷积填充和卷积转置的具体过程:

    深度学习下的医学图像分析(二)

    来源: https://github.com/vdumoulin/conv_arithmetic

    激活层:“激活函数”能分成两类——“饱和激活函数”和“非饱和激活函数”。

    深度学习下的医学图像分析(二)

    sigmoid和tanh是“饱和激活函数”,而ReLU及其变体则是“非饱和激活函数”。使用“非饱和激活函数”的优势在于两点:

    1.首先,“非饱和激活函数”能解决所谓的“梯度消失”问题。

    2.其次,它能加快收敛速度。

    Sigmoid函数需要一个实值输入压缩至[0,1]的范围

    σ(x) = 1 / (1 + exp(−x))

    tanh函数需要讲一个实值输入压缩至 [-1, 1]的范围

    tanh(x) = 2σ(2x) − 1

    ReLU

    ReLU函数代表的的是“修正线性单元”,它是带有卷积图像的输入x的最大函数(x,o)。ReLU函数将矩阵x内所有负值都设为零,其余的值不变。ReLU函数的计算是在卷积之后进行的,因此它与tanh函数和sigmoid函数一样,同属于“非线性激活函数”。这一内容是由Geoff Hinton首次提出的。

    ELUs

    ELUs是“指数线性单元”,它试图将激活函数的平均值接近零,从而加快学习的速度。同时,它还能通过正值的标识来避免梯度消失的问题。根据一些研究,ELUs分类精确度是高于ReLUs的。下面是关于ELU细节信息的详细介绍:

    深度学习下的医学图像分析(二)

    图片来源: http://image-net.org/challenges/posters/JKU_EN_RGB_Schwarz_poster.pdf

    深度学习下的医学图像分析(二)

    图片来源:维基百科

    Leaky ReLUs

    ReLU是将所有的负值都设为零,相反,Leaky ReLU是给所有负值赋予一个非零斜率。Leaky ReLU激活函数是在声学模型(2013)中首次提出的。以数学的方式我们可以表示为:

    深度学习下的医学图像分析(二)

    图片来源:《卷积网络中整流激活函数的实证评估》

    上图中的ai是(1,+∞)区间内的固定参数。

    参数化修正线性单元(PReLU)

    PReLU可以看作是Leaky ReLU的一个变体。在PReLU中,负值部分的斜率是根据数据来定的,而非预先定义的。作者称,在ImageNet分类(2015,Russakovsky等)上,PReLU是超越人类分类水平的关键所在。

    随机纠正线性单元(RReLU)

    “随机纠正线性单元”RReLU也是Leaky ReLU的一个变体。在RReLU中,负值的斜率在训练中是随机的,在之后的测试中就变成了固定的了。RReLU的亮点在于,在训练环节中,aji是从一个均匀的分布U(I,u)中随机抽取的数值。形式上来说,我们能得到以下结果:

    深度学习下的医学图像分析(二)

    下图是ReLU、Leaky ReLU、PReLU和RReLU的比较:

    深度学习下的医学图像分析(二)

    图片来源 :https://arxiv.org/pdf/1505.00853.pdf

    PReLU中的ai是根据数据变化的;Leaky ReLU中的ai是固定的;RReLU中的aji是一个在一个给定的范围内随机抽取的值,这个值在测试环节就会固定下来。

    噪声激活函数

    这些是包含了Gaussian噪声的激活函数,下图能帮助你了解“噪声”是如何与激活函数相结合的:

    深度学习下的医学图像分析(二)

    图片来源:维基百科

    聚积层

    “聚积层”的目的就是通过逐渐缩减矩阵的空间大小,减少参数和网络内计算的数量,进而控制过度拟合。“聚积层”在输入中独立运行,然后利用最大值或平均值的操作来调整输入矩阵的空间大小。“聚积层”最常见的形式就是带有应用于输入的两个样本中的2x2过滤器的“聚积层”。在这种形式中,每一次最大值操作都会取超过4个的最大数量,深度维数保持不变。更常见的“聚积层”如下图:

    深度学习下的医学图像分析(二)

    图片来源: http://cs231n.github.io/convolutional-networks/#pool

    深度学习下的医学图像分析(二)

    图片来源: https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/

    注意:这里我们把2 x 2窗口移动了两个单元格,然后取每个区域的最大值。

    批规范化层

    “批规范化”是将每个过渡层,包括激活函数,标准化的有效方法。“批规范化”操作的两个主要优点是:

    1.在一个模型中添加“批规范”能够加快训练的速度

    2.规范化操作大大降低了少数外围输入对训练的制约影响,同时减少了过度拟合的发生。

    Jeremy的网络公开课中有更多关于“批规范化”的细节。

    全连接层

    “全连接层”是一个传统的“多层感知器”,这个感知器在输出层中使用了一个“柔性最大值激活函数”。顾名思义,“全连接”意味着上一层的每一个神经元都与下一层的每个神经元相连接。一个“柔性最大值函数”是逻辑函数的泛化,该函数将一个任意实值的K维向量转化为一个实值在(0,1)范围之间的K维向量。

    深度学习下的医学图像分析(二)

    图片来源:维基百科

    “柔性最大值激活函数”一般被用于最后的全连接层,获取实值在0到1之间的概率。现在,我们对“卷积神经网络”中的不同层已经有所了解了,那么具备了这些知识,我们就能建立起肺癌检测所需的深度学习架构了。关于肺癌检测的深度学习架构,我们将在下一篇文章中讨论。

     

     在《深度学习下的医学图像分析》系列的第一篇文章中,我们介绍了一些使用OpenCV和DICOM图像基础知识进行图像处理的过程。本文,我们将从“卷积神经网络”的角度讨论深度学习。在系列的第三部分,我们将利用Kaggle的肺癌数据库,重新查看肺癌DICOM图像中的关键内容和信息,并且利用Kera开发一个肺癌预测模型。

    • “卷积神经网络”(CNN)

    在了解“卷积神经网络”之前,我们要先知道什么是“卷积”。

    何为“卷积”?

    维基百科对“卷积”的定义是:一个关于两个函数的数学运算。这个数学运算将会产生两个原始函数之外的第三个函数,这个函数通常被看作是两个原始函数之一的修正版,实际上是这两个原始函数的点乘式相乘的积分。我们可以简单地将第三个函数理解为“一个矩阵上的滑动窗口函数”。深度学习下的医学图像分析(二)

    图片来源:deeplearning.stanford.edu/wiki/index.php/Feature_extraction_using_convolution

    如上图所示,绿色表示的是滑动窗口,红色的是滑动窗口矩阵,输出的结果是带有卷积特性的矩阵。下图是两个方形脉冲的卷积及其输出结果。

    深度学习下的医学图像分析(二)

    图片来源:维基百科

    Jeremy Howard在他的MOOC课程里,利用一个Excel表格很好地解释了“卷积”。f和g两个矩阵的卷积输出是第三个矩阵卷积的第一层,也是这两个矩阵的点乘结果。这两个矩阵的点乘结果是下图所示的“标量矩阵”,也是一个数学函数的来源

    深度学习下的医学图像分析(二)

    两个矩阵的点乘结果

    像Jeremy一样,我们也来利用Excel表格。我们输入的矩阵是函数f(),滑动窗口矩阵是函数g()。两个函数的点乘结果是表格中的两个矩阵的和积,如下图所示:深度学习下的医学图像分析(二)

    两个矩阵的卷积

    接下来,我们把这个规律用到大写字母A的一张图像。大家都知道,所有图像都是由像素构成的。因此,我们输入的矩阵f是“A”,把滑动窗口函数定为任意的矩阵g。然后,我们就得到了两个函数的点乘结果,如下图:深度学习下的医学图像分析(二)

    何为“卷积神经网络”?

    深度学习下的医学图像分析(二)

    图片来源: cs231n.github.io/convolutional-networks/

    在我看来,一个简单的卷积神经网络CNN是所有层的一个序列。每一层都有一些特定的函数。每个卷积层都是三维的,所以我们用体积来作为度量标准。再进一步,卷积神经网络的每一层都会通过一个可微函数来将激活量转化为另一个,这个函数叫做“激活”或者“转化函数”。

    “卷积神经网络”包含的不同实体分别是:输入层、过滤器(或内核)、卷积层、激活层、聚积层、批处理层。虽然这些层的组合排列各异,但是在不同的排列中还是存在一些规律的,给我们提供了不同的深度学习架构。
    输入层:一般情况下,我们输入至“卷积神经网络”的通常是一个n维数组。如果是一张图像,我们有彩色通道的三维输入——长、宽、高。

    深度学习下的医学图像分析(二)

    图片来源: http://xrds.acm.org/blog/2016/06/convolutional-neural-networks-cnns-illustrated-explanation/

    过滤器(或内核):如下图所示,一个过滤器或内核会滑动到图像的所有位置,将一个新像素作为所有像素的加权总和来进行计算。正如上面Excel表格的示例,我们的过滤器g移动到了输入的矩阵f处。

    深度学习下的医学图像分析(二)

    来源: intellabs.github.io/RiverTrail/tutorial/

    卷积层:输入矩阵的点乘结果与内核共同创造出的新矩阵就是“卷积矩阵”,也被称作“卷积层”。

    深度学习下的医学图像分析(二)

    来源: https://docs.gimp.org/en/plug-in-convmatrix.html

    下面这张非常清晰的视觉图表能够帮助你能更好地了解卷积填充和卷积转置的具体过程:

    深度学习下的医学图像分析(二)

    来源: https://github.com/vdumoulin/conv_arithmetic

    激活层:“激活函数”能分成两类——“饱和激活函数”和“非饱和激活函数”。

    深度学习下的医学图像分析(二)

    sigmoid和tanh是“饱和激活函数”,而ReLU及其变体则是“非饱和激活函数”。使用“非饱和激活函数”的优势在于两点:

    1.首先,“非饱和激活函数”能解决所谓的“梯度消失”问题。

    2.其次,它能加快收敛速度。

    Sigmoid函数需要一个实值输入压缩至[0,1]的范围

    σ(x) = 1 / (1 + exp(−x))

    tanh函数需要讲一个实值输入压缩至 [-1, 1]的范围

    tanh(x) = 2σ(2x) − 1

    ReLU

    ReLU函数代表的的是“修正线性单元”,它是带有卷积图像的输入x的最大函数(x,o)。ReLU函数将矩阵x内所有负值都设为零,其余的值不变。ReLU函数的计算是在卷积之后进行的,因此它与tanh函数和sigmoid函数一样,同属于“非线性激活函数”。这一内容是由Geoff Hinton首次提出的。

    ELUs

    ELUs是“指数线性单元”,它试图将激活函数的平均值接近零,从而加快学习的速度。同时,它还能通过正值的标识来避免梯度消失的问题。根据一些研究,ELUs分类精确度是高于ReLUs的。下面是关于ELU细节信息的详细介绍:

    深度学习下的医学图像分析(二)

    图片来源: http://image-net.org/challenges/posters/JKU_EN_RGB_Schwarz_poster.pdf

    深度学习下的医学图像分析(二)

    图片来源:维基百科

    Leaky ReLUs

    ReLU是将所有的负值都设为零,相反,Leaky ReLU是给所有负值赋予一个非零斜率。Leaky ReLU激活函数是在声学模型(2013)中首次提出的。以数学的方式我们可以表示为:

    深度学习下的医学图像分析(二)

    图片来源:《卷积网络中整流激活函数的实证评估》

    上图中的ai是(1,+∞)区间内的固定参数。

    参数化修正线性单元(PReLU)

    PReLU可以看作是Leaky ReLU的一个变体。在PReLU中,负值部分的斜率是根据数据来定的,而非预先定义的。作者称,在ImageNet分类(2015,Russakovsky等)上,PReLU是超越人类分类水平的关键所在。

    随机纠正线性单元(RReLU)

    “随机纠正线性单元”RReLU也是Leaky ReLU的一个变体。在RReLU中,负值的斜率在训练中是随机的,在之后的测试中就变成了固定的了。RReLU的亮点在于,在训练环节中,aji是从一个均匀的分布U(I,u)中随机抽取的数值。形式上来说,我们能得到以下结果:

    深度学习下的医学图像分析(二)

    下图是ReLU、Leaky ReLU、PReLU和RReLU的比较:

    深度学习下的医学图像分析(二)

    图片来源 :https://arxiv.org/pdf/1505.00853.pdf

    PReLU中的ai是根据数据变化的;Leaky ReLU中的ai是固定的;RReLU中的aji是一个在一个给定的范围内随机抽取的值,这个值在测试环节就会固定下来。

    噪声激活函数

    这些是包含了Gaussian噪声的激活函数,下图能帮助你了解“噪声”是如何与激活函数相结合的:

    深度学习下的医学图像分析(二)

    图片来源:维基百科

    聚积层

    “聚积层”的目的就是通过逐渐缩减矩阵的空间大小,减少参数和网络内计算的数量,进而控制过度拟合。“聚积层”在输入中独立运行,然后利用最大值或平均值的操作来调整输入矩阵的空间大小。“聚积层”最常见的形式就是带有应用于输入的两个样本中的2x2过滤器的“聚积层”。在这种形式中,每一次最大值操作都会取超过4个的最大数量,深度维数保持不变。更常见的“聚积层”如下图:

    深度学习下的医学图像分析(二)

    图片来源: http://cs231n.github.io/convolutional-networks/#pool

    深度学习下的医学图像分析(二)

    图片来源: https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/

    注意:这里我们把2 x 2窗口移动了两个单元格,然后取每个区域的最大值。

    批规范化层

    “批规范化”是将每个过渡层,包括激活函数,标准化的有效方法。“批规范化”操作的两个主要优点是:

    1.在一个模型中添加“批规范”能够加快训练的速度

    2.规范化操作大大降低了少数外围输入对训练的制约影响,同时减少了过度拟合的发生。

    Jeremy的网络公开课中有更多关于“批规范化”的细节。

    全连接层

    “全连接层”是一个传统的“多层感知器”,这个感知器在输出层中使用了一个“柔性最大值激活函数”。顾名思义,“全连接”意味着上一层的每一个神经元都与下一层的每个神经元相连接。一个“柔性最大值函数”是逻辑函数的泛化,该函数将一个任意实值的K维向量转化为一个实值在(0,1)范围之间的K维向量。

    深度学习下的医学图像分析(二)

    图片来源:维基百科

    “柔性最大值激活函数”一般被用于最后的全连接层,获取实值在0到1之间的概率。现在,我们对“卷积神经网络”中的不同层已经有所了解了,那么具备了这些知识,我们就能建立起肺癌检测所需的深度学习架构了。关于肺癌检测的深度学习架构,我们将在下一篇文章中讨论。

     

    本文将从卷积神经网络的角度讨论深度学习。在本文中,我们将使用Keras和Theano,重点关注深度学习的基本原理。本文将展示两个例子——其中一个例子使用Keras进行基本的预测分析,另外一个使用VGG进行图像分析。

    我们谈论的话题其实是相当广泛和深入的,需要更多的文章进行探讨。在接下来的一些文章中,我们将会讨论医学影像中DICOM和NIFTI格式之间的不同,并且研究如何使用深度学习进行2D肺分割分析。除此之外,我们还将讨论在没有深度学习时,医学图像分析是如何进行的;以及我们现在如何使用深度学习进行医学图像分析。在这里,我非常欢迎和感谢我的新伙伴Flavio Trolese——4Quant的联合创始人和ETH Zurich的讲师——他将协助我整合所有讨论的内容。

    在本文中,我们将讨论Keras并且展示两个示例——其中一个使用Keras完成简单的预测性分析任务,另一个进行图像分析。

    • 何为Keras?

    根据Keras官网的介绍,Keras是Theanos和Tensor Flow的一个深度学习库。

    深度学习下的医学图像分析(三)

    运行于Theano和TensorFlow之上的Keras api

    Keras是一个高级Python神经网络API,它能够运行于TensorFlow和Theano之上。Keras的开发重点在于支持快速实验。

    • 何为Theano和Tensor Flow?

    James Bergstra教授等人在2010年的Scipy曾说,Theano是一个CPU和GPU的数学表达式编译器。换句话来说,Theano是一个能够让你高效地对数学表达式进行定义、优化和评估的Python学习库。Theano是由一些高级研究人员,如Yoshua Bengio,和“蒙特罗学习算法研究所”(MILA)共同研发的。下图是发布于2010年Scipy上的Theano教程,图中对比了Theano下的GPU和CPU与当年其他的工具。这张图片发表于原创论文——《Theano——CPU和GPU的Python数学编译器》。

    深度学习下的医学图像分析(三)

    《Theano——CPU和GPU的Python数学编译器》作者:James Bergstra, Olivier Breuleux, Frédéric Bastien, Pascal Lamblin, Razvan    Pascanu, Guillaume Desjardins,Joseph Turian, David Warde-Farley, Yoshua Bengio

    建立在Theano之上的还有一些其他的深度学习库,包括Pylearn2、GroundHog(同样是由MILA开发的)、Lasagne和Blocks and Fuel等。

    • 《使用Theano计算的透明GPU》——James Bergstra

    TensorFlow是由“谷歌机器智能研究所”组织下的“谷歌大脑”团队研发完成的。TensorFlow的开发是为了进行机器学习和深度神经网络的研究,除此之外,它还广泛适用于其他的领域。根据TensorFlow官网介绍,TensorFlow是一个使用数据流图表进行数值计算的开源软件库。图表中的节点代表数学运算,而表格边缘则代表沟通节点的多维数据数组(tensors)。其中的代码视觉上正如下图所展示的:

    深度学习下的医学图像分析(三)

    图片来源:《TensorFlow:异构分布系统上的大规模机器学习》 

    • 使用Keras进行预测性分析的示例

    在本文中,我们将使用来自UCI网站的Sonar数据集来完成一个简单的预测模型示例。在下面的代码中,我们直接从UCI网站获取数据,并将这些数据按照60::40的比例分为训练数据和测试数据。我们使用Keras进行预测建模,使用sklearn对标签进行编码。

    深度学习下的医学图像分析(三)

    在下一个代码片段中,我们使用之前定义好的函数来读取数据集中的数据。打印数据集之后,我们会发现我们的独立变量是需要进行编码的。

    深度学习下的医学图像分析(三)

    我们使用来自Scikit-learn的LabelEncoder(标签编码器)对标签进行编码,将字母R和M分贝转换为数字0和1。一种热编码还将分类特征转换成为了一种与算法更合适的格式。在这个示例中,我们的Y变量与R和M一样是分类对象,使用标签编码器,我们将这些字母变量转换为了1或0。

    深度学习下的医学图像分析(三)

    Scikit-learn的标签编码器

    之后,我们创建了一个使用Keras的模型:

    深度学习下的医学图像分析(三)

    在没有任何预处理操作的情况下,使用简单模型的准确度为81.64%

    • 使用Keras进行图像分析的示例

    为了更好地用Keras解释图像处理过程,我们将使用来自“Kaggle猫狗竞赛”的数据。这个竞赛的目的是开发一个能够用来区分图像中包含的是一只狗还是一只猫的算法。对于人类来说,区分猫狗是很简单的,但对于计算机来说可就复杂的多了。在这项“区分猫狗”的挑战中,有25000张标记了猫狗的训练图片,测试数据库中还有12500张等着我们去标记。根据Kaggle官网,当这个竞赛开始时(2013年年底):

    “目前的文献表明,机器分类器在这个任务上的准确度能达到80%以上。”因此,如果我们能成功突破80%的准确度,我们就能跃居2013年的技术发展最前沿。

    想要了解更多细节、进行下一步的学习或对深度学习进行尖端研究,我强烈推荐Fast.ai的网络公开课程。我在下面的代码中引用了fast.ai,它为我们的学习提供了一个很好的起点。

    深度学习下的医学图像分析(三)

    第一步:完成设置

    从Kaggle网站上下载猫、狗的图片数据,将其保存在你的电脑上。在本文提到的示例中,我会在我的iMac电脑上运行代码。

    深度学习下的医学图像分析(三)

    基本的设置

    Jeremy Howard提供了一个Python实用文件,帮助我们获取已封装的基础函数。我们要做的第一步就是使用这个实用文件。下图就是这个实用文件。随着细节的深入,我们将一步步打开这个文件,看看隐藏在文件背后的信息。

    深度学习下的医学图像分析(三)

    第二步:使用VGG

    我们在第一步中简单地使用了一个完全为我们建立的模型,这个模型能够识别各种各样的图像。第二步,我们将使用VGG。VGG是一个非常容易创建和理解的模型,它赢得了2014年的“ImageNet挑战赛”。VGG imagenet团队创建了两个模型——VGG 19和VGG 16。VGG 19是一个大型的、操作性能慢的、准确度稍佳的模型;而VGG 16是一个小型的、操作性能快的模型。我们将会使用VGG 16,因为VGG 19的操作性能比较慢,通常不值得在精确度上再做改进。

    我们建立了一个Python类——Vgg16。Vgg16能让VGG 16模型的使用更加简单。在fast.ai的github上同样能找到Vgg16,具体细节如下图:

    深度学习下的医学图像分析(三)

    第三步:实例化VGG

    深度学习下的医学图像分析(三)

    Vgg16建立于Keras(我们将在稍后讨论更多关于Keras的内容)之上。Keras是一个灵活的、易于使用的、建立在Theano和TensorFlow上的深度学习库。Keras使用一个固定的目录结构来分批查看大量的图像和标签,在这个目录结构下,每一类训练图像都必须放置在单独的文件夹里。

    下面是我们从文件夹中随意抓取的数据:

    深度学习下的医学图像分析(三)

    深度学习下的医学图像分析(三)

    第四步:预测猫、狗

    深度学习下的医学图像分析(三)

    第五步:将图像和代码文件汇总

    为了汇总这些图像和文件,我推荐的方法如下图:

    深度学习下的医学图像分析(三)

    总结: 

    阅读到这里,就证明你就已经采纳了我们在上一篇文章中讨论的理论,并做了一些实际的编程。如果你按照上面的指示和说明完成了两个示例,那么你就已经成功建立了你的第一个预测模型,并完成了图像分析。

    展开全文
  • 利用Hive进行数据分析

    万次阅读 2016-07-06 21:30:20
    面对当今互联网产生的巨大的TB甚至PB级原始数据,利用基于Hadoop的数据仓库解决方案Hive早已是Hadoop的热点应用之一。达观数据团队长期致力于研究和积累Hadoop系统的技术和经验,并构建起了分布式存储、分析、挖掘...

    近十年来,随着Hadoop生态系统的不断完善,Hadoop早已成为大数据事实上的行业标准之一。面对当今互联网产生的巨大的TB甚至PB级原始数据,利用基于Hadoop的数据仓库解决方案Hive早已是Hadoop的热点应用之一。达观数据团队长期致力于研究和积累Hadoop系统的技术和经验,并构建起了分布式存储、分析、挖掘以及应用的整套大数据处理平台。本文将从Hive的原理、架构及优化等方面来分享Hive的一些心得和使用经验,希望对大家有所收货。


    1  Hive基本原理

    Hadoop是一个流行的开源框架,用来存储和处理商用硬件上的大规模数据集。对于HDFS上的海量日志而言,编写Mapreduce程序代码对于类似数据仓库的需求来说总是显得相对于难以维护和重用,Hive作为一种基于Hadoop的数据仓库解决方案应运而生,并得到了广泛应用。

    Hive是基于Hadoop的数据仓库平台,由Facebook贡献,其支持类似SQL的结构化查询功能。Facebook设计开发Hive的初衷就是让那些熟悉sql编程方式的人也可以更好的利用hadoop,hive可以让数据分析人员只关注于具体业务模型,而不需要深入了解Map/Reduce的编程细节,但是这并不意味着使用hive不需要了解和学习Map/Reduce编程模型和hadoop,复杂的业务需求和模型总是存在的,对于Hive分析人员来说,深入了解Hadoop和Hive的原理和Mapreduce模型,对于优化查询总有益处。

    以下先以一个简单的例子说明利用hadoop Map/Reduce程序和Hive实现hadoop word count的例子。



    图:mapreduce和hive分别实现count

     

    通过以上可以看出,hive优点:成本低,可以通过类sql语句快速实现简单或复杂的MapReduce统计。

    借助于Hadoop和HDFS的大数据存储能力,数据仍然存储于Hadoop的HDFS中,Hive提供了一种类SQL的查询语言:HiveQL(HQL),对数据进行管理和分析,开发人员可以近乎sql的方式来实现逻辑,从而加快应用开发效率。(关于Hadoop、hdfs的更多知识请参考hadoop官网及hadoop权威指南)

    HQL经过解析和编译,最终会生成基于Hadoop平台的Map Reduce任务,Hadoop通过执行这些任务来完成HQL的执行。

     

    1.1   Hive组件

    Hive的组件总体上可以分为以下几个部分:用户接口(UI)、驱动、编译器、元数据(Hive系统参数数据)和执行引擎。


    图:Hive执行流程图

    1)      对外的接口UI包括以下几种:命令行CLI,Web界面、JDBC/ODBC接口;

    2)      驱动:接收用户提交的查询HQL;

    3)     编译器:解析查询语句,执行语法分析,生成执行计划;

    4)     元数据Metadata:存放系统的表、分区、列、列类型等所有信息,以及对应的HDFS文件信息等;

    5)     执行引擎:执行执行计划,执行计划是一个有向无环图,执行引擎按照各个任务的依赖关系选择执行任务(Job)。

     

    需要注意的是,元数据库一般是通过关系型数据库MySQL来存储。元数据维护了库信息、表信息、列信息等所有内容,例如表T包含哪些列,各列的类型等等。因此元数据库十分重要,需要定期备份以及支持查询的扩展性。

     

    读时验证机制

    与传统数据库对表数据进行写时严重不同,Hive对数据的验证方式为读时模式,即只有在读表数据的时候,hive才检查解析具体的字段、shema等,从而保证了大数据量的快速加载。

    既然hive采用的读时验证机制,那么 如果表schema与表文件内容不匹配,会发生什么呢?

    答案是hive会尽其所能的去读数据。如果schema中表有10个字段,而文件记录却只有3个字段,那么其中7个字段将为null;如果某些字段类型定位为数值类型,但是记录中却为非数值字符串,这些字段也将会被转换为null。简而言之,hive会努力catch读数据时遇到的错误,并努力返回。既然Hive表数据存储在HDFS中且Hive采用的是读时验证方式,定义完表的schema会自动生成表数据的HDFS目录,且我们可以以任何可能的方式来加载表数据或者利用HDFS API将数据写入文件,同理,当我们若需要将hive数据写入其他库(如oracle),也可以直接通过api读取数据再写入目标库。在实际生产环境中,当需要数据仓库之间的迁移时,就可以直接利用api将源库的数据直接写入hive库的表文件中,包括淘宝开源的datax数据交换系统都采用类似的方式来交换跨库数据。

    再次注意,加载或者写入的数据内容要和表定义的schema一致,否则将会造成字段或者表为空。

     

    1.2   Hive数据模型

    从数据仓库的角度看,Hive是建立在Hadoop上的数据仓库基础架构,可以方便的ETL操作。Hive没有专门的数据存储格式,也没有为数据建立索引,用于可以非常自由的组织Hive中的表,只需要在创建表的时候定义好表的schema即可。Hive中包含4中数据模型:Tabel、ExternalTable、Partition、Bucket。


    图:hive数据模型

    a)         Table:类似与传统数据库中的Table,每一个Table在Hive中都有一个相应的目录来存储数据。例如:一个表t,它在HDFS中的路径为:/user/hive/warehouse/t

    b)        Partition:类似于传统数据库中划分列的索引。在Hive中,表中的一个Partition对应于表下的一个目录,所有的Partition数据都存储在对应的目录中。例如:t表中包含ds和city两个Partition,则对应于ds=2014,city=beijing的HDFS子目录为:/user/hive/warehouse/t/ds=2014/city=Beijing

    需要注意的是,分区列是表的伪列,表数据文件中并不存在这个分区列的数据。

    c)         Buckets:对指定列计算的hash,根据hash值切分数据,目的是为了便于并行,每一个Buckets对应一个文件。将user列分数至32个Bucket上,首先对user列的值计算hash,比如,对应hash=0的HDFS目录为:/user/hive/warehouse/t/ds=2014/city=Beijing/part-00000;对应hash=20的目录为:/user/hive/warehouse/t/ds=2014/city=Beijing/part-00020

    d)        External Table指向已存在HDFS中的数据,可创建Partition。Managed Table创建和数据加载过程,可以用统一语句实现,实际数据被转移到数据仓库目录中,之后对数据的访问将会直接在数据仓库的目录中完成。删除表时,表中的数据和元数据都会删除。ExternalTable只有一个过程,因为加载数据和创建表是同时完成。数据是存储在Location后面指定的HDFS路径中的,并不会移动到数据仓库中。

     

    1.3   Hive翻译成MapReduce Job

    Hive编译器将HQL代码转换成一组操作符(operator),操作符是Hive的最小操作单元,每个操作符代表了一种HDFS操作或者MapReduce作业。Hive中的操作符包括:

    表:Hive执行常用的操作符列表

    操作符

    描述

    TableScanOperator

    扫描hive表数据

    ReduceSinkOperator

    创建将发送到Reducer端的<Key,Value>对

    JoinOperator

    Join两份数据

    SelectOperator

    选择输出列

    FileSinkOperator

    建立结果数据,输出至文件

    FilterOperator

    过滤输入数据

    GroupByOperator

    Group By 语句

    MapJoinOperator

    Mapjoin

    LimitOperator

    Limit语句

    UnionOperator

    Union语句

     

    对于MapReduce操作单元,Hive通过ExecMapper和ExecReducer执行MapReduce任务。

    对于Hive语句:

    INSERT OVERWRITETABLE read_log_tmp
    SELECT a.userid,a.bookid,b.author,b.categoryid
    FROM user_read_log aJOIN book_info b ON a.bookid= b.bookid;

    其执行计划为:


    图:reduce端join的任务执行流程

     

    1.4   与一般SQL的区别

    Hive 视图与一般数据库视图

    Hive视图与一般数据库视图作用角色相同,都是基于数据规模缩减或者基于安全机制下的某些条件查询下的数据子集。Hive视图只支持逻辑视图,不支持物化视图,即每次对视图的查询hive都将执行查询任务,因此视图不会带来性能上的提升。作为Hive查询优化的一部分,对视图的查询条件语句和视图的定义查询条件语句将会尽可能的合并成一个条件查询。

     

    Hive索引与一般数据库索引

    相比于传统数据库,Hive只提供有限的索引功能,通过在某些字段上建立索引来加速某些操作。通常当逻辑分区太多太细,partition无法满足时,可以考虑建立索引。Hive1.2.1版本目前支持的索引类型有CompactIndexHandler和Bitmap。

    CompactIndexHandler压缩索引通过将列中相同的值得字段进行压缩从而减小存储和加快访问时间。需要注意的是Hive创建压缩索引时会将索引数据也存储在Hive表中。对于表tb_index (id int, name string)而言,建立索引后的索引表中默认的三列一次为索引列(id)、hdfs文件地址(_bucketname)、偏移量(offset)。特别注意,offset列类型为array<bigint>。

    Bitmap位图索引作为一种常见的索引,如果索引列只有固定的几个值,那么就可以采用位图索引来加速查询。利用位图索引可以方便的进行AND/OR/XOR等各类计算,Hive0.8版本开始引入位图索引,位图索引在大数据处理方面的应用广泛,比如可以利用bitmap来计算用户留存率(索引做与运算,效率远好于join的方式)。如果Bitmap索引很稀疏,那么就需要对索引压缩以节省存储空间和加快IO。Hive的Bitmap Handler采用的是EWAH(https://github.com/lemire/javaewah)压缩方式。

    图:Hivecompact索引及bitmap索引 

    从Hive索引功能来看,其主要功能就是避免第一轮mr任务的全表扫描,而改为扫描索引表。如果索引索引表本身很大,其开销仍然很大,在集群资源充足的情况下,可以忽略使用hive下的索引。

     

    2     Schema设计

    没有通用的schema,只有合适的schema。在设计Hive的schema的时候,需要考虑到存储、业务上的高频查询造成的开销等等,设计适合自己的数据模型。

     

    2.1   设置分区表

    对于Hive来说,利用分区来设计表总是必要的,分区提供了一种隔离数据和优化查询的便利的方式。特别是面对日益增长的数据规模。设置符合逻辑的分区可以避免进行全表扫描,只需加载特定某些hdfs目录的数据文件。

    设置分区时,需要考虑被设置成分区的字段,按照时间分区一般而言就是一个好的方案,其好处在于其是按照不同时间粒度来确定合适大小的数据积累量,随着时间的推移,分区数量的增长是均匀的,分区的大小也是均匀的。达观数据每日处理大量的用户日志,对于user_log来说,设置分区字段为日期(天)是合理的。如果以userid字段来建立动态分区,而userid的基数是非常大的,显然分区数目是会超过hive的默认设置而执行失败。如果相对userid进行hash,我们可以以userid进行分桶(bucket),根据userid进行hash然后分发到桶中,相同hash值的userid会分发到同一个桶中。每个桶对应着一个单独的文件。

     

    2.2   避免小文件

    虽然分区有利于隔离数据和查询,设置过多过细的分区也会带来瓶颈,主要是因为HDFS非常容易存储大数据文件,由于分区对应着hdfs的目录结构,当存在过多的分区时,意味着文件的数目就越多,过多增长的小文件会给namecode带来巨大的性能压力。同时小文件过多会影响JOB的执行,hadoop会将一个job转换成多个task,即使对于每个小文件也需要一个task去单独处理,task作为一个独立的jvm实例,其开启和停止的开销可能会大大超过实际的任务处理时间。因此,hive表设计的分区不应该过多过细,每个目录下的文件足够大,应该是文件系统中块大小的若干倍。

     

    查询避免生成小文件

    既然hive或者说hadoop需要大文件,HQL执行语句也需要注意输入文件和输出文件的大小,防止生成过多小文件。hive可以通过配置参数在mr过程中合并小文件。

    Map合并小文件:

    setmapred.max.split.size=256000000  #每个Map最大输入大小(单位:字节)
    set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat  #执行Map前进行小文件合并

    输出合并:

    set hive.merge.mapfiles= true                 #在Map-only的任务结束时合并小文件
    sethive.merge.mapredfiles= true               #在Map-Reduce的任务结束时合并小文件
    set hive.merge.size.per.task= 256*1000*1000    #合并文件的大小
    set hive.merge.smallfiles.avgsize=16000000     #当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge


    </pre><p>一个独立的map-reduce任务进行文件merge</p><p align="left"><pre name="code" class="sql">create table user_log (user_id int,url string,source_ip string)
    partitionedby (dt  string)
    clusteredby (user_id) into 96 buckets;

    我们知道hive输出最终是mr的输出,即reducer(或mapper)的输出,有多少个reducer(mapper)输出就会生成多少个输出文件,根据shuffle/sort的原理,每个文件按照某个值进行shuffle后的结果。我们可通过设置hive.enforce.bucketing=true来强制将对应记录分发到正确桶中,或者通过添加cluster by语句以及设置setmapred.reduce.tasks=96来设置reducer的数目,从而保证输出与schema一致。根据hive的读时验证方式,正确的插入数据取决与我们自己,而不能依靠schema。

     

    2.3   选择文件格式

    Hive提供的默认文件存储格式有textfile、sequencefile、rcfile等。用户也可以通过实现接口来自定义输入输的文件格式。

    在实际应用中,textfile由于无压缩,磁盘及解析的开销都很大,一般很少使用。Sequencefile以键值对的形式存储的二进制的格式,其支持针对记录级别和块级别的压缩。rcfile是一种行列结合的存储方式(text file和sequencefile都是行表[row table]),其保证同一条记录在同一个hdfs块中,块以列式存储。一般而言,对于OLTP而言,行表优势大于列表,对于OLAP而言,列表的优势大于行表,特别容易想到当做聚合操作时,列表的复杂度将会比行表小的多,虽然单独rcfile的列运算不一定总是存在的,但是rcfile的高压缩率确实减少文件大小,因此实际应用中,rcfile总是成为不二的选择,达观数据平台在选择文件存储格式时也大量选择了rcfile方案。

     

    3     查看执行计划及优化

    达观的数据仓库基于Hive搭建,每日需要处理大量的计算流程,Hive的稳定性和性能至关重要。众多的任务需要我们合理的调节分配集群资源,合理的配置各参数,合理的优化查询。Hive优化包含各个方面,如job个数优化、job的map/reducer个数优化、并行执行优化等等,本节将主要从HQL查询优化角度来具体说明。

    3.1   Join语句

    对于上述的join语句

    INSERT OVERWRITETABLE read_log_tmp
    SELECT a.userid,a.bookid,b.author
    FROM user_read_log aJOIN book_info b ON a.bookid= b.bookid;

    explain该查询语句后:

     

    图:map端join的执行计划

    由于表中数据为空,对于小数据量,hive会自动采取map join的方式来优化join,从mapreduce的编程模型来看,实现join的方式主要有map端join、reduce端join。Map端join利用hadoop 分布式缓存技术通过将小表变换成hashtable文件分发到各个task,map大表时可以直接判断hashtable来完成join,注意小表的hashtable是放在内存中的,在内存中作匹配,因此map join是一种非常快的join方式,也是一种常见的优化方式。如果小表够小,那么就可以以map join的方式来完成join完成。Hive通过设置hive.auto.convert.join=true(默认值)来自动完成map join的优化,而无需显示指示map join。缺省情况下map join的优化是打开的。 

    Reduce端join需要reducer来完成join过程,对于上述join代码,reduce 端join的mr流程如下,


    图:reduce端join的mapreduce过程

    相比于map join, reduce 端join无法再map过程中过滤任何记录,只能将join的两张表的所有数据按照join key进行shuffle/sort,并按照join key的hash值将<key,value>对分发到特定的reducer。Reducer对于所有的键值对执行join操作,例如0号(bookid的hash值为0)reducer收到的键值对如下,其中T1、T2表示记录的来源表,起到标识作用:


    图:reduce端join的reducer join

    Reducer端join无法避免的reduce截断以及传输的大量数据都会给集群网络带来压力,从上图可以看出所有hash(bookid)% reducer_number等于0的key-value对都会通过shuffle被分发到0号reducer,如果分到0号reducer的记录数目远大于其他reducer的记录数目,显然0号的reducer的数据处理量将会远大于其他reducer,因此处理时间也会远大于其他reducer,甚至会带来内存等其他问题,这就是数据倾斜问题。对于join造成的数据倾斜问题我们可以通过设置参数setHive.optimize.skewjoin=true,让hive自己尝试解决join过程中产生的倾斜问题。

    3.2   Group by语句

    我们对user_read_log表按userid goup by语句来继续探讨数据倾斜问题,首先我们explain group by语句:

    explain select userid,count(*)from user_read_log groupby userid

    图:goupby的执行计划


    Group by的执行计划按照userid的hash值分发记录,同时在map端也做了本地reduce,group by的shuffle过程是按照hash(userid)来分发的,实际应用中日志中很多用户都是未注册用户或者未登录,userid字段为空的记录数远大于userid不为空的记录数,当所有的空userid记录都分发到特定某一个reducer后,也会带来严重的数据倾斜问题。造成数据倾斜的主要原因在于分发到某个或某几个reducer的数据量远大于其他reducer的数据量。

    对于groupby造成的数据倾斜问题,我们可以通过设置参数 

    set hive.map.aggr=true (开启map端combiner);
    set hive.groupby.skewindata=true;

    这个参数的作用是做Reduce操作的时候,拿到的key并不是所有相同值给同一个Reduce,而是随机分发,然后Reduce做聚合,做完之后再做一轮MR,拿前面聚合过的数据再算结果。虽然多了一轮MR任务,但是可以有效的减少数据倾斜问题可能带来的危险。

     

    Hive解决数据倾斜

    正确的设置Hive参数可以在某种程度上避免的数据倾斜问题,合适的查询语句也可以避免数据倾斜问题。要尽早的过滤数据和裁剪数据,减少后续处理的数据量,使得join key的数据分布较为均匀,将空字段随机赋予值,这样既可以均匀分发倾斜的数据:

    select userid,namefrom user_info a
    join (
        select case when userid isnull then cast(rand(47)*100000as int)
        else userid
        from user_read_log
    ) b on a.userid= b.userid

    如果用户在定义schema的时候就已经预料到表数据可能会存在严重的数据倾斜问题,Hive自0.10.0引入了skew table的概念,如建表语句

    CREATE TABLE user_read_log (useridint,bookid,…)
    SKEWEDBY (userid) ON (null)[STORED AS DIRECTORIES];

    需要注意的是,skewtable只是将倾斜特别严重的列的分开存储为不同的文件,每个制定的倾斜值制定为一个文件或者目录,因此在查询的时候可以通过过滤倾斜值来避免数据倾斜问题:

    select userid,namefrom user_info a
    join (
    select userid from user_read_log where pt=’2015’and userid isnot null
    ) b on a.userid= b.userid

    可以看出,如果不加过滤条件,倾斜问题还是会存在,通过对skewtable加过滤条件的好处是避免了mapper的表扫描过滤操作。

    3.3   Join的物理优化

    Hive内部实现了MapJoinResolver(处理MapJoin)、SkewJoinResolver(处理倾斜join)、CommonJoinResolver

    (处理普通Join)等类来实现join的查询物理优化(/org/apache/hadoop/hive/ql/optimizer/physical)。

    CommonJoinResolver类负责将普通Join转换成MapJoin,Hive通过这个类来实现mapjoin的自动优化。对于表A和表B的join查询,会产生3个分支:

    1)        以表A作为大表进行Mapjoin;

    2)        以表A作为大表进行Mapjoin;

    3)        Map-reduce join

    由于不知道输入数据规模,因此编译时并不会决定走那个分支,而是在运行时判断走那个分支。需要注意的是要像完成上述自动转换,需要将hive.auto.convert.join.noconditionaltask设置为true(默认值),同时可以手工控制转载进内存的小表的大小(hive.auto.convert.join.noconditionaltask.size)。

    MapJoinResolver 类负责迭代各个mr任务,检查每个任务是否存在map join操作,如果有,会将local map work转换成local map join work。

    SkewJoinResolver类负责迭代有join操作的reducer任务,一旦单个reducer产生了倾斜,那么就会将倾斜值得数据写入hdfs,然后用一个新的map join的任务来处理倾斜值的计算。虽然多了一轮mr任务,但是由于采用的map join,效率也是很高的。良好的mr模式和执行流程总是至关重要的。


    4     窗口分析函数

    Hive提供了丰富了数学统计函数,同时也提供了用户自定义函数的接口,用户可以自定义UDF、UDAF、UDTF Hive 0.11版本开始提供窗口和分析函数(Windowingand Analytics Functions),包括LEAD、LAG、FIRST_VALUE、LAST_VALUE、RANK、ROW_NUMBER、PERCENT_RANK、CUBE、ROLLUP等。

    窗口函数是深受数据分析人员的喜爱,利用窗口函数可以方便的实现复杂的数据统计分析需求,oracle、db2、postgresql等数据库中也提供了window function的功能。窗口函数与聚合函数一样,都是对表子集的操作,从结果上看,区别在于窗口函数的结果不会聚合,原有的每行记录依然会存在。

    窗口函数的典型分析应用包括:

    1)        按分区聚合(排序,topn问题)

    2)        行间计算(时间序列分析)

    3)        关联计算(购物篮分析)

    我们以一个简单的行间计算的例子说明窗口函数的应用(关于其他函数的具体说明,请参考hive文档)。用户阅读行为的统计分析需要从点击书籍行为中归纳统计出来,用户在时间点T1点击了章节A,在时间点T2点击了章节B,在时间点T3点击了章节C 。用户浏览日志结构如下表所示。

    USER_ID

    BOOK_ID

    CHAPTER_ID

    LOG_TIME

    1001

    2001

    40001

    1443016010

    1001

    2001

    40004

    1443016012

    1001

    2001

    40005

    1443016310

    通过对连续的用户点击日志分析,通过Hive提供的窗口分析函数可以计算出用户各章节的阅读时间。按照USER_ID、BOOKID构建窗口,并按照LOG_TIME排序,对窗口的每一条记录取相对下一条记录的LOG_TIME减去当前记录的LOG_TIME即为当前记录章节的阅读时间。

    SELECT
        Userid, bookid, chapterid, end_time – start_timeas read_time
    FROM
    (
        SELECT userid, bookid, chapterid, log_timeas start_time,
        lead(log_time,1,null) over(partitionby userid, bookidorder by log_time)as end_time 
        FROM user_read_logwhere pt=’2015-12-01’
    ) a;

    通过上述查询既可以找出2015-12-01日所有用户对每一章节的阅读时间。感谢窗口函数,否则hive将束手无策。只能通过开发mr代码或者实现udaf来实现上述功能。

    窗口分析函数关键在于定义的窗口数据集及其对窗口的操作,通过over(窗口定义语句)来定义窗口。日常分析和实际应用中,经常会有窗口分析应用的场景,例如基于分区的排序、集合、统计等复杂操作。例如我们需要统计每个用户阅读时间最多的3本书:

    •  

    图:行间计算示意图及代码

    对上述语句explain后的结果:


    图:行间计算的执行计划

    窗口函数使得Hive的具备了完整的数据分析功能,在实际的应用环境中,达观数据分析团队大量使用hive窗口分析函数来实现较为复杂的逻辑,提高开发和迭代效率。

     

    5     总结

    本文在介绍Hive的原理和架构的基础上,分享了达观团队在Hive上的部分使用经验。Hive仍然处在不断的发展之中,将HQL理解成Mapreduce程序、理解Hadoop的核心能力是更好的使用和优化Hive的根本。

    技术的发展日新月异,随着spark的日益完善和流行,hive社区正考虑将spark作为hive的执行引擎之一。Spark是一种基于rdd(弹性数据集)的内存分布式并行处理框架,内部集成了Spark SQL模块来实现对结构化数据的SQL功能。相比于Hadoop将大量的中间结果写入HDFS,Spark避免了中间结果的持久化,速度更快且更有利于迭代计算。 具体需要结合自身的业务需求,采取合理的框架架构,提升系统的处理能力。

     

     

    参考:

    1.  Hive wiki:https://cwiki.apache.org/confluence/display/Hive/Home

    2.  Hive Design Docs:https://cwiki.apache.org/confluence/display/Hive/DesignDocs

    3.  Hadoop: The Definitive Guide (3rd Edition)

    4. Programming Hive

    5. Analytical Queries with Hive:http://www.slideshare.net/Hadoop_Summit/analytical-queries-with-hive

     

    展开全文
  • 利用opencv棋盘格标定法对鱼眼图像校正分析

    万次阅读 多人点赞 2016-09-28 15:27:01
    利用opencv棋盘格标定法对鱼眼图像校正分析 一、开发环境 PC端、vs2013+opencv3.0、摄像头为淘宝购置的鱼眼摄像头外设+iphone6 二、镜头标定 1. 输入畸变的棋盘格以及棋盘格的size(横纵坐标上的角点个数...
  • 系列一:《python数据分析基础与实践》 章节1Python概况 课时2Python简介 章节2Python安装 课时3安装Anaconda 课时4使用Anaconda 章节3数据准备 课时5数据类型 – 布尔型 课时6数据类型 – 数值型 课时7数据类型 – ...
  • 数据处理-利用 python进行异常值分析

    千次阅读 2019-07-06 14:17:18
    异常值分析是检验数据是否有录入错误数据和不合常理的数据。不加剔除的把异常值代入数据分析过程中,会对结果产生不良影响,而对异常值的分析其原因,常常成为为发现问题的而改进决策的契机。 异常值是指样本中的...
  • 利用SPSS进行多重线性回归分析-基础篇

    千次阅读 多人点赞 2020-09-16 11:56:00
    2、控制混杂因素,评价多个自变量对因变量的独立效应; 3、用已知的自变量来估计和预测因变量的值及其变化。 多重线性回归与多元线性回归 多重线性回归:是指包含两个或两个以上自变量的线性回归模型; 多元线性...
  • 以数据相关为主,互联网为辅进行文章发布。 本文是《Python数据分析与挖掘实战》一书的实战部分,在整理分析后的复现。 本篇文章是本书第七章的实战:航空公司客户价值分析。 相关附件代码、数据和PDF,关注...
  • MATLAB实现控制系统的时域分析

    万次阅读 多人点赞 2017-04-26 19:19:27
    目的用 MATLAB 对控制系统进行时域分析,包括典型响应、判断系统稳 定性和分析系统的动态特性。理论 二、典型响应及其性能分析 1、单位阶跃响应 单位阶跃响应调用格式为: (1) step(num,den) (2) step(num,den,...
  • 两轮差速移动机器人运动分析、建模和控制

    万次阅读 多人点赞 2018-11-02 21:24:35
    两轮差速运动分析及建模运动学分析三种运动状态分析函数模型仿真验证直线验证曲线验证旋转验证运动控制 运动学分析 运动特性为两轮差速驱动,其底部后方两个同构驱动轮的转动为其提供动力,前方的随动轮起支撑作用...
  • 图像分析,使用Halcon进行缺陷检测

    万次阅读 多人点赞 2018-10-16 22:47:26
    它节约了产品成本,缩短了软件开发周期——HALCON灵活的架构便于机器视觉,医学图像和图像分析应用的快速开发。在欧洲以及日本的工业界已经是公认具有最佳效能的Machine Vision软件。 Halcon语句的分类: 绿色:...
  • 在深度学习模型训练过程中,在服务器端或者本地pc端,输入nvidia-smi来观察显卡的GPU内存占用率(Memory-Usage),显卡的GPU利用率(GPU-util),然后...接下来仔细分析这些问题和处理办法。 1. GPU内存占用率问...
  • 1.背景与挖掘目标1.1背景航空公司业务竞争...对不同的客户类别进行特征分析,比较不同类客户的客户价值对不同价值的客户类别提供个性化服务,制定相应的营销策略。详情数据见数据集内容中的air_data.csv和客户信息属性
  • 利用Oprofile对多核多线程进行性能分析 杨小华 工欲善其事,必先利其器 ---墨子性能分析工具简介在对应用程序不断调优的过程中,除了制定完备的测试基准(Benchmark)外,还需要一把直中要害的利器——性能分析...
  • 学习了seaborn的基本风格操作设置之后我们便操作seaborn学习直方、散点的绘制方法,以及对数据进行回归分析的方法(本文使用jupyter notebook为开发环境)。 直方的绘制 首先我们导入必须的包以及matplotlib...
  • 它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。...可以在本地就能控制服务器。要开始一个telnet会话,必须输入用户名和密码来登录服务
  • 本代码是MathWorks讲座"PID Control Made Easy"的演示文件。 This is the demo file for MathWorks...演示了如何在MATLAB和Simulink中进行PID控制器的设计与调整。 The demo shows design and tuning of PID control...
  • 做个简单的demo记录下,...我们的目的是要分析各个维度对金钱的影响。 关联度分析代码: # -*- coding: utf-8 -*- from numpy import array import pandas as pd import seaborn as sns from matplotlib impo...
  • 木马分析(隐藏分析)实验 木马分析控制分析)实验 木马植入方法实验---冰河木马
  • 利用subplot输出子图的方式将所有的PID效果都输出到一个图进行对比。该代码根据上述代码修改已经很容易,PID比较图的代码如下: close all PID = [ 0.22 , 0.13 , 0 ; 0.4 , 0.13 , 0 ; 0.4 , 0.25 , 0 ; ...
  • Retinex图像增强算法的优势分析

    千次阅读 2020-10-01 21:51:13
    上面我们已经介绍了关于各类图像增强算法,并重点对Retinex图像增强算法进行了仿真,这里... 任意选取一个图片,通过其灰度直方图进行增强分析,如图2所示。 ·熵 图像的熵值反映了图像的信息量,熵越大,信息...
  • 自动控制原理(4) - 时域分析

    千次阅读 2019-03-19 20:40:33
    &amp;nbsp; &amp;nbsp;... 1,直接在时间域内对系统进行分析 &amp;nbsp; &amp;nbsp; &amp;nbsp; 2,提供系统时间响应的全部信息,更加直观、准确。 &amp;nbsp; &amp;n
  • 伯德图(Bode分析系统性能

    万次阅读 多人点赞 2020-02-19 19:19:31
    根据Bode,从系统频率的角度分析系统性能。 坐标系 伯德图由两张组成,一个是幅频特性曲线,另一个是相频特性曲线。 伯德图横坐标为对数刻度,纵坐标幅值或相角采用线性分度。 幅频特性曲线,其中横坐标上为ω\...
  • Soot生成控制

    千次阅读 2016-10-21 21:27:38
    Soot是McGill大学的Sable研究小组自1996年开始开发的Java字节码分析工具,它提供了多种字节码分析和变换功能,通过它可以进行过程内和过程间的分析优化,以及程序流的生成,还能通过图形化的方式输出,让用户对...
  • 利用水文分析方法提取山脊、山谷线 1. 背景:山脊线、山谷线是地形特征线,它们对地形、地貌具有一定的控制作用。它们与山顶点、谷底点以及鞍部点等一起构成了地形及其起伏变化的骨架结构。因此在数字地形分析中...
  • 原生js实现轮播原理分析

    万次阅读 多人点赞 2018-08-04 10:40:03
    利用浮动将所有所有照片依次排成一行,给这一长串图片添加一个父级的遮罩,每次只显示一张,其余的都隐藏起来。对图片添加绝对定位,通过控制left属性,实现照片的移动。 2.图片移动动画原理: 从a位置移动到b...
  • 利用多层卷积神经网络(CNN)特征的互补优势 进行图像检索 本文原网址为:http://www.sciencedirect.com/science/article/pii/S0925231216314734 翻译不当之处请多多指正 摘要:深度卷积神经网络已经证明了图像分类...
  • spss教程进行单因素方差分析(图文教程) 单因素方差分析原理 因变量:连续变量 自变量:多分类 用来测试某一个控制变量的不同水平是否给观察变量造成显著差异和变动。 方差分析前提:不同水平下,各总体均值...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 364,508
精华内容 145,803
关键字:

如何利用控制图进行分析