首先將MINST數據集60,000張手寫數字(0至9)圖像用於28 x 28像素網格上做訓練,以及10,000張用於測試的圖像。因此,每個數字由784條信息表示。在這個測試中,將每個圖像分解為28個steps,並為LSTM網絡提供28個features,看它是否仍然可以學習。有效地將784像素的圖像分解為28個time-step的“movie”(每個frame包含28條訊息)。
在下面的第一次嘗試中,將完全沒有優化的網絡做學習能夠達到98.89%的準確度。
# James implementation of minst database# import required to process csv files with pandasimport pandas as pd # for array manipulationimport numpy as np# for normalizing the datafrom sklearn.preprocessing import MinMaxScaler# allows onehotencodingfrom sklearn.preprocessing import OneHotEncoder# read the training csv file # data from 60000 images originally represented as a 28 x 28 pixel grid# originally obtained from http://yann.lecun.com/exdb/mnist/mnist_training_data = pd.read_csv(r'C:\Users\james\Anaconda3JamesData\mnist_train.csv', header=None)# each row of data consists of# the first element [0] is the label of the actual number (0 through 9)# the following 784 element [1:785] is the actual number originally respresented as a 28 x 28 pixel grid# we want to create training data, and label data for our LSTM to train frommnist_training_data_values = mnist_training_data.iloc[:, 1:785].valuesmnist_training_data_labels = mnist_training_data.iloc[:, 0].values# we will normalize the training data (from 0 to 1 using MinMaxScaler)# normalise the training datascaler = MinMaxScaler(feature_range = (0.0, 1.0))mnist_training_data_values = scaler.fit_transform(mnist_training_data_values.astype('float64'))# the output of the network values (the labels) are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9# Onehotencoding expects a 2D arraymnist_training_data_labels = mnist_training_data_labels.reshape (60000,1)# create the encoderencoder = OneHotEncoder(sparse=False, categories='auto')# encode the training labelsmnist_training_data_labels = encoder.fit_transform(mnist_training_data_labels)# reshape mnist_training_data_values into 3d arraymnist_training_data_values = mnist_training_data_values.reshape(60000 , 28, 28)# effectively I will feed each image into the LSTM as 28 rows of data # with 28 steps - so effectively preceptually changing the data into a # 28 step time sequence (with 28 features per step)#print("mnist_training_data_values shape:", mnist_training_data_values.shape)#print ("mnist_training_data_labels shape: ",mnist_training_data_labels.shape)#print (mnist_training_data_labels )from keras.models import Sequential from keras.layers import LSTM from keras.layers import Densefrom keras.optimizers import Adam#from keras.layers import Dropout # each sequence (representing one number from the minst database) has 28 steps and 28 featuresmodel = Sequential()model.add(LSTM(50,return_sequences=True,input_shape=(28, 28)))model.add(LSTM(50))model.add(Dense(10, activation='softmax'))model.compile(Adam(lr=0.001), loss='categorical_crossentropy', metrics=['acc'])history = model.fit(mnist_training_data_values , mnist_training_data_labels , validation_split=0.1, shuffle=True, batch_size= 28,epochs=500, verbose=2)# display diagnostics of the trainingimport matplotlib.pyplot as plt %matplotlib inlineplt.figure(figsize=(13,8)) plt.plot(history.history['loss'], color='blue')plt.plot(history.history['val_loss'], color='orange')plt.plot(history.history['acc'], color='red')plt.plot(history.history['val_acc'], color='green')plt.title('model loss during training')plt.ylabel('loss')plt.xlabel('epoch')plt.legend(['loss', 'val_loss', 'acc',' val_acc'], loc='upper left')plt.show()# prediction modelmnist_testing_data = pd.read_csv(r'C:\Users\james\Anaconda3JamesData\mnist_test.csv', header=None)# process the data as beforemnist_testing_data_values = mnist_testing_data.iloc[:, 1:785].valuesmnist_testing_data_labels = mnist_testing_data.iloc[:, 0].values# using the same normalisation as I used on the training data# hence using 'transform' and not 'fit_transform'mnist_testing_data_values = scaler.transform(mnist_testing_data_values.astype('float64'))length_of_testing_data = len(mnist_testing_data_values)# reshape the testing data values to the same shape as the training valuesmnist_testing_data_values = mnist_testing_data_values.reshape(length_of_testing_data, 28, 28)predict = model.predict(mnist_testing_data_values)# decode the onehotencoded prediction resultsone_hot_decoded_data = encoder.inverse_transform(predict)#length = len(one_hot_decoded_data) #the decoded predict modelone_hot_decoded_data = np.array(one_hot_decoded_data)mnist_testing_data_labels = np.array(mnist_testing_data_labels)#print (one_hot_decoded_data.shape)#print (mnist_testing_data_labels.shape)# reshape the one_hot_decoded_dataone_hot_decoded_data = one_hot_decoded_data.reshape(1,-1)mnist_testing_data_labels = mnist_testing_data_labels.reshape(1,10000)#print (one_hot_decoded_data.shape)#print (mnist_testing_data_labels.shape)# accuracy analyticscorrect= 0for i in range(0,10000): if (one_hot_decoded_data[0,i] == mnist_testing_data_labels[0,i]): print ("sample number: ",i," test: ",mnist_testing_data_labels[0,i], " predicted: ",one_hot_decoded_data[0,i], " CORRECT") correct+=1 else: print ("sample number: ",i," test: ",mnist_testing_data_labels[0,i], " predicted: ",one_hot_decoded_data[0,i], " FALSE")print ('Accuracy: %f' % ((correct/10000)*100))
參考
https://www.drjamesfroggatt.com/python-and-neural-networks/keras-implementation-of-an-lstm-neural-network-to-classify-and-predict-the-minst-dataset/
沒有留言:
張貼留言