G4周:CGAN,手势生成

 本文为🔗365天深度学习训练营 中的学习记录博客
 原作者:K同学啊|接辅导、项目定制

我的环境:

1.语言:python3.7

2.编译器:pycharm

3.深度学习框架Pytorch 1.8.0+cu111


一、CGAN介绍

条件生成对抗网络(Conditional Generative Adversarial Network,简称cGAN)是一种深度学习模型,属于生成对抗网络(GAN)的一种变体。它的基本思想是通过训练生成器和判别器两个网络,使生成器能够生成与给定条件相匹配的合成数据,而判别器则负责区分真实数据和生成数据。cGAN在生成器和判别器的结构上引入了条件信息,使得生成过程可以受到外部条件的控制。

cGAN的结构包括两个主要部分:

  1. 生成器(Generator): 生成器负责从随机噪声和条件信息中生成合成数据。与普通的生成器不同的是,cGAN的生成器除了接收随机噪声作为输入,还接受一个条件向量,这个条件向量可以是任何有助于生成特定类型数据的信息,例如类别标签、图像特征等。生成器的目标是生成尽可能逼真的数据,使得判别器难以区分生成的数据和真实数据。

  2. 判别器(Discriminator): 判别器负责区分生成器生成的数据和真实数据。它接收真实数据和生成器生成的数据,通过学习鉴别两者的差异,从而推动生成器生成更逼真的数据。与生成器一样,判别器也接收条件向量,以帮助区分不同条件下的数据。

cGAN的训练过程是一个动态平衡的过程。生成器和判别器相互竞争,通过对抗的方式逐渐提升生成器生成真实样本的能力,同时判别器也不断提高对生成样本和真实样本的辨别能力。

cGAN在图像生成、图像编辑、风格转换等任务上取得了显著的成果,其能够根据给定条件生成具有语义信息的合成数据,为许多应用领域提供了强大的工具。

条件生成对抗网络(cGAN)有一些显著的特点,使其在许多任务中表现出色。以下是一些关键特点:

  1. 条件输入: cGAN引入了条件输入,使得生成器可以受到外部条件的指导。这个条件可以是任何形式的信息,例如类别标签、文本描述、图像特征等。这使得生成的结果更有针对性和语义合理性。

  2. 有监督学习: 由于条件信息的引入,cGAN在一些任务中可以进行有监督学习。通过提供真实样本的标签作为条件,生成器可以学习生成与给定标签相对应的合成数据,从而在特定任务上取得更好的性能。

  3. 图像到图像的转换: cGAN在图像生成任务中表现出色,特别是在图像到图像的转换任务上,例如图像翻译、风格迁移、超分辨率等。通过条件信息,生成器可以更好地理解并保留输入图像的语义结构。

  4. 样本多样性: cGAN的生成过程是基于随机噪声的,因此可以生成多样性的结果。在相同的条件下,生成器可以产生多个不同但符合条件的合成样本。

  5. 对抗训练: cGAN通过生成器和判别器的对抗训练,使得两者相互竞争,逐渐提升生成器的能力同时提高判别器的辨别能力。这种对抗训练的方式有助于生成更逼真的合成数据。

  6. 无监督学习: 虽然cGAN可以进行有监督学习,但它也可以在无监督设置下进行训练。在无监督学习中,生成器可以学习从随机噪声中生成逼真的数据,而无需额外的条件信息。

总体而言,cGAN以其能够根据条件信息生成具有高语义合理性和多样性的数据而著称,广泛应用于图像生成和转换任务。

二、准备工作

import torch
import numpy as np
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets,transforms
from torch.autograd import Variable
from torchvision.utils import save_image
from torchvision.utils import make_grid
from torchsummary import summary
import matplotlib.pyplot as pltdevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

1、导入数据

train_transform = transforms.Compose([transforms.Resize(int(128* 1.12)),   ## 图片放大1.12倍transforms.RandomCrop((128, 128)),     ## 随机裁剪成原来的大小transforms.ToTensor(),transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])])train_dataset = datasets.ImageFolder(root='E:/GAN/G3/rps/', transform=train_transform)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True,num_workers=6)

Resize与RandomCrop:将图像先放大再随机裁剪,有利于防止过拟合,获得更好的泛化能力。

ToTensor(): 将图像转换为 PyTorch 的张量(tensor)格式。

Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]): 对图像进行标准化,将其像素值归一化到 [-1, 1] 的范围。这里的参数分别是均值和标准差。

2、数据可视化

def show_images(dl):for images,_ in dl:fig,ax = plt.subplots(figsize=(10,10))ax.set_xticks([]);ax.set_yticks([])ax.imshow(make_grid(images.detach(),nrow=16).permute(1,2,0))breakshow_images(train_loader)

 

这段代码定义了一个名为 show_images 的函数,该函数接受一个 DataLoader 对象 dl 作为参数。在函数内部,通过迭代 DataLoader 中的每个批次数据(images,_),进行以下操作:

  1. 创建一个图形对象 fig 和轴对象 ax,设置图形大小为 (10,10)。
  2. 禁用坐标轴的刻度。
  3. 使用 make_grid 函数将批次中的图像以16列的形式排列,并通过 permute(1,2,0) 调整维度顺序以适应 Matplotlib 图像显示的需求。
  4. 通过 ax.imshow 在轴上显示调整后的图像。
  5. 使用 break 语句,只显示 DataLoader 中的第一个批次,然后退出循环。

 

 三、构建模型

latent_dim = 100
n_classes = 3
embedding_dim = 100

weights_init用于权重初始化。

# 自定义权重初始化函数,用于初始化生成器和判别器的权重
def weights_init(m):# 获取当前层的类名classname = m.__class__.__name__# 如果当前层是卷积层(类名中包含 'Conv' )if classname.find('Conv') != -1:# 使用正态分布随机初始化权重,均值为0,标准差为0.02torch.nn.init.normal_(m.weight, 0.0, 0.02)# 如果当前层是批归一化层(类名中包含 'BatchNorm' )elif classname.find('BatchNorm') != -1:# 使用正态分布随机初始化权重,均值为1,标准差为0.02torch.nn.init.normal_(m.weight, 1.0, 0.02)# 将偏置项初始化为全零torch.nn.init.zeros_(m.bias)class Generator(nn.Module):def __init__(self):super(Generator, self).__init__()# 定义条件标签的生成器部分,用于将标签映射到嵌入空间中# n_classes:条件标签的总数# embedding_dim:嵌入空间的维度self.label_conditioned_generator = nn.Sequential(nn.Embedding(n_classes, embedding_dim),  # 使用Embedding层将条件标签映射为稠密向量nn.Linear(embedding_dim, 16)             # 使用线性层将稠密向量转换为更高维度)# 定义潜在向量的生成器部分,用于将噪声向量映射到图像空间中# latent_dim:潜在向量的维度self.latent = nn.Sequential(nn.Linear(latent_dim, 4*4*512),  # 使用线性层将潜在向量转换为更高维度nn.LeakyReLU(0.2, inplace=True)  # 使用LeakyReLU激活函数进行非线性映射)# 定义生成器的主要结构,将条件标签和潜在向量合并成生成的图像self.model = nn.Sequential(# 反卷积层1:将合并后的向量映射为64x8x8的特征图nn.ConvTranspose2d(513, 64*8, 4, 2, 1, bias=False),nn.BatchNorm2d(64*8, momentum=0.1, eps=0.8),  # 批标准化nn.ReLU(True),  # ReLU激活函数# 反卷积层2:将64x8x8的特征图映射为64x4x4的特征图nn.ConvTranspose2d(64*8, 64*4, 4, 2, 1, bias=False),nn.BatchNorm2d(64*4, momentum=0.1, eps=0.8),nn.ReLU(True),# 反卷积层3:将64x4x4的特征图映射为64x2x2的特征图nn.ConvTranspose2d(64*4, 64*2, 4, 2, 1, bias=False),nn.BatchNorm2d(64*2, momentum=0.1, eps=0.8),nn.ReLU(True),# 反卷积层4:将64x2x2的特征图映射为64x1x1的特征图nn.ConvTranspose2d(64*2, 64*1, 4, 2, 1, bias=False),nn.BatchNorm2d(64*1, momentum=0.1, eps=0.8),nn.ReLU(True),# 反卷积层5:将64x1x1的特征图映射为3x64x64的RGB图像nn.ConvTranspose2d(64*1, 3, 4, 2, 1, bias=False),nn.Tanh()  # 使用Tanh激活函数将生成的图像像素值映射到[-1, 1]范围内)def forward(self, inputs):noise_vector, label = inputs# 通过条件标签生成器将标签映射为嵌入向量label_output = self.label_conditioned_generator(label)# 将嵌入向量的形状变为(batch_size, 1, 4, 4),以便与潜在向量进行合并label_output = label_output.view(-1, 1, 4, 4)# 通过潜在向量生成器将噪声向量映射为潜在向量latent_output = self.latent(noise_vector)# 将潜在向量的形状变为(batch_size, 512, 4, 4),以便与条件标签进行合并latent_output = latent_output.view(-1, 512, 4, 4)# 将条件标签和潜在向量在通道维度上进行合并,得到合并后的特征图concat = torch.cat((latent_output, label_output), dim=1)# 通过生成器的主要结构将合并后的特征图生成为RGB图像image = self.model(concat)return imagegenerator = Generator().to(device)
generator.apply(weights_init)
print(generator)a = torch.ones(100)
b = torch.ones(1)
b = b.long()
a = a.to(device)
b = b.to(device)
import torch
import torch.nn as nnclass Discriminator(nn.Module):def __init__(self):super(Discriminator, self).__init__()# 定义一个条件标签的嵌入层,用于将类别标签转换为特征向量self.label_condition_disc = nn.Sequential(nn.Embedding(n_classes, embedding_dim),     # 嵌入层将类别标签编码为固定长度的向量nn.Linear(embedding_dim, 3*128*128)         # 线性层将嵌入的向量转换为与图像尺寸相匹配的特征张量)# 定义主要的鉴别器模型self.model = nn.Sequential(nn.Conv2d(6, 64, 4, 2, 1, bias=False),       # 输入通道为6(包含图像和标签的通道数),输出通道为64,4x4的卷积核,步长为2,padding为1nn.LeakyReLU(0.2, inplace=True),             # LeakyReLU激活函数,带有负斜率,增加模型对输入中的负值的感知能力nn.Conv2d(64, 64*2, 4, 3, 2, bias=False),    # 输入通道为64,输出通道为64*2,4x4的卷积核,步长为3,padding为2nn.BatchNorm2d(64*2, momentum=0.1, eps=0.8),  # 批量归一化层,有利于训练稳定性和收敛速度nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(64*2, 64*4, 4, 3, 2, bias=False),  # 输入通道为64*2,输出通道为64*4,4x4的卷积核,步长为3,padding为2nn.BatchNorm2d(64*4, momentum=0.1, eps=0.8),nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(64*4, 64*8, 4, 3, 2, bias=False),  # 输入通道为64*4,输出通道为64*8,4x4的卷积核,步长为3,padding为2nn.BatchNorm2d(64*8, momentum=0.1, eps=0.8),nn.LeakyReLU(0.2, inplace=True),nn.Flatten(),                               # 将特征图展平为一维向量,用于后续全连接层处理nn.Dropout(0.4),                            # 随机失活层,用于减少过拟合风险nn.Linear(4608, 1),                         # 全连接层,将特征向量映射到输出维度为1的向量nn.Sigmoid()                                # Sigmoid激活函数,用于输出范围限制在0到1之间的概率值)def forward(self, inputs):img, label = inputs# 将类别标签转换为特征向量label_output = self.label_condition_disc(label)# 重塑特征向量为与图像尺寸相匹配的特征张量label_output = label_output.view(-1, 3, 128, 128)# 将图像特征和标签特征拼接在一起作为鉴别器的输入concat = torch.cat((img, label_output), dim=1)# 将拼接后的输入通过鉴别器模型进行前向传播,得到输出结果output = self.model(concat)return output

 

  1. 条件标签的嵌入层:

    • self.label_condition_disc 是一个包含两个层的序列。首先是一个嵌入层 (nn.Embedding),用于将类别标签编码为固定长度的向量。然后是一个线性层 (nn.Linear),将嵌入的向量转换为与图像尺寸相匹配的特征张量。
  2. 主要的鉴别器模型:

    • self.model 是一个包含卷积层、批量归一化层、LeakyReLU激活函数、全连接层等的序列,构成了整个鉴别器的主体部分。
    • 输入通道为6,其中包括图像和经过嵌入层处理后的标签通道数。这是因为通过嵌入层后,标签被转换为一个与图像尺寸相匹配的特征张量。
    • 通过卷积层和下采样,网络逐渐减小特征图的空间尺寸。
    • 使用LeakyReLU激活函数,有助于网络对输入中的负值的感知能力。
    • 批量归一化层有助于训练的稳定性和收敛速度。
    • 使用Flatten将最终的特征图展平为一维向量,用于后续的全连接层处理。
    • Dropout层用于减少过拟合风险。
    • 最后的全连接层将特征向量映射到输出维度为1的向量,而Sigmoid激活函数用于输出范围限制在0到1之间的概率值。
  3. 前向传播方法 (forward):

    • 接受输入 inputs,其中包含图像 img 和标签 label
    • 类别标签通过条件标签的嵌入层转换为特征向量,并重塑为与图像尺寸相匹配的特征张量。
    • 将图像特征和标签特征在通道维度上拼接在一起,形成最终的输入。
    • 通过鉴别器模型进行前向传播,得到输出结果,即对输入图像的鉴别结果。

总体而言,这个鉴别器模型是一个基于卷积神经网络的条件GAN的组成部分,其设计旨在处理包含条件信息的图像数据。它通过将标签嵌入到特征向量中,并将其与图像特征拼接在一起,从而允许生成器和鉴别器之间的条件信息传递。

 

四、训练模型

1、损失函数

adversarial_loss = nn.BCELoss() def generator_loss(fake_output, label):gen_loss = adversarial_loss(fake_output, label)return gen_lossdef discriminator_loss(output, label):disc_loss = adversarial_loss(output, label)return disc_loss

2、优化器

learning_rate = 0.0002G_optimizer = optim.Adam(generator.parameters(),     lr = learning_rate, betas=(0.5, 0.999))
D_optimizer = optim.Adam(discriminator.parameters(), lr = learning_rate, betas=(0.5, 0.999))

3、训练模型

# 设置训练的总轮数
num_epochs = 100
# 初始化用于存储每轮训练中判别器和生成器损失的列表
D_loss_plot, G_loss_plot = [], []# 循环进行训练
for epoch in range(1, num_epochs + 1):# 初始化每轮训练中判别器和生成器损失的临时列表D_loss_list, G_loss_list = [], []# 遍历训练数据加载器中的数据for index, (real_images, labels) in enumerate(train_loader):# 清空判别器的梯度缓存D_optimizer.zero_grad()# 将真实图像数据和标签转移到GPU(如果可用)real_images = real_images.to(device)labels      = labels.to(device)# 将标签的形状从一维向量转换为二维张量(用于后续计算)labels = labels.unsqueeze(1).long()# 创建真实目标和虚假目标的张量(用于判别器损失函数)real_target = Variable(torch.ones(real_images.size(0), 1).to(device))fake_target = Variable(torch.zeros(real_images.size(0), 1).to(device))# 计算判别器对真实图像的损失D_real_loss = discriminator_loss(discriminator((real_images, labels)), real_target)# 从噪声向量中生成假图像(生成器的输入)noise_vector = torch.randn(real_images.size(0), latent_dim, device=device)noise_vector = noise_vector.to(device)generated_image = generator((noise_vector, labels))# 计算判别器对假图像的损失(注意detach()函数用于分离生成器梯度计算图)output = discriminator((generated_image.detach(), labels))D_fake_loss = discriminator_loss(output, fake_target)# 计算判别器总体损失(真实图像损失和假图像损失的平均值)D_total_loss = (D_real_loss + D_fake_loss) / 2D_loss_list.append(D_total_loss)# 反向传播更新判别器的参数D_total_loss.backward()D_optimizer.step()# 清空生成器的梯度缓存G_optimizer.zero_grad()# 计算生成器的损失G_loss = generator_loss(discriminator((generated_image, labels)), real_target)G_loss_list.append(G_loss)# 反向传播更新生成器的参数G_loss.backward()G_optimizer.step()# 打印当前轮次的判别器和生成器的平均损失print('Epoch: [%d/%d]: D_loss: %.3f, G_loss: %.3f' % ((epoch), num_epochs, torch.mean(torch.FloatTensor(D_loss_list)), torch.mean(torch.FloatTensor(G_loss_list))))# 将当前轮次的判别器和生成器的平均损失保存到列表中D_loss_plot.append(torch.mean(torch.FloatTensor(D_loss_list)))G_loss_plot.append(torch.mean(torch.FloatTensor(G_loss_list)))if epoch%10 == 0:# 将生成的假图像保存为图片文件save_image(generated_image.data[:50], './images/sample_%d' % epoch + '.png', nrow=5, normalize=True)# 将当前轮次的生成器和判别器的权重保存到文件torch.save(generator.state_dict(), './training_weights/generator_epoch_%d.pth' % (epoch))torch.save(discriminator.state_dict(), './training_weights/discriminator_epoch_%d.pth' % (epoch))
  1. 总轮次和损失记录初始化:

    • num_epochs 设置总的训练轮次。
    • D_loss_plotG_loss_plot 是用于存储每轮训练中判别器和生成器损失的列表。
  2. 训练循环:

    • 外层循环遍历每个训练轮次。
    • 内层循环遍历训练数据加载器中的每个批次。
  3. 判别器训练(Discriminator Training):

    • 清空判别器的梯度缓存。
    • 将真实图像数据和标签移到GPU(如果可用)。
    • 计算判别器对真实图像的损失(D_real_loss)。
    • 从噪声向量中生成假图像,并计算判别器对假图像的损失(D_fake_loss)。
    • 计算判别器总体损失(D_total_loss),是真实图像损失和假图像损失的平均值。
    • 反向传播更新判别器的参数。
  4. 生成器训练(Generator Training):

    • 清空生成器的梯度缓存。
    • 从噪声向量中生成假图像。
    • 计算生成器的损失(G_loss),这个损失是判别器对生成图像的输出与真实标签之间的误差。
    • 反向传播更新生成器的参数。
  5. 打印和记录损失:

    • 在每个训练轮次结束时,打印判别器和生成器的平均损失。
    • 将当前轮次的判别器和生成器的平均损失保存到列表中。
  6. 可选的保存操作:

    • 每隔10个训练轮次,生成一些假图像并将它们保存为图片文件。
    • 将当前轮次的生成器和判别器的权重保存到文件。

这段代码的目标是通过训练生成器和判别器来生成逼真的图像,其中生成器试图生成足够逼真的图像以欺骗判别器,而判别器则试图区分真实图像和生成图像。在训练的过程中,两者通过对抗学习逐渐提高性能。

五、生成指定图像

from numpy.random import randint, randn
from numpy import linspace
from matplotlib import pyplot as plt, gridspec
import numpy as np# Assuming 'generator' and 'device' are defined earlier in your codegenerator.load_state_dict(torch.load('E:/GAN/G4/generator_epoch_300.pth'), strict=False)
generator.eval()interpolated = randn(100)
interpolated = torch.tensor(interpolated).to(device).type(torch.float32)label = 0
labels = torch.ones(1) * label
labels = labels.to(device).unsqueeze(1).long()predictions = generator((interpolated, labels))
predictions = predictions.permute(0, 2, 3, 1).detach().cpu()import warnings
warnings.filterwarnings("ignore")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['figure.dpi'] = 100plt.figure(figsize=(8, 3))pred = (predictions[0, :, :, :] + 1) * 127.5
pred = np.array(pred)
plt.imshow(pred.astype(np.uint8))
plt.show()

   从已训练的生成器(generator)中加载参数,生成一张图像,并使用 Matplotlib 显示生成的图像。假设在代码的其他地方已经定义了生成器(generator)和设备(device)。这段代码加载预训练的生成器参数,并将生成器设置为评估模式(eval())。

  生成一个包含 100 个随机数的噪声向量(interpolated),将其转换为 PyTorch 张量并移到指定的设备上。同时,创建一个标签(label)并将其转换为 PyTorch 张量,最后在设备上调整形状和数据类型。

  使用生成器和生成的噪声与标签生成图像,并将图像的通道顺序调整为 Matplotlib 所需的顺序(通常是 HWC - Height, Width, Channel)。然后将图像的计算图分离(detach())并移动到 CPU 上。

  创建一个 Matplotlib 图形对象,将生成的图像进行处理,然后使用 plt.imshow 显示图像。最后,通过 plt.show() 将图形显示出来。

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

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

相关文章

Visio导出eps格式图片

Visio导出eps格式图片 文章目录 Visio导出eps格式图片1. Visio中使用Adobe Acrobat虚拟打印2. Adobe Acrobat中裁剪并另存为eps格式 如何使用Visio绘图然后导出.eps格式的图片呢?这个过程需要用到Adobe Acrobat,使用Adobe Acrobat的虚拟打印功能&#xf…

ssm基于JAVA的驾校信息管理系统设计论文

摘 要 信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古…

Java HashMap 面试题(一)

HashMap 面试题(一) 文章目录 HashMap 面试题(一)3.3 面试题-说一下HashMap的实现原理?面试题-HashMap的put方法的具体流程hashMap常见属性源码分析 3.3 面试题-说一下HashMap的实现原理? HashMap的数据结…

篇三:让OAuth2 server支持密码模式

由于Spring-Security-Oauth2停止维护&#xff0c;官方推荐采用 spring-security-oauth2-authorization-server&#xff0c;而后者默认不支持密码授权模式&#xff0c;本篇实战中采用的版本如下&#xff1a; <dependency><groupId>org.springframework.security<…

1-02VS的安装与测试

一、概述 对于一名C语言程序员而言&#xff0c;进行C语言程序的开发一般需要一个文本编辑器加上一个编译器就足够了。但为了方便起见&#xff0c;我们选择使用集成开发环境——Visual Studio&#xff08;简称VS&#xff09;。安装Visual Studio 下面讲一下如何安装VS&#xff0…

【AI视野·今日Sound 声学论文速览 第三十八期】Mon, 1 Jan 2024

AI视野今日CS.Sound 声学论文速览 Mon, 1 Jan 2024 Totally 5 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers The Arrow of Time in Music -- Revisiting the Temporal Structure of Music with Distinguishability and Unique Orientability as the …

金和OA C6 MailTemplates.aspx SQL注入漏洞复现

0x01 产品简介 金和OA协同办公管理系统软件(简称金和OA),本着简单、适用、高效的原则,贴合企事业单位的实际需求,实行通用化、标准化、智能化、人性化的产品设计,充分体现企事业单位规范管理、提高办公效率的核心思想,为用户提供一整套标准的办公自动化解决方案,以帮助…

【DevOps-07-3】Jenkins集成Sonarqube

一、简要说明 Jenkins安装Sonarqube插件Jenkins安装和配置Sonar-Scanner信息Jenkins打包项目中,增加Sonar-Scanner代码质量扫描二、Jenkins安装Sonarqube插件 1、登录Jenkins管理后台,搜索安装Sonar-Scanner插件 Jenkins管理后台示例:http://192.168.95.131:8080/jenkins/

Oracle数据库新手零基础入门,Oracle安装配置和操作使用详解

一、教程描述 本套教程是专门为初学者量身定制的&#xff0c;无需任何Oracle数据库基础&#xff0c;课程采用循序渐进的教学方式&#xff0c;从Oracle数据库的基础知识开始讲起&#xff0c;并不会直接涉及到一项具体的技术&#xff0c;而是随着课程的不断深入&#xff0c;一些…

docker部署mysql主从复制篇

环境准备&#xff1a;docker服务安装&#xff0c;mysql镜像 配置文件方式&#xff1a;可以挂载目录&#xff0c;也可以写好配置文件&#xff0c;利用docker cp 到容器内&#xff0c;这里直接在启动镜像创建容器时候挂载目录方式服务器上配置文件内容(下图标红路径)&#xff1a…

WEB 3D技术 three.js 顶点缩放

本文 我们来说 顶点缩放 我们官网搜索 BufferGeometry 下面有一个 scale 函数 例如 我们先将代码写成这样 上面图片和资源文件 大家需要自己去加一下 import ./style.css import * as THREE from "three"; import { OrbitControls } from "three/examples/j…

MySQL 临时表

MySQL 临时表 MySQL 临时表在我们需要保存一些临时数据时是非常有用的。 临时表只在当前连接可见&#xff0c;当关闭连接时&#xff0c;MySQL 会自动删除表并释放所有空间。 在 MySQL 中&#xff0c;临时表是一种在当前会话中存在的表&#xff0c;它在会话结束时会自动被销毁…

【教学类-09-04】20240102《游戏棋N*N》数字填写,制作棋子和骰子

作品展示 背景需求&#xff1a; 最近在清理学具材料库&#xff0c;找到一套1年多前的《N*N游戏棋》&#xff0c;把没有用完的棋盘拿出来&#xff0c;&#xff0c;想给大4班换花样&#xff0c;并把它们用掉。 程序代码在这里 【教学类-09-03】20221120《游戏棋10*10数字如何直接…

一篇五分生信临床模型预测文章代码复现——Figure 10.机制及肿瘤免疫浸润(九)——Estimate——倒数第二节

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…

马目标检测数据集VOC格式500张

马&#xff0c;一种优雅而强健的哺乳动物&#xff0c;以其独特的形态和特点而闻名于世。 马的体型高大&#xff0c;四肢修长&#xff0c;有着强健的肌肉和结实的骨骼。马头一般较长&#xff0c;眼睛炯炯有神&#xff0c;耳朵直立&#xff0c;鼻子和嘴巴都较大。毛发根据品种不…

黑马程序员SSM框架-Maven进阶

视频链接&#xff1a;Maven-01-分模块开发的意义_哔哩哔哩_bilibili 分模块开发与设计 分模块开发意义 分模块开发 依赖管理 依赖传递 依赖传递冲突问题 可以点击红框按钮查看依赖情况。 可选依赖和排除依赖 继承和聚合 聚合 聚合工程开发 继承 聚合和继承的区别 属性 属性…

大模型在现代应用中的多元实例

目录 前言1 GPT-3、GPT-3.5、GPT-4&#xff1a;自然语言处理的新纪元1.1 GPT-3与传统NLP方法的区别1.2 GPT-3.5 和 GPT-4 的进展1.3 技术背后的革新 2 自然语言转换为Python代码2.1 简介2.2 技术原理2.3 应用和优势 3 DALL-E 2&#xff08;5B&#xff09;图像生成3.1 简介3.2 技…

【Bootstrap学习 day11】

Bootstrap5字体图标 字体图标是在Web项目中使用的图标字体。 使用字体图标的好处是&#xff0c;可以通过应用CSS color属性来创建任何颜色的图标。此外&#xff0c;要更改图标的大小&#xff0c;只需使用CSS font-size属性即可。 获取字体图标 在网页中包含Bootstrap5图标的最…

深入了解Apache 日志,Apache 日志分析工具

Apache Web 服务器在企业中广泛用于托管其网站和 Web 应用程序&#xff0c;Apache 服务器生成的原始日志提供有关 Apache 服务器托管的网站如何处理用户请求以及访问您的网站时经常遇到的错误的重要信息。 什么是 Apache 日志 Apache 日志包含 Apache Web 服务器处理的所有事…

B+树索引及其原理

MySQL索引的底层结构是B树&#xff0c;为什么它会选择这个结构&#xff1f;联合索引是怎么实现的&#xff1f;最左侧匹配原则的原理是什么&#xff1f;本文将一一解答这些疑惑。 1 前置知识 在学习B树之前&#xff0c;我们先了解下其他的树形结构&#xff1a;二叉树、平衡二叉…