声音生成项目(6)——在矢量量化变分编码器上使用自回归模型PixelCNN模型生成新的样本

文章目录

      • 引言
      • PixelCNN论文简读
      • 模型介绍
        • 自回归模型
        • PixelCNN
          • 模型结构
        • 基础知识回顾
      • 代码实现
        • PixelConvLayer
        • 具体运行过程
        • 卷积模块
        • 整体网络结构
      • 模型执行效果
      • 问题解决
        • 训练好的模型在生成新的图片时,为什么要逐个元素进行生成?
          • 掩码卷积仅仅是考虑了一部分的数据,并没有考虑当前像素之前所有的像素?
      • 总结
      • 参考连接

引言

  • 在上一篇就是介绍了矢量量化变分模型的具体实现,就是一个编码器和解码器,只能生成和原来图片一样的图片,没啥意义。这里需要生成一个新的码字序列,解码器能够接受这部分数据,然后解码成对应的新的图片。

  • 作者使用PixelCNN去训练这些码本

    • pixelCNN的论文链接
    • 代码样例
  • PixelCNN是一个自回归模型,根据已有的序列生成下一个位置的值。在这个任务里,就是生辰新的码字序列,然后使用训练好的解码器生成对应的新的图片。

  • 注意:

    • 这里的代码是局部代码,是vqvae项目中的一部分,是生成新的索引序列,并不是原来的图片 ,最后还是需要一个解码器来将索引序列还原成对应的图片。
    • 项目地址,vqvae生成手写字符的地址

PixelCNN论文简读

  • Abstract
    • 这篇文章主要讲的是根据PixelCNN按照条件生成图片。这个模型可以根据向量,描述性的符号或者标记,甚至是别的网络模型生成的潜在embedding来生成新的图片。这个模型可以根据ImageNet中数据的类别标记,生成逼真并且完全不同的图片。如果输入模型的是一个其他卷积网络生成的embedding,并且这个embedding是表示人脸的,他会自动生成具有不同面部表情、姿势和光照条件的,同一个人的不同的各种新的画像。PixelCNN在图片自编码器中,也可以当作一个强大的图片解码器使用。
  • Introduction
    • 图片生成应用广泛,常见的比如说降噪、去模糊、修复、超分辨和着色都是使用图片生成技术,他们都需要根据不完整的图片或者带有噪声的图片来生成原始的图片。
    • 这篇文章改良PixelRNN中的卷积变量实现的,基本的思路是使用自回归链接逐个像素对图片进行建模,将联合图像分布,分解成条件概率分布的乘积。原文中主要有两个变种,分别是PixelRNN,是使用LSTM进行预测,PixelCNN是使用卷积进行预测。
    • 我们还引入了门控PixelCNN(条件PixelCNN)的条件变体,它允许我们在给定潜在向量嵌入的情况下对自然图像的复杂条件分布进行建模。我们表明,通过简单地对类的 one-hot 编码进行条件调节,可以使用单个条件 PixelCNN 模型从狗、草坪扇和珊瑚礁等不同类别的图像生成图像。类似地,可以使用捕获图像高级信息的嵌入来生成具有各种具有相似特征的图像。这让我们深入了解嵌入中编码的不变性——例如,我们可以根据单个图像生成同一个人的不同姿势。相同的框架也可用于分析和解释深度神经网络中的不同层和激活。

模型介绍

  • 本来是想读论文的,一看已经是2016年的文章了,网上已经有很多相关的介绍了。
  • PixelCNN是通过链式法则,将概率密度转成一系列条件概率之积,然后通过网络来估计条件分布。

自回归模型

  • 自回归创建一个显式密度模型,该模型学习训练数据的最大似然。但是处理多个维度\特征的数据时,需要完整如下的步骤

    • 首先,输入空间需要为其特征确定顺序,对于图像而言,通过像素的空间位置,来定义顺序,左侧像素在右侧像素之前,顶部像素在底部像素之前等。
    • 其次,自回归模型需要将特征的联合分布p(x)转换为条件分布的乘积,以对数据观察中的特征的联合分布进行精确建模。
    • 给定先前特征的值,自回归模型使用每一个特征的条件定义联合分布
  • 图像中某一个像素具有特定强度值的概率由先前像素的值确定

  • 图像的概率(所有像素的联合分布)是其所有像素的概率的组合

  • 因此,自回归模型使用链式法则,将数据样本x的可能性分解成一维分布的乘积,将联合建模问题变成了序列问题,学习了在给定所有先前像素的情况下,预测下一个像素的过程。

在这里插入图片描述

PixelCNN

  • PixelCNN是生成神经网络,一次生成一个像素,并且使用之前已经训练好的像素去生成下一个像素,类似于根据一个序列,去预测下一个像素点的值。如下图,是使用蓝色的像素块,来预测红色的像素块。

在这里插入图片描述

  • 因为常规的卷积是计算周围所有的像素点,和PixelCNN的预测方式不同,所以这里出现了掩码卷积,来控制没有被预测的像素点。主要有两类掩码卷积类型,分别如下
    • Mask Type A仅仅是用于第一层卷积,中间值被屏蔽,因为没有预测过
    • Mask Type B可以用于出第一层以外的所有的层卷积,除了第一层,后续每一层的自身值都是被预测过的。

在这里插入图片描述

模型结构
  • 第一层使用77的A类型掩码卷积模块,然后使用15个残差模块。每一個残拆模块的构成图如下,使用33的B类型的掩码卷积模块,首尾两个1*1的卷积模块。

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

  • 经历过残差序列模块的处理之后,经过两个带有relu的1*1的卷积层,然后经过softmax进行输出,预测像素所有可能的预测值。模型的输出是具有与输入图像大小相同的格式乘以可能值的数量。

基础知识回顾

  • 极大似然:利用已知样本结果信息,反推最具有可能导致当前样本结果的模型参数值。相当于数据的样本是已经知道的,对应的模型分布类型不知道,缺的是对应类型的模型参数,所以是根据样本估计模型参数。
  • 概率和统计
    • 概率:已知模型和参数,推断数据的分布。
    • 统计:已知数据的具体内容,推断具体模型和参数。
  • 联合概率和条件概率
    • 联合概率:同一个时间,两个独立事件同时发生的可能性,事件相交的概率
    • 条件概率:P(B|A)事件B在事件A发生的情况下,B发生的概率。两个相依事件的联合概率变为P(A 和B)= P(A)P(B | A)
  • 贝叶斯公式
    • 后验概率等于先验概率乘以似然比
    • P(H|E)=P(H)P(E|H)/P(E)
  • 先验概率和后颜概率
    • 后验概率:所有证据被采用之后,事件发生的概率
    • 先验概率:未采用证据之前,事件发生的概率,经验性概率
    • 后验概率= (可能性*先验)/证据
  • 最大似然估计
    • 根据样本,也就是数据,来估计模型的参数,使得似然函数的值最大

代码实现

PixelConvLayer

  • 这部分就是掩码卷积,通过之前已经预测的点的概率,来预测当前的点。在原来的卷积上,增加了一个掩码的部分。
  • 主要是两类,差别在于A类中心点的坐标并没有标记,B类的中心点已经被预测过的,具体看上面的图。
# 掩码卷积
class PixelConvLayer(Layer):
    """
    掩码卷积层,分别是两种类型,A类和B类
    """
    def __init__(self,mask_type,**kwargs):
        super().__init__()
        self.mask_type = mask_type
        self.conv = Conv2D(**kwargs)
        self.mask = None

    def build(self,input_shape):
        # 创建二维卷积层,并初始化对应的卷积核权重参数
        self.conv.build(input_shape)
        kernel_shape = self.conv.kernel.get_shape()
        # 生成同等大小的掩码层,用来抑制没有预测的卷积层
        self.mask = np.zeros(shape = kernel_shape)
        self.mask[:kernel_shape[0] // 2,...] = 1.0
        self.mask[kernel_shape[0] // 2,:kernel_shape[1] // 2,...] = 1.0
        if self.mask_type == "B":
            self.mask[kernel_shape[0] // 2,kernel_shape[1]//2,...] = 1.0

    def call(self,inputs):
        # 根据掩码层,来修改更正卷积层的结果
        self.conv.kernel.assign(self.conv.kernel * self.mask)
        return self.conv(inputs)

具体运行过程

  • 这里用一个33的掩码卷积作为样例,对一个88的图片,进行A类型的掩码卷积,然后使用的padding模式是same.这里并不是完全的使用之前所有的已经预测过的标记点,进行预测当前的标记点,是根据卷积核中的已经预测过的点进行预测,具体过程如下:
  • 第一次预测红框中心的点

在这里插入图片描述

  • 后续,第一个位置已经被预测过了,就会考虑到第一个点的预测结果
    在这里插入图片描述
  • 以此类推,不断向后迭代

在这里插入图片描述

  • 最多的情况下,就是考虑了四个点的情况

在这里插入图片描述

  • 代码主要有两部分构成,分别是掩码和前向传播的实际计算
# 掩码卷积
class PixelConvLayer(Layer):
    """
    掩码卷积层,分别是两种类型,A类和B类
    """
    def __init__(self,mask_type,**kwargs):
        super().__init__()
        self.mask_type = mask_type
        self.conv = Conv2D(**kwargs)
        self.mask = None

    def build(self,input_shape):
        # 创建二维卷积层
        self.conv.build(input_shape)
        kernel_shape = self.conv.kernel.get_shape()
        # 将卷积层改成,掩码卷积,这里是生成掩码层
        self.mask = np.zeros(shape = kernel_shape)
        self.mask[:kernel_shape[0] // 2,...] = 1.0
        self.mask[kernel_shape[0] // 2,:kernel_shape[1] // 2,...] = 1.0
        if self.mask_type == "B":
            self.mask[kernel_shape[0] // 2,kernel_shape[1]//2,...] = 1.0

    def call(self,inputs):
        self.conv.kernel.assign(self.conv.kernel * self.mask)
        return self.conv(inputs)

卷积模块

  • 这部分就是在原来的基础上,使用残差网络将B类的掩码卷积套在残差模块中,具体形成如下
    • 首尾分别是两个1*1的卷积
    • 中间是3*3的B类掩码卷积

在这里插入图片描述

class ResidualBlock(Layer):
    """
    基于掩码卷积层的残差模块
    """
    
    def __init__(self,filters,**kwargs):
        super().__init__()
        # 第一个卷积模块
        self.conv1 = Conv2D(
            filters = filters,kernel_size = 1,activation="relu"
        )
        # 中间的B类掩码卷积,进行概率估计
        self.pixel_conv = PixelConvLayer(
            mask_type="B",
            kernel_size = 3,
            activation = "relu",
            padding = "same",
            filters = filters // 2
        )
        # 最后一个卷积模块
        self.conv2 = Conv2D(
            filters = filters,kernel_size = 1,activation="relu"
        )

    def call(self,inputs):
    # 前向传播中,数据传播的方式
        x = self.conv1(inputs)
        x = self.pixel_conv(x)
        x = self.conv2(x)
        # 残差模块中的直连
        res = add([inputs,x])
        return res

整体网络结构

  • 具体网络结构如下图,但是教程的代码实现起来最后做了修改,我是觉得如果使用11的掩码卷积其实和常规的11的卷积是一个效果
    在这里插入图片描述
class PixelCNN:
    """
    PixelCNN:像素卷积模型
    功能:用于生成新的码本序列
    """

    def __init__(self,
                 input_shape,
                 num_residual_blocks,
                 num_pixelcnn_layers,
                 num_embeddings
                 ):
        self.input_shape = input_shape
        self.num_residual_blocks = num_residual_blocks
        self.num_pixelcnn_layers = num_pixelcnn_layers
        self.num_embeddings = num_embeddings

        # 定义不同的层
        self.model = None

        # 构建模型
        self._build()


    def _build(self):
        """
        网络结构为:Aconv3*3,residual815,Rconv,Rconv,Softmax
        :return:
        """
        PixelCNN_Input = Input(shape = self.input_shape,name = "PixelCNN input")
        x = PixelConvLayer(mask_type="A",
                           filters = 128,
                           kernel_size = 7,
                           strides = 1,
                           activation = "relu",
                           padding = "same"
                           )(PixelCNN_Input)
        # 添加卷积模块
        for i in range(self.num_residual_blocks):
            x = ResidualBlock(filters = 128)(x)

        # 添加后续的像素卷积层
        for i in range(self.num_pixelcnn_layers):
            x = PixelConvLayer(
               mask_type="B",
               filters = 128,
               kernel_size = 1,
               strides = 1,
               activation = "relu",
               padding = "valid"
            )(x)

        out = Conv2D(
            filters=1,
            kernel_size=1,
            strides=1,
            activation="sigmoid",
            padding="valid"
        )(x)
        self.model = Model(PixelCNN_Input,out)

    def summary(self):
        self.model.summary()

    def compile(self, learning_rate=0.0001):
        """ 指定损失函数和优化器,并对模型进行优化 """
        optimizer = Adam(learning_rate=learning_rate)
        self.model.compile(
            optimizer=optimizer,
            loss="binary_crossentropy",
        )

    # 3.3 增加训练函数
    def train(self, x_train, batch_size, num_epochs):
        self.model.fit(
            x_train,
            x_train,
            batch_size=batch_size,
            epochs=num_epochs,
            shuffle=True
        )

模型执行效果

在这里插入图片描述

  • 这里生成的模型比较简单,没有按照他的弄了几层。

问题解决

训练好的模型在生成新的图片时,为什么要逐个元素进行生成?

  • 模型在训练的过程中,会逐个预测每一个像素的像素值的概率分布,然后计算预测结果和真实值之间的差异,也就是损失函数,然后使用反向传播来更新模型的参数,使得模型预测的每一个像素的概率分布能够更加接近真实的像素值。对于这个手写数字生成的模型而言,是使用交叉熵损失函数来当作损失函数。如下图

在这里插入图片描述

  • 所以,训练过程中,使用多重掩码卷积逐个扫描每一个区域,预测出一个和输入图像同样大小的结果,然后计算输出图像和输入图像的像素误差。在生成过程中,一开始给的序列是空白序列,所有的像素值都是无效的,如果像训练过程一样,直接生成完整的子图,那么后续像素所参考的像素就没有任何意义,参考价值就不大。生成的图片如下图

在这里插入图片描述

  • 而逐个元素进行生成确认,即迭代生成每一个元素,并将当前元素加入到序列中,重新进行预测。后续生成的序列会和之前的生成的像素值相关,也就是后续的像素值,有之前的像素值决定。如下图。

在这里插入图片描述

  • 生成的效果明显就要好很多,如下图。

在这里插入图片描述

  • 说白了,在训练过程中,用的是极大似然估计,调整模型的参数,使得模型的效果尽可能地好,预测的结果尽可能地贴近实际的图片,这里还没有用到具体的条件概率,然后在预测的过程中,迭代逐个像素进行预测,就用到了条件概率,由之前预测的像素值,来决定之后的像素值。
掩码卷积仅仅是考虑了一部分的数据,并没有考虑当前像素之前所有的像素?
  • 问题:我们知道,PixelCNN的原理是将联合分布拆解成多个条件概率的分布,也就是说预测每一个像素需要考虑之前每一个值,但是掩码卷积仅仅是使用了卷积核之内的数据,并没有考虑到每一个数据。

  • PixelCNN使用了掩码卷积(masked convolution)来限制卷积核只能看到先前生成的像素值,从而确保每个像素的生成仅依赖于其前面的像素。确实并不能考虑到之前所有的像素点,只能考虑到当前像素点的感受野中的元素,还是条件概率,但是并不是之前所有的像素点。

  • 具体可以看这个图片,五角星的那个像素点,确实只能考虑圆圈圈出来的点,计算他们的条件概率,并不能考虑到没有圈处来的其他的点,但这是只有一层卷积,如果有多层卷积,感受野会更大,考虑的也会更加全面。

在这里插入图片描述

  • 如果是二层卷积,可以看到他的感受野更大了,所以能够考虑到的像素点越多。

在这里插入图片描述

  • 通过使用掩码卷积,PixelCNN可以将联合分布拆解成多个条件概率的分布,从而将生成过程转化为逐个像素的条件生成。在预测每个像素的时候,模型只考虑了之前已经生成的像素值,并没有考虑到后面的像素值。
  • 掩码卷积保证了模型的生成过程是自回归的,能够逐步地生成图像,并且可以捕捉到像素之间的条件依赖关系。每个像素的生成都受限于其前面已经生成的像素,确保了生成的图像具有一致性和合理性。
  • 需要注意的是,掩码卷积仅在训练过程中使用,用于限制卷积核的感受野。在生成过程中,模型可以自由地逐个像素生成,而不受掩码卷积的限制。
  • 因为生成图片的过程中,是迭代预测生成了每一个像素,每一个像素都要做一次完整的预测迭代,所以是不受掩码卷积的限制。
  • 总结起来,PixelCNN使用掩码卷积将联合分布拆解成条件概率分布,并通过逐个像素的条件生成来保持自回归性质。掩码卷积限制了卷积核只能看到先前生成的像素值,从而确保每个像素的生成仅依赖于其前面的像素。

总结

  • 一开始这里弄了很久都没有弄懂,尤其是条件概率那里,我知道他是考虑了之前所有的像素点,也理解掩码卷积,但是就是不理解为什么生成的时候要逐个元素进行预测,预测那么多次,现在理解了。通过做实验可以知道,这样的效果更好,而且最终生成的像素也完全不受感受野的大小,完全考虑到了所有的确定的像素点。
  • 同时这样给出了一个思路,对于第一个像素点,随即指定不同的初值,可以生成不同风格,不同类型的数据。同时可以适当减少预测的类别,来提高准确率,但是要对数据尽心有效的分割,能够分成不同的部分。
  • 这一章拖了蛮久的,终于写完了,找机会录一个视频,发一下。代码还是要好好写一下。

参考连接

  • 参考并引用下述文章的内容
    • 生成模型之PixelCNN
    • 什么是PixelCNN
    • 自回归模型–PixelCNN

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

R语言实现SMOTE与SMOGN算法解决不平衡数据的回归问题

本文介绍基于R语言中的UBL包,读取.csv格式的Excel表格文件,实现SMOTE算法与SMOGN算法,对机器学习、深度学习回归中,训练数据集不平衡的情况加以解决的具体方法。 在之前的文章Python实现SMOGN算法解决不平衡数据的回归问题&#x…

Spring初识(二)

前言 经过前面的学习,我们已经知道spring就是包含了众多方法的Ioc,那么既然是容器,就具备两个功能,我们接下来就是要介绍以下两个功能: 1.将对象存储到容器(spring)中: 2.从容器(spring)中将对象取出来. 这两个功能就应发出来,spring的创建和使用. 一.Spring创建 我们先来说…

Ubuntu关闭自动休眠

一、查看当前休眠模式 使用systemctl status sleep.target 命令查看当前休眠模式,结果如下图,sleep状态为enabled,表示自动休眠模式开启。 二、关闭自动休眠模式 使用sudo systemctl mask sleep.target suspend.target 关闭休眠模式 三…

面向初学者的卷积神经网络

卷积神经网络在机器学习中非常重要。如果你想做计算机视觉或图像识别任务,你根本离不开它们。但是很难理解它们是如何工作的。 在这篇文章中,我们将讨论卷积神经网络背后的机制、它的优点和应用领域。 什么是神经网络? 首先,让…

【ACM】—蓝桥杯大一暑期集训Day2

🚀欢迎来到本文🚀 🍉个人简介:陈童学哦,目前正在学习C/C、Java、算法等方向,一个正在慢慢前行的普通人。 🏀系列专栏:陈童学的日记 💡其他专栏:CSTL&#xff…

MySQL-分库分表详解(二)

♥️作者:小刘在C站 ♥️个人主页: 小刘主页 ♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生! ♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏&#xf…

Xcode报错--访问keychain,出现弹窗处理方案

情景 访问keychain弹出弹窗&#xff0c;不想人工点击&#xff0c;比如自动化测试中使用keychain中的证书的情况 原因 Mac的保护机制 处理 1、人工&#xff1a;输入Password&#xff0c;点击Allow或者Always Allow 2、命令行处理 security unlock-keychain -p "<…

Spring Batch之读数据库——JdbcCursorItemReader之自定义PreparedStatementSetter(三十八)

一、自定义PreparedStatementSetter 详情参考我的另一篇博客&#xff1a; Spring Batch之读数据库——JdbcCursorItemReader&#xff08;三十五&#xff09;_人……杰的博客-CSDN博客 二、项目实例 1.项目实例 2.代码实现 BatchMain.java&#xff1a; package com.xj.dem…

docker的安装以及常用命令详解

目录 一、docker简介 二、docker安装 三、常用命令 1、显示 Docker 版本信息 2、显示 Docker 系统信息&#xff0c;包括镜像和容器数 3、帮助 四、镜像管理 1、列出镜像 2、获取一个新的镜像 3、查找镜像 4、删除镜像 5、镜像导入与导出 五、容器生命周期 1、运行…

小程序form表单验证,validate 在更新数据以后不能验证?还是提示同样的错误

报错&#xff1a; 一直报手机号码必须填写&#xff0c;但是我已经填写了。 解决&#xff1a; 花了2个小时&#xff0c;最后发布是模式models写错了。 改完之后&#xff0c;终于提示别的错误了&#xff1a; 源码&#xff1a; //wxml <view class"welcome">欢…

安装Visual Studio Installer Projects 2022插件

VS主界面--扩展--管理扩展--搜索VS插件“Visual Studio Installer Projects 2022”并安装。

【多模态】1、几种多模态 vision-language 任务和数据集介绍

文章目录 一、Phrase Grounding1.1 概念介绍1.2 常用数据集介绍 二、Referring Expression Comprehension&#xff08;REC&#xff09;2.1 概念介绍2.2 常用数据集介绍 三、Visual Question Answer&#xff08;VQA&#xff09;3.1 概念介绍 四、Image Caption4.1 概念介绍 现在…

cookie 生命周期和cookie有效路径超级详细讲解

文章目录 cookie 生命周期和cookie有效路径超级详细讲解cookie 生命周期介绍代码示例完成测试 , 注意抓包看数据 cookie 有效路径有效路径规则规则如下:代码示例完成测试 , 注意抓包看创建 Cookie 时,返回的数据完成测试 , 注意抓包看读取 Cookie 时,返回的数据 代码示例html页…

bug:file name too long文件名超出系统最大限制

各操作系统支持最长的文件和目录名称长度&#xff08;Linux、Win、Mac&#xff09; 今天开发需求的时候发现无法新建文件&#xff0c;提示file name too lang&#xff0c;于是翻阅和查询了一些资料&#xff0c;发现不同操作系统下文件名和目录名最长的长度不同。 操作系统文件名…

elementUI 非表单格式的校验

在普通表单中对输入框、选择框都有校验案例。 但是在自定义非空中如何进行校验官网并没有说明 关键代码 clearValidate 方法清除校验 this.$refs.formValue.clearValidate(signinimg) 使用案例 <template><div class"stylebg"><Tabs icons"el-…

.net6中WPF的串口通信和USB通信

之前写过串口通信&#xff0c;不过是winform的。 c#使用串口进行通信_c# 串口通信_故里2130的博客-CSDN博客 今天说一下&#xff0c;.net6中wpf的串口通信和USB通信&#xff0c;在工控行业中&#xff0c;这2种的方式非常多&#xff0c;还有网口通信&#xff0c;它们都是用来和…

利用ChatGPT场景化学习英语听说读写

大家好&#xff0c;我是可夫小子&#xff0c;关注AIGC、读书和自媒体。解锁更多ChatGPT、AI绘画玩法。加我&#xff0c;备注&#xff1a;chatgpt&#xff0c;拉你进群。 我们从初中就开始学习英语&#xff0c;到大学也有小十年&#xff0c;在这个过程中&#xff0c;我们投入了很…

提高驾驶安全性 | 基于ACM32 MCU的胎压监测仪方案

概述 作为车辆的基础部件&#xff0c;轮胎是影响行车安全不可忽视的因素之一。据统计&#xff0c;中国每年由胎压问题引起轮胎爆炸的交通事故约占 30%&#xff0c;其中 50%的高速交通事故是由车辆胎压异常引起。因此&#xff0c;准确实时地监测车辆在行驶过程中的轮胎压监测系…

Java List中通过对象属性排序,可实现多条件排序

直接上代码&#xff1a; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Data;import java.util.Comparator; import java.util.List; import java.util.stream.Collectors;/*** List 对象属性排序*/Data AllArgsConstructor clas…

【Linux】进程概念

【Linux】进程概念 文章目录 【Linux】进程概念1、冯诺依曼体系结构2、操作系统2.1 概念2.2 设计OS的目的2.3 定位2.4 管理2.5 系统调用和库函数概念 3、进程3.1 基本概念3.2 描述进程—PCB3.3 组织进程3.4 查看进程3.5 获取进程标示符3.6 创建进程-fork初识3.7 进程状态3.7.1 …
最新文章