自己动手实现一个深度学习算法——二、神经网络的实现

文章目录

      • 1. 神经网络概述
        • 1)表示
        • 2)激活函数
        • 3)sigmoid函数
        • 4)阶跃函数的实现
        • 5)sigmoid函数的实现
        • 6)sigmoid函数和阶跃函数的比较
        • 7)非线性函数
        • 8)ReLU函数
      • 2.三层神经网络的实现
        • 1)结构
        • 2)代码实现
      • 3.输出层的设计
        • 1)概述
        • 2)softmax函数
        • 3)实现softmax函数时的注意事项
        • 4)softmax函数的特征
        • 5)输出层的神经元数量
      • 4.手写数字识别
        • 1)MNIST数据集
        • 2)实现
        • 3)批处理

神经网络可以自动地从数据中学习到合适的权重参数。

1. 神经网络概述

1)表示

神经网络信号传递类似于感知机。最左边的一列称为输入层,最右边的一列称为输出层,中间的一列称为中间层。中间层有时也称为隐藏层。实现中,输入层到输出层依次称为第 0层、第1 层、第 2 层

在这里插入图片描述

2)激活函数

h(x)函数会将输入信号的总和转换为输出信号,这种函数一般称为激活函数(activation function)。如下:

y = h(b + w1x1+ w2x2)

如果激活函数如下,即以阈值为界,一旦输入超过阈值,就切换输出。这样的函数称为“阶跃函数”。因此,可以说感知机中使用了阶跃函数作为
激活函数。

在这里插入图片描述

3)sigmoid函数

神经网络中经常使用的一个激活函数就是sigmoid函数(sigmoid function)。表达式如下:

在这里插入图片描述

神经网络中用sigmoid函数作为激活函数,进行信号的转换,转换后的信号被传送给下一个神经元。

感知机和神经网络的主要区别就在于这个激活函数

4)阶跃函数的实现
# coding: utf-8
import numpy as np
import matplotlib.pylab as plt


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

X = np.arange(-5.0, 5.0, 0.1)
Y = step_function(X)
plt.plot(X, Y)
plt.ylim(-0.1, 1.1)  # 指定图中绘制的y轴的范围
plt.show()

5)sigmoid函数的实现
# coding: utf-8
import numpy as np
import matplotlib.pylab as plt


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

X = np.arange(-5.0, 5.0, 0.1)
Y = sigmoid(X)
plt.plot(X, Y)
plt.ylim(-0.1, 1.1)
plt.show()

6)sigmoid函数和阶跃函数的比较

sigmoid函数是一条平滑的曲线,输出随着输入发生连续性的变化。sigmoid函数的平滑性对神经网络的学习具有重要意义。

当输入信号为重要信息时,阶跃函数和sigmoid函数都会输出较大的值;当输入信号为不重要的信息时,两者都输出较小的值。

不管输入信号有多小,或者有多大,输出信号的值都在0到1之间。

# coding: utf-8
import numpy as np
import matplotlib.pylab as plt


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


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

x = np.arange(-5.0, 5.0, 0.1)
y1 = sigmoid(x)
y2 = step_function(x)

plt.plot(x, y1)
plt.plot(x, y2, 'k--')
plt.ylim(-0.1, 1.1) #指定图中绘制的y轴的范围
plt.show()
7)非线性函数

阶跃函数和sigmoid函数还有其他共同点,就是两者均为非线性函数。

神经网络的激活函数必须使用非线性函数。线性函数的问题在于,不管如何加深层数,总是存在与之等效的“无隐藏层的神经网络”

为了发挥叠加层所带来的优势,激活函数必须使用非线性函数。

8)ReLU函数

sigmoid函数很早就开始被使用了,而最近则主要使用ReLU(Rectified Linear Unit)函数。

ReLU 函数也是一种激活函数,可以表示为下面的式

在这里插入图片描述

ReLU函数的实现如下,

# coding: utf-8
import numpy as np
import matplotlib.pylab as plt


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

x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)
plt.plot(x, y)
plt.ylim(-1.0, 5.5)
plt.show()

2.三层神经网络的实现

1)结构

3层神经网络:输入层(第0层)有2个神经元,第1个隐藏层(第1层)有3个神经元,第2个隐藏层(第2层)有2个神经元,输出层(第3层)有2个神经元,结构

如下,

在这里插入图片描述

2)代码实现
# coding: utf-8
import numpy as np
from common.functions import sigmoid,identity_function

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, 0.5])
y = forward(network, x)
print(y) # [ 0.31682708  0.69627909]

3.输出层的设计

1)概述

机器学习的问题大致可以分为分类问题和回归问题。分类问题是数据属于哪一个类别的问题。比如,区分图像中的人是男性还是女性的问题就是分类问题。而回归问题是根据某个输入预测一个(连续的)数值的问题。比如,根据一个人的图像预测这个人的体重的问题就是回归问题(类似“57.4kg”这样的预测)。

输出层的激活函数用σ()表示,不同于隐藏层的激活函数h()(σ读作sigma)。

输出层所用的激活函数,要根据求解问题的性质决定。一般地,回归问题可以使用恒等函数,二元分类问题可以使用sigmoid函数,多元分类问题可以使用softmax函数。

恒等函数会将输入按原样输出,对于输入的信息,不加以任何改动地直接输出。

2)softmax函数

分类问题中使用的softmax函数可以用下面的式表示。
在这里插入图片描述

softmax 函数的分子是输入信号 ak的指数函数,分母是所有输入信号的指数函数的和。输出层的各个神经元都受到所有输入信号的影响。

3)实现softmax函数时的注意事项

softmax函数的实现中要进行指数函数的运算,但是此时指数函数的值很容易变得非常大。结果可能会返回一个表示无穷大的inf。如果在这些超大值之间进行除法运算,结果会出现“不确定”的情况。这个问题称为溢出。

解决方式如下:

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

4)softmax函数的特征

softmax函数的输出是0.0到1.0之间的实数。并且,softmax函数的输出值的总和是1

一般而言,神经网络只把输出值最大的神经元所对应的类别作为识别结果。并且,即便使用softmax函数,输出值最大的神经元的位置也不会变。

**因此,神经网络在进行分类时,输出层的softmax函数可以省略。**在实际的问题中,由于指数函数的运算需要一定的计算机运算量,因此输出层的softmax函数
一般会被省略。

在输出层使用softmax函数是因为它和神经网络的学习有关系

5)输出层的神经元数量

输出层的神经元数量需要根据待解决的问题来决定。对于分类问题,输出层的神经元数量一般设定为类别的数量。

4.手写数字识别

假设学习已经全部结束,我们使用学习到的参数,先实现神经网络的“推理处理”。这个推理处理也称为神经网络的前向传播(forward propagation)。

1)MNIST数据集

MNIST是机器学习领域最有名的数据集之一,被应用于从简单的实验到发表的论文研究等各种场合。

MNIST 数据集是由 0 到 9 的数字图像构成的(图 3-24)。训练图像有 6 万张,测试图像有1万张,这些图像可以用于学习和推理。MNIST数据集的一般使用方法是,先用训练图像进行学习,再用学习到的模型度量能在多大程度上对测试图像进行正确的分类。

显示图形代码

# 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)
print(x_train.shape)
print(t_train.shape)
img = x_train[0]
label = t_train[0]
print(label)  # 5
print(img.shape)
print(img.shape)  # (784,)
img = img.reshape(28, 28)  # 把图像的形状变为原来的尺寸
print(img.shape)  # (28, 28)

img_show(img)

load_mnist 函数以“(训练图像,训练标签),(测试图像,测试标签)”的形式返回读入的MNIST数据。此外,还可以像load_mnist(normalize=True, flatten=True, one_hot_label=False) 这 样,设 置 3 个 参 数。第 1 个 参 数normalize 设置是否将输入图像正规化为 0.0~1.0 的值。如果将该参数设置为False,则输入图像的像素会保持原来的0~255。第2个参数flatten设置是否展开输入图像(变成一维数组)。如果将该参数设置为False,则输入图像为1×28×28 的三维数组;若设置为 True,则输入图像会保存为由 784 个元素构成的一维数组。第3个参数one_hot_label设置是否将标签保存为one-hot 表示(one-hot representation)onehot 表示是仅正确解标签为 1,其余皆为0的数组,就像[0,0,1,0,0,0,0,0,0,0]这样。当one_hot_label为False时,只是像7、2这样简单保存正确解标签;one_hot_label为True时,标签则保存为one-hot表示。

2)实现

神经网络的输入层有784个神经元,输出层有10个神经元。输入层的784这个数字来源于图像大小的28×28 = 784,输出层的 10 这个数字来源于 10 类别分类(数
字0到9,共10类别)。此外,这个神经网络有2个隐藏层,第1个隐藏层有50 个神经元,第 2 个隐藏层有 100 个神经元。

# 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

#读入保存在 pickle 文件 sample_weight.pkl 中的学习到的权重参数.这个文件中以字典变量的形式保存了权重和偏置参数。
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)))

将 normalize 设置成 True 后,函数内部会进行转换,将图像的各个像素值除以255,使得数据的值在0.0~1.0的范围内。像这样把数据限定到某个范围内的处理称为正规化(normalization)。此外,对神经网络的输入数据进行某种既定的转换称为预处理(pre-processing)

3)批处理
# 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

#按照batch_size间隔,从0获取元素
for i in range(0, len(x), batch_size):
    x_batch = x[i:i+batch_size]
    y_batch = predict(network, x_batch)
    #按照1维取最大值,即按行取最大值
    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)))

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt Concurrent框架详解(QFuture、QFutureWatcher)

1.概述 Qt Concurrent是Qt提供的一个并发编程框架,用于简化多线程和并行计算的开发。它提供了一组易于使用的函数和类,可以方便地在多线程环境下处理并发任务。 有以下特点: 简单易用:Qt Concurrent提供了一组高级函数和类&…

数据库-索引

概念: Mysql 索引 事务 存储引擎 索引:索引是一个排序的列表,列表当中存储的是索引的值和包含这个值的数据所在行的物理地址 索引的作用:就好比书的目录,加快查询的速度 概念图: 索引的作用&#xff1a…

第四章 应用SysML基本特性集的汽车示例 P1|系统建模语言SysML实用指南学习

仅供个人学习记录 汽车模型 主要就是应用练习建模了 Automobile Domain包 用于组织模型的包图 将模型组织入包的包图 需求图捕获汽车规范 汽车规范中包含系统需求的需求图 块定义图定义车辆及其外部环境 汽车域块定义图 用例图表示操作车辆 描述车辆主要功能的用…

uniapp中APP端使用echarts用formatter设置y轴保留2位小数点不生效

uniapp使用echarts,在内置浏览器中,设置保留2位小数能正常显示(代码如下),但是在APP端这个设置不起作用。 yAxis: {type: value,axisLabel: {formatter: function (val) {return val.toFixed(2); //y轴始终保留小数点…

【Java 进阶篇】Java Web开发:实现验证码功能

在Web应用程序中,验证码(CAPTCHA)是一种常见的安全工具,用于验证用户是否为人类而不是机器。验证码通常以图像形式呈现,要求用户在登录或注册时输入正确的字符。在这篇文章中,我们将详细介绍如何在Java Web…

Ubuntu 搭建 DHCP ivp6 server 步骤

Ubuntu 搭建 DHCP ivp6 server 步骤 安装 DHCP server安装 radvd(实现局域网路由功能)测试运行 安装 DHCP server apt 安装 isc-dhcp-server sudo apt-get install isc-dhcp-server修改配置文件 /etc/dhcp/dhcpd6.conf 内容如下: lease-time 7200; lo…

如何在idea中使用maven搭建tomcat环境

目录 一、创建maven项目 二、完善代码结构 三、引入依赖和插件 四、启动tomcat,运行项目 (1)点击添加配置 (2)点击左上角的加号,选择maven (3)输入运行命令 五、验证 一、创建…

GB28181学习(十四)——语音广播与语音对讲

语音对讲 定义 用户端向设备通过视音频点播请求音频数据;用户端接收音频数据并通过特定的播放设备(如音响)播放;用户端向设备发送广播请求;设备解析广播成功后通过INVITE方法向用户请求音频数据;用户通过音…

Android studio进入手机调试状态

首先usb插入电脑手机打开开发者模式进入点击就会在你的页面显示了

ARL灯塔安装与使用

ARL灯塔安装与使用 1. 系统要求2. ARL灯塔安装2.1. docker环境安装2.1.1. 更新yum包2.1.2. 卸载老版docker2.1.3. 安装docker所需要的依赖包2.1.4. 设置yum源2.1.5. 查看仓库中docker版本2.1.6. 安装docker最新版2.1.7. docker设置2.1.8. docker其它命令 2.2. 安装docker-compo…

JS(JavaScript) 实现延迟等待(sleep方法)

起因: 只使用 setTimeout 会产生嵌套等方面的问题,达不到想要的效果。 解决方法: 使用 async/await 还有 Promise 相结合的方式来解决问题。 直接上代码: function sleep(time) {return new Promise((resolve) > setTimeout…

SAP MM学习笔记39 - MRP(资材所要量计划)

这一章开始,离开请求书,学点儿新知识啦。 MRP ( Material Requirement Planning ) - 资材所要量计划。 它的位置在下面的调达周期图上来看,就是右上角的 所要量决定那块儿。 1,MRP(资材所要量计划) 的概要 MRP 的主要目的就是 确…

python进程

进程的定义和常用方法 import os from multiprocessing import Process from time import sleepm 1 list1 []def task1(s, name):global mwhile True:sleep(1)m 1print("进程1", m)list1.append(str(m) "task1")print(list1)print("------------…

FedAT:异步更新联邦学习方法

文章链接:FedAT: A Communication-Efficient Federated Learning Method with Asynchronous Tiers under Non-IID Data 发表会议: SC’21 (International Conference for High Performance Computing, Networking, Storage, and Analysis) 高性能计算,体…

网络套接字编程(二)

网络套接字编程(二) 文章目录 网络套接字编程(二)简易TCP网络程序服务端创建套接字服务端绑定IP地址和端口号服务端监听服务端运行服务端网络服务服务端启动客户端创建套接字客户端的绑定和监听问题客户端建立连接并通信客户端启动程序测试单执行流服务器的弊端 多进程版TCP网络…

scrapy-redis分布式爬虫(分布式爬虫简述+分布式爬虫实战)

一、分布式爬虫简述 (一)分布式爬虫优势 1.充分利用多台机器的带宽速度 2.充分利用多台机器的ip地址 (二)Redis数据库 1.Redis是一个高性能的nosql数据库 2.Redis的所有操作都是原子性的 3.Redis的数据类型都是基于基本数据…

攻防世界-web-bug

1. 问题描述 没有额外的描述,仅仅是这样的一个登录界面 但是,我们注意到有注册(Register)和找回密码(Findpwd)这俩按钮 注册界面如下:需要输入用户名,密码,生日及地址 …

自动曝光算法(第一讲)

序言 失业在家无事,想到以后换方向不做自动曝光了,但是自动曝光的工作经验也不能浪费了,准备写一个自动曝光的教学,留给想做自动曝光的小伙伴参考。笔者当时开发自动曝光没有按摄影的avtvevbvsv公式弄,而是按正确的增…

K-means(K-均值)算法

K-means(k-均值,也记为kmeans)是聚类算法中的一种,由于其原理简单,可解释强,实现方便,收敛速度快,在数据挖掘、聚类分析、数据聚类、模式识别、金融风控、数据科学、智能营销和数据运…

UML类图关系

1.依赖 依赖关系由箭头表示,含义为A类在类中用到了B类,如B类作为A类的属性、参数、返回值等都属于依赖关系。 2.泛化(继承) 泛化用三角箭头和直线表示,extend。 3.实现 实现用三角箭头和虚线表示,在…