《斋藤康毅-深度学习入门》读书笔记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)))
相关推荐
scott19851210 分钟前
扩散模型之(二十)Stable Diffusion的运作原理
深度学习·stable diffusion·扩散模型·生成式
YuanDaima204818 分钟前
解决Conda环境下RTX 50系列显卡PyTorch+Transformers+PEFT微调报错
人工智能·pytorch·笔记·python·深度学习·机器学习·conda
适应规律38 分钟前
深度学习第四版
人工智能·深度学习
八角Z1 小时前
从行为惯性到正向认同:留守问题青年在数字社群中的风险机制与干预策略研究
科技·深度学习·创业创新
枫叶林FYL1 小时前
MCP 实现深度技术报告
人工智能·深度学习
iiiiii111 小时前
【LLM学习笔记】Batch Normalization vs Layer Normalization,为什么 NLP 中使用 LN 而非 BN
笔记·深度学习·学习·语言模型·大模型·llm·transformer
Elastic 中国社区官方博客1 小时前
从判断列表到训练好的 Learning to Rank( LTR )模型
大数据·数据库·人工智能·深度学习·elasticsearch·搜索引擎·全文检索
卡梅德生物科技小能手1 小时前
深度解析先天免疫核心受体:TLR2(CD282)的分子机制、信号通路与药物研发技术路径
经验分享·深度学习·生活
HyperAI超神经1 小时前
在线教程丨华中科大与小红书 hi lab开源dots.mocr,SOTA级OCR模型完美还原文档结构,图形也能转 SVG
人工智能·深度学习·学习·机器学习·gpu·orc·vllm
jay神1 小时前
垃圾分类检测数据集
人工智能·深度学习·yolo·目标检测·毕业设计