导入Tensorflow框架
在安装好tensorflow库之后,使用如下命令导入
import tensorflow as tf # tf作为别名使用
Tensorflow编写程序的过程
定义tensorflow常量
C = tf.constant(N,name='C') # N为一个常量的值
定义tensorflow变量/张量
f = tf.Variable(f(x,y),name='f') # 可以用来定义变量,也可以定义简单的函数
初始化变量
由于tf.Variable类型的变量在创建时是没有初始化的,因此,在使用到tf.Variable、tf.get_Variable的场合,必须全局初始化变量。
init = tf.global_variables_initializer()
# 这仅仅是定义一个语句init,并没有执行
执行语句
tensorflow定义的语句都是静态的,执行语句需要依靠tf.Session
with tf.Session() as session:
session.run(init)
Tensorflow特色
设计/动工特色
[In]
a = tf.constant(2)
b = tf.constant(10)
c = tf.multiply(a,b)
print(c)
[Out]
Tensor("Mul:0", shape=(), dtype=int32)
上述代码中,打印c的值并没有输出a与b的乘积,而是输出了张量(Tensor) c 的属性值:shape为空,数据类型为int32. 这说明这些代码仅仅是一个设计过程,并没有实际执行。执行代码如下:
[In]
sess = tf.Session()
print(sess.run(c))
[Out]
20
由此可见,tensorflow使用的基本流程是:
创建变量和操作,然后对变量进行初始化,然后创建session,最后用session来执行所有操作。
placeholder占位符
- 占位符仅占着位置,位置里面的内容是空的,后续可以根据需求来填充不同的东西。就像刚刚建好的大厦,里面的一个个空房间就是占位符,我们可以在空房间里放置需要的东西。
- tensorflow使用feed_dict语法来给占位符填充内容
x = tf.placeholder(tf.int64, name = 'x')
print(sess.run(2 * x, feed_dict = {x: 3}))
sess.close()
上述代码中,先是创建了一个名为x的占位符,类型为tf.int64,然后用sess.run执行时,使用feed_dict将3填充到x里,所以最后输出的是2*3=6
计算图
当我们创建变量和操作时,仅仅是在tensorflow里面构建了一个计算图,计算图里面可以有占位符。这些都只是设计而已,并没有实际的数值也没有被执行。直到创建了session后,就可以用session.run来执行前面设计好的计算图了,在执行计算图时可以往计算图里的占位符中填充内容。同一个计算图,在每次run时,即在每次被执行时都可以往占位符中填充不同的数值。就像一座大厦,可以往房间里面堆放书籍,也可以把书籍搬出来将里面堆放电脑。
创建session的两种方式
方法一
sess = tf.Session()
result = sess.run(..., feed_dict = {...})
sess.close()
方法二
with tf.Session() as sess:
result = sess.run(..., feed_dict = {...})
使用Tensorflow来构建常用函数
线性函数
下面将实现人工智能领域中著名的线性函数: Y=WX+b,其中用到的操作有矩阵相加操作tf.add(X,Y),还有矩阵相乘操作tf.matmul(X,Y)。
def linear_function():
np.random.seed(1)
X = tf.constant(np.random.randn(3, 1), name = "X")
# 定义一个维度是(3, 1)的常量,randn函数会生成随机数
W = tf.constant(np.random.randn(4, 3), name = "W")
b = tf.constant(np.random.randn(4, 1), name = "b")
Y = tf.add(tf.matmul(W, X), b)# tf.matmul函数会执行矩阵运算
# 创建session,然后用run来执行上面定义的操作
sess = tf.Session()
result = sess.run(Y)
sess.close()
return result
非线性函数
下面将实现著名的非线性函数sigmoid。其实,tensorflow框架已经帮我们实现了这些函数了,我们只需要学会使用它们就可以了。下面将用placeholder来使用tensorflow中的sigmoid函数。
def sigmoid(z):
x = tf.placeholder(tf.float32, name="x")
# 定义一个类型为float32的占位符
sigmoid = tf.sigmoid(x)
# 调用tensorflow的sigmoid函数,并且将占位符作为参数传递进去
with tf.Session() as sess: # 创建一个session
# 用run来执行上面定义的sigmoid操作。
# 执行时将外面传入的z填充到占位符x中,也就相当于把z作为参数传入了tensorflow的sigmoid函数中了。
result = sess.run(sigmoid, feed_dict = {x: z})
return result
Cost函数
cost函数也是人工智能领域的一个重要部分。像sigmoid一样,tensorflow也已经帮我们定义好了各种著名的cost函数。
我们可以用tensorflow函数来一次性实现sigmoid和上面的cost函数,上面的cost函数也叫做cross_entropy函数:
tf.nn.sigmoid_cross_entropy_with_logits(logits = ..., labels = ...)
- logits参数:最后一层神经元输出的z
- labels参数:真实标签y
- 上面的代码一次性实现了将最后一层神经元的输出z传入sigmoid激活函数,再计算cross_entropy损失函数
def cost(z_in, y_in):
z = tf.placeholder(tf.float32, name="z") # 创建占位符
y = tf.placeholder(tf.float32, name="y")
# 使用sigmoid_cross_entropy_with_logits来构建cost操作。
cost = tf.nn.sigmoid_cross_entropy_with_logits(logits=z, labels=y)
# 创建session
sess = tf.Session()
# 将传入的z_in和y_in填充到占位符中,然后执行cost操作
cost = sess.run(cost, feed_dict={z: z_in, y: y_in})
sess.close()
return cost
One Hot编码
- 应用场景:多分类问题
- 编码转换原理图例:
- 右边的向量就叫做one hot向量,因为向量中只有一个元素是1,其它的都是0。例如,最后一个元素是1就表示类型3。在之前我们实现纯python编程时,如果要实现上面的转换,我们需要写好几行代码,改用tensorflow框架的话,只需要一行代码:
tf.one_hot(indices, depth, axis)
# indices表示真实标签,depth表示的是类别数量,axis规定了输出向量方向
- 实例:
def one_hot_matrix(labels, C_in):
"""
labels就是真实标签y向量;
C_in就是类别的数量
"""
# 创建一个名为C的tensorflow常量,把它的值设为C_in
C = tf.constant(C_in, name='C')
# 使用one_hot函数构建转换操作,将这个操作命名为one_hot_matrix。
one_hot_matrix = tf.one_hot(indices=labels, depth=C, axis=0)
sess = tf.Session()
# 执行one_hot_matrix操作
one_hot = sess.run(one_hot_matrix)
sess.close()
return one_hot
初始化0和1
- 两个tensorflow常用函数,tf.ones()和tf.zeros()。将维度信息传入到这两个函数中,它们就会返回填充好1或0的数组。
def ones(shape):
# 将维度信息传入tf.ones中
ones = tf.ones(shape)
sess = tf.Session()
# 执行ones操作
ones = sess.run(ones)
sess.close()
return ones
随机初始化
- 用tensorflow内置的xavier_initializer函数来进行权重w的随机初始化
W1 = tf.get_variable("W1", [25, 12288], initializer = tf.contrib.layers.xavier_initializer(seed=1))
- 用tensorflow内置的zeros_initializer函数将偏置值b1初始化为0
b1 = tf.get_variable("b1", [25, 1], initializer = tf.zeros_initializer())
重置全局默认图形
用于清除默认图形堆栈并重置全局默认图形,使用tf时必须执行,否则图形栈会溢出。
tf.reset_default_graph()
tf转置矩阵操作
labels = tf.transpose(Y)
计算张量的平均值
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels))
反向传播optimizer
- 标准的梯度下降反向传播
optimizer = tf.train.GradientDescentOptimizer(learning_rate = learning_rate).minimize(cost)
- Adam优化的反向传播
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
使用Tensorflow构建卷积神经网络(CNN)
相关工具函数
- tf.nn.conv2d(X,W1, strides = [1,s,s,1], padding = ‘SAME’): X是指输入矩阵,W1是指过滤器。这个函数会将X和W1进行卷积。strides是指各个维度的卷积步长,[1,s,s,1]的含义分别是[样本数,输入矩阵的高,输入矩阵的宽,输入矩阵的深度]。padding是指填补数量,默认使用SAME填补,也就是自动填补一定数量元素而保证输入矩阵与输出矩阵的尺寸一样。
- tf.nn.max_pool(A, ksize = [1,f,f,1], strides = [1,s,s,1], padding = ‘SAME’): 这个函数会对输入矩阵A进行最大池化。ksize中的f表示池化窗口的大小。strides中的s表示步长。
- tf.nn.relu(Z1): 对Z1中的每一个元素进行relu激活
- tf.contrib.layers.flatten§: 它会将P中样本的矩阵扁平化成向量。
- tf.contrib.layers.fully_connected(F, num_outputs): 构建一个全连接层,F是该层的输入,num_outputs表示该层中神经元的个数。这个函数会自动初始化该层的权重w。我们在前面只初始化了卷积层相关的参数,因为TensorFlow会自动帮我们初始化全链接层的参数。