代碼1如下:
#深度學習入門課程之感受神經網絡(上)代碼解釋: import numpy as np import matplotlib.pyplot as plt #matplotlib是一個庫,pyplot是其中一個模塊 #%matplotlib inline 適用於在ipython notebook中進行繪圖內嵌說明,由於我在Pycharm上寫的,應此不需要這條以及下面的幾個命令 plt.rcParams['figure.figsize'] = (10.0,8.0) #創建一個10*8大小的繪圖對象 plt.rcParams['image.interpolation'] = 'nearest' plt.rcParams['image.cmap'] = 'gray' #%load_ext autoreload #%autoreload 2 np.random.seed(0) #用於指定隨機數生成時所用算法開始的整數值,如果使用相同的seed值,則每次生成的隨機數相同 N = 100 #每類有一百個點 D = 2 #每個點是二維的,即x和y值為樣本的特征向量 K = 3 #總共有三類,因此總共三百個訓練樣本 X = np.zeros((N*K,D)) #生成一個300*2的零矩陣 y = np.zeros(N*K,dtype='uint8') #生成一個1*300的零矩陣,類型為uint8 for j in xrange(K): #j從0到2 ix = range(N*j,N*(j+1)) r = np.linspace(0.0,1,N) #radius t = np.linspace(j*4,(j+1)*4,N) + np.random.randn(N)*0.2 #theta X[ix] = np.c_[r*np.sin(t),r*np.cos(t)] y[ix] = j #給300個點分類,每一百一類,即[0,99]為0類,[100,199]為1類,以此類推 fig = plt.figure() plt.scatter(X[:,0],X[:,1],c=y,s=40,cmap=plt.cm.Spectral) #scatter畫散點圖; plt.xlim([-1,1]) plt.ylim([-1,1]) #使用單層神經網絡,未使用激活函數,即線性分類 w = 0.01*np.random.randn(D,K) #權值初始化,2*3,即輸入兩個特征向量,輸出三個類別,[-0.01,0.01] b = np.zeros((1,K)) #閾值初始化,1*3的零矩陣 step_size = 1e-0 #學習步長為1 reg = 1e-3 #正則化系數,10的負三次方 num_examples = X.shape[0] #X是300*2,shape[0]求它第一維的長度即樣本個數 for i in xrange(200): #迭代兩百次 scores = np.dot(X,w)+b #下面是softmax分類器解釋,scores為300*3 exp_score = np.exp(scores) #為300*3 probs = exp_score/np.sum(exp_score,axis = 1,keepdims = True) #每個點分類的得分所占概率(包括正確分類和錯誤分類),#300*3 corect_logprobs = -np.log(probs[range(num_examples),y]) #probs[range(num_examples),y]是正確分類的概率 data_loss = np.sum(corect_logprobs)/num_examples reg_loss = 0.5*reg*np.sum(w*w) #正則化項 loss = data_loss+reg_loss if i%10 == 0: #每迭代10次輸出一次Loss值 print 'iteration %d:loss %f'%(i,loss) dscores = probs dscores[range(num_examples),y] -= 1 #Loss關於scores的偏導,為probs-1 dscores /= num_examples dW = np.dot(X.T,dscores) #data_loss傳遞下來的梯度 db = np.sum(dscores,axis = 0,keepdims = True) dW +=reg*w #再加上正則化項傳遞下來的梯度 w += -step_size * dW b += -step_size * db #求一下分類的准確率 scores = np.dot(X,w)+b predicted_class = np.argmax(scores , axis=1) #predicted_class為[1,300],為每個點得分最大的所在的那個列數,即類 print 'training accuracy:%.2f'%(np.mean(predicted_class == y)) #mean()是求均值 #畫出分類效果 h=0.02 x_min , x_max = X[:,0].min() - 1, X[:,0].max() + 1 y_min , y_max = X[:,1].min() - 1, X[:,1].max() +1 xx, yy = np.meshgrid(np.arange(x_min , x_max ,h), np.arange(y_min , y_max ,h)) Z = np.dot(np.c_[xx.ravel(),yy.ravel()],w) + b Z = np.argmax(Z,axis = 1) Z = Z.reshape(xx.shape) fig = plt.figure() plt.contourf(xx,yy,Z,cmap=plt.cm.Spectral,alpha=0.8) plt.scatter(X[:,0],X[:,1],c=y,s=40,cmap=plt.cm.Spectral) plt.xlim(xx.min(),xx.max()) plt.ylim(yy.min(),yy.max()) plt.show()
迭代兩百次,loss值到后面開始趨於飽和,accuracy為0.49,可見這種單層的神經網絡和線性分類得到的最終效果並不好,效果圖如下:

下面我們來使用雙層神經網絡和relu激活函數來進行非線性分類,代碼如下:
#深度學習入門課程之感受神經網絡(下)代碼解釋: import numpy as np import matplotlib.pyplot as plt #matplotlib是一個庫,pyplot是其中一個模塊 #%matplotlib inline 適用於在ipython notebook中進行繪圖內嵌說明 plt.rcParams['figure.figsize'] = (10.0,8.0) #創建一個10*8大小的繪圖對象 plt.rcParams['image.interpolation'] = 'nearest' plt.rcParams['image.cmap'] = 'gray' #%load_ext autoreload #%autoreload 2 np.random.seed(0) #用於指定隨機數生成時所用算法開始的整數值,如果使用相同的seed值,則每次生成的隨機數相同 N = 100 #每類有一百個點 D = 2 #每個點是二維的 K = 3 #總共有三類 X = np.zeros((N*K,D)) #生成一個300*2的零矩陣 y = np.zeros(N*K,dtype='uint8') #生成一個1*300的零矩陣,類型為uint8 for j in xrange(K): #j從0到K-1 ix = range(N*j,N*(j+1)) r = np.linspace(0.0,1,N) #radius t = np.linspace(j*4,(j+1)*4,N) + np.random.randn(N)*0.2 #theta X[ix] = np.c_[r*np.sin(t),r*np.cos(t)] y[ix] = j #給300個點分類,每一百一類; fig = plt.figure() plt.scatter(X[:,0],X[:,1],c=y,s=40,cmap=plt.cm.Spectral) #scatter畫散點圖; plt.xlim([-1,1]) plt.ylim([-1,1]) #使用雙層神經網絡,使用Relu激活函數,將之前的線性分類變為非線性分類 h = 100 #隱層神經元個數 w = 0.01*np.random.randn(D,h) #D為輸入層神經元個數 b = np.zeros((1,h)) w2 = 0.01*np.random.randn(h,K) #K為輸出層神經元個數 b2 = np.zeros((1,K)) step_size = 1e-0 #學習步長為1 reg = 1e-3 #正則化系數,10的負三次方 num_examples = X.shape[0] #由於X是300*3矩陣,這里的shape[0]讀取它第一維長度及300為樣本個數 for i in xrange(10000): #迭代兩百次 hidden_layer = np.maximum(0,np.dot(X,w)+b) #ReLu激活函數,hidden_layer為300*100 scores = np.dot(hidden_layer,w2) + b2 exp_scores = np.exp(scores) probs = exp_scores / np.sum(exp_scores,axis=1,keepdims=True) corect_logprobs = -np.log(probs[range(num_examples),y]) data_loss = np.sum(corect_logprobs) / num_examples reg_loss = 0.5*reg*np.sum(w*w) + 0.5*reg*np.sum(w2*w2) loss = data_loss + reg_loss if i%10 == 0: #每迭代10次輸出一次Loss值 print 'iteration %d:loss %f'%(i,loss) dscores = probs dscores[range(num_examples), y] -= 1 # Loss關於scores的偏導,為probs-1 dscores /= num_examples dw2 = np.dot(hidden_layer.T,dscores) db2 = np.sum(dscores,axis=0,keepdims=True) dhidden = np.dot(dscores,w2.T) #梯度的反向傳播,dihidden是300*100 dhidden[hidden_layer <= 0] = 0 #hidden_layer是隱層的輸出值,若隱層輸出為0,則對應位置的dhidden梯度為0不傳播 dw = np.dot(X.T,dhidden) db = np.sum(dhidden,axis=0,keepdims=True) dw2 += reg * w2 dw += reg * w w += -step_size * dw w2+= -step_size * dw2 b += -step_size * db b2 += -step_size * db2 #求一下准確率 hidden_layer = np.maximum(0,np.dot(X,w)+b) scores = np.dot(hidden_layer,w2) + b2 predicted_class = np.argmax(scores,axis = 1) print 'training accuracy: %.2f' %(np.mean(predicted_class == y)) h=0.02 x_min , x_max = X[:,0].min() - 1, X[:,0].max() + 1 y_min , y_max = X[:,1].min() - 1, X[:,1].max() +1 xx, yy = np.meshgrid(np.arange(x_min , x_max ,h), np.arange(y_min , y_max ,h)) Z = np.dot(np.maximum(0,np.dot(np.c_[xx.ravel(),yy.ravel()],w)+b),w2) + b2 Z = np.argmax(Z,axis = 1) Z = Z.reshape(xx.shape) fig = plt.figure() plt.contourf(xx,yy,Z,cmap=plt.cm.Spectral,alpha=0.8) plt.scatter(X[:,0],X[:,1],c=y,s=40,cmap=plt.cm.Spectral) plt.xlim(xx.min(),xx.max()) plt.ylim(yy.min(),yy.max()) plt.show()
上述網絡在迭代時,到了后期loss也沒有飽和,我們將迭代期改為2000次,loss由原來的1點幾降為0.3幾且未飽和,accuracy達到97%.效果圖如下:
注意:在編寫上述代碼時要注意矩陣的操作!

