当前位置: 首页 > news >正文

机器学习与深度学习-2-Softmax回归从零开始实现

机器学习与深度学习-2-Softmax回归从零开始实现

1 前言

内容来源于沐神的《动手学习深度学习》课程,本篇博客对于Softmax回归从零开始实现进行重述,依旧是根据Python编程的PEP8规范,将沐神的template代码进行简单的修改。近期有点懒散哈哈哈~以后争取周更,努力为大家提供一篇信息量满满、优质的博客文章。

最近重新整理了一下自己的Github仓库,博客中的代码我都会上传到:ZetingLiu/DeepLearning中,有需要的小伙伴请在这里下载。

2 问题背景–以图片分类为例

想象一下,您是一个百货公司的算法工程师。公司希望您设计一个识别货物的系统,可以自动识别货物是裤子、衣服、鞋子等等,这样也许可以节省一部分人员(拣货员)的人力资源成本。如果是您,您会怎么做?

首先,我希望这个系统能向人一样思考,那我就要提供一些学习资料,去学习这些货物大概长个什么样(特征提取),然后去广泛的学习记忆它们。等功夫到家,这个系统就可以顺利出色地完成我这个任务。而向人一样思考,就需要人工智能、深度学习的技术。让我们开始设计这个系统吧。

首先,为了多快好省的设计系统,我们导入一些现有的轮子(库):

import torch
from torchvision import transforms
from torchvision.datasets import FashionMNIST
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt

这些库经常用于数据处理与深度学习训练。

接着,让我们提供一些学习资料,给系统学习一下吧。我们使用FashionMNIST数据集,给系统提供学习。

def load_data_fashion_mnist(input_batch_size):"""加载FashionMNIST数据集并返回数据迭代器Load FashionMNIST dataset and return data iterators.Args:input_batch_size (int): 批量大小 / Batch size.Returns:Tuple[DataLoader, DataLoader]: 训练数据迭代器和测试数据迭代器 / Training and test data iterators."""transform = transforms.ToTensor()train_dataset = FashionMNIST(root='./data', train=True, transform=transform, download=True)test_dataset = FashionMNIST(root='./data', train=False, transform=transform, download=True)output_train_iter = DataLoader(train_dataset, batch_size=input_batch_size, shuffle=True)input_test_iter = DataLoader(test_dataset, batch_size=input_batch_size, shuffle=False)return output_train_iter, input_test_iter

批量大小可以由自己决定,数据也在Github仓库里提供,最好把数据与程序放在同一个文件夹下。

接着,我们定义一些用于训练的实参,并初始化一些模型参数:

# 设置全局参数 / Set global parameters
batch_size = 256
train_iter, test_iter = load_data_fashion_mnist(batch_size)# 初始化模型参数 / Initialize model parameters
num_inputs, num_outputs = 784, 10
W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)
b = torch.zeros(num_outputs, requires_grad=True)

在线性回归中,线性模型被用于进行回归任务,它是一个连续的问题,用一个连续的线性函数去预测房价的走势。在Softmax回归中,虽然它叫回归,但实际上在本问题中是一个离散的分类问题,它的输出是一个具体的类别。我希望在一个二维坐标系中,将不同的类型用一条直线分隔开,且希望数据到线性直线的距离越大越好,这样区分度更大以便用于之后的分类任务。

接下来我们正式定义Softmax函数,这个是分类任务的核心:

def softmax(x):"""计算输入x的softmax / Compute the softmax of input x.Args:x (torch.Tensor): 输入张量 / Input tensor.Returns:torch.Tensor: softmax后的张量 / Softmax tensor."""x_exp = torch.exp(x - x.max(dim=1, keepdim=True).values)partition = x_exp.sum(dim=1, keepdim=True)return x_exp / partition

它的原理是把输入的数据映射到指数空间(这样不管是什么值,都是大于0的正数)中,输出一个概率。比如说,有十个图片,哪个像鞋子的概率更大,我就输出哪个,所以概率是Softmax的输出。

我们再定义一个网络,这是一个输入-输出映射:

def net(x):"""定义网络 / Define the network.Args:x (torch.Tensor): 输入张量 / Input tensor.Returns:torch.Tensor: 网络输出 / Network output."""return softmax(torch.matmul(x.reshape((-1, W.shape[0])), W) + b)

它返回的就是图片的概率。

事实上分类任务也是一个优化问题,就像回归任务的目标函数是均方根误差一样,分类问题中,其目标函数是交叉熵函数:

def cross_entropy(y_hat, input_y):"""交叉熵损失函数 / Cross-entropy loss function.Args:y_hat (torch.Tensor): 模型预测值 / Predicted values.input_y (torch.Tensor): 实际标签 / Actual labels.Returns:torch.Tensor: 交叉熵损失值 / Cross-entropy loss."""return -torch.log(y_hat[range(len(y_hat)), input_y] + 1e-9)

加一个1e-9是防止真数为0,导致Bug。

我们总要设计一套准则,来评估我们的系统功能怎么样,不然公司为什么采取你的系统。所以我们设计一个衡量准确率的函数:

def accuracy(y_hat, input_y):"""计算准确率 / Compute accuracy.Args:y_hat (torch.Tensor): 模型预测值 / Predicted values.input_y (torch.Tensor): 实际标签 / Actual labels.Returns:float: 准确率 / Accuracy."""if y_hat.ndimension() > 1:y_hat = y_hat.argmax(dim=1)cmp = y_hat.type(input_y.dtype) == input_yreturn float(cmp.sum())

在正式进入训练、评估之前,我们需要定义一个类,用于计算数据的类,这个实际上现有的深度学习框架是有的,不过我们既然是从0开始实现,我们有必要自己去写一遍这个类:

class Accumulator:"""用于累加数据的类 / Class for accumulating data."""def __init__(self, n):self.data = [0.0] * ndef add(self, *args):"""累加多个参数的值 / Add values of multiple arguments.Args:*args: 要累加的值 / Values to accumulate."""self.data = [a + float(bia) for a, bia in zip(self.data, args)]def reset(self):"""重置累加器 / Reset the accumulator."""self.data = [0.0] * len(self.data)def __getitem__(self, idx):"""获取指定索引的值 / Get value at specified index.Args:idx (int): 索引值 / Index.Returns:float: 累加的值 / Accumulated value."""return self.data[idx]

接着我们要设计一个评估准确率的函数:

def evaluate_accuracy(input_net, data_iter):"""评估模型在数据集上的准确率 / Evaluate model accuracy on a dataset.Args:input_net (callable): 网络函数 / Network function.data_iter (DataLoader): 数据迭代器 / Data iterator.Returns:float: 模型准确率 / Model accuracy."""metric = Accumulator(2)for input_X, input_y in data_iter:metric.add(accuracy(input_net(input_X), input_y), input_y.numel())return metric[0] / metric[1] if metric[1] > 0 else 0

现在,我们正式设计训练函数,让我们的系统学习一些知识,从而让它能够思考。

def train_epoch_ch3(input_net, input_train_iter, loss, input_updater):"""训练模型一个epoch / Train the model for one epoch.Args:input_net (callable): 网络函数 / Network function.input_train_iter (DataLoader): 训练数据迭代器 / Training data iterator.loss (callable): 损失函数 / Loss function.input_updater (callable): 参数更新函数 / Parameter updater.Returns:Tuple[float, float]: 平均损失和准确率 / Average loss and accuracy."""metric = Accumulator(3)for input_X, input_y in input_train_iter:y_hat = input_net(input_X)loss_value = loss(y_hat, input_y).sum()loss_value.backward()input_updater()W.grad.zero_()b.grad.zero_()metric.add(float(loss_value), accuracy(y_hat, input_y), input_y.numel())return metric[0] / metric[2], metric[1] / metric[2]

系统学习的速度是快一点,还是慢一点,是通过学习率的设置实现的:

lr = 1e-3  # 学习率 / Learning rate

学习率过大,系统容易发散,始终完不成任务;学习率过小,虽然系统早晚收敛,但过程会缓慢。所以学习率是一个需要反复去调试的参数。而从学习率上,我们也能获得一些哲学–做事要把握度。

基于学习率,我们设计一个更新参数的函数:

def updater():"""更新模型参数 / Update model parameters."""global W, bwith torch.no_grad():W -= lr * W.gradb -= lr * b.grad

前面设计的训练函数是训练一个epoch的,接下来我们要设计一个训练整个epoch的训练函数:

def train_ch3(input_net, input_train_iter, input_test_iter, loss, input_num_epochs, input_updater):"""训练模型 / Train the model.Args:input_net (callable): 网络函数 / Network function.input_train_iter (DataLoader): 训练数据迭代器 / Training data iterator.input_test_iter (DataLoader): 测试数据迭代器 / Test data iterator.loss (callable): 损失函数 / Loss function.input_num_epochs (int): 训练轮数 / Number of training epochs.input_updater (callable): 参数更新函数 / Parameter updater."""for epoch in range(input_num_epochs):train_metrics = train_epoch_ch3(input_net, input_train_iter, loss, input_updater)test_acc = evaluate_accuracy(input_net, input_test_iter)print(f'epoch {epoch + 1}, loss {train_metrics[0]:.3f}, 'f'train acc {train_metrics[1]:.3f}, test acc {test_acc:.3f}')

接着,我们需要展示一下分类的结果,设计一个展现分类结果的函数:

def show_images(images, num_rows, num_cols, titles=None, scale=1.5):"""显示图片 / Display images.Args:images (List[torch.Tensor]): 图片列表 / List of images.num_rows (int): 行数 / Number of rows.num_cols (int): 列数 / Number of columns.titles (List[str], optional): 图片标题 / Titles of images. Defaults to None.scale (float, optional): 图片缩放比例 / Scale factor. Defaults to 1.5."""figure_size = (num_cols * scale, num_rows * scale)_, axes = plt.subplots(num_rows, num_cols, figsize=figure_size)axes = axes.flatten()for i, (img, ax) in enumerate(zip(images, axes)):if isinstance(img, torch.Tensor):img = img.numpy()ax.imshow(img, cmap='gray')ax.axis('off')if titles:ax.set_title(titles[i])plt.tight_layout()plt.show()# 全局变量初始化
X = None
y = Nonedef predict_ch3(input_net, input_test_iter, n=6):"""预测并显示结果 / Predict and display results.Args:input_net (callable): 网络函数 / Network function.input_test_iter (DataLoader): 测试数据迭代器 / Test data iterator.n (int, optional): 显示图片数量 / Number of images to display. Defaults to 6."""global X, yfor X, y in input_test_iter:breaktrues = [str(y[i].item()) for i in range(n)]predictions = [str(input_net(X).argmax(dim=1)[i].item()) for i in range(n)]titles = [true + '\n' + pred for true, pred in zip(trues, predictions)]show_images(X[0:n].reshape((n, 28, 28)), 1, n, titles=titles)

最后,我们设置训练参数:

num_epochs = 50
train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)
predict_ch3(net, test_iter)

绘制一下Loss曲线、训练准确率、测试准确率,看看我们的系统怎么样。

这个是训练日志:

epoch 1, loss 0.9313, train acc 0.7327, test acc 0.7920
epoch 2, loss 0.6130, train acc 0.8031, test acc 0.8216
epoch 3, loss 0.5490, train acc 0.8192, test acc 0.8270
epoch 4, loss 0.5478, train acc 0.8197, test acc 0.8272
epoch 5, loss 0.5111, train acc 0.8322, test acc 0.8342
epoch 6, loss 0.5039, train acc 0.8317, test acc 0.8363
epoch 7, loss 0.5025, train acc 0.8354, test acc 0.8331
epoch 8, loss 0.4808, train acc 0.8394, test acc 0.8350
epoch 9, loss 0.4834, train acc 0.8387, test acc 0.8353
epoch 10, loss 0.4827, train acc 0.8396, test acc 0.8139
epoch 11, loss 0.4742, train acc 0.8426, test acc 0.8231
epoch 12, loss 0.4672, train acc 0.8442, test acc 0.8383
epoch 13, loss 0.4695, train acc 0.8427, test acc 0.8405
epoch 14, loss 0.4808, train acc 0.8400, test acc 0.8451
epoch 15, loss 0.4707, train acc 0.8431, test acc 0.8358
epoch 16, loss 0.4502, train acc 0.8472, test acc 0.8409
epoch 17, loss 0.4768, train acc 0.8425, test acc 0.8412
epoch 18, loss 0.4563, train acc 0.8477, test acc 0.8443
epoch 19, loss 0.4609, train acc 0.8459, test acc 0.8376
epoch 20, loss 0.4637, train acc 0.8459, test acc 0.8427
epoch 21, loss 0.4531, train acc 0.8479, test acc 0.8283
epoch 22, loss 0.4575, train acc 0.8472, test acc 0.8395
epoch 23, loss 0.4539, train acc 0.8466, test acc 0.8340
epoch 24, loss 0.4527, train acc 0.8477, test acc 0.8442
epoch 25, loss 0.4463, train acc 0.8503, test acc 0.8399
epoch 26, loss 0.4394, train acc 0.8517, test acc 0.8372
epoch 27, loss 0.4524, train acc 0.8491, test acc 0.8344
epoch 28, loss 0.4317, train acc 0.8532, test acc 0.8425
epoch 29, loss 0.4610, train acc 0.8473, test acc 0.8398
epoch 30, loss 0.4411, train acc 0.8509, test acc 0.8435
epoch 31, loss 0.4308, train acc 0.8536, test acc 0.8354
epoch 32, loss 0.4416, train acc 0.8517, test acc 0.8344
epoch 33, loss 0.4391, train acc 0.8519, test acc 0.8381
epoch 34, loss 0.4342, train acc 0.8537, test acc 0.8437
epoch 35, loss 0.4317, train acc 0.8540, test acc 0.8366
epoch 36, loss 0.4319, train acc 0.8530, test acc 0.8441
epoch 37, loss 0.4373, train acc 0.8524, test acc 0.8285
epoch 38, loss 0.4438, train acc 0.8502, test acc 0.8389
epoch 39, loss 0.4339, train acc 0.8527, test acc 0.8409
epoch 40, loss 0.4311, train acc 0.8539, test acc 0.8440
epoch 41, loss 0.4358, train acc 0.8530, test acc 0.8406
epoch 42, loss 0.4334, train acc 0.8540, test acc 0.8440
epoch 43, loss 0.4374, train acc 0.8527, test acc 0.8428
epoch 44, loss 0.4329, train acc 0.8535, test acc 0.8364
epoch 45, loss 0.4348, train acc 0.8527, test acc 0.8379
epoch 46, loss 0.4293, train acc 0.8541, test acc 0.8390
epoch 47, loss 0.4265, train acc 0.8554, test acc 0.8439
epoch 48, loss 0.4253, train acc 0.8554, test acc 0.8457
epoch 49, loss 0.4276, train acc 0.8553, test acc 0.8438
epoch 50, loss 0.4301, train acc 0.8542, test acc 0.8427

损失曲线图与训练准确率、测试准确率的图如下:
在这里插入图片描述
在这里插入图片描述

由图可以看出,我们的系统能达到80%以上的准确率。打个比方,有100的图片,我们的系统可以正确识别出八十多个。这算是一个还算不错的准确率,不过在实际生活中显然不能允许这样。因此日后,我们可以一起设计一个精度更高的分类系统,那今天我们的内容就结束了。

3 结果讨论

实际上训练效果还与学习参数有关,我把学习率降低,训练日志如下:

epoch 1, loss 0.9046, train acc 0.7268, test acc 0.7712
epoch 2, loss 0.6373, train acc 0.7970, test acc 0.7953
epoch 3, loss 0.5789, train acc 0.8131, test acc 0.8047
epoch 4, loss 0.5475, train acc 0.8220, test acc 0.8140
epoch 5, loss 0.5267, train acc 0.8266, test acc 0.8170
epoch 6, loss 0.5116, train acc 0.8316, test acc 0.8211
epoch 7, loss 0.5003, train acc 0.8340, test acc 0.8164
epoch 8, loss 0.4913, train acc 0.8355, test acc 0.8250
epoch 9, loss 0.4835, train acc 0.8389, test acc 0.8218
epoch 10, loss 0.4770, train acc 0.8403, test acc 0.8262
epoch 11, loss 0.4715, train acc 0.8419, test acc 0.8280
epoch 12, loss 0.4668, train acc 0.8432, test acc 0.8302
epoch 13, loss 0.4625, train acc 0.8451, test acc 0.8315
epoch 14, loss 0.4583, train acc 0.8463, test acc 0.8321
epoch 15, loss 0.4549, train acc 0.8465, test acc 0.8333
epoch 16, loss 0.4515, train acc 0.8477, test acc 0.8338
epoch 17, loss 0.4494, train acc 0.8481, test acc 0.8312
epoch 18, loss 0.4462, train acc 0.8492, test acc 0.8342
epoch 19, loss 0.4436, train acc 0.8501, test acc 0.8352
epoch 20, loss 0.4415, train acc 0.8513, test acc 0.8346
epoch 21, loss 0.4397, train acc 0.8511, test acc 0.8349
epoch 22, loss 0.4375, train acc 0.8515, test acc 0.8355
epoch 23, loss 0.4359, train acc 0.8522, test acc 0.8374
epoch 24, loss 0.4341, train acc 0.8525, test acc 0.8351
epoch 25, loss 0.4326, train acc 0.8528, test acc 0.8369
epoch 26, loss 0.4309, train acc 0.8539, test acc 0.8367
epoch 27, loss 0.4296, train acc 0.8539, test acc 0.8376
epoch 28, loss 0.4282, train acc 0.8549, test acc 0.8339
epoch 29, loss 0.4269, train acc 0.8542, test acc 0.8389
epoch 30, loss 0.4258, train acc 0.8554, test acc 0.8384
epoch 31, loss 0.4244, train acc 0.8552, test acc 0.8401
epoch 32, loss 0.4236, train acc 0.8559, test acc 0.8401
epoch 33, loss 0.4221, train acc 0.8559, test acc 0.8393
epoch 34, loss 0.4211, train acc 0.8571, test acc 0.8400
epoch 35, loss 0.4206, train acc 0.8560, test acc 0.8395
epoch 36, loss 0.4190, train acc 0.8576, test acc 0.8410
epoch 37, loss 0.4182, train acc 0.8577, test acc 0.8405
epoch 38, loss 0.4175, train acc 0.8584, test acc 0.8397
epoch 39, loss 0.4167, train acc 0.8579, test acc 0.8401
epoch 40, loss 0.4159, train acc 0.8583, test acc 0.8407
epoch 41, loss 0.4150, train acc 0.8583, test acc 0.8384
epoch 42, loss 0.4143, train acc 0.8590, test acc 0.8415
epoch 43, loss 0.4138, train acc 0.8590, test acc 0.8416
epoch 44, loss 0.4135, train acc 0.8590, test acc 0.8410
epoch 45, loss 0.4120, train acc 0.8600, test acc 0.8410
epoch 46, loss 0.4116, train acc 0.8600, test acc 0.8412
epoch 47, loss 0.4107, train acc 0.8594, test acc 0.8430
epoch 48, loss 0.4102, train acc 0.8600, test acc 0.8412
epoch 49, loss 0.4099, train acc 0.8596, test acc 0.8421
epoch 50, loss 0.4089, train acc 0.8610, test acc 0.8398

Loss曲线与训练准确率、测试准确率图:
在这里插入图片描述
在这里插入图片描述
由Loss曲线可以看出,实际上这个曲线还可以再收敛于一个更小的Loss Value,且相比之前的更大的学习率的损失曲线,这一条更加平滑。由于只是一个示例,我的epoch只设置到了50。而训练的准确率有些略高于测试的准确率,有可能有过拟合行为,但在这个案例中我们不往这方面扩展,之后会扩展一下这个内容。分类的可视化结果:
在这里插入图片描述
上面是真实类别,下面是预测类别。我们的运气很好,这轮训练全部预测正确。后续我们将继续探讨如何正确地提高分类的准确率。

相关文章:

机器学习与深度学习-2-Softmax回归从零开始实现

机器学习与深度学习-2-Softmax回归从零开始实现 1 前言 内容来源于沐神的《动手学习深度学习》课程,本篇博客对于Softmax回归从零开始实现进行重述,依旧是根据Python编程的PEP8规范,将沐神的template代码进行简单的修改。近期有点懒散哈哈哈…...

Vue3之弹窗

文章目录 第一步、引入JS第二步、弹框 在前端开发语言Vue3&#xff0c;在管理端如何进行弹窗&#xff1f;下面根据API实现效果。 Element API文档&#xff1a; Element-plus文档 搭建环境可参考博客【 初探Vue3环境搭建与nvm使用】 第一步、引入JS <script lang"ts&…...

计算机的错误计算(一百七十一)

摘要 探讨 MATLAB 中秦九韶&#xff08;Horner&#xff09;多项式的错误计算。 例1. 用秦九韶&#xff08;Horner&#xff09;算法计算&#xff08;一百零七&#xff09;例1中多项式 直接贴图吧&#xff1a; 这样&#xff0c;MATLAB 给出的仍然是错误结果&#xff0c;因为准…...

利用Python爬虫精准获取淘宝商品详情的深度解析

在数字化时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是在电子商务领域。淘宝作为中国最大的电商平台之一&#xff0c;拥有海量的商品数据&#xff0c;对于研究市场趋势、分析消费者行为等具有重要意义。本文将详细介绍如何使用Python编写爬虫程序&#xff0c;精准获取…...

_C#_串口助手_字符串拼接缺失问题(未知原理)

最近使用WPF开发串口助手时&#xff0c;遇到一个很奇怪的问题&#xff0c;无论是主线程、异步还是多线程&#xff0c;当串口接收速度达到0.016s一次以上&#xff0c;就会发生字符串缺失问题并且很卡。而0.016s就一切如常&#xff0c;仿佛0.015s与0.016s是天堑之隔。 同一份代码…...

volcano k8s 部署

下载volcano-development文件 官网 https://volcano.sh/zh/docs/installation/volcano-development.yaml wget https://raw.githubusercontent.com/volcano-sh/volcano/master/installer/volcano-development.yaml部署volcano 查下需要下载的镜像 grep vc- volcano-develo…...

Linux---对时/定时服务

文章目录 目录 文章目录 前言 一.对时服务 服务端配置 客户端配置 二.定时服务 单次定时任务 循环定时任务 前言 在当今信息化高速发展的时代&#xff0c;时间的准确性和任务的定时执行对于各种系统和服务来说至关重要。Linux操作系统&#xff0c;凭借其强大的功能和灵活的…...

13 设计模式之外观模式(家庭影院案例)

一、什么是外观模式&#xff1f; 1.定义 在日常生活中&#xff0c;许多人喜欢通过遥控器来控制家中的电视、音响、DVD 播放器等设备。虽然这些设备各自独立工作&#xff0c;但遥控器提供了一个简洁的界面&#xff0c;让用户可以轻松地操作多个设备。而这一设计理念正是 外观模…...

spring boot整合ArtemisMQ进行手动消息确认

1、SpringBoot整合ArtemisMQ进行手动消息确认使用的是&#xff1a; factory.setSessionTransacted(false); factory.setSessionAcknowledgeMode(ActiveMQJMSConstants.INDIVIDUAL_ACKNOWLEDGE); 2、SpringBoot整合ActiveMQ进行手动消息确认使用的是&#xff1a; factory.setSe…...

dpwwn02靶场

靶机下载地址&#xff1a;https://download.vulnhub.com/dpwwn/dpwwn-02.zip 信息收集 ip add 查看kali Linux虚拟机的IP为&#xff1a;10.10.10.128 https://vulnhub.com/entry/dpwwn-2,343/中查看靶机的信息&#xff0c;IP固定为10.10.10.10 所以kali Linux添加仅主机网卡…...

展示和添加篮球队信息--laravel与elementplus

之前使用laravel与inertia来做过一样的功能,感觉不满意,因此再结合elementplus重做一遍,先展示下重做后的效果。重写后的代码相比之下比较优雅。 球队首页 球队添加页 球员首页 很明显的改变,我新增了侧栏菜单来控制局部模块(这里是指NBABasketba…...

K8S疑难概念理解——Pod,应该以哪种Kind来部署应用,为什么不直接Pod这种kind?

文章目录 一、Pod概念深度理解&#xff0c;为什么一般不直接以kindPod资源类型来部署应用?二、究竟应该以哪种资源类型来部署应用 一、Pod概念深度理解&#xff0c;为什么一般不直接以kindPod资源类型来部署应用? Pod是Kubernetes中的最小部署单元&#xff0c;可以包含一个或…...

centos7怎么安装keepalive+nginx

在CentOS 7上安装Keepalived和Nginx&#xff0c;可以按照以下步骤进行&#xff1a; 安装Nginx 添加Nginx到Yum源&#xff1a; rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm安装Nginx&#xff1a; yum install -y ng…...

DevOps工程技术价值流:Jenkins驱动的持续集成与交付实践

一、Jenkins系统概述 Jenkins&#xff1a;开源CI/CD引擎的佼佼者 Jenkins&#xff0c;作为一款基于Java的开源持续集成&#xff08;CI&#xff09;与持续交付&#xff08;CD&#xff09;系统&#xff0c;凭借其强大的插件生态系统&#xff0c;成为DevOps实践中不可或缺的核心…...

el-select 修改样式

这样漂亮的页面&#xff0c;搭配的却是一个白色风格的下拉框 &#xff0c;这也过于刺眼。。。 调整后样式为&#xff1a; 灯红酒绿总有人看着眼杂&#xff0c;但将风格统一终究是上上选择。下面来处理这个问题。 分为两部分。 第一部分&#xff1a;是修改触发框的样式 第二部…...

文本内容处理命令和正则表达式

文本内容处理命令 grep 用来过滤文本内容&#xff0c;以匹配要查询的结果。 -m 数字 匹配几次后停止&#xff1a; grep -m 1 /root/etc/passwd #查找包含root的行 -v 取反 -i 忽略字符的大小写&#xff0c;默认的&#xff0c;可以不加 -n 显示匹配的行号 -c 统计匹配的…...

【PlantUML系列】类图(一)

目录 一、类 二、接口 三、抽象类 四、泛型类 五、类之间的关系 六、添加注释 七、包图 八、皮肤参数 一、类 使用class关键字定义类&#xff0c;类名后跟大括号&#xff0c;声明类的属性和方法。 属性&#xff1a;格式为{visibility} attributeName : AttributeType…...

【Leetcode Top 100】21. 合并两个有序链表

问题背景 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 数据约束 两个链表的节点数目范围是 [ 0 , 50 ] [0, 50] [0,50] − 100 ≤ N o d e . v a l ≤ 100 -100 \le Node.val \le 100 −100≤Node.val≤100 l 1 l_1 …...

【真正离线安装】Adobe Flash Player 32.0.0.156 插件离线安装包下载(无需联网安装)

网上很多人声称并提供的flash离线安装包是需要联网才能安装成功的&#xff0c;其实就是在线安装包&#xff0c;而这里提供的是真正的离线安装包&#xff0c;无需联网即可安装成功。 点击下面地址下载离线安装包&#xff1a; Adobe Flash Player 32.0.0.156 for IE Adobe Fla…...

UG NX二次开发(C#)-如何进行NX多版本的编译

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、以删除对象为例3、解决方案1、前言 由于UG NX的版本不同,新版本与旧版本开发过程中,如果是在一个工程中,其会出现低版本不能编译高版本NX的问题,这是因为高版本会引入新的函数,或者…...

Spark优化--开发调优、资源调优、数据倾斜调优和shuffle调优等

针对Spark优化&#xff0c;我们可以从多个角度进行&#xff0c;包括开发调优、资源调优、数据倾斜调优和shuffle调优等。以下是一些具体的优化方法&#xff1a; 1. 开发调优 避免创建重复的RDD&#xff1a;对于同一份数据&#xff0c;只应该创建一个RDD&#xff0c;避免创建多…...

911事件反思:灾难通信和ddos之间的取舍

流量分析与监控 建立基线流量模型&#xff1a;在正常情况下监控和记录网络流量&#xff0c;建立正常流量的基线。这样&#xff0c;当突发请求发生时&#xff0c;可以更容易地识别出流量的异常变化。 实时流量监控&#xff1a;使用流量分析工具实时监控网络流量&#xff0c;快速…...

网络安全之IP伪造

眼下非常多站点的涉及存在一些安全漏洞&#xff0c;黑客easy使用ip伪造、session劫持、xss攻击、session注入等手段危害站点安全。在纪录片《互联网之子》&#xff08;建议搞IT的都要看下&#xff09;中。亚伦斯沃茨&#xff08;真实人物&#xff0c;神一般的存在&#xff09;涉…...

算法笔记:力扣24. 两两交换链表中的节点

思路&#xff1a; 本题最简单的就是通过递归的形式去实现 class Solution {public ListNode swapPairs(ListNode head) {if(head null || head.next null){return head;}ListNode next head.next;head.next swapPairs(next.next);next.next head;return next;} } 对于链…...

Shell脚本小练习

学习了这么长时间Shell脚本&#xff0c;总得来一次小小的练习吧&#xff0c;那么请看下文&#xff01; 1.用Shell写一个小计算器。 通过read命令获取用户输入的表达式&#xff0c;表达式的格式设定为操作数1 运算符 操作数2&#xff0c;例如53&#xff0c;然后利用设计的脚本…...

Fastify装饰器:增强你的路由处理功能加入日志

Fastify以其出色的性能和扩展性脱颖而出。装饰器是Fastify提供的一个强大功能&#xff0c;它允许开发者在不修改核心代码的情况下&#xff0c;向请求&#xff08;Request&#xff09;和响应&#xff08;Response&#xff09;对象添加自定义属性和方法。本文将通过一个简单的示例…...

node.js基础学习-url模块-url地址处理(二)

前言 前面我们创建了一个HTTP服务器&#xff0c;如果只是简单的http://localhost:3000/about这种链接我们是可以处理的&#xff0c;但是实际运用中一般链接都会带参数&#xff0c;这样的话如果我们只是简单的判断链接来分配数据&#xff0c;就会报404找不到链接。为了解决这个问…...

Vue如何加载十万条数据

加载十万条数据到 Vue 应用中是一个相对复杂的问题&#xff0c;主要因为渲染大量数据可能会导致性能瓶颈&#xff0c;尤其是在前端性能较低的设备上。为了确保加载大量数据时&#xff0c;页面不会卡顿或崩溃&#xff0c;我们通常采取一些优化手段&#xff0c;以下是几种常用的方…...

重生之我在异世界学编程之C语言:二维数组篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一 二维数组的创建1. 二维数组的…...

linux——进程间通信及管道的应用场景

linux进程的控制-CSDN博客 liunx——进程间通信&#xff08;管道通信&#xff09;-CSDN博客 文章目录 文章目录 前言 二、管道的应用 1.创建子进程 1、描述&#xff1a; 2.创建进程及管理 3、子进程接受任务 4、控制子进程 总结 前言 上篇博客我们学习了进程间通信&…...

深度学习基础3

目录 1.过拟合与欠拟合 1.1 过拟合 1.2 欠拟合 1.2 解决欠拟合 1.2.1 L2正则化 1.2.2 L1正则化 1.2.3 Dropout 1.2.4 简化模型 1.2.5 数据增强 1.2.6 早停 1.2.7 模型集成 1.2.8 交叉验证 2.批量标准化 2.1 实现过程 2.1.1 计算均值和方差 2.1.2 标准化 2.1.3…...

靶机dpwwn-01

靶机下载地址&#xff1a;https://download.vulnhub.com/dpwwn/dpwwn-01.zip 信息收集 扫描靶机的IP地址 arp-scan -l 获得靶机的IP地址&#xff1a;192.168.200.130 查看靶机的服务类型&#xff0c;端口信息 nmap -sS -sV -T4 -A -p- 192.168.200.130 开启了22&#xf…...

Python毕业设计选题:基于django+vue的智慧社区可视化平台的设计与实现+spider

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 养老机构管理 业主管理 社区安防管理 社区设施管理 车位…...

大语言模型微调与 XTuner 微调实战

1 大语言模型微调 1.1 什么是微调 大语言模型微调&#xff08;Fine-tuning of Large Language Models&#xff09;是指在预训练的大型语言模型基础上&#xff0c;使用特定任务的数据进一步训练模型&#xff0c;以使其更好地适应和执行特定任务的过程&#xff0c;用于使LLM&am…...

数据结构-查找(四)总结与对比

查找算法总结 文章目录 查找算法总结一、查找的基本概念二、顺序查找法适用场景 三、分块查找法适用场景 四、折半查找法&#xff08;Binary Search&#xff09;适用场景 五、树型查找1. 二叉搜索树&#xff08;BST&#xff09;2. 平衡二叉树&#xff08;AVL&#xff09;3. 红黑…...

c++总复习

一、什么是 C 中的函数对象&#xff1f;它有什么特点&#xff1f; 在 C 中&#xff0c;函数对象&#xff08;Function Object&#xff09;也称为仿函数&#xff08;Functor&#xff09;&#xff0c;它是一个类的实例&#xff0c;该类重载了函数调用运算符()&#xff0c;使得这个…...

AJAX一、axios使用,url组成(协议,域名,资源路径)查询参数和化简,错误处理,请求/响应报文,状态码,接口文档,

一、AJAX是什么 概念 &#xff1a; AJAX是一种与服务器&#xff08;后端&#xff09;通信的技术 二、请求库axios的基本用法 1导包 2使用 // 1. 发请求 axios({ url: 请求地址 }).then(res > { // 2.接收并使用数据 }) <body><p class"province"…...

Python学习笔记

MJ大神的Python课&#xff0c;课堂笔记 int 和float运算结果是 float除法&#xff08;/&#xff09;的结果是float整除&#xff08;//&#xff09;&#xff0c;向下取整(floor)int 和 int 进行整除&#xff08;//&#xff09;,得到的结果是int 绘制一个填充色边框色 import …...

开源 - Ideal库 - Excel帮助类,TableHelper实现(三)

书接上回&#xff0c;我们今天继续讲解实现对象集合与DataTable的相互转换。 01、把表格转换为对象集合 该方法是将表格的列名称作为类的属性名&#xff0c;将表格的行数据转为类的对象。从而实现表格转换为对象集合。同时我们约定如果类的属性设置了DescriptionAttribute特性…...

ceph手动部署

ceph手动部署 一、 节点规划 主机名IP地址角色ceph01.example.com172.18.0.10/24mon、mgr、osd、mds、rgwceph02.example.com172.18.0.20/24mon、mgr、osd、mds、rgwceph03.example.com172.18.0.30/24mon、mgr、osd、mds、rgw 操作系统版本&#xff1a; Rocky Linux release …...

macOS 开发环境配置与应用开发指南

macOS 开发环境配置与应用开发指南 macOS作为苹果公司推出的操作系统&#xff0c;因其稳定性、优雅的用户界面和强大的开发支持&#xff0c;已成为开发者和创意专业人士的首选平台之一。无论是开发iOS、macOS桌面应用&#xff0c;还是Web应用、跨平台程序&#xff0c;macOS都提…...

自动化是语法,智能化是语义与语用

自动化与智能化可以从语言学的角度来进行类比和探讨。 1. 自动化是语法 自动化可以类比为“语法”的部分&#xff0c;因为它关注的是操作过程的规则、结构和执行方式。语法是语言中关于词汇、句子结构和规则的系统&#xff0c;它提供了语言运作的框架和规范。类似地&#xff0c…...

基于DHCP,ACL的通信

该问题为华为的学习资料 1.首先把所有的PC机全部设置为DHCP 2.配置地址 3.ospf 4.dhcp 5.acl AR1 dhcp en interface GigabitEthernet0/0/0ip address 192.168.1.254 255.255.255.0 dhcp select global interface GigabitEthernet0/0/1ip address 10.1.12.1 255.255.255.…...

Unity跨平台基本原理

Unity跨平台基本原理 Unity跨平台基本原理微软的.Net是什么微软做 .Net平台的目的如何实现的.Net跨语言&#xff1f;总结 .Net Framework.Net Framework的体系结构CLR总结 如何实现的跨平台&#xff1f;.Net Core.Net FrameWork 到 .Net CoreMonoMono如何实现跨平台总结如何实现…...

基于 Python、OpenCV 和 PyQt5 的人脸识别上课打卡系统

大家好&#xff0c;我是Java徐师兄&#xff0c;今天为大家带来的是基于 Python、OpenCV 和 PyQt5 的人脸识别上课签到系统。该系统采用 Python 语言开发&#xff0c;开发过程中采用了OpenCV框架&#xff0c;Sqlite db 作为数据库&#xff0c;系统功能完善 &#xff0c;实用性强…...

IDEA的简易安装思路

IDEA(本身就是Java开发的)&#xff1a;是目前为止开发Java效率最高的工具&#xff0c;但正版收费……&#xff08;eclipse的话不好说&#xff0c;反正还是随主流吧&#xff09; 使用IDEA的前提&#xff1a;必须先安装JDK【否则直接使用IDEA工具来运行程序是无效的&#xff0c;它…...

【实战】在Koa.js中实现文件上传的接口 (本地存储)

目录 环境准备 使用 koa-body 中间件获取上传的文件 使用 Postman 测试 使用 koa-static 中间件生成图片链接 编写前端页面上传文件 文件上传是一个基本的功能&#xff0c;每个系统几乎都会有&#xff0c;比如上传图片、上传Excel等。那么在Node Koa应用中如何实现一个支持…...

flink学习(10)——allowedLateness/测道输出

allowedLateness(lateness: Time) 水印&#xff1a;短期延迟&#xff0c;达到条件后触发计算并且关闭窗口&#xff08;触发关闭同时进行&#xff09; 水印allowedLateness : 短期延迟 等待长期延迟效果 1、达到水印条件后&#xff0c;会触发窗口计算&#xff0c;但是不关闭窗口…...

微信小程序按字母顺序渲染城市 功能实现详细讲解

在微信小程序功能搭建中&#xff0c;按字母渲染城市会用到多个ES6的方法&#xff0c;如reduce&#xff0c;map&#xff0c;Object.entries()&#xff0c;Object.keys() &#xff0c;需要组合熟练掌握&#xff0c;才能优雅的处理数据完成渲染。 目录 一、数据分析 二、数据处理 …...

openjdk17 jvm 对象 内存溢出 在C++源码体现

##java大对象类 public class MiBigObject {private String f1;private String f2;private String f3;private String f4;private String f5;private String f6;private String f7;private String f8;private String f9;private String f10;private String f11;private String…...