SVM分类器里面的东西好多呀,碾压前两个。怪不得称之为深度学习出现之前表现最好的算法。

今天学到的也应该只是冰山一角,懂了SVM的一些原理。还得继续深入学习理解呢。

一些关键词:

超平面(hyper plane)SVM的目标就是找到一个超平面把两类数据分开。使边际(margin)最大。如果把超平面定义为w*x+b=0.那么超平面距离任意一个支持向量的距离就是1/||w||。(||w||是w的范数,也就是√w*w’)

SVM就是解决

这个优化问题。再经过拉格朗日公式和KKT条件等数学运算求解得到一个d(XT)=∑yi*ai XT +b0。yi是类别标记,Xi是支持向量点。XT是待预测实例的转置。ai,b0是求解出的固定值。根据d(XT)的正负判断分类。

简单来说就是这样的。下面写一个简单的程序

线性可分

 1 import numpy as np
 2 import pylab as pl   #画图用
 3 from sklearn import svm
 4
 5 #随机生成两组二位数据
 6 np.random.seed(0)#使每次产生随机数不变
 7 X = np.r_[np.random.randn(20,2)-[2,2],np.random.randn(20,2)+[2,2]]#注意这里np.r_[],而不是np.r_()我都打错了,会报错TypeError: 'RClass' object is not callable
 8 #np.r_是按列连接两个矩阵,就是把两矩阵上下相加,要求列数相等,np.c_是按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等
 9
10 Y = [0] * 20+[1] * 20#Python原来可以这么简单的创建重复的列表呀
11
12 clf=svm.SVC(kernel='linear')
13 clf.fit(X,Y)
14
15 w=clf.coef_[0]
16 a=-w[0]/w[1]
17 xx=np.linspace(-5,5)#产生-5到5的线性连续值,间隔为1
18 yy=a*xx-(clf.intercept_[0])/w[1]  #clf.intercept_[0]是w3.即为公式a1*x1+a2*x2+w3中的w3。(clf.intercept_[0])/w[1]即为直线的截距
19
20 #得出支持向量的方程
21 b=clf.support_vectors_[0]
22 yy_down=a*xx+(b[1]-a*b[0])#(b[1]-a*b[0])就是简单的算截距
23 b=clf.support_vectors_[-1]
24 yy_up=a*xx+(b[1]-a*b[0])
25
26 print("w:",w) #打印出权重系数
27 print("a:",a) #打印出斜率
28 print("suport_vectors_:",clf.support_vectors_)#打印出支持向量
29 print("clf.coef_:",clf.coef_)                  #打印出权重系数,还是w
30
31
32 #这个就是画出来而已。很简单,也不太常用,都用matplotlib去了。不多说了
33 pl.plot(xx,yy,'k-')
34 pl.plot(xx,yy_down,'k--')
35 pl.plot(xx,yy_up,'k--')
36
37 pl.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,0],s=80,facecolors='none')
38 pl.scatter(X[:,0],X[:,1],c=Y,cmap=pl.cm.Paired)
39
40 pl.axis('tight')
41 pl.show()

小知识点:

np.r_是按列连接两个矩阵,就是把两矩阵上下相加,要求列数相等,np.c_是按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等

运行之后就是

w: [0.90230696 0.64821811]
a: -1.391980476255765
suport_vectors_: [[-1.02126202 0.2408932 ]
[-0.46722079 -0.53064123]
[ 0.95144703 0.57998206]]
clf.coef_: [[0.90230696 0.64821811]]

实线就是传说中的超平面,虚线就是支持向量所在的直线。

线性不可分

接下来就是线性不可分的情况啦。

顾名思义就是一根直线划分不出来两个类。

这样的话就用一个非线性的映射转化到一个更高维度的空间中。很好理解。比如一维的[-1,0,1]三个点,0是一类,(-1,1)是另一类。一根直线不可能分开,那就用一个y=x2转化为了[(-1,1),(0,0),(1,1)]这样的话就能用一根直线分开啦,比如,y=0.5这个直线。这不画图了,可以自行画图理解一下,高维亦然。

但是吧转化到高维可以分类了,然而又不便于计算了。维度越高,内积算的越慢,就令K(xi,yi)=φ(xi)·φ(yi)=x1*y1+x2*y2+......+xn*yn。这里的φ(x)就是上面说的映射。

核函数就简化了算内积的数量。让程序运行更快。将映射后的高维空间内积转换成低维空间的函数。

常用的核函数:

线性核函数(Linear Kernel):K(x,z)=x∙zK(x,z)=x∙z

多项式核函数:K(x,z)=(γx∙z+r)dK(x,z)=(γx∙z+r)d。 γ,r,dγ,r,d需要自己调参定义。

   高斯核函数(Gaussian Kernel):K(x,z)=exp(−γ||x−z||2)K(x,z)=exp(−γ||x−z||2),也称为径向基核函数(Radial Basis Function,RBF),它是非线性分类SVM最主流的核函数。libsvm默认的核函数就是它。γ大于0,需要自己调参定义。

Sigmoid核函数(Sigmoid Kernel):K(x,z)=tanh(γx∙z+r)K(x,z)=tanh(γx∙z+r)。γ,rγ,r都需要自己调参定义。

图像分类通常用RBF。文字识别通常不用RBF。具体用哪个可以尝试不同的kernel,根据结果准确度确定。

其中还有一个我看的教程中没讲到的惩罚函数C。和松弛变量ξi≥0。就是为了避免一些无法被分类的实例。也属于线性不可分。

对于多类的分类问题。一般都对于每个类,有以下当前类和其他类的二类分类器。

下面是一个人脸识别的程序。

 1 #from __future__ import print_function #__future__模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中测试一些新版本的特性
 2                                         #我的Python版本是3.6.4.所以不需要这个
 3
 4 from time import time   #对程序运行时间计时用的
 5 import logging           #打印程序进展日志用的
 6 import matplotlib.pyplot as plt  #绘图用的
 7
 8 from sklearn.model_selection import train_test_split
 9 from sklearn.datasets import fetch_lfw_people
10 from sklearn.model_selection import GridSearchCV
11 from sklearn.metrics import classification_report
12 from sklearn.metrics import confusion_matrix
13 from sklearn.decomposition import PCA
14 from sklearn.svm import SVC
15
16 logging.basicConfig(level=logging.INFO,format='%(asctime)s %(message)s')
17 lfw_people=fetch_lfw_people(min_faces_per_person=70,resize=0.4)  #名人的人脸数据集、
18
19 n_samples,h,w=lfw_people.images.shape  #多少个实例,h,w高度,宽度值
20
21 X=lfw_people.data   #特征向量矩阵
22 n_feature=X.shape[1]#每个人有多少个特征值
23
24 Y=lfw_people.target
25 target_names=lfw_people.target_names
26 n_classes=target_names.shape[0]     #多少类
27 print("Total dataset size")
28 print("n_samples:",n_samples)
29 print("n_feature:",n_feature)
30 print("n_classes:",n_classes)
31
32 X_train,X_test,Y_train,Y_test=train_test_split(X,Y,test_size=0.25)  #选取0.25的测试集
33
34 #降维
35 n_components=150  #PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
36 print("Extracting the top %d eigenfaces from %d faces" % (n_components,X_train.shape[0]))
37 t0=time()
38 pca=PCA(svd_solver='randomized',n_components=n_components,whiten=True).fit(X_train)#训练一个pca模型
39
40 print("Train PCA in %0.3fs" % (time()-t0))
41
42 eigenfaces  = pca.components_.reshape((n_components,h,w))  #提取出来特征值之后的矩阵
43
44 print("Prijecting the input data on the eigenfaces orthonarmal basis")
45 t0=time()
46 X_train_pca = pca.transform(X_train)     #将训练集与测试集降维
47 X_test_pca = pca.transform(X_test)
48 print("Done PCA in %0.3fs" % (time()-t0))
49
50
51 #终于到SVM训练了
52 print("Fiting the classifier to the training set")
53 t0=time()
54 param_grid ={'C':[1e3,5e3,1e4,5e4,1e5],#C是对错误的惩罚
55              'gamma':[0.0001,0.0005,0.001,0.005,0.01,0.1],}#gamma核函数里多少个特征点会被使用}#对参数尝试不同的值
56 clf = GridSearchCV(SVC(kernel='rbf'),param_grid)
57 clf=clf.fit(X_train_pca,Y_train)
58 print("Done Fiting in %0.3fs" % (time()-t0))
59
60 print("Best estimotor found by grid search:")
61 print(clf.best_estimator_)
62
63 print("Predicting people's names on the test set")
64 t0=time()
65 Y_pred = clf.predict(X_test_pca)
66 print("done Predicting in %0.3fs" % (time()-t0))
67
68 print(classification_report(Y_test,Y_pred,target_names=target_names)) #生成一个小报告呀
69 print(confusion_matrix(Y_test,Y_pred,labels=range(n_classes)))#这个也是,生成的矩阵的意思是有多少个被分为此类。
70
71
72 #把分类完的图画出来12个。
73
74 #这个函数就是画图的
75 def plot_gallery(images,titles,h,w,n_row=3,n_col=4):
76     plt.figure(figsize=(1.8*n_col,2.4*n_row))
77     plt.subplots_adjust(bottom=0,left=.01,right=.99,top=.90,hspace=.35)
78     for i in range(n_row*n_col):
79         plt.subplot(n_row,n_col,i+1)
80         plt.imshow(images[i].reshape((h,w)),cmap=plt.cm.gray)
81         plt.title(titles[i],size=12)
82         plt.xticks(())
83         plt.yticks(())
84
85 #这个函数是生成一个固定格式的字符串的
86 def title(y_pred,y_test,target_names,i):
87     pred_name=target_names[y_pred[i]].rsplit(' ',1)[-1]
88     true_name = target_names[y_test[i]].rsplit(' ', 1)[-1]
89     return "predicted: %s\n true: %s" %(pred_name,true_name)
90
91 predicted_titles=[title(Y_pred,Y_test,target_names,i) for i in range(Y_pred.shape[0])] #这个for循环的用法很简介
92
93 plot_gallery(X_test,predicted_titles,h,w)
94
95 eigenfaces_titles=["eigenface %d " % i for i in range(eigenfaces.shape[0])]
96 plot_gallery(eigenfaces,eigenfaces_titles,h,w)
97
98 plt.show()

运行结果为

Total dataset size
n_samples: 1288
n_feature: 1850
n_classes: 7
Extracting the top 150 eigenfaces from 966 faces
Train PCA in 0.440s
Prijecting the input data on the eigenfaces orthonarmal basis
Done PCA in 0.019s
Fiting the classifier to the training set
Done Fiting in 52.087s
Best estimotor found by grid search:
SVC(C=1000.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma=0.001, kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
Predicting people's names on the test set
done Predicting in 0.147s
                               precision recall   f1-score support

Ariel Sharon             0.75       0.80     0.77       15
Colin Powell             0.81       0.86     0.84       59
Donald Rumsfeld     0.86       0.81     0.83        37
George W Bush       0.90       0.90     0.90      134
Gerhard Schroeder  0.77       0.82     0.79        28
Hugo Chavez           0.92       0.86     0.89       14
Tony Blair                 0.81       0.71     0.76       35

avg / total                 0.85       0.85     0.85      322

[[ 12 3 0 0 0 0 0]
[ 1 51 0 5 0 0 2]
[ 2 1 30 2 0 1 1]
[ 1 5 5 120 2 0 1]
[ 0 1 0 2 23 0 2]
[ 0 1 0 1 0 12 0]
[ 0 1 0 4 5 0 25]]

下面这个是用主成分分析提取特征后的图像

两个矩阵的解释

precision recall   f1-score support

Ariel Sharon             0.75       0.80     0.77       15
Colin Powell             0.81       0.86     0.84       59
Donald Rumsfeld     0.86       0.81     0.83        37
George W Bush       0.90       0.90     0.90      134
Gerhard Schroeder  0.77       0.82     0.79        28
Hugo Chavez           0.92       0.86     0.89       14
Tony Blair                 0.81       0.71     0.76       35

avg / total                 0.85       0.85     0.85      322

这个

- TP,True Positive      本来是对的也预测对了
- FP,False Positive     本来是对的但预测错了
- TN,True Negative     本来是错的也预测对了
- FN,False Negative    本来是错了但是也预测错了

precision = TP / (TP + FP)

recall = TP / (TP + FN)

accuracy = (TP + TN) / (TP + FP + TN + FN)

F1 Score = P*R/2(P+R),其中P和R分别为 precision 和 recall

[[ 12 3 0 0 0 0 0]
[ 1 51 0 5 0 0 2]
[ 2 1 30 2 0 1 1]
[ 1 5 5 120 2 0 1]
[ 0 1 0 2 23 0 2]
[ 0 1 0 1 0 12 0]
[ 0 1 0 4 5 0 25]]

就是七个类,7*7的矩阵,一个类被预测为的类加一,明显对角线是预测为本身的数量。最多

其中一些函数的具体解释

lfw_people=fetch_lfw_people(min_faces_per_person=70,resize=0.4)

'''
看他的官方文档
def fetch_lfw_people(data_home=None, funneled=True, resize=0.5,min_faces_per_person=0, color=False,slice_=(slice(70, 195), slice(78, 172)),download_if_missing=True):"""Loader for the Labeled Faces in the Wild (LFW) people datasetThis dataset is a collection of JPEG pictures of famous peoplecollected on the internet, all details are available on theofficial website:http://vis-www.cs.umass.edu/lfw/Each picture is centered on a single face. Each pixel of each channel(color in RGB) is encoded by a float in range 0.0 - 1.0.The task is called Face Recognition (or Identification): given thepicture of a face, find the name of the person given a training set(gallery).
The original images are 250 x 250 pixels, but the default slice and resizearguments reduce them to 62 x 74.Parameters----------data_home : optional, default: NoneSpecify another download and cache folder for the datasets. By defaultall scikit learn data is stored in '~/scikit_learn_data' subfolders.funneled : boolean, optional, default: TrueDownload and use the funneled variant of the dataset.resize : float, optional, default 0.5Ratio used to resize the each face picture.min_faces_per_person : int, optional, default NoneThe extracted dataset will only retain pictures of people that have atleast `min_faces_per_person` different pictures.color : boolean, optional, default FalseKeep the 3 RGB channels instead of averaging them to a singlegray level channel. If color is True the shape of the data hasone more dimension than the shape with color = False.slice_ : optionalProvide a custom 2D slice (height, width) to extract the'interesting' part of the jpeg files and avoid use statisticalcorrelation from the backgrounddownload_if_missing : optional, True by defaultIf False, raise a IOError if the data is not locally availableinstead of trying to download the data from the source site.Returns-------dataset : dict-like object with the following attributes:dataset.data : numpy array of shape (13233, 2914)Each row corresponds to a ravelled face image of original size 62 x 47pixels. Changing the ``slice_`` or resize parameters will change theshape of the output.dataset.images : numpy array of shape (13233, 62, 47)Each row is a face image corresponding to one of the 5749 people inthe dataset. Changing the ``slice_`` or resize parameters will changethe shape of the output.dataset.target : numpy array of shape (13233,)Labels associated to each face image. Those labels range from 0-5748and correspond to the person IDs.dataset.DESCR : stringDescription of the Labeled Faces in the Wild (LFW) dataset意思就是min_faces_per_person=定义了每个人取多少个不同图片,resize=重新定义了图片的大小
'''

pca=PCA(svd_solver='randomized',n_components=n_components,whiten=True).fit(X_train)
'''
n_components:PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
类型:int 或者 string,缺省时默认为None,所有成分被保留。赋值为int,比如n_components=1,将把原始数据降到一个维度。赋值为string,比如n_components='mle',将自动选取特征个数n,使得满足所要求的方差百分比。copy:表示是否在运行算法时,将原始训练数据复制一份。若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;若为False,则运行PCA算法后,原始训练数据的值会改,因为是在原始数据上进行降维计算。
类型:bool,True或者False,缺省时默认为True。whiten:白化,使得每个特征具有相同的方差。由于图像中相邻像素之间具有很强的相关性,所以用于训练时输入是冗余的。白化的目的就是降低输入的冗余性;更正式的说,我们希望通过白化过程使得学习算法的输入具有如下性质:(i)特征之间相关性较低;(ii)所有特征具有相同的方差。类型:bool,缺省时默认为FalsePCA对象的属性
components_ :返回具有最大方差的成分。
explained_variance_ratio_:返回 所保留的n个成分各自的方差百分比。
n_components_:返回所保留的成分个数n。
mean_:
noise_variance_:'''

很容易理解。用的时候再具体看。

同时我照着教程上的代码写的时候也遇到了一些错误

1、 DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. This module will be removed in 0.20.
DeprecationWarning)
该模块在0.18版本中被弃用,支持所有重构的类和函数都被移动到的model_selection模块

解决办法。

from sklearn.model_selection import GridSearchCV

from sklearn.model_selection import train_test_split

改为:
from sklearn.grid_search import GridSearchCV

from sklearn.cross_validation import train_test_split

2、ValueError: class_weight must be dict, 'balanced', or None, got: 'auto'

在第五十行

clf = GridSearchCV(SVC(kernel='rbf'),param_grid)中原本是clf = GridSearchCV(SVC(kernel='rbf',class_weight ='auto'),param_grid).但是

class_weight ='auto'在此版本中不存在,删除即可。或者用 'balanced' or None

3、DeprecationWarning: Class RandomizedPCA is deprecated; RandomizedPCA was deprecated in 0.18 and will be removed in 0.20. Use PCA(svd_solver='randomized') instead. The new implementation DOES NOT store whiten ``components_``. Apply transform to get them.
warnings.warn(msg, category=DeprecationWarning)

还是版本问题
将from sklearn.decomposition import RandomizedPCA修改为from sklearn.decomposition  import PCA

然后将出错的那个程序句子改为:pca = PCA(svd_solver='randomized', n_components = n_components, whiten = True).fit(X_train)即可

4、ValueError: Found input variables with inconsistent numbers of samples: [322, 966]

两个矩阵行或者宽的不一样而已,我打错了。

今天也只是入个门。学的还不是太深。今后有机会会继续深入学习的。

在此推荐个大佬写的

支持向量机原理(一) 线性支持向量机

支持向量机原理(二) 线性支持向量机的软间隔最大化模型

支持向量机原理(三)线性不可分支持向量机与核函数

支持向量机原理(四)SMO算法原理

支持向量机原理(五)线性支持回归

有空一定要研究一下。

另外,我看到网上也有很多写的跟我一样的博客。学的教程都一样。有的只是简单复制粘贴,有的也写的很详细。我想说的是,既然学了就学的尽量详细点,也就是代码自己一句一句的打,每个函数都弄清楚。算法原理也要及时记下来。不要只看看教程看看别人实现一遍。

转载于:https://www.cnblogs.com/albert-yzp/p/9525162.html

菜鸟之路——机器学习之SVM分类器学习理解以及Python实现相关推荐

  1. python 非线性回归_机器学习入门之菜鸟之路——机器学习之非线性回归个人理解及python实现...

    本文主要向大家介绍了机器学习入门之菜鸟之路--机器学习之非线性回归个人理解及python实现,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助. 梯度下降:就是让数据顺着梯度最大的方向,也 ...

  2. python支持向量机分类器怎么用_可视化SVM分类器开源实现的python代码

    如下的Python代码是可视化SVM分类器开源实现的python代码.这是个小巧又简单,却不一定满足大家高效要求的具有可视化功能的SVM分类器源码.是采用标准python写成的,但如果需要作图功能,则 ...

  3. 机器学习 matlab工具箱,[matlab]机器学习及SVM工具箱学习笔记

    机器学习与神经网络的关系: 机器学习是目的,神经网络是算法.神经网络是实现机器学习的一种方法,平行于SVM. 常用的两种工具:svm tool.libsvm SVM分为SVC和SVR,svc是专门用来 ...

  4. 机器算法有哪几种 python_8种顶级Python机器学习算法-你必须学习

    今天,我们将更深入地学习和实现8个顶级Python机器学习算法. 让我们开始Python编程中的机器学习算法之旅. 8 Python机器学习算法 - 你必须学习 以下是Python机器学习的算法: 1 ...

  5. 【机器学习】SVM学习(三):线性分类器的求解

    [机器学习]SVM学习(三):线性分类器的求解 2016-10-10 19:56 239人阅读 评论(0) 收藏 举报 本文章已收录于:  机器学习知识库  分类: 机器学习(37)  目录(?)[+ ...

  6. 数学之路(3)-机器学习(3)-机器学习算法-SVM[7]

    SVM是新近出现的强大的数据挖掘工具,它在文本分类.手写文字识别.图像分类.生物序列分析等实际应用中表现出非常好的性能.SVM属于监督学习算法,样本以属性向量的形式提供,所以输入空间是Rn的子集. 图 ...

  7. 系统学习机器学习之SVM(三)--Liblinear,LibSVM使用整理,总结

    1.Libsvm与Liblinear区别,简单源码剖析. http://blog.csdn.net/zhzhl202/article/details/7438160 http://blog.csdn. ...

  8. svm分类器训练详细步骤_「五分钟机器学习」向量支持机SVM——学霸中的战斗机...

    大家好,我是爱讲故事的某某某. 欢迎来到今天的[五分钟机器学习]专栏内容 --<向量支持机SVM> 今天的内容将详细介绍SVM这个算法的训练过程以及他的主要优缺点,还没有看过的小伙伴欢迎去 ...

  9. svm分类器_使用放射学机器学习分类器区分胶质母细胞瘤与孤立性脑转移瘤

    使用放射学机器学习分类器区分胶质母细胞瘤与孤立性脑转移瘤 脑转移瘤(MET)和胶质母细胞瘤(GBM)是成人中最常见的恶性脑肿瘤.因此,MET和GBM的准确术前区分对于个体化治疗至关重要.在这项研究中, ...

最新文章

  1. 十年JAVA架构经验总结:这几点尤为关键!
  2. 二叉树数据结构和算法
  3. python统计表中单词及其出现的次数 字典形式输出_统计字符串中字母出现的次数,字典形式输出(python)...
  4. mfc 获取窗口在屏幕中的位置_CSocket与CAsynSocket中的阻塞与非阻塞
  5. 产品设计中不可忽视的意见反馈功能
  6. Lumion文件结构及Benchmark in progrees问题
  7. 如何清理驱动人生的新闻弹窗
  8. 【小插件】文字镂空“LSP”制作空心文字CAD
  9. vray铺装材质参数设计蓝海创意云渲染
  10. 按颜色分类:蓝色系(Blue)
  11. 陀螺仪传感器和加速度传感器的区别与联系
  12. Java并发编程学习篇3_读写锁ReadWriteLock、阻塞队列BlockingQueue、同步队列SynchronousQueue、线程池(三大方法、七大参数、四种拒绝策略、原生方式创建线程池)
  13. java 基准测试 格式_JMH java基准测试
  14. MD5 SHA1 SHA256 SHA512 SHA1WithRSA RSA 的区别
  15. 山东省2013高职分数线
  16. 抖音电商直播间SOP主播工作计划脚本话术模板方案
  17. 超级实用案例,Python 提取 PDF 指定内容生成新PDF
  18. 用户增长——Cohort Analysis 留存分析(三)
  19. eclipselink 数据库表命名规则 驼峰转下划线/表名转换
  20. Hi3516开发笔记(一):海思HI3516DV300芯片介绍,入手开发板以及Demo测试

热门文章

  1. 微信 企业付款到余额 开发 教程
  2. 微软专业讲师教程(mcse 2003 server)下载(经典视频学习教材)e
  3. Java工程师修炼之路(从小白到BAT的两年学习历程)...
  4. 百度、360、搜狗自动收入js
  5. 让算法工程师变身街舞达人,蚂蚁金服的这个比赛绝了!
  6. 显著性检验 python_《显》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...
  7. 保卫萝卜项目(java端)
  8. 是什么让我放弃了restful api?了解清楚后我全面拥抱GraphQL
  9. pyqt(二)动图(gif)显示与资源文件(qrc文件)
  10. three.js学习笔记(十二)——使用Blender自定义模型