深度学习pytorch实战第P2周:CIFAR10彩色图片识别

>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/0dvHCaOoFnW8SCp3JpzKxg) 中的学习记录博客**
>- **🍖 原作者:[K同学啊](https://mtyjkh.blog.csdn.net/)**

零、引言(温故而知新,可以为师矣)

这是·学习的第二周,

1.复习上周

首先我们要回顾以上上周的内容,温习一下,以便我们快速的将知识碎片捡起来。进行下一步学习

深度学习pytorch实战第P1周:实现mnist手写数字识别icon-default.png?t=N7T8http://t.csdnimg.cn/YZome

2.摆正心态

其次,我们现在要开启第二周的学习了,摆正我们的心态,接下来可能会遇到困难,和有些不太理解的地方,不要慌,我会尽可能地在本文中讲清楚,如果还有疑问,欢迎评论留言

3.本机环境

同上篇

4.学习目标

一、前期准备

1.设置GPU

import torch
#这行代码导入了PyTorch库,它是一个开源的机器学习库,广泛用于计算机视觉和自然语言处理等领域。PyTorch提供了强大的张量计算(类似于NumPy),并且具有自动求导功能,这使得它在深度学习模型的构建和训练中非常有用。
import torch.nn as nn
#这行代码从PyTorch库中导入了nn模块,并将其重命名为nn。nn模块包含了构建神经网络所需的所有基础组件,例如不同类型的层(如卷积层、全连接层、循环层等)、激活函数、损失函数等。通过这个模块,我们可以方便地定义和实现复杂的神经网络结构。
import matplotlib.pyplot as plt
#这行代码导入了matplotlib库的pyplot模块,并将其重命名为plt。matplotlib是一个非常流行的Python绘图库,用于创建高质量的图形和图表。pyplot模块提供了MATLAB风格的接口,使得绘图变得简单直观。在深度学习中,我们经常使用matplotlib来可视化数据、模型结构或者训练过程中的损失和准确率等信息。
import torchvision
#这行代码导入了torchvision库。torchvision是PyTorch的一个扩展库,它提供了大量的用于图像处理和计算机视觉任务的工具和预训练模型。它包括常用的数据集、模型架构以及图像转换和增强的方法。torchvision使得加载和处理图像数据变得非常方便,并且可以加速计算机视觉应用的开发过程。device = torch.device("cuda" if torch.cuda.is_available() else "cpu")device

机器学习&&深度学习——torch.nn模块icon-default.png?t=N7T8http://t.csdnimg.cn/OmkKL

2.导入数据

train_ds = torchvision.datasets.CIFAR10('data', train=True, transform=torchvision.transforms.ToTensor(), # 将数据类型转化为Tensordownload=True)test_ds  = torchvision.datasets.CIFAR10('data', train=False, transform=torchvision.transforms.ToTensor(), # 将数据类型转化为Tensordownload=True)

batch_size = 32
#DataLoader是PyTorch中一个非常重要的工具,它能够自动地为我们加载数据,提供了批量处理、打乱数据顺序等功能。这对于训练深度学习模型是非常有用的,因为它可以减少内存消耗,并提高计算效率。
train_dl = torch.utils.data.DataLoader(train_ds, batch_size=batch_size, shuffle=True)test_dl  = torch.utils.data.DataLoader(test_ds, batch_size=batch_size)
# 取一个批次查看数据格式
# 数据的shape为:[batch_size, channel, height, weight]
# 其中batch_size为自己设定,channel,height和weight分别是图片的通道数,高度和宽度。
imgs, labels = next(iter(train_dl))
imgs.shape
在这段代码中,我们首先设置了一个变量`batch_size`,其值为32,这意味着每个批次将包含32个图像样本。然后,我们使用`torch.utils.data.DataLoader`类创建了两个数据加载器:`train_dl`用于训练数据集,`test_dl`用于测试数据集。`DataLoader`是PyTorch中一个非常重要的工具,它能够自动地为我们加载数据,提供了批量处理、打乱数据顺序等功能。这对于训练深度学习模型是非常有用的,因为它可以减少内存消耗,并提高计算效率。在`DataLoader`的初始化过程中,我们传递了以下参数:
- `train_ds`和`test_ds`:分别是训练集和测试集的数据集实例。
- `batch_size`:每个批次的样本数量。
- `shuffle=True`:仅在训练数据加载器`train_dl`中设置,这意味着在每个epoch开始时,数据加载器会随机打乱训练数据的顺序。这样做有助于提高模型的泛化能力,防止模型对数据顺序产生依赖。
- `iter(train_dl)`:通过迭代数据加载器来获取一个批次的数据。`next(iter(train_dl))`是获取数据加载器中的下一个元素,即获取第一个批次的数据。当我们执行`imgs, labels = next(iter(train_dl))`这行代码时,我们从训练数据集中获取了第一个批次的图像和标签。`imgs`是一个形状为`[batch_size, channel, height, width]`的4D张量,其中:
- `batch_size`:当前批次中的图像数量,这里是32。
- `channel`:图像的通道数,对于CIFAR-10数据集,通道数是3,因为这些图像是RGB彩色图像。
- `height`和`width`:图像的高度和宽度,CIFAR-10中的图像都是32x32像素。`labels`是一个1D张量,包含了与`imgs`中图像对应的标签,每个标签是一个整数,表示图像所属的类别。通过查看`imgs.shape`,我们可以确认获取的数据形状是否符合预期。实际上,由于我们已经知道CIFAR-10数据集的图像是32x32像素的RGB图像,所以`imgs`的形状应该是`[32, 3, 32, 32]`,其中32是批次大小,3是通道数,32和32分别是图像的高度和宽度。

3.数据可视化

import numpy as np# 指定图片大小,图像大小为20宽、5高的绘图(单位为英寸inch)
plt.figure(figsize=(20, 5)) 
for i, imgs in enumerate(imgs[:20]):# 维度缩减npimg = imgs.numpy().transpose((1, 2, 0))# 将整个figure分成2行10列,绘制第i+1个子图。plt.subplot(2, 10, i+1)plt.imshow(npimg, cmap=plt.cm.binary)plt.axis('off')#plt.show()  如果你使用的是Pycharm编译器,请加上这行代码
这段代码使用了Python的`matplotlib`库和`numpy`库来显示一批图像。`matplotlib`是一个用于创建静态、动态和交互式可视化的库,而`numpy`是Python中用于科学计算的基础库,提供了对多维数组对象的支持。让我们逐步分析代码:1. `import numpy as np`:导入`numpy`库,并将其简称为`np`。张量操作: PyTorch 中的张量(tensor)和 NumPy 中的多维数组(ndarray)都是用来表示多维数据的数据结构。它们都支持类似的操作,如索引、切片、数学运算等2. `plt.figure(figsize=(20, 5))`:创建一个新的图形窗口,设置大小为20英寸宽、5英寸高。`figsize`参数控制的是图形的尺寸,以英寸为单位。3. `for i, imgs in enumerate(imgs[:20]):`:遍历`imgs`张量的第一个20个图像。`enumerate`函数同时返回图像的索引`i`和图像本身`imgs`。`imgs[:20]`表示我们只取前20个图像。4. `npimg = imgs.numpy().transpose((1, 2, 0))`:将PyTorch张量`imgs`转换为NumPy数组,并使用`.transpose`方法调整数组的维度。对于图像数据,原始的维度顺序通常是`[batch_size, channels, height, width]`,而`.transpose((1, 2, 0))`将其改为`[channels, height, width, batch_size]`,这样每个图像就被放到了单独的通道维度上。5. `plt.subplot(2, 10, i+1)`:在图形窗口中创建子图。`2`表示行数,`10`表示列数,`i+1`表示当前子图的索引(因为索引从1开始)。6. `plt.imshow(npimg, cmap=plt.cm.binary)`:使用`imshow`函数在当前子图中显示图像。`cmap=plt.cm.binary`指定了颜色映射,`binary`表示使用黑白两色,这有助于突出图像中的边缘和细节。7. `plt.axis('off')`:关闭坐标轴,这样图像显示得更加整洁,因为我们通常不需要在展示图像时显示坐标轴。8. `#plt.show()`:这是一个注释掉的代码行。`plt.show()`函数用于显示图形窗口。如果你在Jupyter Notebook或其他支持交云互动式环境的平台上运行代码,取消这行代码的注释可以显示图像。如果你使用的是PyCharm或其他IDE,可能需要使用其他方式来显示图像。需要注意的是,这段代码中的`plt.subplot(2, 10, i+1)`和`plt.imshow(npimg, cmap=plt.cm.binary)`是在一个循环中执行的,所以它会创建20个子图,每个子图显示一个图像。由于`plt.show()`被注释掉了,如果你在一个脚本中运行这段代码,你需要取消注释才能看到图像。在某些IDE中,如PyCharm,可能需要使用不同的方法来显示图像,例如使用`matplotlib`的`InlineBackend`。

 

二、构建简单的CNN网络

对于一般的CNN网络来说,都是由特征提取网络和分类网络构成,其中特征提取网络用于提取图片的特征,分类网络用于将图片进行分类。

1. torch.nn.Conv2d()详解

函数原型:

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros', device=None, dtype=None)

关键参数说明

  • in_channels ( int ) – 输入图像中的通道数
  • out_channels ( int ) – 卷积产生的通道数
  • kernel_size ( int or tuple ) – 卷积核的大小
  • stride ( int or tuple , optional ) -- 卷积的步幅。默认值:1
  • padding ( int , tuple或str , optional ) – 添加到输入的所有四个边的填充。默认值:0
  • dilation (int or tuple, optional) - 扩张操作:控制kernel点(卷积核点)的间距,默认值:1。
  • padding_mode (字符串,可选) – 'zeros', 'reflect', 'replicate'或'circular'. 默认:'zeros'

 2. torch.nn.Linear()详解

函数原型:

torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)

关键参数说明:

  • in_features:每个输入样本的大小
  • out_features:每个输出样本的大小

3. torch.nn.MaxPool2d()详解 

函数原型:

torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

关键参数说明:

  • kernel_size:最大的窗口大小
  • stride:窗口的步幅,默认值为kernel_size
  • padding:填充值,默认为0
  • dilation:控制窗口中元素步幅的参数

 4. 关于卷积层、池化层的计算:

下面的网络数据shape变化过程为:

3, 32, 32(输入数据)
-> 64, 30, 30(经过卷积层1)-> 64, 15, 15(经过池化层1)
-> 64, 13, 13(经过卷积层2)-> 64, 6, 6(经过池化层2)
-> 128, 4, 4(经过卷积层3) -> 128, 2, 2(经过池化层3)
-> 512 -> 256 -> num_classes(10)

这是一个典型的卷积神经网络(Convolutional Neural Network,CNN)结构,经过一系列的卷积层、池化层和全连接层后,最终输出 num_classes 个类别的概率分布。
让我们逐步解释每一步的变化:1.输入数据: 输入的数据是 3 通道(RGB)的图像,大小为 32x32 像素。
2.卷积层1: 卷积层1有64个卷积核,每个卷积核的大小是3x3,步长为1。在经过这一层后,输出特征图的大小变为 64x30x30。
3.池化层1: 池化层1对每个 2x2 的区域进行最大池化,步长为2,因此特征图的大小减半,变为 64x15x15。
4.卷积层2: 卷积层2有64个卷积核,每个卷积核的大小是3x3,步长为1。在经过这一层后,输出特征图的大小变为 64x13x13。
5.池化层2: 池化层2对每个 2x2 的区域进行最大池化,步长为2,因此特征图的大小再次减半,变为 64x6x6。
6.卷积层3: 卷积层3有128个卷积核,每个卷积核的大小是3x3,步长为1。在经过这一层后,输出特征图的大小变为 128x4x4。
7.池化层3: 池化层3对每个 2x2 的区域进行最大池化,步长为2,因此特征图的大小再次减半,变为 128x2x2。
8.Flatten: 将 128x2x2 的特征图展平为一个长度为 512 的向量。
9.全连接层1: 将长度为 512 的向量输入到全连接层,经过一层大小为 512x256 的权重矩阵进行线性变换,输出长度为 256 的向量。
10.全连接层2: 将长度为 256 的向量输入到全连接层,经过一层大小为 256xnumclasses(10)的权重矩阵进行线性变换,最终输出长度为 numclasses(10)的向量,表示每个类别的概率分布。这样的结构经过一系列的卷积和池化操作可以提取出图像的特征,最后通过全连接层得到最终的分类结果。

请根据我在之后作品发布的【卷积层的计算】与【池化层的计算】这两篇文章手动推导这个过程。

import torch.nn.functional as Fnum_classes = 10  # 图片的类别数class Model(nn.Module):def __init__(self):super().__init__()# 特征提取网络self.conv1 = nn.Conv2d(3, 64, kernel_size=3)   # 第一层卷积,卷积核大小为3*3self.pool1 = nn.MaxPool2d(kernel_size=2)       # 设置池化层,池化核大小为2*2self.conv2 = nn.Conv2d(64, 64, kernel_size=3)  # 第二层卷积,卷积核大小为3*3   self.pool2 = nn.MaxPool2d(kernel_size=2) self.conv3 = nn.Conv2d(64, 128, kernel_size=3) # 第二层卷积,卷积核大小为3*3   self.pool3 = nn.MaxPool2d(kernel_size=2) # 分类网络self.fc1 = nn.Linear(512, 256)          self.fc2 = nn.Linear(256, num_classes)# 前向传播def forward(self, x):x = self.pool1(F.relu(self.conv1(x)))     x = self.pool2(F.relu(self.conv2(x)))x = self.pool3(F.relu(self.conv3(x)))x = torch.flatten(x, start_dim=1)x = F.relu(self.fc1(x))x = self.fc2(x)return x
#加载并打印模型
from torchinfo import summary
# 将模型转移到GPU中(我们模型运行均在GPU中进行)
model = Model().to(device)summary(model)

注意:在加载并打印模型的时候 ,可能会报错,输入这条命令就可以了

输出结果:

三、训练模型

1.设置超参数

#已经是老生常谈得了 设置超参数,一开始的参数叫超参数
loss_fn    = nn.CrossEntropyLoss() # 创建损失函数
learn_rate = 1e-2 # 学习率
opt        = torch.optim.SGD(model.parameters(),lr=learn_rate)

2.编写训练函数

1. optimizer.zero_grad()

optimizer.zero_grad() 是 PyTorch 中用于将优化器中所有参数的梯度清零的方法。在训练神经网络时,通常会在每个 mini-batch 的训练之前调用 optimizer.zero_grad() 来手动将之前计算的梯度清零,以确保每次迭代的梯度是新的,不会受到之前迭代的影响。

2. loss.backward()

PyTorch的反向传播(即tensor.backward())是通过autograd包来实现的,autograd包会根据tensor进行过的数学运算来自动计算其对应的梯度。

具体来说,torch.tensor是autograd包的基础类,如果你设置tensor的requires_grads为True,就会开始跟踪这个tensor上面的所有运算,如果你做完运算后使用tensor.backward(),所有的梯度就会自动运算,tensor的梯度将会累加到它的.grad属性里面去。

更具体地说,损失函数loss是由模型的所有权重w经过一系列运算得到的,若某个w的requires_grads为True,则w的所有上层参数(后面层的权重w)的.grad_fn属性中就保存了对应的运算,然后在使用loss.backward()后,会一层层的反向传播计算每个w的梯度值,并保存到该w的.grad属性中。

如果没有进行tensor.backward()的话,梯度值将会是None,因此loss.backward()要写在optimizer.step()之前。

3. optimizer.step()

optimizer.step() 方法的作用是根据优化器的规则来更新模型参数,将模型向损失函数减小的方向优化。

step()函数的作用是执行一次优化步骤,通过梯度下降法来更新参数的值。因为梯度下降是基于梯度的,所以在执行optimizer.step()函数前应先执行loss.backward()函数来计算梯度。

注意:

optimizer只负责通过梯度下降进行优化,而不负责产生梯度,梯度是tensor.backward()方法产生的。

# 训练循环
def train(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset)  # 训练集的大小,一共60000张图片num_batches = len(dataloader)   # 批次数目,1875(60000/32)train_loss, train_acc = 0, 0  # 初始化训练损失和正确率for X, y in dataloader:  # 获取图片及其标签X, y = X.to(device), y.to(device)# 计算预测误差pred = model(X)          # 网络输出loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失# 反向传播optimizer.zero_grad()  # grad属性归零loss.backward()        # 反向传播optimizer.step()       # 每一步自动更新# 记录acc与losstrain_acc  += (pred.argmax(1) == y).type(torch.float).sum().item()train_loss += loss.item()train_acc  /= sizetrain_loss /= num_batchesreturn train_acc, train_loss

3.编写测试函数

测试函数和训练函数大致相同,但是由于不进行梯度下降对网络权重进行更新,所以不需要传入优化器

def test (dataloader, model, loss_fn):size        = len(dataloader.dataset)  # 测试集的大小,一共10000张图片num_batches = len(dataloader)          # 批次数目,313(10000/32=312.5,向上取整)test_loss, test_acc = 0, 0# 当不进行训练时,停止梯度更新,节省计算内存消耗with torch.no_grad():for imgs, target in dataloader:imgs, target = imgs.to(device), target.to(device)# 计算losstarget_pred = model(imgs)loss        = loss_fn(target_pred, target)test_loss += loss.item()test_acc  += (target_pred.argmax(1) == target).type(torch.float).sum().item()test_acc  /= sizetest_loss /= num_batchesreturn test_acc, test_loss

4.正式训练

1. model.train()

model.train()的作用是启用 Batch Normalization 和 Dropout。

如果模型中有BN层(Batch Normalization)和Dropout,需要在训练时添加model.train()model.train()是保证BN层能够用到每一批数据的均值和方差。对于Dropoutmodel.train()是随机取一部分网络连接来训练更新参数。

2. model.eval()

model.eval()的作用是不启用 Batch Normalization 和 Dropout。

如果模型中有BN层(Batch Normalization)和Dropout,在测试时添加model.eval()model.eval()是保证BN层能够用全部训练数据的均值和方差,即测试过程中要保证BN层的均值和方差不变。对于Dropoutmodel.eval()是利用到了所有网络连接,即不进行随机舍弃神经元。

训练完train样本后,生成的模型model要用来测试样本。在model(test)之前,需要加上model.eval(),否则的话,有输入数据,即使不训练,它也会改变权值。这是model中含有BN层和Dropout所带来的的性质

epochs     = 10
train_loss = []
train_acc  = []
test_loss  = []
test_acc   = []for epoch in range(epochs):model.train()epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)model.eval()epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)train_acc.append(epoch_train_acc)train_loss.append(epoch_train_loss)test_acc.append(epoch_test_acc)test_loss.append(epoch_test_loss)template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))
print('Done')

四、结果可视化

import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings("ignore")               #忽略警告信息
plt.rcParams['font.sans-serif']    = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False      # 用来正常显示负号
plt.rcParams['figure.dpi']         = 100        #分辨率epochs_range = range(epochs)plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

 

五、学员问题

 

一句话总结 每一次的卷积层和池化层 都会让特征图的像素大小减半,然后输入通道和输出通道分别是输入几张特征图和输出几张特征图所以输出特征图为128,像素是2x2,所以经过flat层展平后有512个像素。让我们通过一个简单的例子来说明如何将第三个池化层的输出尺寸(128个特征图)和后面全连接层的输入尺寸(512)联系起来。
假设我们有一张彩色图像,尺寸为 32x32 像素,这是输入到我们神经网络的图像。我们的神经网络经过一系列的卷积和池化操作后,得到了一组特征图,其中最后一个池化层的输出是 128 个特征图。1.在第一个池化层之前,经过第一个卷积层后,特征图的尺寸可能减小为 16x16(这取决于卷积核大小和步幅)。
2.经过第一个池化层后,每个特征图的尺寸再次减半,变为 8x8。
3.经过第二个卷积层和第二个池化层后,特征图的尺寸再次减半,变为 4x4。
4.经过第三个卷积层和第三个池化层后,特征图的尺寸再次减半,变为 2x2。所以,最后一个池化层输出的 128 个特征图,每个尺寸为 2x2。这 128 个特征图包含了原始图像经过神经网络处理后的各种抽象特征。
现在,我们将这些特征图中的每个像素看作是一个独立的特征。因此,每个特征图有 2x2 = 4 个像素,因此总共有 128x4 = 512 个像素。这就是为什么最后一个池化层的输出大小为 512。
在神经网络的全连接层中,这 512 个像素被展开成一个向量,作为全连接层的输入。因此,虽然我们在最后一个池化层输出了 128 个特征图,但在全连接层中,这些特征图的像素被组合成了一个 512 维的向量作为输入。

 

六,总结

构建数据集中

也是从网上下的 简单方便,在构建数据集时,我认为有两个重点,1是dataset下载,2是dataloader加载数据集,后续处理也都是用的dataloader

构建cnn网络中

,定义网络结构,几层卷积池化根据自己的想法,前向传播得出经过特征提取和分类网络得到的数据结果

训练模型中

编写训练函数中

损失函数,学习率,优化器,统统安排上,我们要计算准确率和损失,先把训练集的大小,批次数目加载出来,初始化训练损失和正确率,然后for循环依次取图片标签,好嘞,可以开始预测了 计算预测误差,得到损失函数后,也就是能初步判断这个模型咋样了,然后我们根据损失函数,梯度清零,反向传播,更新网络中的参数,每一步按照梯度下降的方向依次更新,这个时候要记录准确的数量和损失函数的总量,最后,准确的数量除以总量,就是准确率,损失除以批次数量,就是损失

编写测试函数同理

测试函数和训练函数大致相同,但是由于不进行梯度下降对网络权重进行更新,所以不需要传入优化器

来到了正式训练

正式训练来了,先把批次定义了,然后定义四个数组存贮每次的acc和loss,运行训练模型和测试模型,记录他们对应的acc和loss,注意先用model().train然后在记录,详细问题看代码

最后可视化

matplotlib.pyplot来绘图,图如上,可以看到最后将近接近一个峰值。

本次的学习结束了,想起一句话,路虽远,行则将至,慢慢来吧,跟着K同学大佬一步步学习


   

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

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

相关文章

智能合约平台开发指南

随着区块链技术的普及,智能合约平台已经成为了这个领域的一个重要趋势。智能合约可以自动化执行合同条款,大大减少了执行和监督合同条款所需的成本和时间。那么,如何开发一个智能合约平台呢?以下是一些关键步骤。 一、选择合适的区…

MySQL学习笔记2——基础操作

基础操作 一、增删改查1、添加数据2、删除数据3、修改数据4、查询语句 二、主键三、外键和连接1、外键2、连接 一、增删改查 1、添加数据 INSERT INTO 表名[(字段名[,字段名]…)] VALUES (值的列表); --[]表示里面的内容可选添加数据分为插入数据记录和插入查询结果 插入数据…

AI+BI,欢迎数据分析进入大模型时代

过去一年大模型应用集中爆发,中关村科金作为领先的对话式AI技术解决方案提供商,基于各个行业真实的业务痛点,围绕营销、服务与运营场景,创新打造和升级了知识助手、投顾助手、智能陪练等大模型应用,全面赋能客户经理展…

【INNODB引擎篇】深奥探究Innodb存储引擎

🔥作者主页:小林同学的学习笔录 🔥mysql专栏:小林同学的专栏 目录 1.InnoDB引擎 1.1 逻辑存储结构 1.2 架构 1.2.1 概述 1.2.2 内存结构 1.2.3 磁盘结构 1.2.4 后台线程 1.3 事务原理 1.3.1 事务基础 1.3.2 redo log 1.…

鸿蒙TypeScript学习第12天【Map对象】

1、TypeScript Map 对象 Map 对象保存键值对,并且能够记住键的原始插入顺序。 任何值(对象或者原始值) 都可以作为一个键或一个值。 Map 是 ES6 中引入的一种新的数据结构,可以参考gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md 2、创…

【架构-九】数据库反规范化设计

什么是反规范化设计? 反规范化是指为了提高数据库的性能或满足特定需求而向数据库中增加冗余数据的过程。与数据库规范化设计正好相反,反规范化的目的是减少查询的复杂度,加快数据检索的速度。主要的反规范化手段如下: 优点&am…

YOLOv8打印模型结构配置信息并查看网络模型详细参数:参数量、计算量(GFLOPS)

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

Python3.7编程之病毒

基础篇 什么是病毒 病毒,指的是一些通过非法手段获取系统的一些权限,然后进行破坏或者盗取。 病毒分为两类: 1、破坏型 这类病毒往往会将系统弄的乱七八糟,比如把你的U盘删光,把你的系统背景调成黑客图片&#xff0c…

python 的join函数

join函数是一个对字符串处理的函数 字符串.join(str)的含义是把字符串加入到str的每一个间隙里面 如 str1234 ,.join(str) #打印的结果为 1,2,3,4

类和对象【一】类和对象简介

文章目录 C的类与C语言结构体的区别【引入类】类的定义类体中的成员函数的实现类中的访问限定符C中class和struct的区别 类的作用域类的实例化类中成员的存储位置类的大小 C的类与C语言结构体的区别【引入类】 类里面不仅可以定义变量还可以定义函数 例 类具有封装性【将在该…

abap 字符超过255的显示

大家都知道SAP ALV的一个单元格最大显示的长度就是255 意思就是你的这个字段在内表里面即使是超过255位,也无法只能显示255 如果客户的需求是需要看到完整的消息内容, 最简单的就是将整个程序的数据右键导出到excle中去查看 如果客户执意需要在ALV中…

python+django教师业绩考评考核评分系统flask

在设计过程中,将参照一下国内外的一些同类网站,借鉴下他们的一些布局框架,将课题要求的基本功能合理地组织起来,形成友好、高效的交互过程。开发的具体步骤为:   第一步,进行系统的可行性分析&#xff0c…

佛山市人工智能产业生态交流会:实在智能Agent引领“智造浪潮”

制造业,实体经济的核心,技术创新的先锋,供给侧结构性改革的关键。在新一轮产业竞争中,数字化转型成为制造业升级的必由之路,是引领未来的重要抓手。 为促进数字经济赋能实体经济,加快人工智能技术的推广应用…

汇编入门--基础知识(1)

1.汇编语言的概念 汇编语言是一种低级编程语言,它与计算机的机器语言非常接近,但比机器语言更易于人类阅读和理解。汇编语言是用一系列的助记符来表示机器语言的操作码和操作数。每种计算机体系结构(如x86、ARM等)都有自己的汇编语…

CCD机器视觉在工业生产中起到什么作用?

CCD机器视觉尺寸测量是基于相对测量方法,通过可追溯性、放大校准、自动边缘提升和屏幕图像测量来计算实际尺寸。在精密测量中,放大倍数必须达到35倍或更高,才能达到微米级的精度。此时,视线宽度小于5mm。对于大于5mm的物体&#x…

小型时间继电器ST3PA-C DC24V 带插座PF085A 导轨安装 JOSEF约瑟

ST3P系列时间继电器 系列型号 ST3PF-2Z(JSZ3F-2Z) 5s AC110V ST3PF(JSZ3F) 10s AC48V ST3PC-1(AH3-3) 5s DC24V ST3PC-1(AH3-3) 2h AC220V ST3PC-F(JSZ3C-F) AC380V ST3PA-E(JSZ3A-E) DC24V ST3PA-F(JSZ3A-F) DC24V ST3PF(JSZ3F) 10s AC36V ST3PC-1(AH3-3) 10s AC24V ST3PC-1…

Linux使用C语言实现Socket编程

Socket编程 这一个课程的笔记 相关文章 协议 Socket编程 高并发服务器实现 线程池 网络套接字 socket: (电源)插座(电器上的)插口,插孔,管座 在通信过程中, 套接字是成对存在的, 一个客户端的套接字, 一个…

【算法】求{1,2,3}序列的全排列,邻里交换法(Java)

【算法】求{1,2,3}序列的全排列,邻里交换法(Java) 代码如下: public class Main{static int count;static int a[] {1,2,3};public static void main(String[] args) {f(a,0);System.out.println(count);}p…

MAC苹果电脑如何使用Homebrew安装iperf3

一、打开mac终端 找到这个终端打开 二、终端输入安装Homebrew命令 Homebrew官网地址:https://brew.sh/ 复制这个命令粘贴到mac的终端窗口,然后按回车键 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/in…

未来汽车硬件安全的需求(1)

目录 1.概述 2.EVITA 2.1 EVITA HSM 2.2 EVITA保护范围 3.市场变化对车载网络安全的影响 3.1 非侵入式攻击的风险 3.2 量子计算机的蛮力攻击 3.3 整车E/E架构的变化 3.4 网络安全标准和认证 3.5 汽车工业的网络安全措施 4.汽车安全控制器 4.1 TPM2.0 4.2 安全控…