PyTorch--卷积神经网络(CNN)模型实现手写数字识别

news2024/11/14 5:52:34

文章目录

    • 前言
      • 完整代码
      • 代码解析
        • 1. 导入必要的库
        • 2. 设备配置
        • 3. 超参数设置
        • 4. 加载MNIST数据集
        • 5. 创建数据加载器
        • 6. 定义卷积神经网络模型
        • 7. 实例化模型并移动到设备
        • 8. 定义损失函数和优化器
        • 9. 训练模型
        • 10. 测试模型
        • 11. 保存模型
      • 常用函数解析
      • 小改进
        • 数据集部分可视化
        • 训练过程可视化

前言

今天要介绍的这段代码是一个使用PyTorch框架实现的卷积神经网络(CNN)模型,用于对MNIST数据集进行分类的示例。MNIST数据集是手写数字识别领域的一个标准数据集,包含0到9的灰度图像。

代码的主要组成部分如下:

  1. 导入必要的库:导入PyTorch、PyTorch神经网络模块、torchvision(用于处理图像数据集)和transforms(用于图像预处理)。

  2. 设备配置:设置模型运行的设备,优先使用GPU(如果可用),否则使用CPU。

  3. 超参数设置:定义了训练迭代的轮数(num_epochs)、类别数(num_classes)、批次大小(batch_size)和学习率(learning_rate)。

  4. 加载MNIST数据集:使用torchvision.datasets.MNIST加载MNIST训练集和测试集,并应用transforms.ToTensor将图像转换为张量。

  5. 创建数据加载器:使用torch.utils.data.DataLoader创建训练和测试数据的加载器,以便在训练和测试过程中批量加载数据。

  6. 定义卷积神经网络模型:定义了一个名为ConvNet的类,继承自nn.Module。模型包含两个卷积层(每层后接批量归一化和ReLU激活函数),以及一个全连接层。

  7. 实例化模型并移动到设备:创建ConvNet模型的实例,并将其移动到之前设置的设备上。

  8. 定义损失函数和优化器:使用nn.CrossEntropyLoss作为损失函数,torch.optim.Adam作为优化器。

  9. 训练模型:进行多个epoch的训练,每个epoch中对数据集进行遍历,执行前向传播、损失计算、反向传播和参数更新。

  10. 测试模型:在测试阶段,将模型设置为评估模式,并禁用梯度计算以提高效率,然后计算模型在测试集上的准确率。

  11. 保存模型:使用torch.save保存训练后的模型参数到文件,以便将来可以重新加载和使用模型。

完整代码

import torch 
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms


# Device configuration
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

# Hyper parameters
num_epochs = 5
num_classes = 10
batch_size = 100
learning_rate = 0.001

# MNIST dataset
train_dataset = torchvision.datasets.MNIST(root='../../data/',
                                           train=True, 
                                           transform=transforms.ToTensor(),
                                           download=True)

test_dataset = torchvision.datasets.MNIST(root='../../data/',
                                          train=False, 
                                          transform=transforms.ToTensor())

# Data loader
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=batch_size, 
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                          batch_size=batch_size, 
                                          shuffle=False)

# Convolutional neural network (two convolutional layers)
class ConvNet(nn.Module):
    def __init__(self, num_classes=10):
        super(ConvNet, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(1, 16, kernel_size=5, stride=1, padding=2),
            nn.BatchNorm2d(16),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.layer2 = nn.Sequential(
            nn.Conv2d(16, 32, kernel_size=5, stride=1, padding=2),
            nn.BatchNorm2d(32),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.fc = nn.Linear(7*7*32, num_classes)
        
    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.reshape(out.size(0), -1)
        out = self.fc(out)
        return out

model = ConvNet(num_classes).to(device)

# Loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

# Train the model
total_step = len(train_loader)
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        images = images.to(device)
        labels = labels.to(device)
        
        # Forward pass
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # Backward and optimize
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        if (i+1) % 100 == 0:
            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' 
                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))

# Test the model
model.eval()  # eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)
with torch.no_grad():
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = images.to(device)
        labels = labels.to(device)
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    print('Test Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))

# Save the model checkpoint
torch.save(model.state_dict(), 'model.ckpt')

代码解析

1. 导入必要的库
import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
  • 导入PyTorch及其神经网络(nn)、计算机视觉(vision)模块和变换(transforms)模块。
2. 设备配置
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
  • 使用torch.device设置模型运行的设备,优先使用GPU(如果可用)。
3. 超参数设置
num_epochs = 5
num_classes = 10
batch_size = 100
learning_rate = 0.001
  • 定义训练迭代的轮数(num_epochs),输出类别的数量(num_classes),每个批次的样本数(batch_size),以及优化算法的学习率(learning_rate)。
4. 加载MNIST数据集
train_dataset = torchvision.datasets.MNIST(root='../../data/',
                                           train=True, 
                                           transform=transforms.ToTensor(),
                                           download=True)

test_dataset = torchvision.datasets.MNIST(root='../../data/',
                                          train=False, 
                                          transform=transforms.ToTensor())
  • 使用torchvision.datasets.MNIST加载MNIST数据集,包括训练集和测试集。transforms.ToTensor将图像数据转换为张量。
5. 创建数据加载器
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=batch_size, 
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                          batch_size=batch_size, 
                                          shuffle=False)
  • 使用torch.utils.data.DataLoader创建数据加载器,用于批量加载数据,并在训练时打乱数据顺序。
6. 定义卷积神经网络模型
class ConvNet(nn.Module):
    def __init__(self, num_classes=10):
        super(ConvNet, self).__init__()
        # 定义模型层
        pass
    
    def forward(self, x):
        # 定义前向传播过程
        pass
  • 定义一个名为ConvNet的类,继承自nn.Module。在__init__中初始化模型的层,在forward中定义前向传播逻辑。
7. 实例化模型并移动到设备
model = ConvNet(num_classes).to(device)
  • 创建ConvNet模型的实例,并使用.to(device)将其移动到之前设置的设备上。
8. 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
  • 定义nn.CrossEntropyLoss作为损失函数,使用torch.optim.Adam作为优化器。
9. 训练模型
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        # 训练过程
        pass
  • 遍历所有epoch和batch,执行训练过程,包括数据预处理、前向传播、损失计算、反向传播和参数更新。
10. 测试模型
model.eval()  # eval mode
with torch.no_grad():
    # 测试过程
    pass
  • 将模型设置为评估模式,禁用梯度计算,并执行测试过程,计算模型的准确率。
11. 保存模型
torch.save(model.state_dict(), 'model.ckpt')
  • 使用torch.save保存模型的状态字典到文件,以便之后可以重新加载和使用模型。

常用函数解析

  1. torch.device(device_str)

    • 格式:torch.device(device_str)
    • 参数:device_str —— 指定设备类型和编号(如’cuda:0’)或’cpu’。
    • 意义:确定模型和张量运行的设备。
    • 用法示例:
      device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
      model.to(device)
      
  2. torchvision.datasets.MNIST(...)

    • 格式:torchvision.datasets.MNIST(root, train, transform, download)
    • 参数:指定数据集路径、是否为训练集、预处理变换、是否下载数据集。
    • 意义:加载MNIST数据集。
    • 用法示例:
      train_dataset = torchvision.datasets.MNIST(root='../../data/', train=True, transform=transforms.ToTensor(), download=True)
      
  3. torch.utils.data.DataLoader(...)

    • 格式:torch.utils.data.DataLoader(dataset, batch_size, shuffle)
    • 参数:数据集对象、批次大小、是否打乱数据。
    • 意义:创建数据加载器。
    • 用法示例:
      train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
      
  4. nn.Module

    • 格式:作为基类,不直接实例化。
    • 意义:所有神经网络模块的基类。
    • 用法示例:
      class ConvNet(nn.Module):
          def __init__(self, num_classes=10):
              super(ConvNet, self).__init__()
              # ...
      
  5. nn.Sequential

    • 格式:nn.Sequential(*modules)
    • 参数:一个模块序列。
    • 意义:按顺序应用多个模块。
    • 用法示例:
      self.layer1 = nn.Sequential(
          nn.Conv2d(1, 16, kernel_size=5, stride=1, padding=2),
          nn.BatchNorm2d(16),
          nn.ReLU(),
          nn.MaxPool2d(kernel_size=2, stride=2)
      )
      
  6. nn.Conv2d(...)

    • 格式:nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
    • 参数:输入通道数、输出通道数、卷积核大小、步长、填充。
    • 意义:创建二维卷积层。
    • 用法示例:
      nn.Conv2d(1, 16, kernel_size=5, stride=1, padding=2)
      
  7. nn.BatchNorm2d(...)

    • 格式:nn.BatchNorm2d(num_features)
    • 参数:特征数量。
    • 意义:创建二维批量归一化层。
    • 用法示例:
      nn.BatchNorm2d(16)
      
  8. nn.ReLU()

    • 格式:nn.ReLU()
    • 意义:创建ReLU激活层。
    • 用法示例:
      nn.ReLU()
      
  9. nn.MaxPool2d(...)

    • 格式:nn.MaxPool2d(kernel_size, stride)
    • 参数:池化核大小、步长。
    • 意义:创建最大池化层。
    • 用法示例:
      nn.MaxPool2d(kernel_size=2, stride=2)
      
  10. nn.Linear(...)

    • 格式:nn.Linear(in_features, out_features)
    • 参数:输入特征数、输出特征数。
    • 意义:创建全连接层。
    • 用法示例:
      self.fc = nn.Linear(7*7*32, num_classes)
      
  11. nn.CrossEntropyLoss()

    • 格式:nn.CrossEntropyLoss()
    • 意义:创建交叉熵损失层。
    • 用法示例:
      criterion = nn.CrossEntropyLoss()
      
  12. torch.optim.Adam(...)

    • 格式:torch.optim.Adam(params, lr)
    • 参数:模型参数、学习率。
    • 意义:创建Adam优化器。
    • 用法示例:
      optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
      
  13. .to(device)

    • 格式:.to(device)
    • 参数:设备对象。
    • 意义:将模型或张量移动到指定设备。
    • 用法示例:
      images = images.to(device)
      labels = labels.to(device)
      
  14. .reshape(-1, num_features)

    • 格式:reshape(new_shape)
    • 参数:新形状。
    • 意义:重塑张量形状。
    • 用法示例:
      out = out.reshape(out.size(0), -1)
      
  15. torch.max(outputs.data, 1)

    • 格式:torch.max(input, dim)
    • 参数:输入张量、计算最大值的维度。
    • 意义:获取张量在指定维度上的最大值和索引。
    • 用法示例:
      _, predicted = torch.max(outputs.data, 1)
      
  16. torch.no_grad()

    • 格式:torch.no_grad()
    • 意义:上下文管理器,用于推理或测试阶段禁用梯度计算。
    • 用法示例:
      with torch.no_grad():
          # 测试模型的代码
      
  17. .sum().item()

    • 格式:.sum(dim).item()
    • 参数:求和的维度。
    • 意义:计算张量在指定维度的和,并转换为Python数值。
    • 用法示例:
      correct += (predicted == labels).sum().item()
      
  18. model.eval()

    • 格式:model.eval()
    • 意义:将模型设置为评估模式。
    • 用法示例:
      model.eval()
      
  19. torch.save(...)

    • 格式:torch.save(obj, f)
    • 参数:要保存的对象、文件路径。
    • 意义:保存对象到文件。
    • 用法示例:
      torch.save(model.state_dict(), 'model.ckpt')
      

小改进

在运行代码的时候发现可视化十分简陋,于是进行了第一波可视化小改进:读取部分数据集。

数据集部分可视化
def show_images(images):
    plt.figure(figsize=(10,10))
    for i, img in enumerate(images):
        plt.subplot(5, 5, i+1)
        plt.xticks([])
        plt.yticks([])
        plt.grid(False)
        plt.imshow(img.squeeze().numpy(), cmap='gray')
    plt.show()

# Visualize a few images
dataiter = iter(train_loader)
images, _ = next(dataiter)
show_images(images[:25])  # Visualize 25 images

另外,请注意,由于MNIST数据集中的图像是灰度图,它们的形状是(batch_size, channels, height, width),即(100, 1, 28, 28)。在使用show_images函数之前,我们需要将图像重塑为(batch_size, height, width),即(100, 28, 28)。以下是show_images函数的修正:

def show_images(images):
    plt.figure(figsize=(10,10))
    for i, img in enumerate(images):
        plt.subplot(5, 5, i+1)
        plt.xticks([])
        plt.yticks([])
        plt.grid(False)
        plt.imshow(img.squeeze().numpy(), cmap='gray')  # 使用 squeeze() 来去除单维度
    plt.show()

确保在使用show_images函数时传递正确形状的图像。如果图像是从DataLoader中获取的,你可能需要使用unsqueeze(0)来添加一个批次维度,然后再调用squeeze()来去除单维度。例如:

images = images.unsqueeze(0)  # 添加一个批次维度
show_images(images[:25])  # 可视化前25张图像

这样就可以正确地显示图像了。
在这里插入图片描述
然后呢,继续执行代码,我们发现训练过程的可视化也是少得可怜,于是我们再加多一点可视化内容。在这里插入图片描述

训练过程可视化

要对训练过程进行更多的可视化,咱们可以记录每个epoch的损失值,并使用Matplotlib绘制损失随epoch变化的图表。以下是如何修改代码来实现这一点:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt

# ...(之前的代码保持不变,包括设备配置、数据加载、模型定义等)

# 训练模型
def train(model, device, train_loader, optimizer, epoch, num_epochs):
    model.train()  # Set the model to training mode
    total_step = len(train_loader)
    losses = []
    
    for i, (images, labels) in enumerate(train_loader):
        images, labels = images.to(device), labels.to(device)

        # Forward pass
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # Backward and optimize
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        # Collect loss for plotting
        losses.append(loss.item())
        
        if (i+1) % 100 == 0:
            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'
                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))

    return losses

# 绘制损失曲线的函数
def plot_losses(epochs, losses):
    plt.figure(figsize=(10, 5))
    for i, loss_per_epoch in enumerate(losses):
        plt.plot(loss_per_epoch, label=f'Epoch {i+1}')
    plt.title('Loss over epochs')
    plt.xlabel('Steps')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()

# 训练过程
losses_over_epochs = []
for epoch in range(num_epochs):
    losses = train(model, device, train_loader, optimizer, epoch, num_epochs)
    losses_over_epochs.append(losses)
    print(f'Epoch {epoch+1}/{num_epochs} - Average Loss: {sum(losses)/len(losses):.4f}')

# 绘制所有epoch的损失曲线
plot_losses(num_epochs, losses_over_epochs)

# ...(测试模型和保存模型的代码保持不变)

在这个修改后的代码中,我们添加了两个新的函数:

  • train:这个函数用于训练模型,并记录每个step的损失。它返回一个包含所有step损失的列表。
  • plot_losses:这个函数接受epoch列表和损失列表作为参数,并绘制出损失随训练step变化的曲线。

在主训练循环中,我们对每个epoch调用train函数,并收集所有epoch的损失,然后使用plot_losses函数绘制损失曲线。

请注意,这里绘制的是每个step的损失,而不是每个epoch的损失均值。如果想要绘制每个epoch的平均损失,可以修改train函数来计算每个epoch的平均损失,并只记录这个值。

咱直接把最终代码贴上:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt

# Device configuration
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

# Hyper parameters
num_epochs = 10
num_classes = 10
batch_size = 100
learning_rate = 0.001

# MNIST dataset
train_dataset = torchvision.datasets.MNIST(root='../../data/',
                                           train=True, 
                                           transform=transforms.ToTensor(),
                                           download=True)

test_dataset = torchvision.datasets.MNIST(root='../../data/',
                                          train=False, 
                                          transform=transforms.ToTensor())

# Data loader
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=batch_size, 
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                          batch_size=batch_size, 
                                          shuffle=False)

# Convolutional neural network (two convolutional layers)
class ConvNet(nn.Module):
    def __init__(self, num_classes=10):
        super(ConvNet, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(1, 16, kernel_size=5, stride=1, padding=2),
            nn.BatchNorm2d(16),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.layer2 = nn.Sequential(
            nn.Conv2d(16, 32, kernel_size=5, stride=1, padding=2),
            nn.BatchNorm2d(32),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.fc = nn.Linear(7*7*32, num_classes)
        
    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.view(out.size(0), -1)  # Flatten the output
        out = self.fc(out)
        return out

model = ConvNet(num_classes).to(device)

# Loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# Function to visualize images
def show_images(images):
    plt.figure(figsize=(10,10))
    for i, img in enumerate(images):
        plt.subplot(5, 5, i+1)
        plt.xticks([])
        plt.yticks([])
        plt.grid(False)
        plt.imshow(img.squeeze().numpy(), cmap='gray')
    plt.show()

# Function to train the model
def train(model, device, train_loader, optimizer, epoch, num_epochs):
    model.train()  # Set the model to training mode
    total_step = len(train_loader)
    losses = []
    
    for i, (images, labels) in enumerate(train_loader):
        images, labels = images.to(device), labels.to(device)
        
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        
        losses.append(loss.item())
        
        if (i+1) % 100 == 0:
            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'
                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))

    return losses

# Function to test the model
def test(model, device, test_loader):
    model.eval()  # Set the model to evaluation mode
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images = images.to(device)
            labels = labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    return 100 * correct / total

# Function to plot training progress
def plot_progress(epochs, train_losses, test_accuracies):
    plt.figure(figsize=(12, 5))
    plt.subplot(1, 2, 1)
    for i in range(epochs):
        plt.plot(train_losses[i], label=f'Epoch {i+1}')
    plt.title('Training Loss')
    plt.xlabel('Batch')
    plt.ylabel('Loss')
    plt.legend()

    plt.subplot(1, 2, 2)
    plt.plot(test_accuracies, label='Accuracy')
    plt.title('Test Accuracy')
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy (%)')
    plt.legend()
    plt.show()

# Visualize a few images
dataiter = iter(train_loader)
images, _ = next(dataiter)
show_images(images[:25])  # Visualize 25 images

# Initialize lists to monitor loss and accuracy
train_losses = []
test_accuracies = []

# Train the model
for epoch in range(num_epochs):
    print(f'Epoch {epoch+1}/{num_epochs}')
    train_loss = train(model, device, train_loader, optimizer, epoch, num_epochs)
    train_losses.append(train_loss)
    test_accuracy = test(model, device, test_loader)
    test_accuracies.append(test_accuracy)

    print(f'Epoch {epoch+1}/{num_epochs} - Average Loss: {sum(train_loss)/len(train_loss):.4f}, Accuracy: {test_accuracy:.2f}%')

# Plot training progress
plot_progress(num_epochs, train_losses, test_accuracies)

# Save the model checkpoint
torch.save(model.state_dict(), 'model.ckpt')

经过修改后的训练过程如下图所示:
在这里插入图片描述
在这里插入图片描述
还有很多很多小改进的方向,就留给各位自己尝试啦。

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

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

相关文章

阿里V2缺口图-滑块验证码逆向分析思路学习

一、声明! 原创文章,请勿转载! 本文内容仅限于安全研究,不公开具体源码。维护网络安全,人人有责。 文章中所有内容仅供学习交流使用,不用于其他任何目的,均已做脱敏处理&…

【Datawhale X 魔搭 】AI夏令营第四期大模型方向,Task1:智能编程助手(持续更新)

在一个数据驱动的世界里,人工智能的未来应由每一个愿意学习和探索的人共同塑造和掌握。希望这里是你实现AI梦想的起点。 大模型小白入门:https://linklearner.com/activity/14/11/25 大模型开发工程师能力测试:https://linklearner.com/activ…

20240810在荣品RK3588S-AHD开发板的预置Android13下挂载exFAT的256GB的TF卡

df -h mount fdisk无效 20240810在荣品RK3588S-AHD开发板的预置Android13下挂载exFAT的256GB的TF卡 2024/8/10 21:19 缘起:当时比较便宜96.9¥/想看看256GB的TF卡的高速卡的效果,就在京东入手了3张三星的高速TF卡。最近在弄RK3588S&#xff0c…

部署和体验llama3.1:8B中文微调版本

前言 llama-3-1 meta于2024-07-23发布 https://ai.meta.com/blog/meta-llama-3-1/ 文档 https://llama.meta.com/docs/llama-everywhere/running-meta-llama-on-linux/ git https://github.com/meta-llama/llama3 Cloudflare提供了免费访问的入口 https://linux.do/t/to…

uvm(7)factory

重载 针对任务或者函数,定义virtual;然后就可以重载 第二个是 约束的重载 然后 m_trans.crc_err_cons.constraint_mode(0); 这个是关闭此约束 m_trans.constraint_mode(0); 这是关闭所有约束 还可以集成原来的transation直接重写约束起到重载的作用 用factory重…

二十二、简易画图工具

目录 一、设计需求 二、示例代码 三、代码解析 1、setAutoFillBackground函数的作用 2、resizeEvent被调用的时机 四、Qt5双缓冲机制 五、总结 一、设计需求 实现一个简单的绘图工具,可以选择线型、线宽及颜色等基本要素。 二、示例代码 mainwindow.cpp #in…

Dijkstra算法c++详解

算法是一种用于寻找图中两点间最短路径的算法&#xff0c;适用于无负权边的图。下面是一个使用C实现的算法示例&#xff0c;使用优先队列来优化算法效率&#xff1a; #include <iostream> #include <climits> // For INT_MAX #include <vector> #include &l…

ptqt5 打包把资源文件合进exe文件中 单个exe文件即可

目录 安装 PyInstaller 项目结构 编写 spec 文件 修改代码以嵌入资源 打包应用程序 解释 检查打包结果 使用 PyQt5 开发的应用程序可以通过 PyInstaller 工具打包成单个可执行文件(exe),并将所有资源文件(如图像、图标、样式表等)嵌入到 exe 文件中。以下是如何实现…

利用java结合python实现gis在线绘图,主要技术java+python+matlab+idw+Kriging

主要技术javapythonmatlabidwKriging GIS中的等值面和等高线绘图主要用于表达连续空间数据的分布情况&#xff0c;特别适用于需要展示三维空间中某个变量随位置变化的应用场景。 具体来说&#xff0c;以下是一些适合使用GIS等值面和等高线绘图的场景&#xff1a; 地形与地貌分…

spring-security-1-快速入门

1 功能 身份认证(authentication)授权(authorization)防御常见攻击 身份认证&#xff1a;常见账号密码登录&#xff0c;短信登录 授权&#xff1a;什么样的角色&#xff0c;能看见什么菜单&#xff0c;能访问哪些接口。 2 pom <dependency><groupId>org.springf…

开关电源:优化电子产品中的能源使用

电压转换器是许多技术系统的支柱。根据应用的不同&#xff0c;所需的电源单元由变压器、整流器 AC/DC 转换器实现。当高性能开关电源尚未上市时&#xff0c;几乎只使用 50 Hz 变压器解决方案。 电源注意事项 电能几乎完全以三相电流的形式提供&#xff0c;系统电压为 10 ...3…

ThinkPHP5漏洞分析之文件包含

目录 漏洞概要 漏洞环境 环境搭建 配置 测试&#xff1a; 漏洞分析&#xff1a; extract: 参数 Lua::assign 示例 array_merge 说明 返回值 array_merge() 示例 fetch: 漏洞修复 漏洞概要 本次漏洞存在于 ThinkPHP 模板引擎中&#xff0c;在加载模版解析变量时…

代码随想录 day 39 动态规划 打家劫舍

第九章 动态规划part07 今天就是打家劫舍的一天&#xff0c;这个系列不算难&#xff0c;大家可以一口气拿下。 198.打家劫舍 视频讲解&#xff1a;https://www.bilibili.com/video/BV1Te411N7SX https://programmercarl.com/0198.%E6%89%93%E5%AE%B6%E5%8A%AB%E8%88%8D.html…

Ubuntu虚拟机安装及汉化

一、安装 1.勾选典型(推荐)(T)——点击下一步 2.点击浏览找到光盘映像文件打开&#xff08;此文件很重要安装好后安装包不要卸载&#xff0c;放在不容易被删除的地方&#xff09;——点击下一步 3.将信息补充完整——点击下一步 4.点击浏览选择要将虚拟机安装在哪个路径&…

【IT行业研究报告】Internet Technology

一、引言 随着信息技术的飞速发展&#xff0c;IT行业已成为全球经济的重要驱动力。从云计算、大数据、人工智能到物联网&#xff0c;IT技术正深刻改变着各行各业的生产方式、商业模式和人们的生活方式。本报告旨在深入分析IT行业的现状、发展趋势和挑战&#xff0c;探讨其在各…

基于C11的简单log,支持C++的‘<<’风格和C的‘可变参数’风格

基于C11的简单log&#xff0c;支持C的‘<<’风格和C的‘可变参数’风格 日志仅由richlog.h单个文件实现功能&#xff0c;软件集成简单。 支持C的std::cout的<<风格的日志打印&#xff0c;也支持C的printf风格的日志打印 日志多线程安全&#xff0c;采用C11 mute…

Adobe PhotoShop - 制图操作

1. 排布照片 菜单 - 视图 - 对齐&#xff1a;打开后图层将会根据鼠标的移动智能对齐 菜单 - 视图 - 标尺&#xff1a;打开后在页面出现横纵标尺&#xff0c;方便图层的对齐与排列 2. 自动生成全景照 在日常处理中&#xff0c;我们常常想要将几张图片进行拼接获得一张全景图&…

Linux:文件管理,目录管理,文件系统,链接类型

1&#xff0c;文件管理 用户&#xff08;标识号&#xff1a;UID&#xff09;&#xff1a;一定资源的使用者&#xff0c;可以创建和管理文件以及访问其他用户文件。可以从属于多个群组。 用户组&#xff08;标识号&#xff1a;GID&#xff09;&#xff1a;由一定数量的对某些文件…

GlobalMapper软件安装流程

目录 一、环境准备 二、安装步骤 三、软件激活 一、环境准备 系统&#xff1a;win7操作系统 安装包下载&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1Vb4VVRFBRYawt3MT-5gYOw 提取码&#xff1a;sxdj 二、安装步骤 1、解压&#xff0c;右键global-mapper-23_1-x…

NVDLA专题5:具体模块介绍——Convolution Buffer

概述 卷积缓冲器(CBUF)是卷积流水线中的一个阶段&#xff0c;module定义在NV_NVDLA_cbuf.v&#xff0c;module信息如下&#xff1a; module NV_NVDLA_cbuf (nvdla_core_clk //|< i,nvdla_core_rstn //|< i,cdma2buf_dat_wr_addr //|< i,cdma2buf_dat_wr_…