好的代码像粥一样,都是用时间熬出来的

初识TensorFlow_1

记录一个tensorflow的demo,详细记录一下学习过程中的一些术语和步骤

直接跳转到代码

本个demo的神经元模型

image

名词理解

张量(tensor)

多维数组(列表) 阶:张量的维数

维数 名字 例子
0-D 0 标量 scalar s=1 2 3
1-D 1 向量 vector v=[1,2,3]
2-D 2 矩阵 matrix m=[[1,2,3],[4,5,6]]
n-D n 张量 tensor t=[[[ …

ps: 左边方括号有几个,张量就是几阶

数据类型

tf.float32 tf.int32 …

使用

导入相应模块

1
import tensorflow as tf

tf是tensorflow的缩写,约定俗成写成tf,可以根据自己口味酌情更改

1
2
a = tf.constant([1.0,2.0])
b = tf.constant([3.0,4.0])

张量a、b的常数定义,下边会详细写

1
print a+b

结果

image

计算图(Graph)

搭建神经网络的计算过程,只搭建,不计算

下图是神经元(神经网络的基本单元)的基本模型

image

数学公式表示为:y=wx=x1*w1+x2*w2

1
2
3
4
5
6
7
8
import tensorflow as tf
x = tf.constant([[1.0,2.0]])
#x一行两列
w = tf.constant([[3.0],[4.0]])
#两行一列
y = tf.matmul(x,w)
#矩阵乘法
print y

结果Tensor("MatMul:0", shape=(1, 1), dtype=float32)

想得到运算结果,需要用到会话

会话(Session)

执行计算图中的结点运算

1
2
3
4
5
6
7
8
9
10
import tensorflow as tf
x = tf.constant([[1.0,2.0]])
#x一行两列
w = tf.constant([[3.0],[4.0]])
#两行一列
y = tf.matmul(x,w)
#矩阵乘法

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

结果[[ 11.]]

$$
1.33.0+2.04.0 = 11.0
$$

参数

image线上的权重W,用变量表示,随机给初值

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

其中:tf.random_normal()—> 正态分布

[2,3]—>产生2x3矩阵

stddev=2—>标准差2

均值,随机种子

除了tf.random_normal()外,还有

tf.truncated_normal()—>去掉过大偏离点的正态分布

tf.random_uniform()—>平均分布

除了生成随机数,还能生成常量

eg

tf.zeros 全0数组 tf.zeros([3,2],int32)生成[[0,0],[0,0],[0,0]]

tf.ones 全1数组 同上

tf.fill 全定值数组 tf.fill([3,2],6)生成[[6,6],[6,6],[6,6]]

tf.constant 直接给值 tf.constant([3,2,1])—>[3,2,1]

神经网络实现过程

  1. 准备数据集,提取特征,作为输入喂给神经网络

  2. 搭建NN结构,从输入到输出(先搭建计算图,再用会话执行)

    NN前向传播算法—>计算输出

  3. 大量特征数据喂给NN,迭代优化NN参数

    NN反向传播算法—>优化参数训练模型

  4. 使用训练好的模型预测和分类

训练过程1,2,3的迭代

使用过程4

前向传播

使模型有推理能力

eg.生产一批零件将体积x,和重量x为特征输入NN,通过NN
后输出一个数值。

image

—>

1
2
a = tf.matmul(X,W1)
y = tf.matmul(a,W2)

变量初始化

1
2
init = tf.global_variables_initializer()
sees.run(init)

计算图结点运算

sess.run(y)

tf.placeholder占位,在sess.run中用feed_dict喂数据

占位的意思就是画图的过程中先占一个位置,不存入数据

1
x = tf.placeholder(tf.float32,shape=(None,2))

shape=中参数意思:None 为未指定多少组数据,2是指数据有重量和体积两个参数

1
sees.run(y, feed_dict={x: [[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})

反向传播

目的:训练模型参数,在所有参数上用梯度下降,使NN模型在训练数据上的损失函数最小

损失函数(loss)

预测值(y)与已知答案(y_)的差距

均方误差

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

反向传播训练方法

以减小loss为优化目标

三种优化器

1
2
3
4
5
train_step= tf.train. GradientDescentOptimizer(learning_rate).minimize (loss)

train_step= tf.train.MomentumOptimizer(learning_rate, momentum).minimize(loss)

train_step =tf.train.AdamOptimizer(learning_rate).minimize(loss)

学习率

以上三种优化器都有一个学习率的参数,学习率决定参数每次更新的幅度

demo

本个代码的神经元模型

image

加深学习的印象

1
#coding:utf-8

防止中文输出报错,加入格式

1
2
import tensorflow as tf
import numpy as np

导入TensorFlow模块和numpy模块(Python的科学计算模块)

1
BATCH_SIZE = 8

一次传入神经网络8组数据,宏定义

1
2
3
seed = 23455
##基于seed产生数据集
rng = np.random.RandomState(seed)

nump.random.RandomState(0)为随机数产生器的种子,里面的数字相同,则产生的随机数相同,对于某一个伪随机数发生器,只要该种子(seed)相同,产生的随机数序列就是相同的,此处的23455不具有特殊含义

1
2
#随机数返回32行2列的矩阵 表示32组 体积和重量 作为输入数据集
X = rng.rand(32,2)

32组,每组两个特征

1
2
#从x这个32行2列的矩阵中取出一行,判断如果和小于1,给y赋值1,不小于赋值0  零件1合格
Y = [[int(x0 + x1 <1)] for (x0,x1) in X]

用Y生成序列集对应的标签,人为的给出一个零件 体积+重量 合格为小于1,不合格为0。因为这个例子没有实际的数据集,是虚拟的零件样本(X)和标签(Y)

定义神经网络的输入、参数和输出,定义前向传播过程

占位

1
x = tf.placeholder(tf.float32,shape=(None,2))

输入的特征,32位浮点型,两个特征,没定义多少组

1
y_= tf.placeholder(tf.float32,shape=(None,1)) #标准答案占位

下边是参数

1
2
w1= tf.Variable(tf.random_normal([2,3]))
w2= tf.Variable(tf.random_normal([3,1]))

要匹配输入和输出,输入是两个特征,输出是一个数。w1两行,对应x,w2一列对应y

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

前向传播计算描述,用矩阵乘法实现

定义损失函数及反向传播方法

1
2
loss = tf.reduce_mean(tf.square(y-y_))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

生成会话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
#输出未训练前的参数
print "w1:\n",sess.run(w1)
print "w2:\n",sess.run(w2)

#训练模型
for i in range(3000):
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 "第%d次训练的值为%g"%(i,total_loss)
1
2
3
print "\n"
print "w1:\n",sess.run(w1)
print "w2:\n",sess.run(w2)

最后输出优化后的w1,w2

运行结果

x:
[[ 0.83494319 0.11482951]
[ 0.66899751 0.46594987]
[ 0.60181666 0.58838408]
[ 0.31836656 0.20502072]
[ 0.87043944 0.02679395]
[ 0.41539811 0.43938369]
[ 0.68635684 0.24833404]
[ 0.97315228 0.68541849]
[ 0.03081617 0.89479913]
[ 0.24665715 0.28584862]
[ 0.31375667 0.47718349]
[ 0.56689254 0.77079148]
[ 0.7321604 0.35828963]
[ 0.15724842 0.94294584]
[ 0.34933722 0.84634483]
[ 0.50304053 0.81299619]
[ 0.23869886 0.9895604 ]
[ 0.4636501 0.32531094]
[ 0.36510487 0.97365522]
[ 0.73350238 0.83833013]
[ 0.61810158 0.12580353]
[ 0.59274817 0.18779828]
[ 0.87150299 0.34679501]
[ 0.25883219 0.50002932]
[ 0.75690948 0.83429824]
[ 0.29316649 0.05646578]
[ 0.10409134 0.88235166]
[ 0.06727785 0.57784761]
[ 0.38492705 0.48384792]
[ 0.69234428 0.19687348]
[ 0.42783492 0.73416985]
[ 0.09696069 0.04883936]]
y:
[[1], [0], [0], [1], [1], [1], [1], [0], [1], [1], [1], [0], [0], [0], [0], [0], [0], [1], [0], [0], [1], [1], [0], [1], [0], [1], [1], [1], [1], [1], [0], [1]]

第0次训练的值为0.646454
第500次训练的值为0.383877
第1000次训练的值为0.383805
第1500次训练的值为0.38375
第2000次训练的值为0.38371
第2500次训练的值为0.383681

w1:
[[-0.54031479 0.58477235 0.78871536]
[ 0.35046345 -0.73379153 0.00478574]]
w2:
[[-0.83987921]
[-0.57386231]
[ 0.74306184]]

坚持原创技术分享,您的支持将鼓励我继续创作!