[toc]
参考文献
- 谷歌TensorFlow官方文档(鸢尾花品种预测):https://www.tensorflow.org/get_started/get_started_for_beginners
获取示例程序
- 安装TensorFlow & pandas
方法1: 使用pip 安装
$ pip install tensorflow
$ pip install pandas
方法2: virtualenv ,Pycharm 直接导入即可(个人示例)
- 执行下列步骤以获取示例程序:
-
通过输入以下命令从 GitHub 克隆 TensorFlow 模型代码库:
git clone https://github.com/tensorflow/models
-
将此分支内的目录更改为包含本文档中所用示例的位置:
cd models/samples/core/get_started/
在该 get_started 目录中,找到一个名为 premade_estimator.py 的程序,直接运行即可。
- over
项目代码讲解
步骤如下:
- 导入和解析数据集
- 创建特征以描述数据
- 选择模型类型
- 训练模型
- 评估模型的效果
- 让经过训练的模型进行预测
杂记
- 统计Excel的列数:=COLUMNS(A:ADD)
TensorFlow 视频案例
MNIST手写数字识别视频:http://www.cbdio.com/BigData/2017-01/24/content_5438545.htm
MNIST实战高级部分:https://blog.csdn.net/xierhacker/article/details/53282060
TensorBoard可视化
TensorFlow 基本函数
- TensorFlow用张量这种数据结构来表示所有的数据
学会用数据表格式
阶 | 数学实例 | Python 例子 |
---|---|---|
0 | 纯量 (只有大小) | s = 483 |
1 | 向量(大小和方向) | v = [1.1, 2.2, 3.3] |
2 | 矩阵(数据表) | m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] |
3 | 3阶张量 (数据立体) | t = [[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]] |
n | n阶 | ...... |
- 矩阵与向量的乘法
martrix2 = tf.constant([[2., 7.], [5., 9.]])
martrix3 = tf.constant([[2.0, 3.0]])
martrix4 = tf.constant([2.0, 3.0])
matrix2 的shape = (2, 2) ,rank = 2
matrix3 的shape = (1, 1), rank = 2
matrix4 的shape = (2), rank = 1
矩阵和向量的乘法,要注意,如果rank(阶数)不同则不能相乘。
matmul(matrix2, martrix3) = [[25.], [37.]] (martrix3必须转置)
matmul(matrix2, martrix4) = error! 报错
- 矩阵加法
二阶矩阵和一阶矩阵相加
只要确保列或者相同,行row为一维或者列column为一维,比如:
(N, 5) + (1, 5) 可以相加
(N, 5) + (5) 可以相加
(N, m)+ (N, 1)也可以相加
x1 = tf.constant([[2., 7.], [5., 9.]])
x2 = tf.constant([2.0, 3.0])
x3 = tf.constant([[2.0], [3.0]])
x4 = tf.constant([2.0])
x5 = tf.constant(2.0)
x6 = tf.constant([2.0, 3.0, 4.0]) #error shape = (3)
print("矩阵和向量加法: ", sess.run(x1 + x2))
矩阵和向量加法: [[ 4. 10.]
[ 7. 12.]]
x1矩阵和x2,x3,x4,x5都可以相加,和x6不能相加
二阶矩阵和二阶矩阵相加
- ==矩阵与向量的乘法,使用点积然后相加的方式实现==
import tensorflow as tf
a = tf.constant([2, 3])
b = tf.constant([[0, 1], [2, 3]])
mul =tf.reduce_sum(tf.multiply(a, b), reduction_indices=1)
with tf.Session() as sess:
print(sess.run(mul))
结果:
[ 3 13]
- np.newaxis 为 numpy.ndarray(多维数组)增加一个轴。
x = np.arange(3)
x = array([1, 2, 3])
x[:, np.newaxis]
x = array([[0],
[1],
[2]])
x.shape = (3, 1)
- np.linspace(-1, 1, 300, dtype=np.float32)
np.linspace(-1, 1, 300, dtype=np.float32) 取-1到1均匀的300个float数字
- 关于神经网络
==参考文献== 神经网络浅讲:从神经元到深度学习:https://www.cnblogs.com/subconscious/p/5058741.html
这篇文章详细的讲述了从神经元到深度学习的发展历程和原理变化过程。
- 单层神经网络&感知器(输入层和输出层,只有一个计算层)
局限性:无法解决异或问题 - 多层感知器,两个计算层
- 深度神经网络
Ng 2010 Coursera
==Ng 机器学习最新课程==:https://www.bilibili.com/video/av17624209/?p=14李飞飞计算机视觉
斯坦福终生教授、计算机视觉ImageNet发起人
==计算机视觉教程==:https://www.bilibili.com/video/av17741845/?p=1
- tf.ones & tf.reshape
将(1, 784)784维度的图转换成28*28的图片,-1代表样本数量不固定,最后一个1代表颜色通道数量。这里用了tf.ones和tf.reshape函数
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
a = tf.ones([1, 784], dtype=tf.float32)
a_image = tf.reshape(a, [-1, 28, 28, 1])
print(sess.run(a_image))
- over
MNIST手写识别
参考文档:http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_beginners.html
参考文档:谷歌云官方http://www.cbdio.com/BigData/2017-01/24/content_5438545.htm
- 无数文档介绍了此TensorFlow入门教程,这里仅仅记录个人的几个疑惑点与如何解决。
- 疑惑点:MNIST数据集的格式与矩阵乘法
MNIST数据集把分为训练集和测试集,而每个集合又分为images和labels两个数据集,images被拆分成28X28的矩阵,labels则是[10] 10维向量。
这里很难理解这些数据。我们先来理解一张图片的回归方式。
单张图片被切分成了 28X28 = 784 维度的矩阵,对应的标签值是一个[10]维度向量。因此,单张图片可以这样通过神经网络:
[图片上传失败...(image-9a3421-1531452420145)]
==这里是 w = (10, 784) ,x = (784, 1) , b = (10)==
==y = softmax(matmul(w, x) + b)==
[图片上传失败...(image-ca252d-1531452420145)]
==对于60000张图片,只需将 x = (784, 60000) 即可。==
- 疑惑点: TensorFlow MNIST案例的流程
第一步:定义矩阵 y= w*x + b
第二步: 定义激励函数
第三步:定义损失函数
第四步:cnn训练
第五步:测试集,测试
- 疑惑点:损失函数
参考损失函数: https://blog.csdn.net/marsjhao/article/details/72630147
训练模型时,需要用损失函数来判断训练集的精度。
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
y_ = tf.placeholder("float", [None,10])
[图片上传失败...(image-ef067a-1531452420145)]
y 是我们预测的概率分布, y' 是实际的分布(我们输入的one-hot vector)。这里的交叉熵是损失函数,我们需要最小化这个损失函数。
使用梯度下降函数最小化Loss
# Loss
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_label * tf.log(y), reduction_indices=[1]))
train = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
- 疑惑点:评估模型
tf.argmax(input, axis=None, name=None, dimension=None)
此函数是对矩阵按行或列计算最大值,返回最大值所在的索引
input:输入Tensor
axis:0表示按列,1表示按行
name:名称
dimension:和axis功能一样,默认axis取值优先。新加的字段
tf.argmax(y,1)返回的是模型对于任一输入x预测到的标签值,而
tf.argmax(y_,1) 代表正确的标签,
tf.equal 来检测我们的预测是否真实标签匹配(索引位置一样表示匹配)。
为了确定正确预测项的比例,我们可以把布尔值转换成浮点数,然后取平均值。例如,[True, False, True, True] 会变成 [1,0,1,1] ,取平均值后得到 0.75
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
最后,我们计算所学习到的模型在测试数据集上面的正确率。
print sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})
- 疑惑点:
全连接网络案例
参考文献:https://blog.csdn.net/shine19930820/article/details/78359249
源码位置:tf_test_bp_all.py
源码:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# TensorFlow 全连接网络实现
# 参考 文档:https://blog.csdn.net/shine19930820/article/details/78359249
# 1. 准备数据, 这里用函数模拟数据
# x_data.shape = (300, 1), np.newaxis 将数据转化成 (300, 1)
x_data = np.linspace(-1, 1, 300, dtype=np.float32)[:, np.newaxis]
# 定义噪音波动, shape和x_data一样,也是 (300, 1), astype copye the array and cast to float32
noise = np.random.normal(0, 0.05, x_data.shape).astype(np.float32)
# y_data, 定义函数 y_data = 2*x_data^3 + x_data^2 + noise, y_data = (300, 1)
y_data = 2 * np.power(x_data, 3) + np.power(x_data, 2) + noise
# 2. 定义网络结构
# 定义占位符
xs = tf.placeholder(tf.float32, [None, 1])
ys = tf.placeholder(tf.float32, [None, 1])
# 定义两个隐藏层,一个输出层
# 隐藏层1 , relu(xs * Weights1 + biases1), relu((300, 1)* (1, 5) + (1, 5))
Weights1 = tf.Variable(tf.random_normal([1, 5]))
biases1 = tf.Variable(tf.zeros([1, 5]) + 0.1)
Wx_plus_b1 = tf.matmul(xs, Weights1) + biases1
# l1.shape= (300, 5)
l1 = tf.nn.relu(Wx_plus_b1)
# 隐藏层2, relu(l1 * Weights2 + biases2), relu((300, 5) * (5, 10) + (1, 10))
Weights2 = tf.Variable(tf.random_normal([5, 10]))
biases2 = tf.Variable(tf.zeros([1, 10]) + 0.1)
Wx_plus_b2 = tf.matmul(l1, Weights2) + biases2
# l2.shape = (300, 10)
l2 = tf.nn.relu(Wx_plus_b2)
# 输出层 prediction = (300, 10) * (10, 1) + (1, 1) = (300, 1)
Weights3 = tf.Variable(tf.random_normal([10, 1]))
biases3 = tf.Variable(tf.zeros([1, 1]) + 0.1)
prediction = tf.matmul(l2, Weights3) + biases3
# loss = MAE(y,ŷ )=(1/nsamples)∑i=1n (yi−yi^)2
# 定义loss表达式
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), reduction_indices=[1])
)
# optimizer 最小化loss,梯度下降法
train_step = tf.train.AdamOptimizer(0.1).minimize(loss)
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
# 绘制原始x-y散点图
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.scatter(x_data, y_data)
plt.ion()
plt.show()
# 训练10000次
for i in range(10000):
# 训练
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
# 每500步绘图并打印输出
if i % 500 == 0:
# 可视化模型输出的结果
try:
ax.lines.remove(lines[0])
except Exception:
pass
prediction_value = sess.run(prediction, feed_dict={xs: x_data})
loss_value = sess.run(loss, feed_dict={xs: x_data, ys: y_data})
print(prediction_value)
print("\n")
print(loss_value)
# 绘制模型预测值, 预测的是y值, 在x_data共用的情况下,模型预测的是y值, 原来的scatter散点图和曲线图对比
# 散点图为训练数据, 曲线图为在同一 x_data的前提下,y_prediction 的预测值., 预测结果与原来的散点图吻合.
lines = ax.plot(x_data, prediction_value, 'r-', lw=5)
plt.pause(1)
MNIST手写识别深入
通过上述步骤获取的准确率只有 91%,于是我们使用卷积神经网络CNN来预测,提升准确率到 99.1%
- 疑惑点:比起入门级别MNIST,深入级别有哪些添加的东西?
新增了卷积函数、池化函数、归一层,其余部分和全连接网络一样。
- 疑惑点:如何构建卷积神经网络
权重初始化
卷积和池化
第一层卷积
第二层卷积
密集连接层
输出层
训练和评估模型
- 源码解读
参考文献:实现简单的CNN卷积神经网络 :https://blog.csdn.net/SMF0504/article/details/56666229
参考文献:极客学院wiki MNIST深入
1. 首先,必须熟读下文《卷积神经网络一节》
2. 源码
# coding=utf-8
import tensorflow as tf
# import data
from tensorflow.exaemples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# 卷积神经网络会有很多的权重和偏置需要创建
# 定义初始化函数以便重复使用
def weigth_variable(shape):
# 给权重制造一些随机的噪声来打破完全对称,例如这里截断的正态分布,标准差为0.1
inital = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(inital)
def bias_variable(shape):
# 由于使用Relu,也给偏置增加一些小的正值(0.1)用来避免死亡节点(dead neurous)
inital = tf.constant(0.1, tf.float32, shape)
return tf.Variable(inital)
# 卷积层和池化层也是接下来重复使用的
# 定义卷积层和池化层
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2X2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
# 在正式设计卷积神经网络之前,先定义输入placeholder,x是特征,y是真实的label
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
x_image = tf.reshape(x, [-1, 28, 28, 1])
# 定义第一个卷积层
# 先使用前面写好的函数进行参数初始化,包括weigth和bias,
# 接着使用conv2d函数进行卷积操作,并加上偏置,
# 然后在使用ReLu激活函数进行非线性处理,
# 最后,使用最大池化函数对卷积的输出结果进行池化操作
W_conv1 = weigth_variable([5, 5, 1, 32]) # patch 5x5, in size 1, out size 32
# 矩阵用大写字母开头,便于自己下面区分(这只是个人建议)
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(tf.conv2d(x_image, W_conv1) + b_conv1) # output size 28x28x32
h_pool1 = tf.max_pool_2X2(h_conv1) # output size 14x14x32
# 定义第二层卷积层
# 步骤如上一层,只是参数有所改变而已
W_conv2 = weigth_variable([5, 5, 32, 64]) # patch 5x5, in size 32, out size 64
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(tf.conv2d(h_pool1, W_conv2) + b_conv2) # output size 14x14x64
h_pool2 = tf.max_pool_2X2(h_conv2) # output size 7x7x64
# 全连接层
W_fc1 = weigth_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
# [n_samples, 7, 7, 64] ->> [n_samples, 7*7*64]
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
# 为了减轻过拟合,增加一个dropout层
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
# 将dropout层的输出连接到一个softmax层,得到最后的概率输出
W_fc2 = weigth_variable([1024, 10])
b_fc2 = bias_variable([10])
pre = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
# 最后定义损失函数为cross entropy,和之前一样,但是最后的优化器使用Adam,并给予一个比较小的学习率1e-4
cross_entropy = tf.reduce_mean(tf.reduce_sum(y*tf.log(pre), reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) # 使用的优化方法,以及追求的目标
# 定义评测准确率的操作
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(pre, 1))
accuray = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# train,开始训练
# 首先依然是初始化所有变量,设置训练是的Dropout的keep_prob比率为0.5,
# 然后使用大小为50的mini_batch,共进行20000次训练迭代,
# 参与训练的样本数量总共100万,其中每100次训练,会准确率进行一次评测时keep_prob为1,用以实时监测模型的性能
with tf.InteractiveSession() as sess:
tf.global_variables_initializer().run()
for i in range(20000):
batch = mnist.train.next_batch(50)
if i % 100 == 0:
train_accuracy = accuray.eval(feed_dict={x: batch[0], y: batch[1], keep_prob: 1.0})
print("step %d, training accuracy %g" % (i, train_accuracy))
train_step.run(feed_dict={x: batch[0], y: batch[1], keep_prob: 0.5})
# 全部训练完后,在最终的测试集上进行全面的测试,得到整体分类准确率
print("test accuracy %g" % accuray.eval(feed_dict={x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0}))
卷积神经网络
==参考文档卷积神经网络:== https://www.jianshu.com/p/fe428f0b32c1 (这篇文章很棒)
这篇文章详细讲述了卷积网络的工作流程
inputlayer --> convolution --> relu(convolution)--> pooling(relu) --> back propogation (bp) --> output
卷积神经网络CNN的结构一般有以下几层:
- 输入层:用于数据的输入
- 卷积层:使用卷积核进行特征提取和特征映射
- 激励层:由于卷积也是一种线性运算,因此需要增加非线性映射
- 池化层:进行下采样,对特征图稀疏处理,减少数据运算量。
- 全连接层:通常在CNN的尾部进行重新拟合,减少特征信息的损失
- 输出层:用于输出结果
- 卷积函数
卷积函数def conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None):
def conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None,
data_format=None, name=None):
1. input就是需要做卷积的图像(这里要求用Tensor来表示输入图像,
并且Tensor(一个4维的Tensor,要求类型为half或者float32)的shape为[batch, in_height, in_width,
in_channels]具体含义[训练时一个batch图像的数量,图像高度,图像宽度, 图像通道数])
2. filter就是卷积核(这里要求用Tensor来表示卷积核,并且Tensor(一个4维的Tensor,要求类型与input相同)的shape为[filter_height, filter_width, in_channels, out_channels]
具体含义[卷积核高度,卷积核宽度,图像通道数,卷积核个数],这里的图片通道数也就input中的图像通道数,二者相同。)
3. strides就是卷积操作时在图像每一维的步长,strides是一个长度为4的一维向量。
4. padding是一个string类型的变量,只能是 "SAME" 或者 "VALID",决定了两种不同的卷积方式.
'SAME' 图像的每一个点都作为卷积核的中心 'VALID' 为正常方式
- 卷积函数conv2d再解
参考文献:https://blog.csdn.net/SMF0504/article/details/56666229
tf.nn.conv2d是Tensorflow的2维卷积函数:
x是输入,4维;
W是卷积的参数,也就是卷积核,
eg:当W=[5, 5, 1, 32],前两个参数为卷积核的大小;第三个参数为channel的个数,也就是上一层的输出,由于这里是灰度图像,所以为1,第四个参数为卷积核的数量;
strides是卷积核的移动步长,若strides=[1, 1, 1, 1],都是1代表不遗漏地划过图片的每一点;
padding是边界地处理方式,这里SAME代表给边界加上padding让卷积的输出和输入保持同样(SAME)的尺寸;
name是卷积层的名字,是可选项。
- 卷积后图片的尺寸
参考文献:https://blog.csdn.net/wuzqChom/article/details/74785643
对于“VALID”,输出的形状计算如下:
new_height=new_width=⌈(W–F+1)/S⌉
对于“SAME”,输出的形状计算如下:
new_height=new_width=⌈W/S⌉
其中,W为输入的size,F为filter为size,S为步长,⌈⌉为向上取整符号。
a = tf.ones([1, 784], dtype=tf.float32)
a_image = tf.reshape(a, [-1, 28, 28, 1])
conv1 = weight_variable([5, 5, 1, 32]) # patch 5x5, in size 1, out size 32
# 矩阵用大写字母开头,便于自己下面区分(这只是个人建议)
b = bias_variable([32])
h = tf.nn.relu(conv2d(a_image, conv1) + b) # output size 28x28x32
h_pool = max_pool_2x2(h) # output size 14x14x32
sess.run(tf.global_variables_initializer())
print("h_pool_shape:", sess.run(tf.shape(h_pool)), "h_shape: ", sess.run(tf.shape(h)))
h_pool_shape: [ 1 14 14 32] h_shape: [ 1 28 28 32]
- 池化函数
池化函数 tf.nn.max_pool(x,ksize,strides,padding,name)
池化函数参考文档:https://blog.csdn.net/SMF0504/article/details/56666229
max_pool是tf的最大化池化函数,还有平均池化函数。最大池化会保留原始像素块中灰度值最高的那一个像素,即保留最显著的特征。
x是输入,4维;
ksize是池化的大小,
eg:当ksize=[1, 2, 2, 1],第一个和最后一个参数固定设定为1,第二个和第三个为自定义参数,这里的意思就是将一个2*2的像素块降为1*1的像素。
strides是池化的步长,
eg:当strides=[1, 2, 2, 1],第一个参数和最后一个参数固定设定为1,第二个和第三个参数自定义参数,这里的意思就是横竖两个方向以2为步长。如果步长还是1,那么会得到一个尺寸不变的图片拍;
padding与卷积函数的padding的一样。
- reshape函数、reduce_sum求和函数、argmax函数
tf.reshape(x,shape) x为输入,shape为转后的形式。
eg:tf.reshape(x, [-1,28,28,1]),意思就是将1D向量转为2D的图片格式,即从1*784转化为原始的28*28的结构。同时由于只有一个颜色通道,故最终尺寸为[-1, 28, 28, 1],前面的-1代表样本数量不固定,最后一个1代表颜色通道数量。
tf.argmax(input, dimension, name=None) 返回input最大值的索引index
tf.reduce_sum(input_tensor, reduction_indices=None, keep_dims=False, name=None) 计算输入tensor元素的和,或者安照reduction_indices指定的轴进行求和
- over
机器学习斯坦福大学公开课:第一课 机器学习的动机和应用
官网:https://open.163.com/movie/2008/1/M/C/M6SGF6VB4_M6SGHFBMC.html
我的学习路径
- 读《大话TensorFlow和人工智能》读完、精读、对函数推导
- 复习一遍高等数学、线性代数、概率论。按这个顺序复习
- 读《大话大数据》读完,精读回归、分类、聚类等模块
- python语法,廖雪峰的python学起
- 跑TensorFlow,熟悉tensorflow的各种函数和矩阵计算
- 学习pandas和numpy、matplotlib
- OK,到此为止,开始深度学习
- 跑鸢尾花预测案例,一遍一遍,把流程和函数弄清楚
- 跑MNIST案例,一遍一遍,把流程和函数弄清楚
- 全连接网络,进一步理解全连接网络的原理
- CNN,全力研习CNN,理解CNN的原理和流程
- 跑MNIST深入案例
- 跑图片分类案例
- 跑 opencv + TensorFlow 人脸识别+猫脸识别案例
- 打标签,开始自己做一个案例,如猫脸识别
- 把这个案例做到最佳
- 进军RNN
- TensorFlow高级教程之微积分方程、RNN
- 进军Caffe、Keras等框架
- 出师,整合案例:猫脸识别、大数据预测
- 云计算、部署到集群上,Docker和AWS云上跑项目
所需掌握的技能栈
- python基本语法
- Pandas
- Numpy
- 线性代数矩阵计算
- 高等数学之偏微分方程
- TensorFlow基本函数
- 全连接网络流程和原理、隐藏层等
- CNN网络流程与原理、卷积层和池化层
- sigmoid、relu等激励函数
- 损失函数、交叉熵
- 回归、聚类、分类
- RNN
- 打标签、图片分类