Pytorch 卷积神经网络-手写数字识别

卷积神经网络是深度学习中的一个里程碑式的技术,有了这个技术,才会让计算机有能力理解图片和视频信息,才会有计算机视觉的众多应用。 本文讨论卷积神经网络模型(CNN)的Hello World。前面讨论的是一个二分类问题,本文讨论多分类问题。每张图片是一个28*28的灰度图片,所以本文的任务是给出一张图片,能识别这个图片是0-9数字中的哪一个。不过在此之前,还得学习一下卷积神经网络的基础知识。

1 卷积神经网络基础

之前我们学习的案例,对于模型的输入都是向量,但是当输入是一个图片的时候该怎么做呢?最直接的方式是把图片的像素点按照行列拉成一个长长的向量。这样就可以采用之前的方式来训练模型。但是如上图所示,一个“猫”的照片是1000_1000,由于是彩色的,具有R,G,B三个通道,那么输入的数据大小就是1000_1000_3,如果一个神经网络第一层有1000个神经元,那么总的参数量为1000_1000_3_1000 = 3 * 109个参数,这对硬件资源提出了太高的要求。

传统的方式,进行可以先对上面的图片进行模糊化处理,这个是怎么做到的呢?

RGB可以看出3个2维矩阵,在模糊化的过程中,需要用上面的这个3_3矩阵,称之为核-kernel,核的大小为3_3,被称为kernel-size,这个核和原来矩阵作用的过程称为卷积。这个kernel就类似全连接层中的Weights一样,所以卷积核里的数值,也是通过反向传播的方法学习到的。

1.1 卷积层

卷积的运算规则:卷积核在输入矩阵中上下滑动,然后和对应的元素相乘求和。

如上图,卷积核大小是3x3的,也就是说其卷积核每次覆盖原图像的9个像素,行和列都滑动了3次,一共滑动3x3=9次,得到了一个3*3的二维矩阵。卷积核在矩阵横向或者纵向一次移动的大小叫做步长(stride),步长可以为1,2,3,4。我们直接看一下代码。

import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
import torch.nn.functional as F
from PIL import Image
import matplotlib.pyplot as pltif __name__ == "__main__":# 使用convert('L')读入一个灰度图片image = Image.open('../digital_recognition/digital_data/cat.png').convert('L')# 将图片转成矩阵image = np.array(image, dtype='float32')# 将图片显示出来plt.imshow(image.astype('uint8'), cmap='gray')print("finish")

torch.nn.Conv2d(in_channels, #输入特征矩阵的深度即channel,比如输入一张RGB彩色图像,那in_channels = 3;out_channels, #代表卷积核的个数,使用n个卷积核输出的特征矩阵深度即channel就是n;kernel_size, #卷积核大小stride=1, # 卷积的步长padding=0, #卷积核对图像四周的填充边界dilation=1, groups=1, bias=True, padding_mode='zeros', device=None, dtype=None
)
# 将图片矩阵转换成pytorch tensor,并适配卷积的输入的要求
image = torch.from_numpy(image.reshape(1,1,image.shape[0],image.shape[1]))# 构建一个卷积,输入和输出通道都是1(因为是黑白的),卷积核大小是3,
conv = nn.Conv2d(1,1,3,bias=False)
# 构建卷积核
sobel_kernel = np.array([[-1,-1,-1],[-1,-8,-1],[-1,-1,-1]],dtype='float32')
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3))
# 给卷积的kernel赋值
conv.weight.data = torch.from_numpy(sobel_kernel)
edge = conv(Variable(image))
# 将输出转成图片的格式
edge = edge.data.squeeze().numpy()
plt.imshow(edge,cmap='gray')
print("finish")

卷积操作图片结果如下:

下面表格列举了其他卷积核的效果

卷积核里面的数字现在是固定的,只能表现图像的某些特性,那么我们可以不固定卷积核里面的数值,然后通过监督学习的方式去自动学习他,“这个可以学习的卷积操作”就是构成卷积神经网络里面最重要的概念。

1.2 池化层

池化是一个对输入进行下采样的操作,能快速减少输入大小,从而减少神经网络后面的参数量,便于训练模型。相对于卷积的下采样,有不需要参数的优点(没有卷积核参数)。一般有两种池化方式:
● 最大值池化层(max pooling)
● 平均值池化层(average pooling)

下面图是一个最大值池化层,每种颜色的矩阵取一个最大值构成右边的图。

我们从代码来看一下:

#池化核大小是2,移动步长是2
max_pool = nn.MaxPool2d(2, 2)
print('before max pool, image shape:{} * {}'.format(image.shape[2], image.shape[3]))image = max_pool(Variable(image))image = image.data.squeeze().numpy()
plt.imshow(image,cmap='gray')
print('before max pool, image shape:{} * {}'.format(image.shape[0], image.shape[1]))
print("max_pool finish")
image shape= (886, 878)
before max pool, image shape:886 * 878
before max pool, image shape:443 * 439

和原图对比,内容没有变化但是尺寸发生了变化。说明池化只能改变图片的大小,不会影响图片的内容。

1.3 总结

理解了卷积层和池化层,那么卷积神经网络就是卷积层+池化层作用神经网络的隐藏层反复出现的多层神经网络结构,如下图所示。

我们分析一下它的层级结构:
● 原始的输入是一张图片,可以是彩色的,也可以是灰度的或黑白的。这里假设是只有一个通道的图片,目的是识别0~9的手写体数字;
● 第一层卷积,我们使用了4个卷积核,得到了4张feature map;激活函数层没有单独画出来,这里我们紧接着卷积操作使用了Relu激活函数;
● 第二层是池化,使用了Max Pooling方式,把图片的高宽各缩小一倍,但仍然是4个feature map;
● 第三层卷积,我们使用了4x6个卷积核,其中4对应着输入通道,6对应着输出通道,从而得到了6张feature map,当然也使用了Relu激活函数;
● 第四层再次做一次池化,现在得到的图片尺寸只是原始尺寸的四分之一左右;
● 第五层把第四层的6个图片展平成一维,成为一个全连接层;
● 第六层再接一个小一些的全连接层;
● 最后接一个softmax函数,判别10个分类,这个后面实战会在介绍一下。
所以,在一个典型的卷积神经网络中,会至少包含以下几个层:
● 卷积层
● 激活函数层
● 池化层
● 全连接分类层

2 手写数字识别实战

2.1 ReLU激活函数

上面了解了卷积神经网络的基础知识,这里在介绍一个新的激活函数,ReLU函数(Rectified Linear Unit)。

ReLU和Sigmoid函数是常用的激活函数,它们在神经网络中起到非线性映射的作用,下面是它们的优缺点对比:
ReLU函数优点:
● 计算简单,只需要判断输入是否大于零。
● 解决了sigmoid函数的梯度消失问题,能更好地应对梯度下降算法。
● 可以使一部分神经元的输出为零,从而实现稀疏性,减少模型的复杂度。
ReLU函数缺点:
● ReLU函数在输入小于零时,梯度为零,导致神经元无法更新权重,称为“神经元死亡”问题。
● 对于输入小于零的情况,ReLU函数不是严格的非线性函数,可能导致模型的表达能力受限。

Sigmoid函数优点:
● Sigmoid函数的输出范围在(0,1)之间,可以将输出解释为概率。
● Sigmoid函数是严格的非线性函数,具有较强的表达能力。
● 可以将Sigmoid函数的输出直接作为分类器的输出,适用于二分类问题。
Sigmoid函数缺点:
● Sigmoid函数存在梯度饱和问题,当输入的绝对值很大时,梯度接近于零,导致梯度下降算法收敛缓慢。
● Sigmoid函数的计算量较大,使用指数运算,计算时间较长。

2.2 交叉熵损失函数

2.3 读取数据集
def load_dataset():train_data = mnist.MNIST('.data', train=True, download=True)test_data = mnist.MNIST('.data', train=False, download=True)return train_data, test_dataif __name__ == '__main__':train_data, test_data = load_dataset()data, label = train_data[0]print("data", data)print("label", label)image = np.array(data, dtype='float32')print("image shape =", image.shape)print("image =", image)# 将图片显示出来plt.imshow(image.astype('uint8'), cmap='gray')print("finish")

首次执行的时候,需要下载。

输出:

label 5
image shape = (28, 28)
image = [[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   3.  18.18.  18. 126. 136. 175.  26. 166. 255. 247. 127.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.  30.  36.  94. 154. 170. 253.253. 253. 253. 253. 225. 172. 253. 242. 195.  64.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.  49. 238. 253. 253. 253. 253. 253.253. 253. 253. 251.  93.  82.  82.  56.  39.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.  18. 219. 253. 253. 253. 253. 253.198. 182. 247. 241.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.  80. 156. 107. 253. 253. 205.11.   0.  43. 154.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.  14.   1. 154. 253.  90.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0. 139. 253. 190.2.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.  11. 190. 253.70.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.  35. 241.225. 160. 108.   1.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.  81.240. 253. 253. 119.  25.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.45. 186. 253. 253. 150.  27.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.  16.  93. 252. 253. 187.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0. 249. 253. 249.  64.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.46. 130. 183. 253. 253. 207.   2.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.  39. 148.229. 253. 253. 253. 250. 182.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.  24. 114. 221. 253.253. 253. 253. 201.  78.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.  23.  66. 213. 253. 253. 253.253. 198.  81.   2.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.  18. 171. 219. 253. 253. 253. 253. 195.80.   9.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.  55. 172. 226. 253. 253. 253. 253. 244. 133.  11.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0. 136. 253. 253. 253. 212. 135. 132.  16.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
[  0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]]
2.4 定义模型

class CNN(nn.Module):  # 我们建立的CNN继承nn.Module这个模块def __init__(self):super(CNN, self).__init__()# 建立第一个卷积(Conv2d)-> 激活函数(ReLU)->池化(MaxPooling)self.conv1 = nn.Sequential(# 第一个卷积con2dnn.Conv2d(  # 输入图像大小(1,28,28)in_channels=1,  # 输入图片的高度,因为minist数据集是灰度图像只有一个通道out_channels=16,  # n_filters 卷积核的高度kernel_size=5,  # filter size 卷积核的大小 也就是长x宽=5x5stride=1,  # 步长padding=2,  # 想要con2d输出的图片长宽不变,就进行补零操作 padding = (kernel_size-1)/2),  # 输出图像大小(16,28,28)# 激活函数nn.ReLU(),# 池化,下采样nn.MaxPool2d(kernel_size=2),  # 在2x2空间下采样# 输出图像大小(16,14,14))# 建立第二个卷积(Conv2d)-> 激励函数(ReLU)->池化(MaxPooling)self.conv2 = nn.Sequential(# 输入图像大小(16,14,14)nn.Conv2d(  # 也可以直接简化写成nn.Conv2d(16,32,5,1,2)in_channels=16,out_channels=32,kernel_size=5,stride=1,padding=2),# 输出图像大小 (32,14,14)nn.ReLU(),nn.MaxPool2d(2),# 输出图像大小(32,7,7))# 建立全卷积连接层self.out = nn.Linear(32 * 7 * 7, 10)  # 输出是10个类# 下面定义x的传播路线def forward(self, x):x = self.conv1(x)  # x先通过conv1x = self.conv2(x)  # 再通过conv2# 把每一个批次的每一个输入都拉成一个维度,即(batch_size,32*7*7)# 因为pytorch里特征的形式是[bs,channel,h,w],所以x.size(0)就是batchsizex = x.view(x.size(0), -1)  # view就是把x弄成batchsize行个tensoroutput = self.out(x)return output
2.5 训练模型
# 超参数
EPOCH = 10 
BATCH_SIZE = 50
LR = 0.001  # 学习率
DOWNLOAD_MNIST = True  # 表示还没有下载数据集,如果数据集下载好了就写Falseif __name__ == '__main__':# 训练集train_data = torchvision.datasets.MNIST(root='./data/',  # 保存或提取的位置  会放在当前文件夹中train=True,  # true说明是用于训练的数据,false说明是用于测试的数据transform=torchvision.transforms.ToTensor(),  # 转换PIL.Image or numpy.ndarraydownload=DOWNLOAD_MNIST,  # 已经下载了就不需要下载了)# 测试集test_data = torchvision.datasets.MNIST(root='./data/',train=False)# 加载数据train_loader = Data.DataLoader(dataset=train_data,batch_size=BATCH_SIZE,shuffle=True  # 是否打乱数据,一般都打乱)# 图像的pixel本来是0到255之间,除以255对图像进行归一化使取值范围在(0,1)# torch.unsqueeze(a) 是用来对数据维度进行扩充,这样shape就从(x,28,28)->(x,1,28,28)test_x = torch.unsqueeze(test_data.train_data, dim=1).type(torch.FloatTensor) / 255test_y = test_data.test_labelscnn = CNN()print(cnn)# 优化器选择Adamoptimizer = torch.optim.Adam(cnn.parameters(), lr=LR)# 损失函数loss_func = nn.CrossEntropyLoss() # 开始训练for epoch in range(EPOCH):for step, (b_x, b_y) in enumerate(train_loader):  # 分配batch dataoutput = cnn(b_x)  # 先将数据放到cnn中计算outputloss = loss_func(output, b_y)  # 输出和真实标签的loss,二者位置不可颠倒optimizer.zero_grad()  # 清除之前学到的梯度的参数loss.backward()  # 反向传播,计算梯度optimizer.step()  # 应用梯度if step % 100 == 0:test_output = cnn(test_x)pred_y = torch.max(test_output, 1)[1].data.numpy()accuracy = float((pred_y == test_y.data.numpy()).astype(int).sum()) / float(test_y.size(0))print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy(), '| test accuracy: %.2f' % accuracy)# 保存模型torch.save(cnn.state_dict(), 'cnn2.pkl')

跑了7个Epoch之后,模型的准确率已经到99%。

Epoch:  0 | train loss: 2.3034 | test accuracy: 0.14
Epoch:  0 | train loss: 0.5552 | test accuracy: 0.89
Epoch:  0 | train loss: 0.1276 | test accuracy: 0.95
Epoch:  0 | train loss: 0.0556 | test accuracy: 0.96
.....
Epoch:  7 | train loss: 0.0666 | test accuracy: 0.99
Epoch:  7 | train loss: 0.0071 | test accuracy: 0.99
Epoch:  7 | train loss: 0.0054 | test accuracy: 0.99
2.6 模型验证
cnn.load_state_dict(torch.load('cnn2.pkl'))
cnn.eval()test_output = cnn(test_x)
pred_y = torch.max(test_output, 1)[1].data.numpy()
print(pred_y, 'prediction number')
print(test_y.numpy(), 'real number')
# 检查元素是否相等并统计不相等的个数
unequal_count = sum(pred_y[i] != test_y[i] for i in range(len(pred_y)))# 计算不相等的比例
equal_ratio = 1 - unequal_count / len(pred_y)
# 输出结果
print("总个数:{},不相等的个数{}".format(len(pred_y), unequal_count))
print("准确率:", equal_ratio.item())
[7 2 1 ... 4 5 6] prediction number
[7 2 1 ... 4 5 6] real number
总个数:10000,不相等的个数165
准确率: 0.9835000038146973

那么,我们该如何学习大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

一、大模型全套的学习路线

学习大型人工智能模型,如GPT-3、BERT或任何其他先进的神经网络模型,需要系统的方法和持续的努力。既然要系统的学习大模型,那么学习路线是必不可少的,下面的这份路线能帮助你快速梳理知识,形成自己的体系。

L1级别:AI大模型时代的华丽登场

L2级别:AI大模型API应用开发工程

L3级别:大模型应用架构进阶实践

L4级别:大模型微调与私有化部署

一般掌握到第四个级别,市场上大多数岗位都是可以胜任,但要还不是天花板,天花板级别要求更加严格,对于算法和实战是非常苛刻的。建议普通人掌握到L4级别即可。

以上的AI大模型学习路线,不知道为什么发出来就有点糊,高清版可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

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

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

相关文章

网络安全 - DNS劫持原理 + 实验

DNS 劫持 什么是 DNS 为什么需要 DNS D N S \color{cyan}{DNS} DNS(Domain Name System)即域名系统。我们常说的 DNS 是域名解析协议。 DNS 协议提供域名到 IP 地址之间的解析服务。计算机既可以被赋予 IP 地址,也可以被赋予主机名和域名。用…

Hbase搭建教程

Hbase搭建教程 期待您的关注 ☀小白的Hbase学习笔记 目录 Hbase搭建教程 1.上传hbase的jar包并解压 2.重新登录 3.启动zookeeper 4.配置环境变量 5.关闭ZK的默认配置 6.修改hbase-site.xml文件 7.修改regionservers文件 8.将配置好的文件分发给其它节点 9.配置环境变量…

单通道触摸感应开关RH6016

1.简介 SOT23-6 RH6016 封装和丝印 RH6016 是一款内置稳压模块的单通道电容式触摸感应控制开关IC,可以替代传统的机械式开关。 RH6016可在有介质(如玻璃、亚克力、塑料、陶瓷等)隔离保护的情况下实现触摸功能,安全性高。 RH6016内置高精度稳压、上电复…

Requests —— 请求头设置!

前戏 在我们进行自动化测试的时候,很多网站都会都请求头做个校验,比如验证 User-Agent,看是不是浏览器发送的请求,如果我们不加请求头,使用脚本访问,默认User-Agent是python,这样服务器如果进行…

DeepSORT(目标跟踪算法)卡尔曼滤波中的贝叶斯定理

DeepSORT(目标跟踪算法)卡尔曼滤波中的贝叶斯定理 flyfish 从例子中介绍名词 假设我们有一个袋子,里面有5个红球和3个蓝球。我们从袋子里随机抽取一个球。 概率 (Probability) 我们想计算从袋子里抽到红球的概率 P ( R ) P(R) P(R)。 …

misc刷题记录(1)陇剑杯

[陇剑杯 2021]签到 题目内容:此时正在进行的可能是__________协议的网络攻击。(如有字母请全部使用小写,填写样例:http、dns、ftp)。得到的flag请使用NSSCTF{}格式提交。 打开统计,找到协议分级&#xff…

大模型应用之路:从提示词到通用人工智能(AGI)

前言 大模型在人工智能领域的应用正迅速扩展,从最初的提示词(Prompt)工程到追求通用人工智能(AGI)的宏伟目标,这一旅程充满了挑战与创新。本文将探索大模型在实际应用中的进展,以及它们如何为实…

php实现一个简单的MySQL分页

一、案例演示&#xff1a; 二、php 代码 <?php $servername "localhost"; // MySQL服务器名称或IP地址 $username "root"; // MySQL用户名 $password "123456"; // MySQL密码 $dbname "test"; // 要连接…

CentOS7安装nginx【巨详细】

CentOS7安装nginx 安装依赖 1.安装gcc&#xff0c;nginx 编译时依赖 gcc 环境 # 安装c yum install gcc-c# 查看版本 gcc -v正常情况显示如下 2.安装openssl 安全套接字层密码库&#xff0c;用于通信加密 yum install -y openssl openssl-devel3.安装zlib,zlib 库 提供了很多…

java反序列化---cc6链

目录 Transformer[]数组分析 链条代码跟进 ChainedTransformer.transform() LazyMap.get() TiedMapEntry.getValue() TiedMapEntry.hashCode() HashMap.hash() HashMap.put()的意外触发 LazyMap.get()中key的包含问题 cc6的payload如下 import org.apache.commons.co…

【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【08】【商品服务】Object划分_批量删除

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【08】【商品服务】Object划分_批量删除 Object划分批量删除/添加参考 Object划分 数据库中对于一张表的数据&#xff0c;由于拥有隐私字段、多余字段、字段过少等原因&#xff0c;不应该直…

汽车油耗NEDC与WLTP有什么区别?以及MATLAB/Simulink的汽车行驶工况仿真

最近的热点新闻非比亚迪的秦L莫属&#xff0c;其油耗达到2.9L/100km&#xff0c;但其标注为NEDC也引起了讨论&#xff0c; NEDC与WLTP的区别 NEDC的全称为“New European Driving Cycle”&#xff0c;即“新欧洲驾驶循环”。这种油耗测试标准起源于上世纪80年代&#xff0c;主…

液晶拼接屏企业应该采取哪些措施来提升整体竞争力和市场地位呢?

步入智能科技时代以来&#xff0c;商显行业面对着各式各样的挑战&#xff0c;人工智能、AI大模型等整合中&#xff0c;液晶拼接屏企业应该采取哪些措施以提升整体竞争力和市场地位。下面小编个人观点简单说一下&#xff1b;下是一些关键的措施&#xff1a; 首先&#xff0c;加…

用Vue3和p5.js打造一个交互式数据可视化仪表盘

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 基于 Vue.js 集成 p5.js 实现交互式波形图 应用场景介绍 在数据可视化领域&#xff0c;波形图广泛应用于展示动态变化的数据&#xff0c;如声音信号、心跳曲线等。通过动态绘制波形图&#xff0c;用户可以直观…

5.所有权

标题 一、概念二、规则三、示例3.1 变量作用域3.2 所有权的移交&#xff08;深拷贝与浅拷贝&#xff09;3.3 函数与所有权3.4 返回值与作用域3.5 引用的使用 四、切片(&str) 一、概念 所有权是Rust的核心特性。所有程序在运行时都必须管理它们使用计算机内存的方式。Rust的…

InfoComm 2024 直击:千视新品P3和KiloLink技术闪耀亮相

InfoComm 2024 直击&#xff1a;千视新品P3和KiloLink技术闪耀亮相&#xff0c;现场亮点不断 北京时间2024年6月13日&#xff0c;UTC-7时间6月12日&#xff0c;美国视听显示与系统集成展览会InfoComm 2024在美国拉斯维加斯正式开幕。作为全美规模最大、最具影响力的展会&#…

【Test 73 】引用 () 实际的一些用法、常引用问题 详解!

文章目录 1. 常引用的背景2. 字符 a 与 整形 97 是相同的&#xff0c;但是具体是怎么比较的呢 &#xff1f; 1. 常引用的背景 注意&#xff1a; &#x1f427;① 权限可以平移、可以缩小&#xff0c;但是权限 不可以放大。 &#x1f427; 类型转换中间会产生临时变量 2. 字…

[AI资讯·0612] AI测试高考物理题,最高准确率100%,OpenAI与苹果合作,将ChatGPT融入系统中,大模型在物理领域应用潜力显现

AI资讯 国产AI大战高考物理&#xff0c;第1题全对&#xff0c;第2题开始放飞终于放大招了&#xff0c;2024WWDC&#xff0c;苹果开启AI反击战苹果一夜重塑iPhone&#xff01;GPT-4o加持Siri&#xff0c;AI深入所有APPOpenAI确认苹果集成ChatGPT 还任命了两位新高管GPT-4搞不定…

【Golang】探索进程资源监控的精妙细节:利用Gopsutil/Process实现高级进程性能和资源信息监控

【Golang】探索进程资源监控的精妙细节&#xff1a;利用Gopsutil/Process实现高级进程性能和资源信息监控 大家好 我是寸铁&#x1f44a; 总结了一篇【Golang】探索进程资源监控的精妙细节&#xff1a;利用Gopsutil/Process实现高级进程性能和资源信息监控的文章✨ 喜欢的小伙伴…

Scrum Day盛大启幕【限时优惠】

关于 Scrum Day 智驭未来&#xff0c;敏捷先行 —— 2024中国Scrum大会启航 在全球数字化转型的浪潮中&#xff0c;敏捷已成为企业脱颖而出的关键。 Scrum中文网携手全球敏捷行业巨擘 —— Scrum.org 联袂呈现年度敏捷盛会 Scrum Day&#xff0c;将于今秋盛大启幕&#xff01…