深度学习入门笔记03

  1. 1. 输出层设计
    1. 1.1. 恒等函数和softmax函数
    2. 1.2. 输出层神经元数量
    3. 1.3. 前向传播
      1. 1.3.1. MNIST数据集
      2. 1.3.2. 神经网络的推理处理
    4. 1.4. 批处理

输出层设计

神经网络可以分为两类问题: 分类问题,回归问题

分类问题:属于哪一类问题。 (e.g 根据图片判断人物是男的还是女的)

回归问题:根据输入的值,预测数值问题。(e.g 根据图片预测这个人的身高体重)

恒等函数和softmax函数

恒等函数:将输入原样输出。用于回归问题。

softmax函数:用于分类问题

softmax函数公式表示:

python实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np
#机器学习分为 分类问题 回归问题
#分类问题: e.g 判别图像中的人是男是女
#回归问题: e.g 根据图像,预测这个人的身高体重

# 输出层用到的激励函数: 恒等函数 softmax函数
#恒等函数 ==> 适合解决回归问题,将输入按照原样输出

#softmax函数 ==> 适合解决分类问题
#表示方式为
# y = exp(ak) / n个exp(ai)的总和 exp()为e^x指数函数,n为n个神经元
a = np.array([0.3,2.9,4.0])
exp_a = np.exp(a) #指数函数

sum_exp_a = np.sum(exp_a) #指数和
print(sum_exp_a)

y = exp_a / sum_exp_a
print(y)

print(exp_a)

def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c)#针对溢出问题
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y

这里有个操作 exp_a = np.exp(a - c) 用来解决溢出问题。因为是指数函数,a的值如果变得很大,那会使得发生溢出现象。解决方法很简单,分子分母同时乘上一个常数C,推导如下:

这样一波操作下来,溢出问题解决,y的值是正确的,同时输出的值在0.0到1.0之间,而且softmax输出的值总和为1,因此可以把softmax的输出解释为“概率”

一般来说,神经网络是以输出值最大的作为结果,因为使用了softmax,最大的值概率也是最大的。可以为了减少计算量,不使用softmax,用最大值代替。

输出层神经元数量

根据待解决问题决定,分类问题按照类别数量设定。

前向传播

前向传播:使用学习到的参数,实现神经网络的“推理处理”,这个推理处理也成为神经网络的前向传播

下面通过实例——手写数字识别,完成前向传播过程

MNIST数据集

MNIST数据集是手写数字图像集,有60000个训练样本,10000个测试样本。每张图像是28像素x28像素的单通道灰度图像。

书中提供了方便mnist下载的python文件。python运行mnist.py即可下载数据集,以及训练好的pickle文件。

pickle: python将程序运行中的对象保存为文件,通过加载保存过的pickle文件,可以立刻复原之前运行中的对象。

通过mnist.py中的load_mnist()函数,读出MNIST数据

1
2
3
4
5
6
from mnist import load_mnist
(x_train,t_train),(x_test,t_test) = load_mnist(flatten=True,normalize=False)
print(x_train.shape)
print(t_train.shape)
print(x_test.shape)
print(x_test.shape)

这里只是读出数据,检查是否读出成功。

load_mnist(flatten=True,normalize=False,one_hot_label=False)中

flatten是确定是否将图像展开,意思是如果图像是 1x28x28的三维数组,展开后就是一个784个元素的一维数组。

normalize就是正规化的意思,打开mnist文件可以发现,他做的一件事就是每个像素的值除了一个255,让他在0.0 ~ 1.0之间。这个操作十分重要。

one_hot_label表示将正确解标签为1,意思是有0 - 9这10个数,10个类别。[0,0,1,0,0,0,0,0,0,0] 表示当前的标签正确的是2

显示图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from mnist import load_mnist
from PIL import Image
import numpy as np

def img_show(img):
pil_img = Image.fromarray(np.uint8(img))
pil_img.show()
(x_train,t_train),(x_test,t_test) = load_mnist(flatten=True,normalize=False)

img = x_train[0]
label = t_train[0]
print(label)

print(img.shape)
img = img.reshape(28,28)
print(img.shape)
img_show(img)

神经网络的推理处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from mnist import load_mnist
from PIL import Image
import numpy as np
import pickle
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
def img_show(img):
pil_img = Image.fromarray(np.uint8(img))
pil_img.show()
def get_data():
#此处一定要做正规化,否则在sigmoid函数处会造成溢出问题
(x_train,t_train),(x_test,t_test) = load_mnist(flatten=True,normalize=True)
return x_test,t_test
def init_network():
with open("sample_weight.pkl",'rb') as f:
network = pickle.load(f)
return network
def softmax(x):
c = np.max(x)
exp_a = np.exp(x - c)
sum_exp_a = np.sum(exp_a)
return exp_a / sum_exp_a

def predict(network,x):
W1,W2,W3 = network['W1'],network['W2'],network['W3']
b1,b2,b3 = network['b1'],network['b2'],network['b3']
a1 = np.dot(x,W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1,W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2,W3) + b3
y = softmax(a3)
return y

if __name__ == '__main__':
x,t = get_data()
network = init_network()

accuracy_cnt = 0
for i in range(len(x)):
y = predict(network,x[i])
p = np.argmax(y)
if p == t[i]:
accuracy_cnt += 1

print('Accuracy:' + str(float(accuracy_cnt / len(x))))

批处理