请你作为一个代码翻译解释生成器,下面我会发送一个github链接给你,请你详细解析与介绍这个链接下代码

好的,请发送链接。

https://github.com/huggingface/transformers/blob/main/src/transformers/models/blip_2/

这是Hugging Face开发的transformers库中的一个模型: “BLiP-2”。

“BLiP”代表“Bidirectional Language-Independent Parser”,是一个用于自然语言处理的模型。该模型使用了自注意力机制(self-attention),可以自动地对输入语句进行编码,从而提取出其语言特征。

在这个链接中,我们可以看到一些文件和文件夹,这些都是与BLiP-2模型有关的代码和数据。其中,modeling_blip_2.py文件定义了BLiP-2模型的架构,包括了embedding、Self-Attention、全连接层等。

training_args_blip_2.py文件包含了用于训练模型时的参数,例如batch size、epochs、learning rate等。

config_blip_2.json文件则是该模型的配置文件,包含了模型的参数设置,输入和输出的最大长度和词表的大小等。

此外,还有一些用于测试和评估模型的文件,例如run_glue_blip_2.pyrun_qa_blip_2.py

总体来说,这个链接下的代码是与BLiP-2模型有关的,包含了模型的架构、训练参数、配置文件以及用于测试和评估模型的代码。

能否介绍地更详细一些,请分别根据每个文件的代码进行解析,让我们一步步来分段输出

好的,让我们一步步来解析这些文件的代码。

首先,modeling_blip_2.py文件定义了BLiP-2模型的架构。整个模型由BLiP2Model类实现,该类继承自PreTrainedModel类,后者是Hugging Face官方库transformers提供的通用模型类,它实现了许多模型共有的方法和属性。

BLiP-2模型的架构主要包含三个部分:Embedding层、Self-Attention层和全连接层。其中,Self-Attention层是BLiP-2模型的核心,它使用Transformer结构进行实现。

Embedding 类定义了模型的Token Embedding和Position Embedding,它们对应模型的输入Token和位置信息的嵌入层。SelfAttention 类则定义了Multi-Head Self-Attention层。MLP 类则实现了全连接层。

training_args_blip_2.py文件中定义了模型训练和优化所需的各种参数,例如训练时的batch size,最大的训练epoch数量,学习率等。

config_blip_2.json文件定义了BLiP-2模型的各种超参数,例如输入的最大长度、输出的最大长度、词表的大小、self-attention层的头数等。这些超参数可以用于初始化BLiP2Config类的实例,该实例可以在模型构建的时候使用。

run_glue_blip_2.pyrun_qa_blip_2.py是用于测试和评估模型的脚本文件。run_glue_blip_2.py定义了GLUE任务(General Language Understanding Evaluation)中的训练和测试过程,run_qa_blip_2.py则定义了回答问题任务的训练和测试过程。

综上所述,这些文件相互之间是紧密关联的,通过它们我们可以了解到BLiP-2模型的架构、参数、输入输出格式以及如何用Hugging Face库进行模型训练和评估。

这段代码定义了一个名为Blip2Processor的类,它继承自ProcessorMixin类,并实现了一个用于处理图像和文本的处理器,同时将BlipImageProcessorAutoTokenizer两个类封装在一起。下面逐行解释代码:

from typing import List, Optional, Union
from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding, PaddingStrategy, PreTokenizedInput, TextInput, TruncationStrategy
from ...utils import TensorType class Blip2Processor(ProcessorMixin):

Blip2Processor是一个类,继承自ProcessorMixin类。

    r"""
Constructs a BLIP-2 processor which wraps a BLIP image processor and an OPT/T5 tokenizer into a single processor.
...
"""

这是一个类的文档字符串,它介绍了这个类的作用和功能。

    attributes = ["image_processor", "tokenizer"]
image_processor_class = "BlipImageProcessor"
tokenizer_class = "AutoTokenizer"

这些属性保存了image_processortokenizer的名称,以及它们对应的类的名称。

    def __init__(self, image_processor, tokenizer):
tokenizer.return_token_type_ids = False
super().__init__(image_processor, tokenizer)
self.current_processor = self.image_processor

这是类的构造函数,它接受两个参数:image_processortokenizer。它设置了tokenizer.return_token_type_ids为False,然后调用了父类ProcessorMixin的构造函数,并将image_processortokenizer传递给它。最后,它设置了self.current_processorself.image_processor

    def __call__(
self,
images=None,
text: Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None,
add_special_tokens: bool = True,
padding: Union[bool, str, PaddingStrategy] = False,
truncation: Union[bool, str, TruncationStrategy] = None,
max_length: Optional[int] = None,
stride: int = 0,
pad_to_multiple_of: Optional[int] = None,
return_attention_mask: Optional[bool] = None,
return_overflowing_tokens: bool = False,
return_special_tokens_mask: bool = False,
return_offsets_mapping: bool = False,
return_token_type_ids: bool = False,
return_length: bool = False,
verbose: bool = True,
return_tensors: Optional[Union[str, TensorType]] = None,
**kwargs,
) -> BatchEncoding:
"""
This method uses [`BlipImageProcessor.__call__`] method to prepare image(s) for the model, and
[`BertTokenizerFast.__call__`] to prepare text for the model. Please refer to the docstring of the above two methods for more information.
"""

这是一个类方法,它重载了__call__()方法,用于将图像和文本编码为模型可以接受的格式。它接受多个参数,其中imagestext是输入的图像和文本,其他参数用于控制编码过程的各个方面。这个方法使用BlipImageProcessor.__call__方法来准备图像,使用BertTokenizerFast.__call__方法来准备文本。

    def batch_decode(self, *args, **kwargs):
"""
This method forwards all its arguments to PreTrainedTokenizer's [`~PreTrainedTokenizer.batch_decode`]. Please
refer to the docstring of this method for more information.
"""

这是一个类方法,它重载了batch_decode()方法,它将所有参数转发到PreTrainedTokenizer.batch_decode()方法中。

    def decode(self, *args, **kwargs):
"""
This method forwards all its arguments to PreTrainedTokenizer's [`~PreTrainedTokenizer.decode`]. Please refer
to the docstring of this method for more information.
"""

这是一个类方法,它重载了decode()方法,它将所有参数转发到PreTrainedTokenizer.decode()方法中。

    @property
def model_input_names(self):
tokenizer_input_names = self.tokenizer.model_input_names
image_processor_input_names = self.image_processor.model_input_names
return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names))

这是一个类属性,它返回一个包含所有模型输入名称的列表,这些名称由tokenizerimage_processor的模型输入名称组成。

请浏览这个链接中的代码,并给出详细的解释:https://github.com/huggingface/transformers/blob/main/src/transformers/models/blip_2/modeling_blip_2.py

这是一个实现了Blip2模型的代码文件。下面是代码的逐行解释:

from typing import Any, Dict, List, Optional, Tuple, Union

import torch

import torch.utils.checkpoint

from torch import Tensor, nn

from torch.nn import CrossEntropyLoss, MSELoss

from ...activations import ACT2FN

from ...file_utils import (

ModelOutput,

add_code_sample_docstrings,

add_start_docstrings,

add_start_docstrings_to_model_forward,

replace_return_docstrings,

)

from ...modeling_utils import PreTrainedModel

from ...utils import logging

from .configuration_blip_2 import Blip2Config

logger = logging.get_logger(name)

_CHECKPOINT_FOR_DOC = "blip-2-base"

_CONFIG_FOR_DOC = "Blip2Config"

_TOKENIZER_FOR_DOC = "Blip2Tokenizer"

BLIP_2_PRETRAINED_MODEL_ARCHIVE_LIST = [

"blip-2-base",

"blip-2-large",

"blip-2-small",

"blip-2-tiny",

]

这些导入和定义了一些常量和变量,例如模型配置、日志记录器和预训练模型的存档列表。

class Blip2Attention(nn.Module):

def init(self, config: Blip2Config):

super().init()

self.self_attention = nn.MultiheadAttention(config.hidden_size, config.num_attention_heads)

self.self_attention_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)

self.dense_output = nn.Linear(config.hidden_size, config.hidden_size * 4)

self.output_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)

self.dropout = nn.Dropout(config.attention_dropout_prob)

def forward(
self,
hidden_states: Tensor,
attention_mask: Optional[Tensor] = None,
output_attentions: bool = False,
) -> Tuple[Tensor, Optional[Tensor]]:
self_outputs = self.self_attention(
hidden_states,
hidden_states,
hidden_states,
attn_mask=attention_mask,
)
attention_output = self_outputs[0]
attention_output = self.self_attention_layer_norm(hidden_states + attention_output)
intermediate_output = self.dense_output(attention_output)
layer_output = self.output_layer_norm(attention_output + intermediate_output)
layer_output = self.dropout(layer_output)
outputs = (layer_output,)
if output_attentions:
outputs = outputs + self_outputs[1:]
return outputs

这是一个Blip2Attention类,它实现了模型中的一个注意力机制。在初始化函数中,它定义了多头自注意力层、层归一化、全连接层、输出层归一化和dropout层。在forward()函数中,它计算了自注意力,然后将结果应用于层归一化。接着,它通过全连接层和输出层归一化来产生中间输出。最后,它将结果应用于dropout层,并返回输出。

class Blip2ImageEncoder(nn.Module):

def init(self, config: Blip2Config):

super().init()

self.image_embedding = nn.Linear(config.image_feature_size, config.hidden_size)

self.image_feature_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)

self.image_transformer_blocks = nn.ModuleList(

[Blip2Attention(config) for _ in range(config.num_image_transformer_blocks)]

)

self.image_pooler = nn.Linear(config.hidden_size, config.hidden_size)

self.image_pooler_activation = nn.Tanh()

def forward(
self,
pixel_values: Tensor,
attention_mask: Optional[Tensor] = None,
output_attentions: bool = False,
) -> Tuple[Tensor, Optional[Tensor]]:
hidden_states = self.image_embedding(pixel_values)
hidden_states = self.image_feature_layer_norm(hidden_states) for transformer_block in self.image_transformer_blocks:
outputs = transformer_block(
hidden_states=hidden_states,
attention_mask=attention_mask,
output_attentions=output_attentions,
)
hidden_states = outputs[0] pooled_output = torch.mean(hidden_states, dim=1)
pooled_output = self.image_pooler(pooled_output)
pooled_output = self.image_pooler_activation(pooled_output)
outputs = (pooled_output,)
if output_attentions:
outputs = outputs + outputs[1:]
return outputs

这是一个Blip2ImageEncoder类,它实现了将输入图像编码为隐藏表示的功能。在初始化函数中,它定义了图像嵌入层,图像特征层归一化、图像变换块、池化层和池化层激活函数。在forward()函数中,它首先将输入图像的像素值通过图像嵌入层进行编码,并应用图像特征层归一化。然后,它在每个图像变换块上进行循环,并在每个块上计算注意力,最终得到一个池化输出。输出包括池化输出和可选的注意力值。

class Blip2TextEncoder(nn.Module):

def init(self, config: Blip2Config):

super().init()

self.embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)

self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)

self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)

self.text_transformer_blocks = nn.ModuleList(

[Blip2Attention(config) for _ in range(config.num_text_transformer_blocks)]

)

self.text_pooler = nn.Linear(config.hidden_size, config.hidden_size)

self.text_pooler_activation = nn.Tanh()

def forward(
self,
input_ids: Optional[Tensor] = None,
attention_mask: Optional[Tensor] = None,
token_type_ids: Optional[Tensor] = None,
position_ids: Optional[Tensor] = None,
output_attentions: bool = False,
) -> Tuple[Tensor, Optional[Tensor]]:
input_shape = input_ids.size()
device = input_ids.device if position_ids is None:
position_ids = torch.arange(input_shape[1], dtype=torch.long, device=device)
position_ids = position_ids.unsqueeze(0).expand(input_shape) if attention_mask is None:
attention_mask = torch.ones(input_shape, device=device) if token_type_ids is None:
token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) inputs_embeds = self.embeddings(input_ids)
position_embeddings = self.position_embeddings(position_ids)
token_type_embeddings = self.token_type_embeddings(token_type_ids) hidden_states = inputs_embeds + position_embeddings + token_type_embeddings
hidden_states = nn.functional.dropout(hidden_states, p=0.1, training=self.training) for transformer_block in self.text_transformer_blocks:
outputs = transformer_block(
hidden_states=hidden_states,
attention_mask=attention_mask,
output_attentions=output_attentions,
)
hidden_states = outputs[0] pooled_output = hidden_states[:, 0]
pooled_output = self.text_pooler(pooled_output)
pooled_output = self.text_pooler_activation(pooled_output)
outputs = (pooled_output,)
if output_attentions:
outputs = outputs + outputs[1:]
return outputs

这是一个Blip2TextEncoder类,它实现了将输入文本编码为隐藏表示的功能。在初始化函数中,它定义了文本嵌入层、位置嵌入层、类型嵌入层、文本变换块、池化层和池化层激活函数。在forward()函数中,它根据输入的input_ids、attention_mask、token_type_ids和position_ids来计算嵌入。然后,它在每个文本变换块上进行循环,并在每个块上计算注意力,最终得到一个池化输出。输出包括池化输出和可选的注意力值。

class Blip2Encoder(nn.Module):

def init(self, config: Blip2Config):

super().init()

self.image_encoder = Blip2ImageEncoder(config)

self.text_encoder = Blip2TextEncoder(config)

self.fusion_gate = nn.Linear(config.hidden_size * 2, config.hidden_size)

self.fusion_gate_activation = ACT2FN["sigmoid"]

self.dropout = nn.Dropout(config.hidden_dropout_prob)

def forward(
self,
pixel_values: Optional[Tensor] = None,
input_ids: Optional[Tensor] = None,
attention_mask: Optional[Tensor] = None,
token_type_ids: Optional[Tensor] = None,
position_ids: Optional[Tensor] = None,
output_attentions: bool = False,

) -> Tuple[Tensor, Optional[Tensor]]:

if pixel_values is not None and input_ids is not None:

raise ValueError("You cannot specify both pixel_values and input_ids at the same time.")

if pixel_values is None and input_ids is None:

raise ValueError("You have to specify either pixel_values or input_ids.")

if input_ids is not None and token_type_ids is None:

token_type_ids = torch.zeros_like(input_ids)

ini

Copy

if pixel_values is not None:

image_outputs = self.image_encoder(

pixel_values=pixel_values,

attention_mask=attention_mask,

output_attentions=output_attentions,

)

text_outputs = None

else:

image_outputs = None

text_outputs = self.text_encoder(

input_ids=input_ids,

attention_mask=attention_mask,

token_type_ids=token_type_ids,

position_ids=position_ids,

output_attentions=output_attentions,

)

if image_outputs is not None and text_outputs is not None:
pooled_output = torch.cat((image_outputs[0], text_outputs[0]), dim=-1)
else:
pooled_output = image_outputs[0] if image_outputs is not None else text_outputs[0] pooled_output = self.dropout(pooled_output) if image_outputs is not None and text_outputs is not None:
gated_output = self.fusion_gate(pooled_output)
gated_output = self.fusion_gate_activation(gated_output)
pooled_output = gated_output * pooled_output outputs = (pooled_output,)
if output_attentions:
outputs = outputs + (image_outputs[1] if image_outputs is not None else text_outputs[1],)
return outputs

这是一个Blip2Encoder类,它实现了将图像和文本编码为一个隐藏表示的功能。在初始化函数中,它定义了图像编码器、文本编码器、融合门、融合门激活函数和dropout层。在forward()函数中,它首先检查输入是否为图像或文本,并根据情况调用相应的编码器。然后,它将图像和文本编码的输出连接在一起,并应用dropout层。接着,它使用融合门来控制图像和文本的贡献,并返回输出和可选的注意力值。

class Blip2ForImageClassification(PreTrainedModel):
def __init__(self, config: Blip2Config):
super().__init__(config) self.config = config
self.blip2 = Blip2Encoder(config)
self.classifier = nn.Linear(config.hidden_size, config.num_labels) self.init_weights() @add_start_docstrings_to_model_forward(
"The forward method of Blip2ForImageClassification is identical to Blip2Encoder. See "
"Blip2Encoder.forward() for more information.",
Blip2Config,
)
@replace_return_docstrings(output_type=Tuple[Tensor, Optional[Tensor]])
def forward(
self,
pixel_values: Optional[Tensor] = None,
input_ids: Optional[Tensor] = None,
attention_mask: Optional[Tensor] = None,
token_type_ids: Optional[Tensor] = None,
position_ids: Optional[Tensor] = None,
output_attentions: bool = False,
) -> Tuple[Tensor, Optional[Tensor]]:
r"""
Returns:
"""
pooled_output = self.blip2(
pixel_values=pixel_values,
input_ids=input_ids,
attention_mask=attention_mask,
token_type_ids=token_type_ids,
position_ids=position_ids,
output_attentions=output_attentions,
)[0] logits = self.classifier(pooled_output) outputs = (logits,)
if output_attentions:
outputs = outputs + (None,)
return outputs # logits, (attentions)
这是一个Blip2ForImageClassification类,它实现了图像分类任务的模型。它继承自PreTrainedModel类,并在初始化函数中定义了Blip2Encoder和分类器。在forward()函数中,它首先调用Blip2Encoder来计算输入的隐藏表示,然后将隐藏表示传递给分类器并返回logits。 class Blip2ForTokenClassification(PreTrainedModel):
def __init__(self, config: Blip2Config):
super().__init__(config) self.config = config
self.blip2 = Blip2Encoder(config)
self.classifier = nn.Linear(config.hidden_size, config.num_labels) self.init_weights() @add_start_docstrings_to_model_forward(
"The forward method of Blip2ForTokenClassification is identical to Blip2Encoder. See "
"Blip2Encoder.forward() for more information.",
Blip2Config,
)
@replace_return_docstrings(output_type=Tuple[Tensor, Optional[Tensor]])
def forward(
self,
pixel_values: Optional[Tensor] = None,
input_ids: Optional[Tensor] = None,
attention_mask: Optional[Tensor] = None,
token_type_ids: Optional[Tensor] = None,
position_ids: Optional[Tensor] = None,
output_attentions: bool = False,
) -> Tuple[Tensor, Optional[Tensor]]:
r"""
Returns:
"""
pooled_output = self.blip2(
pixel_values=pixel_values,
input_ids=input_ids,
attention_mask=attention_mask,
token_type_ids=token_type_ids,
position_ids=position_ids,
output_attentions=output_attentions,
)[0] logits = self.classifier(pooled_output) outputs = (logits,)
if output_attentions:
outputs = outputs + (None,)
return outputs # logits, (attentions)
这是一个Blip2ForTokenClassification类,它实现了标记分类任务的模型。它的架构与Blip2ForImageClassification相同,唯一的区别是分类器的输出数量与config.num_labels相同,因为标记分类任务需要输出每个标记的预测标签。

blip2代码解析的更多相关文章

  1. VBA常用代码解析

    031 删除工作表中的空行 如果需要删除工作表中所有的空行,可以使用下面的代码. Sub DelBlankRow() DimrRow As Long DimLRow As Long Dimi As L ...

  2. [nRF51822] 12、基础实验代码解析大全 · 实验19 - PWM

    一.PWM概述: PWM(Pulse Width Modulation):脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形. PWM 的几个基本概念: 1) 占空比:占空比是指 ...

  3. [nRF51822] 11、基础实验代码解析大全 · 实验16 - 内部FLASH读写

     一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识 ...

  4. [nRF51822] 10、基础实验代码解析大全 · 实验15 - RTC

    一.实验内容: 配置NRF51822 的RTC0 的TICK 频率为8Hz,COMPARE0 匹配事件触发周期为3 秒,并使能了TICK 和COMPARE0 中断. TICK 中断中驱动指示灯D1 翻 ...

  5. [nRF51822] 9、基础实验代码解析大全 · 实验12 - ADC

    一.本实验ADC 配置 分辨率:10 位. 输入通道:5,即使用输入通道AIN5 检测电位器的电压. ADC 基准电压:1.2V. 二.NRF51822 ADC 管脚分布 NRF51822 的ADC ...

  6. java集合框架之java HashMap代码解析

     java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...

  7. Kakfa揭秘 Day8 DirectKafkaStream代码解析

    Kakfa揭秘 Day8 DirectKafkaStream代码解析 今天让我们进入SparkStreaming,看一下其中重要的Kafka模块DirectStream的具体实现. 构造Stream ...

  8. linux内存管理--slab及其代码解析

    Linux内核使用了源自于 Solaris 的一种方法,但是这种方法在嵌入式系统中已经使用了很长时间了,它是将内存作为对象按照大小进行分配,被称为slab高速缓存. 内存管理的目标是提供一种方法,为实 ...

  9. MYSQL常见出错mysql_errno()代码解析

    如题,今天遇到怎么一个问题, 在理论上代码是不会有问题的,但是还是报了如上的错误,把sql打印出來放到DB中却可以正常执行.真是郁闷,在百度里面 渡 了很久没有相关的解释,到时找到几个没有人回复的 & ...

  10. Postgres中postmaster代码解析(中)

    今天我们对postmaster的以下细节进行讨论: backend的启动和client的连接请求的认证 客户端取消查询时的处理 接受pg_ctl的shutdown请求进行shutdown处理 2.与前 ...

随机推荐

  1. 一文搞懂SaaS应用架构:应用服务、应用结构、应用交互设计

    大家好,我是汤师爷~ 今天系统性地聊聊SaaS应用架构设计. 应用架构概述 我们已经完成了SaaS系统的定位分析,明确了系统的目标和核心能力.这为接下来的应用架构设计奠定了基础. 应用架构就像整个Sa ...

  2. RecyclerView刷新方式

    RecyclerView刷新方式 刷新全部item notifyDataSetChanged() student.setValue(new Student("二狗")); stud ...

  3. 对比 Unittest 和 Pytest

    一.用例编写规则 1,Unittest提供了test cases.test suites.test fixtures.test runner相关的类,让测试更加明确.方便.可控.使用unittest编 ...

  4. NOIP2024模拟11:忠于自我

    NOIP2024模拟11:忠于自我 T1 一句话题意:有若干个容量为 \(L\) 的包,从左往右装物品,当前包还能装则装,否则必须重开一个包装进去,对于\(\forall i \in [1,n]\), ...

  5. TypeError: fs.existsSync is not a function | import { ipcRenderer } from 'electron'

    在electron的渲染进程中导包会发生TypeError: fs.existsSync is not a function node_modules/electron/index.js:6 var ...

  6. Hook框架之Frida

    Frida是一款轻量级HOOK框架,可用于多平台上,例如android.windows.ios等.    frida分为两部分,服务端运行在目标机上,通过注入进程的方式来实现劫持应用函数,另一部分运行 ...

  7. 2021GPLT

    病毒溯源 给定一棵树,树上有\(n\)个节点,编号从\(0\)到\(n-1\),请你输出从根节点开始的最长的一条链,且该链字典序最小 题解:\(dfs\)树的遍历 + 贪心 首先我们先找到入度为\(0 ...

  8. Mybatis【16】-- Mybatis多对一关联查询

    注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-12-many2one,需要自取,需要配置mave ...

  9. Vue.js 其他指令

    1.ref标识 通过给HTML标签或者组件标签设定ref属性,根据他的属性值来访问这个HTML元素或者组件 语法:this.$refs.属性值 //为p标签设置ref属性 <div id=&qu ...

  10. 基于CPLD/FPGA的呼吸灯效果实现(附全部verilog源码)

    一.功能介绍 此设计可以让你的FPGA板子上那颗LED具有呼吸效果,像智能手机上的呼吸灯一样.以下源码已上板验证通过,大家可直接使用. 二.呼吸灯Verilog源码 ps1. 带★号处可根据需要进行修 ...