2018-10-16 10:46:55 weixin_42711936 阅读数 101

本系列专门用来记录我的深度学习历程,其中代码大部分均出自于李金洪老师的《深度学习之TensorFlow》,希望所有机器学习的道友都能有所知、有所得。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

plotdata = {"batchsize": [], "loss": []}
def moving_average(a, w=10):
    if len(a) < w:
        return a[:]
    return [val if idx < w else sum(a[(idx - w):idx]) / w for idx, val in enumerate(a)]

1.准备数据

train_X = np.linspace(-1, 1, 100)
train_Y = 2 * train_X + np.random.randn(*train_X.shape) * 0.3  # 加入噪声

显示模拟数据点

plt.plot(train_X, train_Y, 'ro', label='Original data')
plt.legend()  # 显示图例
plt.show()  # 显示图

2.创建模型

正向搭建模型

X = tf.placeholder("float")#占位符
Y = tf.placeholder("float")

模型参数

W = tf.Variable(tf.random_normal([1]), name="weight")  # W被初始化成[-1,1]的随机数,形状为一维
b = tf.Variable(tf.zeros([1]), name="bias")  # b被初始化为0,形状也为一维

前向结构

z = tf.multiply(X, W) + b

反向搭建模型

cost = tf.reduce_mean(tf.square(Y - z))
learning_rate = 0.01
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)  #梯度下降

3.迭代训练模型 初始化所有变量

init = tf.global_variables_initializer()

定义参数

training_epochs = 20
display_step = 2

启动session

with tf.Session() as sess:
    sess.run(init)
    plotdata={"batchsize": [], "loss": []}
# 向模型输入数据
for epoch in range(training_epochs):
    for (x, y) in zip(train_X, train_Y):
        sess.run(optimizer, feed_dict={X: x, Y: y})

    # 显示训练中的详细信息
    if epoch % display_step == 0:
        loss = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
        print("EPOCH:", epoch + 1, "cost=", loss, "W=", sess.run(W), "b=", sess.run(b))
        if not (loss == "NA"):
            plotdata["batchsize"].append(epoch)
            plotdata["loss"].append(loss)

print("Finished!")
print("cost=", sess.run(cost, feed_dict={X: train_X, Y: train_Y}), 'W=', sess.run(W), "b=", sess.run(b))

4.训练模型可视化

plt.plot(train_X, train_Y, 'ro', label='Original data')
plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fittedline')
plt.legend()
plt.show()

plotdata["avgloss"] = moving_average(plotdata["loss"])
plt.figure(1)
plt.subplot(211)
plt.plot(plotdata["batchsize"], plotdata["avgloss"], 'b--')
plt.xlabel('Minibatch number')
plt.ylabel('Loss')
plt.title('Minibatch run vs. Training loss')

plt.show()

5.使用模型

print("x=0.2,z=",sess.run(z,feed_dict={X:0.2}))

总结

本次练习是深度学习开头的一个小引例,里面的代码我还没有完全吃透,目前继续往下学习,以后可能会对本章内容进行补充。

2017-07-09 10:53:40 applecore123456 阅读数 3127

图像识别的经典课题

计算机视觉

  • 核心目标:让计算机“看懂”图像内容
  • 问题挑战:
    • 图像包含的信息复杂,充满着简单(颜色、线条、形状等)和复杂(姿势、场景、物体分布等)的元素,难以使用单一知识体系来概括。
    • 图像对于计算机来说,只是独立的像素集合,计算机无法归纳像素之间的关联关系

图像识别课题

Markdown
Markdown

卷积神经网络原理

前深度学习时代

  • 传统机器学习方法
    • 图像预处理:调整大小、调整明暗度、图像降噪、图像增强等
    • 特征提取:手工或利用图像处理算子(如,SIFT、HoG、Sobel等)
    • 归纳识别:SVM、人工神经网络
  • 局限
    • 传统机器学习算法只能得出输入特征与输出标签之间的映射关系
    • 特征选取强烈依赖人类的先验经验和大量实践,可移植程度低
    • 大量特征无法由人类归纳总结

卷积操作(Convolution)

  • 卷积操作简单来说,就是对于图片中的每一个像素点,计算它的邻域像素和滤波器矩阵(卷积核)的对应位置元素的乘积,然后将所有乘积累加,作为该像素位置的输出值,如下图所示。
    @图中的卷积核(Convolution Kernel)是一个浮雕滤波器(Emboss Filter)
  • 卷积操作的动图:http://deeplearning.stanford.edu/wiki/index.php/Feature_extraction_using_convolution
    Markdown
  • 在图像处理中,通常会用到一些经典的卷积滤波器,如低通滤波器、高通滤波器、高斯滤波器,这些滤波器会产生不容的效果,如下图所示。上排三个依次为:原图、低通滤波器(Low Pass Filter)、高斯滤波器(Gaussian Filter),下三排依次为:锐化滤波器(Sharpeness Filter)、边缘检测(Edge Detection)、浮雕滤波器(Embossing Filter。
    Markdown
  • 在线实验,可以自定义卷积核参数测试:https://graphics.stanford.edu/courses/cs178/applets/convolution.html

池化(Pooling)

  • 池化操作
    • 一般有最大池化(max pooling)和平均池化(average pooling)两种操作
    • 通常采用2×2的窗口大小,步长为2,处理完的图像长和宽都是原图的一半
  • 池化的作用
    • 降维
    • 使特征提取具有“平移不变性”(translation invariant)——即使图像有了一定程度的位移,依然可以获得稳定的特征集合。如人脸检测,不会因为由于角度问题导致的五官位置不对应而无法判断是否是同一个人。
      @Max Pooling,可以看到是一个降采样的过程,由4维矩阵变为了2维
      Markdown

ReLU(Rectified Linear Units)

  • 上述提到的卷积操作是一种线性操作,而特征空间映射到另一个特征空间使之线性可分是需要通过非线性变换才能实现,激活函数(activation function)就是一种引入非线性的手段。
  • 在传统神经网络中,常用的激活函数是sigmoid函数,但容易导致“梯度消失”,使得收敛速度慢且不收敛。
  • ReLU的提出就是为了解决梯度消失问题。
  • ReLU计算公式:f(x)=max(0,x)
  • ReLU求导公式:Markdown
    Markdown

多层卷积

  • 深度学习的精髓是利用多层特征组合,将简单的特征组合成复杂的抽象特征。深度卷积网络也是如此,整个网络是由多个特征提取阶段组成。每一个阶段都包括三种操作:卷积、池化和非线性激活函数(ReLU)。这种组合方式能够逼近复杂的非线性模型函数,同时又能够以较简单的方式训练。
  • 如下图所示,多层卷积可以看作一个金字塔结构,随着层次的加深,特征图的尺寸越来越小,但通道个数越来越多。在比较浅的层次(离输入较近的层次),卷积会提取比较细节的特征,而在较深的层次,会将前面的细节特征进行二次提取和组合,相当于观察的视野变大,就能提取更完整、更加抽象的特征。最终由全连接层和分类器按照提取的特征进行分类。
    Markdown

Dropout

  • Dropout是一种防止过拟合的手段。过拟合是指训练结果在训练集与测试集性能表现差距非常大的情况,即在训练集上能够得到很高的精度,但由于过度拟合,使得模型泛化性能不足,在测试集上的性能变差。
  • 操作:在每次训练中,随机让一部分隐层节点失效,可以达到改变网络结构的目的,但保留每个节点的权值。在预测时,打开全部隐层节点,使用完整的网络进行计算,相当于把多个不同的网络组合在一起,达到集成学习(ensemble)的目的。
  • 作用:削弱节点的共同作用,防止过拟合
    Markdown

经典模型介绍及TensorFlow代码解析

AlexNet: 震惊世界的突破

Krizhevsky, Alex, Ilya Sutskever, and Geoffrey E. Hinton. “Imagenet classification with deep convolutional neural networks.” Advances in neural information processing systems. 2012. [PDF]

  • 背景:
    • LeNet + MNIST 成为 Deep Learning 界的 “Hello World”
    • 传统图像识别技术陷入瓶颈
  • ILSVRC 2012 图像分类第一名
    • Top-5 错误率 15.3%(第二名错误率 26.2%)
  • 关键点及意义
    • 验证了深度学习的威力,开启深度学习时代
    • 使用 ReLU 替代 sigmoid,加速计算
    • 使用 Dropout 技术,防止过拟合(overfitting)
    • 提出GPU训练&分布式并行训练,降低训练时间
      Markdown

VGGNet:更深的结构更优秀

Simonyan, Karen, and Andrew Zisserman. “Very deep convolutional networks for large-scale image recognition.” arXiv preprint arXiv:1409.1556 (2014). [PDF]

  • VGGNet 是基于 AlexNet 的改进
  • ILSVRC 2014 图像分类第二名、图像定位第一名
    • 图像分类 TOP-5 错误率 7.4%
    • 图像定位错误率 25.3%
  • 关键点及意义
    • 发现更“深”的网络,能达到更高的识别准确率
    • 全部使用3×3的卷积核,有效减少参数个数,加深网络深度,计算代价更小收敛速度更快
      @AlexNet、VGG16和VGG19网络结构对比
      Markdown

GoogLeNet & Inception: 更全面的结构更优秀

GoogLeNet

Szegedy, Christian, et al. “Going deeper with convolutions.” Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2015. [PDF]

  • ILSVRC 2014 图像分类第一名
    • 图像分类 TOP-5 错误率 6.6%
  • 关键点及意义
    • 最优局部结构(如下图),通过增加“宽度”的方式增加网络的复杂度。
    • 1×1卷积核有效降维。AlexNet 有 6000W 参数,VGGNet 是 AlexNet 的三倍,GooLgeNet 只有 500W 参数
    • 模型计算量更小,速度更快
  • GoogLeNet 的 Block 结构
    • 在每一个卷积层中,并行使用 1X1 卷积、3X3 卷积和 5X5 卷积,同时提取不同尺度的特征,然后通过 1X1 卷积对每一个分支进行降维(降低的是channel的维度)。
      @GoogLeNet 中的 Block 结构
      Markdown
      @完整的GoogLeNet模型结构
      Markdown
Inception-V2:加入Batch Normalization

Ioffe, Sergey, and Christian Szegedy. “Batch normalization: Accelerating deep network training by reducing internal covariate shift.” arXiv preprint arXiv:1502.03167 (2015). [PDF]

  • 图像分类 TOP-5 错误率 4.9%,TOP-1 错误率 20.1%
  • Batch Normalization
    • 操作:将batch中的所有数值转换为 mean=0,variance=1 的正态分布
    • 原因:
      • 由于 mini-batch 样本数太少,所以每一个 mini-batch 内的实际分布都各不相同,在梯度计算的时候会导致梯度方向不停变化(就像下山走Z字形),导致收敛速度减慢。
      • 标准化后,保证数据分布始终一致,保留数值之间的相对差距,忽略绝对差距,在识别任务上会有更好的表现。
Inception-V3:重新思考 Inception 结构

Szegedy C, Vanhoucke V, Ioffe S, et al. Rethinking the Inception Architecture for Computer Vision[C]. computer vision and pattern recognition, 2015. [PDF]

  • 图像分类 TOP-5 错误率 3.58%,TOP-1 错误率17.2%
  • 关键点及意义
    • 将卷积操作继续分解成更小的卷积核
    • 用2层 3X3 卷积替代 5X5 卷积
    • 用 1X3 和 3X1 两个卷积核替代 3X3 卷积核
    • 加深网络层次,减少模型参数,减少计算,提高准确率
      @将卷积操作分解成更小的卷积核
      Markdown
      @左:1X3 和 3X1 的卷积核替代 3X3,右:2层 3X3 的卷积核替代 5X5 的卷积
      Markdown

ResNet:飙升的深度

He, Kaiming, et al. “Deep residual learning for image recognition.” arXiv preprint arXiv:1512.03385 (2015).[PDF]

  • 深度网络的退化问题
    • VGGNet 证明了加深网络层次是提高精度的有效手段,但是由于梯度弥散问题,导致网络深度有限,即深度越深反而效果下降。
      • 残差块(Residual Block)
    • 将 H(x) 的求解过程,转化为H(x) = F(x) + x,通过短路的形式更好的传递梯度
      Markdown
  • ILSVRC 2015 图像分类第一名
    • 图像分类 TOP-5 错误率 3.57%
  • 关键点及意义
    • 残差结构解决深度网络的退化问题(degradation problem)
    • 模型深度越深,识别更准确
    • 参数更少,计算速度更快
    • 目前主流的图像识别模型
      @34层ResNet跟34层plain网络及VGG-19结构对比
      Markdown

上述模型的图形化对比


感谢《深度学习基础与TensorFlow实践》课程主讲王琛老师的讲解
Edited by @AppleCore_Q | http://blog.csdn.net/applecore123456

2019-08-12 20:32:44 weixin_43745588 阅读数 85

tensorflow自主学习入门-从零开始篇(一)

本文所有源码及资源都会附在文末,大家各取所需。
  • 本文提到的图书源码来自github https://github.com/amusi/TensorFlow-From-Zero-To-One 感谢作者amusi 的分享* 下文有百度云盘源码分享
    自己学习tensorlfow已经有一段时间,但是一直停留在入门的边缘,没有办法真正的学习到一定的知识,非常羡慕已经学有所成的人(比如这个B站的视频
    一直没有什么突破,最近有一定的突破与感悟,分享出来,希望对各位有所帮助。

目前我的学习路径是根据由李金洪所著的《深度学习之TensorFlow》感觉非常详细,也非常不错,但是内容一定需要反复琢磨。本文的例子就是书上的第三单元 “线性回归”全部实现代码的详细解答(详细的解释在代码中可看到)。当然,本文讲解的是最终的代码结果,所以各位还是有必要认真的读完第三章的内容,然后结合理解阅读本文。本实例为 “监督学习”,简而言之就是,我们清楚的知道模型(也就是y=2x)并用此引导不知道模型的 “机器” 调整(y=w*x+b)这一模型中的 (w) 与(b)来接近答案


1.第一步

import 所需要的库
分别是:tensorflow用于生成神经节点、numpy用于生成训练数据、matplotlib用于可视化的展示

import tensorflow as tf #tensorflow库
import numpy as np #numpy用于随机产生数据,当然numpy的功能很强,本实例中仅仅用于生成数据
import matplotlib.pyplot as plt

2.第二步

def moving_average(a, w=10):
    if len(a) < w:
        return a[:]
    return [val if idx < w else sum(a[(idx-w):idx])/w for idx, val in enumerate(a)]

3.第三步

使用numpy生成数据,并使用matplotlib用点图的方式展示出来

# 数据准备
# 训练数据x
train_X = np.linspace(-1, 1, 100) #numpy中 linspace的作用是将(-1,1)分为100个数
# 训练标签y,y=2x,但是加入了噪声(噪声即为加入一定的人为误差使数据不是那么精确)
train_Y = 2 * train_X  +  np.random.randn(*train_X.shape) * 0.3  
#  *train_x.shape 与  train_x.shape[0]  的结果是一致的 在这里是 100 这么做的目的是确保100个train_X有 100 个b与之对应,以此生成相关的100 个train_Y , 而可能你已经注意到了 w 直接给出了他的正确值(2)这是为了让所有的数据更加接近(y=2x)直线,降低我们的学习曲线
# 以train_X为横坐标以train_Y为纵坐标做图,显示模拟数据点。
plt.plot(train_X, train_Y, 'ro', label="Original data")
# 展示出每个数据对应的名称
plt.legend()
# 显示整个图像
plt.show()

4.第四步

从这一步开始,我们开始构建真正的模型,也就是设置y = wx + b中的可变量w与b,让他们可以根据结果调整接近真实的值。

#### 创建模型
#placeholder是占位符的意思,在tensorflow中类似于函数参数,在执行的时候再赋具体的值。
# 分别设置训练 x,y占位符。
X = tf.placeholder(dtype="float32", name="x") #dtype 用来定义它的“形状”
Y = tf.placeholder(dtype="float32", name="y")
# 模型参数
# tf.Variable(initializer,name),参数initializer是初始化参数
#tf.random_normal()函数用于从服从指定正太分布的数值中取出指定个数的值。
weight = tf.Variable(tf.random_normal([1]), name="weight")
bias = tf.Variable(tf.zeros([1]), name="bias")

5.第五步

# 前向结构
y_pre = tf.multiply(X, weight) + bias 

# 反向优化
# 损失值计算,这里使用了预测值减真值然后平方的形式来表示预测值与真值的近似程度
cost = tf.reduce_mean(tf.square(Y - y_pre))
# 学习率,用于控制参数调整的速度,这一部分书上的解释非常形象
learning_rate = 0.01
# 优化器,封装好的一个梯度下降算法
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

# 初始化变量,tf与python正常开发不同的是所有的变量在使用之前需要进行初始化变量,是由于tf因为数据的流动(w , b)的变化需要存储
init = tf.global_variables_initializer()

#### 迭代训练
# 训练参数
# 将所有数据训练的轮数
training_epochs = 20
# 每隔几个epoch展示一次数据,也就是print以此目前的情况
display_step = 2

6.第六步

# 开启Session
with tf.Session() as sess:
    # 初始化变量,init我们上面定义好的全局变量,使用sess.run()初始化
    sess.run(init)

    plotdata = {"batchsize":[], "loss":[]}
    # 训练所有的数据
    #开始循环
    for epoch in range(training_epochs):
        # zip:打包为元组的列表,train_X,train_Y就是我们上面定义好的
        for (x, y) in zip(train_X, train_Y):
            # 开始训练,optimizer就是我们上面定义好的一个tf函数,tensorflow有趣的就是他的各个数据是环环相扣的,所以我们这里只需要调用optimizer,并使用feed_dict传入我们的原始数据即可
            sess.run(optimizer, feed_dict={X:x, Y:y})

        # 显示训练中的详细信息,我们上面调整的参数是每两次展示一次
        if epoch % display_step == 0:
            loss = sess.run(cost, feed_dict={X:train_X, Y:train_Y})
            print(f"Epoch: {epoch+1}; loss: {loss}; weight: {sess.run(weight)};"
                  f" bias= {sess.run(bias)}")

            if not loss == "NA":
                plotdata["batchsize"].append(epoch)
                plotdata["loss"].append(loss)

    print("Finished!")
    print(f"loss: {cost.eval(feed_dict={X:train_X, Y:train_Y})}; weight: {weight.eval()}; bias: {bias.eval()}")


7.第七步

注意,接下来的所有均在with tf.Session() as sess:这个语句中,分段讲解的目的是让思路更加清晰,整体代码还需要下载完整的来进一步分析。

第七步的主要作用就是让我们的数据(训练数据和训练结果)通过图像的方式来展示

# 图形化显示
    plt.plot(train_X, train_Y, "ro", label="Original data")
    plt.plot(train_X, sess.run(weight) * train_X + sess.run(bias), label="Fitted line")
    plt.legend()
    plt.show()

    plotdata["avgloss"] = moving_average(plotdata["loss"])
    plt.figure(1)
    plt.subplot(211)
    plt.plot(plotdata["batchsize"], plotdata["avgloss"], "b--")
    plt.xlabel("Minibatch number")
    plt.ylabel("Loss")
    plt.title("Minibatch run vs. Training loss.")

    plt.show()

    print(f"x=0.2, y_pre={sess.run(y_pre, feed_dict={X:0.2})}")

最后,我想说tensorflow的学习需要不断的总结与沉淀,很难一蹴而就,所以可能大家看完本文以后感觉收获甚少,这就需要反复的分析,包括读这一本书,个人观点是,目前的中文tensorflow系统学习中,李金洪所著的《深度学习之TensorFlow》最为靠谱,而视频课程还是难以消化,可以留在学习渐入佳境以后再去观看。


最后,附上资源:

《深度学习之TensorFlow》+源码 :链接: https://pan.baidu.com/s/1Z_jTGhK81CUusIP9eBHOGw 提取码: 2333

本文源码:
链接: https://pan.baidu.com/s/1w8QWmfMIUjqUhW_fRFd5gw 提取码: 2333


感谢大家观看,有用可以点击喜欢支持一下,谢谢。

深度学习书籍

阅读数 709

没有更多推荐了,返回首页