【Pytorch】learning notes

news/2024/4/29 18:53:14/文章来源:https://blog.csdn.net/bryant_meng/article/details/126612558

文章目录

  • 【torch.xxx】
    • torch.addmm() / torch.addmm_()
    • torch.clamp() / torch.clamp_()
    • torch.eq() / torch.ne()
    • torch.manual_seed()
    • torch.unique()
    • torch.save() / torch.load()
    • torch.view() / torch.permute() / torch. transpose() / torch.reshape()
  • 【torch.cuda.xxx】
    • torch.cuda.synchronize()
  • 【torch.distributed.xxx】
  • 【torch.nn.xxx】
    • torch.nn.MaxPool2d
  • 【torchvision.xxx】
  • 【pytorch to caffe】
  • 【Pinned Memory】
  • 【Parameter 和 buffer】

【torch.xxx】

torch.addmm() / torch.addmm_()

来自 Pytorch里addmm()和addmm_()的用法详解

在这里插入图片描述

addmm_() 的操作和 addmm() 函数功能相同,区别就是addmm_()有inplace的操作,也就是在原对象基础上进行修改,即把改变之后的变量再赋给原来的变量。

def addmm(self, beta=1, mat, alpha=1, mat1, mat2, out=None):...

torch.clamp() / torch.clamp_()

来自 pytorch:torch.clamp()

torch.clamp(input, min, max, out=None) → Tensor
      | min, if x_i < min
y_i = | x_i, if min <= x_i <= max| max, if x_i > max

demo

a=torch.randint(low=0,high=10,size=(10,1))
print(a)
a=torch.clamp(a,3,9)
print(a)

这相当于是个框,把框外的拉回来,框内不动

使用场景

但凡是除数,未免是0,都用 torch.clamp(a ,min=1e-6),将除数设置为不小于1e-6的值。

PYTORCH CLAMP 与CLAMP_区别

pytorch clamp 与clamp_ ,有下划线的表示修改并赋给自身,无下划线的表示需要返回处理后的值,比如:
h = k.clamp(min=0) #将结果存入h,k保留原值
k.clamp_(min=0) # 将结果存入k

torch.eq() / torch.ne()

torch.eq(input, other, *, out=None) → Tensor

  • input (Tensor) – the tensor to compare
  • other (Tensor or float) – the tensor or value to compare

torch.ne(input, other, *, out=None) → Tensor

eg1

torch.eq(torch.tensor([[1, 2], [3, 4]]), torch.tensor([[1, 1], [4, 4]]))
tensor([[ True, False],[False, True]])

eg2

torch.eq(torch.tensor([[1, 2], [3, 4]]), 1)
tensor([[ True, False],[False, False]])

torch.manual_seed()

torch.manual_seed()  #为CPU设置种子用于生成随机数,以使得结果是确定的
torch.cuda.manual_seed() #为当前GPU设置随机种子;
torch.cuda.manual_seed_all() #为所有的GPU设置种子。

torch.unique()

torch.unique(input, sorted=True, return_inverse=False, return_counts=False, dim=None) → Tuple[Tensor, Tensor, Tensor]

Returns the unique elements of the input tensor.

output = torch.unique(torch.tensor([1, 3, 2, 3], dtype=torch.long))
print(output)

output

tensor([1, 2, 3])

eg2

output, inverse_indices = torch.unique(torch.tensor([[1, 3], [2, 3]], dtype=torch.long), sorted=True, return_inverse=True)
print(output)
print(inverse_indices)

output

tensor([1, 2, 3])
tensor([[0, 2],[1, 2]])

torch.save() / torch.load()

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optimdevice = torch.device("cuda:2") # run on GPUclass Net(nn.Module):def __init__(self):super(Net,self).__init__()self.conv1 = nn.Conv2d(3,6,5)self.pool = nn.MaxPool2d(2)self.conv2 = nn.Conv2d(6,16,5)self.fc1 = nn.Linear(16*5*5,120)self.fc2 = nn.Linear(120,84)self.fc3 = nn.Linear(84,10)def forward(self,x):x = self.pool(F.relu(self.conv1(x)))x = self.pool(F.relu(self.conv2(x)))x = x.view(x.size(0),-1)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xnet = Net()
net.to(device)optimizer = optim.SGD(net.parameters(),lr = 0.001,momentum=0.9)print("Model's state_dict")
for para_tensor in net.state_dict():print(para_tensor,'\t',net.state_dict()[para_tensor].size())
"""
conv1.weight 	 torch.Size([6, 3, 5, 5])
conv1.bias 	 torch.Size([6])
conv2.weight 	 torch.Size([16, 6, 5, 5])
conv2.bias 	 torch.Size([16])
fc1.weight 	 torch.Size([120, 400])
fc1.bias 	 torch.Size([120])
fc2.weight 	 torch.Size([84, 120])
fc2.bias 	 torch.Size([84])
fc3.weight 	 torch.Size([10, 84])
fc3.bias 	 torch.Size([10])Process finished with exit code 0
"""
# print(net.fc1.out_features) # can see the input size and output size
# print(net.fc1.in_features) # can see the input size and output size# **********************************************************************# print("Optimizer's state dict:")
#
# for var_name in optimizer.state_dict():
#     print(var_name,"\t",optimizer.state_dict()[var_name])
"""
state 	 {}
param_groups 	 [{'lr': 0.001, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [140660776619680, 140660585225240, 140660585225312, 140660585225384, 140660585225456, 140660585225528, 140660585225600, 140660585225672, 140660585225744, 140660585225816]}]
"""# save and load: method 1 pth
# save
torch.save(net.state_dict(),"model.pth")
# load
net.load_state_dict(torch.load("model.pth"))
net.eval() # to set dropout and BN as inference manner# save and load: method 2 pth
# save the total model
torch.save(net,"model2.pth")
torch.load("model2.pth")
net.eval()# save and load: method 3 tar
# save the checkpoint
# for exampleepoch = 10
loss = 0.5e-5torch.save({'epoch':epoch,'model_state_dict':net.state_dict(),'optimizer_state_dict':optimizer.state_dict(),'loss':loss
},"model3.tar")checkpoint = torch.load("model3.tar")
net.load_state_dict((checkpoint['model_state_dict']))
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']
# or
# net.train()

torch.view() / torch.permute() / torch. transpose() / torch.reshape()

transpose是交换两个维度,permute()是交换多个维度。

permute().contiguous().view()相当于reshape

transpose()和view()实现方式不一样,shape 相同但内容不同

view()只能对连续的张量进行操作,并且返回的张量仍然是连续的。

transpose()既可以在连续张量上操作,也可以在非连续张量上操作。与view()不同,返回的张量可能不再是连续的。

来自

  • PyTorch的 transpose、permute、view、reshape
  • permute()和view()

【torch.cuda.xxx】

torch.cuda.synchronize()

来自

  • torch.cuda.synchronize() 的作用: 测试模型运行时间
  • pytorch 正确的测试时间的代码 torch.cuda.synchronize()

测试模型运行时间

torch.cuda.synchronize()
start = time.time()
result = model(input)
torch.cuda.synchronize()
end = time.time()

基本等价于

start = time.time()
result = model(input)
print(result)
end = time.time()

不等同

start = time.time()
result = model(input)
end = time.time()

【torch.distributed.xxx】

来自

  • [深度学习] 分布式Pytorch介绍(三)
  • PyTorch多卡分布式训练DistributedDataParallel 使用方法
  • Pytorch 分布式训练
  • WRITING DISTRIBUTED APPLICATIONS WITH PYTORCH

优势(相较于 DataParallel)

  1. 每个进程对应一个独立的训练过程,且只对梯度等少量数据进行信息交换。

在每次迭代中,每个进程具有自己的 optimizer ,并独立完成所有的优化步骤,进程内与一般的训练无异。

在各进程梯度计算完成之后,各进程需要将梯度进行汇总平均,然后再由 rank=0 的进程,将其 broadcast 到所有进程。之后,各进程用该梯度来更新参数。由于各进程中的模型,初始参数一致 (初始时刻进行一次 broadcast),而每次用于更新参数的梯度也一致,因此,各进程的模型参数始终保持一致。
而在 DataParallel 中,全程维护一个 optimizer,对各 GPU 上梯度进行求和,而在主 GPU 进行参数更新,之后再将模型参数 broadcast 到其他 GPU。
相较于 DataParallel,torch.distributed 传输的数据量更少,因此速度更快,效率更高。

  1. 每个进程包含独立的解释器和 GIL。

由于每个进程拥有独立的解释器和 GIL,消除了来自单个 Python 进程中的多个执行线程,模型副本或 GPU 的额外解释器开销和 GIL-thrashing ,因此可以减少解释器和 GIL 使用冲突。这对于严重依赖 Python runtime 的 models 而言,比如说包含 RNN 层或大量小组件的 models 而言,这尤为重要。
(GIL 全局解释器锁(Global Interpreter Lock)是Python用于同步线程的工具,使得任何时刻仅有一个线程在执行)


1)单机多卡,DataParallel(DP,最常用,最简单,是单进程,多线程)—— single process multi-gpus
2)单机多卡,DistributedDataParallel(DDP,较高级,多进程)——multi-processes multi-gpus
3)多机多卡,DistributedDataParallel(最高级)


1)DP

  1. 尽管 DataLoader 可以指定 num_worker,增加负责加载数据的线程数量,但是线程的资源受限于父进程,且由于python的GIL机制,不能利用好多核的并行优势
  2. 模型在 gpu 群组中进行初始化与广播过程依赖单一进程的串行操作
  3. DP模式相当于将多个GPU卡合并为一个卡进行训练

在这里插入图片描述

2)DDP

  1. 一个进程一个GPU(当然可以让每个进程控制多个GPU,但这显然比每个进程有一个GPU要慢)
  2. 充分利用多核并行的优势加载数据
  3. 模型在 gpu 群组中进行初始化的过程由各自的进程负责调度
  4. 代码可以无缝切换单机多卡与多机多卡训练,因为此时单机单卡成为了单机多卡/多机多卡并行下的一个特例
  5. GPU可以都在同一个节点上,也可以分布在多个节点上。每个进程都执行相同的任务,并且每个进程都与所有其他进程通信。进程或者说GPU之间只传递梯度,这样网络通信就不再是瓶颈。

在这里插入图片描述
all reduce(即汇总不同 GPU 计算所得的梯度,并同步计算结果)
在这里插入图片描述

【torch.nn.xxx】

torch.nn.MaxPool2d

PyTorch中MaxPool的ceil_mode属性

PyTorch中的MaxPool(最大池化)有一个属性:ceil_mode,默认为False(地板模式),为True时是天花板模式。
在这里插入图片描述

【torchvision.xxx】

来自:

  • torchvision 包的介绍
  • torchvision.datasets 的使用(附代码)
  • PyTorch 学习笔记:transforms的二十二个方法(transforms用法非常详细)

torchvision 是 PyTorch 中专门用来处理图像的库。这个包中有四个大类。

  • torchvision.datasets

    • MNISTCOCO
    • Captions
    • Detection
    • LSUN
    • ImageFolder
    • Imagenet-12
    • CIFAR
    • STL10
    • SVHN
    • PhotoTour
    test_data = torchvision.datasets.CIFAR10(root='../BigData',transform=torchvision.transforms.ToTensor(),train=False,download=True
    )
    
  • torchvision.models

    • AlexNet
    • VGG
    • ResNet
    • SqueezeNet
    • DenseNet
    import torchvision.models as models
    resnet18 = models.resnet18()
    alexnet = models.alexnet()
    squeezenet = models.squeezenet1_0()
    densenet = models.densenet_161()
    
  • torchvision.transforms
    在这里插入图片描述

    transform = transforms.Compose([transforms.Resize(96), # 缩放到 96 * 96 大小transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 归一化
    ])
    
  • torchvision.utils

torchvision.transforms 方法整理如下

  • 裁剪(Crop)

    • transforms.CenterCrop(size,padding,pad_if_needed,fill,padding_mode) 中心裁剪
    • transforms.RandomCrop(size) 随机裁剪
    • transforms.RandomResizedCrop(size, scale, ratio, interpolation) 随机长宽比裁剪
    • transforms.FiveCrop(size) 上下左右中心裁剪
    • transforms.TenCrop(size, vertical_flip) 上下左右中心裁剪后翻转
  • 翻转和旋转(Flip and Rotation)

    • transforms.RandomHorizontalFlip(p=0.5) 依概率p水平翻转
    • transforms.RandomVerticalFlip(p=0.5) 依概率p垂直翻转
    • transforms.RandomRotation(degrees, resample=False, expand=False, center=None) 随机旋转
  • 图像变换(resize)

    • transforms.Resize(size, interpolation=2)
    • transforms.Normalize(mean, std) 标准化:
    • transforms.ToTensor() 转为tensor,并归一化至[0-1]:
    • transforms.Pad(padding, fill=0, padding_mode='constant') 填充
    • transforms.ColorJitter(brightness=0, contrast=0, saturation=0, hue=0) 修改亮度、对比度和饱和度:
    • transforms.Grayscale(num_output_channels=1) 转灰度图:
    • transforms.LinearTransformation(transformation_matrix) 线性变换
    • transforms.RandomAffine(degrees, translate=None, scale=None, shear=None, resample=False, fillcolor=0) 仿射变换
    • transforms.RandomGrayscale(p=0.1) 依概率p转为灰度图
    • transforms.ToPILImage(mode=None) 将数据转换为PILImage
    • transforms.Lambda(lambd),Apply a user-defined lambda as a transform
  • 对 transforms 操作,使数据增强更灵活

    • transforms.RandomChoice(transforms), 从给定的一系列transforms中选一个进行操作
    • transforms.RandomApply(transforms, p=0.5),给一个transform加上概率,依概率进行操作
    • transforms.RandomOrder(transforms),将transforms中的操作随机打乱

【pytorch to caffe】

https://github.com/xxradon/PytorchToCaffe/blob/master/pytorch_to_caffe.py

【Pinned Memory】

来自:

  • CUDA 之 Pinned Memory
  • 物理内存和虚拟内存

虚拟内存技术定义了一个连续的虚拟地址空间,并把内存扩展到硬盘空间。它使得应用程序认为自己拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。

为何使用虚拟内存技术?

电脑中运行的所有程序,都需经过内存来执行,若执行的程序占用内存很大或很多,则会导致内存消耗殆尽。为了解决该问题,Windows 运用了虚拟内存技术,即匀出一部分硬盘空间来充当内存使用。若计算机运行程序或操作所需要的 RAM(随机存储器)不足时,则 Windows 会用这部分虚拟存储器进行补偿,以缓解内存的紧张。

物理内存 VS 虚拟内存

  • 作用不同:物理内存是与 CPU 进行沟通的桥梁,而虚拟内存是在物理内存不足时,起到辅助补偿的作用。
  • 主体不同:物理内存是指通过插在主板内存槽上的物理内存条而获得的内存空间,虚拟内存是指根据系统需要从硬盘匀出来的用来充当内存的那部分空间。
  • 速度不同:物理内存是内存条的读写速度,虚拟内存是硬盘的读写速度,物理内存的处理速度是虚拟内存的30倍以上(即使是固态硬盘,速度也比内存条差很多)。

对于 CUDA 架构而言,主机端的内存可分为两种:
1)可分页内存(Pageable Memory)。
2)页锁定内存(Page-locked Memory),或称固定内存(Pinned Memory)。

对于页锁定内存,操作系统不会对其进行分页和交换操作,一定是存储在物理内存,不会存储在虚拟内存,因此,GPU 可直接通过 DMA 机制,在主机和 GPU 之间快速复制数据。而对于可分页内存,CUDA 驱动会首先将 Pageable Memory 的数据拷贝到临时的 Pinned Memory,然后再通过 DMA 机制进行数据传输。如下图所示:

在这里插入图片描述

C++ 中,通过操作系统接口 malloc() 在主机上分配可分页内存,通过 CUDA 函数 cudaHostAlloc() 在主机上分配页锁定内存。

torch.utils.data.DataLoader() 中的 pin_memory 参数同理

【Parameter 和 buffer】

来自:Pytorch模型中的parameter与buffer

If you have parameters in your model, which should be saved and restored in the state_dict, but not trained by the optimizer, you should register them as buffers.Buffers won’t be returned in model.parameters(), so that the optimizer won’t have a change to update them.

模型中需要保存下来的参数包括两种:

  • 一种是反向传播需要被 optimizer 更新的,称之为 parameter
  • 一种是反向传播不需要被 optimizer 更新,称之为 buffer

在这里插入图片描述
模型保存的是 state_dict 返回的 OrderDict

class MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()buffer = torch.randn(2, 3)  # tensorself.register_buffer('my_buffer', buffer)self.param = nn.Parameter(torch.randn(3, 3))  # 模型的成员变量def forward(self, x):# 可以通过 self.param 和 self.my_buffer 访问pass
model = MyModel()
for param in model.parameters():print(param)
print("----------------")
for buffer in model.buffers():print(buffer)
print("----------------")
print(model.state_dict())

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

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

相关文章

可以替代911s5的这几款产品还有跨境人士不知道吗?

不久前跨境电商用户都收到的坏消息无疑就是&#xff1a;911s5正式宣布停止运营并永久关闭。对于911s5&#xff0c;相信几乎所有的跨境电商用户都知道&#xff0c;因为其低廉的价格一直很受欢迎。所以一时间大家纷纷寻找911s5的替代品&#xff0c;但不是那么容易找的。今天这篇文…

投资组合图形化:EAP.util.plot

实证资产定价&#xff08;Empirical asset pricing&#xff09;已经发布于Github和Pypi. 包的具体用法(Documentation)博主将会陆续在CSDN中详细介绍&#xff0c;也可以通过Pypi直接查看。 Pypi: pip install --upgrade EAP HomePage&#xff1a; EAP a catchy description …

38 字典名[键名]=值 向字典增加键值对

38 字典名[键名]值 向字典增加键值对 文章目录38 字典名[键名]值 向字典增加键值对1. 语法2. 代码示例1. 字典中有要操作的键名—作用为修改2. 字典中没有要操作的键名—作用是增加3. 课后练习4. 列表增加元素知识回顾5. 总结1. 语法 向字典中增加键值对和修改字典的值的语法结…

开箱即用的数据缓存服务|EMQX Cloud 影子服务应用场景解析

在物联网业务高速迭代的今天&#xff0c;快速连接物联网设备与平台应用&#xff0c;实现业务快速落地与市场验证&#xff0c;是很多企业塑造核心竞争力、实现业务创新的关键。 EMQX Cloud 作为一站式运维代管的 MQTT 消息云服务&#xff0c;可以帮助用户在公有云环境中快速实现…

JavaScript:模拟拍照

实现拍照功能需要使用电脑的摄像头&#xff0c;可以使用 navigator.mediaDevices.getUserMedia() 方法&#xff0c;传递相应的参数就能开启摄像头 navigator.mediaDevices 是一个媒体设备对象&#xff0c;通过 getUserMedia( )方法开启音频和视频媒体设备。 getUserMedia 参数…

文献阅读-融合注意力机制的 IETM 细粒度跨模态检索算法

引用格式&#xff1a;翟一琛&#xff0c;顾佼佼&#xff0c;宗富强&#xff0c;姜文志&#xff0e;融合注意力机制的 IETM 细粒度跨模态 检索算法[J/OL]&#xff0e;系统工程与电子技术. https://kns.cnki.net/kcms/detail/11.2422.TN.20220823.1030.004.html 期刊&#xff1a…

跟李沐学AI-动手学深度学习1

整体内容 神经网络可以理解为是一种语言 数学和代码的结合&#xff0c;道术结合&#xff0c;关键在动手 是什么&#xff0c;怎么做&#xff0c;为什么这样 发展知识和应用 广告点击预测三个步骤 预测和训练 模型控制广告展现 数据格式 0维&#xff0c;1维&#xff0c…

【仿牛客网笔记】初识Spring Boot,开发社区首页-MyBatis入门

安装MySQL Server 安装MySQL Workbench 安装过程略。。。 Mybatis手册 Mybatis整合 Mybatis的核心组件&#xff1a; SqlSessionFactory:用于创建SqlSessionFactory工厂类。 SqlSession&#xff1a;Mybatis的核心组件&#xff0c;用于数据库执行SQL 主配置文件&#xff1a;XM…

大一学生期末大作业 html+css+javascript网页设计实例【电影购票项目】html网页制作成品代码

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 文章目录一、网页介绍一…

java面试题总结-1

Java语言特点 &#xff08;1&#xff09;简单易学、有丰富的类库 &#xff08;2&#xff09;面向对象&#xff08;java最重要的特性&#xff0c;让程序耦合度更低&#xff0c;内聚性更高&#xff09; &#xff08;3&#xff09;与平台无关性&#xff08;JVM是Java跨平台使用的…

拦截器和过滤器

拦截器和过滤器 参考&#xff1a; 过滤器和拦截器的区别_至今没搞明白的博客-CSDN博客_过滤器和拦截器的区别 拦截器与过滤器的区别_℡tang的博客-CSDN博客_拦截器和过滤器的区别 文章目录拦截器和过滤器过滤器概念作用Filter链与Filter生命周期SpringBoot 实现过滤器方式一…

如何将各大网盘整合到一起顺便挂载本地使用(文末附软件获取方式)

目录 1、Alist.exe 2、RaiDrive 今天发现了一个网盘变硬盘神器&#xff0c;它不仅安全免费&#xff0c;更全面支持&#xff1a;百度网盘、阿里云盘、天翼云盘、蓝奏云、闪电盘、夸克网盘、迅雷网盘、等众多你们听过&#xff0c;以及没有听过的所有网盘&#xff01; 直接先看效…

Mac环境下反编译工具的使用

日常工作中避免不了反编译工具经常安装&#xff08;换电脑设备、手滑把文件夹删除了。。。等等原因&#xff09;&#xff0c;而且时间一久忘记命令的使用&#xff0c;因此做下记录。 一、反编译工具三件套 apktool&#xff1a;获取apk里的资源文件、配置文件、清单文件、lib文…

毕业论文中引用方法、原理、定义等 如何降重才更有效果?

论文重复率过高是一件很痛苦的事&#xff0c;我当年的本科论文&#xff0c;一共查了四遍才过。 我的查重方法其实比较简单&#xff0c;初稿出来以后我就开始查重了&#xff0c;然后按照标注把标红的部分全部修改掉&#xff0c;而后以此类推&#xff0c;每次改外&#xff0c;或…

BIM+物联网应用,可以解决生活中的诸多问题?

hi&#xff0c;还是我&#xff0c;建模助手。 本期的头条我们聊过有关于元宇宙、BIM和智慧城市之间的些许关联。顺着这条线&#xff0c;再和大家说说更深入的东西——物联网。 它与BIM的结合&#xff0c;可以解决生活中的哪些问题。 01 物联网与BIM关系 在建筑走向智能的时代&a…

ProGAN 论文精读

作者&#xff1a;Tero Karras, Timo Aila, Samuli Laine, Jaakko Lehtinen单位&#xff1a;NVIDIA发表期刊&#xff1a;ICLR 2018 一、前期知识储备&#xff1a; 1.1DCGAN&#xff1a; 1.1.1模型结构&#xff1a; 1.1.2项目地址&#xff1a; github git clone https://git…

【附源码】计算机毕业设计SSM数据分析教学网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

微信公众号搭建查题系统

微信公众号搭建查题系统 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;…

Go Machine Learning

Go Machine Learning 前言 最近因为一直在弄部署整天c写的非常头疼,趁着昨天把分割部署写好后打算换换口味,想着试试Go语言来实现一些机器学习,深度学习会是什么样子.之前推荐过Go(goplus),不过这次打算用更基础的go语法来尝试. 1.准备工作 对于某个从未涉及的领域一开始肯…

硬盘分哪几种类型及主要参数详解

硬盘分哪几种类型 按接口分为:ide、sata、scsi 。 按大小分1.8英寸、 2.5英寸、 3.5英寸、 5.25英寸。 转速分为&#xff1a; 4500转,5400转&#xff0c;7200转和万转。 缓存分为&#xff1a;2m、8m、16m。 硬盘主要参数 硬盘主要参数详解&#xff1a; 转速&#xff1a;硬盘…