【深度学习与TensorFlow 2.0】入门篇
注:因为毕业论文需要用到相关知识,借着 TF 2.0 发布的时机,重新捡起深度学习。在此,也推荐一下优达学城与 TensorFlow 合作发布的TF 2.0入门课程,下面的例子就来自该课程。
原文发布于博客园:https://www.cnblogs.com/Belter/p/10626418.html
本文中所有代码都在文末第二个链接中,转载请注明出处!
机器学习与深度学习
深度学习是机器学习的一个分支,当下也是该领域发展最快、最受关注的一个分支。上周刚刚公布的2018年图灵奖就颁发给了对深度学习的发展做出了重要贡献的三位科学家:Yoshua Bengio、Geoffrey Hinton 和 Yann LeCun。相对于传统的机器学习算法,深度学习最大的区别在于:在训练的过冲中,由神经网络自主学习数据的表示,而不需要人工做特征工程。
之前写了多篇与机器学习有关的博文,以下几篇与深度学习有关,可以帮助理解基础知识:
因为深度学习是机器学习的一个分支,与传统的机器学习方法有非常多的相似之处。概括如下:
- 解决的主要问题:分类(二分类或多分类),回归,聚类;
- 学习的基本过程:在有监督学习(分类和回归问题)中,都是输入“数据 + 标签(答案)”,获得“算法”(从数据到答案的某种映射关系);
- 训练过程都是对代价函数的优化过程;
- 都面临过拟合的挑战,因此都需要正则化方面的技术;
- 都可以使用梯度下降法来优化参数.
当然深度学习中,也有一些有别于传统机器学习的主题:
- 网络的结构:层数,每一层的神经单元数;
- 激活函数:作用于隐藏层神经元,使得数据的变化过程从线性到非线性;
- 反向传播:用于多层神经网络中误差(或梯度)从网络的输出层向输入层传播;
- 其他特殊网络结构:CNN 中的卷积、长短期记忆网络、编码器和解码器等.
多层感知机
多层感知机(multilayer percepton, MLP)也叫深度前馈网络或前馈神经网络,是典型的深度学习模型。其目的是近似某个函数$f^*$。当前馈神经网络被拓展成包含反馈连接时,它们被称为循环神经网络(recurrent neural network, RNN)。
关于多层感知机的基础知识,可以参考我之前的博客——【机器学习】神经网络实现异或(XOR),或下面的两篇博主"python27"的学习笔记:
一个简单的例子
虽然接触到深度学习的知识已经很长时间了,但是在平时遇到分类或是回归相关的问题,还是会优先选择传统的机器学习算法。有时候是因为数据量比较小,但是还有一个比较重要的原因是自己实践太少,对于深度学习这个工具,用起来还不顺手。之前学习的时候,在TensorFlow、Pytouch和Keras之间很难做出选择。现在TF 2.0借鉴Keras中的API风格,既保持了性能的优势,也更加简单易学。加上最近刚刚发布的课程,因此就决定选择TF 2.0作为自己以后练习深度学习算法的工具。
将摄氏度转换成华氏度
温度的不同单位之间的转换有明确的定义,知道其中一种单位的温度值可以通过下面的公式精确的计算出另一种单位下的温度值。
$$ f = c \times 1.8 + 32 $$
如果我们已知该公式,将该公式写成一个函数,输入为$c$,输出为$f$,那么这就是一个入门级的编程练习题。
但是假如我们现在知道几个数值对,即输入和答案,该公式并不知道。此时就可以利用机器学习的方法,求出一个近似的从$c$到$f$的映射关系。
下面是代码:
from __future__ import absolute_import, division, print_function
import tensorflow as tf import numpy as np # 输入的摄氏温度以及其对应的华氏温度,前面两个故意写错了
celsius_q = np.array([-40, -10, 0, 8, 15, 22, 38], dtype=float)
fahrenheit_a = np.array([-40, 14, 32, 46, 59, 72, 100], dtype=float) for i,c in enumerate(celsius_q):
print("{} degrees Celsius = {} degrees Fahrenheit".format(c, fahrenheit_a[i])) # 输入后连接了只有一个神经单元的隐藏层
l0 = tf.keras.layers.Dense(units=1, input_shape=[1]) # 将网络层添加到序列模型中
model = tf.keras.Sequential([l0]) # 编译神经网络模型
model.compile(loss='mean_squared_error',
optimizer=tf.keras.optimizers.Adam(0.1)) # 训练模型
history = model.fit(celsius_q, fahrenheit_a, epochs=500, verbose=False)
print("Finished training the model")
在这个例子中,包括以下要素:
- 训练数据:一共有7个样本(输入 + 答案),有两个样本的值不准确(在实际项目中,有可能是因为测量或记录导致的误差);
- 层(layers):神经网络是以层为基本组成单位的,每层有两个最基本的参数units和activation,分别表示该层神经单元的个数和激活函数(这里没有设置第二个参数就表示不对该层的神经单元进行任何变换);
- 层的类型:层的不同类型,代表了层之间不同的连接方式,这里使用的是全连接层(Dense),表示各层之间所有点都直接相连;
- 模型:组织不同“层”的方式,这里使用的序列模型(Sequential)按照层的顺序从输入到输出叠加各个层;
- 编译(compile):训练之前必须编译,在编译的时候需要指定两个非常重要的参数——loss和optimizer,loss就是代价函数,optimizer是训练模型的方法;
- 训练模型(fit):必要参数为输入数据,对于的标签(答案),迭代次数(epochs)等.
上面15行和18行通常会写在一起:
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1, input_shape=[1])
])
模型训练的过程中,损失函数的值会随着训练次数发生变化。这些变化由fit函数返回,记录在history中。画出来如下:
import matplotlib.pyplot as plt
plt.xlabel('Epoch Number')
plt.ylabel("Loss Magnitude")
plt.plot(history.history['loss'])

图1:loss随着训练次数的增加而减小
这个模型非常简单,如果不算输入层,整个模型只有1层:输入层连接了只有一个神经单元的层l0,该层处理之后的数据直接作为输出值。
因此该模型的网络结构如下:

图2:上面例子中神经网络的结构
上图中的l0只有一个神经单元,另外还有一个偏置单元(输入值x上方的蓝色点,除了输入层外,每层默认都会有一个作用于该层的偏置单元)。因此,从输入到输出可以表示为:
$$y = x*w + b$$
神经网络的结构本质上是对最终模型的一种假设,这里的假设恰好与真实模型完全相同:线性模型,两个参数。但是在完全不知道真实模型的情况下,大部分时候模型的容量可能都远超过了真实模型,表现在参数多(模型的自由度大),结构复杂,添加了非线性变换的激活函数,因此容易导致过拟合。
训练完成后,可以查看模型各层的参数(偏置单元虽然画在了输入层上方,但还是算作l0层的参数):
print("These are the layer variables: {}".format(l0.get_weights()))
下面是输出:
These are the layer variables: [array([[1.8220955]], dtype=float32), array([29.117624], dtype=float32)]
第一个值(1.822,x的参数)与真实值1.8非常接近,第二个值(29.118,偏置单元的取值)与真实值32也比较接近。由此可见,虽然训练数据中包含两个误差比较大的点,但是最终模型还是比较准确的找到了这两组数据之间的基本规律:$y = 1.82x + 29.12$
训练好模型之后,可以使用下面的方法预测新值:
print(model.predict([100.0]))
输出为"[[211.32718]]",该值与真实值212非常接近。
以上就是假设在不知道温度两种单位之间的转换公式的情况下,通过非常简单的神经网络学习到两组数据之间关系的过程。
学习到与真实的转换公式如此接近的结果,强烈依赖于最开始设定的网络结构(一种先验,对最终模型的假设)。在不知道真实模型的情况下,通常会假设一个比较复杂的网络结构。此时模型参数多,自由度大,模型的容量和搜索空间也是远超过了真实模型,此时真实模型一定被包含其中,但不一定能找到,或者找到非常接近全局最优解的局部最优解。
下面是另一种网络结构的假设:
l0 = tf.keras.layers.Dense(units=4, input_shape=[1])
l1 = tf.keras.layers.Dense(units=4)
l2 = tf.keras.layers.Dense(units=1)
model = tf.keras.Sequential([l0, l1, l2])
model.compile(loss='mean_squared_error', optimizer=tf.keras.optimizers.Adam(0.1))
model.fit(celsius_q, fahrenheit_a, epochs=500, verbose=False)
print("Finished training the model")
print(model.predict([100.0]))
print("Model predicts that 100 degrees Celsius is: {} degrees Fahrenheit".format(model.predict([100.0])))
print("These are the l0 variables: {}".format(l0.get_weights()))
print("These are the l1 variables: {}".format(l1.get_weights()))
print("These are the l2 variables: {}".format(l2.get_weights()))
输出如下:
Finished training the model
[[211.74747]]
Model predicts that 100 degrees Celsius is: [[211.74747]] degrees Fahrenheit
These are the l0 variables: [array([[ 0.45070484, -0.611826 , 0.1898421 , 0.0913914 ]],
dtype=float32), array([ 3.4355907, -3.5666099, -2.7151687, 3.45835 ], dtype=float32)]
These are the l1 variables: [array([[ 0.22470416, 1.2858697 , 0.81416523, 0.359274 ],
[ 0.38035178, -0.86285967, 0.34824482, -0.30044237],
[-0.16603428, -0.5080208 , -0.27835467, -0.6047108 ],
[-0.5545173 , 0.9019376 , 0.19518667, -0.2925983 ]],
dtype=float32), array([-3.1969943, 3.4892511, 1.7240645, 3.4472196], dtype=float32)]
These are the l2 variables: [array([[-0.30633917],
[ 1.4714689 ],
[ 0.31956905],
[ 0.41886073]], dtype=float32), array([3.3831294], dtype=float32)]
可以看到新模型预测100摄氏度的结果也非常接近其真实的华氏温度。此时模型的结构如下:

图3:第二个模型的网络结构
不算输入层,这个模型一共有3层。其中两个隐藏层各自含有4个神经单元(蓝色点表示每层的偏置单元)。除了输入层外,其他每个神经单元的取值都由直接与之相连的点(及对应的参数)决定:例如l1层从上往下数第2个橙色点的取值由上一层4个点(及对应的参数)的取值和偏置单元的取值决定。可以概括的表示如下:
$$y' = x·w + b$$
其中$x$表示上一层的所有神经单元构成的向量,$w$是连接$y'$与上一层所有单元的参数,$b$是偏置单元。因为这里还是没有设置激活函数,因此每一层中的各个单元都是上一层所有单元取值的线性组合。
虽然第二个模型也能很好的完成预测任务,但是与真实的转换公式之间差异巨大,而且可解释性也变差了。
Reference
https://cn.udacity.com/course/intro-to-tensorflow-for-deep-learning--ud187
https://github.com/OnlyBelter/examples/blob/master/courses/udacity_intro_to_tensorflow_for_deep_learning/l02c01_celsius_to_fahrenheit.ipynb
【深度学习与TensorFlow 2.0】入门篇的更多相关文章
- 【深度学习与TensorFlow 2.0】卷积神经网络(CNN)
注:在很长一段时间,MNIST数据集都是机器学习界很多分类算法的benchmark.初学深度学习,在这个数据集上训练一个有效的卷积神经网络就相当于学习编程的时候打印出一行“Hello World!”. ...
- 深度学习(TensorFlow)环境搭建:(三)Ubuntu16.04+CUDA8.0+cuDNN7+Anaconda4.4+Python3.6+TensorFlow1.3
紧接着上一篇的文章<深度学习(TensorFlow)环境搭建:(二)Ubuntu16.04+1080Ti显卡驱动>,这篇文章,主要讲解如何安装CUDA+CUDNN,不过前提是我们是已经把N ...
- (zhuan) 126 篇殿堂级深度学习论文分类整理 从入门到应用
126 篇殿堂级深度学习论文分类整理 从入门到应用 | 干货 雷锋网 作者: 三川 2017-03-02 18:40:00 查看源网址 阅读数:66 如果你有非常大的决心从事深度学习,又不想在这一行打 ...
- 【原创 深度学习与TensorFlow 动手实践系列 - 4】第四课:卷积神经网络 - 高级篇
[原创 深度学习与TensorFlow 动手实践系列 - 4]第四课:卷积神经网络 - 高级篇 提纲: 1. AlexNet:现代神经网络起源 2. VGG:AlexNet增强版 3. GoogleN ...
- 【原创 深度学习与TensorFlow 动手实践系列 - 3】第三课:卷积神经网络 - 基础篇
[原创 深度学习与TensorFlow 动手实践系列 - 3]第三课:卷积神经网络 - 基础篇 提纲: 1. 链式反向梯度传到 2. 卷积神经网络 - 卷积层 3. 卷积神经网络 - 功能层 4. 实 ...
- 分享《机器学习实战基于Scikit-Learn和TensorFlow》中英文PDF源代码+《深度学习之TensorFlow入门原理与进阶实战》PDF+源代码
下载:https://pan.baidu.com/s/1qKaDd9PSUUGbBQNB3tkDzw <机器学习实战:基于Scikit-Learn和TensorFlow>高清中文版PDF+ ...
- 深度学习(TensorFlow)环境搭建:(二)Ubuntu16.04+1080Ti显卡驱动
前几天把刚拿到了2台GPU机器组装好了,也写了篇硬件配置清单的文章——<深度学习(TensorFlow)环境搭建:(一)硬件选购和主机组装>.这两台也在安装Ubuntu 16.04和108 ...
- JS做深度学习1——偶然发现与入门
JS做深度学习1--偶然发现与入门 不久前,我初次涉猎了Node.js,并且使用它开发了毕业设计的WEB模块,然后通过在Node中调用系统命令执行Python文件方式实现了深度学习功能模块的对接,Py ...
- jQuery学习笔记 - 基础知识扫盲入门篇
jQuery学习笔记 - 基础知识扫盲入门篇 2013-06-16 18:42 by 全新时代, 11 阅读, 0 评论, 收藏, 编辑 1.为什么要使用jQuery? 提供了强大的功能函数解决浏览器 ...
随机推荐
- java反射获取Object的属性和值
在看反射顺便做个笔记,目前知道的反射的Object都是要有对象的也就是实体Bean. import java.lang.reflect.Field; import java.util.ArrayLis ...
- Mac更改PHP默认目录
在Mac上搭建了PHP服务器以后,默认的路径为/Library/WebServer/Documents下面,但这让人很不爽,我想修改到自己定义的路径下.经过好一番折腾,终于成功了. PHPEclips ...
- shell脚本编写遍历某一目录下的所有文件
遍历/root/321321/目录显示里面的所有文件 #!/bin/bash dir=`ls /root//` #定义遍历的目录 for i in $dir do echo $i done
- docker + spring boot 打包 部署。
docker 安装 什么的 就不一一介绍了 不会安装百度一找一堆. 我这直接上代码. 首先你要有个spring boot项目. 然后打包.打包很简单 我打包的是 jar文件.直接在pom.xml文件里 ...
- 安装php rabbitmq扩展,继上一篇安装Rabbitmq
1 安装 rabbitmq-c,C 与 RabbitMQ 通信需要依赖这个库,这里只贴出正确的步骤,错误类型太多,不一一举例,大部分都是安装问题,缺少组件,安装目录问题 git clone git:/ ...
- POI对Excel的操作
1. 先导包 commons-io-2.6.jar包,用于对文件的操作. 下载地址:http://commons.apache.org/proper/commons-io/download_io.cg ...
- CSS3——animation的基础(轮播图)
作为前端刚入门的小菜鸟,只想记录一下每天的小收获 对于animation动画 1.实现动画效果的组成: (1)通过类似Flash的关键帧来声明一个动画 (2)在animation属性中调用关键帧声明的 ...
- Solr Cloud
bin/solr start -cloud -s example/cloud/node1/solr -p 8983 -z node13:2181,node14:2181,node15:2181/usr ...
- 《python语言程序设计》_第4章_选择
第四章 # 4.1 引言 布尔表达式:选择语句选择的条件. 程序: import math #加载math模块radius=eval(input("Enter an integer:&quo ...
- 如何高效地写CSS--等以后有空多加总结一下
CSS写的并不多,如果从零开始的项目,自己一定想搬砖来得容易点.CSS编写一定有其工程化的方法,来时编写更加有效率. 考虑将CSS的预处理LESS.Sass或Stylus引入,或者将CSS的后处理Po ...