首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

python spark 随机森林入门demo

classpyspark.mllib.tree.RandomForest[source] Learning algorithm for a random forest model for classification or regression. New in version 1.2.0. supportedFeatureSubsetStrategies = ('auto', 'all', 'sqrt', 'log2', 'onethird') classmethodtrainClassifier( data, numClasses, categoricalFeaturesInfo, numTrees, featureSubsetStrategy='auto', impurity='gini', maxDepth=4, maxBins=32, seed=None) [source] Train a random forest model for binary or multiclass classification. Parameters: data– Training dataset: RDD of LabeledPoint. Labels should take values {0, 1, ..., numClasses-1}. numClasses– Number of classes for classification. categoricalFeaturesInfo– Map storing arity of categorical features. An entry (n -> k) indicates that feature n is categorical with k categories indexed from 0: {0, 1, ..., k-1}. numTrees– Number of trees in the random forest. featureSubsetStrategy– Number of features to consider for splits at each node. Supported values: “auto”, “all”, “sqrt”, “log2”, “onethird”. If “auto” is set, this parameter is set based on numTrees: if numTrees == 1, set to “all”; if numTrees > 1 (forest) set to “sqrt”. (default: “auto”) impurity– Criterion used for information gain calculation. Supported values: “gini” or “entropy”. (default: “gini”) maxDepth– Maximum depth of tree (e.g. depth 0 means 1 leaf node, depth 1 means 1 internal node + 2 leaf nodes). (default: 4) maxBins– Maximum number of bins used for splitting features. (default: 32) seed– Random seed for bootstrapping and choosing feature subsets. Set as None to generate seed based on system time. (default: None) Returns: RandomForestModel that can be used for prediction. Example usage: >>> from pyspark.mllib.regression import LabeledPoint >>> from pyspark.mllib.tree import RandomForest >>> >>> data = [ ... LabeledPoint(0.0, [0.0]), ... LabeledPoint(0.0, [1.0]), ... LabeledPoint(1.0, [2.0]), ... LabeledPoint(1.0, [3.0]) ... ] >>> model = RandomForest.trainClassifier(sc.parallelize(data), 2, {}, 3, seed=42) >>> model.numTrees() 3 >>> model.totalNumNodes() 7 >>> print(model) TreeEnsembleModel classifier with 3 trees >>> print(model.toDebugString()) TreeEnsembleModel classifier with 3 trees Tree 0: Predict: 1.0 Tree 1: If (feature 0 <= 1.0) Predict: 0.0 Else (feature 0 > 1.0) Predict: 1.0 Tree 2: If (feature 0 <= 1.0) Predict: 0.0 Else (feature 0 > 1.0) Predict: 1.0 >>> model.predict([2.0]) 1.0 >>> model.predict([0.0]) 0.0 >>> rdd = sc.parallelize([[3.0], [1.0]]) >>> model.predict(rdd).collect() [1.0, 0.0] New in version 1.2.0. 摘自:https://spark.apache.org/docs/latest/api/python/pyspark.mllib.html#pyspark.mllib.tree.DecisionTree 本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/7150484.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android硬件入门-照相机

学习Android不能不学习照相机,现在各种美容相机,微信朋友圈发图,现在升级之后直接下拉就可以照相了,各种艳照的的源头也是照相机,扯远了,有点邪恶了,还是简单学习一下Android中照相机的使用,Android中照相机的使用一般分为两种使用已有的照相App(可以理解为系统内置的照相机)和单独创建一个照相App,第一种方式简单易懂,第二种方式如果做的好的话可以养活一个公司~今天就简单的描述一下第一种的调用~ 基础工作 调用照相机需要照相,照相就需要存储,存在外部存储中需要设置权限,本次设置的三个权限:一个是调用Camera权限,第二个是要求设备有照相机,第三个是在外部设备写的权限: 1 2 3 4 5 <uses-permission android:name= "android.permission.CAMERA" /> <uses-feature android:name= "android.hardware.camera" /> <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" /> 简单的页面,一个Buttom,一个ImageView: Demo实现 简单的三部曲,首先创建Intent,然后启动Intent,最后接收结果,没有前置摄像头,就用的是模拟的: 拍照事件: 1 2 3 4 5 6 7 public void cameraEvent(View view) { intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 创建一个意图去获取图片 file= getOutputMediaFile(); // 获取路径 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // 设置文件名 // 启动Intent startActivityForResult(intent, IMAGE_REQUEST_CODE); } 获取文件路径的方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // 图片路径 private static File getOutputMediaFile() { File mediaStorageDir = new File( Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), tag); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d(tag, "存储目录创建失败" ); return null ; } } // 创建文件名 String timeStamp = new SimpleDateFormat( "yyyyMMdd_HHmmss" ) .format( new Date()); File mediaFile = null ; mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg" ); Log.d(tag, "存储目录:" + mediaFile); return mediaFile; } 完成之后的接收事件需要重写Activity中的onActivityResult方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 @Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub if (requestCode == IMAGE_REQUEST_CODE&&resultCode==RESULT_OK) { imageView=(ImageView) findViewById(R.id.camera_img); //两种设置方式 //图片较大的时候可以使用这种 Bitmap bitmap=BitmapFactory.decodeFile(file.toString()); imageView.setImageBitmap(bitmap); // imageView.setImageURI(Uri.fromFile(file)); } super .onActivityResult(requestCode, resultCode, data); } 效果如下: 本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4086004.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

docker入门1 : 使用docker镜像

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26654727/article/details/78360027 持续更新中………. 1.安装docker centos7 内核版本在3.10.0-693.el7.x86_64之上的直接执行: yum install docker -y 即可 本机版本3.10.0-693.el7.x86_64 直接执行yum install docker -y centos7 若centos版本在centos6,则需要更新内核版本才可以安装docker。 2.使用docker镜像 2.1 安装docker镜像 使用docker pull Name[:TAG] 安装指定镜像的名称和版本号 安装centos最近版本的镜像,从docker默认镜像库进行下载 命令: sudo docker pull centos Using default tag: latest Trying to pull repository docker.io/library/centos ... latest: Pulling from docker.io/library/centos d9aaf4d82f24: Pull complete Digest: sha256:eba772bac22c86d7d6e72421b4700c3f894ab6e35475a34014ff8de74c10872e 创建成功之后,我们就开始使用该镜像创建一个容器,并在该容器中进行操作。 docker run -it centos bash [root@localhost sysconfig]# docker run -it centos bash [root@fc99abc4213f /]# ls anaconda-post.log dev home lib64 media opt root sbin sys usr bin etc lib lost+found mnt proc run srv tmp var [root@fc99abc4213f /]# ping localhost PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.105 ms 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.062 ms 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.083 ms ^C --- localhost ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.062/0.083/0.105/0.019 ms [root@fc99abc4213f /]# exit exit 2.2 查看镜像信息 2.2.1 使用命令 docker images 查看当前镜像信息 [root@localhost sysconfig]# sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/redis 3.2 4ae3b93617bd 2 weeks ago 99.67 MB docker.io/centos latest 196e0ce0c9fb 5 weeks ago 196.6 MB images 子命令主要支持如下的选项: (1) -a ,–all=true|false 列出所有的镜像文件 (2) –digests=true|false 列出镜像的数字摘要值,默认为否 (3) -f –filter=[] 过滤列出的镜像 … 2.2.2 使用tag命令添加镜像标签 [root@localhost sysconfig]# docker tag redis:3.2 myredis:0.1 [root@localhost sysconfig]# sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/redis 3.2 4ae3b93617bd 2 weeks ago 99.67 MB myredis 0.1 4ae3b93617bd 2 weeks ago 99.67 MB docker.io/centos latest 196e0ce0c9fb 5 weeks ago 196.6 MB 2.2.3 使用inspect 命令查看详细信息 查看详细信息 [root@localhost sysconfig]# docker inspect myredis:0.1 [ { "Id": "sha256:4ae3b93617bdb7cc7559c021cd57fec2db465daf94e717b61282406b74493941", "RepoTags": [ "docker.io/redis:3.2", "myredis:0.1" ], "RepoDigests": [ "docker.io/redis@sha256:b15e3fabba806a6ee7f14774df0c2dc3036f752969bcdac022f0aa96d5cfc954" ], "Parent": "", "Comment": "", "Created": "2017-10-10T02:50:23.955973925Z", "Container": "13285f8661db6019c0916f3252c76c17bad6508905a319358c85f7acf7967365", "ContainerConfig": { "Hostname": "13285f8661db", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "6379/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "GOSU_VERSION=1.10", "REDIS_VERSION=3.2.11", "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.2.11.tar.gz", "REDIS_DOWNLOAD_SHA=31ae927cab09f90c9ca5954aab7aeecc3bb4da6087d3d12ba0a929ceb54081b5" ], "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"redis-server\"]" ], "ArgsEscaped": true, "Image": "sha256:0d4214b1bf00a587daa1d4f36421bd99e4b2c316249280675bec34faaa6d6e0d", "Volumes": { "/data": {} }, "WorkingDir": "/data", "Entrypoint": [ "docker-entrypoint.sh" ], "OnBuild": [], "Labels": {} }, "DockerVersion": "17.06.2-ce", "Author": "", "Config": { "Hostname": "", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "6379/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "GOSU_VERSION=1.10", "REDIS_VERSION=3.2.11", "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.2.11.tar.gz", "REDIS_DOWNLOAD_SHA=31ae927cab09f90c9ca5954aab7aeecc3bb4da6087d3d12ba0a929ceb54081b5" ], "Cmd": [ "redis-server" ], "ArgsEscaped": true, "Image": "sha256:0d4214b1bf00a587daa1d4f36421bd99e4b2c316249280675bec34faaa6d6e0d", "Volumes": { "/data": {} }, "WorkingDir": "/data", "Entrypoint": [ "docker-entrypoint.sh" ], "OnBuild": [], "Labels": null }, "Architecture": "amd64", "Os": "linux", "Size": 99668649, "VirtualSize": 99668649, "GraphDriver": { "Name": "devicemapper", "Data": { "DeviceId": "10", "DeviceName": "docker-253:0-33690427-dea7d2d0030dc44a3edf0fcc80077d715d5ccf4825a3db161da84436cf1dcdc7", "DeviceSize": "10737418240" } }, "RootFS": { "Type": "layers", "Layers": [ "sha256:29d71372a4920ec230739a9e2317e7e9b18644edb10f78cde85df85e6ab85fc2", "sha256:f5ccc3ab98cc45041bcf1f2cf49afb7e5046316af795c88ef6be50ed149cc3a4", "sha256:3fae9b7c819afb850f999670dc88cc3f646a146c379103c8947df99c03498ebe", "sha256:7044a5153c6481a7284e181703432930f392aa39fb12982c9a2d8cb2f2448cb0", "sha256:7768d1f84ecca49f4ca1005047f7d5d8a3a009dfb3e0213cdbbb3856f7e4c115", "sha256:327ce591d4be258dd33151003eebd5cc362fd6caed83f9a5512b7970a8f5facb" ] } } ] 查看某一个参数信息 “docker inspect -f {{“.Os”}} myredis:0.1 ” “` [root@localhost sysconfig]# docker inspect -f {{“.Os”}} myredis:0.1 linux [root@localhost sysconfig]# docker inspect -f {{“.Size”}} myredis:0.1 99668649 2.3搜索镜像 docker search redis -a 10 [root@localhost ~]# sudo docker search redis -s 10 Flag --stars has been deprecated, use --filter=stars=3 instead INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED docker.io docker.io/redis Redis is an open source key-value store th... 4359 [OK] docker.io docker.io/bitnami/redis Bitnami Redis Docker Image 59 [OK] docker.io docker.io/sameersbn/redis 59 [OK] docker.io docker.io/tenstartups/redis-commander 29 [OK] docker.io docker.io/kubeguide/redis-master redis-master with "Hello World!" 19 docker.io docker.io/joshula/redis-sentinel A container for Redis Sentinel 18 docker.io docker.io/kubeguide/guestbook-redis-slave Guestbook redis slave 14 docker.io docker.io/tutum/redis Base docker image to run a Redis server 10 2.4删除镜像 删除镜像分为两种方式进行删除,分别为: a.使用标签进行删除 使用标签进行删除时,如果存在由该镜像创建的多个标签的镜像,删除其中的一个并不会删除该镜像,只有该镜像只有唯一的一个标签时,删除该标签将会导致该镜像彻底删除。 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/redis 3.2 4ae3b93617bd 2 weeks ago 99.67 MB myredis 0.2 4ae3b93617bd 2 weeks ago 99.67 MB myredis 0.3 4ae3b93617bd 2 weeks ago 99.67 MB [root@localhost ~]# docker rmi myredis:0.2 Untagged: myredis:0.2 [root@localhost ~]# docker rmi myredis:0.3 Untagged: myredis:0.3 Untagged: docker.io/redis@sha256:b15e3fabba806a6ee7f14774df0c2dc3036f752969bcdac022f0aa96d5cfc954 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/redis 3.2 4ae3b93617bd 2 weeks ago 99.67 MB [root@localhost ~]# docker rmi redis Error response from daemon: No such image: redis:latest [root@localhost ~]# docker rmi redis:3.2 Untagged: redis:3.2 Deleted: sha256:4ae3b93617bdb7cc7559c021cd57fec2db465daf94e717b61282406b74493941 Deleted: sha256:23434bfcd3a31cd975c6384253ba687fbcbd895b3e1a54af27824af9ed937591 Deleted: sha256:0d30a0d1a42e43f5dc11264673fd4ee56a03095dbcd3da72924870de4df577aa Deleted: sha256:3a6d079caad238a31ea4283d4fc3f443d6e75bb1d3ce199cd916dc49627c5931 Deleted: sha256:5b3c3d58e5f9d9460b356d01329f9016fbb1959bf1522f357fb81a2db362908b Deleted: sha256:a895b72388eb73dd9fb4406a318ee67fe48c7e70e01190c8f2ac4310dc529245 Deleted: sha256:29d71372a4920ec230739a9e2317e7e9b18644edb10f78cde85df85e6ab85fc2 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE b.使用id进行删除 在删除镜像时,若该镜像创建了一个容器。且该容器存在时,则无法对该镜像进行删除。如若希望强制删除,则使用命令docker rmi -f [image] [root@localhost ~]# docker rmi 196e0ce0c9fb Error response from daemon: conflict: unable to delete 196e0ce0c9fb (must be forced) - image is being used by stopped container fc99abc4213f [root@localhost ~]# docker rmi -f 196e0ce0c9fb Untagged: docker.io/centos:latest Deleted: sha256:196e0ce0c9fbb31da595b893dd39bc9fd4aa78a474bbdc21459a3ebe855b7768 [root@localhost ~]# 2.5创建镜像 创建镜像主要有三种方式 a.使用容器创建镜像。 [root@localhost ~]# docker run -it centos bash WARNING: IPv4 forwarding is disabled. Networking will not work. [root@1ed5befe7051 /]# useradd nrs [root@1ed5befe7051 /]# exit exit [root@localhost ~]# docker commit -m "add user nrs" -a "augus" 1ed5befe7051 mycentos:01 sha256:a154ae24d66d16201ba1bed9112e2cab11714644364b5bccef0d2ea2b1b3c443 [root@localhost ~]# b.使用本地模板创建镜像 c.使用dockerFile创建镜像 2.6镜像的载入和写出 镜像的写出 docker save -o centos.01.tar centos:01 镜像的载入 docker load –input centos.01.tar [augus@localhost ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 01 a154ae24d66d 30 minutes ago 196.9 MB docker.io/centos latest 196e0ce0c9fb 6 weeks ago 196.6 MB [augus@localhost ~]$ docker save -o mycentos.01.tar mycentos:01 [augus@localhost ~]$ ls mycentos.01.tar precreated [augus@localhost ~]$ docker load --input mycentos.01.tar Loaded image: mycentos:01 [augus@localhost ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 01 a154ae24d66d 32 minutes ago 196.9 MB docker.io/centos latest 196e0ce0c9fb 6 weeks ago 196.6 MB [augus@localhost ~]$ docker rmi mycentos:01 Untagged: mycentos:01 Deleted: sha256:a154ae24d66d16201ba1bed9112e2cab11714644364b5bccef0d2ea2b1b3c443 Deleted: sha256:5d58cde1df9c759667826244365052df54e7920391e72f8cdd1a3d1d35bc5bba [augus@localhost ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest 196e0ce0c9fb 6 weeks ago 196.6 MB [augus@localhost ~]$ docker load --input mycentos.01.tar edfd6667dbbb: Loading layer [==================================================>] 312.8 kB/312.8 kB Loaded image: mycentos:01 [augus@localhost ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 01 a154ae24d66d 33 minutes ago 196.9 MB docker.io/centos latest 196e0ce0c9fb 6 weeks ago 196.6 MB [augus@localhost ~]$

优秀的个人博客,低调大师

NLP入门之语音模型原理

这一篇文章其实是参考了很多篇文章之后写出的一篇对于语言模型的一篇科普文,目的是希望大家可以对于语言模型有着更好地理解,从而在接下来的NLP学习中可以更顺利的学习. 1:传统的语音识别方法: 这里我们讲解一下是如何将声音变成文字,如果有兴趣的同学,我们可以深入的研究. 首先我们知道声音其实是一种波,常见的MP3等都是压缩的格式,必须要转化成非压缩的纯波形的文件来处理,下面以WAV的波形文件来示例: 在进行语音识别之前,有的需要把首尾段的静音进行切除,进行强制对齐,以此来降低对于后续步骤的干扰,整个静音的切除技术一般称为VAD,需要用到对于信号处理的一些技术. 如果要对于声音进行分析,就需要对于声音进行分帧,也就是把声音切成一小块一小块,每一小块称为一帧,分帧并不是简单地切开,而是使用的移动窗函数来实现的,并且帧和帧之间一般是有交叠的 就像上图这样 分帧之后,语音就变成了很多个小段,但是波形在时域上是没有什么描述能力的,因此就必须要将波形进行变换,常见的一种变换方法就是提取MFCC特征,然后根据人耳的生理特性,把每一帧波变成一个多维度向量,这个向量里是包含了这块语音的内容信息,这个过程叫做声学特征的提取,但是实际方法有很多,基本类似. 至此,声音就成了一个12行(假设声学特征是12维)、N列的一个矩阵,称之为观察序列,这里N为总帧数。观察序列如下图所示,图中,每一帧都用一个12维的向量表示,色块的颜色深浅表示向量值的大小。 接下来就要介绍怎样把这个矩阵变成文本了。首先要介绍两个概念: 1:音素: 单词的发音由音素构成。对英语,一种常用的音素集是卡内基梅隆大学的一套由39个音素构成的音素集,参见The CMU Pronouncing Dictionary‎。汉语一般直接用全部声母和韵母作为音素集,另外汉语识别还分有调无调,不详述。 1. 状态:这里理解成比音素更细致的语音单位就行啦。通常把一个音素划分成3个状态。 语音识别是怎么工作的呢?实际上一点都不神秘,无非是: 把帧识别成状态(难点)。 把状态组合成音素。 把音素组合成单词。 如下图所示: 图中,每个小竖条代表一帧,若干帧语音对应一个状态,每三个状态组合成一个音素,若干个音素组合成一个单词。也就是说,只要知道每帧语音对应哪个状态了,语音识别的结果也就出来了。 那每帧音素对应哪个状态呢?有个容易想到的办法,看某帧对应哪个状态的概率最大,那这帧就属于哪个状态。比如下面的示意图,这帧在状态S3上的条件概率最大,因此就猜这帧属于状态S3。 那这些用到的概率从哪里读取呢?有个叫“声学模型”的东西,里面存了一大堆参数,通过这些参数,就可以知道帧和状态对应的概率。获取这一大堆参数的方法叫做“训练”,需要使用巨大数量的语音数据,训练的方法比较繁琐,这里不讲。 但这样做有一个问题:每一帧都会得到一个状态号,最后整个语音就会得到一堆乱七八糟的状态号。假设语音有1000帧,每帧对应1个状态,每3个状态组合成一个音素,那么大概会组合成300个音素,但这段语音其实根本没有这么多音素。如果真这么做,得到的状态号可能根本无法组合成音素。实际上,相邻帧的状态应该大多数都是相同的才合理,因为每帧很短。 解决这个问题的常用方法就是使用隐马尔可夫模型(Hidden Markov Model,HMM)。这东西听起来好像很高深的样子,实际上用起来很简单: 第一步,构建一个状态网络。 第二步,从状态网络中寻找与声音最匹配的路径。 这样就把结果限制在预先设定的网络中,避免了刚才说到的问题,当然也带来一个局限,比如你设定的网络里只包含了“今天晴天”和“今天下雨”两个句子的状态路径,那么不管说些什么,识别出的结果必然是这两个句子中的一句。 那如果想识别任意文本呢?把这个网络搭得足够大,包含任意文本的路径就可以了。但这个网络越大,想要达到比较好的识别准确率就越难。所以要根据实际任务的需求,合理选择网络大小和结构。 搭建状态网络,是由单词级网络展开成音素网络,再展开成状态网络。语音识别过程其实就是在状态网络中搜索一条最佳路径,语音对应这条路径的概率最大,这称之为“解码”。路径搜索的算法是一种动态规划剪枝的算法,称之为Viterbi算法,用于寻找全局最优路径。 这里所说的累积概率,由三部分构成,分别是: 观察概率:每帧和每个状态对应的概率 转移概率:每个状态转移到自身或转移到下个状态的概率 语言概率:根据语言统计规律得到的概率 其中,前两种概率从声学模型中获取,最后一种概率从语言模型中获取。语言模型是使用大量的文本训练出来的,可以利用某门语言本身的统计规律来帮助提升识别正确率。语言模型很重要,如果不使用语言模型,当状态网络较大时,识别出的结果基本是一团乱麻。 这样基本上语音识别过程就完成了。 2:端到端的模型 现阶段深度学习在模式识别领域取得了飞速的发展,特别是在语音和图像的领域,因为深度学习的特性,在语音识别领域中,基于深度学习的声学模型现如今已经取代了传统的混合高斯模型GMM对于状态的输出进行建模,因此在普通的深度神经网络的基础之上,基于长短记忆网络的递归神经网络对语音序列的强大的建模能力进一步提高了语音识别的性能,但是这些方法依旧包含着最基础的隐马尔可夫HMM的基本结构,因此依旧会出现隐马尔科夫模型的训练和解码的复杂度问题. 基于深度学习的声学模型训练过程必须是由传统的混合高斯模型开始的,然后对训练数据集合进行强制的对齐,然后进行切分得到不同的声学特征,其实传统的方式并不利于对于整句话的全局优化,并且这个方法也需要额外的语音学和语言学的知识,比如发音词典,决策树单元绑定建模等等,搭建系统的门槛较高等问题. 一些科学家针对传统的声学建模的缺点,提出了链接时序分类技术,这个技术是将语音识别转换为序列的转换问题,这样一来就可以抛弃了传统的基于HMM的语音识别系统的一系列假设,简化了系统的搭建流程,从而可以进一步提出了端到端的语音识别系统,减少了语音对于发音词典的要求. 端到端的系统是由LSTM的声学建模方法和CTC的目标函数组成的,在CTC的准则下,LSTM可以在训练过程中自动的学习声学的特征和标注序列的对应关系,也就不需要再进行强制的对数据集合进行对齐的过程了.并且可以根据各种语种的特点,端到端识别直接在字或者单词上进行建模,但是因为端到端的识别可能是意味着发展的趋势,但是因为完全崛弃了语音学的知识,现如今在识别性能上仍然和传统的基于深度学习的建模方法有着一定的差距,不过我最近在看的一篇论文中,基于端到端的藏语识别已经达到甚至超过了现有的通用算法. 就拿藏语举例,藏语是一种我国的少数民族语言,但是因为藏族人口较少,相比起对于英文,汉语这样的大语种来说,存在着语音数据收集困难的问题,在上一篇文章中我们可以知道,自然语言处理的最重要的需求就是语料,如果有很好的语料库自然会事半功倍,这样就导致了藏语的语音识别研究工作起步较晚,并且因为藏语的语言学知识的匮乏进一步阻碍了藏语语音识别的研究的进展,在我国,藏语是属于一种单音节字的语言,在端到端的语音过程中,藏语是建模起来非常简单的一种语言,但是作为一种少数民族语言,语料不足会在训练过程中出现严重的稀疏性问题,并且很多人在研究现有的藏语词典中发现,如果完全崛弃现有的藏语发音词典,完全不利用这样的先验知识,这样其实也是不利于技术的发现的,因此现阶段下,采用CTC和语言知识结合的方式来建模,可以解决在资源受限的情况下声学的建模问题,使得基于端到端的声学模型方法的识别率超过当下基于隐马尔科夫的双向长短时记忆模型. 在基于CD-DNN-HMM架构的语音识别声学模型中,训练DNN通常需要帧对齐标签。在GMM中,这个对齐操作是通过EM算法不断迭代完成的,而训练DNN时需要用GMM进行对齐则显得非常别扭。因此一种不需要事先进行帧对齐的方法呼之欲出。此外对于HMM假设一直受到诟病,等到RNN出现之后,使用RNN来对时序关系进行描述来取代HMM成为当时的热潮。随着神经网络优化技术的发展和GPU计算能力的不断提升,最终使用RNN和CTC来进行建模实现了end-to-end语音识别的声学模型。CTC的全称是Connectionist Temporal Classification,中文翻译大概是连接时序分类。它要达到的目标就是直接将语音和相应的文字对应起来,实现时序问题的分类。 这里仍然可以描述为EM的思想: E-step:使用BPTT算法优化神经网络参数; M-step:使用神经网络的输出,重新寻找最有的对齐关系。 CTC可以看成是一个分类方法,甚至可以看作是目标函数。在构建end-to-end声学模型的过程中,CTC起到了很好的自动对齐的效果。同传统的基于CD-DNN-HMM的方法相比,对齐效果引用文章[Alex Graves,2006]中的图是这样的效果: 这幅图可以理解:基于帧对齐的方法强制要求切分好的帧对齐到对应的标签上去,而CTC则可以时帧的输出为空,只有少数帧对齐到对应的输出标签上。这样带来的差别就是帧对齐的方法即使输出是正确的,但是在边界区域的切分也很难准确,从而给DNN的训练引入错误。c) End-to-end模型由于神经网络强大的建模能力,End-to-end的输出标签也不再需要像传统架构一样的进行细分。例如对于中文,输出不再需要进行细分为状态、音素或者声韵母,直接将汉字作为输出即可;对于英文,考虑到英文单词的数量庞大,可以使用字母作为输出标签。从这一点出发,我们可以认为神经网络将声学符号到字符串的映射关系也一并建模学习了出来,这部分是在传统的框架中时词典所应承担的任务。针对这个模块,传统框架中有一个专门的建模单元叫做G2P(grapheme-to-phoneme),来处理集外词(out of vocabulary,OOV)。在end-to-end的声学模型中,可以没有词典,没有OOV,也没有G2P。这些全都被建模在一个神经网络中。另外,在传统的框架结构中,语音需要分帧,加窗,提取特征,包括MFCC、PLP等等。在基于神经网络的声学模型中,通常使用更裸的Fbank特征。在End-to-en的识别中,使用更简单的特征比如FFT点,也是常见的做法。或许在不久的将来,语音的采样点也可以作为输入,这就是更加彻底的End-to-end声学模型。除此之外,End-to-end的声学模型中已经带有了语言模型的信息,它是通过RNN在输出序列上学习得到的。但这个语言模型仍然比较弱,如果外加一个更大数据量的语言模型,解码的效果会更好。因此,End-to-end现在指声学模型部分,等到不需要语言模型的时候,才是完全的end-to-end。3、 语言模型(Language Model, LM)语言模型的作用可以简单理解为消解多音字的问题,在声学模型给出发音序列之后,从候选的文字序列中找出概率最大的字符串序列。 4、 解码传统的语音识别解码都是建立在WFST的基础之上,它是将HMM、词典以及语言模型编译成一个网络。解码就是在这个WFST构造的动态网络空间中,找到最优的输出字符序列。搜索通常使用Viterbi算法,另外为了防止搜索空间爆炸,通常会采用剪枝算法,因此搜索得到的结果可能不是最优结果。在end-to-end的语音识别系统中,最简单的解码方法是beam search。尽管end-to-end的声学模型中已经包含了一个弱语言模型,但是利用额外的语言模型仍然能够提高识别性能,因此将传统的基于WFST的解码方式和Viterbi算法引入到end-to-end的语音识别系统中也是非常自然的。然而由于声学模型中弱语言模型的存在,解码可能不是最优的。文章[yuki Kanda, 2016]提出在解码的时候,需要将这个若语言模型减掉才能得到最优结果。 本文作者:云时之间 来源:51CTO

优秀的个人博客,低调大师

Android混淆从入门到精通

简介 作为Android开发者,如果你不想开源你的应用,那么在应用发布前,就需要对代码进行混淆处理,从而让我们代码即使被反编译,也难以阅读。混淆概念虽然容易,但很多初学者也只是网上搜一些成型的混淆规则粘贴进自己项目,并没有对混淆有个深入的理解。本篇文章的目的就是让一个初学者在看完后,能在不进行任何帮助的情况下,独立写出适合自己代码的混淆规则。 说在前面 这里我们直接用Android Studio来说明如何进行混淆,Android Studio自身集成Java语言的ProGuard作为压缩,优化和混淆工具,配合Gradle构建工具使用很简单,只需要在工程应用目录的gradle文件中设置minifyEnabled为true即可。然后我们就可以到proguard-rules.pro文件中加入我们的混淆规则了。 android{ ... buildTypes{ release{ minifyEnabledtrue proguardFilesgetDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro' } } } 以上示例代码表示对release版本就行混淆处理。下面我们先来简介下ProGuard的三大作用,并简要说明下它们常用的命令。 ProGuard作用 压缩(Shrinking):默认开启,用以减小应用体积,移除未被使用的类和成员,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未被使用的类和成员)。 -dontshrink关闭压缩 优化(Optimization):默认开启,在字节码级别执行优化,让应用运行的更快。 -dontoptimize关闭优化 -optimizationpassesn表示proguard对代码进行迭代优化的次数,Android一般为5 混淆(Obfuscation):默认开启,增大反编译难度,类和类成员会被随机命名,除非用keep保护。 -dontobfuscate关闭混淆 混淆后默认会在工程目录app/build/outputs/mapping/release下生成一个mapping.txt文件,这就是混淆规则,我们可以根据这个文件把混淆后的代码反推回源本的代码,所以这个文件很重要,注意保护好。原则上,代码混淆后越乱越无规律越好,但有些地方我们是要避免混淆的,否则程序运行就会出错,所以就有了下面我们要教大家的,如何让自己的部分代码避免混淆从而防止出错。 基本规则 先看如下两个比较常用的命令,很多童鞋可能会比较迷惑以下两者的区别。 -keepclasscn.hadcn.test.** -keepclasscn.hadcn.test.* 一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;两颗星表示把本包和所含子包下的类名都保持;用以上方法保持类后,你会发现类名虽然未混淆,但里面的具体方法和变量命名还是变了,这时如果既想保持类名,又想保持里面的内容不被混淆,我们就需要以下方法了 -keepclasscn.hadcn.test.*{*;} 在此基础上,我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extend,implement等这些Java规则。如下例子就避免所有继承Activity的类被混淆 -keeppublicclass*extendsandroid.app.Activity 如果我们要保留一个类中的内部类不被混淆则需要用$符号,如下例子表示保持ScriptFragment内部类JavaScriptInterface中的所有public内容不被混淆。 -keepclassmembersclasscc.ninty.chat.ui.fragment.ScriptFragment$JavaScriptInterface{ public*; } 再者,如果一个类中你不希望保持全部内容不被混淆,而只是希望保护类下的特定内容,就可以使用 <init>;//匹配所有构造器 <fields>;//匹配所有域 <methods>;//匹配所有方法方法 你还可以在<fields>或<methods>前面加上private 、public、native等来进一步指定不被混淆的内容,如 -keepclasscn.hadcn.test.One{ public<methods>; } 表示One类下的所有public方法都不会被混淆,当然你还可以加入参数,比如以下表示用JSONObject作为入参的构造函数不会被混淆 -keepclasscn.hadcn.test.One{ public<init>(org.json.JSONObject); } 有时候你是不是还想着,我不需要保持类名,我只需要把该类下的特定方法保持不被混淆就好,那你就不能用keep方法了,keep方法会保持类名,而需要用keepclassmembers ,如此类名就不会被保持,为了便于对这些规则进行理解,官网给出了以下表格 保留 防止被移除或者被重命名 防止被重命名 类和类成员 -keep -keepnames 仅类成员 -keepclassmembers -keepclassmembernames 如果拥有某成员,保留类和类成员 -keepclasseswithmembers -keepclasseswithmembernames 移除是指在压缩(Shrinking)时是否会被删除。以上内容时混淆规则中需要重点掌握的,了解后,基本所有的混淆规则文件你应该都能看懂了。再配合以下几点注意事项, 注意事项 1,jni方法不可混淆,因为这个方法需要和native方法保持一致; -keepclasseswithmembernamesclass*{#保持native方法不被混淆 native<methods>; } 2,反射用到的类不混淆(否则反射可能出现问题); 3,AndroidMainfest中的类不混淆,所以四大组件和Application的子类和Framework层下所有的类默认不会进行混淆。自定义的View默认也不会被混淆;所以像网上贴的很多排除自定义View,或四大组件被混淆的规则在Android Studio中是无需加入的; 4,与服务端交互时,使用GSON、fastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象; 5,使用第三方开源库或者引用其他第三方的SDK包时,如果有特别要求,也需要在混淆文件中加入对应的混淆规则; 6,有用到WebView的JS调用也需要保证写的接口方法不混淆,原因和第一条一样; 7,Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常; -keepclass*implementsAndroid.os.Parcelable{#保持Parcelable不被混淆 publicstaticfinalAndroid.os.Parcelable$Creator*; } 8,使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用,见第二条规则。 -keepclassmembersenum*{ publicstatic**[]values(); publicstatic**valueOf(java.lang.String); } 写在最后 发布一款应用除了设minifyEnabled为ture,你也应该设置zipAlignEnabled为true,像Google Play强制要求开发者上传的应用必须是经过zipAlign的,zipAlign可以让安装包中的资源按4字节对齐,这样可以减少应用在运行时的内存消耗。 本文作者:佚名 来源:51CTO

优秀的个人博客,低调大师

《Docker技术入门与实战》——导读

**前言**在一台服务器上同时运行一百个虚拟机,肯定会被认为是痴人说梦。而在一台服务器上同时运行一千个Docker容器,这已经成为现实。在计算机技术高速发展的今天,昔日的天方夜谭正在一个个变成现实。多年的研发和运维(DevOps)经历中,笔者时常会碰到这样一个困境:用户的需求越来越多样,系统的规模越来越庞大,运行的软件越来越复杂,环境配置问题所造成的麻烦层出不穷……为了解决这些问题,开源社区推出过不少优秀的工具。这些方案虽然在某些程度上确能解决部分“燃眉之急”,但是始终没有一种方案能带来“一劳永逸”的效果。让作为企业最核心资源的工程师们花费大量的时间,去解决各种环境和配置引发的 Bug,这真的正常吗?回顾计算机的发展历程,最初,程序设计人员需要直接操作各种枯燥的机器指令,编程效率之低可想而知。高级语言的诞生,将机器指令的具体实现成

优秀的个人博客,低调大师

LXD 2.0 系列(一):LXD 入门

关于 LXD 几个常见问题 什么是 LXD ? 简单地说, LXD 就是一个提供了 REST API 的 LXC 容器管理器。 LXD 最主要的目标就是使用 Linux 容器而不是硬件虚拟化向用户提供一种接近虚拟机的使用体验。 LXD 和 Docker/Rkt 又有什么关系呢 ? 这是一个最常被问起的问题,现在就让我们直接指出其中的不同吧。 LXD 聚焦于系统容器,通常也被称为架构容器。这就是说 LXD 容器实际上如在裸机或虚拟机上运行一般运行了一个完整的 Linux 操作系统。 这些容器一般基于一个干净的发布镜像并会长时间运行。传统的配置管理工具和部署工具可以如在虚拟机、云实例和物理机器上一样与 LXD 一起使用。 相对的, Docker 关注于短期的、无状态的、最小化的容器,这些容器通常并不会升级或者重新配置,而是作为一个整体被替换掉。这就使得 Docker 及类似项目更像是一种软件发布机制,而不是一个机器管理工具。 这两种模型并不是完全互斥的。你完全可以使用 LXD 为你的用户提供一个完整的 Linux 系统,然后他们可以在 LXD 内安装 Docker 来运行他们想要的软件。 为什么要用 LXD? 我们已经持续开发并改进 LXC 好几年了。 LXC 成功的实现了它的目标,它提供了一系列很棒的用于创建和管理容器的底层工具和库。 然而这些底层工具的使用界面对用户并不是很友好。使用它们需要用户有很多的基础知识以理解它们的工作方式和目的。同时,向后兼容旧的容器和部署策略也使得 LXC 无法默认使用一些安全特性,这导致用户需要进行更多人工操作来实现本可以自动完成的工作。 我们把 LXD 作为解决这些缺陷的一个很好的机会。作为一个长时间运行的守护进程, LXD 可以绕开 LXC 的许多限制,比如动态资源限制、无法进行容器迁移和高效的在线迁移;同时,它也为创造新的默认体验提供了机会:默认开启安全特性,对用户更加友好。 LXD 的主要组件 LXD 是由几个主要组件构成的,这些组件都出现在 LXD 目录结构、命令行客户端和 API 结构体里。 容器 LXD 中的容器包括以下及部分: 根文件系统(rootfs) 配置选项列表,包括资源限制、环境、安全选项等等 设备:包括磁盘、unix 字符/块设备、网络接口 一组继承而来的容器配置文件 属性(容器架构、暂时的还是持久的、容器名) 运行时状态(当用 CRIU 来中断/恢复时) 快照 容器快照和容器是一回事,只不过快照是不可修改的,只能被重命名,销毁或者用来恢复系统,但是无论如何都不能被修改。 值得注意的是,因为我们允许用户保存容器的运行时状态,这就有效的为我们提供了“有状态”的快照的功能。这就是说我们可以使用快照回滚容器的状态,包括快照当时的 CPU 和内存状态。 镜像 LXD 是基于镜像实现的,所有的 LXD 容器都是来自于镜像。容器镜像通常是一些纯净的 Linux 发行版的镜像,类似于你们在虚拟机和云实例上使用的镜像。 所以可以「发布」一个容器:使用容器制作一个镜像并在本地或者远程 LXD 主机上使用。 镜像通常使用全部或部分 sha256 哈希码来区分。因为输入长长的哈希码对用户来说不方便,所以镜像可以使用几个自身的属性来区分,这就使得用户在镜像商店里方便搜索镜像。也可以使用别名来一对一地将一个用户好记的名字映射到某个镜像的哈希码上。 LXD 安装时已经配置好了三个远程镜像服务器(参见下面的远程一节): “ubuntu”:提供稳定版的 Ubuntu 镜像 “ubuntu-daily”:提供 Ubuntu 的每日构建镜像 “images”: 社区维护的镜像服务器,提供一系列的其它 Linux 发布版,使用的是上游 LXC 的模板 LXD 守护进程会从镜像上次被使用开始自动缓存远程镜像一段时间(默认是 10 天),超过时限后这些镜像才会失效。 此外, LXD 还会自动更新远程镜像(除非指明不更新),所以本地的镜像会一直是最新版的。 配置 配置文件是一种在一个地方定义容器配置和容器设备,然后将其应用到一系列容器的方法。 一个容器可以被应用多个配置文件。当构建最终容器配置时(即通常的扩展配置),这些配置文件都会按照他们定义顺序被应用到容器上,当有重名的配置键或设备时,新的会覆盖掉旧的。然后本地容器设置会在这些基础上应用,覆盖所有来自配置文件的选项。 LXD 自带两种预配置的配置文件: “default”配置是自动应用在所有容器之上,除非用户提供了一系列替代的配置文件。目前这个配置文件只做一件事,为容器定义 eth0 网络设备。 “docker”配置是一个允许你在容器里运行 Docker 容器的配置文件。它会要求 LXD 加载一些需要的内核模块以支持容器嵌套并创建一些设备。 远程 如我之前提到的, LXD 是一个基于网络的守护进程。附带的命令行客户端可以与多个远程 LXD 服务器、镜像服务器通信。 默认情况下,我们的命令行客户端会与下面几个预定义的远程服务器通信: local:默认的远程服务器,使用 UNIX socket 和本地的 LXD 守护进程通信 ubuntu:Ubuntu 镜像服务器,提供稳定版的 Ubuntu 镜像 ubuntu-daily:Ubuntu 镜像服务器,提供 Ubuntu 的每日构建版 images:images.linuxcontainers.org 的镜像服务器 所有这些远程服务器的组合都可以在命令行客户端里使用。 你也可以添加任意数量的远程 LXD 主机,并配置它们监听网络。匿名的开放镜像服务器,或者通过认证可以管理远程容器的镜像服务器,都可以添加进来。 正是这种远程机制使得与远程镜像服务器交互及在主机间复制、移动容器成为可能。 安全性 我们设计 LXD 时的一个核心要求,就是在不修改现代 Linux 发行版的前提下,使容器尽可能的安全。 LXD 通过使用 LXC 库实现的主要安全特性有: 内核名字空间。尤其是用户名字空间,它让容器和系统剩余部分完全分离。LXD 默认使用用户名字空间(和 LXC 相反),并允许用户在需要的时候以容器为单位关闭(将容器标为“特权的”)。 Seccomp 系统调用。用来隔离潜在危险的系统调用。 AppArmor。对 mount、socket、ptrace 和文件访问提供额外的限制。特别是限制跨容器通信。 Capabilities。阻止容器加载内核模块,修改主机系统时间,等等。 CGroups。限制资源使用,防止针对主机的 DoS 攻击。 为了对用户友好,LXD 构建了一个新的配置语言把大部分的这些特性都抽象封装起来,而不是如 LXC 一般直接将这些特性暴露出来。举了例子,一个用户可以告诉 LXD 把主机设备放进容器而不需要手动检查他们的主/次设备号来手动更新 CGroup 策略。 和 LXD 本身通信是基于使用 TLS 1.2 保护的链路,只允许使用有限的几个被允许的密钥算法。当和那些经过系统证书认证之外的主机通信时, LXD 会提示用户验证主机的远程指纹(SSH 方式),然后把指纹缓存起来以供以后使用。 REST 接口 LXD 的工作都是通过 REST 接口实现的。在客户端和守护进程之间并没有其他的通讯渠道。 REST 接口可以通过本地的 unix socket 访问,这只需要经过用户组认证,或者经过 HTTP 套接字使用客户端认证进行通信。 REST 接口的结构能够和上文所说的不同的组件匹配,是一种简单、直观的使用方法。 当需要一种复杂的通信机制时, LXD 将会进行 websocket 协商完成剩余的通信工作。这主要用于交互式终端会话、容器迁移和事件通知。 LXD 2.0 附带了 1.0 版的稳定 API。虽然我们在 1.0 版 API 添加了额外的特性,但是这不会在 1.0 版 API 端点里破坏向后兼容性,因为我们会声明额外的 API 扩展使得客户端可以找到新的接口。 容器规模化 虽然 LXD 提供了一个很好的命令行客户端,但是这个客户端并不能管理多个主机上大量的容器。在这种使用情况下,我们可以使用 OpenStack 的 nova-lxd 插件,它可以使 OpenStack 像使用虚拟机一样使用 LXD 容器。 这就允许在大量的主机上部署大量的 LXD 容器,然后使用 OpenStack 的 API 来管理网络、存储以及负载均衡。 额外信息 LXD 的主站在:https://linuxcontainers.org/lxd LXD 的 GitHub 仓库:https://github.com/lxc/lxd LXD 的邮件列表:https://lists.linuxcontainers.org LXD 的 IRC 频道: #lxcontainers on irc.freenode.net 如果你不想或者不能在你的机器上安装 LXD ,你可以在 web 上试试在线版的 LXD。 原文发布时间为:2016-07-26 本文来自云栖社区合作伙伴“Linux中国”

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册