PyTorch深度学习实战(34)——Pix2Pix详解与实现
PyTorch深度学习实战(34)——Pix2Pix详解与实现
- 0. 前言
- 1. 模型与数据集
- 1.1 Pix2Pix 基本原理
- 1.2 数据集分析
- 1.3 模型构建策略
- 2. 实现 Pix2Pix 生成图像
- 小结
- 系列链接
0. 前言
Pix2Pix
是基于生成对抗网络 (Convolutional Generative Adversarial Networks
, GAN
) 的图像转换框架,能够将输入图像转换为与之对应的输出图像,能够广泛用于图像到图像转换的任务,如风格转换、图像修复、语义标签到图像的转换等。Pix2Pix
的核心思想是通过对抗训练将输入图像和目标输出图像进行配对,使生成网络可以学习到输入图像到输出图像的映射关系。在本节中,将学习使用 Pix2Pix
根据给定轮廓生成图像。
1. 模型与数据集
1.1 Pix2Pix 基本原理
Pix2Pix
是基于对抗生成网络 (Convolutional Generative Adversarial Networks
, GAN
) 的图像转换算法,可以将一种图像转换为与之对应的输出图像。例如,将黑白线稿转换为彩色图像或将低分辨率图像转换为高分辨率图像等。Pix2Pix
已经被广泛应用于计算机视觉领域,例如风格迁移、语义分割、图像去雾等任务。
假设,数据集中包含成对的相互关联图像,例如,线稿图像作为输入,实际图像作为输出。如果我们要在给定线稿输入图像的情况下生成图像,传统方法中,可以将其视为输入到输出的简单映射(即监督学习问题),但传统监督学习只能从历史数据中学习,无法为新线稿生成逼真图像。而 GAN
能够在确保生成的图像足够逼真的情况下,为新数据样本输出合理预测结果。
1.2 数据集分析
为了训练 Pix2Pix
模型,我们需要了解本节所用的数据集,数据集取自 berkeley Pix2Pix 数据集,可以自行构建数据集,也可以下载本文所用数据集,下载地址:https://pan.baidu.com/s/1a7VE-z1mGWhbIvvst9e8Ng,提取码:rkvd
。数据集包含 4381
张不同样式和颜色的鞋子照片,图像尺寸为 256 x 256
。
1.3 模型构建策略
在本节中,我们将构建 PixPix
模型,根据鞋子的手绘轮廓生成鞋子图像,模型构建策略如下:
- 获取实际图像并使用
cv2
边缘检测技术创建相应的物体轮廓 - 从原始图像的区块中提取颜色样本,以便生成网络预测所需生成的颜色
- 构建
UNet
架构作为生成网络,将带有样本区块颜色的轮廓作为输入并预测相应的图像 - 构建判别网络架构,获取输入图像并预测它是真实图像还是生成图像
- 训练生成网络和判别网络,直到生成网络可以生成欺骗判别网络的生成图像
2. 实现 Pix2Pix 生成图像
接下来,使用 PyTorch
实现 Pix2Pix
模型,根据给定鞋子轮廓生成图像。
(1) 导入数据集以及所需库:
import torch
from torch import nn
from torch import optim
from matplotlib import pyplot as plt
import numpy as np
from torchvision.utils import make_grid
from torch.utils.data import DataLoader, Dataset
import cv2
import random
from glob import glob
# from torch_snippets import *
device = "cuda" if torch.cuda.is_available() else "cpu"from torchvision import transforms
下载后的图像示例如下:
在本节中,我们需要在给定轮廓(边缘)和鞋子的区块颜色的情况下绘制鞋子。接下来,获取给定鞋子图像的边缘,然后训练模型,根据给定鞋子的轮廓和区块颜色重建鞋子图像。
(2) 定义函数,用于从图像中获取边缘:
def detect_edges(img):img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)img_gray = cv2.bilateralFilter(img_gray, 5, 50, 50)img_gray_edges = cv2.Canny(img_gray, 45, 100)img_gray_edges = cv2.bitwise_not(img_gray_edges) # invert black/whiteimg_edges = cv2.cvtColor(img_gray_edges, cv2.COLOR_GRAY2RGB)return img_edges
在以上代码中,利用 OpenCV
中可用的方法获取图像中的边缘。
(3) 定义图像转换管道,用于预处理和归一化:
IMAGE_SIZE = 256preprocess = transforms.Compose([transforms.Lambda(lambda x: torch.Tensor(x.copy()).permute(2, 0, 1).to(device))
])normalize = lambda x: (x - 127.5)/127.5
(4) 定义数据集类 ShoesData
,该数据集类返回原始图像和边缘图像。同时,我们将随机选择的区块中出现的颜色传递到网络中,通过这种方式,能够在图像的不同部分添加所需的颜色,并生成新图像,示例输入(第三张图像)和输出(第一张图像)如下图所示:
输入图像是原始鞋子图像(第一张图像),使用原始图像可以提取鞋子的边缘(第二张图像),接下来,通过在边缘图像中添加颜色获取输入(第三张图像)-输出(第一张图像)
组合。接下来,构建 ShoesData
类,接受输入轮廓图像,添加颜色,并返回带有色彩的轮廓图和原始鞋子图像。
定义 ShoesData
类、__init__
方法和 __len__
方法:
class ShoesData(Dataset):def __init__(self, items):self.items = itemsdef __len__(self):return len(self.items)
定义 __getitem__
方法,处理输入图像以获取边缘图像,然后添加原始图像中存在的颜色。首先获取给定图像的边缘:
def __getitem__(self, ix):f = self.items[ix]try: im = cv2.imread(f, 1)except:blank = preprocess(np.ones((IMAGE_SIZE, IMAGE_SIZE, 3), dtype="uint8"))return blank, blankedges = detect_edges(im)
调整图像大小并规范化图像:
im, edges = cv2.resize(im, (IMAGE_SIZE,IMAGE_SIZE)), cv2.resize(edges, (IMAGE_SIZE,IMAGE_SIZE))im, edges = normalize(im), normalize(edges)
在边缘图像 edges
上添加颜色,并使用函数 preprocess
预处理原始图像和边缘图像:
self._draw_color_circles_on_src_img(edges, im)im, edges = preprocess(im), preprocess(edges)return edges, im
定义添加颜色的函数:
def _draw_color_circles_on_src_img(self, img_src, img_target):non_white_coords = self._get_non_white_coordinates(img_target)for center_y, center_x in non_white_coords:self._draw_color_circle_on_src_img(img_src, img_target, center_y, center_x)def _get_non_white_coordinates(self, img):non_white_mask = np.sum(img, axis=-1) < 2.75non_white_y, non_white_x = np.nonzero(non_white_mask)# randomly sample non-white coordinatesn_non_white = len(non_white_y)n_color_points = min(n_non_white, 300)idxs = np.random.choice(n_non_white, n_color_points, replace=False)non_white_coords = list(zip(non_white_y[idxs], non_white_x[idxs]))return non_white_coordsdef _draw_color_circle_on_src_img(self, img_src, img_target, center_y, center_x):assert img_src.shape == img_target.shape, "Image source and target must have same shape."y0, y1, x0, x1 = self._get_color_point_bbox_coords(center_y, center_x)color = np.mean(img_target[y0:y1, x0:x1], axis=(0, 1))img_src[y0:y1, x0:x1] = colordef _get_color_point_bbox_coords(self, center_y, center_x):radius = 2y0 = max(0, center_y-radius+1)y1 = min(IMAGE_SIZE, center_y+radius)x0 = max(0, center_x-radius+1)x1 = min(IMAGE_SIZE, center_x+radius)return y0, y1, x0, x1def choose(self):return self[random.randint(len(self))]
(5) 定义训练、验证数据对应的数据集和数据加载器:
from sklearn.model_selection import train_test_split
train_items, val_items = train_test_split(glob('ShoeV2_photo/*.png'), test_size=0.2, random_state=2)
trn_ds, val_ds = ShoesData(train_items), ShoesData(val_items)trn_dl = DataLoader(trn_ds, batch_size=16, shuffle=True)
val_dl = DataLoader(val_ds, batch_size=16, shuffle=True)
(6) 定义生成网络和判别网络架构,利用权重初始化函数 (weights_init_normal
),上采样模块 (UNetDown
) 和下采样模块 (UNetUp
) 定义 GeneratorUNet
和 Discriminator
体系结构。
初始化权重,使其服从正态分布:
def weights_init_normal(m):classname = m.__class__.__name__if classname.find("Conv") != -1:torch.nn.init.normal_(m.weight.data, 0.0, 0.02)elif classname.find("BatchNorm2d") != -1:torch.nn.init.normal_(m.weight.data, 1.0, 0.02)torch.nn.init.constant_(m.bias.data, 0.0)
定义 UNetwDown
和 UNetUp
类:
class UNetDown(nn.Module):def __init__(self, in_size, out_size, normalize=True, dropout=0.0):super(UNetDown, self).__init__()layers = [nn.Conv2d(in_size, out_size, 4, 2, 1, bias=False)]if normalize:layers.append(nn.InstanceNorm2d(out_size))layers.append(nn.LeakyReLU(0.2))if dropout:layers.append(nn.Dropout(dropout))self.model = nn.Sequential(*layers)def forward(self, x):return self.model(x)class UNetUp(nn.Module):def __init__(self, in_size, out_size, dropout=0.0):super(UNetUp, self).__init__()layers = [nn.ConvTranspose2d(in_size, out_size, 4, 2, 1, bias=False),nn.InstanceNorm2d(out_size),nn.ReLU(inplace=True),]if dropout:layers.append(nn.Dropout(dropout))self.model = nn.Sequential(*layers)def forward(self, x, skip_input):x = self.model(x)x = torch.cat((x, skip_input), 1)return x
定义 GeneratorUNet
类:
class GeneratorUNet(nn.Module):def __init__(self, in_channels=3, out_channels=3):super(GeneratorUNet, self).__init__()self.down1 = UNetDown(in_channels, 64, normalize=False)self.down2 = UNetDown(64, 128)self.down3 = UNetDown(128, 256)self.down4 = UNetDown(256, 512, dropout=0.5)self.down5 = UNetDown(512, 512, dropout=0.5)self.down6 = UNetDown(512, 512, dropout=0.5)self.down7 = UNetDown(512, 512, dropout=0.5)self.down8 = UNetDown(512, 512, normalize=False, dropout=0.5)self.up1 = UNetUp(512, 512, dropout=0.5)self.up2 = UNetUp(1024, 512, dropout=0.5)self.up3 = UNetUp(1024, 512, dropout=0.5)self.up4 = UNetUp(1024, 512, dropout=0.5)self.up5 = UNetUp(1024, 256)self.up6 = UNetUp(512, 128)self.up7 = UNetUp(256, 64)self.final = nn.Sequential(nn.Upsample(scale_factor=2),nn.ZeroPad2d((1, 0, 1, 0)),nn.Conv2d(128, out_channels, 4, padding=1),nn.Tanh(),)def forward(self, x):d1 = self.down1(x)d2 = self.down2(d1)d3 = self.down3(d2)d4 = self.down4(d3)d5 = self.down5(d4)d6 = self.down6(d5)d7 = self.down7(d6)d8 = self.down8(d7)u1 = self.up1(d8, d7)u2 = self.up2(u1, d6)u3 = self.up3(u2, d5)u4 = self.up4(u3, d4)u5 = self.up5(u4, d3)u6 = self.up6(u5, d2)u7 = self.up7(u6, d1)return self.final(u7)
定义判别网络类 Discriminator
:
class Discriminator(nn.Module):def __init__(self, in_channels=3):super(Discriminator, self).__init__()def discriminator_block(in_filters, out_filters, normalization=True):"""Returns downsampling layers of each discriminator block"""layers = [nn.Conv2d(in_filters, out_filters, 4, stride=2, padding=1)]if normalization:layers.append(nn.InstanceNorm2d(out_filters))layers.append(nn.LeakyReLU(0.2, inplace=True))return layersself.model = nn.Sequential(*discriminator_block(in_channels * 2, 64, normalization=False),*discriminator_block(64, 128),*discriminator_block(128, 256),*discriminator_block(256, 512),nn.ZeroPad2d((1, 0, 1, 0)),nn.Conv2d(512, 1, 4, padding=1, bias=False))def forward(self, img_A, img_B):img_input = torch.cat((img_A, img_B), 1)return self.model(img_input)
(7) 定义生成网络和判别网络模型对象:
from torchsummary import summary
generator = GeneratorUNet().to(device)
discriminator = Discriminator().to(device)
(8) 定义判别网络训练函数 discriminator_train_step
。
判别网络训练函数将源图像 (real_src
)、真实图像目标输出 (real_trg
)、生成图像目标输出 (fake_trg
)、损失函数 (criterion_GAN
) 和判别网络优化器 (d_optimizer
) 作为输入:
def discriminator_train_step(real_src, real_trg, fake_trg, criterion_GAN, d_optimizer):#discriminator.train()d_optimizer.zero_grad()
通过比较真实图像的真实值 (real_trg
) 和预测值 (real_src
) 计算损失 (error_real
),其期望判别网络将图像预测为真实图像(由 torch.ones
表示),然后执行反向传播:
prediction_real = discriminator(real_trg, real_src)error_real = criterion_GAN(prediction_real, torch.ones(len(real_src), 1, 16, 16).cuda())error_real.backward()
计算与生成图像 (fake_trg
) 对应的判别网络损失 (error_fake
),其期望判别网络将生成图像目标分类为伪造图像(由 torch.zeros
表示),然后执行反向传播:
prediction_fake = discriminator(fake_trg.detach(), real_src)error_fake = criterion_GAN(prediction_fake, torch.zeros(len(real_src), 1, 16, 16).cuda())error_fake.backward()
优化模型权重,并返回预测的真实图像和生成图像的总损失:
d_optimizer.step()return error_real + error_fake
(9) 定义函数训练生成网络 (generator_train_step
),其获取生成图像目标 (fake_trg
) 并进行训练,使其在通过判别网络时被识别为生成图像的概率较低:
def generator_train_step(real_src, real_trg, fake_trg, criterion_GAN, criterion_pixelwise, lambda_pixel, g_optimizer):#discriminator.train()g_optimizer.zero_grad()prediction = discriminator(fake_trg, real_src)loss_GAN = criterion_GAN(prediction, torch.ones(len(real_src), 1, 16, 16).cuda())loss_pixel = criterion_pixelwise(fake_trg, real_trg)loss_G = loss_GAN + lambda_pixel * loss_pixelloss_G.backward()g_optimizer.step()return loss_G
在以上代码中,除了生成网络损失之外,我们还获取与给定轮廓的生成图像和真实图像之间的差异相对应的像素损失 (loss_pixel
)。
(10) 定义函数获取预测样本:
denorm = transforms.Normalize((-1, -1, -1), (2, 2, 2))
def sample_prediction():"""Saves a generated sample from the validation set"""data = next(iter(val_dl))real_src, real_trg = datafake_trg = generator(real_src)img_sample = torch.cat([denorm(real_src[0]), denorm(fake_trg[0]), denorm(real_trg[0])], -1)img_sample = img_sample.detach().cpu().permute(1,2,0).numpy()plt.imshow(img_sample)plt.title('Source::Generated::GroundTruth')plt.show()
(11) 对生成网络和判别网络模型对象应用权重初始化函数 (weights_init_normal
):
generator = GeneratorUNet().to(device)
discriminator = Discriminator().to(device)
generator.apply(weights_init_normal)
discriminator.apply(weights_init_normal)
(12) 指定损失计算方法和优化器 (criteria_GAN 和 criteria_pixelwise
):
criterion_GAN = torch.nn.MSELoss()
criterion_pixelwise = torch.nn.L1Loss()lambda_pixel = 100
g_optimizer = torch.optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
d_optimizer = torch.optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))
(13) 训练模型:
val_dl = DataLoader(val_ds, batch_size=1, shuffle=True)epochs = 100
# log = Report(epochs)
d_loss_epoch = []
g_loss_epoch = []
for epoch in range(epochs):N = len(trn_dl)d_loss_items = []g_loss_items = []for bx, batch in enumerate(trn_dl):real_src, real_trg = batchfake_trg = generator(real_src)errD = discriminator_train_step(real_src, real_trg, fake_trg, criterion_GAN, d_optimizer)errG = generator_train_step(real_src, real_trg, fake_trg, criterion_GAN, criterion_pixelwise, lambda_pixel, g_optimizer)d_loss_items.append(errD.item())g_loss_items.append(errG.item())d_loss_epoch.append(np.average(d_loss_items))g_loss_epoch.append(np.average(g_loss_items))
(14) 在样本轮廓图像上生成图像:
[sample_prediction() for _ in range(2)]
在上图中可以看出,模型能够生成与原始图像颜色相似的图像。
小结
Pix2Pix
是强大的图像转换框架,通过对抗训练和 U-Net
结构,使得生成网络能够将输入图像转换为与之对应的输出图像。同时在训练过程中,引入了像素级损失衡量生成图像与目标图像之间的像素级差异,促使生成网络生成更加细致和逼真的图像。本节中,介绍了 Pix2Pix
的模型训练流程,并使用 ShoeV2
数据集训练了一个 Pix2Pix
模型根据边缘图像生成鞋子图像。
系列链接
PyTorch深度学习实战(1)——神经网络与模型训练过程详解
PyTorch深度学习实战(2)——PyTorch基础
PyTorch深度学习实战(3)——使用PyTorch构建神经网络
PyTorch深度学习实战(4)——常用激活函数和损失函数详解
PyTorch深度学习实战(5)——计算机视觉基础
PyTorch深度学习实战(6)——神经网络性能优化技术
PyTorch深度学习实战(7)——批大小对神经网络训练的影响
PyTorch深度学习实战(8)——批归一化
PyTorch深度学习实战(9)——学习率优化
PyTorch深度学习实战(10)——过拟合及其解决方法
PyTorch深度学习实战(11)——卷积神经网络
PyTorch深度学习实战(12)——数据增强
PyTorch深度学习实战(13)——可视化神经网络中间层输出
PyTorch深度学习实战(14)——类激活图
PyTorch深度学习实战(15)——迁移学习
PyTorch深度学习实战(16)——面部关键点检测
PyTorch深度学习实战(17)——多任务学习
PyTorch深度学习实战(18)——目标检测基础
PyTorch深度学习实战(19)——从零开始实现R-CNN目标检测
PyTorch深度学习实战(20)——从零开始实现Fast R-CNN目标检测
PyTorch深度学习实战(21)——从零开始实现Faster R-CNN目标检测
PyTorch深度学习实战(22)——从零开始实现YOLO目标检测
PyTorch深度学习实战(23)——使用U-Net架构进行图像分割
PyTorch深度学习实战(24)——从零开始实现Mask R-CNN实例分割
PyTorch深度学习实战(25)——自编码器(Autoencoder)
PyTorch深度学习实战(26)——卷积自编码器(Convolutional Autoencoder)
PyTorch深度学习实战(27)——变分自编码器(Variational Autoencoder, VAE)
PyTorch深度学习实战(28)——对抗攻击(Adversarial Attack)
PyTorch深度学习实战(29)——神经风格迁移
PyTorch深度学习实战(30)——Deepfakes
PyTorch深度学习实战(31)——生成对抗网络(Generative Adversarial Network, GAN)
PyTorch深度学习实战(32)——DCGAN详解与实现
PyTorch深度学习实战(33)——条件生成对抗网络(Conditional Generative Adversarial Network, CGAN)
相关文章:

PyTorch深度学习实战(34)——Pix2Pix详解与实现
PyTorch深度学习实战(34)——Pix2Pix详解与实现 0. 前言1. 模型与数据集1.1 Pix2Pix 基本原理1.2 数据集分析1.3 模型构建策略 2. 实现 Pix2Pix 生成图像小结系列链接 0. 前言 Pix2Pix 是基于生成对抗网络 (Convolutional Generative Adversarial Netwo…...

第96讲:MySQL高可用集群MHA的核心概念以及集群搭建
文章目录 1.MHA高可用数据库集群的核心概念1.1.主从复制架构的演变1.2.MHA简介以及架构1.3.MHA的软件结构1.4.MHA Manager组件的启动过程1.5.MHA高可用集群的原理 2.搭建MHA高可用数据库集群2.1.环境架构简介2.2.搭建基于GTID的主从复制集群2.2.1.在三台服务器中分别搭建MySQL实…...

外星人入侵(python)
前言 代码来源《python编程从入门到实践》Eric Matthes 署 袁国忠 译 使用软件:PyCharm Community Editor 2022 目的:记录一下按照书上敲的代码 alien_invasion.py 游戏的一些初始化设置,调用已经封装好的函数方法,一个函数的…...

Unity中开发程序打包发布
添加ESC脚本 使用Unity打包发布的过程中,考虑到打开的程序会处于全屏界面,而此时我们又会有退出全屏的需求,因此需要添加ESC脚本,当我们单击ESC脚本的过程中,退出全屏模式。 在Assets/Scenes下,创建esc.cs…...

2024.2.1日总结
web的运行原理: 用户通过浏览器发送HTTP请求到服务器(网页操作)。web服务器接收到用户特定的HTTP请求,由web服务器请求信息移交给在web服务器中部署的javaweb应用程序(Java程序)。启动javaweb应用程序执行…...
LeetCode解法汇总2670. 找出不同元素数目差数组
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 描述: 给你一个下…...

STM32目录结构
之前一直头疼的32目录,比51复杂,又没有C规律,也不像python脚本文件关联不强,也不像工整的FPGA工程,编的时候到处放,爆出的错千奇百怪。短暂整理了一个,还是没有理得很轻。 startup_stm32f10x_m…...
算法专题:记忆搜索
参考练习习题总集 文章目录 前置知识练习习题87. 扰乱字符串97. 交错字符串375. 猜数字大小II403. 青蛙过河464. 我能赢吗494. 目标和552. 学生出勤记录II576. 出借的路径数 前置知识 没有什么特别知识,只有一些做题经验。要做这类型的题目,首先写出暴…...

【数据分享】1929-2023年全球站点的逐日最低气温数据(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、湿度等指标,其中又以气温指标最为常用!说到气温数据,最详细的气温数据是具体到气象监测站点的气温数据! 之前我们分享过1929-2023年全球气象站…...
2024美赛数学建模D题思路+模型+代码+论文(持续更新)
2024美赛数学建模A题B题C题D题E题F题思路模型代码论文:开赛后第一时间更新,获取见文末名片 组队环节: 美赛最多是3个人参赛,一般的队伍都是由三人组成(当然如果你很大佬也可以一个人参赛),队伍…...

dubbo+sentinel最简集成实例
说明 在集成seata后,下面来集成sentinel进行服务链路追踪管理~ 背景 sample-front网关服务已配置好 集成 一、启动sentinel.jar 1、官网下载 选择1:在本地启动 nohup java -Dserver.port8082 -Dcsp.sentinel.dashboard.serverlocalhost:8082 -Dp…...

9.2爬楼梯(LC70-E)
算法: 多举几个例子,找规律: 爬到第一层楼梯有一种方法,爬到二层楼梯有两种方法。 那么第一层楼梯再跨两步就到第三层 ,第二层楼梯再跨一步就到第三层(时序)。 所以到第三层楼梯的状态可以由…...

Asp.net移除Server, X-Powered-By, 和X-AspNet-Version头
移除X-AspNet-Version很简单,只需要在Web.config中增加这个配置节: <httpRuntime enableVersionHeader"false" />移除Server在Global.asax文件总增加: //隐藏IIS版本 protected void Application_PreSendRequestHeaders() {HttpContext.Current.Res…...

reactnative 调用原生ui组件
reactnative 调用原生ui组件 1.该样例已textView,介绍。 新建MyTextViewManager 文件,继承SimpleViewManager。import android.graphics.Color; import andr…...
面试手写第五期
文章目录 一. 实现一个函数用来对 URL 的 querystring 进行编码二. 如何实现一个数组洗牌函数 shuffle三. 异步加法的几种方式四. 实现trim函数五. 求多个数组的交集六. 手写实现render函数七. 驼峰转- -转驼峰八. instanceof实现九. 组合问题十. 字符串分组 一. 实现一个函数用…...

【CSS】css选择器和css获取第n个元素(:nth-of-type(n)、:nth-child(n)、first-child和last-child)
:nth-of-type、:nth-child的区别 一、css选择器二、:nth-of-type、:nth-child的区别:nth-of-type(n):选择器匹配属于父元素的特定类型的第N个子元素:nth-child(n):选择器匹配属于其父元素的第 N 个子元素,不论元素的类型:first-child…...

解析Excel文件内容,按每列首行元素名打印出某个字符串的统计占比(超详细)
目录 1.示例: 1.1 实现代码1:列数为常量 运行结果: 1.2 实现代码2:列数为变量 运行结果: 1.示例: 开发需求:读取Excel文件,统计第3列到第5列中每列的"False"字段占…...

qt中遇到[Makfile.Debug:119:debug/app.res.o] Error 1的原因以及解决方法
当我们将项目已到本地qt环境中会出现下图的代码错误 解决方法:在主界面中,点击左边的项目栏,选择构建设置,看Shadow build下面的路径是否为中文,改成英文,或者直接将Shadow build这个 √ 去掉就行了,如图已…...
pytorch调用gpu训练的流程以及示例
首先需要确保系统上安装了CUDA支持的NVIDIA GPU和相应的驱动程序。 基本步骤如下 检查CUDA是否可用: 使用 torch.cuda.is_available() 来检查CUDA是否可用。 指定设备: 可以使用 torch.device(“cuda:0”) 来指定要使用的GPU。如果系统有多个GPU&…...

学习Android的第一天
目录 什么是 Android? Android 官网 Android 应用程序 Android 开发环境搭建 Android 平台架构 Android 应用程序组件 附件组件 Android 第一个程序 HelloWorld 什么是 Android? Android(发音为[ˈnˌdrɔɪd],非官方中文…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...