人工智能的发展曾经经历过几次起起伏伏,近来在深度学习技术的推动下又迎来了一波新的前所未有的高潮。近日,IBM 官网发表了一篇概述文章,对人工智能技术的发展过程进行了简单梳理,同时还图文并茂地介绍了感知器、聚类算法、基于规则的系统、机器学习、深度学习、神经网络等技术的概念和原理。
人类对如何创造智能机器的思考从来没有中断过。期间,人工智能的发展起起伏伏,有成功,也有失败,以及其中暗藏的潜力。今天,有太多的新闻报道是关于机器学习算法的应用问题,从癌症检查预测到图像理解、自然语言处理,人工智能正在赋能并改变着这个世界。
现代人工智能的历史具备成为一部伟大戏剧的所有元素。在最开始的 1950 年代,人工智能的发展紧紧围绕着思考机器和焦点人物比如艾伦·图灵、冯·诺伊曼,迎来了其第一次春天。经过数十年的繁荣与衰败,以及难以置信的高期望,人工智能及其先驱们再次携手来到一个新境界。现在,人工智能正展现着其真正的潜力,深度学习、认知计算等新技术不断涌现,且不乏应用指向。
本文探讨了人工智能及其子领域的一些重要方面。下面就先从人工智能发展的时间线开始,并逐个剖析其中的所有元素。
现代人工智能的时间线
1950 年代初期,人工智能聚焦在所谓的强人工智能,希望机器可以像人一样完成任何智力任务。强人工智能的发展止步不前,导致了弱人工智能的出现,即把人工智能技术应用于更窄领域的问题。1980 年代之前,人工智能的研究一直被这两种范式分割着,两营相对。但是,1980 年左右,机器学习开始成为主流,它的目的是让计算机具备学习和构建模型的能力,从而它们可在特定领域做出预测等行为。很多初学者,对大数据的概念都是模糊不清的,大数据是什么,能做什么,学的时候,该按照什么线路去学习,学完往哪方面发展,想深入了解,想学习的同学欢迎加入大数据学习扣群:805127855,有大量干货(零基础以及进阶的经典实战)分享给大家,并且有清华大学毕业的资深大数据讲师给大家免费授课,给大家分享目前国内最完整的大数据高端实战实用学习流程体系
图 1:现代人工智能发展的时间线
在人工智能和机器学习研究的基础之上,深度学习在 2000 年左右应运而生。计算机科学家在多层神经网络之中使用了新的拓扑学和学习方法。最终,神经网络的进化成功解决了多个领域的棘手问题。
在过去的十年中,认知计算(Cognitive computing)也出现了,其目标是打造可以学习并与人类自然交互的系统。通过成功地击败 Jeopardy 游戏的世界级选手,IBM Watson 证明了认知计算的价值。
在本文中,我将逐一探索上述的所有领域,并对一些关键算法作出解释。
基础性人工智能
1950 年之前的研究提出了大脑是由电脉冲网络组成的想法,正是脉冲之间的交互产生了人类思想与意识。艾伦·图灵表明一切计算皆是数字,那么,打造一台能够模拟人脑的机器也就并非遥不可及。
上文说过,早期的研究很多是强人工智能,但是也提出了一些基本概念,被机器学习和深度学习沿用至今。
图 2:1950 – 1980 年间人工智能方法的时间线
人工智能搜索引擎
人工智能中的很多问题可以通过强力搜索(brute-force search)得到解决。然而,考虑到中等问题的搜索空间,基本搜索很快就受影响。人工智能搜索的最早期例子之一是跳棋程序的开发。亚瑟·塞缪尔(Arthur Samuel)在 IBM 701 电子数据处理机器上打造了第一款跳棋程序,实现了对搜索树(alpha-beta 剪枝)的优化;这个程序也记录并奖励具体行动,允许应用学习每一个玩过的游戏(这是首个自我学习的程序)。为了提升程序的学习率,塞缪尔将其编程为自我游戏,以提升其游戏和学习的能力。
尽管你可以成功地把搜索应用到很多简单问题上,但是当选择的数量增加时,这一方法很快就会失效。以简单的一字棋游戏为例,游戏一开始,有 9 步可能的走棋,每 1 个走棋有 8 个可能的相反走棋,依次类推。一字棋的完整走棋树包含 362,880 个节点。如果你继续将这一想法扩展到国际象棋或者围棋,很快你就会发展搜索的劣势。
感知器
感知器是单层神经网络的一个早期监督学习算法。给定一个输入特征向量,感知器可对输入进行具体分类。通过使用训练集,网络的权重和偏差可为线性分类而更新。感知器的首次实现是 IBM 704,接着在自定义硬件上用于图像识别。
图 3:感知器与线性分类
作为一个线性分类器,感知器有能力解决线性分离问题。感知器局限性的典型实例是它无法学习专属的 OR (XOR) 函数。多层感知器解决了这一问题,并为更复杂的算法、网络拓扑学、深度学习奠定了基础。
聚类算法
使用感知器的方法是有监督的。用户提供数据来训练网络,然后在新数据上对该网络进行测试。聚类算法则是一种无监督学习(unsupervised learning)方法。在这种模型中,算法会根据数据的一个或多个属性将一组特征向量组织成聚类。
图 4:在一个二维特征空间中的聚类
你可以使用少量代码就能实现的最简单的聚类算法是 k-均值(k-means)。其中,k 表示你为样本分配的聚类的数量。你可以使用一个随机特征向量来对一个聚类进行初始化,然后将其它样本添加到其最近邻的聚类(假定每个样本都能表示一个特征向量,并且可以使用 Euclidean distance 来确定「距离」)。随着你往一个聚类添加的样本越来越多,其形心(centroid,即聚类的中心)就会重新计算。然后该算法会重新检查一次样本,以确保它们都在最近邻的聚类中,最后直到没有样本需要改变所属聚类。
坑1:镜像文件和版本的选择 我开始用的是虚拟机下载的16.04版本,可能是因为使用了虚拟机过后,镜像源出现了问题,安装后出现了不少错误,并且进入系统后也存在问题,安装体验很不好,后来下载最新版的18.04版本,在安装时一进入安装界面就会卡死,也不知道什么问题,虽说新版本很有吸引力,但是如果你只是为了学习和熟悉linux下的操作,不建议使用太新的版本。
最后我从官网上下载了16.04版本,整个安装过程没有出现异常,只是在开机后可以登录,但是无法显示桌面,下面说这个。
坑2:安装好后可以登录系统,但是无法显示桌面 出现这种问题主要是显卡驱动的问题,我的显卡是NAVIDIA GeForce GTX 1050的,可以在win10中的设备管理器中的显示设备中查看,感觉ubuntu对NAVIDIA的支持不是很好,需要自己手动安装驱动才行。
首先在选择系统的界面选中Ubuntu,然后按e键进入编辑模式,在linux最后的splash后添加单独的一个单词:nomodeset,然后按F10保存并进入系统,这次可以正常进入系统。
进入后需要手动安装驱动,因为我是NAVIDIA的显卡驱动,所以只实验了NAVIDIA的,其他出现类似问题的解决方法应该类似吧(可能),首先进入NAVIDIA的驱动选择界面,然后根据你的显卡类型选择相应的驱动,其中Product series 根据你显卡后面的数字,比如1050就是10,点击搜索后出现驱动的版本Version ,记住版本的整数部分就行,然后在终端依次输入如下命令:
sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt-get update sudo apt-get install nvidia-390 #此处要根据上面查询到的版本适当更改 sudo apt-get install mesa-common-dev sudo apt-get install freeglut3-dev 重启设备,进入系统后就可正常运行。
坑3:进入系统后没有亮度调节条,无法调节亮度 这种情况也是驱动的问题,如坑2那样操作之后就可以自由调节亮度了。
坑4:进入系统后无法识别无线网络,无法联网 这种情况我在虚拟机下载的unbutu16.04版本安装过程中遇到过,按照网上说的方法瞎操作一通,配置静态动态ip,添加dns,都没用,我感觉还是iso镜像源的问题,与其浪费时间,不如换个镜像源试试,说不定就行了,后来我从官网上下载的镜像源安装好后就可以直接识别无线网,不需要手动配置了。
坑5:分区问题 总结了一下网上说的分区的误区和成功经验。分区是在安装的时候,系统询问是否和windows共存,千万不要点和windows共存,因为这样的不可控会导致ubuntu的空间可能会占据windows的空间,导致windows有很大几率打不开,选择最底下的其他选项,自己配置空间。
配置的方法网上基本上都一样,我这里记录下各个区的作用和大概分配的比例:
/boot : 主分区,存放的是ubuntu的启动等关键程序,200M是肯定不够的,500M保底,如果你整体空间很多,1G也不为过 swap :交换分区,跟内存一样大或者大点都可以 / :根分区,存放系统软件和系统配置等,与C盘的作用有点类似,不过C盘也包含了/boot的功能,一般10到20G之间,同样整体很大的话30G也不为过 /home :用户分区,存放的是每个用户自己的数据,例如图片、文档、视频、软件等,一般是前三个分完之后剩下的空间作为该分区的空间 坑6:最好别随意升级!卡住警告! 如果你选择的是16.04版本,进入系统后如果你有更新软件的操作,会弹出一个对话框告诉你发现了新版本18.04,问你是否升级,如果你点了立即升级,那么能不能升级成功就看你运气了,反正我是卡在了installing snap……那里,原因是snap的下载时间太长了。网上也有不少升级时卡住的例子,建议如果想升级到18.04,直接去官网下载安装,只要不把/home的内容格式化了基本没啥影响。
但是还是开头那句话,新的不一定最适合你。
来源:黑客网络技术与安全
朋友圈被一条信息刷屏:暗网中文论坛一个ID为 helen250 的发帖人发帖出售华住旗下所有酒店数据,包括汉庭酒店、美爵、禧玥、漫心、诺富特、美居、CitiGo、桔子、全季、星程、宜必思、怡莱、海友等,泄露数据总数更是近 5亿!
紫豹科技的情报专家通过技术手段验证了这批数据的真伪,称数据绝大部分为新泄露数据,而非老数据混杂售卖。
售卖的数据包括三个部分:
1. 华住官网注册资料包括姓名、手机号、邮箱、身份证号、登录密码等,共 53 G,大约 1.23 亿条记录;
2. 酒店入住登记身份信息包括姓名、身份证号、家庭住址、生日、内部 ID 号,共 22.3 G,约 1.3 亿人身份证信息;
3. 酒店开房记录包括内部 id 号,同房间关联号、姓名、卡号、手机号、邮箱、入住时间、离开时间、酒店 id 号、房间号、消费金额等,共 66.2 G,约 2.4 亿条记录。
本次事件疑似华住公司程序员将数据库连接方式上传至GitHub导致其泄露;黑客称在8月14日进行脱裤,此数据库连接方式在20天前上传至GitHub,时间上大致吻合。
发帖人还称打包出售的价格总共是 8 个比特币,按照今天的汇率,1比特币是47081.67 元,换算成人民币为 376477 元
对于这件事情华住酒店官方回应称:正在核实数据来源,并且已经报了警!
详细声明如下:
若此次数据泄露事件属实,该事件或成国内近几年最严重的信息数据事件。为保险起见,如果你曾经在华住旗下的酒店开过房,请及时修改账号密码。
写在最后 大咖的话:“最近有很多想学习编程的朋友问我有没有什么好的编程资料!因为最近今年我都在认真搜集有价值的编程资料,技术资料,只为帮助那些想学习编程而不知道从哪开始的朋友。
下图就是(部分资料截图):
以上价值5万元的资料,绝对比群里那些漫天飞的资料强多了。今天决定免费分享,用来感谢大家的支持。”
免费获取方式:
添加大咖Vx:“cquan123456”,即可免费领取最新价值5万元全栈开发视频资料!,一定要备注:“大咖,CSDN来的领资料”,否则不能通过!
觉得不错请点赞,欢迎留言分享!
咕噜~~
这次usaco没有打上银组真是让我尴尬,第一次打usaco,有点紧张。。。
同组第一题的传送牛粪,虽不知道何必如此大费周章,但也是一代水题
题面是这样的:
Farmer John最讨厌的农活是运输牛粪。为了精简这个过程,他制造了一个伟大的发明:便便传送门!与使用拖拉机拖着装满牛粪的大车从一个地点到另一个地点相比,他可以使用便便传送门将牛粪从一个地点瞬间传送到另一个地点。
Farmer John的农场沿着一条长直道路而建,所以他农场上的每个地点都可以简单地用该地点在道路上的位置来表示(相当于数轴上的一个点)。一个传送门可以用两个数xx和yy表示,被拖到地点xx的牛粪可以瞬间传送到地点yy,反之亦然。
Farmer John想要将牛粪从地点aa运输到地点bb,他建造了一个可能对这一过程有所帮助的传送门(当然,如果没有帮助,他也可以不用)。请帮助他求出他需要使用拖拉机运输牛粪的总距离的最小值。
输入格式(文件名:teleport.in):
输入仅包含一行,为四个用空格分隔的整数:aa和bb,表示起始地点和结束地点,后面是xx和yy,表示传送门。所有的位置都是范围为0…1000…100的整数,不一定各不相同。
输出格式(文件名:teleport.out):
输出一个整数,为Farmer John需要用拖拉机运输牛粪的最小距离。
输入样例:
3 10 8 2 输出样例:
3 在这个样例中,最佳策略是将牛粪从位置3运到位置2,传送到位置8,再运到位置10。 所以需要用拖拉机的总距离为1 + 2 = 3。
这题我采用了模拟法,一遍过,代码如下
#include using namespace std; int a,b,x,y,i,j; long long n=0,m=0; int main() { freopen("teleport.in","r",stdin); freopen("teleport.out","w",stdout); cin>>a>>b>>x>>y; if(b>a) { n=b-a; if(x>y) { if(a>y) m+=a-y; else m+=y-a; if(b>x) m+=b-x; else m+=x-b; } else { if(a>x) m+=a-x; else m+=x-a; if(b>y) m+=b-y; else m+=y-b; } } else { n=a-b; if(x>y) { if(a>x) m+=a-x; else m+=x-a; if(b>y) m+=b-y; else m+=y-b; } else { if(a>y) m+=a-y; else m+=y-a; if(b>x) m+=b-x; else m+=x-b; } } if(n>m) cout< 很长,可以简洁很多,但这样写思路会更清晰,AC后也就没想过化简。
马上华为提前批开始了,吓得我赶紧上牛客网刷题,记录如下: 所有代码都在github
1.字符串最后一个单词的长度 一段英文字符串中最后一个单词的长度。 题目比较简单,做法有很多: 比如, 可以放到stringstream里面split,拿到最后一个单词 也可以从后往前数到第一个空格为止。
让我觉得麻烦是第一次做这种要自己写输入的题, C++用cin是遇到空格停止的,因此要用getline读入一行
#include #include using namespace std; int main() { string str; getline(cin,str); int i=str.size()-1; int count=0; while(str[i]!=' '&&i>=0) { ++count; --i; } cout<return 0; } 2.计算字符个数 输入一个字符串和一个字符,统计该字符在该字符串中出现的次数。 for循环比较即可,没什么好说的
#include #include using namespace std; int main(int argc,char **argv) { string str; char c; getline(cin,str); cin>>c; int count=0; for(int i=0;iif(tolower(str[i])==tolower(c)) ++count; } cout << count<return 0; } 3.明明的随机数 说是随机数,其实跟随机数没有半毛钱关系, 就是输入一串整数,整数去重,输出排好序的结果, C++使用std::sort、std::unique、vector::erase可以轻易做到
#include #include #include #include using namespace std; int main() { // input int n; while(cin>>n) { vector<int>v; v.
题目1 : 电子数字 时间限制:
10000ms 单点时限:
1000ms 内存限制:
256MB 描述 电子数字在生活中很常见,而许多的电子数字是由LED数码管制作而成。数字LED数码管一般由7个发光二极管封装在一起,组成’8’字型,引线在内部连接完成。如下图所示,我们可以对每个发光管进行编码从1到7。而数字0到数字9可以由这七根发光管的亮暗来表示。
对LED数码管的二极管进行编码
用LED数码管表示数字0-9
假设我们现在有从左到右排列好的K个LED数码管,并且我们已知每个数码管当前有哪些编号的二极管是亮着的,另外剩余的二极管由于某些原因,我们并不清楚它们的亮暗情况。由于已经有部分二极管是确定亮着的,所以每个LED数码管能表示的数字范围会有所缩小,譬如假设1号二极管已经确定是亮着的状态,那么这个LED数码管就不能表示数字1和4。
我们想知道的是,给定一个数N,在这K个LED数码管的当前亮暗的状态下,所有可能表示的数中,比N小的数有多少个。
注意,前导0是必须的,假设有4个数码管的话,’0000’表示0,’0123’表示123,即每个数的表示方法唯一。
输入 每个输入数据包含多个测试点。
第一行为测试点的个数 S ≤ 100。之后是 S 个测试点的数据。测试点之间无空行。
每个测试点的第一行为 K(1 ≤ K ≤ 5)和N(0 ≤ N ≤ 109)。之后是K行,每行表示对应数码管已点亮的二极管的情况。每行至少包含一个数字,表示对应点亮的二极管的编号,即每个数码管至少有一根二极管是点亮的。二极管编号的范围保证在1到7之间,且每行无重复编号。
注意表示数码管点亮情况的每行数字之间以及行首行末之间可能存在冗余空格,每行的字符总长度不超过100。
输出 对于每个测试点,对应的结果输出一行,表示这K个数码管在当前状态下,所有可能表示的数中,比N小的数有多少个。
样例解释 第一个样例中,只有’020′, ‘026’, ‘028’符合要求。
第三个样例中,只有’000’符合要求。
样例输入 3 3 50 3 1 1 4 5 1 5 6 7 4 100 1 2 3 4 5 6 7 1 1 7 样例输出 3 0 1 // wangyi.