【xiongwy】人工智能学习笔记汇总


#1

以后所有有关人工智能学习相关的心得都会记录在此。。。。加油!!!


#2

#TF理论学习总结【week1】 ##1、函数集 指很多映射方法的集合,机器学习就是通过对特定数据集的训练学习最合适该数据的映射方法。 ##2、学习方式 ###监督学习 训练数据都需要label,通过对训练数据学习过后可以将学到的东西和label进行比较来判别学习效果,通过效果的好坏优化参数,相当于有老师批改作业。算法有k-近邻算法、分类、回归等问题,应用有分类问题、图像识别等等。 ###非监督学习 训练数据没有label,一般需要机器自己对数据进行分类。算法有聚类。应用有基因选择、疾病诊断等。 ###半监督学习 训练数据有一部分有label,另一部分没有label,将以上两者学习方法结合。在实际问题中,label需要花费很大精力,所以希望通过标记一部分数据进行训练。 ###迁移学习 将在某一领域学到的经验运用到另一个领域 ###强化学习 强化学习通过评分方式判别学习性能,通过别人的评判来衡量自己的学习效果,不知道学习的具体的结果,只知道好与不好。 ##3、机器学习三个步骤

  • 1、定义一个函数集即模型
  • 2、让机器衡量某个函数是好还是不好,通过损失函数判别。
  • 3、通过数据集的训练可以让机器从函数集中选出最优的一个函数 ##4、深度学习,目前有哪些应用领域? 深度学习应用领域有图像识别、语音识别、自然语言处理(机器翻译、问答系统等) ##5、数据预处理,需要注意哪些? ###数据预处理有四个任务,数据清洗、数据集成、数据变换和数据规约。
  • 数据清洗:缺失值处理、异常值处理
  • 数据集成:实体识别、冗余属性识别
  • 数据变换:简单函数变换、规范化、连续属性离散化、属性构造、小波变换
  • 数据规约:属性规约、数值规约 ##6、tensorflow运行原理,架构有哪些核心点? ###Tensorflow的结构组成是边、节点、图、会话。
  • 边(tensor),就是数据,数据是有类型的多维数组。
  • 节点(operation),就是数据之间的计算。一个节点可以对应多条边,也就是可以有多个输入输出。
  • 图(graph),边和节点结合起来就是图,这里的图是有向图,描述了整个计算过程。
  • 会话(session),tensorflow的程序只有在会话中启动才可以执行。启动会话时,会分配任务到cpu或者gpu等的设备上执行。 ###Tensorflow的过程 构建图(构建阶段)->在会话中启动图(执行阶段) ##5、机器学习图解

#3

以前没怎么写过笔记,写的比较简单、其中有一部分是用的前面同学的总结的比较好的内容,后面会慢慢学着自己多做总结,希望在学到知识的同时也能提高自己的文字能力


#4

写笔记可以提高表达能力,加深影响,只是看,可能思路不是特别清晰。加油💪


#5

#BP算法原理分析 考虑以下两个单连接神经元

此处用E表示代价函数,物理意义为均方误差值,t表示训练样本所对应的目标值,a为最终的输出,E中t为已知值,故其为a的函数,又有前可知a为n2的函数,n2为a1的函数,a1为n1的函数,如果将w2看作常数,则a为n1、n2的函数,所以E同时也可以表示为n1、n2的函数,同理也可以表示为w1、w2的函数。机器学习的目的就是通过调整参数W使E最小,为使后面求导方便,同样可以将E表示成如下:

已知E为w1、w2的函数,为使E取值最小,就可以通过最速梯度下降法对w1、w2更新,更新过程如下:

其中α为梯度更新步长,可由人为设定

已知

根据求导链式法则可得

其中

为敏感系数,后面会通过公式计算该系数

将以上公式合并可得出如下公式:

代入更新迭代公式可得:

该更新公式中等式右边只有敏感系数s1、s2未知,现在计算s1、s2的表达式

已知s1、s2的定义式,可通过求导链式法则求出s1与s2之间的关系式:

其中

所以s1与s2之间的关系为

现在s1可以通过s2表示,也就是说到这一步只有s2是未知数,下面计算s2的表达式:由前可知均方误差E的近似表达式为:

将两者合并可得:

注:此表达式中等式的右边含有(t-a)为训练模型的偏差

至此s1、s2的计算表达式均已知

现在重新理一下整个更新过程:

#总结:BP更新过程可分为三步:

###第一步:数据前向传播

###第二步:误差后向传播

###第三步:权重更新


#6

#sigmoid函数、tanh函数和ReLU函数的区别?以及各自的优缺点?对应的tf函数是? ##sigmoid函数
sigmoid表达式为:


函数曲线图如下:

函数导数曲线图如下:

###优点:

  • 输出为0到1之间的连续实值,此输出范围和概率范围一致,因此可以用概率的方式解释输出。-
  • 将线性函数转变为非线性函数 ###缺点:
  • 容易出现gradient vanishing
  • 函数输出并不是zero-centered
  • 幂运算相对来讲比较耗时

###对应的tf函数:tf.nn.sigmoid() ##tanh函数
tanh函数表达式:


其中sinh表达式为

cosh表达式为

函数曲线图为:

sigmoid和tanh函数之间的关系式:

##sigmoid函数和tanh函数导数区别

考虑相同的输入区间[0,1]

sigmoid函数导数输出范围为[0.20,0.25]

tanh函数导数曲线图为


其输出范围为[0.42,1] ###优点:

  • 对比sigmoid和tanh两者导数输出可知,tanh函数的导数比sigmoid函数导数值更大,即梯度变化更快,也就是在训练过程中收敛速度更快。
  • 输出范围为-1到1之间,这样可以使得输出均值为0,这个性质可以提高BP训练的效率,具体原因参考文献 http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf
  • 将线性函数转变为非线性函数 ###缺点:
  • gradient vanishing
  • 幂运算相对来讲比较耗时

###对应的tf函数:tf.nn.tanh() ##ReLU函数
ReLU函数表达式为:

其函数曲线图为:

由函数图像可知其导数为分段函数
x <= 0时,导数为0
x > 0时,导数为1 ###缺点:

  • 不是zero-centered
  • 某些神经元可能永远不会被激活 ###优点:
  • 解决了gradient vanishing问题 (在正区间)
  • 计算速度非常快,只需要判断输入是否大于0
  • 收敛速度远快于sigmoid和tanh
    ###对应的tf函数为:tf.nn.relu()

#7

临近期末,各种专业课和数学课考试接踵而来,现在基本上是有空就往图书馆跑的状态,就怕挂了明年重修。等结束后我会全部补上的,这是对自己的负责!


#8

加油💪,非常棒,争取学完有更大的收获。


#9

嗯嗯!有这么好的学习机会怎能不好好把握~


#10

1卷积神经网络及最大池化原理

1.1卷积神经网络整体训练如下图所示:

其中包括:卷积、最大池化、压平、全连接网络四个部分。其中卷积和最大池化可以重复多次。

卷积原理和实现方式:

考虑如下一张6x6图片:

假设现在需要从该图片中找出两个特征(比如嘴巴和耳朵),此两个特征分别对应如下两个滤波器(也可以理解为特征匹配参数矩阵)

先在整幅图片中寻找第一个特征,寻找过程如下:将匹配矩阵依次从左往右重上往下查找,并计算每次查找的数值,图形匹配过程如下:

分析匹配完后所有的计算结果,不难理解,计算结果值越大,则当前匹配区域与滤波器特征越相似,注意到第一个滤波器特征点位于滤波器矩阵对角线上

匹配计算结果当中有两个相同的最大值"3",则说明该特征在该图片中出现了两次,出现在如下图所示的地方:

在这里思考一下经过卷积运算后的图片大小由原来的6x6变为4x4,而滤波器的大小为3x3,因此可将上述过程总结为如下公式:

image

n表示图片边长像素点

现在同理对第二个特征进行同样的匹配操作,最后结果如下:

第二个特征匹配计算结果中,最大值只有一个“3”,为最后一个匹配区域,则说明该特征在该图片中出现了一次,出现在最后一个匹配区域中。

以上就是卷积网络中卷积计算部分的全部过程。图示如下:

现在比较一下卷积网络和全连接网络的不同点:

以上为全连接网络,已知图片大小为6x6,共36个像素点,全连接网络先将该图片压平为36x1的向量再送至网络训练,第一层网络中的每个节点值均需36个参数,则由输入到第一层网络节点共需36x36个参数。

下面考虑卷积网络连接过程

注意到第一层网络中一个节点只需9个参数,并且不同的节点在计算过程中共用滤波器参数,此两者结合,则实际所需参数比全连接所需参数少很多。

2最大池化原理和实现方式:

2.1如下图是前面两种特征卷积计算结果:

最大池化过程如下:

最大池化就是选取每个红色矩形框中值最大的一个作为后续样本,最大池化将4x4样本缩小为2x2样本,样本量减少为原来的四分之一。也称之为降采样。同理第二个特征计算结果最大池化后如下图所示:

以上原始图片经过第一个卷积和池化过程后如下图所示

最终输出两张2x2大小的图片,每张图片表示一个待处理的特征类型。如果将该类型记为一个通道,则通道数就是特征滤波器的个数。

以上过程在整个卷积网络中只是一个环节,此环节可以被重复很多次,每一次的重复都会在上一次结果基础上达到相同的效果,即卷积池化的三个特性。

其中卷积特点: 稀疏连接和参数共享

最大池化特点:降采样

如图所示:

原始图片经过多次卷积池化后所得图片最终需要压平送入全连接网络中进行识别。如下图所示:

具体操作过程如下图所示:

以上就是这个卷积网络(CNN)运行过程。


#11

TF 干货 顶!


#12

LetNet-5模型图解如下图所示:

该模型包括输入共有8层:

1.输入层

输入层图片大小为32X32的图片

2.C1层

图片经过输入层后第一个操作就是经过C1层处理,C1层中共有6个特征进行特征匹配,每个卷积核大小为5X5,则经过其中任意一个特征匹配后的输出图片大小可通过以下公式计算:

image

输出的图片大小为:32-5+1=28,因为共有6个卷积核所以经过该层后输出6个28X28大小图片。

S2层

将前一层中输出的每一张图片进行降采样,降采样方式有很多种,列举其中一种最大池化采样,根据前面笔记可知,最大池化采样就是选择某个区域中最大的值代表该区域给到下一层处理,该层中池化大小为2X2,每张图片经过最大池化后大小减半变为14X14大小,这一层的输入层共有6张28X28的图片,因此该层的输出层为6张14X14的图片。

C3层

这一层所选择的卷积核大小为5X5,其中输入为6张14X14的图片,输出为16张10X10的图片,其中图片的变换大小由14变为10好理解,关键是由6张图片变为16张图片具体怎么操作呢?

参考一篇比较通俗易懂的博文:https://www.jianshu.com/p/ce609f9b5910 解释,C3中的每个特征map是连接到S2中的所有6个或者几个特征map的,表示本层的特征map是上一层提取到的特征map的不同组合

存在的一种操作为:C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。这样就可以得到我们所需要的16个10X10的图片。

S4层

和S2一样为降采样,池化大小为2X2,因此输出为16张5X5的图片大小

C5层

该层为卷积层,其中卷积核大小为5X5,这里注意:“每张输入图片的大小也是5X5,所以这一层也可以理解为对每张图片的全连接,"这样理解是错误的,因为如果是这样的话,那么每张图片都会产生120神经元,共有16张他图片,计算出来应该是产生16X120个神经元,而在该层的输出只有120个神经元,所以该层的卷积方式不是每个特征图单一的对每张图片进行卷积,而是将输入的16张5X5图片全连接为一个统一的输入,在分别用120个卷积核进行卷积。

F6层

该层为全连接层。


#13

one-hot 编码

考虑多类情况。非onehot,标签是类似0 1 2 3…n这样。而onehot标签则是顾名思义,一个长度为n的数组,只有一个元素是1.0,其他元素是0.0。例如在n为4的情况下,标签2对应的onehot标签就是 0.0 0.0 1.0 0.0使用onehot的直接原因是现在多分类cnn网络的输出通常是softmax层,而它的输出是一个概率分布, 从而要求输入的标签也以概率分布的形式出现,进而算交叉熵之类

例如,考虑一下的三个特征:

[“male”, “female”]

[“from Europe”, “from US”, “from Asia”]

[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]

如果将上述特征用数字表示,效率会高很多。例如:

[“male”, “from US”, “uses Internet Explorer”] 表示为[0, 1, 3][“female”, “from Asia”, “uses Chrome”]表示为[1, 2, 1]

代码示例:

import numpy as np from sklearn.preprocessing import OneHotEncoder enc = OneHotEncoder() enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1],[1, 0, 2]]) print “enc.n_values_ is:”,enc. n_values_

print “enc.feature_indices_ is:”,enc. feature_indices_

print enc.transform([[0, 1, 1]]).toarray()

代码运行结果:

enc.n_values_ is: [2 3 4] enc.feature_indices_ is: [0 2 5 9] [[ 1. 0. 0. 1. 0. 0. 1. 0. 0.]]

enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1],[1, 0, 2]])表示共有四个样本,每个样本都是三维,而每一维都表示一类特征(每类特征中可能含有不同个数的特征),也可将上述情况用矩阵的方式描述,

image

样本为一个3*4的矩阵,每一列是一个样本,共有4列,也就是有4个样本,矩阵的每一行都属于同一类特征(比如男和女都属于性别这一类特征),共有三行,也就是有三类不同的特征属性。

由矩阵中可得,第一类特征(第一行)中只有0和1两个不同的值,说明该类特征中只有两个特征,第二类特征(第二行)中有0、1和2三个不同的值,说明该类中有三个特征,第三类特征(第三行)中0、1、2和3四个不同的值,说明该类中有四个不同的值,所以分别的特征数为2,3,4也就是enc. n_values_的值。

enc.transform([[0, 1, 1]]).toarray()表示将样本[0,1,1]以one-hot编码表示

由以上分析可知,第一维里面有两个特征0表示为[1,0],1表示为[0,1],同理第二维的1表示[0,1,0],第三维的1表示为[0,1,0,0],所以总的表示为:[1,0,0,1,0,0,1,0,0]也就是输出结果值

再回到前面的例子

有如下三个特征属性:

  • 性别:[“male”,“female”]
  • 地区:[“Europe”,“US”,“Asia”]
  • 浏览器:[“Firefox”,“Chrome”,“Safari”,“Internet Explorer”]

对于上述的问题,性别的属性是二维的,同理,地区是三维的,浏览器则是三维的,这样,我们可以采用One-Hot编码的方式对上述的样本“[“male”,“US”,“Internet Explorer”]”编码,“male”则对应着[1,0],同理“US”对应着[0,1,0],“Internet Explorer”对应着[0,0,0,1]。则完整的特征数字化的结果为:[1,0,0,1,0,0,0,0,1]。这样导致的一个结果就是数据会变得非常的稀疏。

参考链接 http://blog.csdn.net/chloezhao/article/details/53484471


#14
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)   #one_hot=True: 输入的标签也以概率分布的形式出现

#占位符:不必指定初始值,类似于只定义一个变量并不赋值
xs = tf.placeholder("float32",shape=[None,784])  # 图片大小为28x28
ys = tf.placeholder("float32",shape=[None,10])
#将输入改为4维张量,第一维表示样本个数,第二三维表示图片尺寸,第四维表示图片颜色深度,对于RGB图片,深度为5,黑白为1
#第一维的具体解释如下:-1其实表示的是缺省值,也可以理解为最后确定值,就是先以你们合适,到时总数除以你们几个的乘积,我该是几就是几
#该例中-1的值为784/(28*28*1)=1;也就是一个样本,正好每次对应一张图片。
x_n = tf.reshape(xs,[-1,28,28,1])          #图片大小为28*28

#定义卷积层函数
def add_conv_layer(inputs,weight_name,biase_name,filter_x_size,filter_y_size,DL_deep,filter_deep):
    conv_weights = tf.get_variable(weight_name,[filter_x_size,filter_y_size, DL_deep, 
    filter_deep],initializer=tf.truncated_normal_initializer(stddev=0.1))#用均值为0,方差为0.1值初始化变量,从截断的正态分布中输出随机值
    conv_biases = tf.get_variable(biase_name,[filter_deep],initializer=tf.constant_initializer(0.0))        #用0初始化偏置值,一个卷积核对应一个偏置量
    conv = tf.nn.conv2d(inputs, conv_weights, strides=[1, 1, 1, 1], padding='SAME')   # 移动步长为1,input只能为浮点型 ,要求类型为float32和float64其中之一,返回一张卷积后的特征映射图, #padding='SAME'表示卷积核可以停留在图像边缘
    relu = tf.nn.relu(tf.nn.bias_add(conv, conv_biases))  # 激活函数去线性化  tf.nn.bias_add 按列向量的维数各自相加,相当于一个卷积核加一个偏置值
    return relu

relu1 = add_conv_layer(x_n,"conv1_weights","conv1_biases",5,5,1,32)    # 卷积核大小为5*5,当前深度为1,过滤器深度为32 返回的是32个特征匹配图   卷积后图片大小为24*24 共有32张
pool1 = tf.nn.max_pool(relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')                                                                #图片大小为12*12     共有32张
relu2 = add_conv_layer(pool1,"conv2_weights","conv2_biases",5,5,32,64)               #因为前一层卷积网络返回的是32层卷积图,所以此次输入的是32张样本图片,而卷积核变为64了   卷积后图片大小为8*8 图片数量为2048=32*64
pool2 = tf.nn.max_pool(relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')          #池化后图片大小为4*4 图片数量为2048=32*64

#第五层
fc1_weights = tf.get_variable("fc1_weights",[7*7*64,1024],initializer=tf.truncated_normal_initializer(stddev=0.1))    #全连接网络的权重为一个矩阵表示,行数表示输入个数,列表是输出个数,
fc1_baises = tf.get_variable("fc1_baises",[1024],initializer=tf.constant_initializer(0.1))
pool2_vector = tf.reshape(pool2,[-1,7*7*64])                                             #将最后一次池化后的图片reshape为样本数为10.44,样本大小为7*7*1024  ,注意这里并不是一个一个样本处理,而是一次性同步处理
fc1 = tf.nn.relu(tf.matmul(pool2_vector,fc1_weights)+fc1_baises)                         #输出1024个节点

#为了减少过拟合,加入Dropout层,按伯努利分布随机丢弃一些神经元节点,使得训练后的网络不会过于依赖于某一个节点,可以增加整体网络的泛化能力
keep_prob = tf.placeholder(tf.float32)
fc1_dropout = tf.nn.dropout(fc1,keep_prob)           #只对第五层使用Dopout
#第六层
fc2_weights = tf.get_variable("fc2_weights",[1024,10],initializer=tf.truncated_normal_initializer(stddev=0.1))        
#神经元节点数1024,分类节点10
fc2_baises = tf.get_variable("fc2_biases",[10],initializer=tf.constant_initializer(0.1))
fc2 = tf.matmul(fc1_dropout,fc2_weights) + fc2_baises
#第七层:输出层
y_conv = tf.nn.softmax(fc2)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(y_conv),reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1),tf.argmax(ys,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
#开始训练
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
for i in range(1000):
    batch = mnist.train.next_batch(100)
    if i%100 ==0:
          train_accuracy = accuracy.eval(feed_dict = {xs:batch[0],ys:batch[1],keep_prob:1.0})  
          print("step %d,training accuracy %g" %(i,train_accuracy))
    train_step.run(feed_dict={xs: batch[0],ys: batch[1],keep_prob:0.5})
print("test accuracy %g" % accuracy.eval(feed_dict=  {xs:mnist.test.images,ys:mnist.test.labels,keep_prob:1.0}))

#15

受教了,期待续载 :grin: