05基於python玩轉人工智能最火框架之TensorFlow基礎知識

從helloworld開始

mkdir mooc # 新建一個mooc文件夾
cd mooc
mkdir 1.helloworld # 新建一個helloworld文件夾
cd 1.helloworld
touch helloworld.py
# -*- coding: UTF-8 -*-

# 引入 TensorFlow 庫
import tensorflow as tf

# 建立一個 Constant(常量)Operation(操做)
hw = tf.constant("Hello World! I love TensorFlow!")  # 我愛 TensorFlow

# 啓動一個 TensorFlow 的 Session(會話)
sess = tf.Session()

# 運行 Graph(計算圖)
print(sess.run(hw))

# 關閉 Session(會話)
sess.close()

 

TensorFlow的編程模式java

mark

命令式編程:python

  • 容易理解,命令語句基本沒優化: C,java, C++, Pythonc++

mark

符號式編程:git

  • 涉及較多的嵌入和優化,運行速度有同比提高github

mark

計算流圖。c和d是能夠共用內存的。有必定優化。算法

mark

TensorFlow的計算流圖,符號式編程的範式。有節點有邊,邊是計算結果在節點中流動。數據庫

TensorFlow的基礎結構

Tensor 在 計算流圖中流動(flow)編程

mark

這張圖簡化一下,取其中一部分。api

mark

邊就是Tensor(張量)在流動數組

mark

節點就是一個operation操做,數學計算或後面的激勵函數等的操做。

節點的輸入與輸出都是Tensor張量。

邊和節點共同構成了Graph 也就是數據流圖。

數據流圖會被放進session會話中進行運行。會話能夠在不一樣的設備上去運行,好比cpu和GPU。

圖的基本構成

數據流圖:

  • Tensor (張量) 邊裏流動的數據

  • Operation(操做)

mark

Tensor 會做爲operation的輸入,operation輸出的依然是Tensor

TensorFlow的基礎模型

數據模型  - Tensor(張量)

張量是TensorFlow中最重要的結構。

計算模型 - Graph(圖)

運行模型 - Session(會話)

mark

圖(Graph)與會話(Session)

mark

計算流圖,也是TensorFlow的基本架構,代表了圖正在運行的狀態。

黑色的線不斷流動, 其中流動的就是Tensor,一個一個的節點就是它的操做

數據流圖的結構

mark

mark

燒杯中進行的化學反應就是操做,其中流動的就是張量。

mark

什麼是會話(Session)?

火狐打開一個瀏覽器就是打開了一個會話。

mark

使用x,y,z三行構建了一個圖,構建了一個實驗儀器。

TensorFlow使用了客戶端和服務端的經典架構。

客戶端是咱們編寫的程序,程序請求服務端(C++)的運行時。
建立一個會話,使用會話中的run方法。

Session的做用

靜態的圖。數據流圖

如何讓某一部分動起來?

須要點燃酒精燈。

mark

要讓這一部分運行起來。就得run

mark

TensorFlow程序的流程

  1. 定義算法的計算圖(Graph)的結構 靜態

  2. 使用會話(Session) 執行計算

python經常使用庫numpy

TensorFlow和numpy有必定聯繫

  • 有不少相似的概念和api

介紹Tensor時,有不少api名稱很類似

numpy官網,科學計算。n階數組對象。

numpy速度是很是快的,比原生快不少。

由於numpy的許多函數是用c語言來實現的。還使用了一些優化,甚至比你本身用c實現快不少。

scipy 是一個開源軟件。Matplotlib。pandas。jupyter notebook

numpy的操做對象是一個多維的數組。相似Tensor

ndarray ndim shape size dtype(同一類型元素)

import numpy as np
vector = np.array([1,2,3])
vector.shape
vector.size
vector.ndim
type(vector)# 建立二維數組(矩陣)matrix = np.array([[1, 2],[3, 4]])
matrix.shape
matrix.size
matrix.ndim
type(matrix)

對於矩陣進行轉置

one = np.arange(12)# 0 - 11one.reshape((3,4))
two = one.reshape((3,4))

two.shape
two.size
two.ndim

什麼是Tensor(張量)?

不斷流動的東西就是張量。節點就是operation計算

mark

TensorFlow裏的數據都是Tensor,因此它能夠說是一個張量的流圖

mark

張量的維度(秩): Rank / Order dimension

mark

維度是0的話,是一個標量(Scalar)

vector & Matrix

numpy中的基礎要素就是array,和Tensor 差很少的一種表述。

import numpy as np
zeros = np.zeros((3,4))
zeros

ones = np.ones((5,6))
ones# 對角矩陣: 必須是一個方陣.對角線是1,其餘都是0的方陣ident = np.eye(4)

mark

一個張量裏面的元素類型都是同樣的。

mark

Tensor 的屬性

由於一個tensor 只能包含一種數據類型。dtype

TensorFlow.datatype list

https://www.tensorflow.org/api_docs/python/tf/DType

mark

TensorFlow數據類型有不少。

其餘屬性:

https://www.tensorflow.org/api_docs/python/tf/Tensor

能夠經過搜索Tensor 查看到它的其餘屬性。

A Tensor是一個輸出的符號句柄 Operation。它不包含該操做輸出的值,而是提供了在TensorFlow中計算這些值的方法tf.Session。

device,在哪一個設備上被計算出來的。

Graph 這個Tensor 所屬的一個圖

name 是咱們能夠給張量起的名字

op 是產生這個Tensor 的一個操做

幾種Tensor

  • Constant

  • Variable

  • Placeholder

  • SparseTensor

Constant (常量)

  • 值不能改變的一種Tensor

但取這個Tensor值有可能仍是會變

定義在tf.constant類

tf.constant(
    value,
    dtype=None,
    shape=None,
    name='Const',
    verify_shape=False)

數值:標量,向量,矩陣

verify_shape 驗證形狀

官網例子:

# Constant 1-D Tensor populated with value list.tensor = tf.constant([1, 2, 3, 4, 5, 6, 7]) => [1 2 3 4 5 6 7]
# Constant 2-D tensor populated with scalar value -1.tensor = tf.constant(-1.0, shape=[2, 3]) => [[-1. -1. -1.]

咱們的代碼

const = tf.constant(3)
const 
# 輸出const:0 shape=() dtype=int32

run以後才能獲得具體的數。與普通的變量常量是不同的。

Variable 變量

  • 值能夠改變的一種tensor

定義在tf.Variable. 注意這個v是大寫的,和constant是不同的。

屬性: initial_value

__init__(
    initial_value=None,
    trainable=True,
    collections=None,
    validate_shape=True,
    caching_device=None,
    name=None,
    variable_def=None,
    dtype=None,
    expected_shape=None,
    import_scope=None,
    constraint=None)

定義一個變量的張量。

var = tf.Variable(3)var# 不會輸出真實值,只會輸出數據類型等特徵量

咱們能夠在建立變量的時候指定好它的數據類型

var1 = tf.Variable(4, dtype=tf.int64)
var1# 默認系統給的變量名會自動遞增

PlaceHolder(佔位符)

  • 先佔住一個固定的位置,等着你以後往裏面添加值的一種Tensor

mark

例子: 圖書館佔座

tf.placeholder

https://www.tensorflow.org/api_docs/python/tf/placeholder

tf.placeholder(
    dtype,
    shape=None,
    name=None)

屬性少。沒有值。形狀。賦值的機制用到了python中字典的機制

x = tf.placeholder(tf.float32, shape=(1024, 1024))
y = tf.matmul(x, x)with tf.Session() as sess:
  print(sess.run(y))  # ERROR: will fail because x was not fed.

  rand_array = np.random.rand(1024, 1024)
  print(sess.run(y, feed_dict={x: rand_array}))  # Will succeed.

feed_dict 真正運行時才經過feed_dict關鍵字以字典形式向裏面傳值。

SparseTensor(稀疏張量)

  • 一種"稀疏"的Tensor,相似線性代數裏面的稀疏矩陣的概念

tf.SparseTensor

在矩陣中,若數值爲0的元素數目遠遠多於非0元素的數目,而且非0元素分佈沒有規律時,則稱該矩陣爲稀疏矩陣;與之相反,若非0元素數目佔大多數時,則稱該矩陣爲稠密矩陣。 定義非零元素的總數比上矩陣全部元素的總數爲矩陣的稠密度。

定義稀疏矩陣,只須要定義非0的數,其餘爲0的數會自動的填充。

SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4])

指定座標,對應座標的值,以及它的形狀。

[[1, 0, 0, 0]
 [0, 0, 2, 0]
 [0, 0, 0, 0]]

Tensor 表示法

Tensor("MUL:0", shape=(),dtype=float32)

類型 : tf.Variable
名字: MUL
0表示索引

你是operation產生的第幾個張量

shape 就是形狀 dtype 數據類型

定義一個有名字的Variable

named_var = tf.Variable([5,6], name="named_var")
named_var

自動生成的會以數據類型爲名字。

圖和會話原理及案例

Graph(圖)的形象比喻

mark

每一個節點能夠想象成一個儀器,在對咱們的實驗品進行操做。

mark

儀器中被操做,以及在各個儀器中流動的是tensor

TensorFlow程序的流程

  1. 定義算法的計算圖(Graph)結構

把實驗的器材等組裝好

  1. 使用會話(Session)執行圖的一部分(計算)

開始點燃酒精燈等操做

Graph tf.Graph

https://www.tensorflow.org/api_docs/python/tf/Graph

若是你沒有顯式的去建立圖,它其實已經幫你註冊了一個默認的圖。

默認Graph老是已註冊,並可經過調用訪問 tf.get_default_graph。

mark

沒有輸出值是由於咱們尚未用會話運行這一部分。

建立sess對象

咱們能夠看一下Session這個類

https://www.tensorflow.org/api_docs/python/tf/Session

一個Session對象封裝了Operation 執行對象的環境,並對Tensor對象進行評估。例如:

OPeration是圖上的節點,輸入張量,產生張量。

mark

run(
    fetches,
    feed_dict=None,
    options=None,
    run_metadata=None)

mark

run返回的結果就是一個張量。

>>> tf.get_default_graph()
<tensorflow.python.framework.ops.Graph object at 0x000001EC0C5EE160>
>>> if c.graph is tf.get_default_graph():...     print("The Graph of c is the default graph")
...
The Graph of c is the default graph

能夠看到c所屬的圖確實是默認圖。

程序小例子

# -*- coding: UTF-8 -*-

# 引入 TensorFlow
import tensorflow as tf

# 建立兩個常量 Tensor
const1 = tf.constant([[2, 2]])
const2 = tf.constant([[4],
                      [4]])

# 張量相乘(multiply 是 相乘 的意思)
multiply = tf.matmul(const1, const2)

# 嘗試用 print 輸出 multiply 的值
print("sess.run() 以前,嘗試輸出 multiply 的值: {}".format(multiply))

# 建立了 Session(會話)對象
sess = tf.Session()

# 用 Session 的 run 方法來實際運行 multiply 這個
# 矩陣乘法操做,並把操做執行的結果賦值給 result
result = sess.run(multiply)
# 用 print 打印矩陣乘法的結果
print("sess.run() 以後,輸出 multiply 的值: {}".format(result))

if const1.graph is tf.get_default_graph():
    print("const1 所在的圖(Graph)是當前上下文默認的圖")

# 關閉已用完的 Session(會話)
sess.close()

# 第二種方法來建立和關閉 Session
# 用了 Python 的上下文管理器(with ... as ... :)
with tf.Session() as sess:
    result2 = sess.run(multiply)
    print("multiply 的結果是 {} ".format(result2))

 

用顯示的close和with上下文管理器兩種方式實現

可視化利器Tensorboard

展現構建的計算圖和節點等信息在瀏覽器裏。

人工智能的黑盒

mark

mark

輸入手寫4等相關4的圖片。輸出這是4

mark

輸入狗狗圖片,輸出多是狗狗

mark

輸入歷史的股票曲線,預測出將來這一年的市值

TensorBoard的做用

mark

打開黑盒,照亮。方便調參等操做。

節點和操做。

上層節點能夠打開,看到下層節點。

以後可能會加入debug功能,目前還只是一種展現。

用TensorFlow保存圖的信息到日誌中

# 第一個參數爲指定的保存路徑,第二個參數爲要保存的圖tf.summary.FileWriter("日誌保存路徑", sess.graph)

https://www.tensorflow.org/api_docs/python/tf/summary?hl=zh-cn

注意咱們這裏的summary是小寫的summary。

張量摘要用於導出關於模型的信息。

官網的develop 中的get Started 裏面有關於TensorBoard的信息。

開源的github源代碼。

使用TensorBoard 讀取並展現日誌

tensorboard --logdir=日誌所在路徑

Tensorflow安裝以後,會默認安裝有TensorBoard

Summary(總結,概覽)

上一節的代碼中自行添加一行

    # 第一個參數爲指定的保存路徑,第二個參數爲要保存的圖
    tf.summary.FileWriter("./", sess.graph)
  • 用於導出關於模型的精簡信息的方法

  • 可使用TensorBoard等工具訪問這些信息

打開瀏覽器會有一系列菜單。

mark

6006端口打開。

菜單分別是標量,圖片,音頻,圖。

mark

能夠點擊節點,若是有加號打開節點裏面內容。節點含義會列在右邊。

distributions 訓練的一些分佈。histograms 直方圖。

對於數字進行分類。

能夠分類進行顏色加顏色。

namespace(命名空間)

咱們剛纔點擊過的雙擊圖形,節點裏面又有子節點。

  • 很像一些編程語言(如 c++) 的namespace, 包含嵌套的關係

卷積神經網絡下的誤差,adam方法(一種優化方法)

mark

符號的含義

mark

通常的操做不會改變輸入的Tensor,若是是一條黃線,表示操做節點能夠改變輸入的Tensor

使用TensorBoard展現圖代碼示例

# -*- coding: UTF-8 -*-

# 引入tensorflow
import tensorflow as tf

# 構造圖(Graph)的結構
# 用一個線性方程的例子 y = W * x + b
W = tf.Variable(2.0, dtype=tf.float32, name="Weight")  # 權重
b = tf.Variable(1.0, dtype=tf.float32, name="Bias")  # 誤差
x = tf.placeholder(dtype=tf.float32, name="Input")  # 輸入
with tf.name_scope("Output"):      # 輸出的命名空間
    y = W * x + b    # 輸出

# const = tf.constant(2.0)  # 不須要初始化

# 定義保存日誌的路徑
path = "./log"

# 建立用於初始化全部變量(Variable)的操做
# 若是定義了變量,但沒有初始化的操做,會報錯
init = tf.global_variables_initializer()

# 建立 Session(會話)
with tf.Session() as sess:
    sess.run(init)  # 初始化變量
    writer = tf.summary.FileWriter(path, sess.graph)
    result = sess.run(y, {x: 3.0})  # 爲 x 賦值 3
    print("y = W * x + b,值爲 {}".format(result))  # 打印 y = W * x + b 的值,就是 7

 

使用tensorBoard

tensorboard --logdir=./log

6006相似於GOOGle的goog

不像以前的例子有不少菜單,只打開了一個graph菜單。

以後的圖有可能很複雜,查看損失函數,優化計算流圖。

mark

酷炫模擬遊樂場playground

mark

生活中所見的遊樂園。

展現了基本的神經網絡結構

  • JavaScript編寫的網頁應用

  • 經過瀏覽器就能夠訓練簡單的神經網絡

  • 訓練過程可視化,高度定製化

https://playground.tensorflow.org/

不用擔憂運行復雜的神經網絡而搞垮。

數據集 - 特徵 - 隱藏層(深度: 不少層) - 輸出

測試的損失。訓練的損失。越接近0越好。

epoch是完整的運行過程。

黃色越黃越接近-1

點亮輸入。選擇激勵函數。問題類型分類仍是迴歸。

遊樂場對神經網絡有更形象的認識。

經常使用的python繪圖庫Matplotlib

mark

一個極其強大的python繪圖庫:

https://matplotlib.org/

官網有不少例子。

scipy下的一個組件。

  • 不多的代碼便可繪製2d 3d 靜態動態等各類圖形

  • 通常經常使用的是它的子包: pyplot 提供相似matlab的繪圖框架

Matplotlib的通常繪圖流程

mark

sudo pip install matplotlib

代碼:

# -*- coding: UTF-8 -*-# 引入 Matplotlib 的分模塊 pyplotimport matplotlib.pyplot as plt# 引入 numpyimport numpy as np# 建立數據# Linespace建立必定範圍內的圖線。-2到2之間等分100個點x = np.linspace(-2, 2, 100)#y = 3 * x + 4y1 = 3 * x + 4y2 = x ** 3# 建立圖像#plt.plot(x, y)plt.plot(x, y1)
plt.plot(x, y2)# 顯示圖像plt.show()

mark

藍色的爲y1.從-2到2的一條直線。

代碼示例2:

# -*- coding: UTF-8 -*-import matplotlib.pyplot as pltimport numpy as np# 建立數據x = np.linspace(-4, 4, 50)
y1 = 3 * x + 2y2 = x ** 2# 第一張圖# 指定圖的大小plt.figure(num=1, figsize=(7, 6))# 第一張圖兩個線plt.plot(x, y1)
plt.plot(x, y2, color="red", linewidth=3.0, linestyle="--")# 第二張圖plt.figure(num=2)
plt.plot(x, y2, color="green")# 顯示全部圖像plt.show()

mark

代碼示例3:

子圖的繪製

import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.ticker import NullFormatter  # useful for `logit` scale# Fixing random state for reproducibility# 爲了重現結果,設置隨機種子np.random.seed(19680801)# make up some data in the interval ]0, 1[y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))# plot with various axes scalesplt.figure(1)# linear# 兩行兩列子圖中第一個plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)# logplt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)# symmetric logplt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthreshy=0.01)
plt.title('symlog')
plt.grid(True)# logitplt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)# Format the minor tick labels of the y-axis into empty strings with# `NullFormatter`, to avoid cumbering the axis with too many labels.plt.gca().yaxis.set_minor_formatter(NullFormatter())# Adjust the subplot layout, because the logit one may take more space# than usual, due to y-tick labels like "1 - 10^{-3}"plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
                    wspace=0.35)

plt.show()

mark

繪製一個像碗同樣的圖像。

from mpl_toolkits.mplot3d.axes3d import Axes3Dimport matplotlib.pyplot as pltimport numpy as np

fig, ax1 = plt.subplots(figsize=(8, 5),
                        subplot_kw={'projection': '3d'})

alpha = 0.8r = np.linspace(-alpha,alpha,100)
X,Y= np.meshgrid(r,r)
l = 1./(1+np.exp(-(X**2+Y**2)))

ax1.plot_wireframe(X,Y,l)
ax1.plot_surface(X,Y,l, cmap=plt.get_cmap("rainbow"))
ax1.set_title("Bowl shape")

plt.show()

mark

製做靜態圖像,製做動態圖像。

示例5:

import numpy as npfrom matplotlib import cmimport matplotlib.pyplot as pltimport mpl_toolkits.mplot3d.axes3d as p3import matplotlib.animation as animationdef cost_function(x):
    return x[0]**2 + x[1]**2def gradient_cost_function(x):
    return np.array([2*x[0], 2*x[1]])

nb_steps = 20x0 = np.array([0.8, 0.8])
learning_rate = 0.1def gen_line():
    x = x0.copy()
    data = np.empty((3, nb_steps+1))
    data[:, 0] = np.concatenate((x, [cost_function(x)]))    for t in range(1, nb_steps+1):
        grad = gradient_cost_function(x)
        x -= learning_rate * grad
        data[:, t] = np.concatenate((x, [cost_function(x)]))    return datadef update_line(num, data, line):
    # NOTE: there is no .set_data() for 3 dim data...
    line.set_data(data[:2, :num])
    line.set_3d_properties(data[2, :num])    return line# Attaching 3D axis to the figurefig = plt.figure()
ax = p3.Axes3D(fig)# Plot cost surfaceX = np.arange(-0.5, 1, 0.1)
Y = np.arange(-1, 1, 0.1)
X, Y = np.meshgrid(X, Y)
Z = cost_function((X, Y))

surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)# Optimizedata = gen_line()# Creating line objects# NOTE: Can't pass empty arrays into 3d version of plot()line = ax.plot(data[0, 0:1], data[0, 0:1], data[0, 0:1], 'rx-', linewidth=2)[0]# Setting the axes propertiesax.view_init(30, -160)

ax.set_xlim3d([-1.0, 1.0])
ax.set_xlabel('X')

ax.set_ylim3d([-1.0, 1.0])
ax.set_ylabel('Y')

ax.set_zlim3d([0.0, 2.0])
ax.set_zlabel('Z')# Creating the Animation objectline_ani = animation.FuncAnimation(fig, update_line, nb_steps+1, fargs=(data, line), \
    interval=200, blit=False)# line_ani.save('gradient_descent.gif', dpi=80, writer='imagemagick')plt.show()

mark

演示了梯度降低的示例

tensorflow-mnist-tutorial的代碼示例

代碼下載地址:

https://github.com/martin-gorner/tensorflow-mnist-tutorial

注意錯誤:

ImportError: No module named 'tensorflowvisu'

是由於這個tensorflowvisu.py的文件得位於同一級目錄。

mark

mark

能夠看到精度在不斷上升。損失在不斷下降。能夠看到他訓練了哪些數字。

weights,權重。Biases,誤差。 測試的手寫數字

這個例子是用TensorFlow結合Matplotlib來繪製一個實時的動圖。

綜合小練習:梯度降低解決線性迴歸

線性迴歸通常用於預測,好比: 股票漲跌

梯度降低是機器學習中最核心的優化算法

複習一下Operation(操做)

mark

  • 基本的操做:

  • 逐元素的數學操做

  • 矩陣操做

  • 狀態型操做

  • 神經網絡操做

  • 保存,還原操做

  • 模型訓練操做

tf.nn.relutf.add

這些均可以在官網直接搜索查看到。

一些等價的操做

mark

查看在線文檔,搜索,或目錄查看。

help(要查看的對象)

mark

梯度降低優化器

mark

構建一個基於梯度降低的優化器。

# -*- coding: UTF-8 -*-'''
用梯度降低的優化方法來快速解決線性迴歸問題
'''import numpy as npimport matplotlib.pyplot as pltimport tensorflow as tf# 構建數據:100個隨機點points_num = 100# 以後要往vectors中填充100個點的值vectors = []# 用 Numpy 的正態隨機分佈函數生成 100 個點# 這些點的(x, y)座標值: 對應線性方程 y = 0.1 * x + 0.2# 權重 (Weight) 爲 0.1,誤差 (Bias)爲 0.2try:    # 運行100次
    for i in xrange(points_num):        # 橫座標值,隨機正態分佈函數。區間0-0.66
        x1 = np.random.normal(0.0, 0.66)        # 在真實值上加一些誤差
        y1 = 0.1 * x1 + 0.2 + np.random.normal(0.0, 0.04)        # 將點list加入vectors列表中
        vectors.append([x1, y1])except:    for i in range(points_num):
        x1 = np.random.normal(0.0, 0.66)
        y1 = 0.1 * x1 + 0.2 + np.random.normal(0.0, 0.04)
        vectors.append([x1, y1])

x_data = [v[0] for v in vectors] # 列表生成式取出真實的點的 x 座標y_data = [v[1] for v in vectors] # 真實的點的 y 座標# 圖像 1 :展現 100 個隨機數據點plt.plot(x_data, y_data, 'ro', label="Original data") # 紅色圓圈圈型的點plt.title("Linear Regression using Gradient Descent")# 展現labelplt.legend()
plt.show()

mark

咱們要找到一條線性迴歸的直線,以後給它x值就能夠預測y值。也就是尋找一條直線它的w最接近0.1,b最接近於0.2最好。

構建線性迴歸模型

# 構建線性迴歸模型# 初始化參數,傳入shape,最小值,最大值W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) # 初始化 Weight# 誤差。初始化爲0b = tf.Variable(tf.zeros([1]))                     # 初始化 Bias# 這裏的y是y帽子,也就是模型預測出來的值y = W * x_data + b                                 # 模型計算出來的 y# 定義 loss function (損失函數) 或 cost function (代價函數)# 計算殘差平方和。用(y帽子-真實的y)的平方累加的和。N就是總的點數,100.# 對 Tensor 的全部維度計算 ((y - y_data) ^ 2) 之和 / N# reduce_mean就是最後面的/N操做。square平方: y - y_dataloss = tf.reduce_mean(tf.square(y - y_data))# 用梯度降低的優化器來優化咱們的 loss functioin# 讓它更快的找到最終最擬合的w和b: 梯度降低的優化器。學習率,梯度降低的快慢。optimizer = tf.train.GradientDescentOptimizer(0.5) # 設置學習率爲 0.5(步長),通常都是小於1的數。# 太大的學習率可能錯過局部最小值的那個點。# 讓它(損失函數)儘量的損失最小train = optimizer.minimize(loss)# 建立會話sess = tf.Session()# 初始化數據流圖中的全部變量init = tf.global_variables_initializer()
sess.run(init)try:    # 訓練 20 步
    for step in range(20):        # 優化每一步
        sess.run(train)        # 打印出每一步的損失,權重和誤差.必須run才能獲得實際的值。
        print(("Step=%d, Loss=%f, [Weight=%f Bias=%f]") % (step, sess.run(loss), sess.run(W), sess.run(b)))except:    # 訓練 20 步
    for step in xrange(20):        # 優化每一步
        sess.run(train)        # 打印出每一步的損失,權重和誤差
        print("Step=%d, Loss=%f, [Weight=%f Bias=%f]") \
                % (step, sess.run(loss), sess.run(W), sess.run(b))   



# 圖像 2 :繪製全部的點而且繪製出最佳擬合的直線plt.plot(x_data, y_data, 'bo', label="Original data") # 藍色圓圈的點plt.title("Linear Regression using Gradient Descent")# 橫座標是x_data.縱座標爲此時的wb肯定的yplt.plot(x_data, sess.run(W) * x_data + sess.run(b), label="Fitted line") # 擬合的線plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.show()# 關閉會話sess.close()

mark

mark

進階版模仿:

作出擬合過程的動態圖像。

激活函數

主要做用: 加入非線性

tf.nn 點擊nn

https://www.tensorflow.org/api_guides/python/nn#Activation_Functions

能夠看到供咱們使用的激活函數。

wiki中不一樣激活函數的圖像,變種。

https://en.wikipedia.org/wiki/Activation_function

mark

1 / float(1 + np.exp(-x))
# -*- coding: UTF-8 -*-import numpy as npimport matplotlib.pyplot as pltimport tensorflow as tf# 建立輸入數據x = np.linspace(-7, 7, 180) # (-7, 7) 之間等間隔的 180 個點# 激活函數的原始手工實現def sigmoid(inputs):
    # y = 1 / (1 + exp(-x)) np.exp至關於e的多少次方
    y = [1 / float(1 + np.exp(-x)) for x in inputs]    return ydef relu(inputs):
    # f(x) = max(0,x) x大於0時,函數值y就是x。x<0時函數值y就是0.
    # x若是大於0,則真值爲1;y=x;而x若不知足>0真值爲0;y=0
    y = [x * (x > 0) for x in inputs]    return ydef tanh(inputs):
    # e的x次方-e的負x次方作分母。e的x次方+e的負x次方作分母
    y = [(np.exp(x) - np.exp(-x)) / float(np.exp(x) - np.exp(-x)) for x in inputs]    return ydef softplus(inputs):
    # y = log(1+e的x平方)
    y = [np.log(1 + np.exp(x)) for x in inputs]    return y# 通過 TensorFlow 的激活函數處理的各個 Y 值y_sigmoid = tf.nn.sigmoid(x)
y_relu = tf.nn.relu(x)
y_tanh = tf.nn.tanh(x)
y_softplus = tf.nn.softplus(x)# 建立會話sess = tf.Session()# 運行run,獲得四個返回值y_sigmoid, y_relu, y_tanh, y_softplus = sess.run([y_sigmoid, y_relu, y_tanh, y_softplus])# 建立各個激活函數的圖像plt.figure(1, figsize=(8, 6))

plt.subplot(221)
plt.plot(x, y_sigmoid, c='red', label='Sigmoid')# y軸取值的區間plt.ylim((-0.2, 1.2))# 顯示label,放在最適合的位置plt.legend(loc='best')

plt.subplot(222)
plt.plot(x, y_relu, c='red', label='Relu')
plt.ylim((-1, 6))
plt.legend(loc='best')

plt.subplot(223)
plt.plot(x, y_tanh, c='red', label='Tanh')
plt.ylim((-1.3, 1.3))
plt.legend(loc='best')

plt.subplot(224)
plt.plot(x, y_softplus, c='red', label='Softplus')
plt.ylim((-1, 6))
plt.legend(loc='best')# 顯示圖像plt.show()# 關閉會話sess.close()

mark

動手實現cnn卷積神經網絡

用到的數據集: MNIST(手寫數字的數據庫)

TensorFlow中封裝了這個數據集。

mark

咱們要構建的cnn的結構大體如上圖所示

輸入時28*28*1的一張圖片。黑白圖片因此高度爲1,若是是彩色的,高度爲3.紅綠藍。

第一層卷積,有32個過濾器。會變成一個28*28*32的矩陣

通過池化層的Pool(2*2)會變成14*14*32的網絡結構

第二層卷積,有64個過濾器。會變成14*14*64的結構

在通過一個Pool 亞採樣層,就會變成一個7*7*64

以後再進行扁平的序化。就變成1*1*1024

最後通過一個全鏈接網絡去輸出。輸出1*1*10

下載數據並聲明變量

# -*- coding: UTF-8 -*-import numpy as npimport tensorflow as tf# 下載並載入 MNIST 手寫數字庫(55000 * 28 * 28)55000 張訓練圖像from tensorflow.examples.tutorials.mnist import input_data# 這個名字是自定義的,會保存在當前目錄下。若是已經下載的有了,下次就不會download了。mnist = input_data.read_data_sets('mnist_data', one_hot=True)# one_hot 獨熱碼的編碼 (encoding) 形式# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 的十位數字# 第一位上被激活,惟一的表示這一個數字。# 0 : 1000000000# 1 : 0100000000# 2 : 0010000000# 3 : 0001000000# 4 : 0000100000# 5 : 0000010000# 6 : 0000001000# 7 : 0000000100# 8 : 0000000010# 9 : 0000000001# onehot設置True會表示成onehot的編碼。不然會表示自己。# None 表示張量 (Tensor) 的第一個維度能夠是任何長度 除以255input_x = tf.placeholder(tf.float32, [None, 28 * 28]) / 255. # 輸入output_y = tf.placeholder(tf.int32, [None, 10]) # 輸出:10個數字的標籤input_x_images = tf.reshape(input_x, [-1, 28, 28, 1]) # 改變形狀以後的輸入

理清卷積神經網絡的原理和思路

mark

咱們想去構建的是一個相似於上圖的結構的卷積神經網絡。

輸入是一張28,28,1的灰度圖,1表示它只有一個顏色。

圖片通過層層的卷積與池化以後會有一個輸出。會變成一個1,1,10的輸出

mark

咱們想要經過圖片數據+標籤 經過cnn 預測出0-9十種結果。

mark

咱們的CNN識別mnist的輸入端是這樣的。

28,28像素的一個圖片。784

而mnist中的圖片張數是55000張圖片。

mark

輸出是如上圖,對應了55000維度,對於每個預測的值它有一個onehot的編碼

只有一位取1,其餘位所有爲0.

mark

表示識別出來的數字分別爲4,9,5,8

mark

padding決定補零模式。same表示輸入與輸出的維數一致。

# 從 Test(測試)數據集裏選取 3000 個手寫數字的圖片和對應標籤test_x = mnist.test.images[:3000] # 圖片test_y = mnist.test.labels[:3000] # 標籤# 構建咱們的卷積神經網絡:# 第 1 層卷積(二維的卷積) tf.nn 和 tf.layers 中的cov2d有類似有不一樣。# 讓圖像通過卷積層,維度變爲28*28*32。用一個5,5的過濾器(採集器)。# 從左上角到右下角一點一點採集。每一個過濾器掃一遍,輸出增長一層。# 掃了32遍,深度就會從1變爲32# 第二個卷積層,掃了64遍,變成了64# tf.layers.conv2d二維的卷積函數(https://www.tensorflow.org/api_docs/python/tf/layers/conv2d?hl=zh-cn)conv1 = tf.layers.conv2d(
    inputs=input_x_images, # 形狀 [28, 28, 1],這裏仍是一個placeholder,後面會填充值
    filters=32,            # 32 個過濾器,輸出的深度(depth)是32
    kernel_size=[5, 5],    # 過濾器(卷積核心)在二維的大小是(5 * 5)
    strides=1,             # 卷積步幅,步長是1
    padding='same',        # same 表示輸出的大小不變,所以須要在外圍補零 2 圈
    activation=tf.nn.relu  # 激活函數是 Relu) # 形狀 [28, 28, 32]

池化(亞採樣)

# 第 1 層池化(亞採樣)比原來的那些數據,輸出沒有輸入那麼多、# 只採一部分數據。pool1 = tf.layers.max_pooling2d(
    inputs=conv1,     # 形狀 [28, 28, 32]
    pool_size=[2, 2], # 過濾器在二維的大小是(2 * 2)
    strides=2         # 步長是 2) # 通過亞採樣以後,形狀 [14, 14, 32]

pooling有幾種方案。平均,max。平面區域中選最大的值。

輸入必須是一個張量,要有四個維度

https://www.tensorflow.org/api_docs/python/tf/layers/max_pooling2d?hl=zh-cn

步長爲2,隔一步採一個樣。

亞採樣層的過濾器只有一個,因此沒有改變深度。改變了二維大小

構建第二層卷積

通過卷積層,深度會不斷加深。提取到的特徵會不斷增多。

# 第 2 層卷積conv2 = tf.layers.conv2d(
    inputs=pool1,          # 輸入形狀 [14, 14, 32]
    filters=64,            # 64 個過濾器,輸出的深度(depth)是64
    kernel_size=[5, 5],    # 過濾器在二維的大小是(5 * 5)
    strides=1,             # 步長是1
    padding='same',        # same 表示輸出的大小不變,所以須要在外圍補零 2 圈
    activation=tf.nn.relu  # 激活函數是 Relu) # 輸出形狀 [14, 14, 64]

構建第二層池化

mark

第二層池化的過濾器是綠色方塊。

# 第 2 層池化(亞採樣)pool2 = tf.layers.max_pooling2d(
    inputs=conv2,     # 形狀 [14, 14, 64]
    pool_size=[2, 2], # 過濾器在二維的大小是(2 * 2)
    strides=2         # 步長是 2) # 輸出形狀 [7, 7, 64]

知道原理以後,構建神經網絡就跟作三明治漢堡包似的,來層面包來片肉。

flat平坦化

將輸出的7,7,64 壓成1,1,1024

# 平坦化(flat)flat = tf.reshape(pool2, [-1, 7 * 7 * 64]) # 形狀 會變成[7 * 7 * 64, ]

輸入時pool2。-1表示: 根據以後肯定的參數推斷-1這個位置的參數大小。
扁平化。將三維形狀,扁平化。

全鏈接層

# 1024 個神經元的全鏈接層dense = tf.layers.dense(inputs=flat, units=1024, activation=tf.nn.relu)

有多少個神經元組成的全鏈接層。全鏈接層也有一個激活函數的參數,若是沒有加激活函數,會是一個線性的,加了激活函數會變成一個非線性的。這裏咱們擁有一個有1024神經元的全鏈接層

Dropout

丟棄50% rate(丟棄的率)是0.5

# Dropout : 丟棄 50%, rate=0.5dropout = tf.layers.dropout(inputs=dense, rate=0.5)

再通過一個10個神經元的全鏈接層,也就是真實的輸出了。

# 10 個神經元的全鏈接層,這裏不用激活函數來作非線性化了logits = tf.layers.dense(inputs=dropout, units=10) # 輸出。形狀[1, 1, 10]

計算偏差

# 計算偏差 (計算 Cross entropy (交叉熵),再用 Softmax 計算百分比機率)loss = tf.losses.softmax_cross_entropy(onehot_labels=output_y, logits=logits)

https://www.tensorflow.org/api_docs/python/tf/losses/softmax_cross_entropy

交叉熵的損失。

onehot_labels 就是咱們真實的標籤值,output_y,暫時是一個placeholder,以後會賦值(訓練集裏對應的真實標籤)。

logits 傳入咱們的預估,logits(y帽子)

用Adam 優化器來最小化偏差,學習率 0.001

# Adam 優化器來最小化偏差,學習率 0.001使之最小化。使loss最小train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)

精度,計算預測值 和 實際標籤的匹配程度

# 精度。計算 預測值 和 實際標籤 的匹配程度# 返回(accuracy, update_op), 會建立兩個局部變量accuracy = tf.metrics.accuracy(
    labels=tf.argmax(output_y, axis=1),
    predictions=tf.argmax(logits, axis=1),)[1]

https://www.tensorflow.org/api_docs/python/tf/metrics/accuracy

Calculates how often predictions matches labels

計算預測值與真實值之間的差距,匹配度

argmax函數會返回張量軸上最大值的下標。

accuracy函數會返回兩個值,咱們取其中一個值。

accuracy:Tensor表明準確度,total除以的值count。
update_op:一種適當增長total和count變量而且其值匹配的操做accuracy。

訓練神經網絡

# 建立會話sess = tf.Session()
# 初始化變量:全局和局部init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init)

初始化全局和局部變量。group是一個組的概念。

https://www.tensorflow.org/api_docs/python/tf/group

建立一個將多個操做分組的操做。

訓練咱們的神經網絡

# 訓練神經網絡for i in range(20000):    # 從訓練集中進行選取。batch,一包。
    batch = mnist.train.next_batch(50)  # 從 Train(訓練)數據集裏取"下一個"50 個樣本
    # run以後,loss的返回值給到train_loss train_op的值給到train_op_
    # 給實際的input_x和input_y賦值。batch有兩列,0是圖片,1是真實標籤。
    train_loss, train_op_ = sess.run([loss, train_op], {input_x: batch[0], output_y: batch[1]})    if i % 100 == 0:        # 這裏測試的精度是在測試集上的精度。
        test_accuracy = sess.run(accuracy, {input_x: test_x, output_y: test_y})        # 步數,訓練的損失,測試的精度
        print(("Step=%d, Train loss=%.4f, [Test accuracy=%.2f]") \
            % (i, train_loss, test_accuracy))

測試,打印20個預測值和真實值的對

# 測試:打印 20 個預測值 和 真實值 的對# 輸入測試集的20項,輸出預測的y(onehot)test_output = sess.run(logits, {input_x: test_x[:20]})# 取到它預測的y是哪一個真實數字inferenced_y = np.argmax(test_output, 1)
print(inferenced_y, 'Inferenced numbers') # 推測的數字# 取出測試集中的真實標籤值print(np.argmax(test_y[:20], 1), 'Real numbers') # 真實的數字

訓練結果

mark

連接:https://www.imooc.com/article/45760

相關文章
相關標籤/搜索