• 使用TensorFlow创建生成式对抗网络GAN案例【转】
    导入必要的库和模块以下是使用TensorFlow创建一个生成式对抗网络(GAN)的案例: 首先,我们需要导入必要的库和模块:import tensorflow as tf from tensorflow.keras import layers import matplotlib.pyplot as plt import numpy as np 然后,我们定义生成器和鉴别器模型。生成器模型将随机噪声作为输入,并输出伪造的图像。鉴别器模型则将图像作为输入,并输出一个0到1之间的概率值,表示输入图像是真实图像的概率。# 定义生成器模型 def make_generator_model():     model = tf.keras.Sequential()     model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))     model.add(layers.BatchNormalization())     model.add(layers.LeakyReLU())     model.add(layers.Reshape((7, 7, 256)))     assert model.output_shape == (None, 7, 7, 256)      model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))     assert model.output_shape == (None, 7, 7, 128)     model.add(layers.BatchNormalization())     model.add(layers.LeakyReLU())     model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))     assert model.output_shape == (None, 14, 14, 64)     model.add(layers.BatchNormalization())     model.add(layers.LeakyReLU())     model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))     assert model.output_shape == (None, 28, 28, 1)     return model # 定义鉴别器模型 def make_discriminator_model():     model = tf.keras.Sequential()     model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',                                      input_shape=[28, 28, 1]))     model.add(layers.LeakyReLU())     model.add(layers.Dropout(0.3))     model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))     model.add(layers.LeakyReLU())     model.add(layers.Dropout(0.3))     model.add(layers.Flatten())     model.add(layers.Dense(1))     return model 定义训练循环在每个epoch中,我们将随机生成一组噪声作为输入,并使用生成器生成伪造图像。然后,我们将真实图像和伪造图像一起传递给鉴别器,计算鉴别器和生成器的损失函数,并使用优化器更新模型参数。# 定义训练循环 @tf.function def train_step(images):     noise = tf.random.normal([BATCH_SIZE, 100])     with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:         generated_images = generator(noise, training=True)         real_output = discriminator(images, training=True)         fake_output = discriminator(generated_images, training=True)         gen_loss = generator_loss(fake_output)         disc_loss = discriminator_loss(real_output, fake_output)     gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)     gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)     generator_optimizer.appy_gradients(zip(gradients_of_generator, generator.trainable_variables))     discriminator_optimizer.appy_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables)) 最后定义主函数加载MNIST数据集并训练模型。# 加载数据集 (train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data() train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32') train_images = (train_images - 127.5) / 127.5  # 将像素值归一化到[-1, 1]之间 BUFFER_SIZE = 60000 BATCH_SIZE = 256 train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE) # 创建生成器和鉴别器模型 generator = make_generator_model() discriminator = make_discriminator_model() # 训练模型 EPOCHS = 100 noise_dim = 100 num_examples_to_generate = 16 # 用于可视化生成的图像 seed = tf.random.normal([num_examples_to_generate, noise_dim]) for epoch in range(EPOCHS):     for image_batch in train_dataset:         train_step(image_batch)     # 每个epoch结束后生成一些图像并可视化     generated_images = generator(seed, training=False)     fig = plt.figure(figsize=(4, 4))     for i in range(generated_images.shape[0]):         plt.subplot(4, 4, i+1)         plt.imshow(generated_images[i, :, :, 0] * 127.5 + 127.5, cmap='gray')         plt.axis('off')     plt.show() 
  • [技术干货] 使用Python对文件进行批量改名的方法【转】
    使用Python对文件进行批量改名Python在Windows系统下的路径表示回顾:反斜杠“\”是转义符,如果继续用windows习惯使用“\”表示文件路径,就会产生歧义。Windows下的原始路径:C:\Users\LUO\Documents\GitHub\CalculatorT3000\introduction所以在Python中有三种方法表示:path="C:\\Users\\LUO\\Documents\\GitHub\\CalculatorT3000\\introduction\\"       path=r'C:\Users\LUO\Documents\GitHub\CalculatorT3000\introduction\'path='C:/Users/LUO/Documents/GitHub/CalculatorT3000/introduction/'使用斜杠“/”: 'C:/Users/LUO/Documents/GitHub/CalculatorT3000/introduction/'  将反斜杠符号转义: "C:\\Users\\LUO\\Documents\\GitHub\\CalculatorT3000\\introduction\\"  因为反斜杠是转义符,所以两个"\\"就表示一个反斜杠符号 使用Python的raw string:r'C:\Users\LUO\Documents\GitHub\CalculatorT3000\introduction\'  python下在字符串前面加上字母r,表示后面是一个原始字符串raw string,不过raw string主要是为正则表达式而不是windows路径设计的,所以这种做法尽量少用,可能会出问题使用os 模块来处理文件和目录python 对文件进行批量改名用到的是 os 模块中的 listdir 方法和 rename 方法。os.listdir(dir) : 获取指定目录下的所有子目录和文件名os.rename(原文件名,新文件名) :os.rename(src, dst) 方法用于命名文件或目录,从 src 到 dst,如果dst是一个存在的目录, 将抛出OSErroros.renames() 方法用于递归重命名目录或文件。类似rename()os.renames(old, new)old -- 要重命名的目录new --文件或目录的新名字。甚至可以是包含在目录中的文件,或者完整的目录树os.getcwd() 返回当前工作目录os.path 模块主要用于获取文件的属性os.path.basename(path)返回文件名os.path.dirname(path)返回文件路径os.path.exists(path)如果路径 path 存在,返回 True;如果路径 path 不存在,返回 False。os.path.getmtime(path)返回最近文件修改时间os.path.getctime(path)返回文件 path 创建时间os.path.getsize(path)返回文件大小,如果文件不存在就返回错误os.path.isfile(path)判断路径是否为文件os.path.isdir(path)判断路径是否为目录os.path.samefile(path1, path2)判断目录或文件是否相同os.path.sameopenfile(fp1, fp2)判断fp1和fp2是否指向同一文件import os #三种路径表示方法 #path="C:\\Users\\LUO\\Documents\\GitHub\\CalculatorT3000\\introduction\\" #转义符的方式不能在此使用 #path=r'C:\Users\LUO\Documents\GitHub\CalculatorT3000\introduction\' #path='C:/Users/LUO/Documents/GitHub/CalculatorT3000/introduction/'   #从控制台输入 path=input("请输入需要改名的路径:") #判断路径是否存在 if os.path.exists(path):          #获取该目录下所有文件,存入列表中     fileList=os.listdir(path)       n=0     for i in fileList:                  #设置旧文件名(就是路径+文件名)         oldname=path+ os.sep + fileList[n]   # os.sep添加系统分隔符         #判断当前是否是文件         if os.path.isfile(oldname):                      #设置新文件名             newname=path + os.sep +'calc_'+str(n+1)+'.jpg'                              os.rename(oldname,newname)   #用os模块中的rename方法对文件改名             print(oldname,'======>',newname)                              n+=1   else:     print('路径不存在') 补充:使用python批量修改文件名使用python对文件名进行批量修改使用split方法对原文件名进行切分,选择需要的部分进行保留做为新的文件名,也可添加字段。函数说明split()函数语法:str.split(str="",num=string.count(str))[n]参数说明:str: 表示为分隔符,默认为空格,但是不能为空(’’)。若字符串中没有分隔符,则把整个字符串作为列表的一个元素num:表示分割次数。如果存在参数num,则仅分隔成 num+1 个子字符串,并且每一个子字符串可以赋给新的变量[n]: 表示选取第n个分片注意:当使用空格作为分隔符时,对于中间为空的项会自动忽略        import os import  re def changename(orignname):       picture=os.listdir(orignname)       for filename in picture:           # filename1 = filename.split(".")[0]           # filename2=re.findall(r"\d+\.?\d*", filename1)[0]+".png"           # srcpath = os.path.join(orignname,filename)           # allpath = os.path.join(orignname,filename2)           # os.rename(srcpath,allpath)            #split("_",2)[1]    “_”表示分隔符 ; 2表示分割次数 ; [1]表示选取第 i 个片段          filename1=filename.split("_")[3]          #设置旧文件名(就是路径+文件名)          srcpath=os.path.join(orignname,filename)          #设置新文件名          allpath= os.path.join(orignname,filename1)          os.rename(srcpath, allpath) if __name__ == '__main__':     orignname=r"D:\AK\GJ\dataset_2\val\labels"     changename(orignname)注意:该方法是直接覆盖原图的文件名,不另存,如果想要保留原文件名,请提前复制
  • [技术干货] Python调用系统命令的四种方法详解(os.system、os.popen、commands、subprocess)【转】
    一、os.system方法这个方法是直接调用标准C的system() 函数,仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息。os.system(cmd)的返回值。如果执行成功,那么会返回0,表示命令执行成功。否则,则是执行错误。使用os.system返回值是脚本的退出状态码,该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码,高位为脚本的退出状态码。os.system()返回值为0 linux命令返回值也为0。os.system()返回值为256,十六位二进制数示为:00000001,00000000,高八位转成十进制为 1 对应 linux命令返回值 1。os.system()返回值为512,十六位二进制数示为:00000010,00000000,高八位转成十进制为 2 对应 linux命令返回值 2。import os result = os.system('cat /etc/passwd') print(result)      # 0二、os.popen方法os.popen()方法不仅执行命令而且返回执行后的信息对象(常用于需要获取执行命令后的返回信息),是通过一个管道文件将结果返回。通过 os.popen() 返回的是 file read 的对象,对其进行读取 read() 的操作可以看到执行的输出。import os result = os.popen('cat /etc/passwd') print(result.read())三、commands模块import commands status = commands.getstatus('cat /etc/passwd') print(status) output = commands.getoutput('cat /etc/passwd') print(output) (status, output) = commands.getstatusoutput('cat /etc/passwd') print(status, output)四、subprocess模块Subprocess是一个功能强大的子进程管理模块,是替换os.system,os.spawn* 等方法的一个模块。当执行命令的参数或者返回中包含了中文文字,那么建议使用subprocess。import subprocess res = subprocess.Popen('cat /etc/passwd', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # 使用管道 print res.stdout.read()  # 标准输出 for line in res.stdout.readlines():     print line res.stdout.close()         # 关闭五、总结:os.system:获取程序执行命令的返回值。os.popen: 获取程序执行命令的输出结果。commands:获取返回值和命令的输出结果。
  • [技术干货] Vision Transformer图像分类模型导论【转】
    Vision Transformer(VIT)Vision Transformer(ViT)是一种新兴的图像分类模型,它使用了类似于自然语言处理中的Transformer的结构来处理图像。这种方法通过将输入图像分解成一组图像块,并将这些块变换为一组向量来处理图像。然后,这些向量被输入到Transformer编码器中,以便对它们进行进一步的处理。ViT在许多计算机视觉任务中取得了与传统卷积神经网络相当的性能,但其在处理大尺寸图像和长序列数据方面具有优势。与自然语言处理(NLP)中的Transformer模型类似,ViT模型也可以通过预训练来学习图像的通用特征表示。在预训练过程中,ViT模型通常使用自监督任务,如图像补全、颜色化、旋转预测等,以无需人工标注的方式对图像进行训练。这些任务可以帮助ViT模型学习到更具有判别性和泛化能力的特征表示,并为下游的计算机视觉任务提供更好的初始化权重。Patch EmbeddingsPatch embedding是Vision Transformer(ViT)模型中的一个重要组成部分,它将输入图像的块转换为向量,以便输入到Transformer编码器中进行处理。Patch embedding的过程通常由以下几个步骤组成:图像切片:输入图像首先被切成大小相同的小块,通常是16x16、32x32或64x64像素大小。这些块可以重叠或不重叠,取决于具体的实现方式。展平像素:每个小块内的像素被展平成一个向量,以便能够用于后续的矩阵计算。展平的像素向量的长度通常是固定的,与ViT的超参数有关。投影:接下来,每个像素向量通过一个可学习的线性变换(通常是一个全连接层)进行投影,以便将其嵌入到一个低维的向量空间中。拼接:最后,所有投影向量被沿着一个维度拼接在一起,形成一个大的二维张量。这个张量可以被看作是输入序列的一个矩阵表示,其中每一行表示一个图像块的嵌入向量。通过这些步骤,Patch embedding将输入的图像块转换为一组嵌入向量,这些向量可以被输入到Transformer编码器中进行进一步的处理。Patch embedding的设计使得ViT能够将输入图像的局部特征信息编码成全局特征,从而实现了对图像的整体理解和分类。Inductive bias在Vision Transformer(ViT)模型中,也存在着Inductive bias,它指的是ViT模型的设计中所假定的先验知识和偏见,这些知识和偏见可以帮助模型更好地学习和理解输入图像。ViT的Inductive bias主要包括以下几个方面:图像切片:ViT将输入图像划分为多个大小相同的块,每个块都是一个向量。这种切片方式的假设是,输入图像中的相邻区域之间存在着相关性,块内像素的信息可以被整合到一个向量中。线性投影:在Patch embedding阶段,ViT将每个块的像素向量通过线性投影映射到一个较低维度的向量空间中。这种映射方式的假设是,输入图像的特征可以被表示为低维空间中的点,这些点之间的距离可以捕捉到图像的局部和全局结构。Transformer编码器:ViT的编码器部分采用了Transformer结构,这种结构能够对序列中的不同位置之间的依赖关系进行建模。这种建模方式的假设是,输入图像块之间存在着依赖关系,这些依赖关系可以被利用来提高模型的性能。通过这些Inductive bias,ViT模型能够对输入图像进行有效的表示和学习。这些假设和先验知识虽然有一定的局限性,但它们可以帮助ViT更好地处理图像数据,并在各种计算机视觉任务中表现出色。Hybrid Architecture在ViT中,Hybrid Architecture是指将卷积神经网络(CNN)和Transformer结合起来,用于处理图像数据。Hybrid Architecture使用一个小的CNN作为特征提取器,将图像数据转换为一组特征向量,然后将这些特征向量输入Transformer中进行处理。CNN通常用于处理图像数据,因为它们可以很好地捕捉图像中的局部和平移不变性特征。但是,CNN对于图像中的全局特征处理却有一定的局限性。而Transformer可以很好地处理序列数据,包括文本数据中的全局依赖关系。因此,将CNN和Transformer结合起来可以克服各自的局限性,同时获得更好的图像特征表示和处理能力。在Hybrid Architecture中,CNN通常被用来提取局部特征,例如边缘、纹理等,而Transformer则用来处理全局特征,例如物体的位置、大小等。具体来说,Hybrid Architecture中的CNN通常只包括几层卷积层,以提取一组局部特征向量。然后,这些特征向量被传递到Transformer中,以捕捉它们之间的全局依赖关系,并输出最终的分类或回归结果。相对于仅使用Transformer或CNN来处理图像数据,Hybrid Architecture在一些图像任务中可以取得更好的结果,例如图像分类、物体检测等。Fine-tuning and higher resolution在ViT模型中,我们通常使用一个较小的分辨率的输入图像(例如224x224),并在预训练阶段将其分成多个固定大小的图像块进行处理。然而,当我们将ViT模型应用于实际任务时,我们通常需要处理更高分辨率的图像,例如512x512或1024x1024。为了适应更高分辨率的图像,我们可以使用两种方法之一或两种方法的组合来提高ViT模型的性能:Fine-tuning: 我们可以使用预训练的ViT模型来初始化网络权重,然后在目标任务的数据集上进行微调。这将使模型能够在目标任务中进行特定的调整和优化,并提高其性能。Higher resolution: 我们可以增加输入图像的分辨率来提高模型的性能。通过处理更高分辨率的图像,模型可以更好地捕捉细节信息和更全面的视觉上下文信息,从而提高模型的准确性和泛化能力。通过Fine-tuning和Higher resolution这两种方法的组合,我们可以有效地提高ViT模型在计算机视觉任务中的表现。这种方法已经在许多任务中取得了良好的结果,如图像分类、目标检测和语义分割等。PyTorch实现Vision Transformerimport torch import torch.nn as nn import torch.nn.functional as F from torchvision import transforms, datasets # 定义ViT模型 class ViT(nn.Module):     def __init__(self, image_size=224, patch_size=16, num_classes=1000, dim=768, depth=12, heads=12, mlp_dim=3072):         super(ViT, self).__init__()         # 输入图像分块         self.image_size = image_size         self.patch_size = patch_size         self.num_patches = (image_size // patch_size) ** 2         self.patch_dim = 3 * patch_size ** 2         self.proj = nn.Conv2d(3, dim, kernel_size=patch_size, stride=patch_size)         # Transformer Encoder         self.transformer_encoder = nn.TransformerEncoder(nn.TransformerEncoderLayer(d_model=dim, nhead=heads, dim_feedforward=mlp_dim), num_layers=depth)         # MLP head         self.layer_norm = nn.LayerNorm(dim)         self.fc = nn.Linear(dim, num_classes)     def forward(self, x):         # 输入图像分块         x = self.proj(x)         x = x.flatten(2).transpose(1, 2)         # Transformer Encoder         x = self.transformer_encoder(x)         # MLP head         x = self.layer_norm(x.mean(1))         x = self.fc(x)         return x # 加载CIFAR-10数据集 transform = transforms.Compose([transforms.Resize((224, 224)), transforms.ToTensor()]) train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=128, shuffle=False) # 实例化ViT模型 model = ViT() # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) # 训练模型 num_epochs = 10 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device) for epoch in range(num_epochs):     # 训练模式     model.train()     train_loss = 0.0     train_acc = 0.0     for images, labels in train_loader:         images, labels = images.to(device), labels.to(device)         # 前向传播         outputs = model(images)         loss = criterion(outputs, labels)         # 反向传播和优化         optimizer.zero_grad()         loss.backward()         optimizer.step()         # 统计训练损失和准确率         train_loss += loss.item() * images.size(0)         _, preds = torch.max(outputs, 1)         train_acc += torch.sum(preds == labels.data)     train_loss = train_loss / len(train_loader.dataset)     train_acc = train_acc 
  • [技术干货] Transformer导论之Bert预训练语言解析【转】
    BertBERT,全称为“Bidirectional Encoder Representations from Transformers”,是一种预训练语言表示的方法,意味着我们在一个大型文本语料库(如维基百科)上训练一个通用的“语言理解”模型,然后将该模型用于我们关心的下游NLP任务(如问答)。BERT的表现优于之前的传统NLP方法,因为它是第一个用于预训练NLP的无监督的、深度双向系统。Bert是利用无标签方式建模的,当谈到NLP语料库中的无标签和有标签数据时,一个常见的例子是将文本分类任务。下面是一个例子:无标签数据:来自维基百科的大量文本,这些文本没有被人工标记或者标注。这些数据可以用来预训练语言模型,例如 BERT、GPT 等,以学习通用的语言表示形式。有标签数据:例如 IMDB 电影评论数据集,其中每个评论都被标记为正面或负面情感。这些数据可以用来训练文本分类器,使其能够自动对新的评论进行情感分类。Bert的无监督预训练方法非常重要,因为它允许我们在大规模文本语料库中进行训练,而无需为每个具体的NLP任务收集大量的有标签数据。由于网络上有大量的无标签文本数据,这种方法使得BERT可以利用这些数据来训练模型,提高模型在各种任务上的表现。与此同时,无监督预训练还能够提高模型对于语言的理解和表达能力。BERT的无监督预训练方法使得我们可以使用一个通用的"语言理解"模型,用于各种NLP任务,如问答、文本分类、实体识别等,而无需为每个任务重新训练一个新的模型。BERT 的主要任务是通过训练模型来预测文本序列中缺失的单词,因此模型只需要对输入的文本序列进行编码,而不需要对序列进行解码。他只用到了Transformer中的Encoder。Pre-training BERTPre-training BERT(Bidirectional Encoder Representations from Transformers)是一种基于大规模无标注文本数据的预训练方法,目的是为了训练出一个通用的语言模型,能够理解上下文语境中词语的语义信息。在BERT的预训练过程中,使用了两个阶段的训练方式:Masked LM和Next Sentence Prediction。(1)Masked LM(MLM)Masked Language Modeling (MLM) 是 BERT 模型的一种预训练方法,通过将输入文本中的某些单词随机地替换成特殊的 [MASK] 标记,使模型在预测被替换的单词时需要依据上下文信息进行推断,从而学习到单词的上下文相关性。具体来说,对于输入文本中的每个单词,以一定的概率(比如15%)随机选择将其替换为 [MASK] 标记,然后将经过 [MASK] 标记处理后的文本输入给模型进行预测。在预测过程中,模型需要根据上下文信息猜测被 [MASK] 标记替换的单词。这样的预测任务可以促使模型学习到单词的上下文信息,从而提高下游任务的性能。例如,对于输入文本 "I went to the [MASK] to buy some apples",模型需要根据上下文信息猜测被 [MASK] 标记替换的单词是 "store","market","shop" 等。通过这样的预测任务,模型可以学习到 "store","market","shop" 在不同上下文中的含义和用法,从而提高下游任务(如文本分类、情感分析、问答等)的性能。因为采用上下文无关的方式进行建模,意味着模型不考虑单词在句子中的位置和上下文环境,而是将每个单词独立地编码为固定的向量表示。所以MLM是至关重要的,因为他学习了上下文的信息。(2)Next Sentence Prediction(NSP)Next Sentence Prediction (NSP) 是 BERT 中的另外一种预训练任务,用于训练模型学习句子之间的关系。它的目标是判断两个句子是否是相邻的,即判断一个句子是否是另一个句子的下一句。NSP 的训练过程中,对于每一对输入的句子,有一半是相邻的,另一半是随机选择的不相邻的句子。模型需要对这两种情况进行分类预测。这个任务主要是为了帮助模型学习更好的语义表示,尤其是对于需要理解多个句子之间关系的任务,如问答和文本推理。输入的文本会被分成多个token,每个token会被映射为一个向量表示,这个向量表示就被称为token embedding。除了token embedding之外,BERT还有另外两种embedding,分别是sentence embedding和positional embedding。Sentence embedding是对整个句子进行编码得到的向量表示。在BERT中,对于输入的句子对(比如问答场景下的问题和回答),BERT会将句子对之间的特殊标记“[SEP]”添加到中间,并在整个输入序列的开头添加另一个特殊标记“[CLS]”。然后,整个序列的第一个token对应的向量就是整个句子的sentence embedding。Positional embedding则是用来表示每个token在句子中的位置信息。由于Transformer并不保留输入中token的位置信息,因此需要在输入的token embedding中加入位置信息,使得Transformer能够捕捉到句子中token的位置信息。这里采用了一种相对位置编码的方式,将每个token与其他token的相对位置信息编码成一个向量,然后将该向量加到该token的embedding中。在BERT中,这三种embedding会被拼接在一起,然后送入Transformer进行编码。这些编码代表了符号句子位置的特征。通过使用 MLM 和 NSP 两个任务来预训练模型,BERT 能够学习到更加丰富的语言表示,这些表示可以在各种 NLP 任务中进行微调。Fine-tuning BERTFine-tuning BERT是指在使用预训练的BERT模型后,将其进一步调整以适应特定任务的过程。这个过程可以理解为在BERT的基础上进行微调以使其更加适合完成特定的自然语言处理(NLP)任务。Fine-tuning BERT的主要步骤如下:准备数据集:根据特定的NLP任务,准备相应的数据集,包括训练集、验证集和测试集。定义任务:根据任务类型,选择适当的BERT模型和Fine-tuning策略。对于分类任务,可以使用BERT的CLS向量来表示整个句子,并通过添加一个全连接层来预测标签。对于序列标注任务,可以在BERT的基础上添加一个序列标注层。Fine-tuning:将准备好的数据集输入BERT模型进行Fine-tuning。在Fine-tuning过程中,对BERT模型的参数进行微调,以适应特定的NLP任务。通常使用反向传播算法进行模型优化。模型评估:使用验证集评估Fine-tuning后的模型性能,可以根据验证集的性能调整Fine-tuning策略或BERT模型的超参数。最终,使用测试集评估模型的性能。需要注意的是,Fine-tuning BERT需要大量的计算资源和时间,因为BERT模型本身具有非常多的参数和复杂的结构。此外,Fine-tuning BERT的性能还取决于任务的复杂性、数据集的质量和模型的选择等因素。代码实现下面是使用PyTorch实现Bert模型的示例代码,包括模型定义、数据预处理、模型训练和推理:import torch import torch.nn as nn import torch.optim as optim import torch.utils.data as data import transformers # 1. 定义Bert模型 class BertModel(nn.Module):     def __init__(self, bert_config):         super(BertModel, self).__init__()         self.bert = transformers.BertModel(bert_config)         self.dropout = nn.Dropout(bert_config.hidden_dropout_prob)         self.fc = nn.Linear(bert_config.hidden_size, num_classes)     def forward(self, input_ids, attention_mask):         output = self.bert(input_ids=input_ids, attention_mask=attention_mask)         output = output[1]  # 取第1个tensor作为CLS向量         output = self.dropout(output)         output = self.fc(output)         return output # 2. 数据预处理 # 数据集包含输入序列和对应的标签 inputs = ["I love Python programming.", "Python is a high-level programming language."] labels = [0, 1]  # 0表示第1个句子不是关于Python编程的,1表示第2个句子是关于Python编程的 tokenizer = transformers.BertTokenizer.from_pretrained('bert-base-uncased') max_seq_length = 64  # 输入序列最大长度 inputs_ids = [] attention_masks = [] for input_text in inputs:     # 将文本转换为ids和attention mask     encoded_dict = tokenizer.encode_plus(         input_text,         add_special_tokens=True,         max_length=max_seq_length,         pad_to_max_length=True,         return_attention_mask=True,         return_tensors='pt'     )     inputs_ids.append(encoded_dict['input_ids'])     attention_masks.append(encoded_dict['attention_mask']) inputs_ids = torch.cat(inputs_ids, dim=0) attention_masks = torch.cat(attention_masks, dim=0) labels = torch.tensor(labels) # 3. 定义超参数和优化器 num_classes = 2 learning_rate = 2e-5 num_epochs = 3 batch_size = 2 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = BertModel(transformers.BertConfig.from_pretrained('bert-base-uncased')).to(device) optimizer = optim.Adam(model.parameters(), lr=learning_rate) # 4. 定义数据加载器 dataset = data.TensorDataset(inputs_ids, attention_masks, labels) dataloader = data.DataLoader(dataset, batch_size=batch_size, shuffle=True) # 5. 训练模型 model.train() for epoch in range(num_epochs):     for i, (input_ids_batch, attention_masks_batch, labels_batch) in enumerate(dataloader):         input_ids_batch = input_ids_batch.to(device)         attention_masks_batch = attention_masks_batch.to(device)         labels_batch = labels_batch.to(device)         optimizer.zero_grad()         outputs = model(input_ids_batch, attention_masks_batch)         loss = nn.CrossEntropyLoss()(outputs, labels_batch)         loss.backward()         optimizer.step()         if i % 10 == 0:             print(f"Epoch {epoch}, batch {i}, loss: {loss.item()}") # 6. 模型推理 model.eval() test_input = "Python is a popular programming language." encoded_dict = tokenizer.encode_plus(     test_input,     add_special_tokens 
  • [技术干货] python如何将txt文件的内容逐行读取转化成数组【转】
    将txt文件的内容逐行读取转化成数组例:将train5bottle.names的每行内容提取出来转化成数组转换代码:1234567891011result = [] with open(r'E:\HISI\darknet-master\build\darknet\x64\data\train5bottle.names' ,'r') as f:    for line in f:     result.append(line.strip().split(',')[0])  #a.append(b):是将b原封不动的追加到a的末尾上,会改变a的值        #strip()用于移除字符串头尾指定的字符(默认为空格或者换行符)或字符序列    print(result) print(result[0])#运行结果:['0degree', '6degree', '12degree', '18degree', '24degree', '30degree', '36degree', '42degree', '48degree', '54degree', '60degree', '66degree', '72degree', '78degree', '84degree', '90degree', '96degree', '102degree', '108degree', '114degree', '120degree', '126degree', '132degree', '138degree', '144degree', '150degree', '156degree', '162degree', '168degree', '174degree', '180degree']0degree将srt文件转化成数组形式原srt文件000:00:00,150 --> 00:00:11,430Fighting this pandemic needs political commitment and commitment at the highest level possible and the President's commitment.100:00:11,431 --> 00:00:16,020you have what it is in it and the would it have seen it.200:00:16,021 --> 00:00:19,320and that kind of leadership is very,300:00:19,321 --> 00:00:20,160very important.400:00:20,161 --> 00:00:21,570The whole of government approach.转化之后的数组(将时间和内容分离)['00:00', '00:11', '00:16', '00:19', '00:20']["Fighting this pandemic needs political commitment and commitment at the highest level possible and the President's commitment.", 'you have what it is in it and the would it have seen it.', 'and that kind of leadership is very,', 'very important.', 'The whole of government approach.']下面贴出转化的代码,即将cte_test.srt转化成数组之后可以考虑输送到mysql数据库上进行复用123456789101112131415161718count1 = 1count2 = 2ktime = []klrc = []with open('cte_test.srt', 'r') as f:    for index, value in enumerate(f.readlines()):        if index==count1:            value= value.strip()[3:8]            ktime.append(value)            count1=count1+4        elif index==count2:            value= value.strip()            klrc.append(value)            count2=count2+4print(ktime)print(klrc)转载自https://www.jb51.net/article/278980.htm
  • [技术干货] python中的取反操作符(~)【转】
    python取反操作符~ : 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。~x 类似于 -x-11、计算依据①正数的原码、反码、补码都是一样的②负数的补码为符号位不变,剩余位取反再加1③原码求补码: 取反,+1④补码求原码: 取反,+1⑤负数是以补码存储的⑥取反操作是在原码上进行的⑦符号位,1表示负数,0表示正数2、例子~(-2)首先你要知道 -2 在计算机里面的二进制形式,由⑤和②可知:-2 原码:1000 0000 0000 0010-2 反码:1111 1111 1111 1101 #符号位不变,各位求反-2 补码:1111 1111 1111 1110 #补码 = 反码 + 11111 1111 1111 1110 就是-2在计算机里面的原型现在开始对他求反,符号位不变,按位取反: 0000 0000 0000 0001很明显是一个正数,其原码为其本身,所以输出为1.~22 原码,反码,补码: 0000 0000 0000 0010按位取反: 1111 1111 1111 1101这是一个负数该怎么办?能直接求吗?很显然是不行的,⑥说了:取反操作计算结果是在原码上进行的,⑤也说了:负数是以补码存储的1111 1111 1111 1101 是 0000 0000 0000 0010 的反码,但我们想要的是结果,而不是在计算机里面的原型,恰好,④补码求原码: 取反,+1取反: 1000 0000 0000 0010加 1: 1000 0000 0000 0011于是,我们得到了原码,可以计算结果了1000 0000 0000 0011 = -3总之,取反很简单,但是要注意,取反后是不是原码,是否可以直接计算结果python数值取反问题~在python中,用取反符号~得到的并不是我们想象中的结果,总结一下规律,就是   (取反后的值)=  -(取反前的值)-1下面来分析一下例如对1取反,1的8位二进制表示为:0000 0001 ,  取反后的结果是:1111 1110, 对于计算机来说,二进制以1开头表示的是负数, 所以这个1111 1110到底表示的是什么负值呢,想要知道这个值,可以求它的补码,即先取反码 :0000 0001, 再加1:0000 0010,说明 1111 1110 的原码为 0000 0010 也就是正数 2, 所以 1111 1110代表的就是负数 -2 下面再举个例如对 -2 取反, -2的二进制表示为 2的补码,即 0000 0010 > 1111 1101 > 1111 1110 ,-2的二进制就表示为1111 1110, 对它取反得到 0000 0001,显而易见,取反后的值为1 , 所以 ~(-2)= 1  ,  ~1=-2总结出来就是:(取反后的值)=  -(取反前的值)-1转载自https://www.jb51.net/article/278982.htm
  • [技术干货] python字典中get()函数的用法总结-转载
     以下内容均为个人笔记,仅供学习参考使用,因内容均为自己实践经验所得,个人水平有限,如有错误欢迎指正  注:编程语言为Python3  1.get()函数利用键来获取值 之前在学习python的时候,在获取值得时候常用的方法就是直接  print(dict[key]) 1 但这种方法中当字典中不存在该键时会返回KeyError类型错误,此时就可以用get()函数还利用键获取值  print(dict.get(key)) 1 利用get()函数操作时当字典中不存在输入的键时会返回一个None,这样程序运行时就不会出异常  2.利用字典统计列表中元素出现次数 比如现在有这么一个列表,让你统计列表中部分元素出现的次数  ls=['aa','b','c','ddd','aa'] 1 统计列表中每个元素出现次数:  cou={} #创建一个空字典 for i in ls:     cou[i]=cou.get(i,0)+1     #之后称其为get的赋值语句,目的是新建字典键值对          '''     赋值语句代码等价于     cou[i]=0     cou[i}=cou[i]+1     ''' print(cou) 输出结果:  {'aa': 2, 'b': 1, 'c': 1, 'ddd': 1} 1 get()函数在这里有两个参数,第一个是确定要分配值的键,第二个是拟定给键分配一个初值,但实际要给键赋值仍需要get赋值语句(为什么这么说下面有介绍)  比如说我现在添加这个语句到代码中  cou.get('b',10)   #之后称为拟定初值语句 1 拟定初值语句本身对结果是没有影响的,因为并没有实际的对键进行赋值语句操作(个人感觉拟定初值语句是因为没有在字典中找到要赋值的键,因为根本没有创建要赋值的键,因此赋值失败,即相当于一个没有返回值的函数,就算给这个函数赋参数了也没有任何返回结果)  注:get()函数在作为键赋值语句(非拟定赋值语句,区别看上代码框内注释)时只有第一次是有效的,(比如get()函数在第一次对’aa’这个键使用get赋值语句后下次再使用get赋值语句时键的值仍为第一次赋值运算后的结果),以下为测试代码:  ls=['aa','b','c','ddd','aa'] cou={} #创建一个空字典 for i in ls:     cou[i]=cou.get(i,0)+1  #功能逻辑看下方阐述 cou['aa']=cou.get('aa',10)  #功能同前一条代码执行到第二次时的 print(cou) 这里着重讲一下第4行代码:cou[i]=cou.get(i,0)+1 第行代码从逻辑上讲执行了两次,而这两次里get语句每次执行时的功能是不一样的:  第一次:cou[i]=cou.get(i,0)+1(i=‘aa’) 此时get语句的功能为赋初值,即把键’aa’的初值置为0然后加1  第二次:cou[i]=cou.get(i,0)+1(i=‘aa’) 因get语句已经作为赋值语句出现过一次了,因此此时再执行这条语句时,赋值功能已经无效了,也就是get语句里第二个参数对’aa’这个键已经无效了,此时get语句的功能为文章内的第一大部分所介绍的功能,所以这条语句此时可等价为 cou[i]=cou.get(i)+1  即 cou[i]=cou[i]+1  输出结果和之前的代码结果相同:  {'aa': 2, 'b': 1, 'c': 1, 'ddd': 1} 当单独使用get赋值语句时如果键是第一次出现的话,效果等同赋值语句(和之前在空字典里通过for循环建立新键值对效果一样)  cou['e']=cou.get(e,10)  输出结果: ```python {'aa': 10, 'b': 1, 'c': 1, 'ddd': 1,'e':10} 顺带一提如果想直接改变字典中键的值时可用如下方法:  cou['aa']=10  #这种赋值语句带有强制性 print(cou) 输出结果:  {'aa': 10, 'b': 1, 'c': 1, 'ddd': 1} ———————————————— 版权声明:本文为CSDN博主「百万雨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/aaa9692/article/details/115469795 
  • [技术干货] Python中的排序函数--sorted()函数-转载
     选择题 以下python代码输出什么? a = [2,3,1] sorted(a) print(a)  A a B [3, 2, 1] C [2, 3, 1] D [1, 2, 3]  问题解析 1.sorted()函数可以对所有可迭代的对象进行排序操作。题目中,sorted()函数提供了一个新的有序的输出结果,并且不改变原始值的顺序。所以使用print()语句输出列表a,结果仍是原来a的排序。 2.sorted()函数是一个内置函数,可以直接使用。sorted()语法(应用于Python 3.x): sorted(iterable,key=None, reverse=False) 其中参数说明: iterable:可迭代对象 key:通过这个参数可以自定义排序逻辑 reverse:指定排序规则,True为降序,False为升序(默认)。 3.sorted()函数返回重新排序的列表,与sort()函数的区别在于sort()函数是list列表中的函数,而sorted()函数可以对所有可迭代对象进行排序操作。并且用sort()函数对列表排序时会影响列表本身,而sorted()函数则不会。 4.需要注意的是,sorted()函数虽然可以处理所有可迭代的对象,例如集合、元组、数组,但是输出结果仍然是一个列表。所以如果返回的对象需要匹配输入类型,那么需要将转化为新类型。  欢迎大家转发,一起传播知识和正能量,帮助到更多人。期待大家提出宝贵改进建议,互相交流,收获更大。辛苦大家转发时注明出处(也是咱们公益编程交流群的入口网址),刘经纬老师共享知识相关文件下载地址为:http://liujingwei.cn  答案 正确答案是:C 代码及运行结果:      温馨期待 期待大家提出宝贵建议,互相交流,收获更大,助教:qzr ———————————————— 版权声明:本文为CSDN博主「刘经纬老师」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/liujingwei8610/article/details/121299626 
  • [技术干货] 贪心算法例题-转载
     贪心算法         贪心算法(greedy algorithm ,又称贪婪算法)是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择 。  找零问题 币种:1 2 4 5 10 若干张,找零:n元。输出找零方案  思路:  (1)因为贪心是要找到最优解,所以我们要从最大的币值开始寻找  (2)每次找到符合条件的币值时,就让n减去已经找到的钱,然后继续循环,直到n不大于0时停止  import java.util.Scanner;   public class Greed {     public static void main(String[] args) {         Scanner scanner = new Scanner(System.in);         int n = scanner.nextInt();         greedy(n);     }       public static void greedy(int n) {         int[] money = {10, 5, 4, 2, 1};//钱的面值,从大到小,因为要找最优解。         int i = 0;//表示目前用money数组中哪一个面值的钱去找零,最开始从10快开始。         int[] num = new int[money.length];         while (n > 0) {//n>0说明钱还没有找完,所以继续循环             if (n >= money[i]) {//剩余要找的钱必须大于等于当前money[i]这个面值                 int zs = n / money[i];                 n -= zs * money[i];                 num[i]+= zs;//当前这个面值的数量加上zs             } else{//如果当前面值不能找开就i++                 i++;             }         }         for (int j = 0; j < num.length; j++) {//输出             if (num[j] > 0) {//说明当前这个面值的钱使用到了,所以才能输出                 System.out.printf("面值:%d 张数:%d ", money[j], num[j]);             }         }     } }  ​              最大的金额         假如整数n表示当前奖池中已经有的钱的总数,请你从n中删除m个数字,余下的数值对应的金额就是可以拿走的钱,我们知道人性是贪婪的,那么请帮助小明,使得余下的数字按原次序组成的新数最大。  比如当n = 92081346718538,m = 10时,则新的最大数是9888  样例输入:  92081346718538 10  1008908 5  样例输出:  9888  98  思路:  (1)先将删除问题变成保留问题,利用贪心的思想,每次在非保留的个数外寻找最大值  (2)假设输入92081346718538 10,所以我们要在14个数中删除10个,所以我们可以在前11个数中选择一个最大值,然后下次循环在从这个最大值到第12个数中寻找最大的数,直到for循环的i等于被保留的数时停止。  import java.util.Scanner;   public class selectMaxNumber {     public static void main(String[] args) {         Scanner scanner = new Scanner(System.in);         while (scanner.hasNext()) {             String n = scanner.next();//输入n为String类型             int m = scanner.nextInt();//输入需要删除数的个数             if (n.length() <= m) {                 System.out.println("输入错误,请重新输入");             }             char[] a = n.toCharArray();//将String类型的数转为char数组,为了循环判断使用             String max = "";//定义max变量存放最后早到的最大数             int retain = a.length - m;//将删除问题变成保留问题             int lastselect = -1;//存放最大数在数组中的位置,开始的时候定义为-1,在循环时在+1就从0开始了             for (int i = 1; i <= retain; i++) {                 char big = '0';//循环比较前先假设big为最小的值                     for (int j = lastselect + 1; j < a.length - (retain - i); j++) {                     //这里lastselect+1主要是因为在找到一个最大的数后下次循环就从这个最大数的下一个开始                     /*                     j < a.length - (retain - i)这个区间判断方法是                     第一次循环判断的范围是j < 11,也就是0到10,因为总共有14个数,需要保留四个,                     所以第一次就需要在前11个中选择一个最大的数,然后每次循环结束范围都要往后移一位                     例如:92081346718538删掉十个数,第一次循环判断在92081346718中                     第二次循环判断在20813467185中,第三次在134671853中,第四次就在538中                      */                       if (a[j] > big) {                         big = a[j];                         lastselect = j;//找到大的数就将j赋给存放最大数地址的这个变量                     }                 }                 max += big;//每次找出那个最大的数后就拼接到max中             }             System.out.println(max);         }     } }     堆果子         在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆,多多决定把所有的果子合成堆,每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有果子经过n-1次合并后,就只剩下了一堆,多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。          因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能的节省体力,假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务就是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小体力的值。  输入:第一行:一个整数n(1<=n<=100),表示果子的种类数。第二行:包含n个整数,用空格分隔。n等于0时自动退出  思路:  (1)如果n==0就停止,n==1就直接输出重量  (2)如果n>1就循环,首先将数组从小到大排序,然后每次循环都将数组的第一个数和第二个数相加,空余的位置给无限大,这样就可以循环相加了。  import java.util.Arrays; import java.util.Scanner;   public class pileFruit {     public static void main(String[] args) {         Scanner scanner = new Scanner(System.in);         while (scanner.hasNext()) {             int n = scanner.nextInt();//输入果子总共的堆数             int[] m = new int[n];//表示n堆果子重量的数组             if (n == 0) break;//n==0时直接结束             if (n == 1) {                 //如果只有一堆果子,就直接输出这堆果子的重量                 System.out.println(scanner.nextInt());                 continue;             }             for (int i = 0; i < n; i++) {                 m[i] = scanner.nextInt();//输入每堆果子的重量             }             int sum = 0;//记录总共搬运的重量             for (int i = 0; i < n - 1; i++) {//循环n-1次,例如三堆果子只需要搬2次                 Arrays.sort(m);//将m数组排序                 sum = sum + m[0] + m[1];//先从最轻的开始合并                 m[0] += m[1];//搬完后m[0]就表示合并后的重量                 m[1] = Integer.MAX_VALUE;//然后m[1]给无穷大,这样每次循环就会到数组最后                 System.out.println(Arrays.toString(m));//查看数组数的排序             }             System.out.println(sum);         }     } }    可以看出输出了每次排序前的数组,也输出了最后总共消耗的体力 ———————————————— 版权声明:本文为CSDN博主「周小末天天开心」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_71646897/article/details/129768164 
  • [技术干货] Python3,选择Python自动安装第三方库,从此跟pip说拜拜!!-转载
     1、引言 续上一篇《Python3:我低调的只用一行代码,就导入Python所有库!》,小鱼发现,别说,还真有不少懒人~ ~  不知道是不是都跟小鱼一样,把剩下的时间来学(撩)习(妹)。  为了体现小鱼在懒上的造就,小鱼今天再分享一个骚操作: Python自动安装第三方库,彻底解放双手!  2、pip手动安装 说道Python安装第三方库,我们第一反应,必须pip方式安装,没毛病,必须的。 但是想想,如果你换电脑了(土豪才换电脑,我都换朋友),Python第三方库那么多,你难道要一次一次的敲击pip install??  难道你还是小学生,还需要练习敲键盘??   不过,按照流程,我们还是要先介绍一下pip的手动安装方式,然后再介绍今天的角:自动安装第三方库,  2.1 在线安装 2.1.1 默认安装 老生常谈了,直接一句命令:  pip install  第三方库名称 1 2.1.2 指定版本安装 指定第三方库的版本安装命令:  pip install  第三方库名称==版本号 1 例如  pip install  selenium==3.3 1 指定版本号的几种方式:  ①不指定的情况下,默认安装最新的 ②== 指定具体版本号 ③<= 指定最高版本号 ④>= 指定最低版本号 ⑤< 不高于某版本号 ⑥> 不低于某版本号 注意 这里提示一下,如果不指定具体的版本号,则需要用引号(’ '),如下:  pip install  'selenium>3.3' 1 2.2 离线安装 很多python库在线安装会超时,或者没有网络的情况下,这个时候,就会想到离线安装。  毕竟上班摸鱼是不对的; 占用公司网络下载安装包也是不对的。  这里推荐两个非常非常全的第三方库地址,别客气,直接拿走:  健康网站:https://www.lfd.uci.edu/~gohlke/pythonlibs/ Pypi:https://pypi.org/  小屌丝:鱼哥,离线安装,总共分几步? 小鱼:总共分三步,请跟我一起数:  第一步:登录Python第三方库网站; 第二步:把第三库的文件,下载到本地 第三步:通过本地安装 命令  pip install C:\Project\pyRXP-2.2.0-cp35-cp35m-win_amd64.whl 1 2.3 设置国内源 小屌丝:鱼哥,有没有一个不用下载到本地,还能嗷嗷快安装的方式 小鱼:这必须的有,上车,看命令。  如果不想下载到本地,还想直接pip安装,那国内源镜像考虑一下。  命令  pip install plotly -i https://pypi.tuna.tsinghua.edu.cn/simple 1 国内源地址,如下:  阿里云镜像:http://mirrors.aliyun.com/pypi/simple/ 清华大学镜像:https://pypi.tuna.tsinghua.edu.cn/simple/ 豆瓣镜像:http://pypi.doubanio.com/simple/ 中科大镜像:https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/  小屌丝:鱼哥,这方法好是好,但是我不想每次都输入地址,能不能搞一个一劳永逸的方法, 小鱼:…你的要求可真高,不过方法可以有。  就在你的当前项目下,创建一个pip.ini文件,直接调用这个文件内容就OK了:   2.4 卸载与升级 2.4.1 卸载 有安装,就有卸载, 也是很简单,一句命令  pip uninstall 第三方库名称 1 2.4.2 升级 在升级之前,我们需要先查看,如下: 1、查看命令  ①查看已安装的库  pip list 1 ②查看指定的库  pip show 库名称 1 2、升级命令  ①查看可升级的库  pip list -o 1 ②升级命令  pip install --upgrade 库名称 1 3、pip.main自动安装 3.1 pip main 安装 千呼万唤始出来,犹抱琵琶不遮面! 前面做了那么多铺垫,主角出场,可以鼓掌,不要停的那种!  我们都经历过,接着别人的代码(拒绝背锅侠),继续前行,但是,有些库我们却没有安装, 这个时候,就很痛苦,不停地提示没有库,不停地安装, 想想就苦逼。 小屌丝:那么有没有一种办法,一步搞定?? 小鱼:必须的,上车,放代码。  代码展示  # -*- coding:utf-8 -*- # @Time   : 2021-08-03 # @Author : carl_DJ  """如果引用的库未安装,则自动安装"""  #为了明确异常信息,我们追加断言 try:     import requests     import pandas as pd     from bs4 import BeautifulSoup     import jieba     import jieba.analyse     import matplotlib.pyplot as plt     from wordcloud import WordCloud,STOPWORDS     import numpy as np     from PIL import Image # 使用pip.main()方法进行依赖库的安装(例举几个常用的库)    except  ImportError:     import pip     pip.main(["install", "--user", "requests","beautifulsoup4","matplotlib","wordcloud","pandas","pillow"])     import requests     import pandas as pd     from bs4 import BeautifulSoup     import jieba     import jieba.analyse     import matplotlib.pyplot as plt     from wordcloud import WordCloud,STOPWORDS     import numpy as np         from PIL import Image  执行这段代码,剩下的就是等(liao)待(mei)。  因为小鱼都已经安装完,所以就不执行了。  3.2 os安装 小屌丝:看到这里,我觉得我牛叉了… 小鱼:这才哪到哪,我用一行代码,自动安装。 小屌丝:我屮艸芔茻…  代码展示  # -*- coding:utf-8 -*- # @Time   : 2021-08-03 # @Author : carl_DJ  import os  #需要安装的库 libs = ["requests","beautifulsoup4","matplotlib","wordcloud","pandas","pillow"]  #循环遍历安装 for lib in libs:     os.system("pip install " + lib) 小屌丝:唉我去~~ 鱼哥,牛了牛了!!! 小鱼:我就想叉腰一会…  4、总结 看到这里,又要到总结的时间了, 我们看看今天分享的内容都有啥:  pip在线安装 pip离线安装 国内源镜像安装 卸载与升级 Python自动安装 想想,回过来品一品,也就那么回事。 不管用什么方法安装,只要能只能安装上就行。 就好比小鱼的这篇博文《Python3:我低调的只用一行代码,就导入Python所有库!》,不管怎么导入第三方库,只要能使用就行。 所以,我们选择的方法,适合自己的就是最好的。 ———————————————— 版权声明:本文为CSDN博主「Carl_奕然」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/wuyoudeyuer/article/details/119350545 
  • [区域初赛赛题问题] python跳帧现象
    python在若干次快速模式运行后会产生跳帧现象并且跳的帧越来越多,可能的原因是什么?
  • [区域初赛赛题问题] 4张图线上报错,选手程序运行异常。本地跑正常,没有跳帧。之前提交过很多次都可以。第一次遇到这种情况
    Python遇到了一个问题,本地跑有分数,四张地图没有跳帧。打压缩包发到平台上, 报错:地图:1, 错误信息:选手程序运行异常;地图:2, 错误信息:选手程序运行异常;地图:3, 错误信息:选手程序运行异常;地图:4, 错误信息:选手程序运行异常;
  • [最佳实践] Python对接MRS集群中Spark
    Pyspark对接MRS集群在Linux节点上(集群上所有节点)均安装Anaconda下载Anaconda安装包: wget https://repo.anaconda.com/archive/Anaconda3-2021.05-Linux-x86_64.sh使用如下命令安装Anaconda说明~/.bashrc 文件会在anaconda安装过程中初始化,请在安装前备份此配置文件cp ~/.bashrc ~/.bashrc.bak bash Anaconda3-2021.05-Linux-x86_64.sh安装程序将提示“In order to continue the installation process, please review the license agreement.”单击Enter以查看许可条款。滚动到许可条款的底部,然后输入“yes”以表示同意。安装程序提示您单击Enter接受默认安装位置,按CTRL-C取消安装,或指定备用安装目录。如果您接受默认安装位置,则安装程序将显示“PREFIX=/home/{username}/anaconda<2 or 3>”并继续安装。可能需要几分钟才能完成。注意: 推荐使用默认安装位置,如果使用非root用户进行交互,请安装在其他可访问的路径,比如/opt,否则之后会报关于用户权限的问题安装程序提示“Do you wish the installer to initialize Anaconda2 by running conda init?”推荐填写 “yes”。安装完成,会显示 “Thank you for installing Anaconda<2 or 3>!”关闭并打开终端窗口,以使安装生效。mv ~/.bashrc ~/.bashrc.anaconda cp ~/.bashrc.bak ~/.bashrc source ~/.bashrc.anaconda退出conda环境conda deactivate到如下链接获取需要的数据文件airlines.csv,并将数据文件上传到对接集群hdfs的/usr/developuser路径下: cid:link_0执行代码进入Anaconda3目录下,执行代码片段cd /usr/anaconda3/bin/ ./python3新建一个notebook,下面为python代码片段:import sys sys.path.insert(0, '/opt/140client/Spark2x/spark/python') sys.path.insert(0, '/opt/140client/Spark2x/spark/python/lib/py4j-0.10.9-src.zip') import os os.environ["PYSPARK_PYTHON"]="/usr/anaconda3/bin/python3" import pyspark from pyspark import SparkConf from pyspark import SparkContext os.system('source /opt/140client/bigdata_env') os.system('echo password | kinit 用户名') conf = pyspark.SparkConf().setMaster('yarn').setAppName('spark-shared_process') sc = pyspark.SparkContext(conf=conf) distFile = sc.textFile('hdfs://hacluster/usr/developuser/airlines.csv') nonempty_lines = distFile.filter(lambda x: len(x) > 0) print ('Nonempty lines', nonempty_lines.count()) words = nonempty_lines.flatMap(lambda x: x.split(' ')) wordcounts = words.map(lambda x: (x, 1)) \ .reduceByKey(lambda x, y: x+y) \ .map(lambda x: (x[1], x[0])).sortByKey(False) print ('Top 100 words:') print (wordcounts.take(100))查看集群中数据
  • [技术干货] 学习 Python 之 Pygame 开发坦克大战(五)-转载
     坦克大战完善地图 我的素材放到了百度网盘里,里面还有原版坦克大战素材,我都放在一起来,我的素材是从原版改的,各位小伙伴可以直接用或者自己改一下再用,做出适合自己的素材  素材链接:百度网盘 链接:https://pan.baidu.com/s/19sCyH7rp37f6DzRj0iXDCA?pwd=tkdz 提取码:tkdz  那我们就继续编写坦克大战吧  1. 创建砖墙 坦克大战中,砖墙是最常见的墙,子弹都可以轻松击穿,下面我们来加入到自己的坦克大战中  创建砖墙类  import pygame.image from ParentObject import ParentObject  class BrickWall(ParentObject):     def __init__(self, x, y):         super().__init__()         self.image = pygame.image.load('../Image/Wall/BrickWall.png')         self.rect = self.image.get_rect()         self.rect.left = x         self.rect.top = y         self.isDestroy = False      def draw(self, window):         window.blit(self.image, self.rect) 在主类中加入砖墙列表  class MainGame:     ...     # 砖墙     brickWallList = []     ... 在主类中加入初始化砖墙函数和显示砖墙函数  def drawBrickWall(self, brickWallList):     for brickWall in brickWallList:         if brickWall.isDestroy:             brickWallList.remove(brickWall)         else:             brickWall.draw(MainGame.window)  def initBrickWall(self):     for i in range(20):         MainGame.brickWallList.append(BrickWall(i * 25, 200)) 这里我在y = 200的位置,连续画出20个砖,砖的图片是25x25的,所以为了防止重叠,要间隔25个距离(像素)  在主函数startGame()函数中调用函数  def startGame(self):     # 初始化展示模块     pygame.display.init()     # 设置窗口大小     size = (SCREEN_WIDTH, SCREEN_HEIGHT)     # 初始化窗口     MainGame.window = pygame.display.set_mode(size)     # 设置窗口标题     pygame.display.set_caption('Tank Battle')      # 初始化我方坦克     MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1)      # 播放开始音乐     MainGame.startingSound.play()          # 初始化场景     self.initBrickWall()      while 1:         # 设置背景颜色         MainGame.window.fill(BACKGROUND_COLOR)          # 获取窗口事件         self.getPlayingModeEvent()                  # 显示物体         self.drawBrickWall(MainGame.brickWallList)          # 展示敌方坦克         self.drawEnemyTank()          # 显示我方坦克         MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])          # 我方坦克移动         if not MainGame.playerTank.stop:             MainGame.playerTank.move()             MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)          # 显示我方坦克子弹         self.drawPlayerBullet(MainGame.playerBulletList)          # 展示敌方坦克子弹         self.drawEnemyBullet()          # 展示爆炸效果         self.drawExplode()          # 更新窗口         pygame.display.update()  运行一下,看看结果  但是墙只是摆设,子弹可以穿过,坦克也可以穿过,下面给墙增加碰撞效果  2. 给砖墙增加子弹击中的碰撞效果 在子弹类中增加函数  def bulletCollideBrickWall(self, brickWallList, explodeList):     for brickWall in brickWallList:         # 子弹与墙发生碰撞         if pygame.sprite.collide_rect(self, brickWall):             self.isDestroy = True             brickWall.isDestroy = True             # 碰撞出现爆炸效果             explode = Explode(brickWall, 25)             explodeList.append(explode)             # 出现爆炸播放音效             Sound('../Sound/block.wav').play() 在主函数中调用 修改显示子弹的两个函数  def drawPlayerBullet(self, playerBulletList):     # 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除     for bullet in playerBulletList:         if not bullet.isDestroy:             bullet.draw(MainGame.window)             bullet.move(MainGame.explodeList)             bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList)             bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)         else:             playerBulletList.remove(bullet) def drawEnemyBullet(self):     for bullet in MainGame.enemyTankBulletList:         if not bullet.isDestroy:             bullet.draw(MainGame.window)             bullet.move(MainGame.explodeList)             bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList)             bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)         else:             bullet.source.bulletCount -= 1             MainGame.enemyTankBulletList.remove(bullet) 运行一下看看  可以看到墙可以被打掉了  3. 给砖墙添加坦克不能通过的碰撞效果 在敌方坦克类中加入函数,在我方坦克类中加入函数 collideBrickWall()  def collideBrickWall(self, brickWallList):     for brickWall in brickWallList:         if pygame.sprite.collide_rect(self, brickWall):             self.rect.left = self.prvX             self.rect.top = self.prvY 在主类中调用 在while循环中调用  while 1:     # 设置背景颜色     MainGame.window.fill(BACKGROUND_COLOR)      # 获取窗口事件     self.getPlayingModeEvent()      # 显示物体     self.drawBrickWall(MainGame.brickWallList)      # 展示敌方坦克     self.drawEnemyTank()      # 显示我方坦克     MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])      # 我方坦克移动     if not MainGame.playerTank.stop:         MainGame.playerTank.move()         MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)         # 不能撞墙         MainGame.playerTank.collideBrickWall(MainGame.brickWallList) 在主类的drawEnemyTank()中调用  def drawEnemyTank(self):     ...     for tank in MainGame.enemyTankList:         # 坦克还有生命值         if tank.life > 0:             tank.draw(MainGame.window)             tank.move()             tank.collidePlayerTank(MainGame.playerTank)             tank.collideEnemyTank(MainGame.enemyTankList)             # 不能撞墙             tank.collideBrickWall(MainGame.brickWallList)             bullet = tank.shot()             if bullet is not None:                 MainGame.enemyTankBulletList.append(bullet)         # 坦克生命值为0,就从列表中剔除         else:             MainGame.enemyTankCurrentCount -= 1             MainGame.enemyTankList.remove(tank)  运行一下,看看效果  确实是不能穿过了 那就完成啦,接下来就是添加其他的物体了 添加的过程跟添加砖墙是一样的   4. 添加石墙 创建石墙类  import pygame.image from ParentObject import ParentObject  class StoneWall(ParentObject):     def __init__(self, x, y):         super().__init__()         self.image = pygame.image.load('../Image/Wall/StoneWall.png')         self.rect = self.image.get_rect()         self.rect.left = x         self.rect.top = y         self.isDestroy = False      def draw(self, window):         window.blit(self.image, self.rect) 在主类中加入石墙列表 在主类中加入显示石墙函数  def initStoneWall(self):     for i in range(20):         MainGame.stoneWallList.append(StoneWall(i * 25, 400))          def drawStoneWall(self, stoneWallList):     for stoneWall in stoneWallList:         if stoneWall.isDestroy:             stoneWallList.remove(stoneWall)         else:             stoneWall.draw(MainGame.window) 给石墙添加坦克不能通过的碰撞效果 在敌方坦克类中加入函数,在我方坦克类中加入函数 collideStoneWall()  def collideStoneWall(self, stoneWallList):     for stoneWall in stoneWallList:         if pygame.sprite.collide_rect(self, stoneWall):             self.rect.left = self.prvX             self.rect.top = self.prvY 在主类中调用函数  接下来是给子弹添加打击石墙的效果  def bulletCollideStoneWall(self, stoneWallList, explodeList):     for stoneWall in stoneWallList:         if pygame.sprite.collide_rect(self, stoneWall):             # 判断坦克的等级,大于等于2时,可以打穿石墙             if self.source.level >= 2:                 stoneWall.isDestroy = True             self.isDestroy = True             explode = Explode(stoneWall, 25)             explodeList.append(explode)             Sound('../Sound/block.wav').play() 在主类中调用函数  主类的完整代码  import pygame import sys  from PlayerTank import PlayerTank from EnemyTank import EnemyTank from Sound import Sound from BrickWall import BrickWall from StoneWall import StoneWall  SCREEN_WIDTH = 1100 SCREEN_HEIGHT = 600 BACKGROUND_COLOR = pygame.Color(0, 0, 0) FONT_COLOR = (255, 255, 255) PLAYER_TANK_POSITION = (325, 550)  class MainGame:      # 窗口Surface对象     window = None      # 玩家坦克     playerTank = None      # 玩家子弹     playerBulletList = []     playerBulletNumber = 3      # 敌人坦克     enemyTankList = []     enemyTankTotalCount = 5     # 用来给玩家展示坦克的数量     enemyTankCurrentCount = 5      # 敌人坦克子弹     enemyTankBulletList = []      # 爆炸列表     explodeList = []      # 坦克移动音效     playerTankMoveSound = Sound('../Sound/player.move.wav').setVolume()      # 游戏开始音效     startingSound = Sound('../Sound/intro.wav')      # 砖墙     brickWallList = []     # 石墙     stoneWallList = []      def __init__(self):         pass      def startGame(self):         # 初始化展示模块         pygame.display.init()         # 设置窗口大小         size = (SCREEN_WIDTH, SCREEN_HEIGHT)         # 初始化窗口         MainGame.window = pygame.display.set_mode(size)         # 设置窗口标题         pygame.display.set_caption('Tank Battle')          # 初始化我方坦克         MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1)          # 播放开始音乐         MainGame.startingSound.play()          # 初始化场景         self.initBrickWall()         self.initStoneWall()          while 1:             # 设置背景颜色             MainGame.window.fill(BACKGROUND_COLOR)              # 获取窗口事件             self.getPlayingModeEvent()              # 显示物体             self.drawBrickWall(MainGame.brickWallList)             self.drawStoneWall(MainGame.stoneWallList)              # 展示敌方坦克             self.drawEnemyTank()              # 显示我方坦克             MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])              # 我方坦克移动             if not MainGame.playerTank.stop:                 MainGame.playerTank.move()                 MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)                 MainGame.playerTank.collideBrickWall(MainGame.brickWallList)                 MainGame.playerTank.collideStoneWall(MainGame.stoneWallList)              # 显示我方坦克子弹             self.drawPlayerBullet(MainGame.playerBulletList)              # 展示敌方坦克子弹             self.drawEnemyBullet()              # 展示爆炸效果             self.drawExplode()              # 更新窗口             pygame.display.update()                  def getPlayingModeEvent(self):         # 获取所有事件         eventList = pygame.event.get()         for event in eventList:              if event.type == pygame.QUIT:                 sys.exit()              """             stop属性用来控制坦克移动,当键盘按键按下时,坦克可以移动,一直按住一直移动,当按键抬起时,停止移动             如果没有该属性,按一下按键移动一次,按一下移动一下,不能一直按住一直移动             """             if event.type == pygame.KEYDOWN:                 MainGame.playerTankMoveSound.play(-1)                 if event.key == pygame.K_w:                     MainGame.playerTank.direction = 'UP'                     MainGame.playerTank.stop = False                 elif event.key == pygame.K_s:                     MainGame.playerTank.direction = 'DOWN'                     MainGame.playerTank.stop = False                 elif event.key == pygame.K_a:                     MainGame.playerTank.direction = 'LEFT'                     MainGame.playerTank.stop = False                 elif event.key == pygame.K_d:                     MainGame.playerTank.direction = 'RIGHT'                     MainGame.playerTank.stop = False                 elif event.key == pygame.K_j:                     # 判断子弹数量是否超过指定的个数                     if len(MainGame.playerBulletList) < MainGame.playerBulletNumber:                         bullet = MainGame.playerTank.shot()                         MainGame.playerBulletList.append(bullet)                         # 添加音效                         Sound('../Sound/shoot.wav').play(0)              if event.type == pygame.KEYUP:                 MainGame.playerTankMoveSound.stop()                 if event.key == pygame.K_w:                     MainGame.playerTank.stop = True                 elif event.key == pygame.K_s:                     MainGame.playerTank.stop = True                 elif event.key == pygame.K_a:                     MainGame.playerTank.stop = True                 elif event.key == pygame.K_d:                     MainGame.playerTank.stop = True      def drawPlayerBullet(self, playerBulletList):         # 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除         for bullet in playerBulletList:             if not bullet.isDestroy:                 bullet.draw(MainGame.window)                 bullet.move(MainGame.explodeList)                 bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList)                 bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)                 bullet.bulletCollideStoneWall(MainGame.stoneWallList, MainGame.explodeList)             else:                 playerBulletList.remove(bullet)      def drawEnemyTank(self):         # 如果当前坦克为0,那么就该重新生成坦克         if len(MainGame.enemyTankList) == 0:             # 一次性产生三个,如果剩余坦克数量超过三,那只能产生三个             n = min(3, MainGame.enemyTankTotalCount)             # 如果最小是0,就说明敌人坦克没有了,那么就赢了             if n == 0:                 print('赢了')                 return             # 没有赢的话,就产生n个坦克             self.initEnemyTank(n)             # 总个数减去产生的个数             MainGame.enemyTankTotalCount -= n         # 遍历坦克列表,展示坦克并且移动         for tank in MainGame.enemyTankList:             # 坦克还有生命值             if tank.life > 0:                 tank.draw(MainGame.window)                 tank.move()                 tank.collidePlayerTank(MainGame.playerTank)                 tank.collideEnemyTank(MainGame.enemyTankList)                 tank.collideBrickWall(MainGame.brickWallList)                 tank.collideStoneWall(MainGame.stoneWallList)                 bullet = tank.shot()                 if bullet is not None:                     MainGame.enemyTankBulletList.append(bullet)             # 坦克生命值为0,就从列表中剔除             else:                 MainGame.enemyTankCurrentCount -= 1                 MainGame.enemyTankList.remove(tank)          def initEnemyTank(self, number):         y = 0         position = [0, 425, 850]         index = 0         for i in range(number):             x = position[index]             enemyTank = EnemyTank(x, y)             MainGame.enemyTankList.append(enemyTank)             index += 1      def drawEnemyBullet(self):         for bullet in MainGame.enemyTankBulletList:             if not bullet.isDestroy:                 bullet.draw(MainGame.window)                 bullet.move(MainGame.explodeList)                 bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList)                 bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)                 bullet.bulletCollideStoneWall(MainGame.stoneWallList, MainGame.explodeList)             else:                 bullet.source.bulletCount -= 1                 MainGame.enemyTankBulletList.remove(bullet)      def drawExplode(self):         for e in MainGame.explodeList:             if e.isDestroy:                 MainGame.explodeList.remove(e)             else:                 e.draw(MainGame.window)      def drawBrickWall(self, brickWallList):         for brickWall in brickWallList:             if brickWall.isDestroy:                 brickWallList.remove(brickWall)             else:                 brickWall.draw(MainGame.window)      def initBrickWall(self):         for i in range(20):             MainGame.brickWallList.append(BrickWall(i * 25, 200))      def initStoneWall(self):         for i in range(20):             MainGame.stoneWallList.append(StoneWall(i * 25, 400))      def drawStoneWall(self, stoneWallList):         for stoneWall in stoneWallList:             if stoneWall.isDestroy:                 stoneWallList.remove(stoneWall)             else:                 stoneWall.draw(MainGame.window)  if __name__ == '__main__':     MainGame().startGame()  5. 添加玩家基地 坦克大战是玩家坦克在保护自己基地的同时消灭敌方坦克,当玩家坦克生命值为0或者基地爆炸时,游戏失败,下面来添加玩家的基地  创建基地类  import pygame.image  from ParentObject import ParentObject  class Home(ParentObject):     def __init__(self, x, y):         super().__init__()         self.image = pygame.image.load('../Image/Home/Home.png')         self.rect = self.image.get_rect()         self.rect.left = x         self.rect.top = y         self.isDestroy = False      def draw(self, window):         window.blit(self.image, self.rect)  为基地添加碰撞效果,在两个坦克类中加入下面的函数  def collideHome(self, home):     if pygame.sprite.collide_rect(self, home):         self.rect.left = self.prvX         self.rect.top = self.prvY 在主函数创建基地变量,并初始化和调用上面的函数  之后给基地加入子弹击中效果  def bulletCollidePlayerHome(self, home, explodeList):     if pygame.sprite.collide_rect(self, home):         self.isDestroy = True         explode = Explode(home, 50)         explodeList.append(explode)         Sound('../Sound/buh.wav').play()         return True     else:         return False 返回值用来判断是否结束游戏 在主类中设置一个变量记录是否游戏结束  def __init__(self):     # 初始化     MainGame.home = Home(425, 550)      # 记录是否输了     self.isDefeated = False 在循环中检查  while 1:     ...     # 检查是否输了     if self.isDefeated:         self.defeated()         break     ... def defeated(self):     # 失败了坦克不能移动了     MainGame.playerTankMoveSound.stop()     # 播放失败音乐     Sound('../Sound/gameOver.wav').play()     print('游戏结束')     self.isDefeated = True 游戏结束后要改变窗口中的内容,显示你输了,所以要用break跳出  这里需要使用到在窗口显示文字,编写一个函数  def drawText(self, text, x, y, fontSize, window):     # 初始化字体     pygame.font.init()     font = pygame.font.SysFont('georgia', fontSize)     # 加载文字并设置颜色     fontColor = pygame.Color(255, 255, 255)     fontObject = font.render(text, True, fontColor)     # 展示文字     window.blit(fontObject, (x, y)) 记得在主函数中调用  while 1:     # 设置背景颜色     MainGame.window.fill(BACKGROUND_COLOR)      # 获取窗口事件     self.getPlayingModeEvent()      # 显示物体     self.drawBrickWall(MainGame.brickWallList)     self.drawStoneWall(MainGame.stoneWallList)     MainGame.home.draw(MainGame.window)      # 展示敌方坦克     self.drawEnemyTank()      # 显示我方坦克     MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])      # 我方坦克移动     if not MainGame.playerTank.stop:         MainGame.playerTank.move()         MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)         MainGame.playerTank.collideBrickWall(MainGame.brickWallList)         MainGame.playerTank.collideStoneWall(MainGame.stoneWallList)         MainGame.playerTank.collideHome(MainGame.home)      # 显示我方坦克子弹     self.drawPlayerBullet(MainGame.playerBulletList)      # 展示敌方坦克子弹     self.drawEnemyBullet()      # 展示爆炸效果     self.drawExplode()      # 检查是否输了     if self.isDefeated:         self.defeated()         break      # 更新窗口     pygame.display.update()  # 设置背景颜色 MainGame.window.fill(BACKGROUND_COLOR)  # 显示字体 self.drawText('Defeated', 200, 200, 50, MainGame.window)  # 更新窗口 pygame.display.update()  给玩家提示敌人坦克数量  到这里,坦克大战的基本功能就实现了,接下来就是添加其他的场景物体和坦克样子了  6. 最终效果 主界面,这里直接放了一张图片上去,图片在素材里,上面的坦克是自己画上去的,w和s键可以上下移动坦克,选择对应的模式  选择关卡,这里使用用了四张图片,左右箭头,上面的标题和start文字,这些都是图片,按下黄色箭头可以选择关卡,使用的鼠标事件   游戏界面   其中加入了奖励功能  地图制作可以使用excel读取信息,下面是第一关的地图   坦克大战代码  链接:https://pan.baidu.com/s/1qFV-0hi0cgZS1Hnvx6mK6Q?pwd=90tk 提取码:90tk ———————————————— 版权声明:本文为CSDN博主「_DiMinisH」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_37354060/article/details/129110457 
总条数:2474 到第 页
上滑加载中