TensorFlow的基本概念
1、使用图(graphs)来表示计算任务
2、在被称之为会话(Session)的上下文(context)中执行图
3、使用tensor表示数据
4、通过变量(Variable)维护状态
5、使用feed和fecth可以为任意的操作赋值或者从中获取数据
6、Tensorflow是一个编程系统,使用图(graphs)来表示计算任务,图(graphs)中的节点称之为op(operation),一个op获得0个或多个Tensor,执行计算,产生0个或多个Tensor,Tensor看做是一个n维的数组或列表,图必须在会话(Session)中被启动。
1、课程的一个小demo-线性回归案例
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#使用numpy生成200个随机点
x_data = np.linspace(-0.5,0.5,200)[:,np.newaxis] #linspace()函数在-0.5到0.5这个范围区间产生200个均匀分布的点,然后存储在x_data内
#linspace()生成的数是一维的数据,[:,np.newaxis]是把数据转化为200行一列的数据
noise = np.random.normal(0,0.02,x_data.shape) #噪音 生成随机值
y_data = np.square(x_data) + noise
#定两个placeholder占位符,先仅仅指定变量的类型,运行的时候在填补具体的值,后面用feed来填充,也就是喂数据
x = tf.placeholder(tf.float32,[None,1]) #第二个参数是用来指定数据的形状shape,第一个为None表示可以是任意行,第二个参数是1列
y = tf.placeholder(tf.float32,[None,1])
#定义网络中间层
Weights_L1 = tf.Variable(tf.random_normal([1,10]))
biases_L1 = tf.Variable(tf.zeros([1,10]))
Wx_plus_b_L1 = tf.matmul(x,Weights_L1) + biases_L1
L1 = tf.nn.tanh(Wx_plus_b_L1)
#定义网络输出层
Weights_L2 = tf.Variable(tf.random_normal([10,1]))
biases_L2 = tf.Variable(tf.zeros([1,1])) #输出层是一个神经元 所以只有一个偏置
Wx_plus_b_L2 = tf.matmul(L1,Weights_L2) + biases_L2 #中间层的L1即是输出层的输入,matmul()是矩阵乘,multiply()是点乘
prediction = tf.nn.tanh(Wx_plus_b_L2)
#二次代价函数
loss = tf.reduce_mean(tf.square(y- prediction))
#二次代价函数
loss = tf.reduce_mean(tf.square(y-prediction))
#使用梯度下降算法训练
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
with tf.Session() as sess:
#变量初始化
sess.run(tf.global_variables_initializer())
for _ in range(2000):
sess.run(train_step,feed_dict = {x:x_data,y:y_data})
#获得预测值
prediction_value = sess.run(prediction,feed_dict={x:x_data})
#画图
plt.figure()
plt.scatter(x_data,y_data)
plt.plot(x_data,prediction_value,'r-',lw=5)
plt.show()
2、demo2 手写数字识别
# coding: utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data #和mnist数据集相关的数据包 用于输入数据
#载入数据集
mnist = input_data.read_data_sets("MNIST_data",one_hot=True) #第一个参数是带路径的文件名,若是没有带路径指当前目录,one_hot是把标签转化为01形式
#即某一位是1,其他位都是0,执行这条语句时会首先从当前目录找数据集,没有的话会从网上下载手写数据集。
#每个批次的大小 即每次训练会放入100张图片。会以矩阵的形式放进去
batch_size = 100
#计算一共有多少个批次
n_batch = mnist.train.num_examples // batch_size #mnist.train.num_examples总的训练图片数
#定义两个placeholder
x = tf.placeholder(tf.float32,[None,784]) #把一个平面的28*28图片转化为一维的向量传入x,维度中的None表示可以是任意值,由后面传入的数据决定
y = tf.placeholder(tf.float32,[None,10]) #输出有10个标签,所以定义为10个神经元
#创建一个简单的神经网络
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
prediction = tf.nn.softmax(tf.matmul(x,W)+b)
#二次代价函数
loss = tf.reduce_mean(tf.square(y-prediction))
#使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
#初始化变量
init = tf.global_variables_initializer()
#结果存放在一个布尔型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))#argmax返回一维张量中最大的值所在的位置
'''比较两个参数是否是一样的,返回bool值,tfargmax(y,1)求y的最大值的位置,比如某个数字在第三个位置(3的标签)的概率最大,就返回3
tf.argmax(input, dimension, name=None) 第一个参数是输入值,第二个参数是维度,0按行找,1按列找.......,要求0 <= dimension < rank(input),tf.argmax()返回最大数值的下标
通常和tf.equal()一起使用,计算模型准确度。
tf.equal()是用来判断预测和实际值是否一致。是一致为true,不是为false
'''
#求准确率 cast()函数时用来把bool类型转化为tf.float32浮点型 ,tf.reduce_mean 求平均值就是准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
with tf.Session() as sess:
sess.run(init)
for epoch in range(21): #迭代21次
for batch in range(n_batch): #每次要多少批次的放入数据
batch_xs,batch_ys = mnist.train.next_batch(batch_size) #每次获得一百张图片,图片的数据草存在batch_xs,标签会放在batch_ys中
#函数会记住前次取图片的位置,下次会从前次取值的地方继续往下取
sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys}) #喂数据,然后进行训练
acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
#穿进去的是测试集的图片和测试集的标签,用测试集来测试准确率
print("Iter " + str(epoch) + ",Testing Accuracy " + str(acc))
程序中API函数:
1、tf.zeros()函数
1.1 函数为tf.zeros(shape, dtype=tf.float32, name=None)形式,创建一个所有的元素值为0的tensor对象
参数:
shape: 用于表示维度,通常为一个int32类型数组,或者一个一维(1-D)的tf.int32数字.注意不能直接使用数字
dtype: 所要创建的tensor对象的数据类型
name: 一个该操作的别名(可选的).
类似的函数还有:
1.2 tf.zeros_like(tensor, dtype=None, name=None)
该方法用于创建一个所有参数均为0的tensor对象
给定一个tensor(tensor对象),该方法会返回一个类似当前参数类型以及维度的对象,但是所有参数的值均为0.当参数dtype选定了后,所有返回参数的类型也会变成选定的类型
该方法实际上为一个拷贝函数:默认情况下,它会拷贝参数tensor的类型,维度等数据,并将其中的值设置为0.当参数dtype设置后,那么拷贝后的tensor对象
参数:
tensor: tensor对象
dtype: 返回的tensor对象类型,不设置(为空时)时返回类型同参数tensor一致.该参数必须为如下tensorflow类型: float32, float64, int8, int16, int32, int64, uint8以及complex64.
name: 该操作别名 (可选).
返回:
所有参数为0的tensor对象
1.3 tf.ones(shape, dtype=tf.float32, name=None)
创建一个所有的参数为1的tensor对象
这个操作会返回一个类型为dtype,并且维度为sharp的tensor,并且所有的参数均为0.
参数:
shape: 用于表示维度,通常为一个int32类型数组,或者一个一维(1-D)的tf.int32数字.注意不能直接使用数字
dtype: 所要创建的tensor对象的数据类型
name: 一个该操作的别名(可选的).
返回:
所有参数都为1的tensor对象
1.4 tf.ones_like(tensor, dtype=None, name=None)
该方法用于创建一个所有参数均为1的tensor对象
给定一个tensor(tensor对象),该方法会返回一个类似当前参数类型以及维度的对象,但是所有参数的值均为1.当参数dtype选定了后,所有返回参数的类型也会变成选定的类型
该方法实际上为一个拷贝函数:默认情况下,它会拷贝参数tensor的类型,维度等数据,并将其中的值设置为1.当参数dtype设置后,那么拷贝后的tensor对象
参数:
tensor: tensor对象
dtype: 返回的tensor对象类型,不设置(为空时)时返回类型同参数tensor一致.该参数必须为如下tensorflow类型: float32, float64, int8, int16, int32, int64, uint8以及complex64.
name: 该操作别名 (可选).
返回:
所有参数为1的tensor对象
1.5 tf.fill(dims, value, name=None)
创建一个维度为dims,值为value的tensor对象.该操作会创建一个维度为dims的tensor对象,并将其值设置为value,该tensor对象中的值类型和value一致
当value为0时,该方法等同于tf.zeros()
当value为1时,该方法等同于tf.ones()
参数:
dims: 类型为int32的tensor对象,用于表示输出的维度(1-D, n-D),通常为一个int32数组,如:[1], [2,3]等
value: 常量值(字符串,数字等),该参数用于设置到最终返回的tensor对象值中
name: 当前操作别名(可选)
返回:
tensor对象,类型和value一致
1.6 tf.constant(value, dtype=None, shape=None, name='Const')
创建一个常量tensor,按照给出value来赋值,可以用shape来指定其形状。value可以是一个数,也可以是一个list。 如果是一个数,那么这个常亮中所有值的按该数来赋值。 如果是list,那么len(value)一定要小于等于shape展开后的长度。赋值时,先将value中的值逐个存入。不够的部分,则全部存入value的最后一个值。
2、tf.argmax()函数
返回最大数值的下标,dimension=0 按列找,dimension=1 按行找,通常和tf.equal()一起使用,计算模型准确度,例如:
>>> import tensorflow as tf
>>> a = tf.constant([1,5,8,9,1])
>>> b = tf.constant([[14,25,4],[54,5,8],[5,72,25]])
>>> with tf.Session() as sess:
... sess.run(tf.argmax(a, 0))
output:3
>>> with tf.Session() as sess:
... sess.run(tf.argmax(b, 1))
output:array([1, 0, 1]) #返回的是对应的下标,所以是从0开始
2、one-hot vectors
程序中mnist = input_data.read_data_sets("MNIST_data",one_hot=True)的one_hot参数:
MNIST数据集的标签介于0-9的数字,需要把标签转化为“one-hot vectors”。一个one-hot向量除了某一个数字是1以外,其余唯独都是0,比如标签0将表示为([1,0,0,0,0,0,0,0,0,0]),标签3将表示为([0,0,0,1,0,0,0,0,0,0]),由于数据集有60000个图片,MNIST的标签mnist.train.labels是一个[60000,10]的数字矩阵
3、softmax()激活函数
prediction = tf.nn.softmax(tf.matmul(x,W)+b)中的激活函数softmax()
softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,对输出的结果归一化为概率值,可以看成概率来理解,从而来进行多分类!softmax()的函数形式如下:
softmax()函数的求导
即求
4、二次代价函数
4.1 loss = tf.reduce_mean(tf.square(y-prediction))二次代价函数的数学表达式如下:
其中,C表示代价,x表示样本,y表示实际值,对应上面的y值,a表示输出值,对应上面的prediction值,n表示样本的总数。
补充:常用的代价函数还有交叉熵代价函数和对数释然代价函数(log-likelihood cost)
4.2 交叉熵代价函数数学表达式:
交叉熵代价函数的导数:
权值和偏置值的调整与无关。另外,梯度公式中表示输出值与实际值的误差。所以当误差越大时,梯度就越大,参数w和b的调整就越快,训练的速度也就越快。如果输出神经元是线性的,那么二次代价函数就是一种合适的选择。如果输出神经元是S型函数,那么比较适合用交叉熵代价函数。
4.3 对数释然代价函数(log-likelihood cost):
对数释然函数通常用来作为softmax回归的代价函数,如果输出层神经元是sigmoid函数,可以采用交叉熵代价函数。而深度学习中更普遍的做法是将softmax作为最后一层,此时常用的代价函数是对数释然函数。
对数释然函数与softmax的组合和交叉熵与sigmoid函数的组合非常相似。对数释然代价函数在二分类时可以化简为交叉熵代价函数的形式。
在TensorFlow中用:
tf.nn.sigmoid_cross_entropy_with_logits()来表示跟sigmoid搭配使用的交叉熵。
tf.nn.softmax_cross_entropy_with_logits()来表示跟softmax搭配使用的交叉熵