• [参赛经验分享] 赛事回顾 | 第四届·2022量子计算黑客松全国大赛圆满落幕!
    随着全球新一轮科技革命的飞速发展,颠覆性技术革新风起云涌,量子科技当之无愧是最引人瞩目的焦点。2022年5月29日,由HiQ量子计算软件团队、上海大学、电子科技大学、南方科技大学、昇思MindSpore社区和华为云ModelArts平台联合举办的第四届·2022量子计算黑客松全国大赛决赛圆满落幕。1大赛赛况总结本此大赛历时两个多月,吸引了来自北京大学、清华大学、中国科学技术大学、复旦大学、浙江大学、上海交通大学、中山大学、南方科技大学、上海大学等国内外170多所高校的本科生、研究生以及建信金科、中国金融认证中心等企业员工,总计500多人报名。近200个团队参与本次比赛,共同创新,推动量子计算的技术研究。为了体现前沿性和交叉性,本次参赛题目涉及量子计算、量子化学、机器学习等交叉学科。初赛题目颇具挑战性,赛题1“利用量子经典混合的神经网络来完成手写字体识别任务”、赛题2“量子化学模拟——基态能求解的浅层线路设计”,基于高性能开源量子计算框架MindSpore Quantum和HiQ量子计算云平台完成赛题。参赛团队之间互相启发,台上竞争,台下合作,经过层层选拔,最终有13个团队、28名优秀选手成功晋级总决赛,汇聚一堂巅峰对决。2嘉宾评委阵容强大2022年5月29日总决赛在线上如期举行。决赛邀请六位量子计算领域的专家组成评审团,分别是南方科技大学物理系教授、HiQ量子计算软件与算法首席科学家翁文康老师,中国科学院计算机技术研究所研究员孙晓明老师,北京清华大学自动化系教授吴热冰老师,上海交通大学物理系教授唐豪老师,电子科技大学计算机系教授王晓霆老师,MindSpore Quantum高级研究员徐旭升博士。决赛答辩环节,由于日程紧,团队多,给予评委团的压力很大。但是,我们的嘉宾评委全程保持了高度专注,认真听取每一支队伍的决赛演讲,以公正、严谨的态度进行打分,并从自己的专业出发为作品提出中肯的意见和建议。各队选手均是有备而来,凭借深厚的专业知识、对赛题创新性的深入挖掘和团队协作精神,深深的打动了各位评委老师,答辩提问环节选手对评委老师的各种挑战和提问也是应对自如。3角逐冠军,竞争激烈!决赛评审团从创新性、通用性、性能三个维度进行评分,经过激烈的角逐,来自重庆大学的参赛团队以总分第一名的成绩,获得冠军,来自上海大学的两支队伍同时获得亚军。此外还产生了三等奖三名,优秀奖七名。恭喜以下获奖团队,让我们来一睹他们的团队风采吧!一等奖获奖团队:五点组会也没关系团队成员:储贻达、周彦桦、徐维(重庆大学)二等奖获奖团队:Hbar团队成员:唐加亮、王瑞、李宇栋(上海大学)获奖团队:Fenice团队成员:徐宜家、刘懿贤(上海大学)三等奖获奖团队:量子emo小分队团队成员:周旭(中山大学)、刘佳薇(中国科学技术大学)、周俊园(南方科技大学)获奖团队:为什么神经网络和化学都要做团队成员:陈柄任(建信金融科技有限责任公司) 、 于小涵(电子科技大学)获奖团队:零熵 团队成员:耿力(同济大学)优秀奖4 总结没有横空出世的幸运,只有不为人知的努力,在征服与挑战中,各位选手在本次大赛中都收获了属于自己的那一份荣誉与认同。来自不同院校和企业的参赛选手、组织者在一起不仅收获了成绩,更多的是在学术交流和创新实践中收获知识、经验和友情。本次大赛涌现了一大波量子计算种子选手,将成为我国量子计算的后备人才。我们相信通过量子计算黑客松这样的重量级精品赛事,将选拔出更多量子计算优秀人才参与到量子计算的研究中来,推动我国量子计算事业发展。  值得一提的是华为已连续举办了四届量子计算黑客松全国大赛,也受到来自全国各高校和企业单位的高度重视和大力支持。重庆大学物理学院、上海大学新闻网、中国海洋大学信息科学与工程学部、上海科技报、新民晚报等多家高校网站和媒体纷纷对赛事进行报道。
  • [其他] 浅谈k近邻算法
    K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:在特征空间中,如果一个样本附近的k个最近(即特征空间中最邻近)样本的大多数属于某一个类别,则该样本也属于这个类别。K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居), 这K个实例的多数属于某个类,就把该输入实例分类到这个类中。KNN 的模型表示就是整个训练数据集。对新数据点的预测结果是通过在整个训练集上搜索与该数据点最相似的 K 个实例(近邻)并且总结这 K 个实例的输出变量而得出的。对于回归问题来说,预测结果可能就是输出变量的均值;而对于分类问题来说,预测结果可能是众数(或最常见的)的类的值。关键之处在于如何判定数据实例之间的相似程度。如果你的数据特征尺度相同(例如,都以英寸为单位),那么最简单的度量技术就是使用欧几里得距离,你可以根据输入变量之间的差异直接计算出该值。KNN 算法本身简单有效,它是一种 lazy-learning 算法,分类器不需要使用训练集进行训练,训练时间复杂度为0。KNN 分类的计算复杂度和训练集中的文档数目成正比,也就是说,如果训练集中文档总数为 n,那么 KNN 的分类时间复杂度为O(n)。KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。K 近邻算法使用的模型实际上对应于对特征空间的划分。K 值的选择,距离度量和分类决策规则是该算法的三个基本要素:    K 值的选择会对算法的结果产生重大影响。K值较小意味着只有与输入实例较近的训练实例才会对预测结果起作用,但容易发生过拟合;如果 K 值较大,优点是可以减少学习的估计误差,但缺点是学习的近似误差增大,这时与输入实例较远的训练实例也会对预测起作用,使预测发生错误。在实际应用中,K 值一般选择一个较小的数值,通常采用交叉验证的方法来选择最优的 K 值。随着训练实例数目趋向于无穷和 K=1 时,误差率不会超过贝叶斯误差率的2倍,如果K也趋向于无穷,则误差率趋向于贝叶斯误差率。    该算法中的分类决策规则往往是多数表决,即由输入实例的 K 个最临近的训练实例中的多数类决定输入实例的类别    距离度量一般采用 Lp 距离,当p=2时,即为欧氏距离,在度量之前,应该将每个属性的值规范化,这样有助于防止具有较大初始值域的属性比具有较小初始值域的属性的权重过大。
  • [技术干货] 人工神经网络训练图像分类器
    我们将仅使用全连接层在20000张图像上训练图像分类模型。所以没有卷积和其他花哨的东西,我们将把它们留到下一篇文章中。不用说,但你真的不应该使用普通的人工神经网络来分类图像。图像是二维的,通过展平图像,你将失去使图像可识别的模式。尽管如此,它还是很有趣且可行的,并且会让你洞察这种方法的所有错误。使用的数据集和数据准备我们将使用Kaggle的狗与猫数据集。它是根据知识共享许可证授权的,这意味着你可以免费使用它:图1:狗与猫数据集:该数据集相当大——25000张图像均匀分布在不同的类中(12500张狗图像和12500张猫图像)。它应该足够大,可以训练一个像样的图像分类器,但不能使用人工神经网络。唯一的问题是——它的结构不适合直接使用。你可以按照之前的文章创建一个适当的目录结构,并将其拆分为训练集、测试集和验证集:缩小、灰度化和展平图像让我们导入相关库。我们需要很多,需要安装Numpy、Pandas、TensorFlow、PIL和Scikit Learn:我们不能将图像直接传递到Dense层。单个图像是三维的——高度、宽度、颜色通道——而Dense层需要一维输入。让我们看一个例子。以下代码加载并显示训练集中的cat图像:src_img = Image.open('data/train/cat/1.jpg')display(src_img)图2——猫的图片示例图像宽281像素,高300像素,有三个颜色通道(np.array(src_img).shape)。总的来说,它有252900个像素,在展平时转化为252900个特征。让我们尽可能节省一些资源。如果有意义的话,你应该对你的图像数据集进行灰度化。如果你能对不以颜色显示的图像进行分类,那么神经网络也应该如此。可以使用以下代码段将图像转换为灰色:gray_img = ImageOps.grayscale(src_img)display(gray_img)图3:灰色猫图像显然,它仍然是一只猫,所以颜色在这个数据集中并没有起到很大作用。灰度图像宽281像素,高300像素,但只有一个颜色通道。这意味着我们从252,900 像素减少到84,300 像素。仍然很多,但肯定是朝着正确的方向迈出了一步。数据集中的图像大小不同。这对于神经网络模型来说是个问题,因为它每次都需要相同数量的输入特征。我们可以将每个图像调整为相同的宽度和高度,以进一步减少输入特征的数量。下面的代码片段调整了图像的大小,使其既宽又高96像素:gray_resized_img = gray_img.resize(size=(96, 96))display(gray_resized_img)图4:调整大小的猫图片当然,图像有点小而且模糊,但它仍然是一只猫。但是我们的特征减少到9216个,相当于将特征的数量减少了27倍。作为最后一步,我们需要将图像展平。你可以使用Numpy中的ravel函数来执行此操作:np.ravel(gray_resized_img)图5:扁平猫图片计算机就是这样看待猫的——它只是一个9216像素的数组,范围从0到255。问题是——神经网络更喜欢0到1之间的范围。我们将整个数组除以255.0即可:img_final = np.ravel(gray_resized_img) / 255.0img_final图6-扁平和缩放的猫图像作为最后一步,我们将编写一个process_image函数,将上述所有转换应用于单个图像:让我们在随机的狗图像上进行测试,然后反转最后一步,以直观地表示图像:tst_img = process_image(img_path='data/validation/dog/10012.jpg')Image.fromarray(np.uint8(tst_img * 255).reshape((96, 96)))图7:经过变换的狗形象就这样,这个函数就像字面意思。接下来,我们将其应用于整个数据集。将图像转换为表格数据进行深度学习我们将编写另一个函数——process_folder——它迭代给定的文件夹,并在任何JPG文件上使用process_image函数。然后,它将所有图像合并到一个数据帧中,并添加一个类作为附加列(猫或狗):让我们将其应用于训练、测试和验证文件夹。每个文件夹需要调用两次,一次用于猫,一次用于狗,然后连接集合。我们还将把数据集转储到pickle文件中:下面是训练集的样子:# Training settrain_cat = process_folder(folder=pathlib.Path.cwd().joinpath('data/train/cat'))train_dog = process_folder(folder=pathlib.Path.cwd().joinpath('data/train/dog'))train_set = pd.concat([train_cat, train_dog], axis=0)with open('train_set.pkl', 'wb') as f:   pickle.dump(train_set, f)# Test settest_cat = process_folder(folder=pathlib.Path.cwd().joinpath('data/test/cat'))test_dog = process_folder(folder=pathlib.Path.cwd().joinpath('data/test/dog'))test_set = pd.concat([test_cat, test_dog], axis=0)with open('test_set.pkl', 'wb') as f:   pickle.dump(test_set, f)# Validation set valid_cat = process_folder(folder=pathlib.Path.cwd().joinpath('data/validation/cat'))valid_dog = process_folder(folder=pathlib.Path.cwd().joinpath('data/validation/dog'))valid_set = pd.concat([valid_cat, valid_dog], axis=0)with open('valid_set.pkl', 'wb') as f:   pickle.dump(valid_set, f)图8——训练集数据集包含所有猫的图像,然后是所有狗的图像。这对于训练集和验证集来说并不理想,因为神经网络会按照这个顺序看到它们。你可以使用Scikit Learn中的随机函数来随机排序:train_set = shuffle(train_set).reset_index(drop=True)valid_set = shuffle(valid_set).reset_index(drop=True)下面是它现在的样子:图9——随机后的训练集下一步是将特征与目标分离。我们将对所有三个子集进行拆分:X_train = train_set.drop('class', axis=1)y_train = train_set['class']X_valid = valid_set.drop('class', axis=1)y_valid = valid_set['class']X_test = test_set.drop('class', axis=1)y_test = test_set['class']最后,使用数字编码目标变量。有两个不同的类(cat和dog),因此每个实例的目标变量应该包含两个元素。例如,使用factorize函数进行编码:y_train.factorize()图10-factorize函数标签被转换成整数——猫为0,狗为1。你可以使用TensorFlow中的to_category函数,并传入factorize后的数组,以及不同类的数量(2):y_train = tf.keras.utils.to_categorical(y_train.factorize()[0], num_classes=2)y_valid = tf.keras.utils.to_categorical(y_valid.factorize()[0], num_classes=2)y_test = tf.keras.utils.to_categorical(y_test.factorize()[0], num_classes=2)因此,y_train现在看起来是这样的:图11——目标变量从概率的角度考虑——第一张图片有100%的几率是猫,0%的几率是狗。这些都是真实的标签,所以概率可以是0或1。我们现在终于有了训练神经网络模型所需的一切。用人工神经网络(ANN)训练图像分类模型我随机选择了层的数量和每层的节点数量,以下2部分不能更改:· 输出层——它需要两个节点,因为我们有两个不同的类。我们不能再使用sigmoid激活函数了,所以选择softmax。· 损失函数——我们使用分类交叉熵。其他部分可以随意更改:以下是我在100个epoch后得到的结果:图12:100个epoch后的ANN结果60%的准确率比猜测稍微好一点,但性能一般。尽管如此,我们还是来检查一下训练期间指标发生了什么变化。以下代码片段绘制了100个epoch中每个epoch的训练损失与验证损失:plt.plot(np.arange(1, 101), history.history['loss'], label='Training Loss')plt.plot(np.arange(1, 101), history.history['val_loss'], label='Validation Loss')plt.title('Training vs. Validation Loss', size=20)plt.xlabel('Epoch', size=14)plt.legend();图13:训练损失与验证损失该模型能很好地学习训练数据,但不能推广。随着我们对模型进行更多epoch的训练,验证损失继续增加,这表明模型不稳定且不可用。让我们看看准确度:plt.plot(np.arange(1, 101), history.history['accuracy'], label='Training Accuracy')plt.plot(np.arange(1, 101), history.history['val_accuracy'], label='Validation Accuracy')plt.title('Training vs. Validation Accuracy', size=20)plt.xlabel('Epoch', size=14)plt.legend();图14:训练准确度与验证准确度类似的图片。验证精度稳定在60%左右,而模型对训练数据的拟合度过高。对于一个包含20K训练图像的两类数据集,60%的准确率几乎是它所能达到的最差水平。原因很简单——Dense层的设计并不是为了捕捉二维图像数据的复杂性。结论现在你知道了——如何用人工神经网络训练一个图像分类模型,以及为什么你不应该这么做。这就像穿着人字拖爬山——也许你能做到,但最好不要。       原文标题 : 人工神经网络训练图像分类器
  • [行业资讯] 行业应用加速落地 5G+AI催化物联网蝶变
    新冠肺炎疫情防控期间,数字技术与线上经济以前所未有的广度和深度向全社会渗透。物联网作为将物理世界映射到数字世界的桥梁,正在从万物互联向万物智联迈进,在社会经济的数字化、智能化转型中扮演着越来越重要的角色。据工业和信息化部运行监测协调局统计,截至今年3月末,国内三家基础电信企业发展蜂窝物联网终端用户15.2亿户,规模快速接近移动电话用户。大体量的用户基数、丰富多样的应用场景,加上5G规模化商用部署、人工智能加速普及产生的叠加效应,我国物联网进入快速发展阶段。IDC报告预测,中国物联网IP连接量将在2025年达到102.7亿,占到亚太(除日本)总连接量的84%。中国企业紧抓数字经济与5G物联网的广阔机遇,面向智慧农业、多媒体、智慧办公、智慧健康、智慧物流等场景推出产品和服务,在助力国内各行各业数字化转型升级的同时,加快融入全球市场。《2022高通物联网创新应用蓝宝书》详细呈现了高通通过多样、领先的连接、计算、物联网等解决方案,支持国内厂商加速出海之路。5G+AI催化物联网蝶变物联网的存在,能有效采集千行百业的数据,并推动数据向结构化、精细化转变,从而促进数字经济与实体经济的融合发展。要充分发挥物联网在数字经济的信息基础设施作用,需要提升物联网的连接能力和处理能力,使之容纳更多终端、更高效地处理数据并覆盖更多场景。5G的高带宽、低时延,正在推动物联网从窄带物联网向大带宽物联网发展,支持100MB/秒的数据传输速度。5G的海量连接特性,可以做到一平方公里支持一百万个传感器联网,大大扩展了物联网的应用。而终端侧和边缘侧的人工智能,加速了数据的采集速度和处理效率,使物联网终端能够实现自动识别、自动跟随、实时导引等丰富多样的智能化功能。中国工程院院士邬贺铨指出,5G的高带宽、低时延打通了数据从采集到决策的全过程,将物联网与云计算、人工智能无缝融合。同时,人工智能芯片与操作系统可以直接嵌入5G物联网模块构成AIoT终端。所以5G物联网不仅是物联网的一种连接方式,5G内生的一些特点也赋能了物联网升级。作为无线技术供应商,高通在物联网、无线通信技术、AI领域有着长期的技术积累。在物联网方面,高通推出了专用的调制解调器、处理器、SoC和解决方案。在无线通信技术方面,高通提供了从支持蜂窝网络、广域网无线技术的调制解调器到射频前端的完整解决方案;在AI方面,高通将AI引擎引入了移动芯片和物联网专业芯片产品。同样值得注意的是,随着物联网向智慧医疗、家庭医疗、直播、办公等场景延伸,需要处理的已不仅仅是物与物的通信,也要满足用户握持、操作终端设备的需求,这就意味着终端要更加小巧轻便、易于部署。如在智慧办公领域,钉钉视频会议系统推出了集音箱、摄像、麦克风于一体的F2视频会议一体机,具备10米内的高音质和高清画面覆盖及智能化功能,在保证会议室与用户终端体验一致的同时,免去了繁琐的布线。F2一体机能够将诸多功能all in one,离不开高通集成了DSP(数字信号处理器)、图像处理及编解码、NPU等芯片的物联网处理器。基于DSP,F2视频会议一体机实现了高速率、全方位的音频捕捉以及抗混响、远距离拾音放音等能力。芯片的图像处理和编解码能力,使F2一体机能够支持最高4K、120帧/秒的视频处理。NPU带来的AI算力,支撑了自动取景、发言人跟踪、多画面自动导播等高阶功能,使与会者具备更好的会议参与感及被关注感。终端产品的简单易用,需要建立在芯片系统的高度集成上。高通多款用于物联网解决方案的移动芯片平台和物联网芯片,都将核心处理器、音视频信号处理、AI引擎、调制解调器等元器件集成到同一芯片平台,并采用高度集成的封装,以降低终端产品设计的复杂性,加快产品的研发上市。行业应用驱动数字经济行业应用是物联网发展的主要驱动力之一,物联网新型基础设施的规模化部署需要与千行百业紧密结合。工业和信息化部等八部门印发的《物联网新型基础设施建设三年行动计划(2021—2023年)》在社会治理、行业应用、民生消费三大领域重点推进12个行业的物联网部署,推进物联网与农业、制造业、建造业、生态环保、文旅等产业深度融合,促进产业提质增效。数字经济倍增作用的标志之一,是将倚重人力的传统行业转向信息化、数字化的运营模式。农业是对人力依赖性较强的传统行业之一,存在智能化、精细化不足的问题,因而容易受到有害生物和气候的影响。在卢森堡,芯讯通与Frontier Connect推出的“室外农田IoT物联网监测系统”,正在通过光学相机、图像控制器、紫外线传感器、智能仪表等传感设备,实时生成温湿度、光照时长、土壤PH值等影响作物生长的因素,以及水泵压力、灌溉时间等设备状态数据。在这套系统中,基于骁龙X55 5G调制解调器及射频系统研发的5G模组,保证了传感设备之间以及传感设备、监测终端、云端、显示终端之间的实时数据传输,让农业从业者可以通过手机、平板等终端随时访问农田数据,获取作物产量和质量的估算和预测。优化资源配置是数字经济“普惠性”的重要体现,医疗等存在资源配置不均的产业,尤其需要数字技术提升全流程的效率和体验。通过信息技术提升医护人员的整体工作效率,是满足民众日益增长的医护需求的有效方式。比如在最常见的输液场景中,如果人工核对药剂和病患,不仅效率有限还有出错的风险。东集推出的5G智慧医疗终端“小码哥Cruise2 5G-HC”,让医护人员能够利用这款轻薄易握的PDA数据采集器扫描输液袋上的条码呼叫病人,也能扫描病人的手持标签确认其身份,既提升了工作效率,也通过双向比对更好地保障用药安全。该终端内置骁龙690 5G移动平台,集成了骁龙X51 5G调制解调器,利用5G网络低至毫秒级的时延,大幅提升了数据的采集、识别速度,在提升医护人员工作效率的同时提升患者的就诊体验。在数字经济时代,数字技术对于文化消费的重塑,正在为消费升级和新的消费增长点培育注入动能。2021年,中央广播电视总台基于“5G+4K/8K+AI”技术矩阵,在东京奥运会报道中实现了全球首次4K超高清频道的奥运赛事直播,通过总台全媒体平台收看人次达479亿次。传统直播方式依赖卫星转播车等大型设备,在极端天气下时常遭遇信号中断等问题,且由于运输不便,在应对突发场景时存在局限。在5G时代,传媒和直播等产业的响应速度和制播效率有了新的可能。为此,移远通信与TVU Networks推出了5G直播背包及5G多网聚合路由器。5G的高速率、低时延和广连接能力,不仅大幅提升了新闻直播的数据采集、远端制作、远程传输能力和效率,还为广大观众带来4K/8K甚至VR级的视觉体验。这套TVU One 5G直播产品搭载了基于骁龙X55 5G调制解调器及射频系统的5G模组。信息显示,TVU One 5G直播包在实际超高清视频直播中的时延可低至0.5秒。高通对于全球蜂窝网和射频主要频段与传输方式的支持,也为国内企业开拓全球市场提供了便利。比如骁龙X55 5G调制解调器支持5G毫米波和6GHz以下频段,高通 9205芯片平台支持海外主流的物联网无线通信技术eMTC,使国内企业在进军海外市场的过程中避免了场测、认证等障碍,提升全球服务能力。
  • [其他] 浅学人工神经网络(Artificial Neural Network,ANN )
    人工神经网络(Artificial Neural Network,即ANN ),是20世纪80 年代以来人工智能领域兴起的研究热点。它从信息处理角度对人脑神经元网络进行抽象, 建立某种简单模型,按不同的连接方式组成不同的网络。在工程与学术界也常直接简称为神经网络或类神经网络。神经网络是一种运算模型,由大量的节点(或称神经元)之间相互联接构成。每个节点代表一种特定的输出函数,称为激励函数(activation function)。每两个节点间的连接都代表一个对于通过该连接信号的加权值,称之为权重,这相当于人工神经网络的记忆。网络的输出则依网络的连接方式,权重值和激励函数的不同而不同。而网络自身通常都是对自然界某种算法或者函数的逼近,也可能是对一种逻辑策略的表达。人工神经网络是由大量处理单元互联组成的非线性、自适应信息处理系统。它是在现代神经科学研究成果的基础上提出的,试图通过模拟大脑神经网络处理、记忆信息的方式进行信息处理。人工神经网络具有四个基本特征:(1)非线性 非线性关系是自然界的普遍特性。大脑的智慧就是一种非线性现象。人工神经元处于激活或抑制二种不同的状态,这种行为在数学上表现为一种非线性关系。具有阈值的神经元构成的网络具有更好的性能,可以提高容错性和存储容量。(2)非局限性 一个神经网络通常由多个神经元广泛连接而成。一个系统的整体行为不仅取决于单个神经元的特征,而且可能主要由单元之间的相互作用、相互连接所决定。通过单元之间的大量连接模拟大脑的非局限性。联想记忆是非局限性的典型例子。(3)非常定性 人工神经网络具有自适应、自组织、自学习能力。神经网络不但处理的信息可以有各种变化,而且在处理信息的同时,非线性动力系统本身也在不断变化。经常采用迭代过程描写动力系统的演化过程。(4)非凸性 一个系统的演化方向,在一定条件下将取决于某个特定的状态函数。例如能量函数,它的极值相应于系统比较稳定的状态。非凸性是指这种函数有多个极值,故系统具有多个较稳定的平衡态,这将导致系统演化的多样性。人工神经网络中,神经元处理单元可表示不同的对象,例如特征、字母、概念,或者一些有意义的抽象模式。网络中处理单元的类型分为三类:输入单元、输出单元和隐单元。输入单元接受外部世界的信号与数据;输出单元实现系统处理结果的输出;隐单元是处在输入和输出单元之间,不能由系统外部观察的单元。神经元间的连接权值反映了单元间的连接强度,信息的表示和处理体现在网络处理单元的连接关系中。人工神经网络是一种非程序化、适应性、大脑风格的信息处理 ,其本质是通过网络的变换和动力学行为得到一种并行分布式的信息处理功能,并在不同程度和层次上模仿人脑神经系统的信息处理功能。它是涉及神经科学、思维科学、人工智能、计算机科学等多个领域的交叉学科。人工神经网络是并行分布式系统,采用了与传统人工智能和信息处理技术完全不同的机理,克服了传统的基于逻辑符号的人工智能在处理直觉、非结构化信息方面的缺陷,具有自适应、自组织和实时学习的特点。人工神经网络模型主要考虑网络连接的拓扑结构、神经元的特征、学习规则等。目前,已有近40种神经网络模型,其中有反传网络、感知器、自组织映射、Hopfield网络、波耳兹曼机、适应谐振理论等。根据连接的拓扑结构,神经网络模型可以分为:前向网络网络中各个神经元接受前一级的输入,并输出到下一级,网络中没有反馈,可以用一个有向无环路图表示。这种网络实现信号从输入空间到输出空间的变换,它的信息处理能力来自于简单非线性函数的多次复合。网络结构简单,易于实现。反传网络是一种典型的前向网络。 反馈网络网络内神经元间有反馈,可以用一个无向的完备图表示。这种神经网络的信息处理是状态的变换,可以用动力学系统理论处理。系统的稳定性与联想记忆功能有密切关系。Hopfield网络、波耳兹曼机均属于这种类型。
  • [前沿分享] 【课程作业经验】【NeRF】基于Mindspore的NeRF实现
    ## 一、NeRF介绍 ### 1. 背景 传统计算机图形学技术经过几十年发展,主要技术路线已经相对稳定。随着深度学习技术的发展,新兴的神经渲染技术给计算机图形学带来了新的机遇,受到了学界和工业界的广泛关注。**神经渲染**是深度网络合成图像的各类方法的总称,各类神经渲染的目标是实现图形渲染中建模和渲染的全部或部分的功能,基于**神经辐射场**(Neural Radiance Field, **NeRF**)的场景三维重建是近期神经渲染的热点方向,目标是使用神经网络实现新视角下的2D图像生成,在20和21年的CVPR、NeuIPS等各大AI顶会上,我们可以看到几十、上百篇相关的高水平论文。 ### 2. 网络结构 NeRF使用多层感知机(Multilayer Perceptron,**MLP**)来重建三维场景,也就是去拟合空间点的颜色分布和光密度分布的函数。NeRF的网络结构如图1所示,网络的输入是采样点对应的空间坐标和视角,输出是采样点对应的密度和RGB值。 由于颜色$\boldsymbol{c}$和光密度$\sigma$在空间中并不是平滑的,变化是比较剧烈的,这意味着函数存在很多高频的部分,让模型去表示这种函数比较困难,所以NeRF通过**positional encoding**,对输入的$\boldsymbol{r},\boldsymbol{d}$进行编码、升维,从而能够让模型更好地学出场景的一些细节部分,具体映射方式如下所示,该映射将标量$p$映射成一个$2L+1$维的向量: $$ \boldsymbol{\gamma}(p)=\left[p,\sin(2^0\pi p),\cos(2^0\pi p),\cdots,\sin(2^{L-1}\pi p), \cos(2^{L-1}\pi p)\right] $$ NeRF采用的MLP完整架构如下图所示: ![MLP](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/28/1656399813915919437.png) ### 3. 光线步进法 NeRF使用MLP隐式重建三维场景时的输入是采样点的位姿,NeRF的目标是实现2D新视角图像生成,那么要怎么得到采样点的位姿,又怎么使用重建得到的3D密度和颜色呢,得到新视角下的2D图像? 为了处理这两个问题,NeRF使用了**光线步进**(Ray Marching)这一经典方法,设$\boldsymbol{o}$代表相机原点$O_c$在世界坐标系中的位置,$\boldsymbol{d}$代表射线的单位方向矢量,$t$代表从$O_c$出发,沿射线方向行进的距离。使用光线步进法时,2D图像的每个像素对应于一条射线,每条射线上的任意位置可以表示为$\boldsymbol{r}(t)=\boldsymbol{o}+t\boldsymbol{d}$,对这些射线进行采样(具体使用下文介绍的**随机采样**和**重要性采样**)即可得到采样点的位姿,对这些射线上的采样点进行积分(具体使用下文介绍的**体绘制方法**)即可得到2D像素的RGB值。 ![rays](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/28/1656399831300545626.png) ### 4. 随机采样和重要性采样 NeRF使用随机采样和重要性采样结合的方式在光线步进法生成的射线上进行采样,这是因为空间中的物体分布是稀疏的,一条射线上可能只有很小的一段区域是对最终渲染起作用的,如果用均匀采样会浪费很多采样点,网络也难以学到整个连续空间中的分布,所以采用**coarse to fine**的思想,构建粗采样网络和细采样网络可以更好的对空间进行采样。 **随机采样**:将射线从近场到远场的范围$[t_n,t_f]$均匀划分成$N_c$个区间,在每段区间内随机取一个点,将其空间坐标$\boldsymbol{r}$和空间视角$\boldsymbol{d}$输入**粗采样网络**,得到粗采样网络预测的该空间点的$RGB\sigma$。 **重要性采样**:粗采样网络的输出中包括一条射线上所有点的**权重**$w_i$(具体将在下一节解释),将其归一化后作为采样区间的**概率密度函数**PDF,按照概率密度函数随机采样$N_f$个点,与前面分段均匀采样的$N_c$个点合并后输入**细采样网络**。 NeRF将粗采样网络和细采样网络的渲染结果(2D像素点的RGB值),分别与ground truth计算均方误差,将两者之和作为总的loss,来同时训练两个网络。 ![sampling](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/28/1656399851221930914.png) ### 5. 体绘制原理 得到采样点的密度和RGB值之后,NeRF使用计算机图形学中经典的体绘制技术(Voulume rendering)将3D采样值渲染至2D平面,具体原理如下。 光在介质中的衰减满足以下微分方程: $$ dL=-L\cdot \sigma \cdot dt $$ 其中$L$为光强,$\sigma$为衰减系数,其解为: $$ L=L_0\cdot \exp(-\int{\sigma}dt) $$ 假设:1) 空间点的颜色$\boldsymbol{c}=[R,G,B]^T$和视线方向$\boldsymbol{d}$有关;2) 空间点的光密度$\sigma$和视线方向$\boldsymbol{d}$无关。因为观察到的物体颜色会受到观察视角的影响(比如金属反射面),而光密度是由物体材质所决定。这一点假设也体现在了NeRF的网络结构当中。 根据光在介质中的衰减方程和体绘制原理,对于一个像素,其渲染颜色为 $$ \boldsymbol{C}=\int_{t_{n}}^{t_{f}} T(t) \sigma(\boldsymbol{r}(t)) c(\boldsymbol{r}(t), \boldsymbol{d}) dt $$ 其中,$T(t)=\exp(-\int_{t_n}^{t}{\sigma(\boldsymbol{r}(s))}ds)$代表$[t_n,t]$内的**累积透光率**,$\sigma(\boldsymbol{r}(t))dt$代表距离微元$dt$内的光强衰减率,等效为$\boldsymbol{r}(t)$处的**反射率**。 再对积分式进行离散化处理,使之适于计算机处理:沿着射线取$N$个点,在每个点$i$所代表的区间长度$\delta_i$内,$\sigma, \mathbf{c}$视作常数,得到渲染得到的2D像素RGB值表达式为 $$ \hat{C}(\mathbf{r})=\sum_{i=1}^{N}{T_i(1-\exp(-\sigma_i \delta_i))\mathbf{c_i}} $$ 其中,**累计透光率**为$T_i=\exp(-\sum_{j=1}^{i-1}\sigma_j \delta_j)$ 用体绘制处理得到的2D像素RGB值,可用于计算loss,也可用于生成最终的2D新视角图像。同时,也可以得到如下两个量: - $\alpha_i=1-\exp(-\sigma_i \delta_i)$,为第$i$个区间的**不透明度**。因此,$T_i=\prod_{j=1}^{i-1}{(1-\alpha_i)}$,为前$i-1$个区间的累积透明度; - $w_i=T_i\cdot \alpha_i$,为第$i$个点的颜色对渲染颜色的贡献度,也就是**权重**,可用于计算粗采样网络得到的PDF。 ### 6. NeRF的总体流程 综上所述,NeRF实现场景新视角合成的工作流程如下图所示。 1. 输入多视角图片(包括像素坐标、像素颜色),以及相机内参、位姿等数据; 2. 根据光线步进法产生射线,用随机采样和重要性采样得到空间采样点的坐标; 3. 将空间采样点的坐标以及射线的视角输入含有位置编码的NeRF,得到网络对于空间点$RGB\sigma$值的预测。 4. 根据空间点的$RGB\sigma$值,用体绘制原理,渲染出射线对应的二维像素点的$RGB$。 5. 将预测、渲染得到的像素点的$RGB$,与ground truth做MSE loss,训练神经网络。 ![workflow](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/28/1656399878480381442.png) ## 二、代码流程介绍 项目地址:等算子完善后发布 程序实现环境:mindspore1.6.1+CUDA11.1。 整体实验流程: ![steps](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/28/1656404684981651912.png) ### 1. 数据准备 NeRF的训练,除了对同一场景拍摄的多视角照片外,还需要相机的内参和每张照片的位姿。后者是无法通过直接测量得到的,因此需要使用一定的算法来获取。 COLMAP是一款通用的运动恢复结构 (SfM) 和多视图立体 (MVS) 软件,可用于点云重建。我们用COLMAP获取相机的内参和每张照片拍摄时的位姿,并根据3D特征点坐标,估计相机成像的深度范围,从而确定远、近平面,也就是边界。 操作步骤如下: 1. 安装COLMAP,官方地址:https://demuc.de/colmap/ 2. 打开软件。点击File---New project,导入照片文件夹images,并在其所在目录下创建一个`database`文件。 ![import](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/28/1656404657829157505.png) 3. 点击`Processing---Feature extraction`,提取照片中的特征点。 4. 点击`Processing---Feature matching`,完成特征点匹配。 5. 点击`Reconstruction---Start reconstruction`,完成稀疏重建。 6. 点击`Reconstruction---Dense reconstruction`,点击`Undistortion`,输出稀疏重建的结果,包括**相机内参、照片位姿、三维特征点信息**的二进制文件。 ![bins](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/28/1656404708727511052.png) COLMAP生成的数据为二进制文件,需要将数据重新保存成`npy`格式的文件`poses_bounds.npy`,便于后续数据的加载。操作步骤如下: 1. 运行`img2pose.py`文件,运行前需要配置形参为`dense`文件夹所在的目录。 ![gen_pose](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/28/1656404724944682770.png) 2. 运行后,在相应文件夹下生成`pose_bound.npy`文件,数据预处理任务完成。`pose_bound.npy`文件内容:包含相机的内参、每幅图像的位姿(从相机坐标系到世界坐标系的变换矩阵),以及根据照片中的三维特征点信息计算出的每幅照片的成像深度范围。 此外,原始的拍摄照片像素数太多,无法进行计算,需要事先对图片进行下采样,减少计算量,此处采用8倍降采样。 ### 2. 模型搭建 #### 2.1 主干网络模块 首先是主干模型的搭建。**模型输入**:空间三维坐标在位置编码后的高维向量;**模型输出**:相应三维坐标点处的 的预测值。模型的具体架构参考原理部分。 这里需要**注意模型权重的初始化**,它对训练时收敛的快慢影响很大。这里,采用权重和偏置都在$(-\sqrt{k},\sqrt{k})$内均匀分布,其中$k=1/\text{in-channels}$,实测这种初始化方式对于NeRF的收敛是有帮助的。 ```python class LinearReLU(nn.Cell): def __init__(self, in_channels, out_channels): super().__init__() self.linear_relu = nn.SequentialCell([ nn.Dense(in_channels, out_channels, weight_init=Uniform(-math.sqrt(1. / in_channels)), bias_init=Uniform(-math.sqrt(1. / in_channels))), nn.ReLU() ]) def construct(self, x): return self.linear_relu(x) class NeRF(nn.Cell): def __init__(self, D=8, W=256, input_ch=3, input_ch_views=3, skips=[4], use_viewdirs=False): super(NeRF, self).__init__() self.D = D self.W = W self.input_ch = input_ch self.input_ch_views = input_ch_views self.skips = skips self.use_viewdirs = use_viewdirs self.pts_layers = nn.SequentialCell( [LinearReLU(input_ch, W)] + [LinearReLU(W, W) if i not in self.skips else LinearReLU(W + input_ch, W) for i in range(D - 1)] ) self.feature_layer = LinearReLU(W, W) if use_viewdirs: self.views_layer = LinearReLU(input_ch_views + W, W // 2) else: self.output_layer = LinearReLU(W, W // 2) self.sigma_layer = nn.SequentialCell([ nn.Dense(W, 1, weight_init=Uniform(-math.sqrt(1. / W)), bias_init=Uniform(-math.sqrt(1. / W))) if use_viewdirs else nn.Dense(W // 2, 1, weight_init=Uniform(-math.sqrt(1. / (W // 2))), bias_init=Uniform(-math.sqrt(1. / (W // 2)))), ]) self.rgb_layer = nn.SequentialCell( nn.Dense(W // 2, 3, weight_init=Uniform(-math.sqrt(1. / (W // 2))), bias_init=Uniform(-math.sqrt(1. / (W // 2)))), nn.Sigmoid() ) def construct(self, x): pts, views = mnp.split(x, [self.input_ch], axis=-1) h = pts for i, l in enumerate(self.pts_layers): h = self.pts_layers<i>(h) if i in self.skips: h = mnp.concatenate([pts, h], -1) if self.use_viewdirs: sigma = self.sigma_layer(h) feature = self.feature_layer(h) h = mnp.concatenate([feature, views], -1) h = self.views_layer(h) rgb = self.rgb_layer(h) else: h = self.feature_layer(h) h = self.output_layer(h) sigma = self.sigma_layer(h) rgb = self.rgb_layer(h) outputs = mnp.concatenate([rgb, sigma], -1) return outputs ``` #### 2.2 位置编码模块 位置编码需要将输入的三维坐标映射到高维,因此需要构建一个由$\sin,\cos$函数构成的列表。对于每个输入,进行编码函数的遍历,将输出结果拼接成高维。 ```python class Embedder: def __init__(self, **kwargs): self.kwargs = kwargs self.create_embedding_fn() def create_embedding_fn(self): embed_fns = [] d = self.kwargs['input_dims'] out_dim = 0 if self.kwargs['include_input']: embed_fns.append(lambda x: x) out_dim += d max_freq = self.kwargs['max_freq_log2'] N_freqs = self.kwargs['num_freqs'] if self.kwargs['log_sampling']: pow = ops.Pow() freq_bands = pow(2., mnp.linspace(0., max_freq, N_freqs)) else: freq_bands = mnp.linspace(2. ** 0., 2. ** max_freq, N_freqs) for freq in freq_bands: for p_fn in self.kwargs['periodic_fns']: embed_fns.append(lambda x, p_fn=p_fn, freq=freq: p_fn(x * freq)) out_dim += d self.embed_fns = embed_fns self.out_dim = out_dim def embed(self, inputs): return mnp.concatenate([fn(inputs) for fn in self.embed_fns], -1) def get_embedder(L): embed_kwargs = { 'include_input': True, 'input_dims': 3, 'max_freq_log2': L - 1, 'num_freqs': L, 'log_sampling': True, 'periodic_fns': [mnp.sin, mnp.cos], } embedder_obj = Embedder(**embed_kwargs) embed = lambda x, eo=embedder_obj: eo.embed(x) return embed, embedder_obj.out_dim ``` #### 2.3 损失网络 NeRF涉及到两个网络loss的相加后作为总的loss,来优化两个网络。因此,需要用`NeRFWithLossCell`类,将前向网络与损失函数连接起来。其中,前向计算过程比较复杂,涉及**空间采样、位置编码、神经网络预测、体渲染**等步骤,而这些步骤在测试阶段同样需要用到,因此将其封装成一个函数`sample_and_render()`,只需输入射线信息`rays`、网络信息`net_kwargs`、训练/测试的参数设置`train_kwargs/test_kwargs`,就能输出射线所对应像素点的RGB的预测值。 类的属性包括优化器、网络信息,还有打印信息所需`psnr`。`psnr`也是一个损失函数,但它不是优化的目标,因此不能作为`construct`的输出,只能用属性的方式进行记录。 ```python class NeRFWithLossCell(nn.Cell): def __init__(self, optimizer, net_coarse, net_fine, embed_fn_pts, embed_fn_views): super(NeRFWithLossCell, self).__init__() self.optimizer = optimizer self.net_coarse = net_coarse self.net_fine = net_fine self.embed_fn_pts = embed_fn_pts self.embed_fn_views = embed_fn_views self.net_kwargs = { 'net_coarse': self.net_coarse, 'net_fine': self.net_fine, 'embed_fn_pts': self.embed_fn_pts, 'embed_fn_views': self.embed_fn_views } self.psnr = None def construct(self, H, W, K, rays_batch, rgb, chunk=1024 * 32, c2w=None, ndc=True, near=0., far=1., use_viewdirs=False, **kwargs): # 数据准备,获取射线的位置、方向、远近场、视角 rays = get_rays_info(H, W, K, rays_batch, c2w, ndc, near, far, use_viewdirs=True) # 采样+渲染 rets_coarse, rets_fine = sample_and_render(rays, **self.net_kwargs, **kwargs) # 计算loss loss_coarse = img2mse(rets_coarse['rgb_map'], rgb) loss_fine = img2mse(rets_fine['rgb_map'], rgb) loss = loss_coarse + loss_fine self.psnr = mse2psnr(loss_coarse) return loss ``` #### 2.4 训练网络 这个类是封装损失网络和优化器,用优化器单步更新网络参数。 ```python class NeRFTrainOneStepCell(nn.TrainOneStepCell): def __init__(self, network, optimizer): super(NeRFTrainOneStepCell, self).__init__(network, optimizer) self.grad = ops.GradOperation(get_by_list=True) self.optimizer = optimizer def construct(self, H, W, K, rays_batch, rgb, **kwargs): weights = self.weights loss = self.network(H, W, K, rays_batch, rgb, **kwargs) grads = self.grad(self.network, weights)(H, W, K, rays_batch, rgb, **kwargs) return F.depend(loss, self.optimizer(grads)) ``` ### 3. 采样 #### 3.1 粗采样 粗采样就是沿着射线进行分段均匀分布的随机采样。输入为射线和采样点数,以及其他参数配置,返回值为采样点的三维坐标`pts`、采样点在-z方向距离值`z_vals`,-z方向分段点`z_splits`。 ```python def sample_coarse(rays, N_samples, perturb=1., lindisp=False, pytest=False): N_rays = rays.shape[0] rays_o, rays_d = rays[:, 0:3], rays[:, 3:6] near, far = rays[..., 6:7], rays[..., 7:8] t_vals = mnp.linspace(0, 1, N_samples + 1) if not lindisp: z_splits = near * (1. - t_vals) + far * t_vals else: z_splits = 1. / (1. / near * (1. - t_vals) + 1. / far * t_vals) z_splits = mnp.broadcast_to(z_splits, (N_rays, N_samples + 1)) if perturb > 0.: upper = z_splits[..., 1:] lower = z_splits[..., :-1] t_rand = np.random.rand(*list(upper.shape)) if pytest: np.random.seed(0) t_rand = np.random.rand(*list(z_splits.shape)) t_rand = Tensor(t_rand, dtype=ms.float32) z_vals = lower + (upper - lower) * t_rand else: z_vals = .5 * (z_splits[..., 1:] + z_splits[..., :-1]) pts = rays_o[..., None, :] + rays_d[..., None, :] * z_vals[..., :, None] return pts, z_vals, z_splits ``` #### 3.2 细采样 细采样根据粗采样的得到的分段权重,将其作为概率密度函数进行采样,然后将采样结果和粗采样结果拼接,得到细采样输出。这里用`sample_pdf()`按照概率密度函数进行采样,其程序实现的主要步骤为: 1. 根据PDF,计算累积分布函数CDF,它将是一个分段线性函数。 2. 在[0, 1]内,对CDF值用均匀分布进行采样。 3. 将采样到的CDF值映射回坐标值。 其中,第3步需要用高维的`searchsorted`算子去寻找坐标值的索引,然而,目前MindSpore的`searchsorted`只支持1维输入,无法完成这一任务,暂时用pytorch的算子代替。 ```python def sample_pdf(bins, weights, N_samples, det=False, pytest=False): weights = weights + 1e-5 pdf = weights / mnp.sum(weights, -1, keepdims=True) cdf = mnp.cumsum(pdf, -1) cdf = mnp.concatenate([mnp.zeros_like(cdf[..., :1]), cdf], -1) if det: u = mnp.linspace(0., 1., N_samples) u = mnp.broadcast_to(u, tuple(cdf.shape[:-1]) + (N_samples,)) else: u = np.random.randn(*(list(cdf.shape[:-1]) + [N_samples])) u = Tensor(u, dtype=ms.float32) if pytest: np.random.seed(0) new_shape = list(cdf.shape[:-1]) + [N_samples] if det: u = np.linspace(0., 1., N_samples) u = np.broadcast_to(u, new_shape) else: u = np.random.rand(*new_shape) u = Tensor(u, dtype=ms.float32) cdf_tmp, u_tmp = torch.Tensor(cdf.asnumpy()), torch.Tensor(u.asnumpy()) inds = Tensor(torch.searchsorted(cdf_tmp, u_tmp, right=True).numpy()) below = ops.Cast()(mnp.stack([mnp.zeros_like(inds - 1), inds - 1], -1), ms.float32) below = ops.Cast()(below.max(axis=-1), ms.int32) above = ops.Cast()(mnp.stack([(cdf.shape[-1] - 1) * mnp.ones_like(inds), inds], -1), ms.float32) above = ops.Cast()(above.min(axis=-1), ms.int32) inds_g = mnp.stack([below, above], -1) matched_shape = (inds_g.shape[0], inds_g.shape[1], cdf.shape[-1]) cdf_g = ops.GatherD()(mnp.broadcast_to(cdf.expand_dims(1), matched_shape), 2, inds_g) bins_g = ops.GatherD()(mnp.broadcast_to(bins.expand_dims(1), matched_shape), 2, inds_g) denom = (cdf_g[..., 1] - cdf_g[..., 0]) denom = mnp.where(denom < 1e-5, mnp.ones_like(denom), denom) t = (u - cdf_g[..., 0]) / denom samples = bins_g[..., 0] + t * (bins_g[..., 1] - bins_g[..., 0]) return samples ``` ### 4. 射线获取 `get_rays()`完成的是根据照片尺寸$[H,W]$、相机内参矩阵$K$,相机位姿$c2w$,计算在世界坐标系下每个像素所对应的位置射线`rays_o`和方向射线`rays_d`。这里统一采用openGL坐标系,即$x$为向右、$y$为向上、$z$为向外。其中,`rays_d`统一按照-z方向,也就是拍摄照片时相机的朝向,进行归一化。因为在进行粗采样和细采样时,对于所有不同方向的射线,都是以-z方向上的距离为准进行采样的。 `get_rays_info()`是将射线的所有信息拼接成`rays`张量,便于后续调用,射线信息包括: 1. 位置向量rays_o; 2. 方向向量rays_d; 3. 近场near(体渲染时的积分下限); 4. 远场far(体渲染时的积分上限); 5. 单位化后的视角向量view_dir; ```python def get_rays(H, W, K, c2w): i, j = mnp.meshgrid(mnp.linspace(0, W - 1, W), mnp.linspace(0, H - 1, H), indexing='xy') dirs = mnp.stack([(i - K[0][2]) / K[0][0], -(j - K[1][2]) / K[1][1], -mnp.ones_like(i)], -1) c2w = Tensor(c2w) rays_d = mnp.sum(dirs[..., None, :] * c2w[:3, :3], -1) rays_o = ops.BroadcastTo(rays_d.shape)(c2w[:3, -1]) return rays_o, rays_d def get_rays_info(H, W, K, rays_batch=None, c2w=None, ndc=True, near=0, far=1, use_viewdirs=True): if c2w is not None: rays_o, rays_d = get_rays(H, W, K, c2w) else: rays_o, rays_d = rays_batch if use_viewdirs: viewdirs = rays_d viewdirs = viewdirs / mnp.norm(viewdirs, axis=-1, keepdims=True) viewdirs = mnp.reshape(viewdirs, [-1, 3]) if ndc: rays_o, rays_d = ndc_rays(H, W, K[0][0], 1., rays_o, rays_d) rays_o = mnp.reshape(rays_o, [-1, 3]) rays_d = mnp.reshape(rays_d, [-1, 3]) near, far = near * mnp.ones_like(rays_d[..., :1]), far * mnp.ones_like(rays_d[..., :1]) rays = mnp.concatenate([rays_o, rays_d, near, far], -1) if use_viewdirs: rays = mnp.concatenate([rays, viewdirs], -1) return rays ``` ### 5. 渲染 根据网络输出的空间采样点的$RGB\sigma$,用体渲染公式计算出射线对应二维像素点的RGB值。因此,本函数是NeRF前向计算的主体框架。其主要过程为: 1. 根据射线数据,进行粗采样。 2. 将粗采样得到的空间采样点坐标`pts_coarse`,和射线单位方向向量`views_coarse`拼接,输入粗采样网络。经过位置编码和神经网络前向计算,得到空间采样点$RGB\sigma$预测值`raw_coarse`。其中,`views_coarse`是`rays_d`的单位向量,消除了不同向量模长的影响。 3. 将`raw_coarse`输入体绘制函数`render()`,得到渲染后的返回值`ret_coarse`。它是一个字典,包括了渲染后的所有结果,其中包括粗采样点的权重`rets_coarse['weights']`。 4. 根据粗采样网络采样点的权重,以及采样分段区间,进行细采样。 5. 将细采样得到的空间采样点坐标`pts_fine`,和射线单位方向向量`views_fine`拼接,输入细采样网络。经过位置编码和神经网络前向计算,得到空间采样点$RGB\sigma$预测值`raw_fine`。 6. 将`raw_fine`输入体绘制函数`render()`,得到渲染后的返回值`ret_fine`,它同样包括了渲染后的所有结果。 7. 返回粗采样网络和细采样网络渲染后的返回值`rets_coarse`,`rets_fine`。 ```python def sample_and_render(rays, net_coarse=None, net_fine=None, embed_fn_pts=None, embed_fn_views=None, N_coarse=64, N_fine=64, perturb=1., lindisp=False, pytest=False, raw_noise_std=0., white_bkgd=False): # 数据准备 rays_d = rays[..., 3: 6] views = rays[:, -3:] if rays.shape[-1] > 8 else None # 粗采样 pts_coarse, z_coarse, z_splits = sample_coarse(rays, N_coarse, perturb, lindisp, pytest) views_coarse = mnp.broadcast_to(views[..., None, :], pts_coarse.shape) sh = pts_coarse.shape # 粗采样网络的positional encoding pts_embeded_coarse = embed_fn_pts(pts_coarse.reshape([-1, 3])) views_coarse_embeded = embed_fn_views(views_coarse.reshape([-1, 3])) # 输入粗采样网络 + 渲染 得到输出 net_coarse_input = mnp.concatenate([pts_embeded_coarse, views_coarse_embeded], -1) raw_coarse = net_coarse(net_coarse_input).reshape(list(sh[:-1]) + [4]) rets_coarse = render(raw_coarse, z_coarse, rays_d, raw_noise_std, white_bkgd, pytest) # 细采样 weights = rets_coarse['weights'] pts_fine, z_fine = sample_fine(rays, z_coarse, z_splits, weights, N_fine, perturb, pytest) views_fine = mnp.broadcast_to(views[..., None, :], pts_fine.shape) sh = pts_fine.shape # 细采样网络的positional encoding pts_embeded_fine = embed_fn_pts(pts_fine.reshape([-1, 3])) views_embeded_fine = embed_fn_views(views_fine.reshape([-1, 3])) # 输入细采样网络 + 渲染 得到输出 net_fine_input = mnp.concatenate([pts_embeded_fine, views_embeded_fine], -1) raw_fine = net_fine(net_fine_input).reshape(list(sh[:-1]) + [4]) rets_fine = render(raw_fine, z_fine, rays_d, raw_noise_std, white_bkgd, pytest) return rets_coarse, rets_fine ``` ### 6. 主函数 main函数的任务如下: 1. 加载图片和位姿、内参等数据,将其分成一个一个batch并打乱; 2. 用`create_nerf()`,创建一个NeRF模型,返回值包括:各网络实例构成的字典`net_kwargs`,训练参数`train_kwargs`,测试参数`test_kwargs`,优化器`optimizer`。 3. 构建损失网络`net_with_loss`,并加载之前保存的训练参数。 4. 构建训练网络`train_net`。 5. 迭代优化`train_net`。 6. 保存训练时参数,保存渲染视频。 训练时调用训练网络: ```python train_net(H, W, K, batch_rays, target_s, **train_kwargs) ``` ## 三、参考资料 [1] Mildenhall, B., Srinivasan, P.P., Tancik, M., Barron, J.T., Ramamoorthi, R., Ng, R. (2020). NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis. In: Vedaldi, A., Bischof, H., Brox, T., Frahm, JM. (eds) Computer Vision – ECCV 2020. ECCV 2020. [2] NeRF论文的官方实现: https://github.com/bmild/nerf [3] NeRF的Pytorch实现:https://github.com/yenchenlin/nerf-pytorch [4] MindSpore 1.6 API:https://www.mindspore.cn/docs/api/zh-CN/r1.6/index.html
  • [AI家园] 边缘人工智能的梦想与挑战
    人工智能正在进一步进入我们的日常生活,但重点主要集中在“大型机器”上,例如自动驾驶汽车。 也许现在也是“小机器”人工智能革命的时候了。在本文中,我们主要探讨两个主要问题,即在“小型机器”中实现人工智能的理由,以及开发人工智能小型机器将面临哪些挑战?未来,在人工智能方面,我们应该有飞行汽车和机器人管家。甚至还可能遇到有感知能力的机器人决定起来反抗我们。虽然我们还没有发展到这种程度,但显然人工智能(AI)技术已经进入了我们的世界。每次当我们让智能语音助手做一件事是,机器学习技术就会先搞明白你说了什么,并试图对你想让它做什么做出最好的决定。例如,每次视频网站或电商平台向你推荐“你可能喜欢的电影”或“你可能需要的商品”时,它都是基于复杂的机器学习算法,尽可能地向你提供具有说服力的建议,这显然比过去的促销活动更有吸引力。虽然我们可能不是所有人都有自动驾驶汽车,但我们敏锐地意识到这一领域的发展以及自动导航提供的潜力。人工智能技术承载着一个伟大的希望——机器可以根据周围的世界做出决定,像人类一样处理信息,甚至以一种优于人类的方式。但如果我们考虑一下上面的例子,就会发现只有“大型机器”才能实现人工智能的承诺,这些设备往往没有功率、尺寸或成本的限制。或者换句话说,它们会发热,有线路供电,体积很大,而且很昂贵。例如,Alexa 和 Netflix 这些全球领先的IT巨头企业依靠云中的大型耗电服务器(数据中心)来推断用户的意图。虽然自动驾驶汽车很可能依赖电池,但考虑到这些电池必须转动车轮和转向,它们的能量容量是巨大的。与最昂贵的人工智能决策相比,它们是巨大的能源支出。因此,尽管人工智能前景广阔,但“小机器”却被抛在了后面 。由较小电池供电或具有成本和尺寸限制的设备无法参与机器可以看到和听到的想法。今天,这些小机器只能利用简单的人工智能技术,也许是听一个关键词,或者从心率分析低维信号,如光电体积描记术 (PPG)。如果小机器能看能听会怎样?但是,小型机器能够看到和听到是否有价值?可能很多人很难想象像门铃摄像头这样利用自动驾驶或自然语言处理等技术的小设备。尽管如此,诸如词汇识别、语音识别和图像分析之类的不太复杂、处理密集程度较低的 AI 计算仍然存在机会:门铃摄像头和消费级安全摄像头通常会触发一些无趣的事件,例如风引起的植物运动、云引起的剧烈光线变化,甚至是狗或猫在镜头前面动等事件。这可能导致错误警报触发,导致房主开始忽略掉一些重要事件。因为,房主可能在世界不同的地方旅行,也可能正在睡觉,而他们的安全摄像机却对日出、云和日落引起的照明变化频繁发出警报。而更智能的摄像机则可以更加精准是识别物体变化,如人体的轮廓,进而避免误报干扰。门锁或其他接入点可以使用面部识别甚至语音识别来验证人员访问权限,在很多情况下无需钥匙或IC卡。许多摄像头希望在某些事件上触发:例如,跟踪摄像头可能希望在画面中出现某一种动物时触发,安全摄像头可能希望在画面中出现人或开门或脚步声等噪音时触发,并且有些摄像机可能想要通过语音命令触发等等。大词汇量命令在许多应用中都很有用。虽然有很多类似 “Hey Alexa”、“Hey Siri” 解决方案,但如果开始考虑 20 个或更多单词的词汇,则可以在工业设备、家庭自动化、烹饪用具和许多其他设备中找到用于简化人机交互的用途。这些例子只是表面上的。让小型机器看到、听到和解决以前需要人工干预的问题的想法是一个强大的想法,我们每天都在继续寻找创造性的新用例。让小型机器能看和听的挑战是什么?那么,如果人工智能对小型机器如此有价值,为什么我们还没有广泛应用呢?答案是计算能力。人工智能推理是神经网络模型计算的结果。把神经网络模型想象成你的大脑如何处理图片或声音的一个粗略的近似,把它分解成非常小的片段,然后当这些小片段组合在一起时识别出模式。现代视觉问题的主力模型是卷积神经网络 (CNN)。这些模型在图像分析方面非常出色,在音频分析中也非常有用。挑战在于此类模型需要数百万或数十亿次数学计算。传统上,这些应用很难选择实施:使用廉价且低功耗的微控制器解决方案。虽然平均功耗可能很低,但 CNN 可能需要几秒钟的时间来计算,这意味着 AI 推理不是实时的,因此会消耗大量电池电量。购买可以在所需延迟内完成这些数学运算的昂贵且高性能的处理器。这些处理器通常很大,需要大量外部组件,包括散热器或类似的冷却组件。但是,它们执行 AI 推理的速度非常快。无法实施。低功耗微控制器解决方案将太慢而无法使用,而高性能处理器方法将打破成本、尺寸和功率预算。我们需要的是一种嵌入式的人工智能解决方案,从头开始构建,以最大限度地减少CNN计算的能源消耗。与传统的微控制器或处理器解决方案相比,AI推断需要在一个数量级上执行,并且不需要内存等外部组件的帮助,这些外部组件会消耗能量、体积和成本。如果人工智能推理解决方案可以消除机器视觉的能量损失,那么即使是最小的设备也可以看到并识别周围世界发生的事情。幸运的是,我们正处于这场“小机器”革命的开端。现在的产品几乎可以消除人工智能推断的能源成本,并实现电池驱动的机器视觉。例如,一个微控制器可用于执行 AI 推理,同时仅消耗微焦耳的能量。责任编辑:庞桂玉    来源: 千家网
  • [其他] 华为诺亚实验室的研究员发现图神经网络(GNN)
    华为诺亚实验室的研究员发现图神经网络(GNN)也能做视觉骨干网络。将图像表示为图结构,通过简洁高效的适配,提出一种新型视觉网络架构 ViG,表现优于传统的卷积网络和 Transformer。在 ImageNet 图像识别任务,ViG 在相似计算量情况下 Top-1 正确率达 82.1%,高于 ResNet 和 Swin Transformer。论文链接:https://arxiv.org/abs/2206.00272PyTorch 代码:https://github.com/huawei-noah/CV-BackbonesMindSpore 代码:https://gitee.com/mindspore/models/tree/master/research/cv/ViG在计算机视觉领域,骨干网络一直是特征提取的重要部件。从 AlexNet 到 ResNet,卷积网络 CNN 在很长一段时间内一直是视觉任务的标配。近年来,基于注意力机制的 Transformer 和以全连接层为主的 MLP 网络也开始在计算机视觉领域崭露头角。与现有主流 CNN 模型相比,基于 Transformer 或 MLP 的模型在视觉任务上也显示出了良好的性能。直到现在,关于谁是更好的视觉骨干网络还是一个仍在探索和颇具争议的课题。 传统的卷积网络将图像视作一个矩阵或网格,通过滑动窗口对邻域像素点或特征点进行聚合;视觉 Transformer 或 MLP 则是输入图片切分为若干个图像块,形成一个序列,用注意力机制或全连接层处理序列关系,如图 1 所示。网格或序列表示的方法,对于图像来说显得不够灵活。比如,一个人往往由头部、四肢和躯干构成,这些部位之间有一定连接关系,是一种非规则化的会变化的模式。 图 1:图像的 3 种表示方法。 为了更好地对图像进行表示,本文提出用图结构(Graph)来对图像进行解析。将图像切分成若干图像块,每个图像块视作一个节点来构建图结构。进而提出用图神经网络进行图像识别等任务,首次构建了视觉 GNN,简称 ViG,如下图 2 所示。 图 2:视觉图神经网络 ViG 架构。 直接使用原始 GNN 在图像任务会有过平滑的问题,也就是随着网络的加深,节点特征之间会越来越相似。为了缓解这个问题,ViG 引入前馈神经网络 FFN 模块来增强特征变换能力和特征多样性。通过基础的图卷积模块和 FFN 模块,作者构建了 isotropic 式和金字塔式的 ViG 网络架构。在 ImageNet 基准测试和下游任务上的实验表明了该方法在视觉任务方面的优越性。例如, Pyramid ViG-S 仅用 4.5G FLOPs 就达到了 82.1% 的 ImageNet top-1 正确率,这比计算量相近的 Swin Transformer 和 ResNet 都要高出不少。 转发自:https://www.jiqizhixin.com/articles/2022-06-26
  • [其他] 神经网络中重要的算法:反向传播BP(Back Propagation)
    在很久以前,人工神经网络面临一个重大的挑战:增加神经网络的层数虽然可为其提供更大的灵活性,让网络能有更强的表征能力,也就是说,能解决的问题更多,但随之而来的庞大网络参数训练,一直是制约多层神经网络发展的一个重要瓶颈。 说到BP算法,我们通常强调的是反向传播。其实在本质上,它是一个双向算法: (1)正向传播输入信息,实现分类功能(所有的有监督学习,在本质都可以归属于分类); (2)反向传播误差,调整网络权值。 神经网络包含了前馈网络和反向传播两个主要过程。前者是多个函数的复合,如果你画出前馈神经网络的图结构,你会发现这个图结构形象地描述了函数的复合方式,最经典的是“链式结构”。而反向传播是目前用来训练神经网络的最常用并且也是最有效的方法。梯度下降因为基于反向传播的思想方法,而得以在神经网络训练过程中大施拳脚。 简化的说,反向传播是从错误出发层层究责的过程,究什么责?究那个部分导致最终训练结果误差的权重的责。究责是为了改正过失,这就是神经网络学习的本质——找到网络中神经元之间的最佳连接权值。换句话说,反向传播就是反向计算偏微分,将信息逆向从神经网络的高层向前层传播。 前向传播完毕后,我们得出了预测值,而这个输出结果与实际结果必然存在着误差。误差越大,说明模型越差,但是这种差可以改善。我们通过将误差转化规范成损失函数,通过训练模型将损失函数不断减小。怎么训练呢?你是否还记得梯度下降这个概念, 反向传播通过对链式函数构成的误差函数的梯度下降,在将这个误差从输出层向隐藏层传播的过程中,对每个权重进行更新,直至传播到输入层。 各个权重在不断迭代的反向传播过程中得以调整,直至收敛。 损失函数的最小化过程采取了对链式结构函数的梯度下降的求解,虽然计算深层的链式结构的梯度直接易懂,但是计算量很大,而反向传播有效地减小了梯度下降算法的计算量,我们也可以说反向传播是计算梯度的算法。
  • [其他] 联结主义人工智能的基本观点
    联结主义人工智能的基本观点是:人工智能必须能够模仿大脑的功能,更具体地强调机器应具有学习能力和认知能力,通过学习来解决问题。 联结主义人工能特指感知机、神经网络发展的机器学习,广泛意义上也可以包括强化学习以及其他机器学习方法。联结主义人工智能主要解决模式识别、聚类、分类、联想等非结构化同题。早在20世纪40年代,McCulloch和Walter开创了集成认知神经学、科学和数理逻辑计算的计算神经学,提出了最早的神经网络模型,给出了神经元的形式化数学描述和网络结构、证明了单个神经元能执行逻辑功能。 1958年,Frank将感知器建立在一个非线性神经元上,得到了神经元的Pitts模型。这是在计算机有限运算能力的条件下,基于硬件结构建立的第一个可进行模式识别的单层神经网络模型。但在此后的一段时间内,神经网络模型仍然无法测试,而且连比较基本的异或(XOR)的逻辑运算都不能实现,即便多层神经网络也不具有低复杂度,相关研究进人了长达20年的停滞状态。 1974年,哈佛大学的Paul首次提出误差反向传播算法,不仅解决了异或运算问题,而且大大提升了神经网络迭代计算效率。直到20世纪80年代,神经网络才再度迎来研究高潮。1982年,John提出了可用作联想存储器的互连网络模型,该模型是一种从输出到输人有反愦连接的循环神经网络。1986年,David等人在神经网络上应用了反向传播算法。1989年,Yann等人受日本学者福岛邦彦提出的仿生视觉皮层神经网络模型等的启发,构建了应用于计算机视觉问题的包含2个卷积层和2个全连接层的神经网络,正式提出了卷积神经网络,并于1998年构建更完备的卷积神经网络LeNet-5,成功用于解决手写识别问题。 2006年,Hinton等人发表文章,提出将预训练、自编码器与深度神经网络结合,开启了深度学习(深度神经网络)在学术界和工业界的研究与应用浪潮,相继在语音识别、图像识别等领域开展应用,显著降低了错误识别率。2011年后,深度学习开始将卷积层与最大池化层合并,并将其输出传递给几个全连接层,再传递给输出层。2013年4月,美国麻省理了学院(MIT)的《麻省理工科技评论》将深度学习列为2013年十大突破性技术之一。2014年,当时还在蒙特利尔大学读博上的Ian等人提出生成对抗网络溉念,使得神经网络系统不仅能够更好地生成图像与声音,还能识别它们,从而奠定了无监督自主学习算法框架的基础。2015年,谷歌DeepMind提出正式的Deep Q Networks系统。2016年,融合了深度学习、强化学习和蒙特卡罗树搜索方法的AlphaGo战胜了世界围棋高手李世石。这些研究让联结主义大放异彩,也是当前人工智能高潮形成的主因。 其他机器学习方向也在不断取得成果。早在1952年,IBM科学家Arthur开发了一个跳棋程序。该程序能够通过观察当前位置,并学习一个隐含的模型,为后续动作提供更好的指导。从1984年开始,Leo Breiman等人相继提出了适用于分类和连续输人(特征)/输出(预测)变量回归预测建模问题的决策树算法和多决策树组合的随机森林算法,后者属于集成学习范畴。1995年,由Corinna等人提出了支持向量机的溉念,通过Kernel的技巧将低维空间线性不可分或难分的样本数据点映射至高维空间使其线性可分,在解决小样本、非线性以及高维模式识别问题方面具有明显优势。
  • [其他] DepthShrinker:一种新的压缩范式,用于提高紧凑神经网络的实际硬件效率
    配备紧凑算子(如深度卷积)的高效深度神经网络(DNN)模型在降低DNN的理论复杂性(如权重/操作的总数)同时保持良好的模型精度方面显示出了巨大的潜力。然而,现有的高效DNN在提高实际硬件效率方面仍然有限,原因是其通常采用的紧凑算子的硬件利用率较低。在这项工作中,我们为开发真正硬件高效的DNN开辟了一种新的压缩范式,从而在保持模型准确性的同时提高硬件效率。有趣的是,我们观察到,虽然一些DNN层的激活函数有助于DNN的训练优化和达到精度,但训练后可以适当地去除它们,而不影响模型的精度。受此启发,提出了一种深度收缩框架DepthShrinker,通过将现有高效且具有不规则计算模式的深度神经网络的基本模块收缩为密集的基本模块,开发硬件友好的紧凑网络,大大提高了硬件利用率,从而提高了硬件效率。令人兴奋的是,我们的DepthShrinker框架提供了硬件友好的紧凑网络,性能优于最先进的高效DNN和压缩技术,例如,在特斯拉V100上比SOTA通道修剪方法MetaPruning更高3.06%的精度和1.53×吞吐量。我们的代码可以在https://github.com/RICEEIC/DepthShrinker上找到。
  • [其他] 图神经网络异常检测的再思考
    图神经网络(GNNs)在图异常检测中有着广泛的应用。由于谱滤波器的选择是GNN设计的关键之一,因此通过图谱分析异常是GNN设计的第一步。我们的关键观察是,异常的存在将导致“右移”现象,即频谱能量分布较少集中在低频,较多集中在高频。这一事实促使我们提出了Beta小波图神经网络(BWGNN)。事实上,BWGNN具有光谱和空间本地化带通滤波器,以更好地处理异常中的“右移”现象。在4个大规模异常检测数据集上验证了BWGNN的有效性。我们的代码和数据发布在https://github.com/squareRoot3/ Rethinking-Anomaly-Detection。
  • [其他] 深度神经网络中的特征学习与信号传播
    Baratin等人最近的工作(2021)揭示了深度神经网络训练期间发生的一个有趣的模式:与其他层相比,一些层与数据的对齐更多(其中对齐被定义为切线特征矩阵和数据标签矩阵的欧氏乘积)。对齐曲线作为层指数的函数(通常)表现出一种上升-下降模式,在某些隐藏层达到最大值。在这项工作中,我们为这一现象提供了第一种解释。我们引入平衡假设,将这种对齐模式与深度神经网络中的信号传播联系起来。我们的实验证明与理论预测非常吻合。https://www.zhuanzhi.ai/paper/eb536aebcbd07e082fa029bfa966c533
  • [其他] 深入探讨置换敏感图神经网络
    邻接矩阵排列的不变性,即图同构,是图神经网络(GNNs)的首要要求。通常,聚合消息时,节点排列上的不变操作可以满足这个前提条件。但是,这种不变性可能会忽略相邻节点之间的关系,从而影响GNN的表达能力。在这项工作中,我们通过排列组设计了一种高效的排列敏感聚合机制,捕获相邻节点之间的成对关联。我们证明了我们的方法严格地比二维Weisfeiler-Lehman (2-WL)图同构检验更强大,且不低于3-WL检验。此外,我们证明了我们的方法实现了线性抽样复杂度。在多个合成数据集和真实数据集上的综合实验证明了我们的模型的优越性。https://www.zhuanzhi.ai/paper/da818de2d710f7cb9087582587f6240f
  • [其他] 浅谈常见聚类算法
    K-means 聚类算法K-means 聚类算法 可能是大家最为熟悉的聚类算法。它在许多的工业级数据科学和机器学习课程中都有被讲解。并且容易理解和实现相应功能的代码 。    我们先确定要聚类的数量,并随机初始化它们各自的中心点。为了确定要聚类的数量,最好快速查看数据并尝试识别任何不同的分组。中心点是与每个数据点向量长度相同的向量,是上图中的“x”。通过计算当前点与每个组中心之间的距离,对每个数据点进行分类,然后归到与距离最近的中心的组中。基于迭代后的结果,计算每一类内,所有点的平均值,作为新簇中心。迭代重复这些步骤,或者直到组中心在迭代之间变化不大。您还可以选择随机初始化组中心几次,然后选择看起来提供最佳结果。Mean-Shift 聚类Mean-shift 聚类是一个基于滑窗的算法,尝试找到数据点密集的区域。它是一个基于质心的算法,也就是说他的目标是通过更新中心点候选者定位每个组或类的中心点,将中心点候选者更新为滑窗内点的均值。这些候选滑窗之后会在后处理阶段被过滤,来减少临近的重复点,最后形成了中心点的集合和他们对应的组。DBSCAN 笑脸聚类    DBSCAN 从一个任意的还没有被访问过的启动数据点开始。用一个距离 epsilon ε 将这个点的邻域提取出来(所有再距离 ε 内的点都视为邻居点)。如果在邻域内有足够数量的点(根据 minPoints) ,那么聚类过程开始,并且当前数据点变成新集群中的第一个点。否则,该点将被标记为噪声(之后这个噪声点可能会变成集群中的一部分)。在这两种情况中的点都被标记为”已访问“。对于这个新集群中的第一个点,在它 ε 距离邻域内的点已将变成相同集群中的一部分。这个让所有在 ε 邻域内的点都属于相同集群的过程在之后会一直被重复做,直到所有新点都被加进集群分组中。第 2,3 步的过程会一直重复直到集群内所有点都被确定,即所有在 ε 邻域内的点都被访问且被打上标签。我们在当前集群做完这些,一个新的未被访问的点会被提取并处理,从而会接着发现下一个集群或噪声。这个过程反复进行直到所有的点都被编辑为已访问。既然在最后所有的点都被访问,那么每个点都被标记为属于一个集群或者是噪声。基于高斯混合模型(GMM)的期望最大化(EM)聚类k-means的一个主要缺点是它简单地使用了集群中心的平均值。通过下面的图片,我们可以看到为什么这不是最好的方式。在左手边,人眼可以很明显地看到,有两个半径不同的圆形星团以相同的平均值为中心。k-means不能处理这个问题,因为不同簇的平均值非常接近。当簇不是圆形时,k均值也会失效,这也是将均值用作簇中心的后果。使用GMMs的EM聚类我们首先设定聚类簇的数量(如k-means),然后随机初始化每个集群的高斯分布参数。我们也可以通过快速查看数据来为初始参数提供一个很好的猜测。正如上图所示,这不是100%必要的,因为高斯操作开始时候是非常差的,但很快优化。给定每个簇的高斯分布,计算每个数据点属于特定簇的概率。一个点越靠近高斯中心,它就越可能属于该簇。这应该是直观的,因为对于高斯分布,我们假设大多数数据都靠近集群的中心。基于这些概率,我们为高斯分布计算了一组新的参数,这样我们就可以最大化群集中数据点的概率。我们使用数据点位置的加权和计算这些新参数,其中权重是属于特定集群的数据点的概率。为了以可视化的方式解释这一点,我们可以查看上面的图形,特别是以黄色集群为例。在第一次迭代中,分布是随机开始的,但是我们可以看到大多数黄点都在分布的右边。当我们计算一个由概率加权的和时,即使在中心附近有一些点,但大多数都在右边。因此,分布的平均值很自然地移近这些点集。我们还可以看到,大多数点是“从右上到左下”。因此,标准偏差会发生变化,以创建一个更适合这些点的椭圆,以便最大化概率加权的和。第2步和第3步重复进行,直到收敛,也就是在收敛过程中,迭代变化不大。凝聚层次聚类凝聚层次聚类算法实际上分为 2 类:自上而下或自下而上。自下而上算法在一开始将每个数据点当作一个单个集群对待,然后逐步的合并(或凝聚)成对的集群,直到所有的集群被合并到一个集群中,这个集群包含所有的点。自下而上层次聚类因此被叫做层次凝聚的聚类或者 HAC。这个聚类的层次被表示为一棵树(或者树状图)。树根是唯一的集群,他聚集了所有的样本,叶子是只有一个样本的集群。
总条数:936 到第
上滑加载中