昇思25天学习打卡营第5天 | 神经网络构建
1. 神经网络构建
神经网络模型是由神经网络层和Tensor操作构成的,mindspore.nn提供了常见神经网络层的实现,在MindSpore中,Cell类是构建所有网络的基类,也是网络的基本单元。一个神经网络模型表示为一个Cell
,它由不同的子Cell
构成。使用这样的嵌套结构,可以简单地使用面向对象编程的思维,对神经网络结构进行构建和管理。
下面我们将构建一个用于Mnist数据集分类的神经网络模型。
# 导入MindSpore框架,这是一个面向AI应用的全场景深度学习框架
import mindspore# 从MindSpore框架中导入nn(神经网络相关模块)和ops(操作相关模块)
# nn模块包含构建神经网络所需的各种层和激活函数等
# ops模块提供了执行计算任务的各种操作,例如数学运算和数组操作等
from mindspore import nn, ops
1.1 定义模型类
当我们定义神经网络时,可以继承nn.Cell
类,在__init__
方法中进行子Cell的实例化和状态管理,在construct
方法中实现Tensor操作。
construct
意为神经网络(计算图)构建,相关内容详见使用静态图加速。
# 定义一个Network类,继承自nn.Cell,Cell是MindSpore中构建网络的基类
class Network(nn.Cell):# 定义初始化方法,用于完成神经网络的构建def __init__(self):# 调用父类的构造函数super().__init__() # 创建一个Flatten层,用于将输入展平为一维向量self.flatten = nn.Flatten() # 创建一个SequentialCell,它将多个层按顺序组合起来self.dense_relu_sequential = nn.SequentialCell(# 第一个全连接层,输入节点(神经元)数为28*28(假设是MNIST图像的大小),输出节点数为512# 权重初始化为正态分布,偏置初始化为0nn.Dense(28*28, 512, weight_init="normal", bias_init="zeros"),# ReLU激活函数nn.ReLU(), # 第二个全连接层,512个输入节点,512个输出节点nn.Dense(512, 512, weight_init="normal", bias_init="zeros"),# ReLU激活函数nn.ReLU(), # 第三个全连接层,512个输入节点,10个输出节点(假设是10个类别)nn.Dense(512, 10, weight_init="normal", bias_init="zeros"))# construct方法是实现Cell向前传播的逻辑def construct(self, x):# 使用Flatten层将输入x展平x = self.flatten(x) # 将展平后的x通过全连接层和激活函数logits = self.dense_relu_sequential(x) # 返回最后的logits,即模型的输出return logits # 创建Network类的实例,这将初始化神经网络模型的结构
model = Network()# 打印模型实例,这将输出模型的结构信息,包括各个层的类型和参数
print(model)
输出:
Network<(flatten): Flatten<>(dense_relu_sequential): SequentialCell<(0): Dense<input_channels=784, output_channels=512, has_bias=True>(1): ReLU<>(2): Dense<input_channels=512, output_channels=512, has_bias=True>(3): ReLU<>(4): Dense<input_channels=512, output_channels=10, has_bias=True>>>
为了方便理解,我把这个神经网络画出来了
为了方便理解,把tensor也画进去了,实际上,这个网络结构定义好的时候是不包含具体的向量值的。
只是一个算法结构定义,flatten层和神经元内都是没有值的。
只有在训练或预测时,传入了Tensor值时,才会如上图所示
并且Tensor基本上会做过数据变换,传入易于神经网络计算的值,不然全是正值的话,ReLU层就没有存在的必要了。
另外,模型在被创建时,一般会完成参数的初始化,即图上所有的a(mn)和b(mn)都会有初始值。
所谓对模型的训练,就是不断调整这些初始参数,使得他们能在尽可能多的情况下满足给定输入可以计算出预期输出的过程。
而模型推理指的是,使用已练训练好的这些模型参数和整个模型算法结构,给定输入后,推测出结果的过程。
1.2 使用模型进行预测
# 使用ops模块的ones函数创建一个形状为(1, 28, 28)的张量,并指定数据类型为float32
# 这个张量可以代表一个单通道的28x28像素的图像,所有元素都初始化为1
X = ops.ones((1, 28, 28), mindspore.float32)# 将创建的张量X作为输入传递给模型model,计算前向传播的输出
logits = model(X)# 打印模型输出的logits,这通常代表了模型对输入数据的预测结果
## 在Python交互式环境(如Python shell或Jupyter notebook)中,当你输入一个变量名并按下回车时,系统会自动调用该变量的__repr__或__str__方法来打印出一个可读的字符串表示,以便于用户查看变量的内容。
## 如果你在脚本文件中执行这段代码,而没有使用print函数,变量logits的内容将不会被打印出来。
logits
输出:
Tensor(shape=[1, 10], dtype=Float32, value=
[[ 4.55602678e-03, -1.45907002e-02, 1.84002449e-03 ... 8.69915355e-03, 6.90837333e-04, -4.99743177e-03]])
# 使用nn模块中的Softmax函数计算logits的softmax概率分布
# Softmax函数通常用于多分类问题,将 logits 转换为概率分布
# 通俗理解就是传入一张图片,Softmax会将这张图片是0-9每个数字(代表10个类别)的概率都计算出来。
# 参数axis=1表示在第二个维度(索引为1)上应用softmax,即对每个样本的所有类别的logits进行归一化
pred_probab = nn.Softmax(axis=1)(logits)# 使用argmax函数找到每个样本在概率分布中最大值的索引,概率最大的类别,即预测的类别
# argmax函数的参数1表示在第二个维度(索引为1)上找到最大值的索引
y_pred = pred_probab.argmax(1)# 打印预测的类别
# f-string是一种格式化字符串的语法,可以在字符串中嵌入表达式
# {y_pred}会被替换为y_pred变量的值
print(f"Predicted class: {y_pred}")
输出:
Predicted class: [4]
1.3 模型层详解
本节中我们分解上节构造的神经网络模型中的每一层。首先我们构造一个shape为(3, 28, 28)的随机数据(3个28x28的图像),依次通过每一个神经网络层来观察其效果。
# 使用ops模块的ones函数创建一个形状为(3, 28, 28)的张量,并指定数据类型为float32
# 这个张量可以代表一个3通道的28x28像素的图像,所有元素都初始化为1
input_image = ops.ones((3, 28, 28), mindspore.float32)# 打印输入图像张量的形状
print(input_image.shape)
输出:
(3, 28, 28)
1.3.1 nn.Flatten(展平层)
实例化nn.Flatten层,将28x28的2D张量转换为784大小的连续数组。
# 创建一个Flatten层实例,用于将输入张量展平为一维向量
flatten = nn.Flatten()# 使用Flatten层处理输入图像张量input_image,将其展平为一维向量
# 由于输入图像是3个通道的28x28像素,展平后每个通道将变成一个784长度的一维向量
flat_image = flatten(input_image)# 打印展平后图像张量的形状
# 输出将是(3, 784),表示有三个一维向量,每个向量长度为784
print(flat_image.shape)
输出:
(3, 784)
1.3.2 nn.Dense(全连接层)
nn.Dense为全连接层,其使用权重和偏差对输入进行线性变换。
# 创建一个全连接层layer1,其中in_channels参数设置为28*28,out_channels参数设置为20
# 这意味着该层将有28*28个输入节点和20个输出节点
layer1 = nn.Dense(in_channels=28*28, out_channels=20)# 将展平后的图像flat_image作为输入传递给全连接层layer1
# 计算全连接层的输出,这将是20个特征的一维向量,每个向量对应于输入图像的一个样本
hidden1 = layer1(flat_image)# 打印全连接层输出的形状和内容
# 输出形状将是(3, 20),表示有三个样本,每个样本有20个特征
# 输出内容将是这些特征的值
print(hidden1.shape, hidden1)
输出:
(3, 20) [[ 0.5608331 -0.06500022 0.5195999 0.45284656 0.22346526 -0.22476278-0.340589 -0.43673825 -0.57077926 -0.44966274 0.3863637 0.52841353-0.44325724 1.1107857 -1.2462549 -0.17119673 0.46310893 -0.8667695-0.204903 0.0104395 ][ 0.5608331 -0.06500022 0.5195999 0.45284656 0.22346526 -0.22476278-0.340589 -0.43673825 -0.57077926 -0.44966274 0.3863637 0.52841353-0.44325724 1.1107857 -1.2462549 -0.17119673 0.46310893 -0.8667695-0.204903 0.0104395 ][ 0.5608331 -0.06500022 0.5195999 0.45284656 0.22346526 -0.22476278-0.340589 -0.43673825 -0.57077926 -0.44966274 0.3863637 0.52841353-0.44325724 1.1107857 -1.2462549 -0.17119673 0.46310893 -0.8667695-0.204903 0.0104395 ]]
1.3.3 nn.ReLU(激活函数)
nn.ReLU层给网络中加入非线性的激活函数,帮助神经网络学习各种复杂的特征。
# 使用ReLU激活函数对全连接层的输出hidden1进行非线性处理
# ReLU激活函数将替换hidden1中的所有负值元素为0
hidden1 = nn.ReLU()(hidden1)# 打印经过ReLU激活函数处理后的输出
# 输出将是经过ReLU处理的特征值,其中所有负值已经被替换为0
print(f"After ReLU: {hidden1}")
输出:
After ReLU: [[0.5608331 0. 0.5195999 0.45284656 0.22346526 0.0. 0. 0. 0. 0.3863637 0.528413530. 1.1107857 0. 0. 0.46310893 0.0. 0.0104395 ][0.5608331 0. 0.5195999 0.45284656 0.22346526 0.0. 0. 0. 0. 0.3863637 0.528413530. 1.1107857 0. 0. 0.46310893 0.0. 0.0104395 ][0.5608331 0. 0.5195999 0.45284656 0.22346526 0.0. 0. 0. 0. 0.3863637 0.528413530. 1.1107857 0. 0. 0.46310893 0.0. 0.0104395 ]]
可以看到,对比激活函数应用之前,所有的负数都被替换成了0
1.3.4 nn.SequentialCell(有序神经网络)
nn.SequentialCell是一个有序的Cell容器。输入Tensor将按照定义的顺序通过所有Cell。我们可以使用SequentialCell
来快速组合构造一个神经网络模型。
# 创建一个SequentialCell实例seq_modules,它将按照顺序组合多个层和激活函数
# 第一个元素是之前定义的Flatten层,用于展平输入图像
# 第二个元素是之前定义的全连接层layer1,它将展平后的图像映射到20个特征
# 第三个元素是ReLU激活函数,用于对layer1的输出进行非线性处理
# 第四个元素是另一个全连接层,它将20个特征映射到10个输出节点,通常用于分类任务的最后一层
seq_modules = nn.SequentialCell(flatten,layer1,nn.ReLU(),nn.Dense(20, 10)
)# 将输入图像input_image通过seq_modules进行处理
# 这将依次通过Flatten层、layer1、ReLU激活函数和最后一个全连接层
logits = seq_modules(input_image)# 打印经过seq_modules处理后的输出logits的形状
# 输出形状将是(3, 10),表示有三个样本,每个样本有10个输出节点
print(logits.shape)
输出:
(3, 10)
1.3.4 nn.Softmax(概率分布函数)
最后使用nn.Softmax将神经网络最后一个全连接层返回的logits的值缩放为[0, 1],表示每个类别的预测概率。axis
指定的维度数值和为1。
# 创建一个Softmax实例,用于计算softmax概率分布
# 参数axis=1表示在第二个维度(索引为1)上应用softmax
# 这通常用于多分类问题,将logits转换为概率分布
softmax = nn.Softmax(axis=1)# 使用softmax函数计算logits的softmax概率分布
# 这将输出每个类别对应的概率,概率总和为1
pred_probab = softmax(logits)
1.4 模型参数
网络内部神经网络层具有权重参数和偏置参数(如nn.Dense
),这些参数会在训练过程中不断进行优化,可通过 model.parameters_and_names()
来获取参数名及对应的参数详情。
# 打印模型的结构,这将显示模型的层次结构和参数信息
print(f"Model structure: {model}\n\n")# 遍历模型中的所有参数和名称
for name, param in model.parameters_and_names():# 打印每个层的名称print(f"Layer: {name}\n")# 打印每个参数的形状print(f"Size: {param.shape}\n")# 打印每个参数的前两个值,用于查看参数的初始化情况print(f"Values : {param[:2]} \n")
输出:
Model structure: Network<(flatten): Flatten<>(dense_relu_sequential): SequentialCell<(0): Dense<input_channels=784, output_channels=512, has_bias=True>(1): ReLU<>(2): Dense<input_channels=512, output_channels=512, has_bias=True>(3): ReLU<>(4): Dense<input_channels=512, output_channels=10, has_bias=True>>>Layer: dense_relu_sequential.0.weight
Size: (512, 784)
Values : [[-0.01270912 -0.00553937 -0.00622345 ... 0.00974897 0.00378853-0.00879488][ 0.00454485 0.00105424 0.02829224 ... -0.00480925 0.00859034-0.0075234 ]] Layer: dense_relu_sequential.0.bias
Size: (512,)
Values : [0. 0.] Layer: dense_relu_sequential.2.weight
Size: (512, 512)
Values : [[-0.00303549 0.02051559 0.03005496 ... 0.00813595 -0.02086384-0.00501902][ 0.00523915 0.00595684 -0.02108657 ... -0.00816013 0.00160791-0.00521205]] Layer: dense_relu_sequential.2.bias
Size: (512,)
Values : [0. 0.] Layer: dense_relu_sequential.4.weight
Size: (10, 512)
Values : [[ 0.00922695 -0.00915574 -0.01120596 ... -0.00575607 -0.00918559-0.00985601][-0.01312499 0.01030371 0.01826839 ... 0.00239934 -0.01605123-0.0015749 ]] Layer: dense_relu_sequential.4.bias
Size: (10,)
Values : [0. 0.]
更多内置神经网络层详见mindspore.nn API。
2. 小结
今天主要学习了昇思神经网络的构建,包括模型定义、使用模型预测,深入学习了模型展平层、全连接层、激活函数、有序神经网络、概率分布函数和模型参数的相关知识。
相关文章:

昇思25天学习打卡营第5天 | 神经网络构建
1. 神经网络构建 神经网络模型是由神经网络层和Tensor操作构成的,mindspore.nn提供了常见神经网络层的实现,在MindSpore中,Cell类是构建所有网络的基类,也是网络的基本单元。一个神经网络模型表示为一个Cell,它由不同…...

Web缓存—Nginx和CDN应用
目录 一、代理的工作机制 二、概念 三、作用 四、常用的代理服务器 二.Nginx缓存代理服务器部署 1.在三台服务器上部署nginx 此处yum安装 2.准备测试界面 三、CDN概念及作用 1.CDN的工作过程 一、代理的工作机制 (1)代替客户机向网站请求数据…...

Linux 端口
什么是虚拟端口 计算机程序之间的通讯,通过IP只能锁定计算机,但是无法锁定具体的程序。通过端口可以锁定计算机上具体的程序,确保程序之间进行沟通。 IP地址相当于小区地址,在小区内可以有许多用户(程序)&…...

菜鸡的原地踏步史02(◐‿◑)
每日一念 改掉自己想到哪写哪的坏习惯 二叉树 二叉树的中序遍历 class Solution {/**中序遍历左 - 中 - 右*/private List<Integer> res new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {if(root null) {return res;}tranve…...

实现Java应用的数据加密与解密技术
实现Java应用的数据加密与解密技术 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 数据加密与解密的重要性 数据安全是当今互联网应用开发中的重要问题之…...

赛博解压板
目录 开头程序程序的流程图程序的解压效果(暂无,但可以运行一下上面的代码)结尾 开头 大家好,我叫这是我58。今天,我们要看关于赛博解压板的一些东西。 程序 #define _CRT_SECURE_NO_WARNINGS 1 #define ROW 6//ROW表示行数,可…...

微信小程序常用的事件
1.点击事件 WXML 中绑定点击事件: <!-- index.wxml --> <button bindtap"handleTap">点击我</button> 对应的 JS 文件中编写点击事件处理函数: // index.js Page({handleTap: function() {console.log(按钮被点击了);} }…...

js时间转成xx前
// 时间戳转多少分钟之前 export default function getDateDiff(dateTimeStamp) {// console.log(dateTimeStamp,dateTimeStamp)// 时间字符串转时间戳var timestamp new Date(dateTimeStamp).getTime();var minute 1000 * 60;var hour minute * 60;var day hour * 24;var …...

iOS 锁总结(cc)
iOS中atomic和synchrosize锁的本质是什么? 在iOS中,atomic和@synchronized锁的本质涉及底层的多线程同步机制。以下是关于这两者本质的详细解释: atomic 定义与用途: atomic是Objective-C属性修饰符的一种,用于指示属性的存取方法是线程安全的。当一个属性被声明为ato…...

【CSAPP】-binarybomb实验
目录 实验目的与要求 实验原理与内容 实验设备与软件环境 实验过程与结果(可贴图) 操作异常问题与解决方案 实验总结 实验目的与要求 1. 增强学生对于程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。 2. 掌握使用gdb调试器…...

SpringBoot实战:轻松实现XSS攻击防御(注解和过滤器)
文章目录 引言一、XSS攻击概述1.1 XSS攻击的定义1.2 XSS攻击的类型1.3 XSS攻击的攻击原理及示例 二、Spring Boot中的XSS防御手段2.1 使用注解进行XSS防御2.1.1 引入相关依赖2.1.2 使用XSS注解进行参数校验2.1.3 实现自定义注解处理器2.1.4 使用注解 2.2 使用过滤器进行XSS防御…...

如何改善提示词,让 GPT-4 更高效准确地把视频内容整体转换成文章?
(注:本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费) 让我们来讨论一下大语言模型应用中的一个重要原则 ——「欲速则不达」。 作为一个自认为懒惰的人,我一直有一个愿望:完成视频制作…...

TensorBoard进阶
文章目录 TensorBoard进阶1.设置TensorBoard2.图像数据在TensorBoard中可视化3.模型结构在TensorBoard中可视化(重点✅)4.高维数据在TensorBoard中低维可视化5.利用TensorBoard跟踪模型的训练过程(重点✅)6.利用TensorBoard给每个…...

使用AES加密数据传输的iOS客户端实现方案
在现代应用开发中,确保数据传输的安全性是至关重要的。本文将介绍如何在iOS客户端中使用AES加密数据传输,并与服务器端保持加密解密的一致性。本文不会包含服务器端代码,但会解释其实现原理。 加密与解密的基本原理 AES(Advance…...

vue3【实战】语义化首页布局
技术要点,详见注释 <script setup></script><template><div class"page"><header>页头</header><nav>导航</nav><!-- 主体内容 --><main class"row"><aside>左侧边栏<s…...

FANG:利用社交网络图进行虚假新闻检测
1.概述 社交媒体已逐渐演变成为公众获取信息的主要途径。然而,值得警惕的是,并非所有流通的信息都具备真实性。特别是在政治选举、疫情爆发等关键节点,带有恶意企图的虚假信息(即“假新闻”)可能会对社会秩序、公平性和理性思考造成严重的干扰。作为全球抗击COVID-19的一部…...

Vue2 基础八电商后台管理项目——中
代码下载 商品分类页 新商品分类组件 goods/Cate.vue,在router.js中导入子级路由组件 Cate.vue,并设置路由规则。 绘制商品分类基本结构 在Cate.vue组件中添加面包屑导航以及卡片视图中的添加分类按钮: <template><div><…...

Typescript window.localStorage 存储 Obj Value区别
window.localStorage.setItem(UserC, JSON.stringify(userC)) const userC JSON.parse(window.localStorage.getItem(UserC) || {}) 不能获得UserC,所有保存的时候需要存储value,而不是对象。 {"__v_isShallow":false, "__v_isRef&quo…...

Linux要解压 .rar 文件,你应该使用 unrar 命令
命令 sudo tar -zxf ~/WebDemo.rar -C /usr/local 有一些问题。tar 命令通常用于解压 .tar、.tar.gz 或 .tar.bz2 文件,而不是 .rar 文件。要解压 .rar 文件,你应该使用 unrar 命令。下面是正确的步骤: 首先,安装 unrar࿰…...

【qt】如何获取网卡的信息?
网卡不只一种,有有线的,有无线的等等 我们用QNetworkInterface类的静态函数allInterfaces() 来获取所有的网卡 返回的是一个网卡的容器. 然后我们对每个网卡来获取其设备名称和硬件地址 可以通过静态函数humanReadableName() 来获取设备名称 可以通过静态函数**hardwareAddre…...

使用Netty框架实现WebSocket服务端与客户端通信(附ssl)
仓库地址: https://gitee.com/lfw1024/netty-websocket 导入后可直接运行 预览页面 自签证书: #换成自己的本地ip keytool -genkey -alias server -keyalg RSA -validity 3650 -keystore D:\mystore.jks -ext sanip:192.168.3.7,ip:127.0.0.1,dns:lo…...

ssm校园志愿服务信息系统-计算机毕业设计源码97697
摘 要 随着社会的进步和信息技术的发展,越来越多的学校开始重视志愿服务工作,通过组织各种志愿服务活动,让学生更好地了解社会、服务社会。然而,在实际操作中,志愿服务的组织和管理面临着诸多问题,如志愿者…...

JVM原理(二):JVM之HotSpot虚拟机中对象的创建寻位与定位整体流程
1. 对象的创建 遇到new指令时 当Java虚拟机遇到一个字节码new指令时。 首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。 如果没有,那么必须执行类的加载过程(加载、检查…...

(七)glDrawArry绘制
几何数据:vao和vbo 材质程序:vs和fs(顶点着色器和片元着色器) 接下来只需要告诉GPU,使用几何数据和材质程序来进行绘制。 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostrea…...

记一次小程序渗透
这次的小程序渗透刚好每一个漏洞都相当经典所以记录一下。 目录 前言 漏洞详情 未授权访问漏洞/ 敏感信息泄露(高危) 水平越权(高危) 会话重用(高危) 硬编码加密密钥泄露(中危࿰…...

C++ 的常见算法 之一
C 的常见算法 之一 不修改序列算法for_eachcountfind 修改序列算法copymove 不修改序列算法 for_each #include <iostream> // std::cout #include <algorithm> // std::for_each #include <vector> // std::vectorusing namespace std;struc…...

微前端的需求有哪些?微前端的原理是怎么样的?为什么这么设计,及微前端的应用场景是什么?对有些客户,前端的重要性高于后端
微前端(Micro Frontends)是将前端应用拆分成多个独立、可部署的部分,每个部分可以由不同的团队独立开发、测试、部署和维护。这种架构类似于微服务在后端的应用,是为了应对复杂前端应用的维护和扩展问题而提出的。 来龙去脉 背景…...

【Spring Boot】统一数据返回
目录 统一数据返回一. 概念二.实现统一数据返回2.1 重写responseAdvice方法2.2 重写beforeBodyWriter方法 三. 特殊类型-String的处理四. 全部代码 统一数据返回 一. 概念 其实统一数据返回是运用了AOP(对某一类事情的集中处理)的思维,简单…...

证券交易系统中服务器监控系统功能设计
1.背景介绍 此服务器监控系统的目的在于提高行情服务器的监管效率,因目前的的行情服务器,包括DM、DT、DS配置数量较多,巡回维护耗时较多,当行情服务器出现异常故障,或者因为网络问题造成数据断线等情况时,监…...

【线性代数的本质】矩阵与线性变换
线性变化要满足两点性质: 直线(连续的点)在变换后还是直线。原点不变。 假设有坐标轴(基底) i ^ \widehat{i} i 和 j ^ \widehat{j} j : i ^ [ 1 0 ] , j ^ [ 0 1 ] \widehat{i}\begin{bmatrix} 1 \…...