算法

ML08 -- 聚类算法K-means

老子叫甜甜 提交于 2019-12-29 20:34:47
聚类算法K-means K-means最简单的聚类算法属于无监督算法 聚类算法和分类算法的对比 - 聚类 分类 核心 将数据分成多个组,探索每个组的数据是否有联系 从已经分组的数据中去学习,把新数据放到已经分好的组中去 学习类型 无监督,无需标签进行训练 有监督,需要标签进行训练 典型算法 K-Means,DBSCAN,层次聚类 决策树,贝叶斯,逻辑回归 算法输出 聚类结果是不确定的, 不一定总是能够反映数据的真实分类, 同样的聚类,根据不同的业务需求,可能是一个好结果,也可能是一个坏结果 分类的结果是确定的, 分类的优劣是客观的, 不是根据业务或算法需求决定 关键概念:簇与质心 簇:KMeans算法将一组N个样本的特征矩阵X划分为K个无交集的簇,直观上来看簇是一组一组聚集在一起的数据,在一个簇中的数据就认为是同一类。簇是聚类结果的表现。 质心:簇中所有数据的均值uj通常被称为这个簇的质心,在一个二维平面中,一簇数据点的质心的横坐标就是这一簇数据点横坐标的均值,质心的纵坐标就是这一簇数据点的纵坐标的均值。同理可推广到高维空间。 在KMeans算法中,簇的个数K是一个超参数,需要我们人为输入来确定。KMeans的核心任务就是根据我们设定好的K,找出K个最优质心,并将离这些质心最近的数据分别分配到这些质心代表的的簇中去。具体步骤 1.随机抽取K个样本作为最初的质心 2.开始循环: 2

转——深度学习之BN算法(Batch Normailization)

∥☆過路亽.° 提交于 2019-12-29 14:36:20
Batch Normalization 学习笔记 原文地址 : http://blog.csdn.net/hjimce/article/details/50866313 作者 :hjimce 一、背景意义 本篇博文主要讲解2015年 深度学习 领域,非常值得学习的一篇文献:《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》,这个 算法 目前已经被大量的应用,最新的文献算法很多都会引用这个算法,进行网络训练,可见其强大之处非同一般啊。 近年来深度学习捷报连连、声名鹊起,随机梯度下架成了训练深度网络的主流方法。尽管随机梯度下降法对于训练深度网络简单高效,但是它有个毛病,就是需要我们人为的去选择参数,比如学习率、参数初始化、权重衰减系数、Drop out比例等。这些参数的选择对训练结果至关重要,以至于我们很多时间都浪费在这些的调参上。那么学完这篇文献之后,你可以不需要那么刻意的慢慢调整参数。BN算法(Batch Normalization)其强大之处如下: (1)你可以选择比较大的初始学习率,让你的训练速度飙涨。以前还需要慢慢调整学习率,甚至在网络训练到一半的时候,还需要想着学习率进一步调小的比例选择多少比较合适,现在我们可以采用初始很大的学习率

SSL与TLS的区别

时光毁灭记忆、已成空白 提交于 2019-12-29 07:36:00
SSL(Secure Socket Layer 安全套接层)是基于HTTPS下的一个协议 加密 层,最初是由网景公司(Netscape)研发,后被IETF(The Internet Engineering Task Force - 互联网工程任务组)标准化后写入(RFCRequest For Comments 请求注释),RFC里包含了很多互联网技术的规范! 起初是因为HTTP在传输数据时使用的是明文(虽然说POST提交的数据时放在报体里看不到的,但是还是可以通过抓包工具窃取到)是不安全的,为了解决这一隐患网景公司推出了SSL安全套接字协议层,SSL是基于HTTP之下TCP之上的一个协议层,是基于HTTP标准并对TCP传输数据时进行加密,所以HPPTS是HTTP+SSL/TCP的简称。 由于HTTPS的推出受到了很多人的欢迎,在SSL更新到3.0时,IETF对SSL3.0进行了标准化,并添加了少数机制(但是几乎和SSL3.0无差异),标准化后的IETF更名为TLS1.0(Transport Layer Security 安全传输层协议),可以说TLS就是SSL的新版本3.1,并同时发布“RFC2246-TLS加密协议详解”,如果想更深层次的了解TLS的工作原理可以去RFC的官方网站:www.rfc-editor.org,搜索RFC2246即可找到RFC文档! SSL连接过程

垃圾收集器与内存分配策略(2)

天涯浪子 提交于 2019-12-29 02:32:34
3.垃圾收集算法 3.1 标记—清除算法 最基础的收集算法是“标记—清除”(Mark-Sweep)算法,如他的名字一样,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。之所以说它是最基础的收集算法,是因为后续的收集算法都是基于这种思路并对其缺点进行改进而得到的。两个主要缺点:一个是效率问题,标记和清除过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致,当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集操作。 3.2 复制算法 为了解决效率问题,出现了复制算法,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对其中的一块儿进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。这种算法代价太高,将内存缩小为原来的一半。 现在的商业虚拟机都采用这种手机算法来回收新生代,据IBM的专门研究表明,新生代中的对象98%是朝生夕死的,所以并不需要按照1:1的比例来划分内存空间,而是将内存分为一块较大的Eden空间和两块较小的Survivor的空间

JVM学习笔记(二):垃圾收集

限于喜欢 提交于 2019-12-29 02:31:02
程序计数器、 虚拟机栈、 本地方法栈3个区域随线程而生,随线程而灭; 栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。 每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这几个区域的内存分配和回收都具备确定性,在这几个区域内就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了。 而 Java堆和方法区 则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期间时才能知道会创建哪些对象,这部分内存的分配和回收都是动态的,垃圾收集器所关注的是这部分内存。 自动垃圾回收机制就是寻找Java堆中的对象,并对对象进行分类判别,寻找出正在使用的对象和已经不会使用的对象,然后把那些不会使用的对象从堆上清除。 一、哪些对象需要回收 1. 引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个对象引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。 但 主流Java虚拟机中并没有采用引用计数算法 ,原因:它很难解决对象之间相互循环引用的问题。 例: /** * 添加参数:-XX:+PrintGC * testGC()方法执行后,objA和objB会不会被GC呢? * */ public class

GC算法与代龄

放肆的年华 提交于 2019-12-29 02:29:53
第一节. GC的算法与工作方式   1.算法   垃圾收集器的本质,就是跟踪所有被引用到的对象,整理对象不再被引用的对象,回收相应的内存。   这听起来类似于一种叫做“引用计数(Reference Counting)”的算法,然而这种算法需要遍历所有对象,并维护它们的引用情况,所以效率较低些,并且在出现“环引用”时很容易造成内存泄露。所以.Net中采用了一种叫做“标记与清除(Mark Sweep)”算法来完成上述任务。   “标记与清除”算法,顾名思义,这种算法有两个本领:   “标记”本领——垃圾的识别:从应用程序的root出发,利用相互引用关系,遍历其在Heap上动态分配的所有对象,没有被引用的对象不被标记,即成为垃圾;存活的对象被标记,即维护成了一张“根-对象可达图”。   其实,CLR会把对象关系看做“树图”,无疑,了解数据结构的同学都知道,有了“树图”的概念,会加快遍历对象的速度。   检测、标记对象引用,是一件很有意思的事情,有很多方法可以做到,但是只有一种是效率最优的,.Net中是利用栈来完成的,在不断的入栈与出栈中完成检测:先在树图中选择一个需要检测的对象,将该对象的所有引用压栈,如此反复直到栈变空为止。栈变空意味着已经遍历了这个局部根(或者说是树图中的节点)能够到达的所有对象。树图节点范围包括局部变量(实际上局部变量会很快被回收,因为它的作用域很明显、很好控制)

操作系统复习笔记

爷,独闯天下 提交于 2019-12-28 21:23:34
操作系统复习 第1章 操作系统概论 定义:管理系统资源、控制程序执行、改善人机界面、提供各种服务,并合理组织计算机工作流程和为用户方便有效的使用计算机提供良好运行环境的一种系统软件。 功能:处理器管理、存储管理、设备管理、文件管理、联网和通信管理 特性:并发性、共享性(1.透明资源共享 2.独占资源共享)、异步性 分类:批处理操作系统、分时操作系统、实时操作系统 第2章 处理器管理 进程定义:进程是具有独立功能的程序在某个数据集合上的一次运行活动,也是操作系统进行资源分配和保护的基本单位。 进程状态和转换:p73 三态模型:运行态、就绪态、等待态 五态模型:新建态、终止态提出的原因? 要求会画图,解释某些转换是不存在的。 引入多线程的动机:减少程序并发执行时所付出的时空开销,使得并发颗粒度更细、并发性更好。 线程的优点:快速线程切换、通信易于实现、减少管理开销、并发程度提高 PCB(Process Control Block)进程控制块:进程存在的唯一标识,是操作系统用来记录和刻画进程状态及环境信息的数据结构,是进程动态特征的汇集,也是操作系统掌握进程的唯一资料结构和管理进程的主要依据。p75 TCB的概念? 动态/静态 优先级? 处理器调度:p101 例题 先来先服务算法 最短作业优先算法(概念) 最短剩余时间优先算法 最高响应比优先算法(概念) 第3章 同步、通信与死锁

操作系统 庞丽萍 第七章

ぐ巨炮叔叔 提交于 2019-12-28 21:23:14
1. 存储管理的功能与目的是什么? 主要包括以下四个方面:(1)映射逻辑地址到物理主存地址;(2)在多用户之间分配物理主存;(3)对各个用户区的信息提供保护措施;(4)扩充逻辑主存区。 2.物理地址 VS 逻辑地址 把内存分成若干个大小相等的单元,每个单元给个编号,就是物理地址,又称为绝对地址或者实地址; 逻辑地址是用户编程序时所用的地址,又称为程序地址或者虚地址。 为了支持多道程序运行,方便用户使用;使得多用户程序共享主存, 必须要解决主存区域如何分配、各个区域内信息如何保护等问题。如果直接以物理地址提交给用户使用,这对用户来说将是十分困难的事情,因此必须要由操作系统实现逻辑地址到物理地址的转换。 3.地址变换可以由软件实现,但是软件实现会花费较多的CPU时间。 4.所谓存储保护,就是指计算机在多用户使用或者多道程序运行的情况下,为了互不影响,必须由硬件(软件配合)保证每道程序只能在给定的存储区域内活动。 分区分配方法中,主要采用上下界保护。 5. 放置策略中: 最佳适应算法 VS 首次匹配算法 最佳适应算法:将输入作业放入到主存中与他所需要大小最接近的空闲区中,这样剩下的未用空间最小。 此时,空闲区队列是按空闲区大小递增的顺序链接在一起的。 起主要缺点是:空闲区一般不可能正好和要求的大小相等,因此将其分割成两部分后,往往会使得剩下的空闲区非常小,以至于无法使用

操作系统课后习题答案(作业题)

梦想的初衷 提交于 2019-12-28 21:22:26
第二章 11.试说明进程在三个基本状态之间转换的典型原因。 答: (1)就绪状态→执行状态:进程分配到CPU资源 (2)执行状态→就绪状态:时间片用完 (3)执行状态→阻塞状态:I/O请求 (4)阻塞状态→就绪状态:I/O完成 12.为什么要引入挂起状态?该状态有哪些性质? 答:引入挂起状态处于五种不同的需要: 终端用户需要,父进程需要,操作系统需要,对换 需要和负荷调节需要。处于挂起状态的进程不能接收处理机调度。 14.试说明引起进程创建的主要事件。 答:引起进程创建的主要事件有:用户登录、作业调度、提供服务、应用请求。 第三章 8.在抢占调度方式中,抢占的原则是什么? 答:抢占的原则有:时间片原则、优先权原则、短作业优先权原则等。 11.何谓静态和动态优先级?确定静态优先级的依据是什么? 答:静态优先级是指在创建进程时确定且在进程的整个运行期间保持不变的优先级。 动态优先级是指在创建进程时赋予的优先权,可以随进程推进或随其等待时间增加而改变的优先级,可以获得更好的调度性能。 确定进程优先级的依据:进程类型、进程对资源的需求和用户要求。 27.何谓死锁?产生死锁的原因和必要条件是什么? 答:死锁是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状 态时,若无外力作用,它们都将无法再向前推进。 产生死锁的原因为竞争资源和进程间推进顺序非法。其必要条件是:互斥条件

插入排序算法

有些话、适合烂在心里 提交于 2019-12-28 20:08:05
  #include <stdio.h>   #include <stdlib.h>   void output(int *a,int len);   void InsertSort(int *array, int len);   int main()   {     int a[6]={1,5,2,9,4,3};     InsertSort(a,6);     output(a,6);     printf("\n");     system("pause");     return 0;   }   void InsertSort(int *array, int len)   {   int i;   for(i=1;i<len;i++)     {       int cur=i; //当前位置       int last=cur-1; //上一个位置       int temp = array[cur];       while(array[last] > temp && last>=0) //当前大小小于上一个       {         array[last+1]=array[last]; //上一个后移         last--;       } //当前小于等于上一个       array[++last]=temp; // 插入当上一个后面