zoukankan      html  css  js  c++  java
  • 模块化神经网络

    在前面的学习中,已经学习了最基本的神经网络搭建过程,现在来总结一下,将神经网络的搭建形成模块化。

            前向传播:由输入到输出,搭建完整的网络结构 。即搭建模型的计算过程,可以根据输入给出相应的输出。

    描述前向传播的过程需要定义三个函数

    1.

                             def forward(x, regularizer): 

                              w=
                              b=
                              y=
                              return y
    第一个函数 forward()完成网络结构的设计,从输入到输出搭建完整的网络结构,实现前向传播过程。该函数中,参数 x 为输入,regularizer 为正则化权重,返回值为预测或分类结果 y。

    2.

                       def get_weight(shape, regularizer):
                       w = tf.Variable( )
                       tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w))
                       return w

    第二个函数 get_weight()对参数 w 设定。该函数中,参数 shape 表示参数 w 的形状,regularizer表示正则化权重,返回值为参数 w。其中,tf.variable()给 w 赋初值,tf.add_to_collection()表示将参数 w 正则化损失加到总损失 losses 中。 

    3.
                            def get_bias(shape):
                            b = tf.Variable( )
                            return b
    第三个函数 get_bias()对参数 b 进行设定。该函数中,参数 shape 表示参数 b 的形状,返回值为参数b。其中,tf.variable()表示给 w 赋初值。 

    反向传播:训练网络,优化网络参数,提高模型准确性。
                     def backward( ):
                      x = tf.placeholder( )
                      y_ = tf.placeholder( )
                      y = forward.forward(x, REGULARIZER)
                      global_step = tf.Variable(0, trainable=False)
                     loss =
    函数 backward()中,placeholder()实现对数据集 x 和标准答案 y_占位,forward.forward()实现前向传播的网络结构,参数 global_step 表示训练轮数,设置为不可训练型参数。 


    在训练网络模型时,常将正则化、指数衰减学习率和滑动平均这三个方法作为模型优化方法。
                在 Tensorflow 中,正则化表示为:
                      首先,计算预测结果与标准答案的损失值
                             ①MSE: y 与 y_的差距(loss_mse) = tf.reduce_mean(tf.square(y-y_))
                            ②交叉熵:ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
                                              y 与 y_的差距(cem) = tf.reduce_mean(ce)
                           ③自定义:y 与 y_的差距
                  其次,总损失值为预测结果与标准答案的损失值加上正则化项
                              loss = y 与 y_的差距 + tf.add_n(tf.get_collection('losses'))
    在 Tensorflow 中,指数衰减学习率表示为:
                    learning_rate = tf.train.exponential_decay(
                                              LEARNING_RATE_BASE,
                                              global_step,
                                             数据集总样本数 / BATCH_SIZE,
                                             LEARNING_RATE_DECAY, staircase=True)
                    train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,
                    global_step=global_step)
    在 Tensorflow 中,滑动平均表示为:
                   ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
                   ema_op = ema.apply(tf.trainable_variables())
                  with tf.control_dependencies([train_step, ema_op]):
                  train_op = tf.no_op(name='train')
     其中,滑动平均和指数衰减学习率中的 global_step 为同一个参数。
    用 with 结构初始化所有参数
                     with tf.Session() as sess:
                     init_op = tf.global_variables_initializer()
                    sess.run(init_op)
                     for i in range(STEPS):
                     sess.run(train_step, feed_dict={x: , y_: })
                    if i % 轮数 == 0:
                   print
    其中,with 结构用于初始化所有参数信息以及实现调用训练过程,并打印出 loss 值。
    判断 python 运行文件是否为主文件
              if __name__=='__main__':
              backward()
    该部分用来判断 python 运行的文件是否为主文件。若是主文件,则执行 backword()函数。
    例如: 
    用 300 个符合正态分布的点 X[x0, x1]作为数据集,根据点 X[x0, x1]的不同进行标注 Y_,将数据集标注为红色和蓝色。标注规则为:当 x02 + x12 < 2 时,y_=1,点 X 标注为红色;当 x02 + x12 ≥2 时,
    y_=0,点 X 标注为蓝色。我们加入指数衰减学习率优化效率,加入正则化提高泛化性,并使用模块化
    设计方法,把红色点和蓝色点分开。 
    代码总共分为三个模块:生成数据集(generateds.py)、前向传播(forward.py)、反向传播(backward.py)。
               ①生成数据集的模块(generateds.py) 
       

    #coding:utf-8
    #生成模拟数据集
    import numpy as np
    import matplotlib.pyplot as plt
    seed = 2 
    def generateds():
        #基于seed产生随机数
        rdm = np.random.RandomState(seed)
        #随机数返回300行2列的矩阵,表示300组坐标点(x0,x1)作为输入数据集
        X = rdm.randn(300,2)
        #从X这个300行2列的矩阵中取出一行,判断如果两个坐标的平方和小于2,给Y赋值1,其余赋值0
        #作为输入数据集的标签(正确答案)
        Y_ = [int(x0*x0 + x1*x1 <2) for (x0,x1) in X]
        #遍历Y中的每个元素,1赋值'red'其余赋值'blue',这样可视化显示时人可以直观区分
        Y_c = [['red' if y else 'blue'] for y in Y_]#对应颜色Y_c
        #对数据集X和标签Y进行形状整理,第一个元素为-1表示跟随第二列计算,第二个元素表示多少列,可见X为两列,Y为1列
        X = np.vstack(X).reshape(-1,2)#整理形状
        Y_ = np.vstack(Y_).reshape(-1,1)#整理形状
        
        return X, Y_, Y_c
        
    #print X
    #print Y_
    #print Y_c
    #用plt.scatter画出数据集X各行中第0列元素和第1列元素的点即各行的(x0,x1),用各行Y_c对应的值表示颜色(c是color的缩写) 
    #plt.scatter(X[:,0], X[:,1], c=np.squeeze(Y_c)) 
    #plt.show()

          ②前向传播模块(forward.py) 

    #coding:utf-8
    #前向传播就是搭建网络
    import tensorflow as tf
    
    #定义神经网络的输入、参数和输出,定义前向传播过程 
    def get_weight(shape, regularizer):#(shape:W的形状,regularizer正则化)
        w = tf.Variable(tf.random_normal(shape), dtype=tf.float32)#赋初值,正态分布权重
        tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w))#把正则化损失加到总损失losses中
        return w#返回w
    #tf.add_to_collection(‘list_name’, element):将元素element添加到列表list_name中
    
    def get_bias(shape):  #偏执b
        b = tf.Variable(tf.constant(0.01, shape=shape)) #偏执b=0.01
        return b#返回值
        
    def forward(x, regularizer):#前向传播
        
        w1 = get_weight([2,11], regularizer)#设置权重    
        b1 = get_bias([11])#设置偏执
        y1 = tf.nn.relu(tf.matmul(x, w1) + b1)#计算图
    
        w2 = get_weight([11,1], regularizer)#设置权重
        b2 = get_bias([1])#设置偏执
        y = tf.matmul(y1, w2) + b2 #计算图
        
        return y#返回值
    #③反向传播模块(backward.py)
    #
    coding:utf-8 #0导入模块 ,生成模拟数据集 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import opt4_8_generateds import opt4_8_forward STEPS = 40000 BATCH_SIZE = 30 LEARNING_RATE_BASE = 0.001 LEARNING_RATE_DECAY = 0.999 REGULARIZER = 0.01#正则化 def backward():#反向传播 x = tf.placeholder(tf.float32, shape=(None, 2))#占位 y_ = tf.placeholder(tf.float32, shape=(None, 1))#占位 #X:300行2列的矩阵。Y_:坐标的平方和小于2,给Y赋值1,其余赋值0 X, Y_, Y_c = opt4_8_generateds.generateds() y = opt4_8_forward.forward(x, REGULARIZER)#前向传播计算后求得输出y global_step = tf.Variable(0,trainable=False)#轮数计数器 #指数衰减学习率 learning_rate = tf.train.exponential_decay( LEARNING_RATE_BASE,#学习率 global_step,#计数 300/BATCH_SIZE, LEARNING_RATE_DECAY,#学习衰减lü staircase=True)#选择不同的衰减方式 #定义损失函数 loss_mse = tf.reduce_mean(tf.square(y-y_))#均方误差 loss_total = loss_mse + tf.add_n(tf.get_collection('losses'))#正则化 #定义反向传播方法:包含正则化 train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss_total) with tf.Session() as sess: init_op = tf.global_variables_initializer()#初始化 sess.run(init_op)#初始化 for i in range(STEPS): start = (i*BATCH_SIZE) % 300 end = start + BATCH_SIZE#3000轮 sess.run(train_step, feed_dict={x: X[start:end], y_:Y_[start:end]}) if i % 2000 == 0: loss_v = sess.run(loss_total, feed_dict={x:X,y_:Y_}) print("After %d steps, loss is: %f" %(i, loss_v)) xx, yy = np.mgrid[-3:3:.01, -3:3:.01]#网格坐标点 grid = np.c_[xx.ravel(), yy.ravel()] probs = sess.run(y, feed_dict={x:grid}) probs = probs.reshape(xx.shape) plt.scatter(X[:,0], X[:,1], c=np.squeeze(Y_c)) #画点 plt.contour(xx, yy, probs, levels=[.5])#画线 plt.show()#显示图像 if __name__=='__main__': backward()

    由运行结果可见,程序使用模块化设计方法,加入指数衰减学习率,使用正则化后,红色点和蓝色点的分割曲线相对平滑,效果变好

  • 相关阅读:
    (一)单例模式
    mysql数据库知识
    JavaScript
    Spring整合AspectJ的AOP
    Spring-AOP
    JDK代理和CGLIB代理
    mybatis-dao开发
    mybatis-入门
    CSS2.1
    HTML基础
  • 原文地址:https://www.cnblogs.com/fcfc940503/p/10970233.html
Copyright © 2011-2022 走看看