对比学习孪生网络之简单的手写数字集代码实战

2023-05-16

对比学习孪生网络

注:大家觉得博客好的话,别忘了点赞收藏呀,本人每周都会更新关于人工智能和大数据相关的内容,内容多为原创,Python Java Scala SQL 代码,CV NLP 推荐系统等,Spark Flink Kafka Hbase Hive Flume等等~写的都是纯干货,各种顶会的论文解读,一起进步。
今天继续和大家分享一下对比学习孪生网络之简单的手写数字集代码实战
#博学谷IT学习技术支持


文章目录

  • 对比学习孪生网络
  • 前言
  • 一、什么是对比学习
  • 二、手写数字MNIST实战代码
    • 1.配置文件
    • 2.模型定义
    • 3.模型训练
    • 3.模型测试
  • 总结


前言

对比学习孪生网络最近很火,这种无监督的学习方式作者最近也一直在关注和学习,今天和大家分享的是最简单的通过手写数字MNIST入门对比学习孪生网络,看看这种无监督网络的效果。


一、什么是对比学习

在这里插入图片描述
对比学习是通过对同一张猫的图像做数据增强学习之后,得到2张不同的猫,这两张猫就是一组正样本,抽样其他的猫和狗就为负样本的一种完全无监督的模型,这样的好处的在隐藏特征空间可以拉近相同的图片,拉远不相同的图片。
注意点:

  1. 输入图片做完数据增强之后,一定是走同样的一对encoder网络。孪生网络
  2. 最后模型训练完成做INFERENCE的时候是输入一张图片,用中间层h的EMBEDDING做下游任务,而不是最后的输出层z。这样模型的泛化能力更强。
    在这里插入图片描述

二、手写数字MNIST实战代码

1.配置文件

import torch
from torch.utils.data import DataLoader
import Dataset
from torch import nn
from torchvision import transforms, models, datasets
import torch.optim as optim
import torchvision
import copy
from model import SimCLR
import argparse
parser = argparse.ArgumentParser(description="对比学习学习图像表征")
parser.add_argument('--image_dir',default='./image_test2/',help="输入文件夹")
parser.add_argument('--batch_size',default=512,type=int,help="")
parser.add_argument('--feature_extract',default=False,type=bool,help="是否需要冻住预训练模型参数")
parser.add_argument('--image_size',default=28,type=int,help="")
parser.add_argument('--encoder_model',default=models.resnet50(),help="")
parser.add_argument('--temperature',default=0.1,type=int,help="")
parser.add_argument('--encoder_output_dim',default=28,type=int,help="")
parser.add_argument('--lr',default=0.01,type=int,help="")
parser.add_argument('--step_size',default=20,type=int,help="")
parser.add_argument('--gamma',default=0.9,type=int,help="")
parser.add_argument('--num_epochs',default=100,type=int,help="")
parser.add_argument('--filename',default="best_test.pth",type=str,help="")
args = parser.parse_args()


class Config(object):
    # 配置参数
    def __init__(self,args):
        self.batch_size = args.batch_size
        self.num_epochs = args.num_epochs

        train_dataset = torchvision.datasets.MNIST(
            root='./MNIST',
            train=True,
            download=True,
            transform=torchvision.transforms.ToTensor()
        )
        val_dataset = torchvision.datasets.MNIST(
            root='./MNISt',
            train=False,
            download=True,
            transform=torchvision.transforms.ToTensor()
        )

        train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=self.batch_size, shuffle=True,drop_last=True)
        test_loader = torch.utils.data.DataLoader(dataset=val_dataset, batch_size=self.batch_size, shuffle=False,drop_last=True)

        self.dataloaders = {'train': train_loader, 'valid': test_loader}


        # 是否用人家训练好的特征来做
        self.feature_extract = args.feature_extract
        self.encoder_output_dim = args.encoder_output_dim
        self.image_size = args.image_size
        self.filename = args.filename

        # 是否用GPU训练
        train_on_gpu = torch.cuda.is_available()
        if not train_on_gpu:
            print('CUDA is not available.  Training on CPU ...')
        else:
            print('CUDA is available!  Training on GPU ...')
        self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

        # encoder的模型选择
        if args.encoder_model is not None:
            self.encoder_model = args.encoder_model
            self.num_ftrs = self.encoder_model.fc.in_features
            self.encoder_model.fc = nn.Sequential(nn.Linear(self.num_ftrs, self.encoder_output_dim))
            self.contrastive_model = SimCLR(self.encoder_model,self.image_size,self.encoder_output_dim,temperature=args.temperature)
        else:
            self.contrastive_model = None

        # 优化器设置
        # self.optimizer_ft = optim.Adam(self.contrastive_model.parameters(), lr=args.lr)
        # self.set_parameter_requires_grad()
        self.optimizer_ft = optim.SGD(self.contrastive_model.parameters(), lr=args.lr)
        self.scheduler = optim.lr_scheduler.StepLR(self.optimizer_ft, step_size=args.step_size, gamma=args.gamma)  # 学习率每7个epoch衰减成原来的1/10

    def set_parameter_requires_grad(self):
        if self.feature_extract:
            for param in self.encoder_model.parameters():
                param.requires_grad = False

2.模型定义

import torch
from torch import nn
class SimCLR(nn.Module):
    def __init__(
            self,
            encoder,
            image_size,
            encoder_output_dim,
            temperature=0.1
    ):
        super().__init__()
        self.encoder = encoder

        self.mlp = nn.Sequential(
        nn.Linear(encoder_output_dim, encoder_output_dim),
        nn.BatchNorm1d(encoder_output_dim),
        nn.ReLU(inplace = True),
        nn.Linear(encoder_output_dim, encoder_output_dim)
    )

        self.conv1 = nn.Sequential(  # 输入大小 (1, 28, 28)
            nn.Conv2d(
                in_channels=1,  # 灰度图
                out_channels=3,  # 要得到几多少个特征图
                kernel_size=1,  # 卷积核大小
                stride=1,  # 步长
                padding=0,  # 如果希望卷积后大小跟原来一样,需要设置padding=(kernel_size-1)/2 if stride=1
            ),  # 输出的特征图为 (16, 28, 28)
            nn.ReLU()  # relu层
        )

        self.fc1 = nn.Sequential(
            nn.Linear(784,1024),
            nn.ReLU()
        )
        self.fc2 = nn.Sequential(
            nn.Linear(1024,1024),
            nn.ReLU()
        )
        self.fc3 = nn.Sequential(
            nn.Linear(1024,2),
            nn.ReLU()
        )
    # 超简单版本,看看二维效果图
    def forward(self,inputs,input_size):
        device = inputs.device
        input_1,input_2 = torch.split(inputs,[input_size,input_size],dim=0)
        input_1 = input_1.to(device)
        input_2 = input_2.to(device)


        x_1 = input_1.reshape(input_size,-1)
        fc1_1 = self.fc1(x_1)
        fc2_1 = self.fc2(fc1_1)
        output_1 = self.fc3(fc2_1)


        x_2 = input_2.reshape(input_size, -1)
        fc1_2 = self.fc1(x_2)
        fc2_2 = self.fc2(fc1_2)
        output_2 = self.fc3(fc2_2)

        return None , None ,output_1 , output_2
    # resnet50版本
    # def forward(self, inputs, input_size):
    #     device = inputs.device
    #     input_1, input_2 = torch.split(inputs, [input_size, input_size], dim=0)
    #     input_1 = input_1.to(device)
    #     input_2 = input_2.to(device)
    #
    #     hidden_layer_1 = self.conv1(input_1)
    #     hidden_layer_2 = self.conv1(input_2)
    #
    #     hidden_layer_i = self.encoder(hidden_layer_1)
    #     hidden_layer_j = self.encoder(hidden_layer_2)
    #
    #     output_1 = self.mlp(hidden_layer_i)
    #     output_2 = self.mlp(hidden_layer_j)
    #
    #     return hidden_layer_i, hidden_layer_j, output_1, output_2

3.模型训练

import torch
import copy
from config import Config, args
from tqdm import tqdm
import numpy as np
import matplotlib.pyplot as plt

def params_test(model):
    print("Params to learn:")
    params_to_update = []
    for name, param in model.named_parameters():
        if param.requires_grad == True:
            params_to_update.append(param)
            print("\t", name)


def train_model(model, dataloaders, optimizer, device, scheduler, batch_size, num_epochs, filename):
    torch.manual_seed(1)
    best_loss = [9999999999]
    model.to(device)

    train_losses = []
    valid_losses = []
    LRs = [optimizer.param_groups[0]['lr']]

    best_model_wts = copy.deepcopy(model.state_dict())

    for epoch in range(num_epochs):
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 10)

        # 训练和验证
        for phase in ['train', 'valid']:
            if phase == 'train':
                model.train()  # 训练
            else:
                model.eval()  # 验证

            running_loss = 0.0

            # 把数据都取个遍
            for index, (inputs, labels_ground) in enumerate(tqdm(dataloaders[phase])):

                # 只能双数做为训练样本,测试没有训练过的单数数据效果
                # labels = labels_ground[labels_ground % 2 == 0]
                # inputs = inputs[labels_ground % 2 == 0]
                # inputs = inputs.to(device)
                # labels = labels.to(device)
                #
                # if len(labels) % 2 != 0:
                #     inputs = inputs[0:-1,:,:,:]
                #     labels = labels[0:-1,]

                # 训练全部样本
                labels = labels_ground.to(device)
                inputs = inputs.to(device)

                input_size = int(len(labels) / 2)
                label_1, label_2 = torch.split(labels, [input_size, input_size], dim=0)
                label = (label_1 == label_2)
                label = (label+0.0).to(device)

                # 清零
                optimizer.zero_grad()
                # 只有训练的时候计算和更新梯度
                with torch.set_grad_enabled(phase == 'train'):
                    # 查看模型需要训练的参数
                    # params_test(model)
                    _,_,output_1,output_2 = model(inputs,input_size)

                    eucd2 = torch.pow(torch.subtract(output_1, output_2), 2)
                    eucd2 = torch.sum(eucd2, 1)
                    eucd = torch.sqrt(eucd2 + 1e-6)

                    loss_pos = torch.multiply(label, eucd2)
                    loss_neg = torch.multiply(torch.subtract(1.0, label), torch.pow(
                        torch.maximum(torch.subtract(torch.tensor(5.0), eucd), torch.tensor(0)), 2))
                    loss = torch.mean(torch.add(loss_neg, loss_pos))

                    # 训练阶段更新权重
                    if phase == 'train':
                        loss.backward()
                        optimizer.step()

                running_loss += loss.item() * inputs.size(0)
            epoch_loss = running_loss / len(dataloaders[phase].dataset)

            # 得到最好那次的模型
            if phase == 'valid' and epoch_loss < min(best_loss):
                best_loss = valid_losses
                best_model_wts = copy.deepcopy(model.state_dict())
                state = {
                    'state_dict': model.state_dict(),  # 字典里key就是各层的名字,值就是训练好的权重
                    'best_acc': best_loss,
                    'optimizer': optimizer.state_dict(),  # 优化器的状态信息
                }
                torch.save(state, filename)
            if phase == 'valid':
                valid_losses.append(epoch_loss)
                scheduler.step()  # 学习率衰减
            if phase == 'train':
                train_losses.append(epoch_loss)

        LRs.append(optimizer.param_groups[0]['lr'])
        print()
        if phase == 'valid' and epoch % 1 == 0:
            print('episode %d: train loss %.3f' % (epoch, epoch_loss))

    print('Best val Loss: {:4f}'.format(min(best_loss)))



    # 训练完后用最好的一次当做模型最终的结果,等着一会测试
    # model.load_state_dict(best_model_wts)
    return model, valid_losses, train_losses, LRs


if __name__ == '__main__':
    config = Config(args)
    model_ft, valid_losses, train_losses, LRs = train_model(
        config.contrastive_model,
        config.dataloaders,
        config.optimizer_ft,
        num_epochs=config.num_epochs,
        batch_size=config.batch_size,
        device=config.device,
        scheduler=config.scheduler,
        filename=config.filename)


    plt.plot(range(1,len(train_losses)+1),train_losses, color='b', label = 'train_losses')
    plt.legend(), plt.ylabel('loss'), plt.xlabel('epochs'), plt.title('train_losses'), plt.show()

    plt.plot(range(1,len(valid_losses)+1),valid_losses, color='b', label = 'valid_losses')
    plt.legend(), plt.ylabel('loss'), plt.xlabel('epochs'), plt.title('valid_losses'), plt.show()

    plt.plot(range(1,len(LRs)+1),LRs, color='b', label = 'LRs')
    plt.legend(), plt.ylabel('LRs'), plt.xlabel('epochs'), plt.title('LRs'), plt.show()

3.模型测试

import torch
from config import Config, args
import numpy as np
import matplotlib.pyplot as plt
import random
from sklearn.cluster import KMeans, AgglomerativeClustering
from sklearn.mixture import GaussianMixture
# 保存文件的名字

def visualize(embed, labels):

    labelset = set(labels.tolist())

    fig = plt.figure(figsize=(8,8))
    ax = fig.add_subplot(111)

    #fig, ax = plt.subplots()
    for label in labelset:
        indices = np.where(labels == label)
        ax.scatter(embed[indices,0], embed[indices,1], label = label, s = 20)
    ax.legend()
    fig.savefig('embed_2.jpeg', format='jpeg', dpi=600, bbox_inches='tight')
    plt.close()

filename=r'C:\best_test.pth'
# 加载模型
checkpoint = torch.load(filename)
config = Config(args)
config.contrastive_model.load_state_dict(checkpoint['state_dict'])

dataiter = iter(config.dataloaders['valid'])
images, labels = next(dataiter)


result_layer_0,result_layer_1 = config.contrastive_model(images,256)[2],config.contrastive_model(images,256)[3]
output = torch.concat([result_layer_0,result_layer_1],0)
labels = labels.numpy()

#这里写的有点丑....就简单测试一下
one_index = list(np.where(labels == 1)[0])
all_one_tensor = output[one_index]

two_index = list(np.where(labels == 2)[0])
all_two_tensor = output[two_index]

three_index = list(np.where(labels == 3)[0])
all_three_tensor = output[three_index]

four_index = list(np.where(labels == 4)[0])
all_four_tensor = output[four_index]

five_index = list(np.where(labels == 5)[0])
all_five_tensor = output[five_index]

six_index = list(np.where(labels == 6)[0])
all_six_tensor = output[six_index]

seven_index = list(np.where(labels == 7)[0])
all_seven_tensor = output[seven_index]

eight_index = list(np.where(labels == 8)[0])
all_eight_tensor = output[eight_index]

nine_index = list(np.where(labels == 9)[0])
all_nine_tensor = output[nine_index]

zero_index = list(np.where(labels == 0)[0])
all_zero_tensor = output[zero_index]

total_tensor_list = [all_zero_tensor] + [all_one_tensor] + [all_two_tensor] + [all_three_tensor] + [all_four_tensor] + [all_five_tensor] + [all_six_tensor] + [all_seven_tensor] + [all_eight_tensor] + [all_nine_tensor]


#
# 随机抽样法,两两余弦相似度对比,效果还可以
right_num = 0
wrong_num = 0

right_cos_sim = []
wrong_cos_sim = []

index1 = random.sample(range(0,20),20)
index2 = random.sample(range(0,20),20)

for i in range(20):
    right_cos_sim.append(round(torch.cosine_similarity(all_eight_tensor[index1[i]],all_eight_tensor[index2[i]],dim=0).item(),6))
    wrong_cos_sim.append(round(torch.cosine_similarity(all_eight_tensor[index1[i]],all_one_tensor[index2[i]],dim=0).item(),6))
    if torch.cosine_similarity(all_eight_tensor[index1[i]],all_eight_tensor[index2[i]],dim=0) >= \
            torch.cosine_similarity(all_eight_tensor[index1[i]],all_one_tensor[index2[i]],dim=0):
        right_num += 1
    else:
        wrong_num += 1

print(right_num)
print(wrong_num)
print(right_cos_sim)
print(wrong_cos_sim)




# Kmeans纯聚类算法对比
total_data = torch.concat([all_zero_tensor,all_one_tensor,all_two_tensor,all_three_tensor,all_four_tensor,all_five_tensor,all_six_tensor,all_seven_tensor,all_eight_tensor,all_nine_tensor],dim=0).detach().numpy()
total_label_list = list(str(0) * len(all_zero_tensor) + str(1) * len(all_one_tensor) + str(2) * len(all_two_tensor)
                        + str(3) * len(all_three_tensor) + str(4) * len(all_four_tensor)
                        + str(5) * len(all_five_tensor) + str(6) * len(all_six_tensor)
                        + str(7) * len(all_seven_tensor) + str(8) * len(all_eight_tensor)
                        + str(9) * len(all_nine_tensor))
total_label_list = [ int(i) for i in total_label_list]

cluster = KMeans(n_clusters=10).fit(total_data)
cluster_labels = cluster.labels_

print(cluster_labels)

output = output.detach().numpy()
visualize(output, labels)

最后看看模型的测试效果,基本都正确。

在这里插入图片描述
在这里插入图片描述


总结

作者这里没有自己写数据增强,因为默认手写数字之间自带了数据增强的效果,其实也试了加上数据增强,区别不是很大。高维的准确效果肯定比2维的要好,resnet的效果肯定比最简单的MLP层效果好。这是无监督的方法,准确率接近有监督模型,但是如果训练集没有见过的数据,效果会有下降,比如只用双数数字进行训练,测试单数数字的泛化能力。也可以试试其他损失函数效果。
对比学习最大的优势是可以做一个强大的预训练模型,得到一个很好的图片embedding,继续做下游任务。进行各种fine tuning的操作。
大家可以试试,有问题可以留言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对比学习孪生网络之简单的手写数字集代码实战 的相关文章

  • SEC物权链奖金制度分析

    启程SEC物权链是什么 xff1f 靠谱吗 xff1f SEC公链是什么 xff1f 物权链怎么样 xff1f 分析于下 xff1a 一 定位 xff1a 依托原中小企业上市包装辅导策划以及不良资产运作等业务 xff0c 130家实体资产分
  • 基于SSM的个人健康信息管理

    项目背景 随着科学技术的飞速发展 xff0c 通过科技手段提高自身的优势 xff1b 对于个人健康信息管理当然也不能排除在外 xff0c 随着网络技术的不断成熟 xff0c 带动了个人健康信息管理 xff0c 它彻底改变了过去传统的管理方式
  • 基于spring boot的个人博客系统的设计与实现

    末尾获取源码 开发语言 xff1a Java Java开发工具 xff1a JDK1 8 后端框架 xff1a SpringBoot 前端 xff1a Vue 43 HTML 数据库 xff1a MySQL5 7和Navicat管理工具结合
  • day 3

    用栈来做是最简便的 栈 stack 是一种数据结构 xff0c 遵循先进后出的原则 最常用的方法为stack pop弹出最顶部的元素并删除 stack peek弹出最顶部的元素查看 xff0c 但不删除 stack push 添加一个元素
  • java方向笔试强训day6

    分别使用字符串和数组的方式 xff0c 数组更简便一些 import java util Scanner public class test26 将字符串转化为数字 public static int function26 String s
  • equals和==的区别

    equals和 61 61 经常用来去比较两个值或者两个对象 61 61 如果只是用来比较基本数据类型常量 的话 xff0c 那么比较的就是两个常量的值 xff0c 如果用来去比较两个对象引用 xff0c 那么比较的是两个对象的地址 equ
  • java训练day 17 ①杨辉三角(二维数组)②二叉树的镜像(数据结构+递归)

    目录 杨辉三角 二叉树的镜像 杨辉三角 import java util public class Main public static void main String args Scanner scanner 61 new Scanne
  • Linux系统项目部署常见问题

    目录 进入数据库 修改数据库密码 未设置或忘记 部署操作 使用jar包部署和修改操作 使用war包部署 修改端口号 ssm项目打包war包可能遇到问题 进入数据库 没有设置数据库密码则使用 mysql uroot 设置了数据库密码则使用 m
  • 音乐web网站搭建思路

    目录 项目所涉及的页面及对应功能 项目设计思路 数据库设计 Http响应数据格式设计 页面各个功能的请求响应格式设计 1 登录功能 2 上传音乐功能 3 删除音乐功能 4 批量删除音乐 5 查询音乐信息 6 收藏音乐 取消收藏音乐 7 播放
  • 五子棋项目

    目录 核心技术 主要模块和功能 基本思路 注册 登录接口 具体实现 匹配功能接口 具体实现 用户对战接口 具体实现 项目源码Gitee地址 网页版五子棋的基本思路及实现 核心技术 Spring SpringBoot SpringMVCWeb
  • Redis笔记

    Redis 内容来自菜鸟教程 redis部分 REmote DIctionary Server Redis 是一个由 Salvatore Sanfilippo 写的 key value 存储系统 xff0c 是跨平台的非关系型数据库 Red
  • Jmeter接口测试实战练习题及答案(本博客原创·全网首发)

    接口地址 Post xff1a http 10 9 15 72 8093 Api PayGateway 接口参数 参数名 参数值 说明 SystemCode Alipay 系统代码 plateformCode Alipay 平台代码 ser
  • 《操作系统》-生产者消费者问题

    什么是生产者消费者问题 xff1f 系统中有一组生产者进程和一组消费者进程 生产者进程每次生产一个产品放入缓冲区 xff0c 消费者进程每次从缓冲区中取出一个进程并使用 xff0c 那么他们之间具有这样一层关系 生产者 消费者共享一个初始为
  • 普通类和抽象类的区别

    普通类和抽象类的区别 抽象类普通类普通类和抽象类的区别总结 抽象类 含有抽象方法的类就叫抽象类 而抽象方法就是被abstract修饰的方法 xff0c 这个方法可以没有具体的实现 在抽象类的子类中必须对抽象方法进行重写 xff0c 当其子类
  • PowerShell 安装、配置和美化

    文章目录 安装 Windows TerminalPowerShell 7安装 PowerShell 7查看版本Winget 安装安装 MSI 包 配置开启 PSReadLine 2 1 预测性 IntelliSense其他配置 美化手动安装
  • c++学习笔记(八)程序一闪而过怎么办?如何让命令提示符暂停?

    在使用控制台输出的时候 xff0c 你可能经常遇到还没有看清楚输出结果如何就自动退出的情景 这很令人头疼 xff0c 下面我就介绍几种方式避免控制台退出 当然你使用CLion可以不写 xff0c 节约时间 xff0c 但是也要知道 xff0
  • Zabbix 6.0 图文安装部署讲解---LNMP环境

    Zabbix 6 0 图文安装部署讲解 LNMP环境 简介环境需求部署环境关闭系统防火墙一 Mysql8 0 30 部署 二 nginx 部署三 PHP 部署四 zabbix server 部署五 Web端初始化六 解决zabbix 6 0
  • Hive 不同级别日志配置 hive-log4j2.properties

    span class token comment Licensed to the Apache Software Foundation ASF under one span span class token comment or more
  • 飞机订购票系统(数据库课程大作业)

    一 需求分析 nbsp 1 1 功能需求及描述 nbsp nbsp nbsp nbsp 通过对机票预定业务的调查 明确了飞机订购票系统共包括乘客信息模块 航班信息模块 机票订购模块 机票退票模块以及取票信息模块五个模块 图1 1 总体功能模
  • 本地与linux服务器文件互传(超简单)

    利用系统自带的命令行窗口powershell上传 xff08 win10以上系统自带的 xff0c 系统级应用 xff0c 十分推荐使用 xff09 在这Linux 用户名 xff1a hadoop ip 192 168 53 20 打开搜

随机推荐

  • 【剑指offer系列】剑指offer 03-06

    这次我们来讲解剑指offer的全部题目 xff0c 今天是第一天 xff0c 我们来讲解第三题到第六题 xff08 我也不清楚为什么力扣上查不到第一题和第二题 xff09 一 剑指offer 03 题目链接 xff1a 力扣 题目描述 xf
  • 什么是scrum中的3355

    scrum的3355是指 xff1a 3个工件 xff1a 产品Backlog Sprint Backlog 潜在可交付软件增量 3个角色 xff1a PO Master 团队 xff08 最适合人数为7 2到7 43 2之间 xff09
  • 搭建ant+jenkins+jmeter自动化接口测试框架(详细篇)

    引言 为什么要持续集成 1 减少风险 2 减少假定 3 减少重复过程 4 增强项目的可见性 5 持续集成可以带来两点积极效果 xff1a 1 有效决策 xff1a 持续集成系统为项目构建状态和品质指标提供了及时的信息 xff0c 有些持续集
  • Linux C生产者和消费者(线程)

    生产者和消费者 生产者消费者问题实现目标原理代码 生产者消费者问题 生产者消费者共享缓冲区 xff0c 生产者向缓冲区中放数据 xff0c 消费者从缓冲取中取数据 xff0c 当缓冲区中被放满时 xff0c 生产者进程就必须进入挂起状态 x
  • HPE DL388GEN9 /windows server 2012r2 重置管理员密码/忘记管理员密码

    有台HPE DL388GEN9 windows server 2012r2的主机 xff0c 不知道密码 从CSND上查了有人可以通过U盘PE进去用工具去改掉 实测 xff0c 难以进入PE xff08 也可能是我操作有问题 xff09 x
  • ArchLinux,ManjaroLlinux安装,运行Android软件。安装anbox(详细)

    安装anbox我也是用了一个下午的时间来进行安装 xff0c 因此我做了一下总结 xff0c 方便大家安装 这个安装教程arch和manjaro都是可以实现的 xff0c 因为manjaro是arch的分支 xff0c 同样也可以使用anb
  • ArchLinux的安装(BIOS引导方式安装)

    archlinux的安装对于很多新手朋友很不友好 xff0c 于是我对archlinux的安装做了一下整理 xff0c 方便大家安装 安装之前我们需要准备一下 xff1a archlinux的镜像iOS文件 U盘 xff0c 或者虚拟机 脑
  • 汇编语言,and、or指令

    and 和 or指令 and指令 xff0c 作用按位与运算 mov ax 1011 1100b mov bx 1100 1011b and ax bx ax的结果为 xff1a 1000 1000 or指令 xff0c 作用 xff1a
  • 解决wget错误:ERROR: The certificate of ‘xxx’ is not trusted.

    使用wget出现以下错误 wget https github com mozilla geckodriver releases download v0 31 0 geckodriver v0 31 0 linux64 tar gz ERRO
  • git 报错SSL certificate problem: unable to get local issuer certificate解决办法

    git中的SSL certificate problem unable to get local issuer certificate错误的解决办法 uManBoy 这是由于当你通过HTTPS访问Git远程仓库的时候 xff0c 如果服务器
  • Linux 对整个系统备份和还原

    对系统进行备份非常的重要 xff0c 如果有一天 xff0c 系统崩溃了 xff0c 可以重装系统 xff0c 但是重装系统后又需要进行相关的配置 xff0c 这会显得非常的麻烦 xff0c 又会浪费很多的时间 备份的方式 xff1a 分两
  • Win11安装python-3.11.1

    注意整个安装过程需要联网 xff01 xff01 xff01 python 3 11 1下载地址 xff1a https www python org ftp python 3 11 1 python 3 11 1 amd64 exe 1
  • 三分钟记住20道性能测试经典面试题

    1 什么是性能测试 xff1f 测试系统有没有性能问题 考虑时间 xff0c 空间 服务端资源是否足够 响应时间是否超时 系统是否足够稳定 2 性能测试的应用领域有哪些 xff1f 能力验证 xff1a 乙方向甲方交付项目时 xff0c 声
  • C++ 对数组的快速排序算法

    include 34 stdio h 34 交换两个数 void swap int amp a int amp b int t 61 a a 61 b b 61 t 根据第一个数 xff0c 把小于第一个数的数放在前面 xff0c 把打印第
  • C++ 广度优先搜索,搜索二叉树,并且打印

    广度优先搜索 xff08 BFS xff09 什么是广度优先搜索 广度优先搜索就是层序遍历 xff0c 一层一层的搜索整个图 BFS的代码实现 使用数组实现静态的二叉树 xff0c 树的结构如下显示 代码如下显示 include 34 st
  • C++ 得到下一天的年月日的函数

    include 34 iostream 34 include 34 string 34 include 34 stdio h 34 using namespace std 得到下一个日期 void next day int amp year
  • 树莓派使用Thonny学习笔记1

    来C站这么久了 xff0c 最近在初学树莓派Raspberry Pi PIco 所以想在C站记录一下自己的学习过程 xff0c 到时候能回头看看自己的学习之路 今天学习了如何新建全局变量与按键输入模式 xff0c 和IO的输出模式配置 xf
  • error while loading shared libraries: librosconsole.so: cannot open shared object file: No such file

    错误背景 xff1a linux下运行ros相关文件出错 错误意思 xff1a Linux下这个的错误的大概意思还是路径问题 xff0c 要么是你下载的库真的不存在 xff0c 要么是没有添加环境变量 xff0c 不过大多数都属于后者 一
  • Python之多线程爬虫实践

    多线程爬虫实践 一 多线程的介绍及threading的基本使用1 什么是多线程 xff1f 2 如何创建一个基本的多线程 xff1a 二 使用Thread类创建多线程1 查看当前线程2 继承自threading Thread类 三 多线程共
  • 对比学习孪生网络之简单的手写数字集代码实战

    对比学习孪生网络 注 xff1a 大家觉得博客好的话 xff0c 别忘了点赞收藏呀 xff0c 本人每周都会更新关于人工智能和大数据相关的内容 xff0c 内容多为原创 xff0c Python Java Scala SQL 代码 xff0