《斋藤康毅-深度学习入门》读书笔记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)))
相关推荐
BulingQAQ1 小时前
论文阅读:PET/CT Cross-modal medical image fusion of lung tumors based on DCIF-GAN
论文阅读·深度学习·生成对抗网络·计算机视觉·gan
slomay4 小时前
关于对比学习(简单整理
经验分享·深度学习·学习·机器学习
AI完全体5 小时前
【AI知识点】偏差-方差权衡(Bias-Variance Tradeoff)
人工智能·深度学习·神经网络·机器学习·过拟合·模型复杂度·偏差-方差
卷心菜小温6 小时前
【BUG】P-tuningv2微调ChatGLM2-6B时所踩的坑
python·深度学习·语言模型·nlp·bug
陈苏同学6 小时前
4. 将pycharm本地项目同步到(Linux)服务器上——深度学习·科研实践·从0到1
linux·服务器·ide·人工智能·python·深度学习·pycharm
FL16238631297 小时前
[深度学习][python]yolov11+bytetrack+pyqt5实现目标追踪
深度学习·qt·yolo
羊小猪~~7 小时前
深度学习项目----用LSTM模型预测股价(包含LSTM网络简介,代码数据均可下载)
pytorch·python·rnn·深度学习·机器学习·数据分析·lstm
龙的爹23337 小时前
论文 | Model-tuning Via Prompts Makes NLP Models Adversarially Robust
人工智能·gpt·深度学习·语言模型·自然语言处理·prompt
工业机器视觉设计和实现7 小时前
cnn突破四(生成卷积核与固定核对比)
人工智能·深度学习·cnn
醒了就刷牙7 小时前
58 深层循环神经网络_by《李沐:动手学深度学习v2》pytorch版
pytorch·rnn·深度学习