CH4 簡化神經網絡模型

  1. 掌握標量、向量、張量等概念
  2. 掌握如何用向量形式簡化神經網絡結構並編程實現
  3. 瞭解線性問題

標量、向量、張量

張量

在上一章的代碼中添加 print 函數:

代碼
# import tensorflow as tf
import tensorflow.compat.v1 as tf

tf.disable_v2_behavior()

x1 = tf.placeholder(dtype = tf.float32)
x2 = tf.placeholder(dtype = tf.float32)
x3 = tf.placeholder(dtype = tf.float32)

yTrain = tf.placeholder(dtype = tf.float32)

print("x1: %s" %x1)

w1 = tf.Variable(0.1, dtype = tf.float32)
w2 = tf.Variable(0.1, dtype = tf.float32)
w3 = tf.Variable(0.1, dtype = tf.float32)

print("w1: %s" %w1)

n1 = x1 * w1
n2 = x2 * w2
n3 = x3 * w3

print("n1: %s" %n1)

y = n1 + n2 + n3

print("y: %s" %y)

loss = tf.abs(y - yTrain)
optimizer = tf.train.RMSPropOptimizer(0.001)
train = optimizer.minimize(loss)

sess = tf.Session()
# init = tf.global_variable_initializer()
init = tf.compat.v1.global_variables_initializer()

sess.run(init)

result = sess.run([train, x1, x2, x3, w1, w2, w3, y, yTrain], feed_dict={x1: 90, x2: 80, x3: 70, yTrain: 96})
print(result)

輸出結果:

image

Placeholder:0 數字代表操作結果的編號(可能有多個輸出結果)。x1 是 Tensor 對象。神經網絡中,輸入節點,隱藏層節點,輸出節點都是張量。w1 是 Variable 對象(可變參數對象)。在神經網絡中,參與節點運算的可變參數(權重)不是 Tensor 對象。

上一章引入的 “三好學生問題” 神經網絡模型:

image

n1 = x1 * w1
# n1: Tensor("mul:0", dtype=float32)

Tensor(張量):包含 了對於輸入數據的計算操作;容納了一個(或一組)數據,即輸出數據。

w1 = tf.Variable(0.1, dtype = tf.float32)
# w1: <tf.Variable 'Variable:0' shape=() dtype=float32_ref>

可變參數不是模型中節點的輸出數據,會參與到某個神經元的計算。

總結:

  • 張量( Tensor)就是神經網絡中神經元節點接收輸入數據後經過一定計算操作輸出的結果對象;
  • 張量( Tensor)在神經網絡模型圖中表現爲各層的節點的輸出節點加上連線所組成的整個神經網絡模型圖標表現的是張量在神經網絡中 “流動(flow)” 的過程;
  • 張量( Tensor)在程序中的具體表現是一個 Tensor 類型的對象。

向量和標量

向量:一串數字,程序中用一個數組表示例如:[90,80,70]

  1. 數組有順序
  2. 根據數字判斷向量維數

image

總結:

  • 張量可以是一個標量,即一個數值
  • 張量可以是一個向量,即一個一維數組
  • 張量也可以是一個多維數組,來表達二維矩陣、三維矩陣甚至更多
  1. 張量的 ** 階 ** 是指這個多維數組的維度數
  2. 張量的 ** 形態 ** 是指用一維數組表示的張量在各個維度上的數值數量(shape,表達張量中存儲的數據的形式)

image

image

注意:一維數組:[90,80,70],形態 [3],只有一個維度,頂數 3,一階;標量:統一用一個空數組便是形態 [] 或者 (),0 階 ...

代碼查看形態結果

import tensorflow as tf

x = tf.placeholder(dtype = tf.float32)
xShape = tf.shape(x) # tf.shape() 函數用於獲取張量的形態

簡化神經網絡

用向量重新組織神經網絡:

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)
n = x * w
y = tf.reduce_sum(n)

loss = tf.abs(y - yTrain)
optimizer = tf.train.RMSPropOptimizer(0.001)
train = optimizer.minimize(loss)

sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x: [90, 80, 70], yTrain: 85})
print(result)

result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x:[98, 95, 87], yTrain: 96})
print(result)
  • x: shape=[0] 表示 x 的形態,取值爲 3,表示輸入佔位符的數據是一個三維向量
  • w: tf.zeros([3]),返回數組 [0,0,0],初始化
  • yTrain: [], 標量
  • n: 點乘
  • tf.reduce_sum(): 將數組中所有數組相加求和得到一個標量 y
result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x: [90, 80, 70], yTrain: 85})
print(result)

喂數據時,yTrain: 85 目標值送入的是 ** 標量形式 ** 的數據, x: [90, 80, 70] 送入 x 的是 ** 向量形式 ** 的輸入數據。

代碼
# import tensorflow as tf
import tensorflow.compat.v1 as tf

tf.compat.v1.disable_eager_execution()

x = tf.placeholder(shape=[3], dtype=tf.float32)
yTrain = tf.placeholder(shape=[], dtype=tf.float32)
w = tf.Variable(tf.zeros([3]), dtype=tf.float32)
n = x * w
y = tf.reduce_sum(n)

loss = tf.abs(y - yTrain)
optimizer = tf.train.RMSPropOptimizer(0.001)
train = optimizer.minimize(loss)

sess = tf.Session()
# init = tf.global_variable_initializer()
init = tf.compat.v1.global_variables_initializer()
sess.run(init)

result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x: [90, 80, 70], yTrain: 85})
print(result)

result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x:[98, 95, 87], yTrain: 96})
print(result)

image

注意: 向量形式在計算機中用的是數組來表達。

循環進行多次訓練:

代碼
# import tensorflow as tf
import tensorflow.compat.v1 as tf

tf.compat.v1.disable_eager_execution()

x = tf.placeholder(shape=[3], dtype=tf.float32)
yTrain = tf.placeholder(shape=[], dtype=tf.float32)
w = tf.Variable(tf.zeros([3]), dtype=tf.float32)
n = x * w
y = tf.reduce_sum(n)

loss = tf.abs(y - yTrain)
optimizer = tf.train.RMSPropOptimizer(0.001)
train = optimizer.minimize(loss)

sess = tf.Session()
# init = tf.global_variable_initializer()
init = tf.compat.v1.global_variables_initializer()
sess.run(init)

for i in range(5000):
    result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x: [90, 80, 70], yTrain: 85})
    print(result)

    result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x:[98, 95, 87], yTrain: 96})
    print(result)

image

誤差被有效控制,運行結果基本一致(與 ch3 中的代碼比較)。

簡化的神經網絡圖:

image

用 Softmax 函數來規範可變參數

Softmax 函數:將一個向量規範化爲一個所有數值相加和爲 1 的新向量。

三好學生問題,幾項分數的權重值之和一定爲 100%,也就是 1.0。

w = tf.Variable(tf.zeros([3]), dtype = tf.float32)
wn = tf.nn.softmax(2)
n = x * wn
y = tf.reduce_sum(n)

nn(neural network) 是 TensorFlow 重要子類。

代碼
# import tensorflow as tf
import tensorflow.compat.v1 as tf

tf.compat.v1.disable_eager_execution()

x = tf.placeholder(shape=[3], dtype=tf.float32)
yTrain = tf.placeholder(shape=[], dtype=tf.float32)
w = tf.Variable(tf.zeros([3]), dtype=tf.float32)

wn = tf.nn.softmax(w)
n = x * wn
y = tf.reduce_sum(n)

loss = tf.abs(y - yTrain)
optimizer = tf.train.RMSPropOptimizer(0.001)
train = optimizer.minimize(loss)

sess = tf.Session()
# init = tf.global_variable_initializer()
init = tf.compat.v1.global_variables_initializer()
sess.run(init)

for i in range(5000):
    result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x: [90, 80, 70], yTrain: 85})
    print(result)

    result = sess.run([train, x, w, y, yTrain, loss], feed_dict={x:[98, 95, 87], yTrain: 96})
    print(result)

線性問題

image

線性問題:用圖形來表達輸入數值和輸出數值的關係,在座標系中將是一條直線。

image

增加了偏移量 b 後,可以表達更多的線性問題(適應性)

知識補充

Python 中的 print

# 按字符串輸出
name = "Adam"
print("name: %s" %name)

# 按整數輸出
x = 101
print("x: %d" %x)

# 按浮點數輸出
y = 12.35
print("y: %f" %y)

image

矩陣

image

多維數組

x1 = [90, 80, 70]
x2 = [98, 95, 87]
xAll = [x1, x2]

xAll = [[90, 80, 70], [98, 95, 87]], xAll 稱爲 2x3 的二維數組。

image

點乘

image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章