01神经网络的理论及实现

news2024/11/16 3:23:48

感知机的缺点就是需要设置合适的权重,而权重的设置都是人工操作的。

1、从感知机到神经网络

重新画出感知机的模型,在图上加上偏置,由于偏置始终为1,所以颜色加深。

图1-1 感知机模型

  引入新函数(激活函数):

h(x)=\left\{\begin{matrix} 0 (x\leqslant 0)\\ 1(x>0) \end{matrix}\right.                                                        (1-1)

将感知机表达式改为:

y=h(b+w_{1}x_{1}+w_{2}x_{2})                                                (1-2)

也可以分开写为:

a=b+w_{1}x_{1}+w_{2}x_{2}                                                  (1-3)

y=h(a)                                                             (1-4)

根据公式(1-3)和(1-4)可以将图1-1更改为图1-2模型。

图1-2 加入激活函数的感知机图

2、激活函数

激活函数会将输入信号的总和转换为输出信号。

激活函数如果使用阶跃函数,就是感知机。

如果使用其它激活函数,就是神经网络。

2.1 阶跃函数

公式(1-1)就是阶跃函数。

实现代码:

import numpy as np
import matplotlib.pylab as plt

def step_function(x):
    return np.array(x>0,dtype=int)

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

运行结果:

原来的程序运行出错:

AttributeError: module 'numpy' has no attribute 'int'

解决办法:是因为版本的问题,将dtype=np.int更改为dtype=int即可。

2.2 sigmoid函数

   Sigmoid型函数是一类S型曲线函数,为两端饱和函数,常见的有Logistic函数和Tanh函数。

饱和:

      对于函数f(x),若x \to -\infty时,导数\frac{\mathrm{d} f(x)}{\mathrm{d} x}n \to 0,称为左饱和,当x \to +\infty时,导数\frac{\mathrm{d} f(x)}{\mathrm{d} x} \to 0,称为右饱和。两个都满足的情况下称为两端饱和。

2.2.1 Logistic函数

表达式:

h(x)=\frac{1}{1+e^{-x}}                                                                   (1-5)

实现代码:

def sigmoid(x):
    return 1/(1+np.exp(-x))

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

输出:

2.2.2 Tanh函数

表达式:

tanh(x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}}                                                       (1-6)

实现代码:

def tanh(x):
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))

x=np.arange(-5,5,0.1)
y1=tanh(x)
plt.plot(x,y1)
plt.ylim(-1.1,1.1)

plt.show()

输出:

Tanh函数的输出是零中心化的,而Logistic函数的输出恒大于0。非中心化的输出会使得其后一层的神经元的输入发生偏置偏移,并进一步使得梯度下降的收敛速度变慢

2.3 ReLU函数

ReLU(Rectified Linear Unit)函数,表达式为:

h(x)=\left\{\begin{matrix} x (x>0)\\ 0 (x\leqslant 0) \end{matrix}\right.                                                       (1-7)

实现代码:

def relu(x):
    return np.maximum(0,x)

x=np.arange(-6,6,0.1)
y=relu(x)
plt.plot(x,y)
plt.ylim(-1,5)
plt.show()

输出:

优点:

1、只需要进行加、乘和比较的操作,计算更高效。

2、具有很好的稀疏性,大约50%的神经元处于激活状态。

3、具有左饱和函数,在一定程度上缓解了梯度消失问题,加速梯度下降的收敛速度。

缺点:

1、非零中心化,影响梯度下降的效率;

2、死亡ReLU问题,即一次不恰当的更新后,ReLU神经元都不能被激活,永远可能都会是0.

2.3.1 带泄露的ReLU(Leaky ReLU)

在x<0时,可以保持一个很小的梯度\gamma,避免死亡ReLU的问题。

表达式:

\gamma一般选择为0.01.

LeakyReLU(x)=\left\{\begin{matrix} x &if x>0 \\ \\0.01 x & if x\leqslant 0 \end{matrix}\right.                                          (1-8)

代码实现:

import numpy as np
import matplotlib.pyplot as plt
def Leaky_relu(x):
    return np.maximum(0.01*x,x)

x=np.arange(-5.0,5.0,0.1)
y=Leaky_relu(x)
plt.plot(x,y)
plt.show()

输出:

和ReLU相比,负方向有个很小的弧度。

2.3.2 带参数的ReLU

带参数的ReLU(parametric ReLU,PReLU),PReLU是一个参数可变的函数。

表达式:

PReLU_{i}(x)=\left\{\begin{matrix} x&if x>0 \\ \gamma _{i} x&if x\leq 0 \end{matrix}\right.                                        (1-9)

2.3.3 ELU函数

ELU(Exponential Linear Unit,指数线性单元)

定义:

ELU(x)=\left\{\begin{matrix} x & if x>0\\ \gamma (e^{x}-1) & if x\leq 0 \end{matrix}\right.                                       (1-10)

代码实现:

import numpy as np
import matplotlib.pyplot as plt
import math
def elu(x,alpha=1):
    a = x[x>0]
    b = alpha*(math.e**(x[x<0])-1)
    result=np.concatenate((b,a),axis=0)
    return result

x=np.arange(-5.0,5.0,0.1)
y=elu(x)
plt.plot(x,y)
plt.show()

输出:

3、3层神经网络的实现

代码实现:

def init_network():#初始化权重和偏置
    network={}
    network['W1']=np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
    network['b1']=np.array([0.1,0.2,0.3])
    network['W2']=np.array([[0.1,0.4],[0.2,0.5],[0.3,0.6]])
    network['b2']=np.array([0.1,0.2])
    network['W3']=np.array([[0.1,0.3],[0.2,0.4]])
    network['b3']=np.array([0.1,0.2])
    
    return network

def forward(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=identity_function(a3)
    
    return y

network=init_network()
x=np.array([1,0.5])
y=forward(network,x)
y

输出:

array([0.31682708, 0.69627909])

4、softmax函数

表达式:

y_{k}=\frac{e^{a_{k}}}{\sum_{i=1}^{n}e^{a_{i}}}                                                          (1-11)

由于会出现溢出情况,所以将公式(1-11)变换。

y_{k}=\frac{e^{a_{k}}}{\sum_{i=1}^{n}e^{a_{i}}}=\frac{Ce^{a_{k}}}{C\sum_{i=1}^{n}e^{a_{i}}}=\frac{e^{(a_{k}+logC)}}{\sum_{n}^{i=1}e^{(a_{i}+logC)}}=\frac{e^{(a_{k}+C{}')}}{\sum_{n}^{i=1}e^{(a_{i}+C{}')}}                 (1-12)

为了防止溢出,增加C{}'为任何值,一般会使用输入信号中的最大值。

实现代码:

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

softmax函数的输出是0~1.0之间的实数,总和为1。所以才把softmax函数的输出解释为“概率”。

举例:

a=np.array([0.3,2.9,4])
y=softmax(a)
y

输出:

array([0.01821127, 0.24519181, 0.73659691])

可以解释为y[0]概率0.018(1.8%),y[1]概率为0.245(24.5%),y[2]概率为0.737(73.7%)。

从概率结果可以看出,有74%概率是第2个类别。

由于指数函数的运算需要一定的计算机运算量,因此输出层的softmax函数一般会被省略。

5、手写数字识别实例

和机器学习步骤一样,分为学习和推理两个阶段。学习就是首先使用训练数据进行权重参数的学习;然后进行推理,使用刚才学习到的参数,对输入参数进行分类。

minist 显示代码

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
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)

输出第1个图片:

计算精度的程序:

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

输出精度为:93.51%。

5.1 批处理

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

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

参考资料:

1、深度学习入门:基于python的理论与实现 

2、神经网络与深度学习 邱锡鹏。

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

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

相关文章

Zookeeper分布式命名服务实战

目录 分布式命名服务 分布式API目录 分布式节点的命名 分布式的ID生成器 分布式的ID生成器方案&#xff1a; 基于Zookeeper实现分布式ID生成器 基于Zookeeper实现SnowFlakeID算法 分布式命名服务 命名服务是为系统中的资源提供标识能力。ZooKeeper的命名服务主要是利用Z…

20240131在ubuntu20.04.6下使用whisper不同模式的比对

20240131在ubuntu20.04.6下使用whisper不同模式的比对 2024/1/31 16:07 首先你要有一张NVIDIA的显卡&#xff0c;比如我用的PDD拼多多的二手GTX1080显卡。【并且极其可能是矿卡&#xff01;】 2、请正确安装好NVIDIA最新的驱动程序和CUDA。可选安装&#xff01; 3、配置whisper…

大华智慧园区综合管理平台 bitmap 任意文件上传漏洞复现

0x01 产品简介 “大华智慧园区综合管理平台”是一款综合管理平台,具备园区运营、资源调配和智能服务等功能。平台意在协助优化园区资源分配,满足多元化的管理需求,同时通过提供智能服务,增强使用体验。 0x02 漏洞概述 大华智慧园区综合管理平台 /emap/webservice/gis/so…

麒麟系统—— openKylin 安装 Nginx

麒麟系统—— openKylin 安装 Nginx 一、准备工作1. 确保麒麟系统 openKylin 已经安装完毕。 二、下载 nginx三、解压与运行解压检查与编译安装编译运行 Nginx 是一款高性能的 HTTP 和反向代理服务器&#xff0c;广泛应用于 Web 服务器领域。本文将分享如何在麒麟系统&#xf…

正则表达式及文本处理三剑客(grep、sed、awk)

目录 一、正则表达式 1、正则表达式的概述 1.1 正则表达式的概念和作用 1.2 正则表达式支持的语言 1.3 正则表达式的优缺点 1.4 正则表达式的分类 1.4.1 基本正则表达式&#xff08;BRE&#xff09;&#xff1a; 1.4.2 扩展正则表达式&#xff08;ERE&#xff09;&…

「数据结构」1.初识泛型

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;Java数据结构 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 初识泛型 &#x1f349;前言&#x1f349;包装类&#x1f34c;装箱&拆箱 &#x1f349;泛型&#x1f34c;擦除机制&#x1f…

爬虫学习笔记-Cookie登录古诗文网

1.导包请求 import requests 2.获取古诗文网登录接口 url https://so.gushiwen.cn/user/login.aspxfromhttp%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx # 请求头 headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like …

基于MATLAB实现的OFDM仿真调制解调,BPSK、QPSK、4QAM、16QAM、32QAM,加性高斯白噪声信道、TDL瑞利衰落信道

基于MATLAB实现的OFDM仿真调制解调&#xff0c;BPSK、QPSK、4QAM、16QAM、32QAM&#xff0c;加性高斯白噪声信道、TDL瑞利衰落信道 相关链接 OFDM中的帧&#xff08;frame&#xff09;、符号&#xff08;symbol&#xff09;、子载波&#xff08;subcarriers&#xff09;、导频…

20240127在ubuntu20.04.6下配置whisper

20240131在ubuntu20.04.6下配置whisper 2024/1/31 15:48 首先你要有一张NVIDIA的显卡&#xff0c;比如我用的PDD拼多多的二手GTX1080显卡。【并且极其可能是矿卡&#xff01;】800&#xffe5; 2、请正确安装好NVIDIA最新的驱动程序和CUDA。可选安装&#xff01; 3、配置whispe…

Windows Server 2003 DNS服务器搭建

系列文章目录 目录 系列文章目录 文章目录 前言 一、DNS服务器是什么&#xff1f; 二、配置服务器 1.实验环境搭建 2.服务器搭建 3)安装Web服务器和DNS服务器 4)查看安装是否成功 5)这里直接配置DNS服务器了,Web服务器如何配置我已经发布过了 文章目录 Windows Serve…

(已解决)Properties和Yaml格式互转

工具转换&#xff1a; 推荐转换工具或者下载idea插件yamls yml&#xff0c;properties互转工具&#xff1a;yaml和proper互转工具 插件转换&#xff1a; 下载yaml插件&#xff0c;对需要转换的文件右键选择转换

林浩然与他的“圆”满人生

林浩然与他的“圆”满人生 Lin Haoran and His “Round” Life of Fulfillment 在那遥远的数学王国&#xff0c;有一个名叫林浩然的小哥&#xff0c;他可不是一般的程序员&#xff0c;而是个痴迷于几何之美、生活之趣的大玩家。话说有一天&#xff0c;林浩然正沉浸在毕达哥拉斯…

4秒读取50w行Excel数据

4秒读取50w行Excel数据 文章比较了几种常用的读取Excel的方法&#xff0c;最终发现rust库Calamine的速度最快&#xff0c;可以在4秒内读取50w行excel数据。 原文&#xff1a;Fastest Way to Read Excel in Python&#xff1a;https://hakibenita.com/fast-excel-python 我们在…

【FFmpeg】ffplay 命令行参数 ① ( 设置播放分辨率 | 禁用 音频 / 视频 / 字幕 选项 )

文章目录 一、ffplay 命令行参数 - 设置播放分辨率1、强制设置通用播放分辨率 -x -y 参数2、命令行示例 - 正常播放视频3、命令行示例 - 强制设置播放分辨率4、设置 YUV 播放分辨率 -video_size 和 像素设置 -pixel_format5、全屏播放 -fs 参数 二、ffplay 命令行参数 - 禁用 音…

ElementUI 组件:Container 布局容器

ElementUI安装与使用指南 Container 布局容器 点击下载learnelementuispringboot项目源码 效果图 el-container.vue页面效果图 项目里el-container.vue代码 <script> import PagePath from "/components/PagePath.vue";export default {name: el_conta…

离线使用Element UI和Vue

需要依赖如下&#xff1a; 1.vue.js; 2.index.js(Element UI) 3.index.css(Element UI) 4.element-icons.ttf(Element UI字体) 5.element-icons.woff(Element UI图标) 下载链接如下&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1nGOi0Vm_xExRGmVp6oVLoA 提取…

(自用)learnOpenGL学习总结-高级OpenGL-帧缓冲Framebuffers

我们在之前使用了很多缓冲了&#xff1a;颜色缓冲、深度缓冲、模板缓冲。这些缓冲结合起来叫做帧缓冲&#xff0c; 其实也能从名字理解&#xff0c;每一帧屏幕都需要不断更新画面&#xff0c;对应的缓冲也需要更新。 不过上面这些都是在默认的缓冲里面做的&#xff0c;现在我…

【ARM Trace32(劳特巴赫) 使用介绍 3.1 -- 不 attach core 直接访问 memory】

文章目录 背景介绍背景介绍 在使用 trace32 时在有些场景需要不 attach core 然后去读写 memory,比如在某些情况下 core 已经挂死连接不上了,这个时候需要dump内存,这个时候需要怎做呢? print "test for memory access directly";SYStem.OPTION WAITRESET OF…

【Java 数据结构】优先级队列(堆)

优先级队列&#xff08;堆&#xff09; 1. 优先级队列1.1 概念 2. 优先级队列的模拟实现2.1 堆的概念2.2 堆的存储方式2.3 堆的创建2.3.1 堆向下调整2.3.2 堆的创建2.3.3 建堆的时间复杂度 2.4 堆的插入与删除2.4.1 堆的插入2.4.2 堆的删除 2.5 用堆模拟实现优先级队列 3.常用…

streampark+flink一键整库或多表同步mysql到doris实战

streamparkflink一键整库或多表同步mysql到doris实战&#xff0c;此应用一旦推广起来&#xff0c;那么数据实时异构时&#xff0c;不仅可以减少对数据库的查询压力&#xff0c;还可以减少数据同步时的至少50%的成本&#xff0c;还可以减少30%的存储成本&#xff1b; streampar…