《斋藤康毅-深度学习入门》读书笔记03-神经网络

从本章开始,会接触到一些深度学习理论框架的知识,为以后实现算法打好基础。 本章新接触的概念有:

  • 神经网络
  • 激活函数(step, sigmoid, ReLU, softmax)
  • 矩阵与矩阵运算
  • 训练集(train),测试集(test)
  • 正规化(normalization),预处理(pre-processing)
  • 批处理(batch)

从感知机到神经网络

图:感知机的图形表达

图:感知机的算式表达

首先复习一下感知机的结构,它由输入输出权重偏置几个元素组成,单层感知机是线性的,通过组合多个单层感知机可以得到多层感知机,用于表达非线性空间。但是,其中的难点在于如何确定每个输入的权重,也就是调参。设定权重的工作依赖于人工进行,而神经网络则是一种可以自动从数据中学习从而得到参数的技术。

在感知机的算式表达中,θ表示神经元被激活的难易程度,可以把它从不等式右侧移到左侧,从而得到偏置b,它的权重是1

图:明确表示出偏置

此时引入激活函数(activation function)的概念,根据算式结果决定输出是0还是1。

图:激活函数的算式表达

图像表达如下:

图:激活函数的图像表达

激活函数

常见的激活函数有

  • 阶跃函数
  • sigmoid函数
  • ReLU函数

阶跃函数

以0为界的跳变,<=0输出0,>0输出1,呈阶梯状变化,故称为阶跃函数。

py 复制代码
# 阶跃函数
import numpy as np
import matplotlib.pylab as plt 

def step_function(x):
	return np.array(x>0, dtype=np.int64) # 将boolean转换为int

x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()

输出:

sigmoid函数

利用到了自然对数e=2.7182,能够在保留原始大小关系的基础上,将输出局限在-1~1之间。

图:sigmoid函数算式

py 复制代码
def sigmoid(x):
	return 1/(1+np.exp(-x))

线性函数(y=cx)的问题在于,不管如何加深层数,总是存在一个与之等价的单层感知机,无法发挥多层网络带来的优势。因此激活函数必须选择非线性函数。

ReLU

Rectified Linear Unit 修正线性单元,修正指的是对于负数和0返回0。

图:ReLU的算式表达

py 复制代码
def relu(x):
    return np.maximum(0, x)

多维数组与矩阵

[[1,2], [3,4], [5,6]]是一个3*2的矩阵,即3行2列。从最外层的中括号开始向内算起,第一级的组数即行数,每一组内的元素数即列数。

矩阵乘法(内积),行与列交叉相乘,相加作为结果矩阵的元素。因此矩阵的行列数在相乘过程中需要前后衔接。

用矩阵乘法表示神经元的信号传递过程

对于权重w而言

  • 上标:表示当前计算的是第几层(输出)的权重(从0开始计数)
  • 下标-左侧:指向输出层第几个神经元(从1开始计数)
  • 下标-右侧:来自输入层第几个神经元(从1开始计数)

神经元从1开始计数,但(输出)层数从0开始计数,这样做的原因是偏置b其实可以作为第0个神经元

一个三层神经网络可以描述为下图:

机器学习问题:分类与回归

机器学习主要研究两类问题:

  • 分类 :数据属于哪一类别,如根据照片判断男人还是女人
    • 二元分类问题可以使用sigmoid函数
    • 多元分类问题使用softmax函数
  • 回归 :预测一个连续的数值,如预测明天的气温
    • 回归问题使用恒等函数

图:恒等函数与softmax函数

图:softmax函数的算式表达

由算式可知,softmax输出层各元素总和是1。

py 复制代码
def softmax(a):
    exp_a = np.exp(a)
    sum_exp_a = np.sum(exp_a)
    y = exp_a / sum_exp_a
    return y

softmax函数会面临溢出问题,可以减去输入中的最大值来避免

py 复制代码
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

实践:手写数字识别

神经网络确定权重的过程,可分为学习和推理两个步骤:

  • 学习:使用训练数据进行权重参数学习
  • 推理 :也称为前向传播(forward propagation),使用刚才学习到的参数对输入数据进行分类

MNIST数据集,是一个手写数字图像集,训练集6w,测试集1w。每张图片都是28*28像素的灰度图像,像素灰度值[0, 255]

首先需要下载数据集,这部分已经封装进了load_mnist函数中,数据集会被下载到../dataset/目录下,需要注意单张图片(28*28)在读入时是经过flatten的,已经被拉平成一维数组,在显示时需要reshape还原。

py 复制代码
# mnist_show.py
# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 把父目录及其全部子目录和文件加入到python检索路径中(默认只检索当前目录)
import numpy as np
from dataset.mnist import load_mnist
from PIL import Image


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)  # 5

print(img.shape)  # (784,)
img = img.reshape(28, 28)  # 把图像的形状变为原来的尺寸
print(img.shape)  # (28, 28)

img_show(img)

这里先跳过训练部分,直接使用训练完成的参数,在测试集上进行验证。

py 复制代码
# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax


# 返回测试集的数据和标签
def get_data():
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
    return x_test, t_test


# 之前训练完成的权重&偏置
def init_network():
    with open("sample_weight.pkl", 'rb') as f:
        network = pickle.load(f)
    return network


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


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)))

输出识别精度accuracy

bash 复制代码
λ python neuralnet_mnist.py
Accuracy:0.9352

正规化与预处理

  • 正规化(normalization) :把数据限定到某个范围内的处理,如把输入图片像素色值除255,得到0~1之间的色值
  • 预处理(pre-processing):对神经网络的输入数据进行转换,正规化是预处理的一种

批处理(batch)

节约数据读入时间,克服数据传输的瓶颈,利用数值计算库的大型数组运算优化功能。

例:100个每批

py 复制代码
batch_size = 100 # 批数量
accuracy_cnt = 0

for i in range(0, len(x), batch_size):
    x_batch = x[i:i+batch_size]
    y_batch = predict(network, x_batch)
    p = np.argmax(y_batch, axis=1)
    accuracy_cnt += np.sum(p == t[i:i+batch_size])

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
相关推荐
WWZZ202543 分钟前
快速上手大模型:深度学习3(实践:线性神经网络Softmax)
人工智能·深度学习·神经网络·机器人·大模型·slam·具身感知
电鱼智能的电小鱼2 小时前
基于电鱼 ARM 工控机的煤矿主控系统高可靠运行方案——让井下控制系统告别“死机与重启”
arm开发·人工智能·嵌入式硬件·深度学习·机器学习
OAFD.2 小时前
深度学习之图像分割:从基础概念到核心技术全解析
人工智能·深度学习
武子康2 小时前
AI研究-116 特斯拉 HW3.0 与 HW4.0 区别详解:摄像头分辨率、FSD算力、雷达与Vision泊车
人工智能·深度学习·计算机视觉·ai·自动驾驶·汽车·视觉检测
TGITCIC3 小时前
通过神经网络手搓一个带finetune功能的手写数字识别来学习“深度神经网络”
人工智能·深度学习·机器学习·卷积神经网络·dnn·文字识别·识别数字
袁气满满~_~3 小时前
关于jupyter notebook调用GPU
人工智能·深度学习·jupyter
熊猫_豆豆4 小时前
神经网络的科普,功能用途,包含的数学知识
人工智能·深度学习·神经网络
xian_wwq5 小时前
【学习笔记】深度学习中梯度消失和爆炸问题及其解决方案研究
人工智能·深度学习·梯度
XIAO·宝7 小时前
深度学习------图像分割项目
人工智能·深度学习·图像分割
渡我白衣10 小时前
C++:链接的两难 —— ODR中的强与弱符号机制
开发语言·c++·人工智能·深度学习·网络协议·算法·机器学习