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

【深度学习】手写数字识别任务

数字识别是计算机从纸质文档、照片或其他来源接收、理解并识别可读的数字的能力,目前比较受关注的是手写数字识别。手写数字识别是一个典型的图像分类问题,已经被广泛应用于汇款单号识别、手写邮政编码识别等领域,大大缩短了业务处理时间,提升了工作效率和质量。

学习总结

本次学习先写总结,因为paddle教程和网络上的同学们都得到了不错的效果,而我按照paddle或者网上的步骤得不到预期的结果。希望有大神可以指教一下,问题到底出在哪里。
运行环境:
在这里插入图片描述

1、paddle的代码运行不过

paddle的代码:
在这里插入图片描述
我的代码:
在这里插入图片描述

2.运行效果不一致

数据处理用的是这种方式

from data_process import get_MNIST_dataloadertrain_loader, test_loader = get_MNIST_dataloader()

paddle的效果:
1、paddle一共有800批次,所以不知道paddle用的batch_size是不是和代码保持了一致。
2、paddle的损失差不多是0.1,而我的损失是2.
在这里插入图片描述
在这里插入图片描述

3.预测效果不一致

从paddle的最终结果看,是预测正确了的。我自己训练的结果没有一个是正确的。
在这里插入图片描述
在这里插入图片描述

深度学习步骤

再次回顾深度学习的步骤
1、数据处理
2、模型设计
3、训练配置
4、训练过程
5、模型保存
6、模型推理

代码目录结构,经过前面的学习,目录也进行了调整
image:准备用实际的jpg图片来预测
work: 保存了训练数据集和训练后的模型
在这里插入图片描述

1.数据处理

数据处理用两种形式,因为两种形式带来的效果差别有些大。
方式一:

# 数据处理部分之前的代码,加入部分数据处理的库
import gzip
import jsonclass MNISTDataset(Dataset):"""步骤一:继承paddle.io.Dataset类"""def __init__(self, datafile, mode='train', transform=None):"""步骤二:实现构造函数"""super().__init__()self.mode = modeself.transform = transformprint('loading mnist dataset from {} ......'.format(datafile))# 加载json数据文件data = json.load(gzip.open(datafile))print('mnist dataset load done')# 读取到的数据区分训练集,验证集,测试集train_set, val_set, eval_set = dataif mode == 'train':# 获得训练数据集self.imgs, self.labels = train_set[0], train_set[1]elif mode == 'valid':# 获得验证数据集self.imgs, self.labels = val_set[0], val_set[1]elif mode == 'test':# 获得测试数据集self.imgs, self.labels = eval_set[0], eval_set[1]else:raise Exception("mode can only be one of ['train', 'valid', 'test']")def __getitem__(self, index):"""步骤三:实现__getitem__方法,定义指定index时如何获取数据"""data = self.imgs[index]label = self.labels[index]return self.transform(data), labeldef __len__(self):"""步骤四:实现__len__方法,返回数据集总数目"""return len(self.imgs)def get_MNIST_dataloader():datafile = './work/mnist.json.gz'# 下载数据集并初始化 DataSettrain_dataset = MNISTDataset(datafile, mode='train', transform=transform)test_dataset = MNISTDataset(datafile, mode='test', transform=transform)print('train images: ', train_dataset.__len__(), ', test images: ', test_dataset.__len__())# 定义并初始化数据读取器train_loader = paddle.io.DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=1, drop_last=True)test_loader = paddle.io.DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers=1, drop_last=True)print('step num:',len(train_loader))return train_loader, test_loader

这种方式paddle官方说用transform进行归一化处理,但是通过查看mnist.json.gz里面的数据可以看出,数据集已经是[-1,1]之间的数据了。
方式二:

def load_data(mode='train'):datafile = './work/mnist.json.gz'print('loading mnist dataset from {} ......'.format(datafile))# 加载json数据文件data = json.load(gzip.open(datafile))print('mnist dataset load done')# 读取到的数据区分训练集,验证集,测试集train_set, val_set, eval_set = dataif mode == 'train':# 获得训练数据集imgs, labels = train_set[0], train_set[1]elif mode == 'valid':# 获得验证数据集imgs, labels = val_set[0], val_set[1]elif mode == 'eval':# 获得测试数据集imgs, labels = eval_set[0], eval_set[1]else:raise Exception("mode can only be one of ['train', 'valid', 'eval']")print("训练数据集数量: ", len(imgs))assert len(imgs) == len(labels), \"length of train_imgs({}) should be the same as train_labels({})".format(len(imgs), len(labels))# 获得数据集长度imgs_length = len(imgs)# 定义数据集每个数据的序号,根据序号读取数据index_list = list(range(imgs_length))# 读入数据时用到的批次大小BATCHSIZE = 100# 定义数据生成器def data_generator():if mode == 'train':# 训练模式下打乱数据random.shuffle(index_list)imgs_list = []labels_list = []print_0 = Truefor i in index_list:# 将数据处理成希望的类型img = np.array(imgs[i]).astype('float32')label = np.array(labels[i]).astype('float32')if print_0:print("图像数据形状和对应数据为:", img)print("图像标签形状和对应数据为:", label.shape, label)print_0 = Falseimgs_list.append(img)labels_list.append(label)if len(imgs_list) == BATCHSIZE:# 获得一个batchsize的数据,并返回yield np.array(imgs_list), np.array(labels_list)# 清空数据读取列表imgs_list = []labels_list = []# 如果剩余数据的数目小于BATCHSIZE,# 则剩余数据一起构成一个大小为len(imgs_list)的mini-batchif len(imgs_list) > 0:yield np.array(imgs_list), np.array(labels_list)return data_generator

2.模型设计

使用与房价预测相同的简单神经网络解决手写数字识别问题,但是效果并不理想。原因是手写数字识别的输入是28×28的像素值,输出是0~9的数字标签,而线性回归模型无法捕捉二维图像数据中蕴含的复杂信息。

2.1.经典的全连接神经网络(MLP)

在这里插入图片描述
在这里插入图片描述
这里的代码是paddle官方的最终的代码
在paddle_model.py中实现模型设计

# 数据处理部分之后的代码,数据读取的部分调用Load_data函数# 加载飞桨、NumPy和相关类库
import paddle
import paddle.nn.functional as F
from paddle.nn import Linear
from tools import plot# from data_process import get_MNIST_dataloader
# train_loader,_ = get_MNIST_dataloader()# 数据处理部分之后的代码,数据读取的部分调用Load_data函数
# 定义网络结构,同上一节所使用的网络结构
class MNIST(paddle.nn.Layer):def __init__(self):super(MNIST, self).__init__()# 定义两层全连接隐含层,输出维度是10,当前设定隐含节点数为10,可根据任务调整self.fc1 = Linear(in_features=784, out_features=10)self.fc2 = Linear(in_features=10, out_features=10)# 定义一层全连接输出层,输出维度是1self.fc3 = Linear(in_features=10, out_features=1)# 定义网络的前向计算,隐含层激活函数为sigmoid,输出层不使用激活函数def forward(self, inputs):inputs = paddle.reshape(inputs, [inputs.shape[0], 784])outputs1 = self.fc1(inputs)outputs1 = F.sigmoid(outputs1)outputs2 = self.fc2(outputs1)outputs2 = F.sigmoid(outputs2)outputs_final = self.fc3(outputs2)return outputs_final# 网络结构部分之后的代码,保持不变
def train(model):model.train()from data_process import load_datatrain_loader = load_data(mode='train')# 使用SGD优化器,learning_rate设置为0.01opt = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())# 训练5轮EPOCH_NUM = 10loss_list = []for epoch_id in range(EPOCH_NUM):for batch_id, data in enumerate(train_loader()):# 准备数据images, labels = dataimages = paddle.to_tensor(images, dtype="float32")labels = paddle.to_tensor(labels, dtype="float32")# 前向计算的过程predicts = model(images)# 计算损失,取一个批次样本损失的平均值loss = F.square_error_cost(predicts, labels)avg_loss = paddle.mean(loss)# 每训练200批次的数据,打印下当前Loss的情况if batch_id % 200 == 0:loss_list.append(avg_loss.numpy())print("epoch: {}, batch: {}, loss is: {}".format(epoch_id, batch_id, avg_loss.numpy()))# 后向传播,更新参数的过程avg_loss.backward()# 最小化loss,更新参数opt.step()# 清除梯度opt.clear_grad()# 保存模型参数paddle.save(model.state_dict(), './work/mnist_mlp.pdparams')return loss_listmodel = MNIST()
params_info = paddle.summary(model, (1, 1, 28, 28))
loss_list = train(model)
plot(loss_list)

2.2.卷积神经网络(CNN)

虽然使用经典的全连接神经网络可以提升一定的准确率,但其输入数据的形式导致丢失了图像像素间的空间信息,这影响了网络对图像内容的理解。对于计算机视觉问题,效果最好的模型仍然是卷积神经网络。卷积神经网络针对视觉问题的特点进行了网络结构优化,可以直接处理原始形式的图像数据,保留像素间的空间信息,因此更适合处理视觉问题。
卷积神经网络由多个卷积层和池化层组成,如图所示。卷积层负责对输入进行扫描以生成更抽象的特征表示,池化层对这些特征表示进行过滤,保留最关键的特征信息。
在这里插入图片描述

# 定义 SimpleNet 网络结构
import paddle
from paddle.nn import Conv2D, MaxPool2D, Linear
import paddle.nn.functional as F
from data_process import get_MNIST_dataloader
from tools import plot# 多层卷积神经网络实现
class MNIST(paddle.nn.Layer):def __init__(self):super(MNIST, self).__init__()# 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2self.conv1 = Conv2D(in_channels=1, out_channels=20, kernel_size=5, stride=1, padding=2)# 定义池化层,池化核的大小kernel_size为2,池化步长为2self.max_pool1 = MaxPool2D(kernel_size=2, stride=2)# 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2self.conv2 = Conv2D(in_channels=20, out_channels=20, kernel_size=5, stride=1, padding=2)# 定义池化层,池化核的大小kernel_size为2,池化步长为2self.max_pool2 = MaxPool2D(kernel_size=2, stride=2)# 定义一层全连接层,输出维度是1self.fc = Linear(in_features=980, out_features=10)# 定义网络前向计算过程,卷积后紧接着使用池化层,最后使用全连接层计算最终输出# 卷积层激活函数使用Relu,全连接层不使用激活函数def forward(self, inputs):x = self.conv1(inputs)x = F.relu(x)x = self.max_pool1(x)x = self.conv2(x)x = F.relu(x)x = self.max_pool2(x)x = paddle.reshape(x, [x.shape[0], -1])x = self.fc(x)return x# 网络结构部分之后的代码,保持不变
def train(model):# 在使用GPU机器时,可以将use_gpu变量设置成Trueuse_gpu = Truefrom data_process import load_datatrain_loader = load_data(mode='train')# train_loader, test_loader = get_MNIST_dataloader()paddle.set_device('gpu:0') if use_gpu else paddle.set_device('cpu')model.train()learning_rate = 0.001# 四种优化算法的设置方案,可以逐一尝试效果opt = paddle.optimizer.SGD(learning_rate=learning_rate, parameters=model.parameters())# opt = paddle.optimizer.Momentum(learning_rate=learning_rate, momentum=0.9, parameters=model.parameters())# opt = paddle.optimizer.Adagrad(learning_rate=learning_rate, parameters=model.parameters())# opt = paddle.optimizer.Adam(learning_rate=learning_rate, parameters=model.parameters())# 训练5轮EPOCH_NUM = 10# MNIST图像高和宽IMG_ROWS, IMG_COLS = 28, 28loss_list = []for epoch_id in range(EPOCH_NUM):for batch_id, data in enumerate(train_loader()):# 准备数据images, labels = dataimages = paddle.to_tensor(images, dtype="float32")images = paddle.reshape(images, [images.shape[0], 1, IMG_ROWS, IMG_COLS])labels = paddle.to_tensor(labels, dtype="int64")# 前向计算的过程predicts = model(images)  # [batch_size, 1]# 计算损失,取一个批次样本损失的平均值loss = F.cross_entropy(predicts, labels)avg_loss = paddle.mean(loss)# 每训练200批次的数据,打印下当前Loss的情况if batch_id % 200 == 0:loss_list.append(avg_loss.numpy())print("epoch: {}, batch: {}, loss is: {}".format(epoch_id, batch_id, avg_loss.numpy()))# 后向传播,更新参数的过程avg_loss.backward()# 最小化loss,更新参数opt.step()# 清除梯度opt.clear_grad()# 保存模型参数paddle.save(model.state_dict(), './work/mnist_cnn.pdparams')return loss_listif __name__ == '__main__':model = MNIST()params_info = paddle.summary(model, (1, 1, 28, 28))print(params_info)loss_list_conv = train(model)plot(loss_list_conv)

3.训练配置

4.训练过程

训练配置和训练过程的代码都在模型设计中一并给出了,这里只给出最终的训练效果。

4.1经典的全连接神经网络

在这里插入图片描述
在这里插入图片描述

4.2.卷积神经网络

在这里插入图片描述
在这里插入图片描述

5.保存模型

6.模型推理

经典的全连接神经网络与卷积神经网络除了模型地址不一样,其他都是一样的代码。

#加载飞桨、NumPy和相关类库
import paddle
from paddle_model_cnn import MNIST
import numpy as np
from PIL import Image
import matplotlibmatplotlib.use('TkAgg')
import matplotlib.pyplot as plt# 读取一张本地的样例图片,转变成模型输入的格式
def load_image(img_path):# 从img_path中读取图像,并转为灰度图im = Image.open(img_path).convert('L')print(np.array(im))im = im.resize((28, 28), Image.LANCZOS)im = np.array(im).reshape(1, 1, 28, 28).astype(np.float32)# 图像归一化,保持和数据集的数据范围一致im = 1 - im / 255return imdef predict():# 将模型参数保存到指定路径中# 定义预测过程model = MNIST()params_file_path = './work/mnist_cnn.pdparams'# 加载模型参数param_dict = paddle.load(params_file_path)model.load_dict(param_dict)# 灌入数据model.eval()for index in range(0, 10):img_path = 'image/{}.jpg'.format(index)tensor_img = load_image(img_path)# 模型反馈10个分类标签的对应概率results = model(paddle.to_tensor(tensor_img))# 取概率最大的标签作为预测输出lab = np.argsort(results.numpy())print("本次预测的数字是: ", lab[0][-1])if __name__ == '__main__':predict()

6.1.全连接神经网络

在这里插入图片描述

6.2.卷积神经网络

在这里插入图片描述

相关文章:

【深度学习】手写数字识别任务

数字识别是计算机从纸质文档、照片或其他来源接收、理解并识别可读的数字的能力,目前比较受关注的是手写数字识别。手写数字识别是一个典型的图像分类问题,已经被广泛应用于汇款单号识别、手写邮政编码识别等领域,大大缩短了业务处理时间&…...

go语言 创建kratos框架工程

go语言 创建kratos框架工程 1、准备 1.1、系统 只支持macos和linux系统, 这里主要是macos(linux类似) 1.2、需要的环境 1.2.1、go语言环境 $ brew install go # 会安装最新的go版本 $ go env -w GO111MODULEon # 设置go的环境1.2.2、 …...

Linux-GlusterFS操作子卷

文章目录 分布式卷添加卷分布式卷删除子卷删除总卷 🏡作者主页:点击! 🤖Linux专栏:点击! ⏰️创作时间:2025年02月20日19点30分 分布式卷添加卷 Node1上进行操作 扩容 #服务器端 gluster volu…...

修改阿里云服务器内网ip

运维同事问能不能改我自己的服务内网ip, 买了一台服99元服务器,以为不能结果,结果还真改成功了, 分享一下经验。 首先最后关闭服务器-关机,必须要关闭服务 访问vpc控制台,就是要新建立一个网络 https://…...

鸿蒙与跨端迁移的重要性

鸿蒙操作系统(HarmonyOS)是由华为公司开发的一款面向未来的全场景分布式操作系统。它旨在提供一个统一的平台,支持各种设备之间的无缝协作和数据共享,从而为用户提供更加连贯和高效的体验。在鸿蒙的生态系统中,跨端迁移…...

XML XML约束 二、DTD

1 什么是DTD DTD&#xff08;Document Type Definition&#xff09;&#xff0c;文档类型定义&#xff0c;用来约束XML文档。例如要求xml文档的根元素必须是<students>&#xff0c;在<students>元素下可以包含0~n个<student>元素&#xff0c;每个<studen…...

用DeepSeek零基础预测《哪吒之魔童闹海》票房——从数据爬取到模型实战

系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 **一、为什么要预测票房&#xff1f;****二、准备工作****三、实战步骤详解****Step 1&#xff1a;数据爬取与清洗&am…...

医院管理系统方案-基于蓝牙室内定位技术的院内智能导航系统:技术详解、功能设计及核心优势

文面向IT技术员、医院信息化负责人及物联网应用开发者&#xff0c;本文介绍了一款基于蓝牙室内定位技术的智能导航系统。该系统通过高精度定位与智能路径规划&#xff0c;极大提升了患者就医体验与医院运营效率。 如需获取院内智能导航系统技术文档可前往文章最下方获取&#x…...

ref() 和 reactive()响应性 浅解

文章目录 1. ref() 和 reactive() 的区别2. 解构 详解2.1. 什么是解构2.2. 解构避免丢失响应性的办法2.2.1. 解决方案&#xff1a;toRefs() 保持响应性2.2.2. 解决方案&#xff1a; toRef()保持响应性 3. 最佳实践 在 Vue 3 中&#xff0c;ref() 和 reactive() 都是用于响应式数…...

聊一聊vue如何实现角色权限的控制的

大家好&#xff0c;我是G探险者。 关于角色与权限控制&#xff0c;通常是分为两大类&#xff1a;一种是菜单权限&#xff1b;一种是操作权限。 菜单权限是指&#xff0c;每个角色对应着可以看到哪些菜单&#xff0c;至于每个菜单里面的每个按钮&#xff0c;比如增删改查等等这类…...

TensorFlow深度学习实战——构建卷积神经网络实现CIFAR-10图像分类

TensorFlow深度学习实战——构建卷积神经网络实现CIFAR-10图像分类 0. 前言1. CIFAR-10 数据集介绍2. CIFAR-10 图像分类3. 提升模型性能3.1 增加网络深度3.2 数据增强 4. 模型测试相关链接 0. 前言 我们已经学习了卷积神经网络 (Convolutional Neural Network, CNN) 的基本概…...

服务器创建conda环境并安装使用jupyter

1.创建conda环境 conda create --name myenv python3.8 conda activate myenv其中 myenv 是您想要创建的环境名称&#xff0c;可以根据需要替换为其他名称。2.安装juypter conda install jupyter3.启动juypter jupyter notebook复制链接到浏览器打开 4.设置jupyter使用的 …...

形参和实参

形参&#xff08;形式参数&#xff09; 函数定义时指定的参数&#xff0c;形参是用来接收数据的&#xff0c;函数定义时&#xff0c;系统不会为形参申请内存&#xff0c;只有当 函数调用时&#xff0c;系统才会为形参申请内存。主要用于存储实际参数&#xff0c;并且当函数返…...

【HarmonyOS Next】鸿蒙监听手机按键

【HarmonyOS Next】鸿蒙监听手机按键 一、前言 应用开发中我们会遇到监听用户实体按键&#xff0c;或者扩展按键的需求。亦或者是在某些场景下&#xff0c;禁止用户按下某些按键的业务需求。 这两种需求&#xff0c;鸿蒙都提供了对应的监听事件进行处理。 onKeyEvent 默认的…...

【Spring详解五】bean的加载

五、bean的加载 当我们显示或者隐式地调用 getBean() 时&#xff0c;则会触发加载 bean 阶段。示例代码如下&#xff1a; public class AppTest {Testpublic void MyTestBeanTest() {BeanFactory bf new XmlBeanFactory( new ClassPathResource("spring-config.xml"…...

5.8 Soft Prompt技术:提示编码器的微调革命

Soft Prompt技术:提示编码器的微调革命 一、Prompt Encoder技术全景图 mindmap root((Prompt Encoder)) P-Tuning v1 双向LSTM编码 可微提示优化 P-Tuning v2 多层感知机编码 任务特定初始化 Prompt Encoder 可学习提示向量 层级提示插入 Prompt Encoder的核心优…...

Qt之多线程处理

在现代应用程序开发中,多线程处理是提高程序性能和响应速度的重要手段。Qt作为一个功能强大的跨平台C++框架,提供了丰富的多线程支持。 Qt多线程基础 Qt中的多线程处理主要依赖于QThread类。QThread类封装了底层的线程启动、运行和终止等细节,每个QThread对象代表一个独立…...

ThinkPHP(TP)如何做安全加固,防webshell、防篡改、防劫持、TP漏洞防护

ThinkPHP是一款非常知名的PHP框架&#xff0c;很多知名CMS系统都是采用TP框架进行二次开发而来&#xff0c;当然ThinkPHP本身也可以直接建站&#xff0c;开源免费、功能强大&#xff0c;深受广大用户喜欢。 虽然ThinkPHP非常优秀&#xff0c;但是为了保障网站安全&#xff0c;我…...

例题:求算法的时间复杂度

xn; // n>1 y0; while(x>(y1)*(y1)) y; 算法行为解析 初始化&#xff1a;x n&#xff08;n > 1&#xff09;&#xff0c;y 0。循环条件&#xff1a;while (x > (y1)*(y1))。循环体&#xff1a;每次迭代中 y 递增 1。 目标&#xff1a;找到最大的整数 y&#x…...

MySQL(1)基础篇

执行一条 select 语句&#xff0c;期间发生了什么&#xff1f; | 小林coding 目录 1、连接MySQL服务器 2、查询缓存 3、解析SQL语句 4、执行SQL语句 5、MySQL一行记录的存储结构 Server 层负责建立连接、分析和执行 SQL存储引擎层负责数据的存储和提取。支持InnoDB、MyIS…...

分裂栅结构对碳化硅MOSFET重复雪崩应力诱导退化的抑制作用

标题 Suppression Effect of Split-Gate Structure on Repetitive Avalanche Stress Induced Degradation for SiC MOSFETs&#xff08;TED 24年&#xff09; 文章的研究内容 这篇文章的研究探讨了重复雪崩应力对碳化硅&#xff08;SiC&#xff09;MOSFET器件退化的影响&am…...

Could not initialize class io.netty.util.internal.Platfor...

异常信息&#xff1a; Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class io.netty.util.internal.PlatformDependent0 Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.reflect.InaccessibleObjec…...

贝叶斯估计习题

x x x 是来自如下指数分布的一个观察值 p ( x ∣ θ ) e − ( x − θ ) , x ≥ θ p(x|\theta)e^{-(x-\theta)},x\geq\theta p(x∣θ)e−(x−θ),x≥θ 取柯西分布作为 θ \theta θ 的先验分布 π ( θ ) 1 π ( 1 θ 2 ) \pi(\theta)\frac{1}{\pi(1\theta^2)} π(θ)π…...

JavaEE基础之- xml

目录 一、xml概述 1.什么是xml 2.W3C组织 3.XML的作用 4.XML与HTML比较 5.XML和properties&#xff08;属性文件&#xff09;比较 二、XML语法概述 1.文档展示 2.XML文档的组成部分 3.xml文档声明 3.1 什么是xml文档声明 3.2 xml文档声明结构 4.xml元素 4.1 xml元素的格…...

网络运维学习笔记 012网工初级(HCIA-Datacom与CCNA-EI)某机构新增:GRE隧道与EBGP实施

文章目录 GRE隧道&#xff08;通用路由封装&#xff0c;Generic Routing Encapsulation&#xff09;协议号47实验&#xff1a;思科&#xff1a;开始实施&#xff1a; 华为&#xff1a;开始实施&#xff1a; eBGP实施思科&#xff1a;华为&#xff1a; GRE隧道&#xff08;通用路…...

RK3568开发板/电脑/ubuntu处于同一网段互通

1.查看无线局域网适配器WLAN winR输入cmd打开电脑终端输入ipconfig或arp -a查看无线局域网IP地址&#xff0c;这就是WIFI. 这里的IPv4是192.168.0.147&#xff0c;默认网关是192.168.0.1&#xff0c;根据网关地址配以太网IP, ubuntu的IP,和rk3568的IP。 且IP范围为192.168.…...

Java常用注解--@FunctionalInterface 函数式接口

文章目录 1 定义要求2 实现方式1. Lambda 表达式2. 方法引用3. 内置函数式接口 3 自定义函数式接口的典型用途1 简化回调逻辑1.1 使用函数式接口简化&#xff0c;1.2 灵活扩展 2 组合函数 4 实践举例4.1 资源清理&#xff08;自动关闭&#xff09;4.2 策略模式&#xff08;动态…...

Xen Center虚拟机Centos 7.x磁盘扩容

文章目录 概要XenCenter虚拟机操作系统命令概览扩容步骤 概要 适用于Centos 7.x系统磁盘扩容&#xff0c;不区分是否虚拟机或者实体系统 XenCenter 使用Xen Center客户端给对应的虚拟机添加一块磁盘后&#xff0c;启动虚拟机系统在系统中进行扩容 虚拟机操作系统 Centos 7.…...

如何调用 DeepSeek API:详细教程与示例

目录 一、准备工作 二、DeepSeek API 调用步骤 1. 选择 API 端点 2. 构建 API 请求 3. 发送请求并处理响应 三、Python 示例&#xff1a;调用 DeepSeek API 1. 安装依赖 2. 编写代码 3. 运行代码 四、常见问题及解决方法 1. API 调用返回 401 错误 2. API 调用返回…...

MySQL_事务的四大特性

1.事务的什么 在学习MySQL的初期&#xff0c;我们通常都是一个一个sql语句的执行&#xff0c;但是在实际开发过程中&#xff0c;我们经常是多个sql语句一起执行&#xff0c;这种多个sql语句在逻辑上要一起执行的就可以看做是一个事务&#xff0c;组成这个事务的多个sql&#x…...