搭建神经八股

我的环境是ubuntu18.04+python3.6+tensorflow-1.5.0-gpu,gpu版本的tensorflow需要安装对应的cuda和cudnn,麻烦一点,但配好以后用其他框架就不用再配置了。tensorflow-1.5.0对应的cuda版本是9.0,cudnn版本是7.0,cpu版本的tensorflow则不需要安装cuda和cudnn。

搭建神经八股,这里的八股指的是搭建神经网络有一个固定的步骤,即

  1. 准备数据集,提取特征,作为输入喂入神经网络NN(Netural Network)
  2. 搭建NN 结构,从输入到输出(先搭建计算图,再用会话执行)
  3. 大量特征数据喂给神经网络,迭代优化参数
  4. 使用训练好的模型预测和分类
  • 一些基本概念

张量:张量就是多维数组(列表),“阶”表示张量的维度

  • 0阶张量:又叫标量,是一个单独的数                例如:a=123
  • 1阶张量:称作向量,表示一个一维数组             例如:b=[1,2,3]
  • 2阶张量:称作矩阵,表示一个二维数组             例如:c=[[1,2,3],[4,5,6]]
  • n阶张量就是看方括号的层数,有几层就是几阶

我们把上面的例子在tensorflow中打印出来看结果如何

import tensorflow as tf        #引入tensorflow模块
a=tf.constant(123)             #tf.constant 表示这是一个常量
b=tf.constant([1,2,3])
c=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]])
print(a)
print(b)
print(c)
  • a的打印结果为Tensor("Const:0", shape=(), dtype=int32)
  • b的打印结果为Tensor("Const_1:0", shape=(3,), dtype=int32)
  • c的打印结果为Tensor("Const_2:0", shape=(2, 3), dtype=float32)

第一项是张量的名字

第二项中a的shape什么都没有,这是一个标量,b的shape表示一个长度为3的一维数组,c的shape表示这是一个2行3列的矩阵

最后一项是数据类型,可以看到tensorflow中有两种数据类型,tf.int32和tf.float32。

神经网络的计算过程是基本的乘加运算,下图表示一个神经元

x1和x2表示输入,w1、w2分别是x1到y和x2到y的权重,y=x1*w1+x2*w2

用代码实现以上过程

import tensorflow as tf
x=tf.constant([[1.0,2.0]])          #x是一个一行两列的矩阵
w=tf.constant([[3.0],[4.0]])        #w是一个两行一列的矩阵
y=tf.matmul(x,w)                    #用tf.matmul实现矩阵相乘,得出的应该是一个一行一列的矩阵
print(y)

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

可以看到结果显示这是一个张量,只搭建了计算过程,没有计算结果,如果想要运算,需要引入会话(Session)模块,

引入的方式为

with tf.Session() as sess:

    print(sess.run(y))          #这里需要缩进

或者

sess=tf.Session()

print(sess.run(y))

看一下实现过程

import tensorflow as tf
x=tf.constant([[1.0,2.0]])          #x是一个一行两列的矩阵
w=tf.constant([[3.0],[4.0]])        #w是一个两行一列的矩阵
y=tf.matmul(x,w)                    #用tf.matmul实现矩阵相乘,得出的应该是一个一行一列的矩阵
print(y)
sess=tf.Session()
print(sess.run(y))

打印出计算结果[[11.]]


神经网络的参数

神经网络的参数是指神经元线上的权重w,用变量表示,一般会先随机生成这些参数。生成参数的方法是让w等于tf.Variable,把生成的方式写在括号里。神经网络中常用的生成随机数的函数有:

tf.random_normal()

生成正态分布随机数
tf.truncated_normal()生成去掉过大偏离点的正态分布随机数
tf.random_uniform()生成均匀分布随机数
tf.zeros生成全0数组
tf.ones生成全1数组
tf.fill生成全定值随机数组
tf.constant生成直接给定值的随机数组

w1=tf.Variable(tf.random_normal([2,3],stddev=2,mean=0,seed=1))
#生成正态分布随机数,形状两行三列,标准差是2,均值是0,随机种子是1
w2=tf.Variable(tf.truncated_normal([2,3],stddev=2,mean=0,seed=1))
#生成去掉偏离过大的正态分布,即随机生成的数超过两个标准差,这个数据将重新生成
w3=tf.Variable(tf.random_uniform(shape=7,minval=0,maxval=1,dtype=tf.int32,seed=1))
#从一个均匀分布[minval,maxval]中随机采样,定义域是前闭后开,和python的切片一样,包前不包后
w4=tf.zeros([3,2])#生成[[0,0],[0,0],[0,0]]
w5=tf.ones([3,2])#生成[[1,1],[1,1],[1,1]]
w6=tf.fill([3,2],6)#生成[[6,6],[6,6],[6,6]]
w7=tf.constant([3,2,1])#生成[3,2,1]

注意:

  1. 随机种子去掉每次生成的随机数将不一样
  2. 如果没有特殊要求,标准差、均值、随机种子都可以不写

了解了基本的知识,现在可以搭建神经网络了

前向传播:前向传播就是搭建模型的计算过程,让模型具有推理能力,可以针对一组输入给出相应的输出

假如生产一批零件,体积为x1,重量为x2,体积和重量就是我们所选的特征,把它们喂入神经网络,当体积和重量这组数据走过神经网络后会得到一个输出,假设输入的特征值是:体积0.7,重量0.5

上面是一个两层的神经网络,为什么是两层?因为神经网络的层数指的是计算层,不包括输入层。

X是输入为1x2的矩阵,表示一次输入两个特征,这组特征包含了体积和重量两个元素。

W为待优化的参数,对于第一层的w前面有两个节点,后面有三个节点,w应该是两行三列的矩阵,这样表示

括号里的1表示第一层,下标为:前节点编号,后节点编号

a=X*W1,a表示第一层网络,

在tensorflow中这样表示:

a=tf.matmul(X,W1)

W2为三行一列的矩阵

输出y=a*W2

y=tf.matmul(a,W2)

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

损失函数(loss):计算得到的预测值y与已知答案y_的差距,比较常见的损失函数是均方误差,即误差的平方和求平均

反向传播训练方法:以减少loss为优化目标,有梯度下降,momentum优化器、adam优化器等方法。

这三种优化方法用tensorflow的函数表示为:

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

学习率:即参数更新的幅度,学习率选择过大会造成震荡不收敛,过小会造成收敛速度慢,可以填一个较小的值填入,如0.01,0.001。

梯度下降的基本原理这里讲的比较好,以后再进行深入理解和公式的推导。

下面是搭建神经八股的完整代码

#coding:utf-8
import tensorflow as tf
import numpy as np
BATCH_SIZE=8
seed=23455

#基于seed产生随机数
rng=np.random.RandomState(seed)
#随机数返回32行2列的矩阵 表示32组 体积和重量  作为输入数据集
X=rng.rand(32,2)
#从X这个32行2列的矩阵中取出一行 判断如果和小于1 给Y赋值1  如果和不小于1   给Y赋值0
#作为输入数据集的标签(正确答案)
Y=[[int(x0+x1<1)] for (x0,x1) in X]
print('X:\n',X)
print('Y:\n',Y)

#定义神经网络的输入、参数和输出,定义前向传播过程
x  = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))

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.AdadeltaOptimizer(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))

    #训练模型
    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(s),loss on all data is %g"%(i,total_loss))
    #输出训练后的参数
    print('\n')
    print('w1:\n',sess.run(w1))
    print('w2:\n', sess.run(w2))

输出的结果为

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值