深度学习笔记:01快速构建一个手写数字识别系统以及张量的概念
深度學習筆記:01快速構建一個手寫數字識別系統
神經網絡代碼最好運行在GPU中,但是對于初學者來說運行在GPU上成本太高了,所以先運行在CPU中,就是慢一些。
一、安裝keras框架
(以后安裝也可以這樣,只要將tensorflow_cpu換成需要下載的庫或包名,根據自己需求自行更改即可)
安裝完成:
檢測是否安裝上keras框架:
運行以下指令:
import tensorflow import keras print(keras.__version__)我的輸出結果是:2.9.0。安裝完畢,可以使用啦~
二、熟悉mnist數據集
首先,我們先把我們需要的數據集引入,并且定義兩個數據集
from keras.datasets import mnist (train_images,train_labels),(test_images,test_labels) = mnist.load_data()其中,這個images和labels分別表示我們這個mnist數據集中的圖片和這個圖片所對應的數字(標簽),例如:
print(test_images)結果:
這個可能并不方便看出什么來,那么我們通過:
print(test_images.shape)結果:
可以看出這個test_images是一個含有10000個元素的數組,并且每個元素是一個28×28的二維數組(像素)。也就是這個test_images含有10000張像素為28×28的手寫數字圖片。
下面我們再看一下test_labels:
print(test_labels)結果:
test_labels是標記我們test_images的標簽,他也是有10000個元素并且每個元素都和test_images的元素一一對應。相當于告訴我們test_images每個圖片對應的手寫數字是什么。
我們可以通過下面幾行代碼做一個簡短的驗證:
digit = test_images[0] import matplotlib.pyplot as plt # matpoltlib是一個繪制圖案的python庫 plt.imshow(digit,cmap=plt.cm.binary) plt.show()結果:
確實,test_labels也顯示第一個數字是7。驗證完畢~
三、使用keras框架快速構建手寫數字識別函數
首先我們之前提過神經網絡的模型結構:
下面這段代碼完成的是這個模型結構的上半部分:
from keras import models from keras import layersnetwork = models.Sequential() network.add(layers.Dense(512,activation="relu",input_shape=(28*28,))) # activation="relu"的意思是激活函數是relu函數 input_shape=(28*28,)的意思是我接受的這個神經網絡必須是28*28的二維數組 network.add(layers.Dense(10,activation="softmax"))**Sequential()函數的作用:**將你的神經網絡的每一層都想象成一個佛珠,然后把每個你想串聯起來的網絡層名字傳給Sequential函數,他的作用就是把每個網絡層像串佛珠一樣串聯起來,這樣你就不用每個都去鏈接一次了。
下面我們再來完善我們這個模型的下半部分:
network.compile(optimizer="rmsprop",loss="categorical_crossentropy",metrics=["accuracy"])**compile()函數的作用:**用于將源代碼編譯為代碼對象或AST模塊對象。 可以根據提供的模式使用exec()或eval()函數執行返回的代碼對象,以構造代碼對象。
那么我們這一行就對應著這個網絡模型的下半部分。
下面我們在對我們images數據進行進一步的處理:
train_images = train_images.reshape((60000,28*28)) train_images = train_images.astype('float32')/255test_images = test_images.reshape(10000,28*28) test_images = test_images.astype('float32')/255將我們原來的train_images里面28×28的二維數組變成28×28的一維數組
再將每一個元素里面的數值都除以255(因為像素點)
因為我們傳給網絡進行訓練的圖片是一個灰度圖,灰度圖指的是這里面的每一個像素點他的值都介于0~255之間。所以除以255以后他的每個數都變成了0~1之間的一個浮點數,這樣傳給網絡便于接下來的識別與統計。
接下來我們來轉化labels數據:
from keras.utils import to_categorical print("before change:",test_labels[0]) train_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels) print("after change:",test_labels[0])關鍵點:調用categorical接口轉換
目的:將數字變成數組表示。因為圖片中包含的都是0~9一共10個數字,下面我們將這個數字變成由10個元素組成的數組。比如說剛剛我們的數字7,將其變成數組以后就其余元素都是0只有數組的第七個元素是1。然后將這個轉換給我們的神經網絡進行識別。
結果:
最后一步,開始訓練我們的神經網絡:
network.fit(train_images,train_labels,epochs=5,batch_size=128)現在我們準備開始訓練網絡,在 keras中這一步是通過調用網絡的fit方法來完成的—— 我們在訓練數據上擬合(fit)模型。
epochs表示每次訓練改進時都是進行5個循環
batch_size=128表示每次訓練都從這個數組中_images隨機抽取128個圖片來進行統計
結果如圖:
訓練過程中顯示了兩個數字:一個是網絡在訓練數據上的損失(loss),另一個是網絡在 訓練數據上的精度(acc)。
下面我們調用evaluate接口看我們對這個測試的圖片進行識別看識別成功率為多少
test_loss,test_acc=network.evaluate(test_images,test_labels,verbose=1) print('test_acc:',test_acc)我這邊是:
最后我們拿一張圖片,來看一下這個對于這張圖片我們的神經網絡的識別結果:
from keras.datasets import mnist (train_images,train_labels),(test_images,test_labels) = mnist.load_data() digit = test_images[1] plt.imshow(digit,cmap=plt.cm.binary) plt.show()test_images = test_images.reshape(10000,28*28) res = network.predict(test_images) print(res[1])for i in range(res[1].shape[0]):if(res[1][i] == 1):print("the number for the picture is",i)break結果很不錯!成功識別是2
四、張量的概念
tensor的中文意思就是:張量
tensor是后面在進行神經網絡開發時的最基本的概念,存儲在多維數組(Numpy)中。
tensor的常用屬性有維度(dim),和形狀(shape)
- 0-dim的tensor就是一個常量,在python中,我們通過ndim的屬性來獲取tensor的維度,通過shape屬性來獲取形狀
- 1-dim的tensor就是一個數組
- 2-dim的tensor就是一個二維數組
所以我們可以理解為一個n-dim的tensor,他其實就是一個一維數組,數組中每個元素都是(n-1)-dim的tensor。所以,3-dim張量就是一個一維數組,數組中的每個元素就是2-dim的tensor,相關代碼如下:
x = np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,1],[1,2]] ]) print(x.ndim) print(x.shape) 3 (3, 2, 2)shape告訴我們,這個x有三個元素,每個元素都是一個2*2的二維數組
幾維張量括號內就對應幾個數字:
所以對照我們上節所學train_images:
所以在面對大規模的張量時我們可以實現另一種操作就是將張量中的某一部分的值單獨提取出來:
from keras.datasets import mnist (train_images,train_labels),(test_images,test_labels) = mnist.load_data() my_slice = train_images[10:100] print(my_slice.shape)這就是batch的概念:batch值得是從全部數據中抽出一部分形成一個子集,上面代碼中的my_slice就是一個batch
五、張量的運算
張量的relu運算:將張量內的值x與0作比較,如果x>0 不變,如果x<0 則將x變成0
類似下面的函數實現:
def naive_relu(x):assert len(x.shape) == 2x = x.copy() #確保操作不對x產生影響for i in range(x.shape[0]):for j in range(x.shape[1]):x[i][j] = max (x[i][j],0) return xx = np.array([[1,-1],[-2,1] ]) print(naive_relu(x))==張量的點乘運算:==1-dim的點乘是每個之間點乘并求和累加
類似下面的函數實現:
def naive_vector_dot(x,y):assert len(x.shape) == 1assert len(y.shape) == 1assert x.shape[0] == y.shape[0]z = 0.for i in range(x.shape[0]):z = z + x[i] * y[i]return zx = np.array([1,2,3]) y = np.array([4,5,6])print(naive_vector_dot(x,y))所以類推高維張量之間做點乘運算,類似于矩陣的運算。
即:一個m*n的矩陣也只能乘以一個n*s的矩陣,這倆矩陣第一個的列數必須得等于第二個的行數
例如:
def naive_matrix_vector_dot(x,y):z = np.zeros(x.shape[0])for i in range(x.shape[0]):z[i] = naive_vector_dot(x[i,:],y)return zx = np.array([[4,5,6],[7,8,9] ]) y = np.array([1,2,3] )print(naive_matrix_vector_dot(x,y))轉化成矩陣運算也就是這個意思:
最后,張量是深度學習中最基礎的一個概念。務必要搞清楚!
總結
以上是生活随笔為你收集整理的深度学习笔记:01快速构建一个手写数字识别系统以及张量的概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个通过添加本地分区索引提高SQL性能的
- 下一篇: e销卡租号系统源码