【PyTorch 攻略】(6-7/7)

news2024/11/27 18:39:16

一、说明

本篇介绍模型模型的参数,模型推理和使用,保存加载。

二、训练参数和模型

        在本单元中,我们将了解如何加载模型及其持久参数状态和推理模型预测。为了加载模型,我们将定义模型类,其中包含用于训练模型的神经网络的状态和参数。

%matplotlib inline
import torch
import onnxruntime
from torch import nn
import torch.onnx as onnx
import torchvision.models as models
from torchvision import datasets
from torchvision.transforms import ToTensor
class NeuralNetwork(nn.Module):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
            nn.ReLU()
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.line

        加载模型权重时,我们需要首先实例化模型类,因为该类定义了网络的结构。接下来,我们使用 load_state_dict() 方法加载参数。

model = NeuralNetwork()
model.load_state_dict(torch.load('data/model.pth'))
model.eval()

        注意:请务必在推理之前调用 model.eval() 方法,以将 dropout 和批量归一化层设置为评估模式。如果不这样做,将产生不一致的推理结果。

三、模型推理

        优化模型以在各种平台和编程语言上运行是很困难的。在所有不同的框架和硬件组合中最大限度地提高性能是非常耗时的。
开放式神经网络交换 (ONNX) 运行时为您提供了一种解决方案,只需训练一次,即可在任何硬件、云或边缘设备上加速推理。

        ONNX 是许多供应商支持的一种通用格式,用于共享神经网络和其他机器学习模型。您可以使用 ONNX 格式在其他编程语言和框架(如 Java、JavaScript、C# 和 ML.NET)上对模型进行推理。

input_image = torch.zeros((1,28,28))
onnx_model = 'data/model.onnx'
onnx.export(model, input_image, onnx_model)

        我们将使用测试数据集作为示例数据,以便从 ONNX 模型进行推理以进行预测。

test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor()
)

classes = [
    "T-shirt/top",
    "Trouser",
    "Pullover",
    "Dress",
    "Coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
]
x, y = test_data[0][0], test_data[0][1]

        我们需要使用 onnxruntime 创建一个推理会话。推理会话。为了推断 onnx 模型,我们使用 run 和 pass 输入要返回的输出列表(如果需要所有输出,请留空)和输入值映射。结果是一个输出列表:

session = onnxruntime.InferenceSession(onnx_model, None)
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name

result = session.run([output_name], {input_name: x.numpy()})
predicted, actual = classes[result[0][0].argmax(0)], classes[y]
print(f'Predicted: "{predicted}", Actual: "{actual}"')

四、torch.utils.data.DataLoader和torch.utils.data.Dataset

        PyTorch有两个基元来处理数据:torch.utils.data.DataLoader和torch.utils.data.Dataset数据集存储样本及其相应的标签,DataLoader 围绕数据集包装一个可迭代对象。

%matplotlib inline
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda, Compose
import matplotlib.pyplot as plt

        PyTorch提供特定于领域的库,如TorchText,TorchVision和TorchAudio,所有这些都包括数据集。在本教程中,我们将使用TorchVision数据集。

        torchvision.datasets 模块包含许多真实世界视觉数据(如 CIFAR 和 COCO)的数据集对象。在本教程中,我们将使用 FashionMNIST 数据集。每个TorchVision数据集都包含两个参数:转换target_transform分别修改样本和标签。

# Download training data from open datasets.
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)

# Download test data from open datasets.
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)

        我们将数据集作为参数传递给 DataLoader。这将在我们的数据集上包装一个可迭代对象,并支持自动批处理、采样、随机排序和多进程数据加载。这里我们定义一个 64 的批量大小,即 dataloader 迭代中的每个元素将返回一批 64 个特征和标签。

batch_size = 64

# Create data loaders.
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print("Shape of X [N, C, H, W]: ", X.shape)
    print("Shape of y: ", y.shape, y.dtype)
    break
    
# Display sample data
figure = plt.figure(figsize=(10, 8))
cols, rows = 5, 5
for i in range(1, cols * rows + 1):
    idx = torch.randint(len(test_data), size=(1,)).item()
    img, label = test_data[idx]
    figure.add_subplot(rows, cols, i)
    plt.title(label)
    plt.axis("off")
    plt.imshow(img.squeeze(), cmap="gray")
plt.show()
Shape of X [N, C, H, W]:  torch.Size([64, 1, 28, 28])
Shape of y:  torch.Size([64]) torch.int64

五、创建模型

        为了在 PyTorch 中定义神经网络,我们创建一个继承自 nn.Module 的类。我们在 __init__ 函数中定义网络层,并在转发函数中指定数据如何通过网络。为了加速神经网络的运算,我们将其转移到 GPU(如果可用)。

# Get cpu or gpu device for training.
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))

# Define model
class NeuralNetwork(nn.Module):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
            nn.ReLU()
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

model = NeuralNetwork().to(device)
print(model)
Using cuda device
NeuralNetwork(
  (flatten): Flatten()
  (linear_relu_stack): Sequential(
    (0): Linear(in_features=784, out_features=512, bias=True)
    (1): ReLU()
    (2): Linear(in_features=512, out_features=512, bias=True)
    (3): ReLU()
    (4): Linear(in_features=512, out_features=10, bias=True)
    (5): ReLU()
  )
)

六、优化模型参数

        为了训练模型,我们需要一个损失函数和一个优化器。我们将使用 nn。交叉熵损失用于损失,随机梯度下降用于优化。

loss_fn = nn.CrossEntropyLoss()
learning_rate = 1e-3
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

        在单个训练循环中,模型对训练数据集进行预测(批量馈送到它),并向后传播预测误差以调整模型的参数。

def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)
        
        # Compute prediction error
        pred = model(X)
        loss = loss_fn(pred, y)
        
        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if batch % 100 == 0:
            loss, current = loss.item(), batch * len(X)

        我们还可以对照测试数据集检查模型的性能,以确保它正在学习。

def test(dataloader, model):
    size = len(dataloader.dataset)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= size
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

        训练过程通过多次迭代(纪元)进行。在每个时期,模型学习参数以做出更好的预测。我们打印模型在每个时期的准确性和损失;我们希望看到精度随着每个时期的增加和损失的减少而减少。

epochs = 15
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model)
print("Done!")
Epoch 1
-------------------------------
loss: 2.295450  [    0/60000]
loss: 2.293073  [ 6400/60000]
loss: 2.278504  [12800/60000]
loss: 2.282501  [19200/60000]
loss: 2.273211  [25600/60000]
loss: 2.258452  [32000/60000]
loss: 2.248237  [38400/60000]
loss: 2.228594  [44800/60000]
loss: 2.240276  [51200/60000]
loss: 2.221318  [57600/60000]
Test Error: 
 Accuracy: 51.8%, Avg loss: 0.034745 

Epoch 2
-------------------------------
loss: 2.212354  [    0/60000]
loss: 2.207739  [ 6400/60000]
loss: 2.160400  [12800/60000]
loss: 2.176181  [19200/60000]
loss: 2.168270  [25600/60000]
loss: 2.146453  [32000/60000]
loss: 2.119934  [38400/60000]
loss: 2.083791  [44800/60000]
loss: 2.126453  [51200/60000]
loss: 2.077550  [57600/60000]
Test Error: 
 Accuracy: 53.2%, Avg loss: 0.032452 

Epoch 3
-------------------------------
loss: 2.082280  [    0/60000]
loss: 2.068733  [ 6400/60000]
loss: 1.965958  [12800/60000]
loss: 1.997126  [19200/60000]
loss: 2.002057  [25600/60000]
loss: 1.967370  [32000/60000]
loss: 1.910595  [38400/60000]
loss: 1.849006  [44800/60000]
loss: 1.944741  [51200/60000]
loss: 1.861265  [57600/60000]
Test Error: 
 Accuracy: 51.6%, Avg loss: 0.028937 

Epoch 4
-------------------------------
loss: 1.872628  [    0/60000]
loss: 1.844543  [ 6400/60000]
loss: 1.710179  [12800/60000]
loss: 1.779804  [19200/60000]
loss: 1.737971  [25600/60000]
loss: 1.746953  [32000/60000]
loss: 1.624768  [38400/60000]
loss: 1.575720  [44800/60000]
loss: 1.742827  [51200/60000]
loss: 1.653375  [57600/60000]
Test Error: 
 Accuracy: 58.4%, Avg loss: 0.025570 

Epoch 5
-------------------------------
loss: 1.662315  [    0/60000]
loss: 1.636235  [ 6400/60000]
loss: 1.508407  [12800/60000]
loss: 1.606842  [19200/60000]
loss: 1.560728  [25600/60000]
loss: 1.606024  [32000/60000]
loss: 1.426900  [38400/60000]
loss: 1.406240  [44800/60000]
loss: 1.619918  [51200/60000]
loss: 1.521326  [57600/60000]
Test Error: 
 Accuracy: 61.2%, Avg loss: 0.023459 

Epoch 6
-------------------------------
loss: 1.527535  [    0/60000]
loss: 1.511209  [ 6400/60000]
loss: 1.377129  [12800/60000]
loss: 1.494889  [19200/60000]
loss: 1.457990  [25600/60000]
loss: 1.502333  [32000/60000]
loss: 1.291539  [38400/60000]
loss: 1.285098  [44800/60000]
loss: 1.484891  [51200/60000]
loss: 1.414015  [57600/60000]
Test Error: 
 Accuracy: 62.2%, Avg loss: 0.021480 

Epoch 7
-------------------------------
loss: 1.376779  [    0/60000]
loss: 1.384830  [ 6400/60000]
loss: 1.230116  [12800/60000]
loss: 1.382574  [19200/60000]
loss: 1.255630  [25600/60000]
loss: 1.396211  [32000/60000]
loss: 1.157718  [38400/60000]
loss: 1.186382  [44800/60000]
loss: 1.340606  [51200/60000]
loss: 1.321607  [57600/60000]
Test Error: 
 Accuracy: 62.8%, Avg loss: 0.019737 

Epoch 8
-------------------------------
loss: 1.243344  [    0/60000]
loss: 1.279124  [ 6400/60000]
loss: 1.121769  [12800/60000]
loss: 1.293069  [19200/60000]
loss: 1.128232  [25600/60000]
loss: 1.315465  [32000/60000]
loss: 1.069528  [38400/60000]
loss: 1.123324  [44800/60000]
loss: 1.243827  [51200/60000]
loss: 1.255190  [57600/60000]
Test Error: 
 Accuracy: 63.4%, Avg loss: 0.018518 

Epoch 9
-------------------------------
loss: 1.154148  [    0/60000]
loss: 1.205280  [ 6400/60000]
loss: 1.046463  [12800/60000]
loss: 1.229866  [19200/60000]
loss: 1.048813  [25600/60000]
loss: 1.254785  [32000/60000]
loss: 1.010614  [38400/60000]
loss: 1.077114  [44800/60000]
loss: 1.176766  [51200/60000]
loss: 1.206567  [57600/60000]
Test Error: 
 Accuracy: 64.3%, Avg loss: 0.017640 

Epoch 10
-------------------------------
loss: 1.090360  [    0/60000]
loss: 1.149150  [ 6400/60000]
loss: 0.990786  [12800/60000]
loss: 1.183704  [19200/60000]
loss: 0.997114  [25600/60000]
loss: 1.207199  [32000/60000]
loss: 0.967512  [38400/60000]
loss: 1.043431  [44800/60000]
loss: 1.127000  [51200/60000]
loss: 1.169639  [57600/60000]
Test Error: 
 Accuracy: 65.3%, Avg loss: 0.016974 

Epoch 11
-------------------------------
loss: 1.041194  [    0/60000]
loss: 1.104409  [ 6400/60000]
loss: 0.947670  [12800/60000]
loss: 1.149421  [19200/60000]
loss: 0.960403  [25600/60000]
loss: 1.169899  [32000/60000]
loss: 0.935149  [38400/60000]
loss: 1.018250  [44800/60000]
loss: 1.088222  [51200/60000]
loss: 1.139813  [57600/60000]
Test Error: 
 Accuracy: 66.2%, Avg loss: 0.016446 

Epoch 12
-------------------------------
loss: 1.000646  [    0/60000]
loss: 1.067356  [ 6400/60000]
loss: 0.912046  [12800/60000]
loss: 1.122742  [19200/60000]
loss: 0.932827  [25600/60000]
loss: 1.138785  [32000/60000]
loss: 0.910242  [38400/60000]
loss: 0.999010  [44800/60000]
loss: 1.056596  [51200/60000]
loss: 1.114582  [57600/60000]
Test Error: 
 Accuracy: 67.5%, Avg loss: 0.016011 

Epoch 13
-------------------------------
loss: 0.966393  [    0/60000]
loss: 1.035691  [ 6400/60000]
loss: 0.881672  [12800/60000]
loss: 1.100845  [19200/60000]
loss: 0.910265  [25600/60000]
loss: 1.112597  [32000/60000]
loss: 0.889558  [38400/60000]
loss: 0.982751  [44800/60000]
loss: 1.029199  [51200/60000]
loss: 1.092738  [57600/60000]
Test Error: 
 Accuracy: 68.5%, Avg loss: 0.015636 

Epoch 14
-------------------------------
loss: 0.936334  [    0/60000]
loss: 1.007734  [ 6400/60000]
loss: 0.854663  [12800/60000]
loss: 1.081601  [19200/60000]
loss: 0.890581  [25600/60000]
loss: 1.089641  [32000/60000]
loss: 0.872057  [38400/60000]
loss: 0.969192  [44800/60000]
loss: 1.005193  [51200/60000]
loss: 1.073098  [57600/60000]
Test Error: 
 Accuracy: 69.4%, Avg loss: 0.015304 

Epoch 15
-------------------------------
loss: 0.908971  [    0/60000]
loss: 0.982067  [ 6400/60000]
loss: 0.830095  [12800/60000]
loss: 1.064921  [19200/60000]
loss: 0.874204  [25600/60000]
loss: 1.069008  [32000/60000]
loss: 0.856447  [38400/60000]
loss: 0.957340  [44800/60000]
loss: 0.983547  [51200/60000]
loss: 1.055251  [57600/60000]
Test Error: 
 Accuracy: 70.3%, Avg loss: 0.015001 

Done!

        准确性最初不会很好(没关系!尝试运行循环以获取更多纪元或将learning_rate调整为更大的数字。也可能是我们选择的模型配置可能不是此类问题的最佳配置。

七、保存模型

        保存模型的常用方法是序列化内部状态字典(包含模型参数)。

torch.save(model.state_dict(), "data/model.pth")
print("Saved PyTorch Model State to model.pth")

八、负载模型

        加载模型的过程包括重新创建模型结构并将状态字典加载到其中。

model = NeuralNetwork()
model.load_state_dict(torch.load("data/model.pth"))

        此模型现在可用于进行预测。

classes = [
    "T-shirt/top",
    "Trouser",
    "Pullover",
    "Dress",
    "Coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
]

model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
    pred = model(x)
    predicted, actual = classes[pred[0].argmax(0)], classes[y]
    print(f'Predicted: "{predicted}", Actual: "{actual}"')
Predicted: "Ankle boot", Actual: "Ankle boot"

        祝贺!您已经完成了 PyTorch 初学者教程!我们希望本教程能帮助您在 PyTorch 上开始深度学习。

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

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

相关文章

CockroachDB集群部署

CockroachDB集群部署 1、CockroachDB简介 CockroachDB(有时简称为CRDB)是一个免费的、开源的分布式 SQL 数据库,它建立在一个事务性和强一致性的键 值存储之上。它由 PebbleDB(一个受 RocksDB/leveldb 启发的 K/B 存储库)支持,并使用 Raft 分布式共识…

利用Java EE相关技术实现一个简单的Web聊天室系统

利用Java EE相关技术实现一个简单的Web聊天室系统 (1)编写一个登录页面,登录信息中有用户名和密码,分别用两个按钮来提交和重置登录信息。 (2)通过请求指派来处理用户提交的登录信息,如果用户名…

基于YOLOv8模型的烟火目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要:基于YOLOv8模型的烟火目标检测系统可用于日常生活中检测与定位烟火目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数据集…

linux中的开发工具

在刚开始使用linux的时候,我们需要在系统上写一些简单的代码,来熟悉环境以及各种指令 并且熟悉属于linux的一套开发的环境,而这对于c来说需要三个软件就可以进行简单的编码 和使用,让我们来认识一下下列工具,以及工具的…

【Java 基础篇】Java字符打印流详解:文本数据的输出利器

在Java编程中,我们经常需要将数据输出到文件或其他输出源中。Java提供了多种输出流来帮助我们完成这项任务,其中字符打印流是一个非常有用的工具。本文将详细介绍Java字符打印流的用法,以及如何在实际编程中充分利用它。 什么是字符打印流&a…

电脑丢失d3dcompiler47.dll怎么办,这个四个修复方法都可以解决

d3dcompiler_47.dll 是一个与 DirectX 相关的动态链接库文件,它包含了 DirectX 编译器的一些函数和类,对于许多应用程序和游戏来说都是必需的。如果您的系统中缺失了这个文件,可能会导致程序无法正常运行。下面我们将介绍四个修复 d3dcompile…

(图论) 1020. 飞地的数量 ——【Leetcode每日一题】

❓ 1020. 飞地的数量 难度:中等 给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个 海洋单元格、1 表示一个 陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边…

vant 组件库的基本使用

文章目录 vant组件库1、什么是组件库2、vant组件 全部导入 和 按需导入的区别3、全部导入的使用步骤:4、按需导入的使用步骤:5、封装vant文件包 vant组件库 该项目将使用到vant-ui组件库,这里的目标就是认识他,铺垫知识 1、什么…

PyG-GAT-Cora(在Cora数据集上应用GAT做节点分类)

文章目录 model.pymain.py参数设置运行图 model.py import torch.nn as nn from torch_geometric.nn import GATConv import torch.nn.functional as F class gat_cls(nn.Module):def __init__(self,in_dim,hid_dim,out_dim,dropout_size0.5):super(gat_cls,self).__init__()s…

安达发APS|国货品牌崛起,制造业迎来智能排产新机遇

随着国货品牌的不断崛起,制造业的生产也面临着巨大的挑战。为应对这一挑战,越来越多的企业开始引入APS智能排产技术,以优化生产线布局、提升设备利用率、缩短生产周期、减少生产成本,从而增强市场竞争力。本文将为您详细解读APS智…

数据结构-----栈(栈的初始化、建立、入栈、出栈、遍历、清空等操作)

目录 前言 栈 1.定义 2.栈的特点 3.栈的储存方式 3.1数组栈 3.2链栈 4.栈的基本操作(C语言) 4.1初始化 4.2判断是否满栈 4.3判断空栈 4.4 入栈 4.5 出栈 4.6获取栈顶元素 4.7遍历栈 4.8清空栈 完整代码示例 前言 大家好呀!今天我…

登录业务实现

登录业务实现: 登录成功/失败实现 -> pinia管理用户数据及数据持久化 -> 不同登录状态的模板适配 -> 请求拦截器携带token -> 退出登录实现 -> token失效(401响应拦截) 1. 登录成功/失败实现 当表单校验通过时&a…

华为云云耀云服务器L实例评测|云耀云服务器L实例部署odoo开源ERP平台

华为云云耀云服务器L实例评测|云耀云服务器L实例部署odoo开源ERP平台 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例使用场景1.3 云耀云服务器L实例特点 二、odoo介绍2.1 odoo简介2.2 odoo特点 三、本次实践介绍3.1 本次实践简介3.2 本…

解决Java应用程序中的SQLException:服务器时区值未识别问题;MySQL连接问题:服务器时区值 ‘Öйú±ê׼ʱ¼ä‘ 未被识别的解决方法

目录 ​编辑 问题背景 解决方案 问题背景 今天遇见一个这个问题,解决后发出来分享一下: java.sql.SQLException: The server time zone value is unrecognized or represents more than one time zone. You must configure either the server or J…

STP介绍

目录 STP概述 二层环路带来的问题 1.广播风暴 2.MAC地址漂移问题 3.多帧复制---这个好理解,同一个数据帧被重复收到多次,被称为多帧复制。 802.1D生成树 STP的BPDU BPDU主要分为两大类 配置BPDU RPC COST 配置BPDU的工作过程 TCN BPDU TCN…

【python爬虫】——历史天气信息爬取

文章目录 1、任务描述1.1、需求分析1.2 页面分析 2、获取网页源码、解析、保存数据3、结果展示 1、任务描述 1.1、需求分析 在2345天气信息网2345天气网依据地点和时间对相关城市的历史天气信息进行爬取。 1.2 页面分析 网页使用get方式发送请求,所需参数包括a…

c语言练习63:用malloc开辟二维数组的三种办法

用malloc开辟二维数组的三种办法 使用malloc函数模拟开辟一个3*5的整型二维数组&#xff0c;开辟好后&#xff0c;使用二维数组的下标访问形式&#xff0c;访问空间。 第一种办法&#xff1a;用指针数组&#xff1a; #include<stdio.h> int main() {int** p (int**)m…

2023-09-19 LeetCode每日一题(打家劫舍 IV)

2023-09-19每日一题 一、题目编号 2560. 打家劫舍 IV二、题目链接 点击跳转到题目位置 三、题目描述 沿街有一排连续的房屋。每间房屋内都藏有一定的现金。现在有一位小偷计划从这些房屋中窃取现金。 由于相邻的房屋装有相互连通的防盗系统&#xff0c;所以小偷 不会窃取…

【C++代码】二叉树的最大深度,二叉树的最小深度,完全二叉树的节点个数--代码随想录

题目&#xff1a;二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 题解 如果我们知道了左子树和右子树的最大深度 l 和 r&#xff0c;那么该二叉树的最大深度即为 m a x ( l , r ) …

令人惊艳的AI项目,这也太猛了...

大家好&#xff0c;我是 Jack。 这两天&#xff0c;我在网上冲浪&#xff0c;发现了一款神器&#xff01; 我在使用 AI 绘画 Stable Diffsuion 和 Midjourney 的时候&#xff0c;花费时间最多的就是写 prompt 描述词了&#xff0c;绞尽脑汁地调试 prompt。 同样&#xff0c;…