网站是什么软件制作的?

网站是什么软件制作的?,第1张

我们从网络上常见到的企业网站是用什么软件制作?

网页制作从图片处理,Flash,数据库等完成,我们来看看网络上常用的软件有那些:

网页制作

一、网页制作软件:

1、Microsoft FrontPage 如果你曾对Word很熟悉,那么相信你用 FrontPage进行网页设计一定会非常顺手。使用FrontPage制作网页,你能真正体会到“功能强大,简单易用”的含义。页面制作由FrontPage中的Editor完成,其工作窗口由3个标签页组成,分别是“所见即所得”的编辑页,HTML代码编辑页和预览页。FrontPage带有图形和GIF动画编辑器,支持CGI和CSS。向导和模板都能使初学者在编辑网页时感到更加方便。

FrontPage最强大之处是其站点管理功能。在更新服务器上的站点时,不需要创建更改文件的目录。FrontPage会为你跟踪文件并拷贝那些新版本文件。FrontPage是现有网页制作软件中惟一既能在本地计算机上工作,又能通过Internet直接对远程服务器上的文件进行工作的软件。

Microsoft FrontPage

2、Netscape编辑器Netscape Communicator和Netscape Navigator Gold3.0版本都带有网页编辑器。如果你喜欢用Netscape浏览器上网,使用Netscape编辑器真是简单方便!当你用Netscape浏览器显示网页时, 单击编辑按钮,Netscape就会把网页存储在硬盘中,然后就可以开始编辑了。你也可以像使用Word那样编辑文字、字体、颜色,改变主页作者、标题、背景颜色或图像,定义描点,插入链接,定义文档编码,插入图像,创建表格等,是不是与FrontPage 2000还有些像?但是,Netscape编辑器对复杂的网页设计就显得功能有限了,它连表单创建、多框架创建都不支持。

Netscape编辑器是网页制作初学者很好的入门工具。如果你的网页主要是由文本和图片组成的,Netscape编辑器将是一个轻松的选择。如果你对HTML语言有所了解的话,能够使用Notepad或Ultra Edit等文本编辑器来编写少量的HTML语句,也可以弥补Netscape编辑器的一些不足。

Netscape

3、Claris Home Page

如果使用ClarisHomePage软件,你可以在几分钟之内创建一个动态网页。这是因为它有一个很好的创建和编辑Frame(框架)的工具,你不必花费太多的力气就可以增加新的Frame(框架)。而且ClarisHomePage3.0集成了FileMaker数据库,增强的站点管理特性还允许你检测页面的合法连接。不过界面设计过于粗糙,对ImageMap图像的处理也不完全。

Claris Home Page

4、Adobe Dreamweaver

,简称“DW”,中文名称"梦想编织者",最初为美国MACROMEDIA公司开发[1],2005年被Adobe公司收购。DW是集网页制作和管理网站于一身的所见即所得网页代码编辑器。利用对HTML、CSS、JavaScript等内容的支持,设计师和程序员可以在几乎任何地方快速制作和进行网站建设。

Dreamweaver

二、图像处理软件:

1、Flash是由macromedia公司推出的交互式矢量图和 Web 动画的标准,由Adobe公司收购。做Flash动画的人被称之为闪客。网页设计者使用 Flash 创作出既漂亮又可改变尺寸的导航界面以及其他奇特的效果。

Flash

2、Adobe Photoshop,简称“PS”,Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具,可以有效地进行图片编辑工作。ps有很多功能,在图像、图形、文字、视频、出版等各方面都有涉及。

Photoshop

三、数据库:

1、MySQL所使用的SQL语言是用于访问数据库的最常用标准化语言。MySQL软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库。

MySQL

2、MS ACCESS以它自己的格式将数据存储在基于Access Jet的数据库引擎里。它还可以直接导入或者链接数据(这些数据存储在其他应用程序和数据库)。

四、环境搭建工具:

1、php程序员工具箱:中国最大的php学习行业网站php中文网开发的 "php程序员工具箱",php程序员工具箱是迄今为止全网唯一款php程序员的专属工具箱,集合了php环境搭建、在线小工具、原生手册、文字与视频教程、问答社区等,非常适合初学者。

php程序员工具箱

2、phpstudy:该程序包集成最新的Apache+Nginx+LightTPD+PHP+MySQL+phpMyAdmin+Zend Optimizer+Zend Loader,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境。该程序绿色小巧简易迷你仅有32M,有专门的控制面板。总之学习PHP只需一个包。

在本文(也是本系列的第五部分)中,Teodor 解释了什么是面向对象编程,何时使用它以及它是如何在 Perl 中工作的。面向对象编程(OOP)是一种强大的编程技术,但它不是万能药。优秀的程序员必须理解如何使用它,并且必须知道何时依赖更传统的编程技术。在 Perl 中使用 OOP 很简单。与 C++ 和 Java 等限制性更强的 OOP 语言不同,Perl 中的 OOP 很少对程序员施加强制性约束。OOP 是对每一名程序员的工具箱的必要补充,并且是用于扩展可用 Perl 解决的问题范围的非常有用的技术。什么是面向对象编程(OOP)?OOP 是一种用于解决问题的编程方法或通用方法。与之相反,算法是用于解决特定问题的 特定方法。OOP 天生是一种强有力的方法;它往往使过程型和函数型编程方法与该问题较少相关,并且除非它与过程型和函数型编程方法的混合对其极其有益,否则它们之间不会很好地结合在一起。在 Perl 中,这种强大的力量有所减弱,但仍然很好地存在着。 本文讨论 Perl 中的 OOP 对比函数型和过程型编程的基本知识,并演示如何在 Perl 程序和模块中使用 OOP。请记住,本文只是一篇概述,而不是对 Perl 中 OOP 所有方面的详尽解释。这样的详尽解释需要几本书才能讲完,并且已经被写过几次了。有关详细信息,请参阅本文稍后的 参考资料。 究竟什么是 OOP?OOP 是一种通过使用对象来解决问题的技术。在编程术语中,对象是这样一些实体:它们的特性和行为是解决手头问题所必需的。这个定义本应该更详细些,但是做不到,因为当今计算机行业中 OOP 方法的种类之多简直难以想象。在Perl 编程环境中,OOP 并不是使用该语言所必需的。Perl 版本 5 和更高版本鼓励使用 OOP,但确切地说不要求这样做。所有 Perl 库都是模块,这意味着它们至少使用 OOP 的基本部分。而且,大多数 Perl 库都作为对象实现,这意味着用户必须通过良好定义的接口将它们作为具有特定行为和特性的 OOP 实体来使用。回页首基本的 OO 编程语言特性通常,有三个语言特性是 OOP 编程语言所必需的。它们是继承、多态性和封装。Perl 支持继承。当一个对象(子对象)使用另一个对象作为起点(父对象),并且随后在需要时修改其特性和行为时,就要用到 继承。子-父关系是 OOP 所必需的,因为它使得在其它对象基础上构建对象成为可能。这种重用是使 OOP 成为程序员宠儿的好处之一。 有两种继承:单一继承和多重继承。 单一继承要求子对象只有一个父对象,而 多重继承更自由(与实际生活一样,在编程过程中具有两个以上的父对象会导致混乱并使子对象难以工作,因此,不要过多使用多重继承)。尽管两个或两个以上的父对象实际上很少见,但 Perl 支持多重继承。 多态性(来自希腊语,表示“很多形态”)是使一个对象被看成另一个对象的技术。这有点复杂,那么我举个例子。比方说,您有一个绵羊牧场,里面有四只绵羊(绵羊属),但是您刚刚买了两只山羊(山羊属)和一只德国牧羊犬(犬科犬属)。您一共有多少动物?您得把所有的绵羊、山羊和狗加起来,结果是 7 只。其实您刚刚应用了多态性,即为了计算,把三种不同种类的动物当成一种通用类型(“动物”)对待。如果您把绵羊、山羊和狗当成哺乳动物看待,这就是一个简单的信心飞跃。生物学家每天都以这种方式使用多态性,而程序员则以从其它科学领域“窃用”(我是指“重用”)好主意闻名。Perl 完全支持 多态性。但它用得不是很频繁,因为 Perl 程序员看起来更喜欢用对象特性、而不是通过修改继承的行为来修改通用行为。这意味着您更可能看到创建三个 IO::Socket::INET 对象的代码:一个对象用于在端口 234 接收和发送 UDP 包、一个对象用于在端口 80 接收 TCP 包,还有一个对象在端口 1024 发送 TCP 包,而不大会看到对第一种情况使用 IO::Socket::INET::UDPTransceiver 、对第二种情况使用 IO::Socket::INET::TCPReceiver 而对第三种情况使用 IO::Socket::TCPTransmitter 的代码。这就象是在生物学术语中说狗和山羊都是哺乳动物,但是山羊属于山羊属,而狗属于犬属。 OOP 纯化论者认为每件事都应该正确分类,但是 Perl 程序员根本不是纯化论者。他们往往更不拘束于 OOP 规则,这使得他们在聚会中比 OOP 纯化论者更快乐。封装指的是以这样一种方式包含对象行为和特性:除非对象作者允许,否则用户无法访问该对象的行为和特性。在这种方式下,对象用户无法做不准他们做的事,无法访问不准他们访问的数据,并且通常是有害数据。Perl 通常用松弛的方法封装。请参阅 清单1。 回页首为什么说 OOP 是一种强有力的方法?返回到我们最初的 OOP 如何是一种强有力的方法这一主题,我们现在可以看到 OOP 结合了几个关键的概念,这使得它很难与过程型和函数型编程(PP 和 FP)混合使用。首先,PP 和 FP 都没有继承或类多态性的概念,因为在 PP 和 FP 中根本就没有类。在 PP 和 FP 中存在封装,但只在过程型级别,从来不作为类或对象属性封装。既然程序员不怕麻烦来使用这些基本的 OOP 工具,那就意味着程序员通常更可能对整个项目使用 OOP,而不是混合不兼容的方法。有人可能争论说所有程序最终都归结为指令的过程型执行,因此无论 OOP 程序实现得有多纯,每个 OOP 程序都在其函数(也称为方法)和创建第一个对象(该对象做其余工作)的代码中包含过程型代码。甚至象 Java 那样接近“纯”OOP 的语言都无法避免地需要一个 main() 函数。因此,看起来 OOP 只是 PP 的一个子集。但是这种 OOP 向序列指令的归结和实际为每个 *** 作所执行的汇编程序指令一样,都不是系统架构设计师或程序员所关心的事。请记住,OOP 本身只是一种方法,而不是目的。 OOP 与过程型编程方法合作得不是很好,因为它集中在对象上,而过程型编程基于过程(我们将 过程大致定义为不使用 OOP 技术就可以得到的函数,而将 方法定义为只有在对象中才能得到的函数)。正如方法一样,过程只是由用户调用的函数,但是二者之间有一些差异。 过程不使用对象数据。必须在它们的参数列表中为它们传递数据,或者它们必须使用所在作用域中的数据。过程可以访问调用它时传递给它的任何数据,甚至整个程序的全局数据。方法应该只访问它们对象的数据。实际上,方法的函数作用域通常是包含该方法的对象。常常发现过程使用全局数据,尽管只有在绝对必要时才应该这样做。应该尽快重写使用全局数据的方法。过程通常用几个参数调用其它过程。方法应该只有几个参数,并且它们调用其它方法的次数比其它过程更多。函数型编程(FP)与 OOP 配合不好有几个原因。最重要的原因是 FP 基于用来解决问题的详细函数型方法,而 OOP 则使用对象来表达概念,并且,与 OOP 方法只能在包含它们的对象中使用不同,FP 过程得到处使用。综上所述,我们现在可以解释 Perl 为什么是混合 OOP、FP 和 PP 方法的最佳语言之一。回页首Perl 是如何将 OOP 与过程型和函数型编程结合起来的?Perl 是一种松弛的语言。它极力让程序员以他们认为方便的任何方式做他们想做的任何事。这与 Java 和 C++ 之类的语言截然不同。例如,如果程序员原本没有声明变量,Perl 乐于允许程序员自动创建变量(尽管不鼓励这样做,并且可以通过使用高度推荐的“use strict”编译指示阻止)。如果您要向自己的脚开q,Perl 会给您十发子d和一个激光瞄准镜,然后站在一旁鼓励您。因此,Perl 是一种非常便于滥用方法的语言。别害怕。没关系。例如,访问内部的对象数据、实时更改类和实时重定义方法都是允许的。Perl 方式是:允许程序员为了编码、调试和执行效率的目的而去打破规则。如果这有助于完成工作,那么没关系。因此,Perl 本身可能是程序员最好的朋友,也可能是最坏的敌人。如果混合 OOP、FP 和 PP 意味着打破规则,那么为什么任何人都想要混合 OOP、FP 和 PP 呢?让我们回头想想这个问题。什么是 OOP、FP 和 PP?它们只是现有的为编程团队服务的编程方法、概念集和规则集。OOP、FP 和 PP 是工具,每名程序员的首要工作就是要了解他的工具。如果一名程序员在排序散列时不能使用 FP 的 Schwartzian 变换,而是编写他自己的 Sort::Hashtable ,或者不能重用 Sys::Hostname 模块,而是编写过程代码来获得系统主机名,那么这个程序员是在浪费时间、精力和金钱,并且降低了代码质量和可靠性。 一个编程团队可能会因为它们最熟知的工具而沾沾自喜,对它们来说,这可能正是最坏的事。如果一个团队只使用象计算机编程行业那样令人冲动和充满创新的行业中所保证的可用工具的一部分,那么它在几年之后注定要变得毫无用处。程序员应该能够结合任何使工作更有效、代码更好以及使团队更具创新能力的方法。Perl 认可并鼓励这种态度。回页首OOP 的好处OOP 的好处太多,本文难以列举。正如我在前面提到的那样,有很多关于该主题的书籍。这些好处中的一小部分是:易于代码重用、代码质量的改进、一致的接口和可适应性。因为OOP 建立在类和对象的基础之上,所以重用 OO 代码意味着在需要时只需简单地导入类。至今为止,代码重用是使用 OOP 的唯一最主要原因,也是 OOP 在当今业界中的重要性和流行性日益增加的原因所在。这里有一些陷阱。例如,在当前的情况下,以前问题的解决方案可能不理想,并且文档库编制得很差,以至于理解和使用文档编制很差的库所花的时间可能与重新编写库的时间一样长。系统架构设计师的工作是看到和避免这些陷阱。使用OOP 可以提高代码质量,因为封装减少了数据毁坏(“友好之火”),而继承和多态性则减少了必须编写的新代码数量和复杂性。在代码质量和编程创新之间有一个微妙的平衡,这最好留给团队去发现,因为它完全取决于团队的构成和目的。OOP 继承和重用使得在代码中实现一致的接口变得简单,但是并不能说所有的 OO 代码都有一致的接口。程序员仍然必须遵循通用的体系结构。例如,团队应该在错误日志记录的格式和接口方面达成一致,最好通过一个允许日后扩展并且极其易用的示范模块接口来这样做。只有在那时,每名程序员才能承诺使用该接口,而不是无规则的 print 语句,因为他们会认识到在出现下一个错误日志记录函数时,学习该接口的努力不会白费。可适应性在编程中是一个有些含糊的概念。我愿意把它定义成对环境和用法更改的接受性和预见性。对于编写良好的软件来说,可适应性很重要,因为所有的软件必须随着外部世界而进化。编写良好的软件应该很容易进化。OOP 通过模块设计、改进的代码质量和一致的接口确保新 *** 作系统或者新报告格式不要求对体系结构的核心作出根本更改,从而有助于软件的进化。回页首如何在 Perl 中使用 OOP不管您是否相信,Perl 中的 OOP 对初级和中级用户都不难,甚至对高级用户也没那么复杂。根据我们到目前为止所讨论的有关 OOP 的复杂工作方式,您可能不这么认为。然而,Perl 却乐意对程序员施加尽可能少的限制。Perl OOP 就象烤肉(恕我比喻不当)。每个人都带来自己的肉,并以自己喜爱的方式烤肉。甚至还有烤肉的团队精神也是那样,就象可以轻易在不相关的对象之间共享数据一样。我们必须采取的第一步是理解 Perl 包。包类似于 C++ 中的名称空间和 Java 中的库:象用来将数据限制在特定区域的围栏。然而,Perl 包只是为程序员提供建议。缺省情况下,Perl 不限制包之间的数据交换(尽管程序员可以通过词法变量这样做)。清单1. 包名、切换包、在包之间共享数据和包变量#!/usr/bin/perl # note: the following code will generate warnings with the -w switch, # and won‘t even compile with "use strict". It is meant to demonstrate # package and lexical variables. You should always "use strict". # pay attention to every line! # this is a global package variableyou shouldn‘t have any with "use strict" # it is implicitly in the package called "main" $global_sound = " "package Cow# the Cow package starts here # this is a package variable, accessible from any other package as $Cow::sound $sound = "moo"# this is a lexical variable, accessible anywhere in this file my $extra_sound = "stampede"package Pig# the Pig package starts, Cow ends # this is a package variable, accessible from any other package as $Pig::sound $Pig::sound = "oink"$::global_sound = "pigs do it better"# another "main" package variable # we‘re back to the default (main) package package mainprint "Cows go: ", $Cow::sound# prints "moo" print "\nPigs go: ", $Pig::sound# prints "oink" print "\nExtra sound: ", $extra_sound# prints "stampede" print "\nWhat‘s this I hear: ", $sound# $main::sound is undefined! print "\nEveryone says: ", $global_sound# prints "pigs do it better" 请注意,可以在所有三个包(“main”、“Pig”和“Cow”)中访问文件作用域内的词法变量 $extra_sound ,因为在该示例中它们是在同一文件中定义的。通常,每个包在它自己文件内部定义,以确保词法变量为该包所私有。这样就可以实现封装。(有关详细信息,请运行“ perldoc perlmod”。) 接下来,我们要将包与类关联。就 Perl 而言,类只是一个奇特的包(相反,对象由 bless() 函数特别创建)。同样,Perl 对 OOP 规则实施得不是很严格,以便程序员不为其所约束。 new() 方法是类构造器的惯用名称(尽管按照 Perl 惯有的不严格方式,您可以使用任意名称)。当将类实例化成对象时都要调用它。 清单2. barebones 类#!/usr/bin/perl -w package Barebonesuse strict# this class takes no constructor parameters sub new { my $classname = shift# we know our class name bless {}, $classname# and bless an anonymous hash } 1可以通过将清单 2 中的代码放入任何目录内名为 Barebones.pm 的文件中,然后在该目录中运行以下命令来测试该代码(这表示:“在库路径中包括当前目录,使用 Barebones 模块,然后创建一个新的 Barebones 对象”):perl -I. -MBarebones -e ‘my $b = Barebones->new()‘ 例如,可以在 new() 方法中放入 print 语句,以便看到 $classname 变量所拥有的内容。 如果调用 Barebones::new() 而不是 Barebones->new() ,类名将不会传递到 new() 。换句话说, new() 将不作为构造器,而只是普通的函数。 您可能要问:为什么需要传入 $classname 。为什么不直接用 bless {}, "Barebones"?因为继承的缘故,这个构造器可能被一个从 Barebones 继承、但名称却不是 Barebones 的类调用。您可能正在用错误的名称享有错误的事,而在 OOP 中,那是个坏主意。 除了new() 之外,每个类都需要成员数据和方法。定义它们就象编写几个过程一样简单。 清单3. 带有成员数据和方法的类#!/usr/bin/perl -w package Barebonesuse strictmy $count = 0# this class takes no constructor parameters sub new { my $classname = shift# we know our class name $count++# remember how many objects bless {}, $classname# and bless an anonymous hash } sub count { my $self = shift# this is the object itself return $count} 1可以用以下命令测试该代码:perl -I. -MBarebones -e ‘my $b = Barebones->new()Barebones->new()print $b->count‘ 您应该得到 ‘2‘ 这个结果。构造器被调用两次,它修改词法变量( $count),该变量被限制在 Barebones 包的作用域,而 不是每个Barebones 对象的作用域。应该将对象本身范围内的数据存储在对象本身中。在 Barebones 的示例中,被享有成对象的是匿名散列。请注意我们怎样才能在每次调用该对象的方法时访问该对象,因为对该对象的引用是传递给那些方法的第一个参数。 有几个特殊的方法,例如 DESTROY() 和AUTOLOAD(),Perl 在某些条件下会自动调用它们。 AUTOLOAD() 是用来允许动态方法名称的全捕获(catch-all)方法。 DESTROY() 是对象析构器,但是除非您确实非常非常需要,否则不应该使用它。在 Perl 中使用析构器通常表明您还在象 C/C++ 程序员那样考虑问题。 让我们看一下继承。在 Perl 中通过更改 @ISA 变量来这样做。您只需将一个类名表赋值给该变量即可。就是这样。您可以在 @ISA 中放入任何东西。您可以使您的类成为 Satan 的子类。Perl 不在乎(尽管您的牧师、部长、教长、犹太学者等可能在乎)。 清单4. 继承#!/usr/bin/perl -w package Barebones# add these lines to your module‘s beginning, before other code or # variable declarations require Animal# the parent class @ISA = qw(Animal)# announce we‘re a child of Animal # note that @ISA was left as a global default variable, and "use # strict" comes after its declaration. That‘s the easiest way to do it. use strictuse Carp# make your new() method look like this: sub new { my $proto = shiftmy $class = ref($proto) || $protomy $self = $class->SUPER::new()# use the parent‘s new() method bless ($self, $class)# but bless $self (an Animal) as Barebones } 1这些是 Perl 中 OOP 的最基本知识。Perl 语言中还有很多您应该探索的知识。人们已经撰写了很多有关这一主题的书籍。如果想阅读的话,请参考 参考资料。 回页首h2xs:您最好的新朋友您不想拥有一个可以为您编写 Perl 类、还可以编写文档(POD)框架并且通常可以通过正确地完成这些事而使您的生活轻松一些的工具吗?Perl 正好带有这种工具: h2xs。 别忘了使用几个重要标志:“ -A -n Module”。利用这些标志,h2xs 将生成一个名为“Module”、且里面全是有用文件的框架目录。这些文件是: Module.pm ,模块本身,带有已经编写好的框架文档。 Module.xs ,用于将您的模块与 C 代码链接。(有关详细信息,请运行“ perldoc perlxs”。) MANIFEST ,用于打包的文件列表。 test.pl ,框架测试脚本。 Changes ,对该模块所做更改的日志。 Makefile.PL,makefile 生成器(用“ perl Makefile.PL ”运行它。) 您无需使用所有这些文件,但是在您确实需要它们时知道它们在那里是很好的。

费良宏:程序员为什么要学深度学习?

深度学习本身是一个非常庞大的知识体系。本文更多想从程序员的视角出发,让大家观察一下深度学习对程序员意味着什么,以及我们如何利用这样一个高速发展的学科,来帮助程序员提升软件开发的能力。

本文根据费良宏在2016QCon全球软件开发大会(上海)上的演讲整理而成。

前言

1973年,美国上映了一部热门的科幻电影《WestWorld》,三年之后又有一个续集叫做《FutureWorld》。这部电影在80年代初被引进到中国叫《未来世界》。那部电影对我来讲简直可以说得上是震撼。影片中出现了很多机器人,表情丰富的面部下面都是集成电路板。这让那时候的我觉得未来世界都是那么遥远、那么神秘。

时间到了2016年,很多朋友可能都在追看HBO斥巨资拍摄的同一题材的系列剧《WestWorld》。如果前两部电影还是局限在机器人、人工智能这样的话题,2016年的新剧则在剧情和人工智能的思考方面有了很大的突破。不再渲染机器人是否会威胁到人类,而是在探讨“Dreamsaremainlymemories”这一类更具哲理的问题。

“记忆究竟如何影响了智能”这个话题非常值得我们去思考,也给我们一个很好的启示——今天,人工智能领域究竟有了怎样的发展和进步。

今天我们探讨的话题不仅仅是简单的人工智能。如果大家对深度学习感兴趣,我相信各位一定会在搜索引擎上搜索过类似相关的关键字。我在Google上以deeplearning作为关键字得到了2,630万个搜索的结果。这个数字比一周之前足足多出了300多万的结果。这个数字足以看得出来深度学习相关的内容发展的速度,人们对深度学习的关注也越来越高。

从另外的一个角度,我想让大家看看深度学习在市场上究竟有多么热门。从2011年到现在一共有140多家专注人工智能、深度学习相关的创业公司被收购。仅仅在2016年这种并购就发生了40多起。

其中最疯狂的是就是Google,已经收购了 11 家人工智能创业公司,其中最有名的就是击败了李世石九段的 DeepMind。排名之后的就要数 Apple、Intel以及Twitter。以Intel 公司为例,仅在今年就已经收购了 3 家创业公司,Itseez、Nervana 和 Movidius。这一系列大手笔的并购为了布局人工智能以及深度学习的领域。

当我们去搜索深度学习话题的时候,经常会看到这样的一些晦涩难懂的术语:Gradient descent(梯度下降算法)、Backpropagation(反向传播算法)、Convolutional Neural Network(卷积神经网络)、受限玻耳兹曼机(Restricted Boltzmann Machine)等。

如打开任何一篇技术文章,你看到的通篇都是各种数学公式。大家看到如下左边的图,其实并不是一篇高水准的学术论文,而仅仅是维基百科关于玻耳兹曼机的介绍。维基百科是科普层面的内容,内容复杂程度就超过了大多数数学知识的能力。

在这样的背景之下,我今天的的话题可以归纳成三点:第一,我们为什么要学习深度学习;第二,深度学习最核心的关键概念就是神经网络,那么究竟什么是神经网络;第三,作为程序员,当我们想要成为深度学习开发者的时候,我们需要具备怎样的工具箱,以及从哪里着手进行开发。

为什么要学习深度学习

首先,我们谈谈为什么要学习深度学习。在这个市场当中,最不缺乏的就是各种概念以及各种时髦新技术的词汇。深度学习有什么不一样的地方?我非常喜欢AndrewNg(吴恩达)曾经用过的一个比喻。

他把深度学习比喻成一个火箭。这个火箭有一个最重要的部分,就是它的引擎,目前来看在这个领域里面,引擎的核心就是神经网络。大家都知道,火箭除了引擎之外还需要有燃料,那么大数据其实就构成了整个火箭另外的重要组成部分——燃料。以往我们谈到大数据的时候,更多是强调存储和管理数据的能力,但是这些方法和工具更多是对于以往历史数据的统计、汇总。

而对于今后未知的东西,这些传统的方法并不能够帮助我们可以从大数据中得出预测的结论。如果考虑到神经网络和大数据结合,我们才可能看清楚大数据真正的价值和意义。AndrewNg就曾经说过“我们相信(神经网络代表的深度学习)是让我们获得最接近于人工智能的捷径”。这就是我们要学习深度学习的一个最重要的原因。

其次,随着我们进行数据处理以及运算能力的不断提升,深度学习所代表的人工智能技术和传统意义上人工智能技术比较起来,在性能上有了突飞猛进的发展。这主要得益于在过去几十间计算机和相关产业不断发展带来的成果。在人工智能的领域,性能是我们选择深度学习另一个重要的原因。

这是一段Nvidia在今年公布的关于深度学习在无人驾驶领域应用的视频。我们可以看到,将深度学习应用在自动驾驶方面,仅仅经历了3千英里的训练,就可以达到什么样的程度。在今年年初进行的实验上,这个系统还不具备真正智能能力,经常会出现各种各样的让人提心吊胆的状况,甚至在某些情况下还需要人工干预。

但经过了3千英里的训练之后,我们看到在山路、公路、泥地等各种复杂的路况下面,无人驾驶已经有了一个非常惊人的表现。请大家注意,这个深度学习的模型只经过了短短几个月、3千英里的训练。

如果我们不断完善这种模型的话,这种处理能力将会变得何等的强大。这个场景里面最重要的技术无疑就是深度学习。我们可以得出一个结论:深度学习可以为我们提供强大的能力,如果程序员拥有了这个技术的话,无异于会让每个程序员如虎添翼。

神经网络快速入门

如果我们对于学习深度学习没有任何疑虑的话,接下来就一定会关心我需要掌握什么样的知识才能让我进入到这个领域。这里面最重要的关键技术就是“神经网络”。说起“神经网络”,容易混淆是这样两个完全不同的概念。

一个是生物学神经网络,第二个才是我们今天要谈起的人工智能神经网络。可能在座的各位有朋友在从事人工智能方面的工作。当你向他请教神经网络的时候,他会抛出许多陌生的概念和术语让你听起来云里雾里,而你只能望而却步了。

对于人工智能神经网络这个概念,大多数的程序员都会觉得距离自己有很大的距离。因为很难有人愿意花时间跟你分享神经网络的本质究竟是什么。而你从书本上读的到的理论和概念,也很让你找到一个清晰、简单的结论。

今天就我们来看一看,从程序员角度出发神经网络究竟是什么。我第一次知道神经网络这个概念是通过一部电影——1991年上映的《终结者2》。男主角施瓦辛格有一句台词:

“MyCPUisaneural-netprocessoralearningcomputer.”(我的处理器是一个神经处理单元,它是一台可以学习的计算机)。从历史来看人类对自身智力的探索,远远早于对于神经网络的研究。

1852年,意大利学者因为一个偶然的失误,将人类的头颅掉到硝酸盐溶液中,从而获得第一次通过肉眼关注神经网络的机会。这个意外加速了对人类智力奥秘的探索,开启了人工智能、神经元这样概念的发展。

生物神经网络这个概念的发展,和今天我们谈的神经网络有什么关系吗?我们今天谈到的神经网络,除了在部分名词上借鉴了生物学神经网络之外,跟生物学神经网络已经没有任何关系,它已经完全是数学和计算机领域的概念,这也是人工智能发展成熟的标志。这点大家要区分开,不要把生物神经网络跟我们今天谈到的人工智能有任何的混淆。

90年代中期,由Vapnik等人提出了支持向量机算法(Support Vector Machines,支持向量机)。很快这个算法就在很多方面体现出了对比神经网络的巨大优势,例如:无需调参、高效率、全局最优解等。基于这些理由,SVM算法迅速打败了神经网络算法成为那个时期的主流。而神经网络的研究则再次陷入了冰河期。

在被人摒弃的十年里面,有几个学者仍然在坚持研究。其中很重要的一个人就是加拿大多伦多大学的Geoffery Hinton教授。2006年,他的在著名的《Science》杂志上发表了论文,首次提出了“深度信念网络”的概念。

与传统的训练方式不同,“深度信念网络”有一个“预训练”(pre-training)的过程,这可以方便的让神经网络中的权值找到一个接近最优解的值,之后再使用“微调”(fine-tuning)技术来对整个网络进行优化训练。这两个技术的运用大幅度减少了训练多层神经网络的时间。在他的论文里面,他给多层神经网络相关的学习方法赋予了一个新名词— “深度学习”。

很快,深度学习在语音识别领域崭露头角。接着在2012年,深度学习技术又在图像识别领域大展拳脚。Hinton与他的学生在ImageNet竞赛中,用多层的卷积神经网络成功地对包含一千个类别的一百万张图片进行了训练,取得了分类错误率15%的好成绩,这个成绩比第二名高了将近11个百分点。

这个结果充分证明了多层神经网络识别效果的优越性。从那时起,深度学习就开启了新的一段黄金时期。我们看到今天深度学习和神经网络的火热发展,就是从那个时候开始引爆的。

利用神经网络构建分类器,这个神经网络的结构是怎样的?

其实这个结构非常简单,我们看到这个图就是简单神经网络的示意图。神经网络本质上就是一种“有向图”。图上的每个节点借用了生物学的术语就有了一个新的名词 – “神经元”。连接神经元的具有指向性的连线(有向弧)则被看作是“神经”。这这个图上神经元并不是最重要的,最重要的是连接神经元的神经。每个神经部分有指向性,每一个神经元会指向下一层的节点。

节点是分层的,每个节点指向上一层节点。同层节点没有连接,并且不能越过上一层节点。每个弧上有一个值,我们通常称之为”权重“。通过权重就可以有一个公式计算出它们所指的节点的值。这个权重值是多少?我们是通过训练得出结果。它们的初始赋值往往通过随机数开始,然后训练得到的最逼近真实值的结果作为模型,并可以被反复使用。这个结果就是我们说的训练过的分类器。

节点分成输入节点和输出节点,中间称为隐层。简单来说,我们有数据输入项,中间不同的多个层次的神经网络层次,就是我们说的隐层。之所以在这样称呼,因为对我们来讲这些层次是不可见的。输出结果也被称作输出节点,输出节点是有限的数量,输入节点也是有限数量,隐层是我们可以设计的模型部分,这就是最简单的神经网络概念。

如果简单做一个简单的类比,我想用四层神经网络做一个解释。左边是输入节点,我们看到有若干输入项,这可能代表不同苹果的RGB值、味道或者其它输入进来的数据项。中间隐层就是我们设计出来的神经网络,这个网络现在有不同的层次,层次之间权重是我们不断训练获得一个结果。

最后输出的结果,保存在输出节点里面,每一次像一个流向一样,神经是有一个指向的,通过不同层进行不同的计算。在隐层当中,每一个节点输入的结果计算之后作为下一层的输入项,最终结果会保存在输出节点上,输出值最接近我们的分类,得到某一个值,就被分成某一类。这就是使用神经网络的简单概述。

除了从左到右的形式表达的结构图,还有一种常见的表达形式是从下到上来表示一个神经网络。这时候,输入层在图的最下方,输出层则在图的最上方。从左到右的表达形式以AndrewNg和LeCun的文献使用较多。而在Caffe框架里则使用的则是从下到上的表达。

简单来说,神经网络并不神秘,它就是有像图,利用图的处理能力帮助我们对特征的提取和学习的过程。2006年Hinton的那篇著名的论文中,将深度学习总结成三个最重要的要素:计算、数据、模型。有了这三点,就可以实现一个深度学习的系统。

程序员需要的工具箱

对于程序员来说,掌握理论知识是为了更好的编程实践。那就让我们看看,对于程序员来说,着手深度学习的实践需要准备什么样的工具。

硬件

从硬件来讲,我们可能需要的计算能力,首先想到的就是CPU。除了通常的CPU架构以外,还出现了附加有乘法器的CPU,用以提升计算能力。此外在不同领域会有DSP的应用场景,比如手写体识别、语音识别、等使用的专用的信号处理器。还有一类就是GPU,这是一个目前深度学习应用比较热门的领域。最后一类就是FPGA(可编程逻辑门阵列)。

这四种方法各有其优缺点,每种产品会有很大的差异。相比较而言CPU虽然运算能力弱一些,但是擅长管理和调度,比如读取数据,管理文件,人机交互等,工具也丰富。DSP相比而言管理能力较弱,但是强化了特定的运算能力。

这两者都是靠高主频来解决运算量的问题,适合有大量递归 *** 作以及不便拆分的算法。GPU的管理能力更弱一些,但是运算能力更强。但由于计算单元数量多,更适合整块数据进行流处理的算法。

FPGA在管理与运算处理方面都很强,但是开发周期长,复杂算法开发难度较大。就实时性来说,FPGA是最高的。单从目前的发展来看,对于普通程序员来说,现实中普遍采用的计算资源就还是是CPU以及GPU的模式,其中GPU是最热门的领域。

这是我前天为这次分享而准备的一个AWS 上p2的实例。仅仅通过几条命令就完成了实例的更新、驱动的安装和环境的设置,总共的资源创建、设置时间大概在10分钟以内。而之前,我安装调试前面提到的那台计算机,足足花了我两天时间。

另外,从成本上还可以做一个对比。p2.8xLarge 实例每小时的费用是7.2美元。而我自己那台计算机总共的花费了是¥16,904元。这个成本足够让我使用350多个小时的p2.8xLarge。在一年里使用AWS深度学习站就可以抵消掉我所有的付出。随着技术的不断的升级换代,我可以不断的升级我的实例,从而可以用有限的成本获得更大、更多的处理资源。这其实也是云计算的价值所在。

云计算和深度学习究竟有什么关系?今年的8月8号,在IDG网站上发表了一篇文章谈到了这个话题。文章中做了这样一个预言:如果深度学习的并行能力不断提高,云计算所提供的处理能力也不断发展,两者结合可能会产生新一代的深度学习,将带来更大影响和冲击。这是需要大家考虑和重视的一个方向!

软件

深度学习除了硬件的基础环境之外。程序员会更关心与开发相关的软件资源。这里我罗列了一些曾经使用过的软件框架和工具。

Scikit-learn是最为流行的一个Python机器学习库。它具有如下吸引人的特点:简单、高效且异常丰富的数据挖掘/数据分析算法实现; 基于NumPy、SciPy以及matplotlib,从数据探索性分析,数据可视化到算法实现,整个过程一体化实现;开源,有非常丰富的学习文档。

Caffe专注在卷及神经网络以及图像处理。不过Caffe已经很久没有更新过了。这个框架的一个主要的开发者贾扬清也在今年跳槽去了Google。也许曾经的霸主地位要让位给他人了。

Theano 是一个非常灵活的Python 机器学习的库。在研究领域非常流行,使用上非常方便易于定义复杂的模型。Tensorflow 的API 非常类似于Theano。我在今年北京的QCon 大会上也分享过关于Theano 的话题。

Jupyter notebook 是一个很强大的基于ipython的python代码编辑器,部署在网页上,可以非常方便的进行交互式的处理,很适合进行算法研究合数据处理。

Torch 是一个非常出色的机器学习的库。它是由一个比较小众的lua语言实现的。但是因为LuaJIT 的使用,程序的效率非常出色。Facebook在人工智能领域主打Torch,甚至现在推出了自己的升级版框架Torchnet。

深度学习的框架非常之多,是不是有一种乱花渐欲迷人眼的感觉?我今天向各位程序员重点介绍的是将是TensorFlow。这是2015年谷歌推出的开源的面向机器学习的开发框架,这也是Google第二代的深度学习的框架。很多公司都使用了TensorFlow开发了很多有意思的应用,效果很好。

用TensorFlow可以做什么?答案是它可以应用于回归模型、神经网络以深度学习这几个领域。在深度学习方面它集成了分布式表示、卷积神经网络(CNN)、递归神经网络(RNN) 以及长短期记忆人工神经网络(Long-Short Term Memory, LSTM)。

关于Tensorflow 首先要理解的概念就是Tensor。在辞典中对于这个词的定义是张量,是一个可用来表示在一些向量、标量和其他张量之间的线性关系的多线性函数。实际上这个表述很难理解,用我自己的语言解释Tensor 就是“N维数组”而已。

使用 TensorFlow, 作为程序员必须明白 TensorFlow这样几个基础概念:它使用图 (Graph) 来表示计算任务;在被称之为 会话 (Session) 的上下文 (context) 中执行图;使用 Tensor 表示数据;通过 变量 (Variable) 维护状态;使用 feed 和 fetch 可以为任意的 *** 作(arbitrary operation) 赋值或者从其中获取数据。

一句话总结就是,TensorFlow 就是有状态图的数据流图计算环境,每个节点就是在做数据 *** 作,然后提供依赖性和指向性,提供完整数据流。

TensorFlow安装非常简单,但官网提供下载的安装包所支持的CUDA 的版本是7.5。考虑到CUDA 8 的让人心动的新特以及不久就要正式发布的现状。或许你想会考虑立即体验CUDA 8,那么就只能通过编译Tensorflow源代码而获得。目前TensorFlow已经支持了Python2.7、3.3+。

此外,对于使用Python 语言的程序员还需要安装所需要的一些库,例如:numpy、protobuf等等。对于卷积处理而言,cuDNN是公认的性能最好的开发库,请一定要安装上。常规的Tensorsorflow的安装很简单,一条命令足矣:

$ pip3 install —upgrade https://storage.233.wiki/tensorflow/linux/cpu/tensorflow-0.11.0rc0-cp35-cp35m-linux_x86_64.whl

如果想评估一下或者简单学习一下,还可以通过Docker进行安装,安装的命令如下:

$ docker run -it -p 8888:8888 gcr.io/tensorflow/tensorflow

TensorFlow有很多优点。首先,目前为止,深度学习的开发框架里面TensorFlow的文档做的最好,对程序员学习而言是非常好的一点。第二,TensorFlow有丰富的参考实例,作为参考学习起来非常容易。

第三,开发者社区活跃,在任何一个深度学习的社区里,都有大量关于TensorFlow的讨论。第四,谷歌的支持力度非常大,从2015年到现在升级速度非常快,这是其他开源框架远远达不到的结果。

参考TensorFlow的白皮书,我们会看到未来TensorFlow还将会有巨大的发展潜力。让我特别感兴趣是这两个方向。第一,支持跨多台机器的 parallelisation。尽管在0.8版本中推出了并行化的能力,但是目前还不完善。随着未来不断发展,依托云计算的处理能力的提升这个特性将是非常让人振奋的。

第二,支持更多的开发语言,对于开发者来说这是一个绝大的利好,通过使用自己擅长的语言使用TensorFlow应用。这些开发语言将会扩展到Java、Lua以及R 等。

在这里我想给大家展示一个应用Tensorflow 的例子。这个例子的代码托管在这个网址上 https://github.com/anishathalye/neural-style。白俄罗斯的现代印象派艺术家Leonid Afremov善于用浓墨重彩来表现都市和风景题材,尤其是其雨景系列作品。他习惯用大色块的铺陈来营造光影效果,对反光物体和环境色的把握非常精准。

于是我就找到了一张上海东方明珠电视塔的一张摄影作品,我希望通过Tensorflow 去学习一下Leonid Afremov 的绘画风格,并将这张东方明珠的照片处理成那种光影色彩丰富的作品风格。利用Tensorflow 以及上面提到的那个项目的代码,在一个AWS 的p2类型的实例上进行了一个一千次的迭代,于是就得到了下图这样的处理结果。

这个处理的代码只有350行里,模型使用了一个成名于2014年ImageNet比赛中的明星 VGG。这个模型非常好,特点就是“go depper”。

TensorFlow 做出这样的作品,并不仅仅作为娱乐供大家一笑,还可以做更多有意思的事情。将刚才的处理能力推广到视频当中,就可以看到下图这样的效果,用梵高著名的作品”星月夜“的风格就加工成了这样新的视频风格。

可以想象一下,如果这种处理能力在更多领域得以应用,它会产生什么样的神奇结果?前景是美好的,让我们有无限遐想。事实上我们目前所从事的很多领域的应用开发都可以通过使用神经网络和深度学习来加以改变。对于深度学习而言,掌握它并不是难事。每一个程序员都可以很容易的掌握这种技术,利用所具备的资源,让我们很快成为深度学习的程序开发人员。

结束语

未来究竟是什么样,我们没有办法预言。有位作家Ray Kurzweil在2005年写了《奇点临近》一书。在这本书里面他明确告诉我们,那个时代很快到来。作为那个时代曙光前的人群,我们是不是有能力加速这个过程,利用我们学习的能力实现这个梦想呢?

中国人工智能的发展

人工智能的时代无疑已经到来,这个时代需要的当然就是掌握了人工智能并将其解决具体问题的工程师。坦率的说,市场上这一类的工程师还属于凤毛麟角。职场上的薪酬待遇可以看得出来这样的工程师的抢手的程度。人工智能这门学科发展到今天,就学术自身而言已经具备了大规模产业化的能力。

所以说,对于工程师而言当务之急就是尽快的掌握应用人工智能的应用技术。当下在互联网上关于人工智能的学习资料可以说已经是“汗牛充栋”,那些具备了快速学习能力的工程师一定会在人工智能的大潮当中脱颖而出。

中国发展人工智能产业的环境已经具备。无论从创业环境、人员的素质乃至市场的机遇而言完全具备了产生产业变革的一切条件。与美国相比较,在人工智能的许多领域中国团队的表现也可以说是不逞多让。就人工智能的技术层面而言,中国的工程师与全球最好的技术团队正处于同一个起跑线上。

时不我待,中国的工程师是有机会在这个领域大展身手的。不过值得注意的是,要切忌两点:一是好高骛远,盲目与国外攀比。毕竟积累有长短,术业有专攻,我们要立足于已有的积累,寻求逐步的突破。二是一拥而上,盲目追求市场的风口。人工智能的工程化需要大量的基础性的积累,并非一蹴而就简单复制就可以成功。

中国的科研技术人员在人工智能领域的成就有目共睹。在王咏刚的一篇文章里面,他统计了从2013年到2015年SCI收录的“深度学习”论文,中国在2014年和2015年超已经超过了美国居于领跑者的位置。

另外一让我感到惊讶的事情,Google的JeffDean在2016年发表过一篇名为《TensorFlow:Asystemforlarge-scalemachinelearning》的论文。文章的22个作者里面,明显是中国名字的作者占已经到了1/5。如果要列举中国人/华人在人工智能领域里的大牛,吴恩达、孙剑、杨强、黄广斌、马毅、张大鹏……很容易就可以说出一大串。

对于中国来说目前的当务之急是人工智能技术的产业化,唯有如此我们才可以讲科研/智力领域的优势转化为整体的、全面的优势。在这一点上,中国是全球最大的消费市场以及制造业强国,我们完全有机会借助市场的优势成为这个领域的领先者。

硅谷创新企业

硅谷虽然去过许多回,但一直无缘在那里长期工作。在人工智能领域的市场我们听到的更多是围绕Google、Apple、Intel、Amazon这样的一些大型科技公司的一举一动。但是在美国市场上还有一大批小型的创业企业在人工智能这个领域有惊艳的表现。仅以硅谷区域的公司为例:

Captricity,提供了手写数据的信息提取;

VIVLab,针对语音识别开发了虚拟助手服务;

TERADEEP,利用FPGA提供了高效的卷积神经网络的方案;

还有提供无人驾驶解决方案的NetraDyne。

这个名单还可以很长,还有许许多多正在利用人工智能技术试图去创造历史的团队正在打造他们的梦想。这些团队以及他们正在专注的领域是值得我们去学习和体会的。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11033702.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存