我按照一个教程创建了一个使用Sigmoid函数的简单神经网络“使用神经网络识别手写数字”,这个教程理论和代码示例都很简单。
问题在于它没有提供使用network.py进行数字识别的任何示例。
例如,我有下面的数字,我想从下图中识别出它是0接下来我应该如何进行数字识别?
进行数字识别是否需要使用其他技术如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数据集中的手写数字进行分类。这些数字看起来像这样:
代码将预处理这些数字,将每张图片转换成一个由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版本安装了numpy
和scikit
学习库。