【学习笔记】cs229机器学习笔记(二)



  • 机器学习实战--KNN分类器
    1.KNN聚类算法

    from numpy import *
    import operator
    def classify(test,data,target,k):
        datasize=data.shape[0]
        diff=tile(test,(datasize,1))-data#tile()
        sq_diff=diff**2
        sq_dis=sq_diff.sum(axis=1)
        dis=sq_dis**0.5
        sorted_dis_index=dis.argsort()
        cnt={}
        for i in range(k):
            num=target[sorted_dis_index[i]]
            cnt[num]=cnt.get(num,0)+1#get() return value of cnt[num](if cnt[num] doesn't exist cnt[num]=0)
        sorted_cnt=sorted(cnt.items(),key=operator.itemgetter(1),reverse=True)#itemgetter(1) 
        return sorted_cnt[0][0]
    #data,target=createDataSet()
    #print(classify([1,1],data,target,3))
    

    2.文件转矩阵形式

    def file2matrix(filename):
    	f=open(filename)
    	array_line=f.readlines()
    	len_line=len(array_line)
    	data=zeros((len_line,3))
    	tar=[]
    	index=0
    	for line in array_line:
    		line=line.strip()
    		line2list=line.split('\t')
    		data[index,:]=line2list[0:3]
    		tar.append(int(line2list[-1]))
    		index+=1
    	return data,tar
    
    
    dt,tar=file2matrix('datingTestSet2.txt')
    #print(dt)
    #print(tar)
    

    3.作图观察数据集两列特征值之间的关系

    import matplotlib as mlp
    mlp.use('Agg')
    import matplotlib.pyplot as plt
    fig=plt.figure()
    ax=fig.add_subplot(111)
    ax.scatter(dt[:,1],dt[:,2],15.0*array(tar),15.0*array(tar))
    
    #plt.savefig('/home/xxh/tf/KNN/datingTestPic.png')
    

    得到散点图:
    0_1541941780830_51854449-0003-413b-a9a6-6fcbffd0491d-image.png

    3.数据归一化

    def autoNorm(dataset):
    	minval=dataset.min(0)
    	maxval=dataset.max(0)
    	Range=maxval-minval
    	normdataset=zeros(shape(dataset))
    	m=dataset.shape[0]
    	normdataset=dataset-tile(minval,(m,1))
    	normdataset=normdataset/tile(Range,(m,1))
    	return normdataset,Range,minval
    
    #normdt,range,minval=autoNorm(dt)
    #print(normdt)
    #print(range)
    #print(minval)
    

    4.分类器测试(主函数)

    def datingClassTest():
    	errorList=[]
    	ratioList=[]
    	data,target=file2matrix('datingTestSet2.txt')
    	normdata,ranges,minval=autoNorm(data)
    	m=normdata.shape[0]	
    	for j in range(1,100):
    		ratioOfTrainingData=0.01*j
    		ratioList.append(ratioOfTrainingData)
    		numOfTrainingData=int(m*ratioOfTrainingData)
    		errorNum=0.0
    		for i in range(numOfTrainingData):
    			result=classify(normdata[i,:],normdata[numOfTrainingData:m,:],target[numOfTrainingData:m],3)
    			if(result!=target[i]):errorNum+=1.0
    		errorRate=errorNum/float(numOfTrainingData)
    		print(j,end=' ')
    		print(errorRate)
    		errorList.append(float(errorRate))
    		
    	figure=plt.figure()
    	axx=figure.add_subplot(111)
    	axx.scatter(ratioList[:],errorList[:])	
    	plt.savefig('/home/xxh/tf/KNN/KNN_TEST.png')
    datingClassTest()
    

    顺便画了一下测试集比例与准确率之间的关系图
    0_1541941937215_daf90642-ac49-43b5-b123-d9eb482f8702-image.png
    5.分类器使用

    def classifyPerson():
    	resultList=['not at all','in small doses','in large doses']
    	percent=float(input("percentage"))
    	ffm=float(input("frequence"))
    	icecream=float(input("ice-cream"))
    	data,target=file2matrix('datingTestSet2.txt')
    	normdata,ranges,minval=autoNorm(data)
    	inArr=array([ffm,percent,icecream])
    	result=classify((inArr-minval)/ranges,normdata,target,3)
    	print(resultList[result-1])
    
    classifyPerson()
    


  • 机器学习实战——KNN手写数字识别

    
    from numpy import*
    from os import listdir
    import operator
    

    1.基于KNN的分类器

    
    def classify(test,data,target,k):
        datasize=data.shape[0]
        diff=tile(test,(datasize,1))-data#tile(扩展行,扩展列)
        sq_diff=diff**2
        sq_dis=sq_diff.sum(axis=1)#axis=1->求列的和;axis=0->求行的和
        dis=sq_dis**0.5
        sorted_dis_index=dis.argsort()
        cnt={}
        for i in range(k):
            num=target[sorted_dis_index[i]]
            cnt[num]=cnt.get(num,0)+1
        sorted_cnt=sorted(cnt.items(),key=operator.itemgetter(1),reverse=True)#itemgetter(1) :0->index,1->key
        return sorted_cnt[0][0]
    #data,target=createDataSet()
    #print(classify([1,1],data,target,3))
    

    2.图片转向量

    def img2vec(filename):
    	returnVec=zeros((1,1024))
    	fr=open(filename)
    	for i in range(32):
    		lineStr=fr.readline()
    		for j in range(32):
    			returnVec[0,32*i+j]=int(lineStr[j])
    	return returnVec
    #testVector=img2vec("0_0.txt")
    

    3.手写数字识别主函数

    def digitRecognition():
    	hwLabels=[]
    	dataFileList=listdir('trainingDigits')
    	len_fileList=len(dataFileList)
    	data=zeros((len_fileList,1024))
    	for i in range(len_fileList):
    		fileNameStr=dataFileList[i]
    		fileStr=fileNameStr.split(',')[0]
    		classNumStr=int(fileStr.split('_')[0])
    		hwLabels.append(classNumStr)
    		data[i,:]=img2vec('trainingDigits/%s'% fileNameStr)
    	testFileList=listdir('testDigits')
    	errorCnt=0.0
    	len_testList=len(testFileList)
    	for i in range(len_testList):
    		fileNameStr=testFileList[i]
    		fileStr=fileNameStr.split(',')[0]
    		classNumStr=int(fileStr.split('_')[0])
    		testVector=img2vec('testDigits/%s'%fileNameStr)
    		classifierResult=classify(testVector,data,hwLabels,3)
    		print("classifier: %d, right: %d" %(classifierResult ,classNumStr))
    		if( classifierResult != classNumStr ): 
    			errorCnt+=1.0
    	errorRate=(errorCnt/float(len_testList))
    	#print(len_testList)
    	print(errorCnt)
    	print(errorRate)
    

    4.测试结果:(好慢啊)

    #errorCnt:11.0
    #errorRate:0.011627906976744186
    #timeCost:19.133 seconds
    


  • 决策树

    • 表示基于特征对实例进行分类的过程
    • 计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据
    • 数据类型:数值型(需要离散化)和标称型
    • 可能会产生过度匹配的问题
      0_1542117438761_a2148abc-72df-43de-9ab5-e83544860def-image.png

    信息熵

    • 熵定义为信息的期望值

    • 计算公式: 0_1542117568039_0d04d11a-2a8e-4978-b2dc-558cd53a8ec7-image.png

    • n为分类数目,熵越大,随机变量的不确定性就越大。

    信息增益

    • 划分数据集前后信息发生的变化
    • 获得信息增益最高的特征就是最好的选择

    基于ID3算法的决策树构造
    1)从根开始,当前结点的最大信息增益的特征为作为结点特征。
    2)由父特征节点建立子特征值节点,再对子结点递归地建树。
    3)当所有特征的信息增益均很小或没有特征时,结束。
    算法实质是一种贪心法的应用,所以得到的是局部最优,而不是全局最优。

    from math import log
    import operator
    def createData():#构造一个数据集&特征标签
        data= [[1, 1, 'yes'],
                   [1, 1, 'yes'],
                   [1, 0, 'no'],
                   [0, 1, 'no'],
                   [0, 1, 'no']]
        datalabel=['A','B']
        return data,datalabel
    
    def calcShannon(data):#计算信息熵
        len_data=len(data)
        cnt_label={}
        for vec in data:
            target=vec[-1]
            if target not in cnt_label.keys():
                cnt_label[target]=0
            cnt_label[target]+=1
        shannonVal=0.0
        for key in cnt_label:
            p=float(cnt_label[key]/len_data)
            shannonVal-=p*log(p,2)
        return shannonVal
    
    mydat,mytar=createData()
    print(mydat)
    print(mytar)
    
    def divData(data,axis,value):#将某一特征列的向量删除掉
        retData=[]
        for vec in data:
            if(vec[axis]==value):
                reducedVec=vec[:axis]
                reducedVec.extend(vec[axis+1:])
                retData.append(reducedVec)
        return retData
    #print(divData(mydat,0,1))
    
    def calcBestDiv(data):#返回信息增益最大特征的索引值
        num_feature=len(data[0])-1
        baseEntropy=calcShannon(data)
        bestInfoGain=0.0
        bestRoot=-1
        for i in range(num_feature):
            featureList=[example[i] for example in data]
            #print(featureList)
            uniqueVals=set(featureList)
            newEntropy=0.0
            for val in uniqueVals:
                subData=divData(data,i,val)
                p=len(subData)/float(len(data))
                newEntropy-=p*log(p,2)
                infoGain=baseEntropy-newEntropy
                if(infoGain>bestInfoGain):
                    bestInfoGain=infoGain
                    bestRoot=i
        return bestRoot
    #print(calcBestDiv(mydat))
    
    def majorityCnt(classList):#计算出classList中出现次数最多的类标签
        classCnt={}
        for item in classList:
            if item not in classCnt.keys():
                classCnt[item]=0
            classCnt[item]+=1
        sortedClassCnt=sorted(classCnt.items(),key=operator.itemgetter(1),reverse=True)
        return sortedClassCnt[0][0]
    
    def createTree(data,labels):#建立决策树结构
        classList=[example[-1] for example in data]
    #print(classList[0])
        if classList.count(classList[0])==len(classList):
            return classList[0]
        if len(classList)==1:
            return majorityCnt(classList)
        bestRoot=calcBestDiv(data)
        bestLabel=labels[bestRoot]
        myTree={bestLabel:{}}
        del(labels[bestRoot])
        featureValues=[example[bestRoot] for example in data]
        uniqueVals=set(featureValues)
        for value in uniqueVals:
            subLabels=labels[:]
            myTree[bestLabel][value]=createTree(divData(data,bestRoot,value),subLabels)
        return myTree
    
    
    
    def classify(inputTree,featLabels,testVec):#根据得到的决策树进行分类
        firstSides=list(inputTree.keys())
        firstStr=firstSides[0]
        secondDict = inputTree[firstStr]
        featIndex = featLabels.index(firstStr)
        key = testVec[featIndex]
        valueOfFeat = secondDict[key]
        if isinstance(valueOfFeat, dict): 
            classLabel = classify(valueOfFeat, featLabels, testVec)
        else: classLabel = valueOfFeat
        return classLabel
    
    
    labels1=mytar[:]
    myTree=createTree(mydat,labels1)
    #test_part
    labels1=mytar[:]
    print(labels1)
    print(classify(myTree,labels1,[1,1]))
    

    debug教训:(悟已往之不谏,知来者之可追)
    1.python复制列表内容要写成label=mytar[:]形式,不能写成引用形式label=mytar。
    2.在Python 3.x 里面,iteritems()方法已经废除了,要用 items()方法。



  • 朴素贝叶斯分类器

    一、预备知识

    • 先验概率:基于经验对于事件概率的估计
    • 后验概率:结合已有知识,考虑事件的相关因素后,对于随机事件的概率的预估
    • 贝叶斯定理:(后验概率的获得方法)
      0_1542258044844_f856bbaa-cc25-424e-a386-01c80fa57330-image.png

    ​ c->随机事件发生的一种情况,x->与随机事件相关的因素

    二、朴素贝叶斯定理

    • 假设:以自变量之间的独立(条件特征独立)性和连续变量的正态性假设为前提

    • 优点:在数据较小的情况下仍然有效,可以处理多类别问题

    • 缺点:对输入数据的准备方式较为敏感

    • 如果有一项概率值为0会影响后面估计,所以我们对未出现的属性概率设置一个很小的值。即进行拉普拉斯修正:img

    • 贝叶斯决策理论核心思想:选择高概率对应的类别

    三、离散属性与连续属性值的分别处理

    • 离散值属性->计算每个属性取值占所有样本的数量比例

    • 连续值属性->用概率密度函数
      0_1542258003835_dccc9fb4-ec92-40ee-874b-71cc21dcb020-image.png
      四、贝叶斯分类器训练

    
    def loadDataSet():#载入数据集
        dataList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                     ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                     ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                     ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                     ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                     ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
        labelMark = [0,1,0,1,0,1]    #1 is abusive, 0 not
        return dataList,labelMark
    my_dataList,my_labelMark=loadDataSet()
    #print(my_dataList)
    #print(my_labelMark)
    def createVocabList(data):#构造单词集合
        vocaSet=set([])
        for document in data:
            vocaSet=vocaSet|set(document)
        return list(vocaSet)
    
    my_vocaList=createVocabList(my_dataList)
    #print(my_vocaList)
    
    def setOfWords2Vec(vocaList,inputSet):#词表转词向量
        returnVec=[0]*len(vocaList)
        for word in inputSet:
            if word in vocaList :
                returnVec[vocaList.index(word)]=1
            else : print("this word is not in my vocaList")
        return returnVec
    
    my_returnVec=setOfWords2Vec(my_vocaList,my_dataList[0])
    #print(my_returnVec)
    
    import numpy as np
    def trainNBC(dataMatrix,labelMark):#朴素贝叶斯分类器训练
        lenDataMatrix=len(dataMatrix)
        numWords=len(dataMatrix[0])
        pAbusive=sum(labelMark)/float(lenDataMatrix)
        print(pAbusive)
        p0Num=np.zeros(numWords)
        p1Num=np.zeros(numWords)
        p0Denom=0.0
        p1Denom=0.0
        for i in range (lenDataMatrix):
            #print("dataMatrix")
            #print(i)
            #print(dataMatrix[i])
            if labelMark[i]==1:
                p1Num+=dataMatrix[i]
                p1Denom+=sum(dataMatrix[i])
            else :
                p0Num+=dataMatrix[i]
                p0Denom+=sum(dataMatrix[i])
        p1Vec=p1Num/p1Denom
        p0Vec=p0Num/p0Denom
        return p0Vec,p1Vec,pAbusive
    dataMat=[]
    for postinDoc in  my_dataList:
        dataMat.append(setOfWords2Vec(my_vocaList,postinDoc))
    print(dataMat)
    p0V,p1V,pAb=trainNBC(dataMat,my_labelMark)
    print(p0V)
    print(p1V)
    print(pAb)
    

    得到的单词集合在积极与消极的文章中出现的概率向量

    [0.         0.         0.04166667 0.04166667 0.04166667 0.04166667
     0.         0.04166667 0.04166667 0.04166667 0.04166667 0.
     0.04166667 0.         0.04166667 0.04166667 0.04166667 0.
     0.         0.08333333 0.04166667 0.04166667 0.         0.04166667
     0.         0.         0.04166667 0.04166667 0.04166667 0.
     0.125      0.04166667]
    [0.05263158 0.15789474 0.         0.         0.         0.
     0.05263158 0.         0.         0.         0.05263158 0.05263158
     0.         0.10526316 0.         0.         0.         0.05263158
     0.05263158 0.05263158 0.         0.         0.05263158 0.10526316
     0.05263158 0.05263158 0.         0.         0.05263158 0.05263158
     0.         0.        ]
    

    后续优化:考虑到贝叶斯分类器在概率计算过程中可能出现下溢出问题,解决办法是对于概率的乘积取对数



  • CS231n学习笔记——PART1:图像分类

    图像识别所面临的问题

    • 计算机视觉算法在图像识别方面,会因为图像的采集环境和拍摄因素遇到一些问题。(感觉之前参加了菜单图片采集任务后有了更深刻的理解,这些图像的噪声,正是我们在进行数据增强过程中想要制造出来的。)

    • 首先,视角变化、大小变化、形变,可以看做是对于良好的正面原图像进行了一些矩阵变换。如旋转、放缩、仿射变换等操作。

    • 其次,遮挡、背景干扰可能会对于物体边缘提取带来麻烦。

    • 然后,一些物体的类内差异 ,从根本上导致了小数据量可能会导致机器学习模型对于物体识别的泛化效果不好,造成过拟合的问题。

    • 最后,光照对于图像的像素分布会有一定影响。

      0_1543292637712_213b3fc5-b269-429b-959c-c08c5bd88a76-image.png


    图像分类流程

    • INPUT:带标签的图像训练集
    • STUDT:图像特征,以便于更好的将不同图片分类。
    • EVALUATION:分类器得到Predicted_Lable,并且与图像的正确Lable比对,得到分类器的正确率,以此评价分类器。

    Kth Nearest Neighbor分类器

    • method:将待分类图片与训练集中的带Label的图片计算图像之间的距离,并将距离前K小的训练集图片的Label 进行一轮vote,“票数最多的”即为分类器给出的标签预测结果。
    • 更高的k值可以让分类的效果更平滑,使得分类器对于异常值更有抵抗力,泛化能力更好。

    距离选择

    • L1距离:
      0_1543293161106_7559c466-1290-43ad-b03c-3d84778b7bc9-image.png

    • L2距离:
      0_1543293186283_8a7d0898-40d4-433d-a29c-b2b8d402a6e5-image.png

    KNN的问题

    • 算法的训练不需要花时间,但是测试要花费大量时间计算,不利于实际应用。
    • KNN主要是基于像素的相似来判断两张照片的匹配程度,而并未考虑语义上的相似性。(运用于图像分类不合理啊)

    实际应用k-NN

    1. 预处理数据:对数据中的特征进行归一化
    2. 高维数据,考虑使用降维方法
    3. 数据随机分入训练集和验证集,数据集较小可以采用交叉验证法
    4. 尝试足够多的k值,调参(作图后观察K与准确率的关系会有帮助)
    5. 采用最优的超参数进行分类


  • CS231n学习笔记——PART2:线性分类器
    (在CS229中学习过线性分类,在CS231n中又有了新的理解。温故而知新!)
    线性分类器的构成

    1. 评分函数,原始图像数据到类别分值的映射
    2. Loss函数,用来量化预测分类标签的得分与真实标签之间一致性,优化分类器的关键。

    新的理解

    • 图像可以看做高维度的点,图片进而在空间中可以通过一些超平面进行分割为不同类别

      0_1543294562939_96fafc6a-31e9-4712-9f1c-c8c0accac2c7-image.png

    • 线性分类器可以看做模板匹配

      • 权重W的每一行可理解为一个分类模板。通过使用内积来比较图像和模板,然后找到和哪个模板最相似。线性分类器在利用学习到的模板,针对图像做模板匹配。
      • 另外将模板看做每一类图片的均值,也可以理解为一种Kth-NN的方法。
        0_1543294866270_753741bc-fd6d-4670-9320-7c68690d3126-image.png
        (这张图真的很神奇,还是不能够完全理解其中的原理)
    • bias和weight的合并技巧(如图)
      0_1543295007707_64a45091-ff85-465e-924a-5b0afd126a8a-image.png


    损失函数 Loss function——主要用于调整weight 矩阵

    1. 多类支持向量机(SVM)损失函数
    • 目标:在正确分类上的得分始终比不正确分类上的得分高出一个边界值

    • 公式:0_1543295233462_85961cfd-f914-4e09-aaf8-40d1a55d75b8-image.png
      针对第j个类别的得分就是第j个元素:0_1543295291378_d8107551-f6ab-4e72-b8e8-40739a9a59b7-image.png

      线性模型中由于0_1543295334089_424bdb31-86f4-4d86-97ab-6eda25dd7049-image.png
      可以得到线性的SVM LOSS函数公式:0_1543295348339_13ef8420-b5a7-4cf7-ab72-f72c4051d241-image.png

    • 正则化:0_1543297674864_4050f611-defe-412f-9922-ba103ba07260-image.png
      引入正则化,能够对大数值权重进行惩罚,可以提升其泛化能力。

    1. Softmax分类器
    • 与SVM不同,将折叶损失替换为交叉熵损失,且输出(归一化的分类概率)更加直观。
    • 公式:0_1543297856553_d65f9845-93b4-4a75-be6d-19f9180793e9-image.png

    SVM与Softmax的比较图

    0_1543298317567_9ceec31c-2627-4ce3-87e3-56181a8e03ca-image.png



  • 《A Few Useful Things to Know about Machine Learning》 论文学习笔记(上)

    • 这是CS231n讲义中拓展阅读中推荐的一篇paper,作者是Pedro Domingos,主要对初学者学习机器学习的一些误区进行了解答并提供了一些有用的技巧。

    TIPS :

    1. Learning=presentation+evaluation+optimization
      进行机器学习之前首要考虑的是如何表现数据输入,并且要做到分类器和特征相匹配,不同的特征需要不同的分类器,有些特征适合使用决策树、有些适合使用线性分类器。

    2. IT’S GENERALIZATION THAT COUNTS
      分类器的目标是达到一种好的泛化效果而不是在训练集上追求准确率,对于数据集要将训练集和测试集分开。

    3. DATA ALONE IS NOT ENOUGH
      每一个机器学习器(learner)应该具有一些先验知识和假设,以便于机器学习更好进行分类选择。

    4. OVERFITTING HAS MANY FACES
      泛化是目标,因而过拟合(overfitting)自然是要避免的,造成过拟合的主要原因是训练数据太少或者模型太复杂。泛化误差由bias和variance构成。交叉验证、增加正则项有利于避免过拟合的产生

    5. INTUITION FAILS IN HIGH DIMENSIONS
      直觉不适用用高维空间,因为首先,高维度下,训练数据就会显得不够用;其次,即使数据够用,那么多的特征也只有很少一部分起到作用,进而大量的其他无用特征可能会带来噪声,使得原本的结果变得更加糟糕;最后,即使训练数据够用,并且所有维度的特征都起作用,数据在高维度时也会变得很相近。
      一种叫做“blessing of non-uniformity”的特点能够对机器学习有所帮助。考虑到大多数的数据并非在空间中均匀分布的,集中于空间的某一区域或者接近一个低维度的流形(a lower-dimensional manifold),我们可以进行降维。

    To be continued...
    (感觉写得很好,很有收获,慢慢锻炼自己读paper的能力吧~)



  • 《A Few Useful Things to Know about Machine Learning》 论文学习笔记(下)

    (续上文。。)
    TIPS:

    1. THEORETICAL GUARANTEES ARE NOT WHAT THEY SEEM
      理论保证就是为了理解,不会在实际运用中起到决策作用,最多就是在设计算法的时候给一些提示。
    2. FEATURE ENGINEERING IS THE KEY
      机器学习过程中,数据的预处理以及数据特征的设计和选择也很重要。有些特征单独看上去是不相关的,但是在组合的时候是相关的。
    3. MORE DATA BEATS A CLEVERER ALGORITHM
      大量的数据可能胜过聪明的算法,因为它能够以更快的方法获得成效。机器学习的瓶颈包括时间、内存和训练数据。同时,更多的数据意味着更加复杂的分类器需要学习,更聪明的算法更难驾驭。
    4. LEARN MANY MODELS, NOT JUST ONE
      不同的学习器的融合可以获得更加好的结果。现在有很多模型集成技术,如:bagging、boosting、stacking。
      模型融合的方法,可以将弱分类器融合之后形成一个强分类器,而且融合之后的效果会比最好的弱分类器更好。
    5. SIMPLICITY DOES NOT IMPLY ACCURACY
      著名的occam’srazor原理中说:entities should not be multiplied beyond necessity。争取的理解是:开始的时候选择简单的假设,可以修正它,直到效果理想。但是不要一开始从复杂的做起,而不是要找简单作为最终的学习器。
    6. REPRESENTABLE DOES NOT IMPLY LEARNABLE
      一个函数可以被表示出来,不见得就能被学习。当我们给定了数据、时间和内存时,用标准的学习器来学习,但是只能学习到所有可能函数的一部分,并不能学习到所有的函数。有的函数它能够写成某种形式,但是我们也可能没有办法求到它。所以要多试一些学习器。
    7. CORRELATION DOES NOT IMPLY CAUSATION
      相关性并不意味着因果(obviously~)


  • CS231n 反向传播算法补充

    • 反向传播的核心问题是基于链式法则对于梯度值的传递。

    • CS231n课程笔记中对于神经元的一种(有趣的)直观理解:将神经元看做是逻辑运算中的加法器、乘法器等逻辑门的组合。反向传播是一个优美的局部过程。门单元完成这两件事是完全独立的,它不需要知道计算线路中的其他细节。
      在整个计算线路图中,每个门单元做两件事:

      1. 前向传播时计算这个门的输出值。

      2. 反向传播时计算输出值关于输入值的局部梯度。

    • 反向传播可以看做是门单元之间在通过梯度信号相互通信,只要让它们的输入沿着梯度方向变化,无论它们自己的输出值在何种程度上升或降低,都是为了让整个网络的输出值更高。

    • 需要注意的一些东西:

      1. 对前向传播变量进行缓存,便于反向传播时的计算。

      2. 在不同分支的梯度要相加:如果变量在线路中分支走向不同的部分,那么梯度在回传的时候,就应该进行累加。

      3. 矩阵计算梯度的时候要先分析维度

    • 回传流中的模式:(基于逻辑门直观解释梯度反向传播)

      1. 加法门单元:把输出的梯度相等地分发给它所有的输入,因为局部梯度为+1

      2. 取最大值门单元:对梯度做路由

      3. 乘法门单元:局部梯度为相互交换之后的输入值



  • A visual proof that neural nets can compute any function

    • hiden layer 中采用的激活函数是sigmoid函数:0_1543540722372_d8f074cd-d2d8-4355-8144-10fdd2056ea5-image.png

    • 当只有一个hiden layer 神经元(另一个W设为0),且W足够大的时候,通过调整b,可以得到[0,1]区间内的一个阶跃函数。
      0_1543540861311_2b161180-bd24-4ce5-a058-d68e6ff531db-image.png

    • 类似的,当同时利用两个hiden layer 神经元时,我们可以通过调整权值,使得其近似于bump function:
      0_1543542651128_8b68cd9e-ef29-4473-baf4-415e6ac7f8c0-image.png 其中0_1543542588002_be7d1d50-ab7d-414c-a7a8-9482e7bd6b45-image.png
      0_1543541118099_74f110d4-c8f5-4457-af2e-c9977a4d0b38-image.png

    • 推而广之,当我们的hiden layer中的神经元越多,就能利用bump function的叠加组合,得到任意一个函数更好地近似。
      0_1543540558283_aaadd188-cdcf-40dd-be33-146afac840a7-image.png

    二、Case2:two input&one output
    0_1543541348510_c0a8dfbb-6535-4602-ba5d-fd5f10739f16-image.png

    • 此时NN近似的函数在三维空间中,为二元函数。
    • 与一元情况相类似的,我们可以使得NN近似一个阶跃函数,
      0_1543541463726_ea0f80d4-e966-4300-a2f9-596c824a0cac-image.png
    • 同时,也可以得到一个三维空间中的bump function:
      0_1543541531008_56c7b1b6-60e8-4d83-930c-3f8d0a05fa65-image.png
    • 当同时利用了x,y输入时,可以得到一个Tower function:
      0_1543541591791_e1441f18-0e8c-4d9f-b240-15e56ad1fd11-image.png
      0_1543541690633_ad45167a-8e7b-40bc-87fc-91ec8b7c3a92-image.png
    • 推而广之,可以得到任意一个三维空间内部的函数的良好近似效果:
      0_1543541658620_3eac0324-66cd-4aa2-8ac3-0912f6188ed1-image.png
      当加上bias项时,可以看做Tower function的上下平移。
      0_1543541975987_d175f846-8712-4da6-9b5d-77863068c882-image.png

    二、Extension beyond sigmoid neurons

    • 不只是基于sigmoid激活函数的神经元可以进行对于任意函数的近似效果,其他的激活函数也可以达到同样的效果:随着权重越来越大,此函数也不断收缩,进而也能够产生step function的特征:

    0_1543542202414_c52263fc-fde3-4ed3-a06e-7a044016fa94-image.png
    0_1543542265103_709b5cbe-6fb1-4643-9de2-1de10360575a-image.png

    0_1543542289219_f1b8b5bc-a7fc-4b77-b18a-46e11d61fbe1-image.png

    三、Fixing up the step functions

    • 虽然我们的神经元近似的阶跃函数会有一定的误差,在每一次的近似过程中产生“a narrow window of failure”。但是我们可以通过大量的近似函数的平均来减小误差。
      0_1543546685270_13100ecc-c994-4896-825b-b9e2ffe969f5-image.png

 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待