本篇博客为学习中国大学MOOC-人工智能实践:Tensorflow笔记课程时的个人笔记记录。具体课程情况可以点击链接查看。(这里推一波中国大学MOOC,很好的学习平台,质量高,种类全,想要学习的话很有用的)
Chapter 1 人工智能概述
机器学习的定义:如果一个程序可在任务T上,随经验E的增加,效果P随之增加,则这个程序可以从经验中学习。
神经网络的基本模型是神经元,神经元的基本模型就是数学中的乘法、加法运算。
本章主要对人工智能进行了简要介绍,没有做啥笔记。
Chapter2 Python语法串讲
本章主要对Python语法进行了简单的简简简介,(只能说是让没接触过Python但是一听就能学会的大佬学Python吧。个人推荐还是老老实实认真学一下Python,可以参见廖雪峰的Python教程,这个差不多算是真正入门啦。)
Chapter3 Tensorflow框架
3.1 张量 计算图 会话
基本概念
基于Tensorflow的NN:用张量表示数据,用计算图搭建神经网络,用会话执行计算图,优化线上的权重(参数),得到模型。
张量:张量其实就是多维数组,用“阶”表示张量的纬度。
**数据类型:**Tensorflow的数据类型有tf.float32,tf.int32等等
**指令:**Tensorflow指令用于创建、销毁和控制张量,一般Tensorflow程序中的大多数代码都是指令。
**图(计算图):**Tensorflow图(也称计算图或者数据流程图)是一种图数据结构,图的节点是指令,图的边是张量,张量流经图,在每一个节点由一个指令操控。
搭建神经网络的计算过程,只搭建不计算。
会话:图必须在Tensorflow会话中运行,会话存储了它所运行的图的状态。
执行计算图中的节点运算。
一些基本操作
首先引入TensorFlow模块:
#coding=utf-8
import tensorflow as tf
定义一个常量张量:
a = tf.constant([1.0, 2.0]) #定义一个张量等于[1.0, 2.0]
b = tf.constant([3.0, 4.0]) # 定义一个张量等于[3.0, 4.0]
张量的加法:
c = a+b #第一种方法
c = tf.add(a, b) #第二种方法
注意:这个时候你可以尝试一下:
print(c)
你会得到如下结果:
Tensor("add:0", shape=(2, ), dtype=float32)
并不是原本编程里面理解的c的结果,因为TensorFlow只在会话中才进行运算,会话外的指令并不会得到实际的运算结果!!!
张量的乘法:
d = tf.matmul(a, b)
上面的乘法和之前的加法一样,直接输出d的话并不会得到直观的结果,需要在会话Session()中进行运算.
Session
#coding=utf-8
import tensorflow as tf
a = tf.constant([1.0, 2.0])
b = tf.constant([3.0, 4.0])
y = tf.matmul(a, b)
print(y)
with tf.Session() as sess:
print(sess.run(y))
需要这样才能输出之前图中运算得到的y的实际值.
会得到输出结果:
Tensor("MatMul:0", shape=(1, 1), dtype=float32)
[[ 11.]]
3.2 前向传播
神经网络的参数:指神经元线上的权重W,用变量表示,一般会先随机生成这些参数.生成参数的方法是使用tf.Variable函数.
在TensorFlow中声明2x3服从正太分布的随机数(标准差2,均值0,随机数种子1)
w = tf.Variable(tf.random_normal([2,3], stddev=2, mean=0, seed=1))
此外,常用的生成随机数/数组的函数有:
tf.random_normal() #生成正太分布随机数
tf.random_normal([2,3], stddev=2, mean=0, seed=1)
tf.truncated_normal() #生成去电过大偏离点的正太分布随机数
tf.truncated_normal([2,3], stddev=2, mean=0, seed=1)
tf.random_uniform() #生成均匀分布随机数
random_uniform(shape=7,minval=0.maxval=1,dtype=tf.in32,seed=1)
tf.zeros() #生成全零数组
tf.zeros([3, 2], int32)
tf.ones() #生成全一数组
tf.ones([3, 2, int32])
tf.fill() #生成全定值数组
tf.fill([3, 2], 6) #[[6,6],[6,6],[6,6]]
tf.constant() #生成直接给定数值的数组
tf.constant([3,2,1])
注:随机种子的作用是确保在不同设备上每次运行都生成一致的随机数.AND如果没有特殊要求,标准差,均值,随机数种子可以不写.
神经网络的搭建过程
1.准备数据集,提取特征,作为输入喂给神经网络(NN)
2.搭建NN结构,从输入到输出(先搭建计算图,然后再用会话执行)
(NN前向传播算法–>计算输出)
3.大量特征数据喂给NN,迭代优化NN参数.
(NN方向传播算法–>优化参数训练模型)
4.使用训练好的模型预测和分类.
前向传播:搭建模型的计算过程,让模型具有推理能力,可以针对一组输入给出相应的输出.
变量初始化:在Session()中最一开始需要对所有变量进行初始化操作.
with tf.Session() as sess:
sess.run()
init_op = tf.global_variables_initializr()
sess.run(init_op)
placeholder占位:由于TensorFlow中图中不进行计算的特性,所以需要一个placeholder为输入进行占位操作.
tf.placeholder(tf.float32, shape=(1, 2)) #这样对应 fees_dict 喂一组数据
sess.run(y, feed_dict={x: [[0.5,0.6]]})
x = tf.placeholder(tf.float32, shape=(None, 2)) #这样对应 fees_dict 喂多组数据
sess.run(y, feed_dict={x: [[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})
下面给出一段完整的,使用TF进行前向传播的代码.
#coding:utf-8
#file:tf3_5.py
import tensorflow as tf
x = tf.placeholder(tf.float32, shape=(None, 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))
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print("y in tf3_3.py is:")
print(sess.run(y, feed_dict={x: [[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]}))
print("w1:\n", sess.run(w1))
print("w2:\n", sess.run(w2))
3.3 反向传播
反向传播:训练模型参数,在所有参数上使用梯度下降,是NN模型在训练数据上的损失函数最小.
损失函数(loss):计算得到的预测值y和已知答案y_的差距.
均方误差MSE是常用的计算loss的方法之一:
使用TensorFlow函数表示为:
loss_mse = tf.reduce_mean(tf.square(y_-y))
反向传播训练方法:以减小loss为优化目标,有梯度下降,momentum优化器,adam优化器等优化方法.
使用TF表示这三种优化方法为:
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
train_step = tf.train.MomentumOptimizer(0.001, 0.9).minimize(loss)
train_step = tf.train.AdamOptimizer(0.001).minimize(loss)
三种优化方法的区别如下:
1.tf.train.GradientDescentOptimizer()使用随机梯度下降算法,使参数沿着梯度的反方向,即总损失减小的方向移动,实现更新参数.参数更新的公式是:
其中, J(θ) J ( θ ) 是损失函数, θ θ 为参数, α α 是学习率.
2.tf.train.MomentumOptimizer()在更新参数时,利用了超参数,参数更新公式为:
其中, α α 为学习率,超参数为 β β , θ θ 是参数, g(θi−1) g ( θ i − 1 ) 为损失函数的梯度.
3.tf.train.AdamOptimizer()是利用自适应学习率的优化算法,Adam算法和随机梯度下降算法不同.随机梯度下降算法保持单一的学习率更新所有的参数,学习率在训练过程中不会改变.二Adam算法通过计算梯度的一阶矩估计和二阶矩估计而为不同的参数设计独立的自适应性学习率.
学习率:决定每次参数更新的幅度.
优化器中都需要一个叫做学习率的参数,使用时,如果学习率选择过大会出现震荡不收敛的情况,如果学习率选择过小,会出现收敛速度过慢的情况.我们可以选择一个较好的值填入,比如0.01,0.001
神经网络搭建的步骤:
0.导入模块,生成数据集
1.前向传播:定义输入,参数还有输出
2.方向传播:定义损失函数,反向传播算法
3.生成会话,训练STEPS轮
一个完整的训练测试过程
#coding:utf-8
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
seed = 23455
# 基于seed生成随机数,确定生成的随机数
rng = np.random.RandomState(seed)
# 使用numpy 生成随机数 32行*两列
X = rng.rand(32,2)
# 将X的每一行相加,如果小于1,Y为1,如果不小于1,Y为0
Y = [[int(x0+x1 < 1)] for (x0, x1) in X]
# 输入x,ground truth y_
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
# 权重 w1,w2
w1 = tf.Variable(tf.random_normal([2,3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3,1], stddev=1, seed=1))
# 前向传播
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 定义损失函数和反向传播算法
loss = tf.reduce_mean(tf.square(y-y_))
#train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
#train_step = tf.train.MomentumOptimizer(0.001, 0.9).minimize(loss)
train_step = tf.train.AdamOptimizer(0.001).minimize(loss)
# 生成会话,训练STEPS轮
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 输出优化前,训练前的参数
print("w1:\n", sess.run(w1))
print("w2:\n", sess.run(w2))
# train
STEPS = 3000
for i in range(STEPS):
start = (i*BATCH_SIZE) % 32
end = start + BATCH_SIZE
sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
if i % 500 == 0:
total_loss = sess.run(loss, feed_dict={x: X, y_: Y})
print("After %d training steps, loss on all data is %g" % (i, total_loss))
print("w1:\n", sess.run(w1))
print("w2:\n", sess.run(w2))