0

我想用簡單的Python代碼對手寫數字(MNIST)進行分類。我的方法是一個簡單的單層感知器,我用批量方法做。用單層感知器對手寫數字進行分類

我的問題是,例如,如果我訓練數字「1」,然後其他數字,網絡總是顯示「1」的結果。事實上,訓練發生在第一位數字。我不知道有什麼問題。

我在想這與批次訓練有關,一次訓練後第二位數不能因爲網絡收斂。但我不能如何解決它。

我使用多層感知器進行測試,並得到相同的行爲。

注:

1:我每次選擇一個數字並加載了很多人,並開始培訓,併爲其他數字我重新啓動的每一件事情,除了權重矩陣(W0)

這是我的代碼的時間-importing庫:

import os, struct 
from array import array as pyarray 
from numpy import append, array, int8, uint8, zeros 
import numpy as np 
from IPython.display import Image 
import matplotlib.pyplot as plt 
from IPython import display 
from scipy.special import expit 
from scipy.misc import imresize 
from IPython.core.page import page 
from IPython.core.formatters import format_display_data 

np.set_printoptions(threshold=np.nan) 
np.set_printoptions(suppress=True) 

2- Sigmoid函數:

def sigmoid(x, deriv=False): 
    if(deriv==True): 
     return x*(1-x) 
    return expit(x) 

3-初始化權重

np.random.seed(1) 
w0 = 2*np.random.random((784,10))-1 

4-讀MNIST數據集

dataset="training" 
path="." 

if dataset == "training": 
    fname_img = os.path.join(path, 'train-images-idx3-ubyte') 
    fname_lbl = os.path.join(path, 'train-labels-idx1-ubyte') 
elif dataset == "testing": 
    fname_img = os.path.join(path, 't10k-images-idx3-ubyte') 
    fname_lbl = os.path.join(path, 't10k-labels-idx1-ubyte') 
else: 
    raise ValueError("dataset must be 'testing' or 'training'") 

flbl = open(fname_lbl, 'rb') 
magic_nr, size = struct.unpack(">II", flbl.read(8)) 
lbl = pyarray("b", flbl.read()) 
flbl.close() 

fimg = open(fname_img, 'rb') 
magic_nr, size, rows, cols = struct.unpack(">IIII", fimg.read(16)) 
img = pyarray("B", fimg.read()) 
fimg.close() 

5-選擇一個號碼

number = 4 
digits=[number] 
ind = [ k for k in range(size) if lbl[k] in digits ] 
N = len(ind) 

images = zeros((N, rows, cols), dtype=uint8) 
labels = zeros((N, 1), dtype=int8) 

for i in range(len(ind)): 
    images[i] = array(img[ ind[i]*rows*cols : (ind[i]+1)*rows*cols ]).reshape((rows, cols)) 
    labels[i] = lbl[ind[i]] 

6-每個數字轉換爲一個矢量和轉換矩陣單元爲二進制:

p = np.reshape(images,(len(images),784)) 
p[p > 0] = 1 

7-目標矩陣(每列一個數字)

t = np.zeros((len(images), 10),dtype=float) 
t[:,number] = 1 

8-訓練(梯度下降)

for iter in xrange(600): 
    predict = sigmoid(np.dot(p,w0)) 
    e0 = predict - t 
    delta0 = e0 * sigmoid(predict,True) 
    w0 -= 0.01*np.dot(p.T,delta0) 

9-測試

test_predict = sigmoid(np.dot(p[102],w0)) 
print test_predict 

回答

2

它是沒有意義的訓練網絡與數據從一個類(數字),直到它收斂,然後添加另一個類,等等。

如果你只訓練一門課,所需的輸出總是相同的,網絡可能會很快收斂。它可能會爲各種輸入模式產生這種輸出,而不僅僅是用於訓練的輸出。

你需要做的是在訓練期間提供來自所有類別的輸入,例如以隨機順序。這樣網絡將能夠找到不同類別之間的界限。

+0

謝謝。你是說當我使用班級和火車時,我的網絡會收斂,而對於第二類,訓練不會發生?如果這是我的問題,那麼我可以使用批量學習的許多任務(多類),對不對? – Fcoder

+1

@Fcoder:培訓仍將發生,但網絡爲第一類人員找到的解決方案可能會遠離任何適用於所有類別的明智解決方案,至少需要很長時間。爲第一類訓練的網絡輸出可能不會取決於輸入,而只取決於偏差值。是的,你應該從一開始就展示來自所有課堂的模式。 –