深度學習-神經網路基礎

Introduction

  • 神經網路是為了模擬神經元傳遞的過程
  • 不同結構的神經網路解決不同的問題

感知器(Perceptron)

有n個輸入數據,通過權重與各數據之間的計算和,比較激活函數結果,得出輸出

  • 應用:很容易解決與(and)、或(or)問題
  • 常用來解決分類問題
  • 一個感知器通常建立一條直線
    • 單個感知器解決不了的問題,可以增加感知機的數目

結構

Perceptron

  • 其中$f$為閾值(threshold)
    • 大於$f$或是小於$f$則屬於不同類別

神經網路的特點

neral network

  • 輸入向量的維度和輸入神經元的個數相同
  • 每個連接都有個權值
  • 同一層神經元之間沒有連接
  • 輸入層隱層輸出層組成
  • 下一層與前一層的所有神經元連接,也叫全連接(Dense Layer)
    其最後有多少全連接神經元,代表共有多少輸出類別

神經網路組成

  • 結構(Architecture):例如神經網路中權重、神經元等等
  • 激活函數(Activity Rule):
  • 學習規則(Learning Rule):學習規則指定了網路中的權重如何隨著時間推進而調整。(反向傳播算法)

神經網絡的多分類問題

輸入一個樣本,並得出這個樣本屬於全部每一個類別的概率,並比較哪個概率較大決定類別

  • 其有多少類別輸出就為多少個類別

神經網路API

在使用tensorflow時,tf.nntf.layerstf.contrib模塊有很多功能式重複的

tf.nn

提供神經網路相關操作的支持,包括卷積操作(conv)、池化操作(pooling)、歸一化、損失(loss)、分類操作、embedding、RNN、Evaluation

tf.layers

主要提供的高層神經網路,主要和卷積相關,對tf.nn進一步的封裝

tf.contrib(最高層的接口)

tf.contrib.layers提供夠將計算圖中的網絡層、正則化、摘要操作。是構建計算圖的高級操作,但是tf.contrib包不穩定以及擁有一些實驗性的代碼

SoftMax回歸

公式:

softmax

  • 其經過softmax後的結果類似邏輯回歸為一概率值
  • 所有類別的概率值相加都等於1
  • 真實類別的值為one-hot編碼形式

全連接-從輸入直接到輸出

  • 特徵加權:
    • tf.matmul(a, b, name=None) + $bias$
      • return: 全連接的結果,供交叉損失運算
      • 不需要激活函數(因為是最後的輸出)

神經網絡策略-交叉熵損失

類似邏輯回歸-對數似然損失的推廣

  • $y_{i}’$ 為真實結果,$y_i$為softmax後結果
  • 一個樣本就有一個交叉熵損失
  • softmax計算出來的概率值 越接近真實值類別onehot編碼的話 表示損失越小

SoftMax計算、交叉熵API

求所有樣本的損失,然後求平均損失

  • tf.nn.softmax_cross_entropy_with_logits(labels=None,logits=None, name=None)

    • 計算logits和labels之間的交叉損失熵
    • labels:標籤值(真實值)
    • logits:樣本加權之後的值(預測值)
    • return:返回損失列表
  • tf.reduce_mean(input_tensor)

    • 計算張量的尺寸的元素平均值

神經網絡優化-反向傳播算法

就是梯度下降

損失下降API

tf.train.GradientDescentOptimizer(learning_rate)

  • 用於梯度下降優化
  • learning_rate:學習率
  • minimize(loss):最小化損失
  • return:梯度下降op

準確率計算API

  1. equal_list = tf.equal(tf.argmax(y,1),tf.argmax(y_label,1))

    • 找尋特徵得到概率最大值的index,如果與onehot編碼label為1的index相同則為1,不同則為0
    • tf.argmax(data,row or column)
      • 返回data中的最大值index
      • 第二個參數為0代表取列中最大值的索引,1則為行中最大值的索引
  2. accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

mnist dataset的基本操作

https://github.com/curtis992250/MachineLearning_StudyNote/blob/master/mnist.ipynb

Example 單層(全連接層)實現手寫數字識別

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

# 定義命令行參數
FLAGS = tf.app.flags.FLAGS

tf.app.flags.DEFINE_integer("is_train",1,"指定程序為預測或是訓練模型")

def full_connected():

#獲取真實的數據
mnist = input_data.read_data_sets("./Training_Data/mnistData", one_hot=True)


# 1. 建立數據的佔位符 x[None, 781] y_true[None, 10]
with tf.variable_scope("data"):
x = tf.placeholder(tf.float32, [None,784])
y_true = tf.placeholder(tf.int32, [None,10])

# 2.建立一個全連接層的神經網絡 weight[784,10] bias[10]
with tf.variable_scope("full_connected_model"):
# 隨機初始化權重和偏置
weight = tf.Variable(tf.random_normal([784,10],mean=0.0, stddev=1.0,name="weight"))

bias = tf.Variable(tf.constant(0.0,shape=[10]))

# 預測None個樣本的輸出結果 x[None, 784] * w[784, 10] + b[10] = result[None,10]
y_predict = tf.matmul(x, weight) + bias

#3. 求出所有樣本的損失,然後求平均值
with tf.variable_scope("soft_cross"):

# 求平均交叉熵損失
loss_list = tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict)
loss = tf.reduce_mean(loss_list)

# 4. 梯度下降求出損失
with tf.variable_scope("optimizer"):
train_op = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(loss=loss)

# 5. 計算準確率
with tf.variable_scope("calc_accuracy"):

equal_list = tf.equal(tf.arg_max(y_true,1), tf.arg_max(y_predict,1))
# equal_list 應有None個樣本類似 [0,1,0,0,1,1,1,1,....]

accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

# 收集單個數字的變量
tf.summary.scalar("losses", loss)
tf.summary.scalar("accuracy", accuracy)

# 收集高維度的變量
tf.summary.histogram("weights", weight)
tf.summary.histogram("biases",bias)

# 定義一個初始化變量的op
init_op = tf.global_variables_initializer()

# 定義一個合併變量的op
merged = tf.summary.merge_all()

# 創建一個saver用於保存模型(Save, restore方法)
saver = tf.train.Saver()


# 開啟會話訓練
with tf.Session() as sess:
#初始化變量
sess.run(init_op)

# 建立events文件然後寫入
filewriter = tf.summary.FileWriter("./summary/number_recognize",graph=sess.graph)

if FLAGS.is_train == True:

#迭代步數去訓練,更新參數預測
for i in range(2000):

#取出真實存在的特徵值和目標值
mnist_x, mnist_y = mnist.train.next_batch(50)

#運行train_op訓練
sess.run(train_op, feed_dict={x: mnist_x,y_true: mnist_y})

# 寫入每步訓練的值
summary = sess.run(merged, feed_dict={x: mnist_x,y_true: mnist_y})

filewriter.add_summary(summary,i)


print("訓練第%d步,準確率為:%f"%(i,sess.run(accuracy, feed_dict={x: mnist_x,y_true: mnist_y})))

else:
# 訓練結束後保存模型
saver.save(sess,"./ckpt/fc_model")

else:
# 加載模型
saver.restore(sess,"./ckpt/fc_model")

# 要是is_train為則做出預測
for i in range(100):

#每次測試一張圖片[0,0,0,0,0,0,1,0,0,0]
x_test, y_test = mnist.test.next_batch(1)

print("第%d張圖片,手寫數字圖片為%d,預測結果是:%d"%(i,
tf.argmax(y_test,1).eval(),
tf.argmax(sess.run(y_predict,feed_dict={x: x_test,y_true: y_test}),1).eval()
))

if __name__ == '__main__':
full_connected()