TensorFlow学习_(2)基于TensorFlow的神经网络

什么是基于TensorFlow的神经网络

  1. 用张量表示数据;
  2. 用计算图搭建神经网络;
  3. 用会话执行计算图;
  4. 优化参数(线上的权重)得到模型;

张量(tensor)

张量是TensorFlow管理数据的形式,所有数据都用张量表示。
单纯从功能角度上看,张量可以被简单的理解为多维数组。张量有三个属性:名称(name)、维度(shape)、类型(type)。

  1. name

    张量的命名通过”node:src_output”形式给出,node为节点名称,src_output表示当前张量来自节点的第几个输出。张量在TensorFlow中的实现并不是直接采用数组的形式,而是对运算结果的引用。张量中没有直接保存数字,而是保存得到数字的计算过程。举例如下:

    import tensorflow as tf
    a = tf.constant([1.0, 2.0], name = "a")
    b = tf.constant([2.0, 3.0], name = "b")
    result = tf.add(a, b, name = "add")
    print(result)

    执行以上代码,输出结果为:

    Tensor("add:0", shape=(2,), dtype=float32)

    其中可以看出 "add:0" 即为此张量的name。

  2. shape

    • 0阶张量表示标量(scalar),即一个数;
    • 1阶张量表示向量(vector),即一维数组;
    • 2阶张量表示矩阵(martrix),即二维数组;
    • n阶张量可以理解为一个n维数组。

    上例中 shape=(2,) 说明张量是一个一维数组,长度是2。

  3. 类型

    即数据类型。不带小数点的默认int32, 带小数点的默认float32。

计算图

TensorFlow是一个用计算图的形式来表述计算的编程系统,计算图就是用节点搭建出神经网络,此过程只搭建不运算。

import tensorflow as tf
x = tf.constant([[3., 3.]])  # 创建一个常量 op,产生1*2矩阵
w = tf.constant([[2.],[2.]]) # 创建另外一个常量 op, 产生一个 2x1 矩阵.
y = tf.matmul(x, w) # 创建一个矩阵乘法 matmul op , 把 'x''w' 作为输入.

会话

会话拥有并管理TensorFlow程序运行时的所有资源,执行计算图中的节点运算,执行后必须关闭,不然会资源泄露。

# 创建一个会话。
sess = tf.Session()
# 使用会话得到之前计算的结果。
print(sess.run(result))
print(sess.run(y))
# 关闭会话使得本次运行中使用到的资源可以被释放。
sess.close()

为了防止程序异常退出不执行关闭语句以及方便,可以通过Python的with语法控制。

with tf.Session() as sess:
    print(sess.run(result))

参数

运算图线上的权值,用变量表示,初值通常随机生成。以下代码声明一个2*3矩阵变量:

w = tf.Variable(tf.random_normal([2, 3], mean = 0, stddev = 2))

以上代码中调用了变量的声明函数 tf.Variable() ,在该函数中给出了初始化这个变量的方法,即2*3的、均值为0、标准差为2的正态随机数矩阵。

其他生成函数还有:

tf.truncated_normal(平均值,标准差,取值类型)       #正态分布,若生成的值偏离随机值超过2个标准差则重新生成

tf.random_uniform(最小取值,最大取值,取值类型)      #均匀分布

tf.zeros([2, 3])  -->  [[0, 0, 0], [0, 0, 0]]

tf.ones([3, 2])  -->  [[1, 1], [1, 1], [1, 1]]

tf.fill([2, 3], 9)  -->  [[9, 9, 9], [9, 9, 9]]

tf.constant([[1, 2, 3][4, 5, 6], [7, 8, 9]])  -->  [[1, 2, 3][4, 5, 6], [7, 8, 9]]

神经网络(Neural Network, NN)的过程

  1. 提取问题中实体的特征向量作为神经网络的输入;
  2. 定义神经网络的结构(计算图),并定义如何从神经网络的输入得到输出。先搭计算图,再用会话执行。这就是神经网络的前向传播算法
  3. 通过训练数据迭代调整神经网络参数取值,使神经网络模型在训练数据上损失函数值最小。这就是神经网络的后向传播算法
  4. 使用训练好的神经网络预测未知的数据。

其他知识点

placeholder:在反向传播中,如果每轮迭代中选取的数据都要通过常量表示,每生成一个常量将在计算图中增加一个节点,计算图将会很大,利用率很低。为了解决此问题,TensorFlow提供了placeholder机制用于提供输入数据。placeholder相当于定义了一个位置,此位置中的数据在程序运行时指定。举例定义placeholder如下:

x = tf.placeholder(tf.float32, shape = (1, 2), name = "input")

损失函数:预测值 y 和实际值 y_ 之间的差距。举例:常用损失函数如下

  • 交叉熵(常用于分类问题):

    cross_entropy = -tf.reduce_mean(y_ *tf.log(tf.clip_by_value(y, 1e-10, 1.0)))    
    
  • 均方误差(常用于回归问题):

    mse = tf.reduce_mean(tf.square(y_ - y))
    

样例:通过变量实现神经网络的参数并实现前向传播过程

#coding:utf-8
#1. 三层简单神经网络

import tensorflow as tf

#1.1 定义变量

# 通过seed参数设定随机种子,可以保证每次运行得到同样的结果
w1= tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2= tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
x = tf.constant([[0.7, 0.9]])

#1.2 定义前向传播的神经网络

a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

#1.3 调用会话输出结果

sess = tf.Session()
# 这里不能直接通过sess.run(y)来获取y的取值,因为w1和w2还没有初始化。
sess.run(w1.initializer)  
sess.run(w2.initializer)  
print(sess.run(y))  
sess.close()

# 输出:[[ 3.95757794]]

#2. 使用placeholder

x = tf.placeholder(tf.float32, shape=(1, 2), name="input")
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

sess = tf.Session()

# 使用tf.initialize_all_variables()来初始化所有的变量
init_op = tf.initialize_all_variables()  
sess.run(init_op)

print(sess.run(y, feed_dict={x: [[0.7,0.9]]}))
sess.close()

#输出:[[ 3.95757794]]

#3. 增加多个输入

x = tf.placeholder(tf.float32, shape=(None, 2), name="input")  
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

sess = tf.Session()
init_op = tf.initialize_all_variables()  
sess.run(init_op)

print(sess.run(y, feed_dict={x: [[0.7,0.9],[0.1,0.4],[0.5,0.8],[0.8,0.1]]}))

sess.close()

#输出:[[ 3.95757794]
#      [ 1.15376544]
#      [ 3.16749191]]

完整实例:训练神经网络解决二分类问题

判断零件是否合格的三层神经网络结构图:
流程

#coding:utf-8

#1.导入模块,生成模拟数据集。
import tensorflow as tf
# NumPy是一个科学的计算工具包,这里通过NumPy工具包生成模拟数据集
from numpy.random import RandomState
# 定义训练数据的大小
BATCH_SIZE = 8
# 通过随机数生成模拟数据集
# RandomState中参数为种子
rdm = RandomState(1)
DATASET_SIZE = 128
X = rdm.rand(DATASET_SIZE, 2)
# 所有 x0 + x1 < 1 的样例都被认为是正样本(如零件合格),其他为负样本(如零件不合格)。
Y = [[int(x0 + x1 < 1)] for (x0, x1) in X]

#2. 定义神经网络的常量,参数,输入和输出节点,定义前向传播过程。
w1= tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2= tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))

x = tf.placeholder(tf.float32, shape=(None, 2), name="x-input")
y_= tf.placeholder(tf.float32, shape=(None, 1), name='y-input')

a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

#3. 定义损失函数及反向传播算法。
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0))) 
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
#train_step = tf.train.GradientDescentOptimizer(0.001).minimize(cross_entropy)
#train_step = tf.train.MomentumOptimizer(0.001,0.9).minimize(cross_entropy)

#4. 创建一个会话来运行TensorFlow程序。反复运行反向传播
with tf.Session() as sess:
    init_op = tf.initialize_all_variables()
    sess.run(init_op)
    # 输出目前(未经训练)的参数取值。
    print("w1:\n", sess.run(w1))
    print("w2:\n", sess.run(w2))

    # 训练模型。
    # 设定训练的轮数
    STEPS = 5000
    for i in range(STEPS):
        # 每次选取 BATCH_SIZE 个样本进行训练
        start = (i*BATCH_SIZE) % DATASET_SIZE
        end = (i*BATCH_SIZE) % DATASET_SIZE + BATCH_SIZE
        sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
        # 每隔一段时间计算在所有数据上的交叉熵并输出
        if i % 1000 == 0:
            total_cross_entropy = sess.run(cross_entropy, feed_dict={x: X, y_: Y})
            print("After %d training step(s), cross entropy on all data is %g" % (i, total_cross_entropy))

    # 输出训练后的参数取值。
    print("w1:\n", sess.run(w1))
    print("w2:\n", sess.run(w2))
# 输出结果:
"""
w1:
 [[-0.81131822  1.48459876  0.06532937]
 [-2.4427042   0.0992484   0.59122431]]
w2:
 [[-0.81131822]
 [ 1.48459876]
 [ 0.06532937]]

After 0 training step(s), cross entropy on all data is 0.0674925
After 1000 training step(s), cross entropy on all data is 0.0163385
After 2000 training step(s), cross entropy on all data is 0.00907547
After 3000 training step(s), cross entropy on all data is 0.00714436
After 4000 training step(s), cross entropy on all data is 0.00578471

w1:
 [[-1.96182752  2.58235407  1.68203771]
 [-3.46817183  1.06982315  2.11788988]]
w2:
 [[-1.82471502]
 [ 2.68546653]
 [ 1.41819501]]
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值