如何使用神经网络识别手写数字

我按照一个教程创建了一个使用Sigmoid函数的简单神经网络“使用神经网络识别手写数字”,这个教程理论和代码示例都很简单。

问题在于它没有提供使用network.py进行数字识别的任何示例。

例如,我有下面的数字,我想从下图中识别出它是0enter image description here接下来我应该如何进行数字识别?

进行数字识别是否需要使用其他技术如Theano或TensorFlow?祝好!


回答:

基于下面的示例,您可以在NeuralNetwork类中添加一个预测函数:

def predict(self, image):    return np.argmax(self.__feedforward(image.astype(bool).astype(int)))

一旦您成功训练了神经网络,您可以用以下方式预测未知数字,准确率可达97%:

prediction = NN.predict(image)

摘自神经网络 – 入门:用Python构建一个简单的ANN。原作者是cᴏʟᴅsᴘᴇᴇᴅdontloo。归属详情可以在贡献者页面找到。源代码根据CC BY-SA 3.0许可证发布,并且可以在文档存档中找到。参考主题ID:2709和示例ID:9069。

下面的代码清单尝试对MNIST数据集中的手写数字进行分类。这些数字看起来像这样:

MNIST

代码将预处理这些数字,将每张图片转换成一个由0和1组成的二维数组,然后使用这些数据来训练一个神经网络,准确率可达97%(50个周期)。

"""深度神经网络(名称:经典前馈)"""import numpy as npimport pickle, jsonimport sklearn.datasetsimport randomimport timeimport os# 记录各种激活函数及其导数def sigmoid(z):    return 1.0 / (1.0 + np.exp(-z))def sigmoid_prime(z):    return sigmoid(z) * (1 - sigmoid(z))def relU(z):    return np.maximum(z, 0, z)def relU_prime(z):    return z * (z <= 0)def tanh(z):    return np.tanh(z)def tanh_prime(z):    return 1 - (tanh(z) ** 2)def transform_target(y):    t = np.zeros((10, 1))    t[int(y)] = 1.0    return tclass NeuralNet:    def __init__(self, layers, learning_rate=0.05, reg_lambda=0.01):        self.num_layers = len(layers)          # 初始化网络参数        self.layers = layers                  self.biases = [np.zeros((y, 1)) for y in layers[1:]]            self.weights = [np.random.normal(loc=0.0, scale=0.1, size=(y, x))                                        for x, y in zip(layers[:-1], layers[1:])]        self.learning_rate = learning_rate        self.reg_lambda = reg_lambda        # 初始化网络激活函数         self.nonlinearity = relU        self.nonlinearity_prime = relU_prime    def __feedforward(self, x):        ''' 返回输出层的softmax概率 '''        for w, b in zip(self.weights, self.biases):            x = self.nonlinearity(np.dot(w, np.reshape(x, (len(x), 1))) + b)        return np.exp(x) / np.sum(np.exp(x))    def __backpropagation(self, x, y):        '''        执行前向传递后进行反向传播         :param x: 输入        :param y: 目标        '''        weight_gradients = [np.zeros(w.shape) for w in self.weights]        bias_gradients = [np.zeros(b.shape) for b in self.biases]        # 前向传递 - 将输入转换为输出softmax概率        activation = x        hidden_activations = [np.reshape(x, (len(x), 1))]        z_list = []        for w, b in zip(self.weights, self.biases):                z = np.dot(w, np.reshape(activation, (len(activation), 1))) + b            z_list.append(z)            activation = self.nonlinearity(z)            hidden_activations.append(activation)        t = hidden_activations[-1]         hidden_activations[-1] = np.exp(t) / np.sum(np.exp(t))   # softmax层        # 后向传递        delta = (hidden_activations[-1] - y) * (z_list[-1] > 0)        weight_gradients[-1] = np.dot(delta, hidden_activations[-2].T)        bias_gradients[-1] = delta        for l in range(2, self.num_layers):            z = z_list[-l]            delta = np.dot(self.weights[-l + 1].T, delta) * (z > 0)            weight_gradients[-l] = np.dot(delta, hidden_activations[-l - 1].T)            bias_gradients[-l] = delta        return (weight_gradients, bias_gradients)    def __update_params(self, weight_gradients, bias_gradients):        ''' 在反向传播步骤后更新网络参数 '''        for i in xrange(len(self.weights)):            self.weights[i] += -self.learning_rate * weight_gradients[i]            self.biases[i] += -self.learning_rate * bias_gradients[i]    def train(self, training_data, validation_data=None, epochs=10):        ''' 训练网络进行`epoch`次迭代 '''        bias_gradients = None        for i in xrange(epochs):            random.shuffle(training_data)            inputs = [data[0] for data in training_data]            targets = [data[1] for data in training_data]            for j in xrange(len(inputs)):                (weight_gradients, bias_gradients) = self.__backpropagation(inputs[j], targets[j])                self.__update_params(weight_gradients, bias_gradients)            if validation_data:                 random.shuffle(validation_data)                inputs = [data[0] for data in validation_data]                targets = [data[1] for data in validation_data]                for j in xrange(len(inputs)):                    (weight_gradients, bias_gradients) = self.__backpropagation(inputs[j], targets[j])                    self.__update_params(weight_gradients, bias_gradients)            print("{} epoch(s) done".format(i + 1))        print("Training done.")    def test(self, test_data):        test_results = [(np.argmax(self.__feedforward(x[0])), np.argmax(x[1])) for x in test_data]        return float(sum([int(x == y) for (x, y) in test_results])) / len(test_data) * 100    def dump(self, file):        pickle.dump(self, open(file, "wb"))if __name__ == "__main__":    total = 5000    training = int(total * 0.7)    val = int(total * 0.15)    test = int(total * 0.15)    mnist = sklearn.datasets.fetch_mldata('MNIST original', data_home='./data')    data = zip(mnist.data, mnist.target)    random.shuffle(data)    data = data[:total]    data = [(x[0].astype(bool).astype(int), transform_target(x[1])) for x in data]    train_data = data[:training]    val_data = data[training:training+val]    test_data = data[training+val:]    print "Data fetched"    NN = NeuralNet([784, 32, 10]) # 定义一个ANN,包含1个输入层(大小784 = 图像展平的大小),1个隐藏层(大小32),和1个输出层(大小10,索引i的单元将预测图像为数字i的概率,其中0 <= i <= 9)      NN.train(train_data, val_data, epochs=5)    print "Network trained"    print "Accuracy:", str(NN.test(test_data)) + "%"

这是一个独立的代码样本,无需进一步修改即可运行。确保您已为您的Python版本安装了numpyscikit学习库。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注