感知机

感知机是二分类的线性分类模型,其输入为实例的特征向量,输出实例为类别,取+1和-1二值,属于判别模型。感知机学习旨在求出能够将训练数据集进行正确的分类的分离超平面的。为此,导入基于误分类的损失函数,利用梯度下降法对损失函数进行极小化,求得感知机模型。感知机具有简单易实现的优点,分为原始和对偶形式。

感知机模型

定义:称函数y=f(x)=sign(ω⋅xi+b)y=f(x)=sign(\omega \cdot x_{i}+b)y=f(x)=sign(ω⋅xi​+b)为感知机,其中ω∈Rn,x∈X⊆Rn,ω≠0,B∈R,sign\omega \in\mathbb{R}^{n} ,x\in X\subseteq \mathbb{R}^{n},\omega \neq 0,B\in R,signω∈Rn,x∈X⊆Rn,ω̸​=0,B∈R,sign为符号函数,即对任意z∈Rz\in \mathbb{R}z∈R,有sign={+1z&gt;00z=0−1z&lt;0sign=\left\{\begin{matrix} +1 &amp; &amp; z&gt;0\\ 0&amp; &amp;z=0 \\ -1&amp; &amp;z&lt;0 \end{matrix}\right.sign=⎩⎨⎧​+10−1​​z>0z=0z<0​对于任意输入x∈X⊆Rnx\in X\subseteq \mathbb{R}^{n}x∈X⊆Rn,感知机的输出是+1或-1中的一个。在几何意义上,ω⋅xi+b=0\omega \cdot x_{i}+b=0ω⋅xi​+b=0是Rn\mathbb{R}^{n}Rn的一个分离超平面S,Rn\mathbb{R}^{n}Rn被划分到分离超平面的两侧,输入感知机后得到+1或-1。

感知机学习策略

对于训练数据集T={(x1,y1)(x2,y2)...(xN,yN)}T=\begin{Bmatrix} (x_{1},y_{1}) &amp; (x_{2},y_{2}) &amp;...&amp; (x_{N},y_{N}) \end{Bmatrix}T={(x1​,y1​)​(x2​,y2​)​...​(xN​,yN​)​},其中x∈X⊆Rnx\in X\subseteq \mathbb{R}^{n}x∈X⊆Rn,yi={+1,−1}y_{i}=\begin{Bmatrix} +1,-1\end{Bmatrix}yi​={+1,−1​}中的实例点(xi,yi)(x_{i},y_{i})(xi​,yi​),Rn\mathbb{R}^{n}Rn中的某一超平面S:ω⋅xi+b=0S:\omega \cdot x_{i}+b=0S:ω⋅xi​+b=0可能会被正确分类,也可能会被错误分类。当被错误分类时,有−yi(ω⋅xi+b)&gt;0-y_{i}(\omega \cdot x_{i}+b)&gt;0−yi​(ω⋅xi​+b)>0(判断和实际的符号不一致,相乘结果小于0,加上负号后大于0)
设M⊆TM\subseteq \ TM⊆ T时SSS关于所有误分类点的集合,且令

L(ω,b)=−∑(xi,yi)∈Myi(ω⋅xi+b)L(\omega ,b)=-\sum_{(x_{i},y_{i})\in M}y_{i}(\omega \cdot x_{i}+b)L(ω,b)=−(xi​,yi​)∈M∑​yi​(ω⋅xi​+b)
L(ω,b)L(\omega ,b)L(ω,b)常被称为感知机的损失函数,其值显然是非负的。如果没有误分类点,损失函数等于0,误分类点越少,损失函数值越小。所以感知机的学习策略就是选取参数:ω:\omega:ω和bbb使L(ω,b)L(\omega ,b)L(ω,b)达到最小值。

感知机学习算法

对于给定的训练集TTT,感知机的学习损失函数L(ω,b)L(\omega ,b)L(ω,b)是:ω:\omega:ω和bbb的连续可导函数。确定最优的:ω:\omega:ω和bbb的问题转化为求解损失函数L(ω,b)L(\omega ,b)L(ω,b)的最优问题,而最优化问题采用随机梯度下降法。

1.感知机学习算法的原始形式
给定一个数据集:T={(x1,y1)(x2,y2)...(xN,yN)}T=\begin{Bmatrix} (x_{1},y_{1}) &amp; (x_{2},y_{2}) &amp;...&amp; (x_{N},y_{N}) \end{Bmatrix}T={(x1​,y1​)​(x2​,y2​)​...​(xN​,yN​)​},x∈X⊆Rnx\in X\subseteq \mathbb{R}^{n}x∈X⊆Rn,yi={+1,−1}y_{i}=\begin{Bmatrix} +1,-1\end{Bmatrix}yi​={+1,−1​},求参数ω\omegaω和bbb,使其为一下损失函数极小化问题的解min⁡ω,bL(ω,b)=−∑(xi,yi)∈Myi(ω⋅xi+b)\underset{\omega ,b }{\min}L(\omega ,b)=-\sum_{(x_{i},y_{i})\in M}y_{i}(\omega \cdot x_{i}+b)ω,bmin​L(ω,b)=−(xi​,yi​)∈M∑​yi​(ω⋅xi​+b)其中M⊆TM\subseteq \ TM⊆ T时SSS关于所有误分类点的集合。
感知机的学习算法是误分类驱动的,采用随机梯度下降法,首先任意选取一个超平面ω\omegaω和bbb,然后用梯度下降法不断极小化损失函数,极小化的过程不是一次使MMM中的所有误分类点的梯度下降,而是一次选取一个误分点使其梯度下降。
设误分点的集合MMM是固定的,那么损失函数L(ω,b)L(\omega ,b)L(ω,b)的梯度为:▽ωL(ω,b)=−∑(xi,yi)∈Myixi\bigtriangledown _{\omega }L(\omega ,b)=-\sum_{(x_{i},y_{i})\in M}y_{i}x_{i}▽ω​L(ω,b)=−(xi​,yi​)∈M∑​yi​xi​▽ωL(ω,b)=−∑(xi,yi)∈Myi\bigtriangledown _{\omega }L(\omega ,b)=-\sum_{(x_{i},y_{i})\in M}y_{i}▽ω​L(ω,b)=−(xi​,yi​)∈M∑​yi​,随机选取一个误分点(xi,yi)∈M(x_{i},y_{i})\in M(xi​,yi​)∈M,对ω\omegaω和bbb进行更新。ω←ω+ηyixi\omega \leftarrow \omega +\eta y_{i}\mathbf{x_{i}}ω←ω+ηyi​xi​b←b+ηyib\leftarrow b +\eta y_{i}b←b+ηyi​参数更新表达式中的η\etaη是步长或学习率。

例:

零件编号 宽度(wid)z1z1z1 长度(len)z2z2z2 检验类别
1 3 3 正品
2 4 3 正品
3 1 1 次品

令x1=(3,3),y1=1;x2=(4,3),y2=1;x2=(1,1),y3=−1x_{1}=(3,3),y_{1}=1;x_{2}=(4,3),y_{2}=1;x_{2}=(1,1),y_{3}=-1x1​=(3,3),y1​=1;x2​=(4,3),y2​=1;x2​=(1,1),y3​=−1,则有T={(x1,y1),(x2,y2),(x3,y3)};T=\begin{Bmatrix} (x_{1},y_{1}) &amp; ,(x_{2},y_{2}) &amp; ,(x_{3},y_{3}) \end{Bmatrix};T={(x1​,y1​)​,(x2​,y2​)​,(x3​,y3​)​};,其中(x1,y1)(x_{1},y_{1})(x1​,y1​)和(x2,y2)(x_{2},y_{2})(x2​,y2​)为正实例点,(x3,y3)(x_{3},y_{3})(x3​,y3​)为负实例点。
(1)设置初始值ω0=(0,0),b0=0,η=1\omega _{0}=(0,0),b_{0}=0,\eta =1ω0​=(0,0),b0​=0,η=1
(2)对x1=(3,3),y1(ω⋅x1+b)=0x_{1}=(3,3),y_{1}(\omega \cdot x_{1}+b)=0x1​=(3,3),y1​(ω⋅x1​+b)=0未能被正确分类,更新参数模型:ω1=ω0+y1x1=(3,3),b1=b0+y1=1\omega _{1}=\omega _{0}+y_{1}x_{1}=(3,3),b_{1}=b_{0}+y_{1}=1ω1​=ω0​+y1​x1​=(3,3),b1​=b0​+y1​=1(3)x1,x2x_{1},x_{2}x1​,x2​被正确分类,而x3=(1,1),y1(ω⋅x1+b)&lt;0x_{3}=(1,1),y_{1}(\omega \cdot x_{1}+b)&lt;0x3​=(1,1),y1​(ω⋅x1​+b)<0,更新参数模型:omega2=ω1+y3x3=(2,2),b2=b1+y3=0omega _{2}=\omega _{1}+y_{3}x_{3}=(2,2),b_{2}=b_{1}+y_{3}=0omega2​=ω1​+y3​x3​=(2,2),b2​=b1​+y3​=0如此继续下去,直到ω7=(1,1),b7=−3\omega _{7}=(1,1),b_{7}=-3ω7​=(1,1),b7​=−3。整个迭代计算过程见表:

迭代次数 误分类点 ω\omegaω bbb ω⋅x1+b\omega \cdot x_{1}+bω⋅x1​+b
0 (0,0) 0
0 x1x_{1}x1​ (0,0) 1 3wid+3len+13wid+3len+13wid+3len+1
2 x3x_{3}x3​ (2,2) 0 2wid+2len2wid+2len2wid+2len
3 x3x_{3}x3​ (1,1) -1 wid+lenwid+lenwid+len-1
4 x3x_{3}x3​ (0,0) -2 −2-2−2
5 x1x_{1}x1​ (3,3) -1 3wid+3len−13wid+3len-13wid+3len−1
6 x3x_{3}x3​ (2,2) -2 2wid+2len−22wid+2len-22wid+2len−2
7 x3x_{3}x3​ (1,1) -3 wid+len−3wid+len-3wid+len−3
8 (1,1) -3 wid+len−3wid+len-3wid+len−3

在整个感知机的迭代算法中,若某个迭代过程有多个误分类点,那么选择不同的误分点,会得到不同的分离超平面。基于不同的初始值,也会的到不同的解。

例题R语言代码如下:

perception<-function(x,class,eta=1)#x为样本的特征矩阵,class为样本的分类标签,eta为学习步长
{ma<-as.matrix(x)N<-nrow(x)  #计算样本容量w<-rep(0,times=ncol(x))b<-0   #初始化w,bwhile(TRUE){k<-0for(i in 1:N){if(y[i]*(ma[i,]%*%w+b)<=0){w<-w+eta*y[i]*ma[i,]b<-b+eta*y[i]k<-k+1} }if(k==0) break }return(list(w=w,b=b))
}
x<-data.frame(x1=c(3,4,1),x2=c(3,3,1))
y<-c(1,1,-1)
model<-perception(x,y)
print(model)

2.感知机学习算法的对偶形式
在例题中的感知机迭代过程中,设置初始值ω0=(0,0),b0=0,η=1\omega _{0}=(0,0),b_{0}=0,\eta =1ω0​=(0,0),b0​=0,η=1
第一次迭代,由于对x1=(3,3)x_{1}=(3,3)x1​=(3,3)为误分点,更新参数模型:ω1=ω0+y1x1=(3,3),b1=b0+η⋅y1=1\omega _{1}=\omega _{0}+y_{1}x_{1}=(3,3),b_{1}=b_{0}+\eta \cdot y_{1}=1ω1​=ω0​+y1​x1​=(3,3),b1​=b0​+η⋅y1​=1第二次迭代,由于对x3=(1,1)x_{3}=(1,1)x3​=(1,1)是误分点,更新参数模型:ω2=ω1+η⋅y3x3=η⋅y1x1+η⋅y3x3=(2,2)\omega _{2}=\omega _{1}+\eta \cdot y_{3}x_{3}=\eta \cdot y_{1}x_{1}+\eta \cdot y_{3}x_{3}=(2,2)ω2​=ω1​+η⋅y3​x3​=η⋅y1​x1​+η⋅y3​x3​=(2,2)b2=b1+η⋅y3=η⋅y1+η⋅y3=0b_{2}=b_{1}+\eta \cdot y_{3}=\eta \cdot y_{1}+\eta \cdot y_{3}=0b2​=b1​+η⋅y3​=η⋅y1​+η⋅y3​=0第三次迭代由于对x3=(1,1)x_{3}=(1,1)x3​=(1,1)是误分点,更新参数模型:ω3=ω2+η⋅y3x3=η⋅y1x1+2η⋅y3x3=(1,1)\omega _{3}=\omega _{2}+\eta \cdot y_{3}x_{3}=\eta \cdot y_{1}x_{1}+2\eta \cdot y_{3}x_{3}=(1,1)ω3​=ω2​+η⋅y3​x3​=η⋅y1​x1​+2η⋅y3​x3​=(1,1)b3=b2+η⋅y3=η⋅y1+2η⋅y3=−1b_{3}=b_{2}+\eta \cdot y_{3}=\eta \cdot y_{1}+2\eta \cdot y_{3}=-1b3​=b2​+η⋅y3​=η⋅y1​+2η⋅y3​=−1第四次迭代由于对x3=(1,1)x_{3}=(1,1)x3​=(1,1)是误分点,更新参数模型:ω4=ω3+η⋅y3x3=η⋅y1x1+3η⋅y3x3=(0,0)\omega _{4}=\omega _{3}+\eta \cdot y_{3}x_{3}=\eta \cdot y_{1}x_{1}+3\eta \cdot y_{3}x_{3}=(0,0)ω4​=ω3​+η⋅y3​x3​=η⋅y1​x1​+3η⋅y3​x3​=(0,0)b4=b3+η⋅y3=η⋅y1+3η⋅y3=−2b_{4}=b_{3}+\eta \cdot y_{3}=\eta \cdot y_{1}+3\eta \cdot y_{3}=-2b4​=b3​+η⋅y3​=η⋅y1​+3η⋅y3​=−2第五次迭代由于对x1=(3,3)x_{1}=(3,3)x1​=(3,3)是误分点,更新参数模型:ω5=ω4+η⋅y3x3=2η⋅y1x1+3η⋅y3x3=(3,3)\omega _{5}=\omega _{4}+\eta \cdot y_{3}x_{3}=2\eta \cdot y_{1}x_{1}+3\eta \cdot y_{3}x_{3}=(3,3)ω5​=ω4​+η⋅y3​x3​=2η⋅y1​x1​+3η⋅y3​x3​=(3,3)b5=b4+η⋅y1=2η⋅y1+3η⋅y3=−1b_{5}=b_{4}+\eta \cdot y_{1}=2\eta \cdot y_{1}+3\eta \cdot y_{3}=-1b5​=b4​+η⋅y1​=2η⋅y1​+3η⋅y3​=−1第六次迭代由于对x3=(1,1)x_{3}=(1,1)x3​=(1,1)是误分点,更新参数模型:ω6=ω5+η⋅y3x3=2η⋅y1x1+4η⋅y3x3=(2,2)\omega _{6}=\omega _{5}+\eta \cdot y_{3}x_{3}=2\eta \cdot y_{1}x_{1}+4\eta \cdot y_{3}x_{3}=(2,2)ω6​=ω5​+η⋅y3​x3​=2η⋅y1​x1​+4η⋅y3​x3​=(2,2)b6=b5+η⋅y3=2η⋅y1+4η⋅y3=−2b_{6}=b_{5}+\eta \cdot y_{3}=2\eta \cdot y_{1}+4\eta \cdot y_{3}=-2b6​=b5​+η⋅y3​=2η⋅y1​+4η⋅y3​=−2第七次迭代由于对x3=(1,1)x_{3}=(1,1)x3​=(1,1)是误分点,更新参数模型:ω7=ω6+η⋅y3x3=2η⋅y1x1+5η⋅y3x3=(1,1)\omega _{7}=\omega _{6}+\eta \cdot y_{3}x_{3}=2\eta \cdot y_{1}x_{1}+5\eta \cdot y_{3}x_{3}=(1,1)ω7​=ω6​+η⋅y3​x3​=2η⋅y1​x1​+5η⋅y3​x3​=(1,1)b7=b6+η⋅y3=2η⋅y1+5η⋅y3=−3b_{7}=b_{6}+\eta \cdot y_{3}=2\eta \cdot y_{1}+5\eta \cdot y_{3}=-3b7​=b6​+η⋅y3​=2η⋅y1​+5η⋅y3​=−3从这个过程中可以发现,当初始值ω0=(0,0),b0=0\omega _{0}=(0,0),b_{0}=0ω0​=(0,0),b0​=0时,感知机模型的参数可以表示为数据集中实例点的线性合:ω=2η⋅y1x1+0η⋅y2x2+5η⋅y3x3\omega =2\eta \cdot y_{1}x_{1}+0\eta \cdot y_{2}x_{2}+5\eta \cdot y_{3}x_{3}ω=2η⋅y1​x1​+0η⋅y2​x2​+5η⋅y3​x3​b=2η⋅y1+0η⋅y2+5η⋅y3b=2\eta \cdot y_{1}+0\eta \cdot y_{2}+5\eta \cdot y_{3}b=2η⋅y1​+0η⋅y2​+5η⋅y3​令α1=2η1,α2=0η2,α3=5η3\alpha_{1}=2\eta _{1},\alpha _{2}=0\eta _{2},\alpha _{3}=5\eta _{3}α1​=2η1​,α2​=0η2​,α3​=5η3​,则有ω=α1y1x1+α2y2x2+α3y3x3=∑3j=1αjyjxj\omega =\alpha_{1}y_{1}x_{1}+\alpha _{2}y_{2}x_{2}+\alpha _{3}y_{3}x_{3}=\sum_{3}^{j=1}\alpha_{j}y_{j}x_{j}ω=α1​y1​x1​+α2​y2​x2​+α3​y3​x3​=3∑j=1​αj​yj​xj​b=α1y1+α2y2+α3y3=∑3j=1αjyjb=\alpha_{1}y_{1}+\alpha _{2}y_{2}+\alpha _{3}y_{3}=\sum_{3}^{j=1}\alpha_{j}y_{j}b=α1​y1​+α2​y2​+α3​y3​=3∑j=1​αj​yj​αj=njη\alpha_{j}=n_{j}\etaαj​=nj​η为xjx_{j}xj​被误分的次数,njn_{j}nj​越大表示实例点(xj,yj)(x_{j},y_{j})(xj​,yj​)离分离超平面越近,就越难被分类。将ω=∑3j=1αjyjxj\omega =\sum_{3}^{j=1}\alpha_{j}y_{j}x_{j}ω=∑3j=1​αj​yj​xj​带入感知机的原始形式就得到感知机的对偶形式,在该形式下,分离超平面为∑3j=1αjyjxj⋅x+b=0\sum_{3}^{j=1}\alpha_{j}y_{j}x_{j}\cdot\mathbf{x} +b=03∑j=1​αj​yj​xj​⋅x+b=0而感知机模型为f(x)=sign(∑3j=1αjyjxj⋅x+b)f(x)=sign(\sum_{3}^{j=1}\alpha_{j}y_{j}x_{j}\cdot\mathbf{x} +b)f(x)=sign(3∑j=1​αj​yj​xj​⋅x+b)这种算法旨在求解α=(α1,α2,...,αn)\mathbf{\alpha }=(\alpha _{1},\alpha _{2},...,\alpha _{n})α=(α1​,α2​,...,αn​)和bbb。

对偶形式的感知机R语言代码:

perception_pair<-function(x,class,eta=1)#x为样本的特征矩阵,class为样本的分类标签,eta为学习步长
{ma<-as.matrix(x)N<-nrow(x)  #计算样本容量a<-rep(0,times=N)w<-vector(length = ncol(x));b<-0   #初始化w,bgram<-ma%*%t(ma)while(TRUE){k<-0for(i in 1:N){if(y[i]*(sum(a*y*gram[,i])+b)<=0){a[i]<-a[i]+etab<-b+eta*y[i]k<-k+1} }if(k==0) break }for (i in 1:N) {w<-w+a[i]*y[i]*ma[i,]}return(list(a=a,w=w,b=b))
}
model_pair<-perception_pair(x,y)
model<-perception(x,y)
print(model)

感知机算法学习笔记(带例题及代码)相关推荐

  1. CG共轭梯度下降法【学习笔记、例题与代码】

    资料 参考视频: [详细推导][本视频还证明了收敛性]https://www.bilibili.com/video/BV16a4y1t76z?from=search&seid=35153938 ...

  2. 数学建模各类算法学习笔记(附matlab代码)

    目录 插值和拟合 线性规划 综合评价1:层次分析法(Analytic Hierarchy Process)AHP 综合评价2:Topsis(优劣解距离法) 最优解问题1:遗传算法Genitic alg ...

  3. 数据结构与算法学习笔记之先进先出的队列

    前言 队列是一种非常实用的数据结构,类似于生活中发排队,可应用于生活,开发中各个方面,比如共享打印机(先请求先打印),消息队列.你想知道他们是怎么工作的么.那就来一起学习一下队列吧 正文 一.队列的定 ...

  4. 莫队算法学习笔记(二)——带修莫队

    前言:什么是莫队 莫队算法,是一个十分优雅的暴力. 普通的莫队可以轻松解决一些离线问题,但是,当遇上了一些有修改操作的问题,普通莫队就无能为力了. 于是,改进后的莫队--带修莫队就这样产生了. L i ...

  5. 输出dag的所有拓扑排序序列_算法学习笔记(53): 拓扑排序

    拓扑排序是对DAG(有向无环图)上的节点进行排序,使得对于每一条有向边 , 都在 之前出现.简单地说,是在不破坏节点 先后顺序的前提下,把DAG拉成一条链.如果以游戏中的科技树(虽然名字带树,其实常常 ...

  6. 数据结构与算法学习笔记——链栈

    数据结构与算法学习笔记(C语言) 链栈 在开始链栈的学习之前,我们先实现一下上一篇文章中提到的检查括号匹配的小程序,鉴于水平有限,本人就随便写一下代码好了,目标仅限于对功能的实现. /*用顺序栈这种数 ...

  7. Lasso线性回归学习笔记(公式与代码实现)

    目录 Lasso线性回归学习笔记(公式与代码实现) 1 为什么要在线性回归中引入正则化项(简介) 2 常见正则化项 3 损失函数图像与正则化之后的图像 3.1损失函数图像 3.2 加了 L~1~ 正则 ...

  8. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  9. 数据结构与算法学习笔记之 从0编号的数组

    数据结构与算法学习笔记之 从0编号的数组 前言 数组看似简单,但掌握精髓的却没有多少:他既是编程语言中的数据类型,又是最基础的数据结构: 一个小问题: 为什么数据要从0开始编号,而不是 从1开始呢? ...

最新文章

  1. 【C语言】一文搞定 “文件操作”
  2. dpkg and apt
  3. Flask实战2问答平台-问答详情完成
  4. mysql在cmd命令下执行数据库操作
  5. 【thymeleaf】分页代码
  6. linux代码工具tag,gcov-dump原理分析_Linux平台代码覆盖率测试
  7. 演练 获取所有电视频道 FullChannels.xml c# 1614256914
  8. 第 180 章 IBM WebSphere
  9. tgp饥荒 服务器无响应,饥荒TGP版常见运行问题有哪些_TGP版礼包领取及邀请添加好友方法详解_快吧单机游戏...
  10. stl之multimap容器
  11. 【BZOJ3207】花神的嘲讽计划Ⅰ Hash+主席树
  12. mysql基础知识复习
  13. npm 下载为什么很慢?解决方案来了
  14. html中语音聊天怎么实现,微信小程序语音聊天功能怎么实现?
  15. 捷太格特PC10G与三菱MR-J4的SSCNETⅢ通讯
  16. DP(Nietzsche)的hu测 T1(状压dp)
  17. 罗格斯的计算机科学博士奖学金,罗格斯大学cs怎么样
  18. miui11开发版升级Android10,小米10 手机 MIUI 11 开发版升级 DXOMARK 相机版本
  19. 计算机统计各职称人数,用公式计算出各年教师的总人数和各职称的百分比
  20. 小众软件:录屏局部放大神器 ZoomIt

热门文章

  1. 恋爱协议(七七条约)
  2. 我会背锅,能去做运维吗?
  3. 压缩打包介绍 gip压缩工具 bzip压缩工具 xz压缩工具
  4. java怎么输入电话号码_如何在输入时更改输入中的电话号码格式?
  5. div c语言,c语言中的div的用法是什么?
  6. 微信恢复专家软件 v1.2.22
  7. 自动寻找如何共享特征层的“十字绣”网络:Cross-stitch Networks for Multi-task Learning
  8. CSS改变字体下划线颜色
  9. 从PC传输文件到ipad
  10. postgrepsql取代mysql_PostgrepSQL(大象)的使用