深度学习基础知识-感知机+神经网络的学习

news2024/11/16 12:44:33

参考书籍:(找不到资源可以后台私信我)
《深度学习入门:基于Python的理论与实现 (斋藤康毅)》
《Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow, 2nd Edition (Aurelien Geron [Géron, Aurélien])》


机器学习和深度学习的区别:
在这里插入图片描述

神经网络的构造

Perceptron(感知机)

感知机就是一种接收多种输入信号,输出一个信号的原件。输入信号被送往神经元时,会被分别乘以固定的权重,神经元会计算传送来的信号的总和,只有当这个总和超过某个界限值时,才会输出1,此时被称为“神经元被激活”,这个界限值称为阈值。(可以把阈值挪到等式的左边,那只需要比较总和减阈值与0的关系)

感知机的实现就是TLU(Threshold Logic Unit),如下图所示。其中X和W都是向量,Z其实计算的就是加权和。再经过step函数就得到了输出。
在这里插入图片描述
常用的step function有两种:
在这里插入图片描述
设置不同的权重和阈值,我们可以用感知机表示与门、与非门、或门(此处不再证明)。下图中直线就可以是一个或门,很好地把(0,0)和(1,0)、(0,1)、(1,1)分开了。
在这里插入图片描述
但是,单个感知机无法表示异或门,因为异或需要用曲线来分类。也就是说,单层感知机只能表示线性空间。
在这里插入图片描述
使用多层感知机即可表示异或:
在这里插入图片描述
如果像下图一样,每个神经元都接收前一层的每个输出,那就是全连接层(fully connected layer / dense layer)。
在这里插入图片描述
输出的计算公式为:
在这里插入图片描述
其中b是bias vector,每个神经元都有一个bias。Φ是激活函数,如果神经元是TLU,那么Φ就是step function。其他的激活函数还有sigmoid、ReLU、softmax等。用上sigmoid就是神经网络了

Multilayer Perceptron

在这里插入图片描述
跟前面的单层perceptron的区别就是加了隐藏层。其中靠近输入层的也叫lower layers,靠近输出层的也叫upper layers。除了输出层都有bias神经元,每一层也都是全连接的。上图也是feedforward neural network(FNN)。

激活函数

神经网络的激活函数必须使用非线性函数。因为如果使用线性函数,那么加深神经网络的层数是没有意义(只是改了权重/参数)。

输出层所用的激活函数,要根据求解问题的性质决定。一般来说,回归问题可以使用恒等函数(直接输出,不作任何处理),二分类问题可以用sigmoid函数,多元分类问题可以使用softmax函数(只是训练阶段,在推理阶段,一般会省略掉sofmax)。

sigmoid函数:
在这里插入图片描述
ReLU(Rectified Linear Unit)函数:
在这里插入图片描述
softmax函数:
在这里插入图片描述
由于指数增长是很恐怖的,所以为了防止溢出,如下图所示修改这个函数,并且将 C’ 改成 -max(x)
在这里插入图片描述
python实现:

def step_func(X):
    return np.array(X > 0, dtype=int)

def sigmoid_func(X):
    return 1 / (1 + np.exp(-X))
    
def relu(X):
    return np.maximum(0, X)

def softmax(X):
    c = np.max(X)
    exp_X = np.exp(X - c)
    sum_exp_X = np.sum(exp_X)
    y = exp_X / sum_exp_X
    return y

输出层的神经元数量需要根据问题决定。对于分类问题,输出层的神经元数量一般设为类别的数量。比如使用mnist训练手写数字分类器,那可以给输出层设置10个神经元,每个神经元对应一个数字。

输入数据的集合称为批(batch)。因为计算机一般会为批处理做优化,所以以batch为单位进行推理会比较快。

神经网络的学习

损失函数(loss function)

损失函数是表示神经网络性能的“恶劣程度”的指标,即当前的神经网络对监督数据在多大程度上不拟合。在神经网络的学习/训练中,寻找最优参数(权重W和偏置B)时,要寻找使损失函数的值尽可能小的参数,此时需要计算参数的导数,然后以导数为指引,逐步更新参数的值。

可以用作损失函数的有:

均方误差(mean squared error)
在这里插入图片描述

def mean_squared_error(y, t):
    return 0.5 * np.sum((y - t) ** 2)

交叉熵误差(cross entropy error):其中y是one-hot表示,所以只需要计算正确预测的情况。比如正确标签的索引是2,神经网络的输出是0.6,那么 E = -ln0.6
在这里插入图片描述

def cross_entropy_error(y, t):
    delta = 1e-7
    # 加一个delta是为了避免log(0)的情况
    return -np.sum(t * np.log(y + delta))

如果扩展到计算一批的误差,则是
在这里插入图片描述
mini-batch学习:从训练数据中选出一批数据(mini-batch),然后对每个mini-batch进行学习。只要计算随机选出的这批数据的损失函数,就可以近似得到所有训练数据的损失。

那么,mini-batch的交叉熵误差这样计算:

def cross_entropy_error_1hot_batch(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
    batch_size = y.shape[0]
    delta = 1e-7
    return -np.sum(t * np.log(y + delta)) / batch_size

def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
    batch_size = y.shape[0]
    delta = 1e-7
    return -np.sum(np.log(y[np.arrange(batch_size), t] + delta)) / batch_size

数值微分(Numerical differentiation)

前面说了,在计算神经网络的参数的时候,需要计算参数的导数。计算导数时,实际计算的是近似值。如下图所示,当h足够小的时候可以认为近似值足够接近真值。
在这里插入图片描述
数值微分指的就是用数值方法近似求解导数的过程。如果以x为中心,计算左右两边的差分,就是中心差分:(如果是 x+h 与 x
之间就是前向差分)
在这里插入图片描述
如果是基于数学式的推导求导数就称为解析性求导(analytic differentiation)。比如y=x^2的导数y’=2x。解析性求导得到的导数是不含误差的真实导数。

偏导数是在有多个变量的情况下,对某一个变量进行求导。比如
在这里插入图片描述
它的偏微分是:
在这里插入图片描述
求法就是将其他变量看作常数,只对当前变量做求导。

如果把所有变量的偏导数合在一起变成向量,就称为梯度(gradient)。梯度指示的方向是各点处的函数值减小最多的方向,但并不保证梯度所指的方向就是函数的最小值。

梯度法:从某个位置沿梯度方向前进一段,再重新求梯度,再继续按新梯度方向前进,以此逐渐减小函数值。寻找最小值的梯度法称为梯度下降法(gradient descent method),反之称为梯度上升法(gradient ascent method)。

梯度法想要寻找梯度为0的点,但是梯度为0处不一定是最小值。比如函数的极小值就是局部最小值,而鞍点(saddle point,指从某个方向看是极大值,从另一个方向看是极小值的点)也不是最小值。而且,如果函数很复杂且比较扁平,那么学习可能会进入一个平坦区域(“学习高原”),此时将无法前进。
在这里插入图片描述

def numerical_gradient(f, x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x) # 生成和x形状相同的数组
    for idx in range(x.size):
        tmp_val = x[idx]
        # f(x+h)的计算
        x[idx] = tmp_val + h
        fxh1 = f(x)
        # f(x-h)的计算
        x[idx] = tmp_val - h
        fxh2 = f(x)
        # 计算导数
        grad[idx] = (fxh1 - fxh2) / (2*h)
        x[idx] = tmp_val # 还原值
    return grad

def gradient_descent(f, init_x, lr=0.01, step_num=100):
    x = init_x
    for i in range(step_num):
        grad = numerical_gradient(f, x)
        x -= lr * grad
    return x

学习率是超参数。权重和偏置可以通过训练获取,但学习率需要人工设定。

总结:神经网络的学习过程

神经网络存在合适的权重和偏置,调整它们以便拟合训练数据,这一过程称为“学习”。学习分为4个步骤:

  1. mini-batch
    从训练数据中随机选出一部分数据称为mini-batch。后续的目标是减小mini-batch的损失函数的值。
  2. 计算梯度
    求出各个权重参数的梯度。
  3. 更新参数
    将权重参数沿着梯度方向进行微小更新。
  4. 重复前三个步骤

一个epoch表示学习中所有训练数据都被使用过一次时的更新次数。比如有1w个训练数据,每个mini-batch是100个,那么就要做100次随机梯度下降,所以epoch=100。实际操作时会先将所有训练数据随机打乱,然后按指定的batch size,按顺序生成mini-batch。

下面是示意代码。没有跑,因为部分函数需要修改。

class TwoLayerNet:
    def __init__(self, input_size, hidden_size, output_size,
                 weight_init_std=0.01):
        self.params = {}
        # 生成服从正态分布的数据,(r, c)
        self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size)
        self.params['b2'] = np.zeros(output_size)

    def sigmoid_func(self, X):
        return 1 / (1 + np.exp(-X))

    def softmax(self, X):
        c = np.max(X)
        exp_X = np.exp(X - c)
        sum_exp_X = np.sum(exp_X)
        y = exp_X / sum_exp_X
        return y

    def cross_entropy_error(self, y, t):
        if y.ndim == 1:
            t = t.reshape(1, t.size)
            y = y.reshape(1, y.size)
        batch_size = y.shape[0]
        delta = 1e-7
        return -np.sum(np.log(y[np.arrange(batch_size), t] + delta)) / batch_size

    def predict(self, x):
        W1, W2 = self.params['W1'], self.params['W2']
        b1, b2 = self.params['b1'], self.params['b2']
        a1 = np.dot(x, W1) + b1
        z1 = self.sigmoid_func(a1)
        a2 = np.dot(z1, W2) + b2
        y = self.softmax(a2)
        return y

    def loss(self, x, t):
        y = self.predict(x)
        return self.cross_entropy_error(y, t)

    def accuracy(self, x, t):
        y = self.predict(x)
        y = np.argmax(y, axis=1)
        t = np.argmax(t, axis=1)
        acc = np.sum(y == t) / float(x.shape[0])
        return acc

    def numerical_gradient(self, f, x):
        h = 1e-4  # 0.0001
        grad = np.zeros_like(x)  # 生成和x形状相同的数组
        for idx in range(x.size):
            tmp_val = x[idx]
            # f(x+h)的计算
            x[idx] = tmp_val + h
            fxh1 = f(x)
            # f(x-h)的计算
            x[idx] = tmp_val - h
            fxh2 = f(x)
            # 计算导数
            grad[idx] = (fxh1 - fxh2) / (2 * h)
            x[idx] = tmp_val  # 还原值
        return grad

    def gradient(self, x, t):
        loss_W = lambda W: self.loss(x, t)
        grads = {}
        grads['W1'] = self.numerical_gradient(loss_W, self.params['W1'])
        grads['b1'] = self.numerical_gradient(loss_W, self.params['b1'])
        grads['W2'] = self.numerical_gradient(loss_W, self.params['W2'])
        grads['b2'] = self.numerical_gradient(loss_W, self.params['b2'])
        return grads

X_train, y_train, X_test, y_test = get_data()
train_size = X_train.shape[0]
batch_size = 100
train_loss_list = []
train_acc_list = []
test_acc_list = []
iter_per_epoch = max(train_size / batch_size, 1)
# hyperparameters
iters_num = 10000
learning_rate = 0.1
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
for i in range(iters_num):
    # get mini-batch
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = X_train[batch_mask]
    y_batch = y_train[batch_mask]
    # calc gradient
    grad = network.numerical_gradient(x_batch, y_batch)
    for key in ('W1', 'b1', 'W2', 'b2'):
        network.params[key] -= learning_rate * grad[key]
    loss = network.loss(x_batch, y_batch)
    train_loss_list.append(loss)
    # 计算每个epoch的识别精度
    if i % iter_per_epoch == 0:
        train_acc = network.accuracy(X_train, y_train)
        test_acc = network.accuracy(X_test, y_test)
        train_acc_list.append(train_acc)
        test_acc_list.append(test_acc)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/464005.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(转)mysql数据库安装指南

如果你的电脑是mac,参考社群会员 奔跑的土豆 的分享: https://http://zhuanlan.zhihu.com/p/37942063232 赞同 162 评论文章 如果你的电脑是windows,参考下面的安装步骤。 一、下载mysql数据库 进入MySQL官方网站(MySQL Co…

ARM Cortex-R52 通用中断控制器GIC:Generic Interrupt Controller(一)

ARM Cortex-R52 GIC:Generic Interrupt Controller 前言:名词解释 英文缩写英文全称(中文释义)GICgeneral interrupt controllerITSInterrupt Translation Service:用来解析中断SPIShared Peripheral InterruptsPPIPrivate peripheral inte…

BM40-重建二叉树

题目 给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。 提示: 1.vin.length pre.length 2.pre 和 vin 均无重复…

超算云服务深度学习环境配置及使用方法

目录 一、环境配置 1. 通过SSH连接服务器 2. 查看服务器已安装模块 3. 调用Anaconda模块 4. 创建Python3.7的虚拟环境(不是必须。不需要的话可以使用默认安装的环境) 5. 虚拟环境下安装CUDA11.6Pytorch1.12.1 二、使用方法 1、提交作业 2、其他…

CKA证书模拟考试24道题

CKA证书模拟24道题-题解 快捷别名 alias kkubectl # will already be pre-configured export do"--dry-runclient -o yaml" # k create deploy nginx --imagenginx $do export now"--force --grace-period 0" # k delete p…

FPGA学习_01_基础知识(有点劝退,心灵弱小者勿入)

有些人喜欢直接拿开发板看教程开干,我认为了解点历史发展没什么坏处,一些FPGA的基础知识也是同样重要的。 1.1. FPGA的主要厂商 XILINX 占据FPGA绝大部分的市场份额 ALTERA 被 INTEL 167亿美元收购 改名为INTEL LATTICE 被神秘的中国公…

成就客户 | 企业如何培养“数据文化”?Smartbi教你3个步骤

随着数字化浪潮的发展,越来越多企业在实际工作中通过采用BI等各种数据处理工具提升工作效率。诚然,BI 工具可以帮助员工更好地理解和分析数据,从而发现业务中的机遇和挑战,然而如果仅仅只是提供工具和技术,而不重视培养…

浅谈“孔乙己的长衫“是脱不下来还是难脱下?

名人说:往者不可谏,来者犹可追。——《论语微子篇》 创作者:Code_流苏(CSDN) ★温馨提示:以下仅代表个人观点,不代表其它任何人看法。 目录 〇、缘由一、社会对于学历和职业之间的关系认知是怎样的?二、学…

密歇根大学Python系列之二:Python 编程进阶

Python如今无疑是全球最受欢迎的编程语言。它最大的好处,就是让越来越多的人通过它加入了编程的世界。学习Python是个好主意。无论你是一个初学者还是C或Java专家,都无需担心其派不上用场。 Paul Resnick 教授是密歇根大学迈克尔科恩学院的信息学教授&a…

解决软件项目冲突的5个重点

1、针对人员冲突管理 信任和沟通是解决人员冲突的关键。常见的人员冲突多表现为不信任和沟通不畅。 企业高层需要对项目经理充分信任和授权,以充分发挥项目经理的能力。项目经理对项目至关重要,如果项目经理频繁换人,高层领导变动&#xff0c…

云原生-k8s核心概念(pod,deploy,service,ingress,configmap,volume)

Gitee-k8s学习 云原生实战-kubernetes核心实战 namespace Namespace是kubernetes系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离 Pod Pod可以认为是容器的封装,一个Pod中可以存在一个或者多个容器。 De…

C#开发的OpenRA的游戏用户的添加

C#开发的OpenRA的游戏用户的添加 OpenRA游戏前面在游戏开始的按钮的界面, 可以看到可以添加游戏用户,小规模战斗的界在,就是默认两个用户, 一个是玩家,一个是电脑的AI, 如果感觉少了,可以添加多几个电脑AI,这样做也是可以的。 不过在代码里是怎么样实现添加用户的呢…

word表格

新建(修改)“表格”样式 新建和修改样式的设置差不多,这里放在一起介绍 设置样式时,注意按图中的步骤设置,以免导致格式的应用出错,这里分四步: 格式应用于 “整个表格”:“字体”…

启英泰伦智能语音芯片在语音控制吸顶灯上的应用解决方案

随着智能控制技术的不断发展,人们对于家用电器的功能需求越来越多,智能吸顶灯是一种常见的照明设备,通常被安装在室内房顶上面,除了具有传统吸顶灯的照明功能外,还添加了智能控制和自动化功能,如远程控制、…

python Import Error: cannot import name SystemRandom

目录 一、前言二、解决方法三、改名之后带来的问题解决四、总结 一、前言 今天运行项目里面的文件,发现我简单的调试都不行,导入包就是不行,但是我新建一个窗口,把运行文件复制到另一个目录下就可以,就很奇怪。 报错信…

速卖通正式推出全托管,卖家竞争进入新阶段

全托管来了,卖家就能安心做甩手掌柜吗? 正式推出全托管 显而易见,越来越多的平台正在转向全托管模式。 近日,速卖通在2023年度商家峰会上,正式推出了全托管服务模式。官方表示,托管是对速卖通平台商家服…

市级大数据中心大数据资源平台概要设计方案(ppt可编辑)

本资料来源公开网络,仅供个人学习,请勿商用,如有侵权请联系删除。 大数据管理中心发展背景 为建设卓越全球城市,实现政府治理能力现代化目标,由市大数据中心牵头,在政务公共数据管理和互联网政务服务方面…

一场没有英伟达/高通的上海车展

两年一度的上海国际车展,在2023年迎来「质」的变化。一方面,电动化浪潮已成定局,无论是传统自主品牌,还是合资品牌,新能源车型成为展区的主角。另一方面,零部件供应商的合纵连横,中外合作&#…

dubbogo如何实现远程配置管理 -- 阅读官方文档

dubbo-go 中如何实现远程配置管理? 之前在 Apache/dubbo-go(以下简称 dubbo-go )社区中,有同学希望配置文件不仅可以放于本地,还可以放于配置管理中心里。那么,放在本地和配置管理中心究竟有哪些不一样呢&…

Android 各大厂面试题汇总与详解(持续更新)

介绍 目前网络中出现了好多各种面试题的汇总,有真实的也有虚假的,所以今年我将会汇总各大公司面试比较常见的问题,逐一进行解答。会一直集成,也会收集大家提供的面试题,如有错误,请大家指出,经过…