泻药,利益相关:
常有人说“人生苦短,我用Python”,而当前人工智能领域中,Python语言的使用率也确实占比在逐年上升,现在它已经是最主流的语言了。
为什么会这样,根据我的认知,这与它免费和开源的策略有很大的关系,想做个什么事情,去Github上查一下,然后把各个项目的代码复制合并一下,就能跑起来,确实不负“胶水语言”之称。
免费开源生态提高了工作效率,促进了开发者们的交流,也保持了火热的社区氛围,但“自由”背后也藏着阴影。
比如我上个月下载了某篇论文作者给出的官方代码实现,但我花了超过5天时间调通所有代码。仅因作者使用conda导出的python虚拟环境存在问题这一项,我就不厌其烦进行debug,最后更新了scikit-learn/tqdm等常用包,梳理了CUDA及其依赖,重装了不下十次Pytorch和PyTorch Geometric框架,才终于搞定一开始就应该解决的环境依赖问题。我至今仍未想明白代码作者怎么在他提供的环境下跑通代码的。
说得有点偏了,其实我想说,开源生态确实好,但将来自各方面的东西聚合在一起会有很难预料的BUG出现,但处理这样的BUG是非常困难的。
而MATLAB这样的商业软件不一样,官方工具箱之间的依赖是很稳定的,而一旦遇到了问题,不仅可以查看官方详实的文档,也能连线工程师进行咨询。相较于免费生态,能够花钱找人解决大问题,或许就是付费用户的快乐吧。
在我认知范围内,MATLAB是一款能在绝大多数工业领域中进行仿真的软件。说起来轻飘飘,但要实现这一点背后有非常恐怖的技术积累。如果要做跨学科跨领域的学术研究或者工业实践,MATLAB可作为首选。
MATLAB有一个著名的优点就是:官方案例的种类全,质量高。现在强调多领域协作,但很少有人同时懂这么多方面,更难找到对应的资料或教程。但MATLAB不同,正因为它被用于多种场景,所以它恰好能提供很多交叉领域的高质量案例与文档。
虽然MATLAB家的教程用过都说好,但没用过的朋友可能会觉得光说不练没啥说服力,我在回答下个部分展示一下~
实验过程可以参考视频:
光说不练假把式,先实现一个demo吧。众所周知,MNIST数据集是一个手写数字的图像数据集,它在人工智能发展历史上算一个重要节点,现在很多图像分类算法也会使用它作为Toy Model展示性能。不过我想肯定会有其他知友介绍MNIST的例子,那不如我举一个我最近研究领域中有类似地位的研究对象吧~
在训练样本极少的情况下(几百个、几十个甚至几个样本),传统的机器学习和深度学习模型普遍无法取得良好的泛化性能,仅用小样本训练的模型很容易陷入对样本的过拟合以及对目标任务的欠拟合。
2015年,科学杂志上发布了贝叶斯规划学习[1](BPL,Bayesian Program Learning)一文,它对认知科学和机器学习涉及的三个比较重要的思想包括Compositionality(组合)、Causality(因果)和Learning to Learn(元学习)进行了验证,证实了它们在小样本学习应用中的重要性,为以后的研究提供了参考方向。这篇文章还发布了一个重要的小样本数据集——Omniglot数据集,1623个不同的手写字符,每一个字符都是由20个不同的人使用亚马逊的Mechanical Turk线上绘制的。这意味着,它有1623个类,每个20个示例,共32460张图片,其中每一张图像的规格为105×105。
自2017年以来,小样本学习[2]逐渐成为学术热点。一方面,由于样本稀少,人们需要减少数据收集工作量和降低计算开支,另一方面,作为模仿人类进行学习(Human-like Learning)的垫脚石,人们也需要研究小样本学习。
2019年CVPR有个关于跨域小样本学习的比赛,使用自然图像数据集ImageNet作为源域,然后在图片类型完全正交的目标域(遥感图像,皮肤病理图像,植物病害图,纹理图像和X光医学图像)上进行图像分类任务。
我今天在看MATLAB官方教程的时候,发现有用预训练模型做迁移学习和用孪生网络对字符进行分类的教程,正好可以把它们结合起来,补一个从自然图像迁移到手写字符图像的跨域小样本图像分类实验(在我心目中它就是Cross-Domain Few-shot Learning的MNIST啦~)。
downloadFolder = tempdir; url = "https://github.com/brendenlake/omniglot/raw/master/python"; urlTrain = url + "/images_background.zip"; urlTest = url + "/images_evaluation.zip"; filenameTrain = fullfile(downloadFolder,"images_background.zip"); filenameTest = fullfile(downloadFolder,"images_evaluation.zip"); dataFolderTrain = fullfile(downloadFolder,"images_background"); dataFolderTest = fullfile(downloadFolder,"images_evaluation"); if ~exist(dataFolderTrain,"dir") fprintf("Downloading Omniglot training data set (4.5 MB)... ") websave(filenameTrain,urlTrain); unzip(filenameTrain,downloadFolder); fprintf("Done.n") end if ~exist(dataFolderTest,"dir") fprintf("Downloading Omniglot test data (3.2 MB)... ") websave(filenameTest,urlTest); unzip(filenameTest,downloadFolder); fprintf("Done.n") end imdsTrain = imageDatastore(dataFolderTrain, ... 'IncludeSubfolders',true, ... 'LabelSource','none'); files = imdsTrain.Files; parts = split(files,filesep); labels = join(parts(:,(end-2):(end-1)),'_'); imdsTrain.Labels = categorical(labels); imdsTest = imageDatastore(dataFolderTest, ... 'IncludeSubfolders',true, ... 'LabelSource','none'); files = imdsTest.Files; parts = split(files,filesep); labels = join(parts(:,(end-2):(end-1)),'_'); imdsTest.Labels = categorical(labels);
在命令行输入 deepNetworkDesigner ,然后会打开网络设计工具箱。
选哪个好呢?
还是使用SqueezeNet吧(这个网络默认下好了,其实也可以使用其他预训练网络)
因为Omniglot数据集是二值图,只有一个颜色通道,所以需要先修改图像输入层(把之前网络的227,227,3改为227,227,1)。
对紧接着的卷积层也需要修改。
修改好了网络头部,还需要针对分类的类别个数修改网络尾部几层。
拖到最后,根据分类个数替换掉 NumFilters 的值(这里因为暂时只用了训练集,个数是964,设置不是很恰当,仅作参考)
网络调整完毕后,进行一下分析。
没问题,就可以准备训练啦。
载入训练集。
调整训练参数。
这里调整了学习率和batchsize等参数,可根据需求自己设置。
训练开始啦~
可以看到因为我机器性能的原因(750TI 2G),速度很慢。另外因为训练数据集设置不当的原因(因为是小样本学习,所以应该参考N-way-K-shot的训练范式去训练),导致模型准确率非常低且很难提高。
可以看到因为训练范式和参数设置不恰当,网络准确率超级低(我的锅)。
一键生成训练代码,连报告都写好了,真香。
总的来说,我们刚才一起用MATLAB实现了从在ImageNet上预训练的SqueezeNet网络,然后修改了网络的倒数第二层,保持其它层参数不变,仅训练倒数第二层的参数来微调模型,希望在Omniglot数据集上实现图像分类任务。
从最终的模型准确度来看,我的实验流程存在很大的问题,因为这个是最经典的迁移学习的做法,很生硬,没有充分考虑到迁移的目标域是小样本数据。
如果想要改进的话,一方面应该参考元学习(特指MAML模型无关的元学习)的训练模式,采样若干“N-way-K-shot”的任务序列,然后改进元训练步骤传入的训练数据batch,最后再进行元测试,效果应该会大大改善。
很显然这样的元学习模式没办法用官方APP直接完成,或许可以通过对自动生成的训练代码进行修改,达成元学习的训练模式。
我看到有其他研究人员在官方论坛提过类似问题,他想在MATLAB实现Prototypical Networks, Relation Networks, Matching Networks等算法,但目前还没解决,我也需要一些时间完善细节,就先搁置一下吧~
不过话说回来,虽然我实验设计有问题,但这并不影响我们了解到使用MATLAB进行训练神经网络的功能齐全和操作便捷。如果想做实验的话,请参考官方更详细的教程哦~
对使用MATLAB做迁移学习感兴趣还可以参考 @王晋东不在家 博士的教程 EasyTL
(注:这里因为实验设计的问题,并没有取得预想中的实验结果,下面换个效果好的demo展示给大家~)
实验过程可以参考视频:
炎炎夏日,怎么能少得了买瓜呢。但挑西瓜可不容易,需要费好大功夫。
在国内,机器学习小白几乎人手一本的西瓜书(周志华《机器学习》)也讨论了如何挑好瓜的问题。不妨拿来再试一下。
新建一个会话。选择刚导入的数据文件,指定分类变量,导入各个维度的数据(ID序列这个就没必要加进来了),选择好需要的,模型验证方式(数据如果稍微多一些的话可以用10折交叉验证法)
快速训练一组分类器,然后从中选择效果好的~可以调用并行功能,充分发掘处理器的潜力,在更短时间能做完更多组实验。
前面仅对原始数据进行处理,这个任务是二分类问题,但特征有9维,或许可以尝试用PCA等方法降维后再训练。
可以看到使用PCA之后,绝大多数模型可以获得更好的模型准确度。而最优分类器也比之前获得了更优表现(最佳分类器准确度,从PCA处理前70.6%,提升到了现在的88.2%)。
训练结束,除了看指标之外,是不是还有一些事情可以做呢?
没错,和前面一样,可靠的MATLAB能一键导出相关图案,生成训练过程的函数,也能导出训练好的模型到工作区用于之后其他数据的实验。
怎么样,学会了吗?希望大家都能挑到好瓜,满载而归。
其实我学AI的过程有些坎坷,本科时候也没什么好资料,自己找到个工具就开始玩,Weka是我入门AI的学习工具(下面表情包第三行的蓝色鸟~),它集成了当时最先进的一些算法,然后还能在带GUI的界面进行实验(也就是用鼠标点点点就行)。自动机器学习其实也是最早在Weka平台上实现的,我当时还靠AutoWeka建模发了文章(没想到现在MATLAB也支持自动机器学习了)。
我用MATLAB从头写过多层感知机,也调用过SVM和神经网络工具包去做实验,但那时感觉比较笨,体验不太好。
所以我很理解有人制作下面的meme图来讽刺使用这些工具搞AI研究的人。
不过时代一直在改变,虽然MATLAB在前几年脚步慢了一些,但凭借深厚的技术底蕴,现在MATLAB平台上做深度学习也能有丝滑体验了。
同其他领域一样,在人工智能领域,MATLAB也提供了非常高质量且简洁易懂的官方课程,通过“视频+问答+交互式编程”的过程帮我弄清楚项目流程的构造与细节的调整。我非常推荐免费课程深度学习入门之旅,跟着老师从头到尾完整实现一个AI项目,耗时还不到半天。
这个是我的学习记录,前面实现迁移学习的demo也来源于此
除了官方推荐的课程以外,我还特别推荐“小迈步”系列视频。深入浅出帮你入门一个领域,快速实现实验原型。
而如果既想用MATLAB在交叉领域设计原型,又习惯了其他框架下开发算法,也没问题,使用ONNX等格式把已有模型进行转换,然后部署到自己感兴趣的领域上就好。
我相信,工具本身并不分什么高下,重要的是找到适合的工具,且让自己成为能驾驭好工具的人。得益于现在AI生态的活跃,我们现在能有非常多的选择去做研究或生产实践,还等什么呢?
MATLAB,YES!
对于大部分工科学生而言,接触的第一门编程语言可能不是Python,也不是C++,而是MATLAB。即便你是计算机专业,基本上也都在本科用过MATLAB。举个例子,我第一次接触MATLAB是本科时做电路仿真。当时印象比较深的是Simulink的设计,毕竟十年前可视化的复杂建模软件并不多见,除了Simulink就是Verilog。当时MATLAB的编辑器给我留下了很不错的印象,因为它可以方便地查看每个变量的值,是查找bug的利器。这个也直接影响到后来我对于能查看具体数值编程IDE的偏好。
抛开MATLAB对我编程习惯的影响,很多人早在人工智能入门路上就直接或者间接使用过MATLAB。比如影响力最大的斯坦福大学吴恩达老师的机器学习公开课作业,就是用了MATLAB设计(以及其他兼容语言)。由此看来,MATLAB其实很早就和机器学习建立了紧密的连接。我周围不少搞数据挖掘的教授也能印证这一点,他们主要用MATLAB进行建模,像我老板很多论文的源码便是基于MATLAB在做。
人工智能可以说是现在主要发展的科技潮流,但很多编程语言都有自己相对应的机器学习工具和系统,比如Python上做传统机器学习有Scikit-learn,做深度学习有Pytorch,MXNET,TensorFlow等,如果要做时间序列还可以再选择statsmodels作为补充。作为一个喜欢折腾的人,并且也是资深的开发者,熟练地掌握这些工具库并不困难。但对于绝大部分人只是需要应用机器学习和深度学习的人而言,知道使用什么工具,知道每个工具里可以使用哪些模型,并高效地尝试这些模型并不易事。在这种情况下,我认为MATLAB可能是更容易上手的工具,大家不妨可以体验下。
首先MATLAB比较适合行业应用工程领域中想应用人工智能项目的人,因为它和各个传统工程学科结合得比较好。比如做信号处理的同学,那么前期你可以在数据上直接用已有的代码进行相应的数据处理(像图1中我们熟悉的各种专门进行信号处理的工具),再使用Signal Analyzer(图2)对数据进行了解后进行各种变换(像傅里叶变换),之后你就可以很简单地套用MATLAB已有的机器学习模型。就像我在COPOD:用「统计」+「机器学习」检测异常提到的统计方法copula,在Python中没有非常完善的包可以调用,但如果是MATLAB的话就可以调用现成的函数。
也因此,这样就不用事先在MATLAB里面进行数据处理,再导出到其他平台进行机器学习建模了。换句话说,MATLAB依托大量的内置工具库,可以做到一站式建模需求。
而新版MATLAB对于复杂的人工智能建模需求更加友好。以我们学校的校园版R2021a版本为例,它拥有三大人工智能工具箱(图3),首先是传统的统计与机器学习工具箱(Statistics and Machine Learning Toolbox),其主要针对的是普通非深度学习建模。其次,是深度学习工具箱(Deep Learning Toolbox),专门用于做深度学习相关的建模,十分适合海量复杂的数据。最后一个重要的组成部分就是强化学习工具箱(Reinforcement Learning Toolbox),越来越多的游戏AI和探索型的任务都在向强化学习转变,这个工具箱的存在很有必要。现在国内的很多学校也有购买全校校园版MATLAB,比如清北复交都有。学校集体购买,全校师生都可以使用。
相信大部分人和我一样,比较感兴趣的是深度学习的部分,那我就和大家分享一下我对MATLAB的认知隵(以经典的卷积网络在MNIST上进行数字分类为例)。首先需要说明的是,MATLAB支持绝大部分的英伟达GPU,因此无需额外设置,便能使用GPU进行加速。具体的支持列表可以参考
MATLAB数据处理和读取比较简单,我们直接看一下对于神经网络的定义部分。这部分定义也不难,我们可以像搭积木一样把需要的神经网络模块加进去。
如图4(上)所示,我们指定网络结构。至于设定参数,只要像图4(下)操作设定学习率等即可。最后一步就是调用内置函数trainNetwork完成深度学习训练。
而MATLAB中深度学习的优势除了设定简单外,还有很好的可视化和网络设计模块。深度学习中我们最想知道当然是训练的过程中loss是否在下降,训练集和验证集上的表现如何。使用开源的PyTorch和Tensorflow时,我们虽然可以用额外的可视化比如tensorboard或者wandb,但也稍微需要进行一些设置。但在MATLAB中,我们可以简单加一个plot选项,就可以自动生成实时的训练过程的可视化。图5中MATLAB自动画出了训练过程中训练集上的accuracy和loss(蓝色曲线),以及测试集上的相关信息(红色部分)。同时也可以看到额外的信息,比如learning rate等。因此使用MATLAB Deep Learning Toolbox,我们可以进行一站化的监控学习的过程。
另一点让MATLAB比传统深度学习更方便的功能,就是可视化的深度学习网络结构设计功能(Deep Network Designer)。换句话说,我们可以很轻松地使用图形化的拖拽生成神经网络,而无需写任何代码!如图6中演示,我们只需把需要的网络结构连接起来,并像图7中简单地点击代码生成,就能快速生成对应的深度学习代码。这大大降低了深度学习的使用门槛。
在这些重要的机器学习和深度学习的基础上,MATLAB还提供了更多便捷和高级的功能。对于一般使用者来讲,有帮助的包括AutoML (Automated Machine Learning),自动机器学习模块,它包含了特征选择、模型选择等一系列功能,可以方便我们在训练了多个模型后自动选择合适的对象。除此以外,MATLAB还有很多有趣的高级工具库,比如自动驾驶工具库(Automated Driving Toolbox)(图8),使用该工具库我们可以进行很多建模,比如前向撞击预警(forward collision warning)等。
因此我认为MATLAB最大的优势就是在充满纷杂工具的年代中提供了一站式的人工智能开发平台,以及提供了完整的文档和使用案例。使用者不必再去寻找不同的工具、平台,也不用把大量的时间花在设置系统上,而可以专注于设计模型。随着MATLAB的发展,它也支持了与更多开源平台的双向调用,比如用MATLAB调用Python,用Python调用MATLAB等。在这个前提下,我们可以更好地完成跨语言平台协作,从而改变Python在很多传统领域缺少成熟工具的现状。这对于很多传统学科的同学和从业者来说无疑是一大利好,因为已有的数学模型可以简单的复用并加入到深度学习里面,而这一切都可以在MATLAB中完成,无需过多的编程基础。此外,我们也可以协同开源的平台,利用MATLAB成熟的数据处理和建模能力简化工作量。而所谓一站式的开发平台,最终也要落回到模型部署上来,MATLAB已经有十分成熟的部署方案,MATLAB 中的 AI 模型可广泛部署到嵌入式设备或板、现场边缘设备、企业系统或云中。举个例子,MATLAB的GPU Coder可以直接为深度学习模型生成CUDA代码,而MATLAB Coder可以用于生成C代码,以便适应不同的硬件。在我看来,不同工具都有不同的适用场景,因此大家不妨根据自己的具体情况多试试不同的平台,最大化提升自己的生产力。毕竟,生产力才是硬道理。