1 深度学习与机器学习的区别
1.1机器学习的定义
用人工 提取的特征来表达数据,对领域的特定知识手动提取;再通过模型算法优化特征的权重进行模型学习。
1.2深度学习的定义
用机器提取的特征来表达数据,自动提取内在特征,模型算法,优化特征的权重进行模型学习。
1.3区别:
深度学习对比机器学习能够实现端到端的模型,中间减少人为的参与。
2 深度学习爆发的原因
- 大数据:大数据,云端的方式让数据的收集非常快!
- GPU的快速发展:大大缩减了训练时间,cpu的核心比较少,但是每个核心都很快,擅长处理序列任务;GPU,更多核心,每个核心都是比较慢,擅长处理并行的任务。
应用举例:人脸识别;机器翻译,下围棋,目标检测,自动驾驶;
学习分类
监督学习
对已经标记的训练样本进行学习,然后对样本外的数据进行标记预测。
- 分类垃圾邮件
首先需要对每一封邮件去人为制定,然后通过学习对新来的邮件判断其是否市垃圾邮件。
非监督学习
对没有标记的训练样本进行学习,发现其中的结构性知识
- 市场划分(聚类算法)
强化学习
一个机器人不断依据环境做决策,然后环境根据决策进行奖励或者惩罚,机器人就根据环境给予反馈来学习。
梯度下降
学习率:梯度下降的步长,往梯度下降的方向走,找到损失函数最大。
w = tf.Variable(initial_value = tf.random_normal(shape=(),seed=2017),dtype = tf.float32,name = "wight")
b = tf.Varibale(initial_value = 0,dtype = t.float32,name="biase")
with tf.variable_scope("Linear_Model"):
y_pred = w*x + b
loss = tf.reduce_meat(tf.squary(y-y_pred))
w_grad,b_grad = tf.gradients(loss,[w,b])
lr = 1e - 2 //学习率
w_update = w.assign_sub(lr*w_grad)
b_update = b.assign_sub(lr*b_grad)
sess.run(tf.global_variables_initializer())
for e in range(10):
sess.run([w_update,b_update])
w,b;同时跟新:
Logistic 回归
回归与分类
回归问题得到结果是连续的:比如学习时间预测成绩,房屋信息预测房价
分类问题是将数据分成几类,比如根据邮件信息将邮件分成垃圾邮件和有效邮件两类等。
Logistic 回归模型
loss函数
#定义 sigmoid 函数
sigmoid = tf.divide(1.0,tf.add(1.0 + tf.exp(-b_float)))
#或者直接调用
sigmoid(x,name = None)
#定义Logistic 回归模型
w = tf.get_variable(initializer = tf.ranom_normal_initial(seed = 2017),shape=(2,1),name='bias')
def logistic_regression(x):
return tf.sigmoid(tf.matmul(x,w)+b)
def binary_loss(y_pred,y):
logit = f.reduce_mean(y*tf.log(y_pred)+(1-y)*tf.log(1-y_pred))
return -logit
#定义logistic 回归模型
def logistic_regression(x):
return tf.sigmoid(tf.matmul(x,w)+b)
#梯度计算以及参数更新
y_pred = logistic_regression(loss,[w,b])
lr = 0.1
w_update = w.assign_sub(lr*w_grad)
b_update = b.assign_sub(lr*b_grad)
#跟新一次参数
sess.run(w_update,b_update)
#梯度计算以及参数更新可以直接用python中的优化函数代替
#首先从tf.train中定义一个优化方法
optimizer = tf.train.GradientDescentOptimizer(learing_rate = 1,name='optimizer')
# 利用这个优化方法去优化一个损失函数,得到这个‘op'就是我们想要的
train_op = optimizer.minimiaze(loss)
sess.run(tf.global_variables_initializer())
for e in range(1000):
seee.run(train_op)
标准神经网络
神经网络的定义
人工神经网络(Artificial Neural Networks,简称ANNs),是一种模仿生物神经网络行为特征的算法数学模型,由神经元、节点与节点之间的连接(突触)所构成:
每个神经网络单元抽象出来的数学模型如下,也叫感知器,它接收多个输入(x1,x2,x3…),产生一个输出,这就好比是神经末梢感受各种外部环境的变化(外部刺激),然后产生电信号,以便于转导到神经细胞(又叫神经元)。
单个的感知器就构成了一个简单的模型,但在现实世界中,实际的决策模型则要复杂得多,往往是由多个感知器组成的多层网络,如下图所示,这也是经典的神经网络模型,由输入层、隐含层、输出层构成。
人工神经网络可以映射任意复杂的非线性关系,具有很强的鲁棒性、记忆能力、自学习等能力,在分类、预测、模式识别等方面有着广泛的应用。
激活函数
ReLU 激活函数最常用!
如果不加激活函数,多层网络和单层网络并没有区别。
- 一般一个一层的神经网络公式:y = max(0,wx+b)
- 一个两层的神经网络就是 y = w2max(0,w1*x + b1) + b2
非常简单但却很有效,使用这个激活函数能够加快梯度下降法的收敛速度,同时对比与其他的激活函数,这个激活函数计算更加简单。
Relu 函数在随机梯度下降散发中收敛速度最快,不会像sigmoid 那样出现梯度消失问题,而且还提供了网络稀疏表达能力。
def two_network(nn_input):
with tf.variable_scope('two_network'):
net = tf.matmul(nn_input,w1)
net = tf.tanh(net)
net = tf.matmul(net,w2) + b2
return tf.sigmoid(net)
net = two_network(x)
#构造训练
loss = tf.losses.log_loss(predictions = net,labels = y)
lr = 1e-1
optimizer = tf.train.GradientDescentOptimizer(learing_rate = lr,train_op = optimizer.minimize(loss)
sess.run(tf.global_variables_initializer())
for e in range(10000):
sess.run(train_op)
if(e+1)%1000 == 0:
loss_numpy = loss.eval(session = sess)
print('Epoch {} : Loss: {}' .formate(e+1,loss_numpy))
深层神经网络
多分类问题所用函数,softmax 函数
任意取值的向量,变化成一个同等长度的概率分布向量,变换后,向量的每一项都大于零,而且所有项的和为1,
交叉熵
交叉熵衡量两个分布相似性的一种度量方式,其中Logistic 中的loss函数就是交叉熵的一种特殊情况:
模型
图片的输入是根据图片的像素而定,例如一个灰度像素的点为28*28的像素,则它就一共有784个元素,
def DNN(x,output_depths,scope = "DNN" ,reuse = None):
net = x;
for i,output_depth in enumerate(output_depth):
net = hidden_layer(net,out_depath,scope = 'layer%d' i,reuse = reuse)
#注意这里的激活函数
net = tf.nn.relue(net)
net = hidden_layer(net,scope='classification;,reuse = reuse)
return net;
dnn = DNN(input_ph,[400,200,100])
反向传播算法
是一个有效求解梯度的算法,本质上其实就是一个链式求导法则的应用。
链式法则
sigmoid函数举例
卷积神经网络
卷积神经网络本质上是多层感知器,是一个包含多个神经网络结构,它由输入层、隐含层核输出层组成。其中隐含层有一个或者多个层组成,每个隐层是由子采样层和特征提取层串联组成。每一层的平面上有多个神经元,神经元是神经网络的基本组成元件,每一个连接都有一个权重:
wi是神经元之间连接的权重值,cta 是神经元的阈值
卷积神经网络的重要性是不断地学习,即网络权重值的学习,卷积神经网络所用的许欸小方法是误差修正型,再卷积神经网络中神经元期望输出与实际输出之间存在偏差,用这个偏差来作为网络连接权值的调整参数参考标准,最终学习得到最优的权值。
其中E是网络误差测量标准,p是样本的个数。训练学习时不断地进行误差跟新,一句误差最小原则,对整个网络权重进行过不断调整。
在卷积神经网络结构中,同一个特征平面上的所有神经元共同对应一个权重值,因此这样的好处时每一个特征值被检测出来以后,跟它所在的位置没有关联,共享同一个权值方法的优点大大降低了参数的学习,对模型大小有很好的控制,所以卷积神经网络子在计算机视觉处理上表现出良好的泛化能力。
一般图像的输入向量是多维的,不需要进行转换可以直接作为输入,送入整个网络,优点是减少了数据特征的提取和数据重建的复杂。
1998年LeCun 提出一个卷积神经网络,局部响应的概念,再加上反向传播技术,再MINST手写体;
随着GPU技术,深层卷积神经网络;
图像预处理
图像在存储和传输过程中都会或多或少收到破坏和各种噪声的污染,使得其失去图像的本质或者导致图像不能满足人们的需求;
- 图像增强
目的:弱化一些对我们不重要的特征,增强对我们研究中重要的特征。方法有频域法和空域法; - 图像颜色归一化
减少不同图像样本颜色差异的技术,主要是用于图像染色和不同扫描仪所引起的图像色彩的差异。有通过校准目标或者从其他图像中找到像素的强度模式,然后再原图像上进行多项式表面处理。 - 图像分割
将图像氛围感兴趣区域和无意义的背景区域。判断图像中感兴趣的目标并且对其进行描述。分割算法:一个是基于阈值的分割方法,一个是基于边缘检测的分割方法。
如何训练图片数据
像素:10001000
RGB:红黄蓝,三个通道,因此图像可以看成三个2维矩阵。
所以向量大小:3106
处理图像方法
1.模糊化,降低像素点
模糊化图像的过程需要用到一个核,将核与原图矩阵作用的过程称为卷积。
通过再矩阵外扩充0的方法来增加卷积输出的大小,能够更多保留边缘的信息。外部补零的层数称为“padding"
k : kernel size 卷积核大小
s: stride 步长
p:padding 补零层数
输出矩阵的维度会随卷积设定的步长大小,以及p,k,决定,但是不变的是每一个卷积层中卷积核的参数量。
可学习的卷积操作
卷积核里面的数值用参数进行表示,然后通过监督学习方法去自动学习它。
在多层神经网络中的隐藏层是由权重和偏置作为参数构成的,那么我们也可以把卷积核里的数值当作参数作为神经网络中的一个隐藏层,参与到模型优化中去。
池化
- 最大值池化
- 均值池化
池化和卷积类似,通过原图上的滑动并且统计一个矩阵的信息,只不过没有参数。
我们也可以把池化看作一个固定的大小的池化核在原图上华东得到统计信息的过程。
池化核的大小
池化在原图上移动的步长称作”池化核的移动步长“
池化的作用
池化是一个对输入进行下采样的操作,这样能够快速减少输入大小,从而减少神经网络后面的参数量,便于训练模型。而且它能够大部分保持输入原有的信息,相对卷积下采样也由不需要参数的优点。
总结
一个”卷积层+池化层“作为神经网络的隐藏层反复出现的多层神经网络结构。
全连接:
由两个卷积+池化层以及三个全链接层,在最后一个池化层通过flatten 操作将小图片摊平成向量,然后链接在一起形成一个长特征向量,之所以叫全连接层是因为卷积核池化都是局部运算,而全连接层前后的数据都有权重相连。
实践
#卷积函数
tf.nn.conv2d(
input,(batch"一次输入多少张图片,可以是1或者其他数",h "输入的高读" w "输入的宽度", channels "输入的通道数,如RGB 3" )
filter,(卷积核的参数,k_h "卷积核的高度" , k_w "卷积核的宽度", in "卷积需要作用输入图片的通道数" out "卷积核通道的个数" )
strides,(卷积核的移动步长,1,s_h "高度方向的移动步长",s_w "宽度方向的移动步长" )
padding, (补零方法,SAME "会对输入自动补0,保证输出大小和输入大小相同" VALID "不会自动补零");
# 定义一个边缘检测算子‘sobel_kernel',并规范形状
sobel_kernel = np.array([[-1,-1,-1],[-1,8,-1].[-1,-1,-1]],dtype = np.float32)
sobel_kernel = tf.constant(sobel_kernel,shape=(3,3,1,1))
卷积核 = 卷积核形状(k_h,k_2,in,out)
# 进行卷积
## padding = ’SAME'的卷积
edge1 = tf.nn.conv2d(im,sobel_kernel,[1,1,1,1],'SAME',name = 'same_conv')
edge2 = tf.nn.conv2d)im,sobel_kernel,[1,1,1,1],'VALID',name = 'valid_conv')
im :输入图片
sobel_kernel: 卷积核
[1,1,1,1] : 移动步长
'VALID' : 补零方法
#tf.nn.max_pool 实现最大值池化
tf.nn.max_pool(
value (池化的输入,batch"一次输入多少张图片,可以是1或者其他数",h "输入的高读" w "输入的宽度", channels "输入的通道数,如RGB 3")
ksize,(1,k_h,k_2,1)
strides
padding
)
small_im1 = tf.nn.max_pool(im,[1,2,2,1],[1,2,2,1] 'SAME',name = 'same_max_pool')
import urllib2
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
%matplotlibinline
im_url = 'https://image.ibb.co/iFGs0x/kitty.png'im = Image.open(urllib2.urlopen(im_url)).convert('L') # 读入一张灰度图的图片im = np.array(im, dtype='float32') # 将其转换为一个矩阵
# 可视化图片
plt.imshow(im.astype('uint8'), cmap='gray')
# 将图片矩阵转化为 tensor,并适配卷积输入的要求
im = tf.constant(im.reshape((1, im.shape[0], im.shape[1], 1)), name='input')
# 定义一个边缘检测算子`sobel_kernel`, 并规范形状
sobel_kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype=np.float32)
sobel_kernel = tf.constant(sobel_kernel, shape=(3, 3, 1, 1))
# 进行卷积## padding='SAME' 的卷积
edge1 = tf.nn.conv2d(im, sobel_kernel, [1, 1, 1, 1], 'SAME', name='same_conv')
## padding='VALID' 的卷积
edge2 = tf.nn.conv2d(im, sobel_kernel, [1, 1, 1, 1], 'VALID', name='valid_conv')
sess = tf.InteractiveSession()
edge1_np = sess.run(edge1)
edge2_np = sess.run(edge2)
plt.imshow(np.squeeze(edge1_np), cmap='gray')
plt.title('shape = {}'.format(edge1_np.shape))
plt.imshow(np.squeeze(edge2_np), cmap='gray')
plt.title('shape = {}'.format(edge2_np.shape))
AlexNet
传统图像识别,通过传统的人工挑选几何特征再加上诸如SVM,随机森林这样传统的机器学习方法进行图像识别。
其内部结构:卷积、池化、和全连接