2.keras实现MNIST手写数字分类问题初次尝试(Python)

    xiaoxiao2021-12-14  22

    根据我上一篇文章下载完MNIST数据集后,下一步就是看看keras是如何对它进行分类的。

    参考博客:

    http://blog.csdn.net/vs412237401/article/details/51983440

    之际复制该blog中的代码发现在我这儿运行不通,初步判断是因为Window和Linux系统路径方面差别,处理有点儿问题,所以对此修改了一点

    先看原文:

    def load_mnist(path, kind='train'):       """Load MNIST data from `path`"""       labels_path = os.path.join(path, '%s-labels-idx1-ubyte' % kind)       images_path = os.path.join(path, '%s-images-idx3-ubyte' % kind)       with open(labels_path, 'rb') as lbpath:           magic, n = struct.unpack('>II', lbpath.read(8))           labels = np.fromfile(lbpath, dtype=np.uint8)       with open(images_path, 'rb') as imgpath:           magic, num, rows, cols = struct.unpack(">IIII", imgpath.read(16))           images = np.fromfile(imgpath, dtype=np.uint8).reshape(len(labels), 784)       return images, labels         X_train, y_train = load_mnist('../data', kind='train')   print('Rows: %d, columns: %d' % (X_train.shape[0], X_train.shape[1]))   X_test, y_test = load_mnist('../data', kind='t10k')   print('Rows: %d, columns: %d' % (X_test.shape[0], X_test.shape[1]))  我的理解是他把MNIST数据集文件直接存放在该python工程文件夹下data文件夹内了。

    对于windows用户,感觉上述代码问题点在于:

    1.load_mnist('../data', kind='train'),对于window系统,分隔符应该是 \,然而即使改了这个地方,仍然行不通,不知道是不是前面路径缩写的原因;

    2.把上面的路径不用简写,完整写出来,并在字符串前加r,仍然行不通。。。错误出现在with open(labels_path, 'rb') as lbpath:

    3.即使路径手动调出来了,labels_path = os.path.join(path, '%s-labels-idx1-ubyte' % kind),这句给出的是你的压缩包的文件路径,读出来的是压缩包,也不对。magic, num, rows, cols = struct.unpack(">IIII", imgpath.read(16))读出的参数是错的。

    鉴于以上问题调了半天,想出以下解决对策

    1.将MNIST解压缩后的文件直接放在该python工程文件夹下,并修改上述代码,以下直接贴出修改后的全部代码

    import os import struct import numpy as np def load_mnist( kind='train'): """Load MNIST data from `path`""" labels_path = ('%s-labels.idx1-ubyte' % kind) images_path = ('%s-images.idx3-ubyte' % kind) with open(labels_path, 'rb') as lbpath: magic, n = struct.unpack('>II', lbpath.read(8)) labels = np.fromfile(lbpath, dtype=np.uint8) print magic, n,labels with open(images_path, 'rb') as imgpath: magic, num, rows, cols = struct.unpack(">IIII", imgpath.read(16)) print magic, num, rows, cols images = np.fromfile(imgpath, dtype=np.uint8).reshape(len(labels), 784) #28*28=784 return images, labels X_train, y_train = load_mnist( kind='train') print('Rows: %d, columns: %d' % (X_train.shape[0], X_train.shape[1])) X_test, y_test = load_mnist( kind='t10k') print('Rows: %d, columns: %d' % (X_test.shape[0], X_test.shape[1])) import theano theano.config.floatX = 'float32' X_train = X_train.astype(theano.config.floatX) X_test = X_test.astype(theano.config.floatX) from keras.utils import np_utils print('First 3 data: ', X_train[:3]) print('First 3 labels: ', y_train[:3]) y_train_ohe = np_utils.to_categorical(y_train) #change numbers to 0/1 mode,for example change 5 to [0 0 0 0 1 0 0 0 0 0] print('First 3 labels (one-hot):', y_train_ohe[:3]) from keras.models import Sequential from keras.layers.core import Dense from keras.optimizers import SGD np.random.seed(1) model = Sequential() model.add(Dense(input_dim=X_train.shape[1], output_dim=50, init='uniform', activation='tanh')) model.add(Dense(input_dim=50, output_dim=50, init='uniform', activation='tanh')) model.add(Dense(input_dim=50, output_dim=y_train_ohe.shape[1], init='uniform', activation='softmax')) sgd = SGD(lr=0.001, decay=1e-7, momentum=.9) model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=["accuracy"]) model.fit(X_train, y_train_ohe, nb_epoch=50, batch_size=300, verbose=1, validation_split=0.1) y_train_pred = model.predict_classes(X_train, verbose=0) print('First 3 predictions: ', y_train_pred[:3]) train_acc = np.sum(y_train == y_train_pred, axis=0) / X_train.shape[0] print('Training accuracy: %.8f%%' % (train_acc * 100)) y_test_pred = model.predict_classes(X_test, verbose=0) test_acc = np.sum(y_test == y_test_pred, axis=0) / X_test.shape[0] print('Test accuracy: %.8f%%' % (test_acc * 100)) 以上代码可以顺利跑完了,但是跑出来的分类结果却跟期待的不太一样 53400/54000 [============================>.] - ETA: 0s - loss: 0.2002 - acc: 0.9409 53700/54000 [============================>.] - ETA: 0s - loss: 0.2003 - acc: 0.9409 54000/54000 [==============================] - 2s - loss: 0.2002 - acc: 0.9409 - val_loss: 0.1840 - val_acc: 0.9478 ('First 3 predictions: ', array([3, 0, 4])) Training accuracy: 0.00000000% Test accuracy: 0.00000000% 特意将准确率打印到小数点后8位,准确率居然为0!!!!what happened?? 难道标签错乱??有点儿方,寻找答案中。。。。 后记: 经过debug,发现问题出在我的python除法运算上,两个整数相除,还是整数。python版本导致,貌似3.0以上版本没有此问题。 如果想得到float结果,将其中一个强行转化为float型,如 1/2 = 0 1/float(2)=0.5 其实有两种处理方法,请参考下文: http://blog.csdn.net/yygydjkthh/article/details/39377265 最后5行代码应该修正为: train_acc = np.sum(y_train == y_train_pred, axis=0) /float( X_train.shape[0]) print('Training accuracy: %.8f%%' % (train_acc * 100)) y_test_pred = model.predict_classes(X_test, verbose=0) test_acc = np.sum(y_test == y_test_pred, axis=0) / float(X_test.shape[0]) print('Test accuracy: %.8f%%' % (test_acc * 100)) 至此,完成使用keras对MNIST手写数字分类实例的运行。 接下来,继续学习理论知识和python的使用。

    转载请注明原文地址: https://ju.6miu.com/read-971765.html

    最新回复(0)