人工智能00025 深度学习与图像识别书评25 神经网络基础07
下面我们来回顾下MNIST的前向传播,从整体的处理流程来看,输入虽然是一个形状为(10000,784)的数据集,但其实每次计算都是一张图一张图地来计算(代码本身是使用for循环来获取每一个数据),单个处理 回顾一下我们之前所写的代码,标黑的部分所代表的就是处理一张一张的图片,具体如下:
for i in range(len(x)):
y = forward(network, x[i])
p = np.argmax(y) #获取概率最高的元素的索引
if p == labels[i]:
accuracy_cnt += 1 如果我们一次直接打包10000条数据(或者更大规模的数据),则可能会造成数据传输的瓶颈,批处理对计算机运算的好处在于,批处理可以减轻数据总线的负荷。
如果我们考虑使用批处理来打包100张图像将其作为一个批次,则需要将X的形状改为100*784,再将100张图像打包在一起作为输入数据, 代码需要修改两个地方,具体说明如下。
其中之一是对我们之前所写的Softmax做一个修改,之前的Softmax只支持向量。现在我们修改下使之可以支持矩阵,修改后的代码如下:
import numpy as np
def _softmax(x):
if x.ndim == 2:
c = np.max(x,axis=1)
x = x.T - c #溢出对策
y = np.exp(x) / np.sum(np.exp(x),axis=0)
return y.T
c = np.max(x)
exp_x = np.exp(x-c)
return exp_x / np.sum(exp_x) 另外一个需要修改的地方如代码段中标黑部分所示:
accuracy_cnt = 0
batch_size = 100
x = test_dataset.test_data.numpy().reshape(-1,28*28)
labels = test_dataset.test_labels.numpy()
for i in range(0,len(x),batch_size):
x_batch = x[i:i+batch_size]
y_batch = forward(network, x_batch)
p=np.argmax(y_batch,axis=1)
accuracy_cnt += np.sum(p == labels[i:i+batch_size])
print("Accuracy:" + str(float(accuracy_cnt) / len(x) * 100) + "%")
思考: 我们既然发现Softmax函数需要针对矩阵做一定的修改,那么,Sigmoid和ReLU激活函数是否也需要针对矩阵做一定的修改呢?
我们写一段程序测试下就知道了。 首先对于向量与矩阵,我们都初始化一些测试值。
对于Sigmoid激活函数,我们使用a作为矩阵,a1作为向量进行测试,看针对向量与矩阵返回的值是否一致,代码如下:
import numpy as np
a = np.array([[-1,1,2,3],
[-2,-1,4,5]])
a1 = np.array([-1,1,2,3])
def _sigmoid(in_data):
return 1 / (1 + np.exp(-in_data))
print(_sigmoid(a1))
print(_sigmoid(a)) 对于ReLU激活函数,我们做同样的操作,代码如下:
import numpy as np
a = np.array([[-1,1,2,3],
[-2,-1,4,5]])
a1 = np.array([-1,1,2,3])
def _relu(in_data):
return np.maximum(0,in_data)
print(_relu(a))
print(_relu(a1))
测试之后我们可以发现,输入x变为矩阵之后,其对于Sigmoid函数以及ReLU函数不会产生影响。