zoukankan      html  css  js  c++  java
  • CH5 用神经网络解决线性问题

    • 了解非线性问题、分类问题
    • 掌握神经网络解决二分类问题
    • 掌握随机生成训练数据的方法

    非线性问题

    三好学生问题:家长们再次凑到一起,但这次情况不一样了,孩子们的总分不知道,仅知道是否评选上三好学生的结果。

    计算总分的规则仍然是:总分 = 德育分*60% + 智育分*30% + 体育分*10%
    评选三好学生的标准是:总分 ≥ 95

    家长不知道这两条规则。

    这是一个典型的分类问题。学校一定是以德育分、智育分和体育分三项分数为依据,把学生们分成两类:三好学生和非三好学生。因此,这是一个常见的二分类问题。下图是用神经网络简述二分类问题。

    image

    分类问题一般是非线性的。

    • 可以看出,当总分达到95之后,y值有一个跳变,并非线性的(一条直线)
    • y=f(xA),跳变函数/阶跃函数
    • “一票否决制”

    image

    设计神经网络模型

    总分(0~100)= 德育分60% + 智育分30% + 体育分*10% -> 评选结果(0、1)

    激活函数:把线性关系转换成非线性关系的函数。激活函数 sigmoid 函数的作用是把参数转换成为 0 到 1 之间的一个小数。

    image

    使用激活函数后的神经网络模型:

    image

    实现该网络模型的代码:

    # import tensorflow as tf
    import tensorflow.compat.v1 as tf
    
    tf.compat.v1.disable_eager_execution()
    
    x = tf.placeholder(dtype=tf.float32)
    yTrain = tf.placeholder(dtype=tf.float32)
    w = tf.Variable(tf.zeros([3]), dtype=tf.float32)
    
    n1 = w * x
    n2 = tf.reduce_sum(n1)
    
    y = tf.nn.sigmoid(n2)
    

    准备训练数据

    使用 random 产生随机数

    import random
    
    random.seed() # 初始化随机数种子,增加随机性
    random.random() # 产生一个 [0,1) 范围内的小数
    
    r = random.random() * 10 # 通过乘以一个整数,使产生的随机数的范围增大,此处范围为 [0,10)
    

    产生随机训练数据

    import random
    
    random.seed()
    
    # 产生一个 [0,100] 范围内的整数代表某一科分数
    xData = [int(random.random() * 101),int(random.random() * 101),int(random.random() * 101)]
    
    # 按规则生成总分
    xAll = xData[0] * 0.6 + xData[1] * 0.3 + xData[2] * 0.1
    
    # 按规则生成评选结果
    if xAll >= 95:
        yTrainData = 1
    else:
        yTrainData = 0
    
    print("xData: %s" %xData)
    print("yTrainData: %s" %yTrainData)
    

    image

    优化产生的训练数据,产生一个[60,101) 范围内的更合理的分数:

    xData = [
        int(random.random() * 41 + 60),
        int(random.random() * 41 + 60),
        int(random.random() * 41 + 60)
    ]
    

    image

    产生更多结果为 1 的训练数据,产生一个[93,101)范围内的符合三好学生要求的分数:

    xData = [
        int(random.random() * 8 + 93),
        int(random.random() * 8 + 93),
        int(random.random() * 8 + 93)
    ]
    

    为什么要使用随机数据来训练神经网络:

    • 并非“剧透”,用于演示和验证
    • 符合人工收集的规贝
    • 满足神经网络大规模训练的需要

    训练

    # import tensorflow as tf
    import tensorflow.compat.v1 as tf
    import random
    
    tf.compat.v1.disable_eager_execution()
    
    random.seed()
    
    x = tf.placeholder(dtype=tf.float32)
    yTrain = tf.placeholder(dtype=tf.float32)
    w = tf.Variable(tf.zeros([3]), dtype=tf.float32)
    
    wn = tf.nn.softmax(w)
    
    n1 = wn * x
    
    n2 = tf.reduce_sum(n1)
    y = tf.nn.sigmoid(n2)
    loss = tf.abs(yTrain - y)
    
    optimizer = tf.train.RMSPropOptimizer(0.1)
    train = optimizer.minimize(loss)
    
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    
    for i in range(5):
        xData = [
            int(random.random() * 8 + 93),
            int(random.random() * 8 + 93),
            int(random.random() * 8 + 93)
        ]
    
        xAll = xData[0] * 0.6 + xData[1] * 0.3 + xData[2] * 0.1
    
        if xAll >= 95:
            yTrainData = 1
        else:
            yTrainData = 0
    
        result = sess.run(
            [train, x, yTrain, w, n2, y, loss], 
            feed_dict={x:xData, yTrain:yTrainData}
        )
    
        print(result)
    
        xData = [
            int(random.random() * 41 + 60),
            int(random.random() * 41 + 60),
            int(random.random() * 41 + 60)
        ]
    
        xAll = xData[0] * 0.6 + xData[1] * 0.3 + xData[2] * 0.1
    
        if xAll >= 95:
            yTrainData = 1
        else:
            yTrainData = 0
    
        result = sess.run(
            [train, x, yTrain, w, n2, y, loss],
            feed_dict={x:xData, yTrain:yTrainData}
        )
    
        print(result)
    

    观察训练结果:

    image

    增加偏移量 b 来加速训练:

    + b = tf.Variable(80, dtype=tf.float32)
    - n2 = tf.reduce_sum(n1)
    + n2 = tf.reduce_sum(n1) - b
    
    # import tensorflow as tf
    import tensorflow.compat.v1 as tf
    import random
    
    tf.compat.v1.disable_eager_execution()
    
    random.seed()
    
    x = tf.placeholder(dtype=tf.float32)
    yTrain = tf.placeholder(dtype=tf.float32)
    w = tf.Variable(tf.zeros([3]), dtype=tf.float32)
    b = tf.Variable(80, dtype=tf.float32)
    
    wn = tf.nn.softmax(w)
    
    n1 = wn * x
    n2 = tf.reduce_sum(n1) - b
    
    y = tf.nn.sigmoid(n2)
    loss = tf.abs(yTrain - y)
    
    optimizer = tf.train.RMSPropOptimizer(0.1)
    train = optimizer.minimize(loss)
    
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    
    for i in range(5):
        xData = [
            int(random.random() * 8 + 93),
            int(random.random() * 8 + 93),
            int(random.random() * 8 + 93)
        ]
    
        xAll = xData[0] * 0.6 + xData[1] * 0.3 + xData[2] * 0.1
    
        if xAll >= 95:
            yTrainData = 1
        else:
            yTrainData = 0
    
        result = sess.run(
            [train, x, yTrain, w, n2, y, loss], 
            feed_dict={x:xData, yTrain:yTrainData}
        )
    
        print(result)
    
        xData = [
            int(random.random() * 41 + 60),
            int(random.random() * 41 + 60),
            int(random.random() * 41 + 60)
        ]
    
        xAll = xData[0] * 0.6 + xData[1] * 0.3 + xData[2] * 0.1
    
        if xAll >= 95:
            yTrainData = 1
        else:
            yTrainData = 0
    
        result = sess.run(
            [train, x, yTrain, w, n2, y, loss],
            feed_dict={x:xData, yTrain:yTrainData}
        )
    
        print(result)
    

    image

    - b = tf.Variable(80, dtype=tf.float32)
    + b = tf.Variable(95, dtype=tf.float32)
    

    image

    批量产生随机训练数据:

    import random
    import numpy as np
    
    tf.compat.v1.disable_eager_execution()
    
    random.seed()
    
    rowCount = 5
    
    xData = np.full(
        shape=(rowCount, 3),
        fill_value=0,
        dtype=np.float32
    )
    
    yTrainData = np.full(
        shape=rowCount,
        fill_value=0,
        dtype=np.float32
    )
    
    for i in range(rowCount):
        xData[i][0] = int(random.random() * 11 + 90)
        xData[i][1] = int(random.random() * 11 + 90)
        xData[i][2] = int(random.random() * 11 + 90)
    
        xAll = xData[i][0] * 0.6 + xData[i][0] * 0.3 + xData[i][2] * 0.1
    
    • numpy 是常用于数学计算的类库
    • npful 函数用于向数组中填充初始数值
    • 使用循环来生成批量的数据
    # import tensorflow as tf
    import tensorflow.compat.v1 as tf
    import random
    import numpy as np
    
    tf.compat.v1.disable_eager_execution()
    
    random.seed()
    
    rowCount = 5
    
    xData = np.full(
        shape=(rowCount, 3),
        fill_value=0,
        dtype=np.float32
    )
    
    yTrainData = np.full(
        shape=rowCount,
        fill_value=0,
        dtype=np.float32
    )
    
    goodCount = 0
    
    for i in range(rowCount):
        xData[i][0] = int(random.random() * 11 + 90)
        xData[i][1] = int(random.random() * 11 + 90)
        xData[i][2] = int(random.random() * 11 + 90)
    
        xAll = xData[i][0] * 0.6 + xData[i][1] * 0.3 + xData[i][2] * 0.1
    
        if xAll >= 95:
            yTrainData[i] = 1
            goodCount = goodCount + 1
        else:
            yTrainData[i] = 0
    
    print("xData=%s" %xData)
    print("yTrainData=%s" %yTrainData)
    print("goodCount=%s" %goodCount)
    
    x = tf.placeholder(dtype=tf.float32)
    yTrain = tf.placeholder(dtype=tf.float32)
    w = tf.Variable(tf.zeros([3]), dtype=tf.float32)
    b = tf.Variable(80, dtype=tf.float32)
    
    wn = tf.nn.softmax(w)
    
    n1 = wn * x
    n2 = tf.reduce_sum(n1) - b
    
    y = tf.nn.sigmoid(n2)
    loss = tf.abs(yTrain - y)
    
    optimizer = tf.train.RMSPropOptimizer(0.1)
    train = optimizer.minimize(loss)
    
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    
    for i in range(2):
        for j in range(rowCount):
            result = sess.run(
                [train, x, yTrain, wn, b, n2, y, loss],
                feed_dict={x:xData[j], yTrain:yTrainData[j]}
            )
            print(result)
    

    image

    可以看到,xData 是一个二维数组,其中包含了 5 条数据,每条是 3 项符合定义范围的分数。tTrainData 中包含 3 个 1,也就是说有 3 位学生符合三好学生的条件,接下来输出的 goodCount 也确实等于 3,再往下的训练也一切正常。

    练习

    1. 编程生成 5 [-20,20) 范围内的随机数,并用 TensorFlow 设法求出这些数字进行 sigmoid 操作后的结果。

      import tensorflow as tf
      import random
      
      a = tf.placeholder(dtype=tf.float32)
      b = tf.nn.sigmoid(a)
      sess = tf.Session()
      
      for i in range(5):
      	print(sess.run(b, feed_dict={a: random.random() * 40 - 20}))
      
    2. 编程解决下述非线性问题

      • 输入数据 [1,1,1],输出目标值:2
      • 输入数据 [1,0,1],输出目标值:1
      • 输入数据 [1,2,3],输出目标值:3
      import tensorflow as tf
      
      x = tf.placeholder(shape=[3], dtype=tf.float32)
      yTrain = tf.placeholder(shape=[], dtype=tf.float32)
      
      w = tf.Variable(tf.zeros([3]), dtype=tf.float32)
      b = tf.Variable(0, dtype=tf.float32)
      y = tf.reduce_sum(tf.nn.sigmoid(x * w + b))
      
      loss = tf.abs(y - yTrain)
      optimizer = tf.train.RMSPropOptimizer(0.1)
      train = optimizer.minimize(loss)
      
      sess = tf.Session()
      sess.run(tf.global_variables_initializer())
      
      for i in range(1000):
      	print(sess.run([train, y, yTrain, loss], feed_dict={x: [1, 1, 1], yTrain: 2}))
      	print(sess.run([train, y, yTrain, loss], feed_dict={x: [1, 0, 1], yTrain: 1}))
      	print(sess.run([train, y, yTrain, loss], feed_dict={x: [1, 2, 3], yTrain: 3}))
      
  • 相关阅读:
    Codeforces-799C-Fountains(分类讨论+线段树)
    HDU-3486-Interviewe(二分+RMQ)
    小技巧---查doc文档的index.html怎么用的和chm一样
    chm文件右边部分查看不了
    最长公共临时文档7
    拓展欧几里得临时文档5
    关于myeclipse代码提示的一些问题
    mysql--乱码
    三分--Football Goal(面积最大)
    printf的一个常用技巧
  • 原文地址:https://www.cnblogs.com/guangzan/p/15367125.html
Copyright © 2011-2022 走看看