4D Radar - A Novel Sensing Paradigm for 3D Object Detection

【If you want to add anything to this repository, please create a PR to github.com/liuzengyun/Awesome-3D-Detection-with-4D-Radar or email to i@cvzoo.cn】 Overview Datasets SOTA Papers From 4D Radar Point Cloud From 4D Radar Tensor Fusion of 4D Radar & LiDAR Fusion of 4D Radar & RGB Camera Others Survey Papers Basic Knowledge Representative researchers Datasets DatasetSensorsRadar DataSourceAnnotationsurlOther Astyx4D Radar,LiDAR, CameraPC19’EuRAD3D bboxgithub paper~500 frames RADIal4D Radar,LiDAR, CameraPC, ADC, RT22’CVPR2D bbox, seggithub paper8,252 labeled frames View-of-Delft(VoD)4D Radar,LiDAR, Stereo CameraPC22’RA-L3D bboxwebsite8,693 frames TJ4DRadSet4D Radar,LiDAR, Camera, GNSSPC22’ITSC3D bbox, TrackIDgithub paper7,757 frames K-Radar4D Radar,LiDAR, Stereo Camera, RTK-GPSRT22’NeurIPS3D bbox, TrackIDgithub paper35K frames; 360° Camera Dual Radardual 4D Radars,LiDAR, CameraPC23’arXiv3D bbox, TrackIDpaper10K frames L-RadSet4D Radar,LiDAR, 3 CamerasPC24’TIV3D bbox, TrackIDgithub paper11.2K frames; Annos range to 220m ZJUODset4D Radar,LiDAR, CameraPC23’ICVISP3D bbox, 2D bboxgithub paper19,000 frames of raw data and 3,800 annotated frames. CMD32-beam LiDAR, 128-beam LiDAR, solid-state LiDAR, 4D Radar, 3 CamerasPC24’ECCV3D bboxgithub paper50 high-quality sequences, each spanning 20 seconds, equating to 200 frames per sensor V2X-R4D Radar,LiDAR, Camera (simulated)PC24’arXiv3D bboxgithub paperV2X-R contains 12,079 scenarios with 37,727 frames of LiDAR and 4D radar point clouds, 150,908 images OmniHD-Scenes6 4D Radars,LiDAR, 6 Cameras, IMUPC24’arXiv3D bbox, TrackID, OCCwebsite papertotaling more than 450K synchronized frames ………………………………………………………………………… SOTA Papers From 4D Radar Point Cloud RPFA-Net: a 4D RaDAR Pillar Feature Attention Network for 3D Object Detection (21’ITSC) Link: paper code Affiliation: Tsinghua University (Xinyu Zhang) Dataset: Astyx Note: Multi-class road user detection with 3+1D radar in the View-of-Delft dataset (22’RA-L) Link: paper Affiliation: Dataset: VoD Note: baseline of VoD SMURF: Spatial multi-representation fusion for 3D object detection with 4D imaging radar (23’TIV) Link: paper Affiliation: Beihang University (Bing Zhu) Dataset: VoD, TJ4DRadSet Note: PillarDAN: Pillar-based Dual Attention Attention Network for 3D Object Detection with 4D RaDAR (23’ITSC) Link: paper Affiliation: Shanghai Jiao Tong University (Lin Yang) Dataset: Astyx Note: MVFAN: Multi-view Feature Assisted Network for 4D Radar Object Detection (23’ICONIP) Link: paper Affiliation: Nanyang Technological University Dataset: Astyx, VoD Note: SMIFormer: Learning Spatial Feature Representation for 3D Object Detection from 4D Imaging Radar via Multi-View Interactive Transformers (23’Sensors) Link: paper Affiliation: Tongji University Dataset: VoD Note: 3-D Object Detection for Multiframe 4-D Automotive Millimeter-Wave Radar Point Cloud (23’IEEE Sensors Journal) Link: paper Affiliation: Tongji University (Zhixiong Ma) Dataset: TJ4DRadSet Note: RMSA-Net: A 4D Radar Based Multi-Scale Attention Network for 3D Object Detection (23’ISCSIC) Link: paper Affiliation: Nanjing University of Aeronautics and Astronautics (Jie Hao) Dataset: HR4D (self-collected and not open source) Note: RadarPillars: Efficient Object Detection from 4D Radar Point Clouds (24’arXiv) Link: paper Affiliation: Mannheim University of Applied Sciences, Germany Dataset: VoD Note: VA-Net: 3D Object Detection with 4D Radar Based on Self-Attention (24’CVDL) Link: paper Affiliation: Hunan Normal University (Bo Yang) Dataset: VoD Note: RTNH+: Enhanced 4D Radar Object Detection Network using Two-Level Preprocessing and Vertical Encoding (24’TIV) Link: code paper Affiliation: KAIST (Seung-Hyun Kong) Dataset: K-Radar Note: The enhanced baseline of K-Radar. RaTrack: Moving Object Detection and Tracking with 4D Radar Point Cloud (24’ICRA) Link: code Affiliation: Royal College of Art, University College London (Chris Xiaoxuan Lu) Dataset: VoD Note: Feature Fusion and Interaction Network for 3D Object Detection based on 4D Millimeter Wave Radars (24’CCC) Link: paper Affiliation: University of Science and Technology of China (Qiang Ling) Dataset: VoD Note: Sparsity-Robust Feature Fusion for Vulnerable Road-User Detection with 4D Radar (24’Applied Sciences) Link: paper Affiliation: Mannheim University of Applied Sciences (Oliver Wasenmüller) Dataset: VoD Note: Enhanced 3D Object Detection using 4D Radar and Vision Fusion with Segmentation Assistance (24’preprint) Link: paper code Affiliation: Beijing Institute of Technology (Xuemei Chen) Dataset: VoD Note: RadarPillarDet: Multi-Pillar Feature Fusion with 4D Millimeter-Wave Radar for 3D Object Detection (24’SAE Technical Paper) Link: paper Affiliation: Tongji University (Zhixiong Ma) Dataset: VoD Note: MUFASA: Multi-View Fusion and Adaptation Network with Spatial Awareness for Radar Object Detection (24’ICANN) Link: paper Affiliation: Technical University of Munich (Xiangyuan Peng) Dataset: VoD, TJ4DRadSet Note: Multi-Scale Pillars Fusion for 4D Radar Object Detection with Radar Data Enhancement (24’IEEE Sensors Journal) Link: paper Affiliation: Chinese Academy of Sciences (Zhe Zhang) Dataset: VoD Note: SCKD: Semi-Supervised Cross-Modality Knowledge Distillation for 4D Radar Object Detection (25’AAAI) Link: paper code(unfilled project) Affiliation: Zhejiang University (Zhiyu Xiang) Dataset: VoD, ZJUODset Note: The teacher is a Lidar-Radar bi-modality fusion network, while the student is a radaronly network. By the effective knowledge distillation of the teacher, the student can learn to extract sophisticated feature from the radar input and boost its detection performance. From 4D Radar Tensor Towards Robust 3D Object Detection with LiDAR and 4D Radar Fusion in Various Weather Conditions (24’CVPR) Link: paper code Affiliation: KAIST (Yujeong Chae) Dataset: K-Radar Note: This method takes LiDAR point cloud, 4D radar tensor (not point cloud) and image as input. CenterRadarNet: Joint 3D Object Detection and Tracking Framework using 4D FMCW Radar (24’ICIP) Link: paper Affiliation: University of Washington (Jen-Hao Cheng) Dataset: K-Radar Note: Fusion of 4D Radar & LiDAR InterFusion: Interaction-based 4D Radar and LiDAR Fusion for 3D Object Detection (22’IROS) Link: paper Affiliation: Tsinghua University (Li Wang) Dataset: Astyx Note: Multi-Modal and Multi-Scale Fusion 3D Object Detection of 4D Radar and LiDAR for Autonomous Driving (23’TVT) Link: paper Affiliation: Tsinghua University (Li Wang) Dataset: Astyx Note: L4DR: LiDAR-4DRadar Fusion for Weather-Robust 3D Object Detection (24’arXiv) Link: paper Affiliation: Xiamen University Dataset: VoD, K-Radar Note: For the K-Radar dataset, we preprocess the 4D radar spar setensor by selecting only the top 10240 points with high power measurement. This paper is submitted to 25’AAAI. Robust 3D Object Detection from LiDAR-Radar Point Clouds via Cross-Modal Feature Augmentation (24’ICRA) Link: paper code Affiliation: University of Edinburgh, University College London (Chris Xiaoxuan Lu) Dataset: VoD Note: Traffic Object Detection for Autonomous Driving Fusing LiDAR and Pseudo 4D-Radar Under Bird’s-Eye-View (24’TITS) Link: paper Affiliation: Xi’an Jiaotong University (Yonghong Song) Dataset: Astyx Note: Fusing LiDAR and Radar with Pillars Attention for 3D Object Detection (24’International Symposium on Autonomous Systems (ISAS)) Link: paper Affiliation: Zhejiang University (Liang Liu) Dataset: VoD Note: RLNet: Adaptive Fusion of 4D Radar and Lidar for 3D Object Detection (24’ECCVW) Link: paper and reviews Affiliation: Zhejiang University (Zhiyu Xiang) Dataset: ZJUODset Note: LEROjD: Lidar Extended Radar-Only Object Detection (24’ECCV) Link: paper code Affiliation: TU Dortmund University (Patrick Palmer, Martin Krüger) Dataset: VoD Note: “Although lidar should not be used during inference, it can aid the training of radar-only object detectors.” V2X-R: Cooperative LiDAR-4D Radar Fusion for 3D Object Detection with Denoising Diffusion (24’arXiv) Link: paper code Affiliation: Xiamen University (Chenglu Wen) Dataset: V2X-R Note: baseline method of V2X-R Datasets Fusion of 4D Radar & RGB Camera RCFusion: Fusing 4-D Radar and Camera With Bird’s-Eye View Features for 3-D Object Detection (23’TIM) Link: paper Affiliation: Tongji University (Zhixiong Ma) Dataset: VoD, TJ4DRadSet Note: GRC-Net: Fusing GAT-Based 4D Radar and Camera for 3D Object Detection (23’SAE Technical Paper) Link: paper Affiliation: Beijing Institute of Technology (Lili Fan) Dataset: VoD Note: LXL: LiDAR Excluded Lean 3D Object DetectionWith 4D Imaging Radar and Camera Fusion (24’TIV) Link: paper Affiliation: Beihang University (Bing Zhu) Dataset: VoD, TJ4DRadSet Note: TL-4DRCF: A Two-Level 4-D Radar–Camera Fusion Method for Object Detection in Adverse Weather (24’IEEE Sensors Journal) Link: paper Affiliation: South China University of Technology (Kai Wu) Dataset: VoD Note: Beyond the VoD, the LiDAR point cloud and images of the VoD dataset are processed with artificial fog to obtain the VoD-Fog dataset for validating our model. UniBEVFusion: Unified Radar-Vision BEVFusion for 3D Object Detection (24’arXiv) Link: paper Affiliation: Xi’an Jiaotong - Liverpool University Dataset: VoD, TJ4DRadSet Note: RCBEVDet: Radar-camera Fusion in Bird’s Eye View for 3D Object Detection (24’CVPR) Link: paper Affiliation: Peking University (Yongtao Wang) Dataset: VoD Note: not only 4D mmWave Radar, but 3D Radar like Nuscenes MSSF: A 4D Radar and Camera Fusion Framework With Multi-Stage Sampling for 3D Object Detection in Autonomous Driving (24’arXiv) Link: paper Affiliation: University of Science andTechnology of China (Jun Liu) Dataset: VoD, TJ4DRadset Note: SGDet3D: Semantics and Geometry Fusion for 3D Object Detection Using 4D Radar and Camera (24’RA-L) Link: paper code Affiliation: Zhejiang University (Huiliang Shen) Dataset: VoD, TJ4DRadset Note: ERC-Fusion: Fusing Enhanced 4D Radar and Camera for 3D Object Detection (24’DTPI) Link: paper Affiliation: Beijing Institute of Technology (Lili Fan) Dataset: VoD Note: HGSFusion: Radar-Camera Fusion with Hybrid Generation and Synchronization for 3D Object Detection (25’AAAI) Link: paper code Affiliation: Southeast University (Yan Huang) Dataset: VoD, TJ4DRadSet Note: Others LiDAR-based All-weather 3D Object Detection via Prompting and Distilling 4D Radar (24’ECCV) Link: paper code (unfilled project) Affiliation: KAIST (Yujeong Chae) Dataset: K-Radar Note: Exploring Domain Shift on Radar-Based 3D Object Detection Amidst Diverse Environmental Conditions (24’ITSC) Link: paper Affiliation: Robert Bosch GmbH (Miao Zhang) Dataset: K-Radar, Bosch-Radar Note: Survey Papers 4D Millimeter-Wave Radar in Autonomous Driving: A Survey (23’arXiv) Link: paper Affiliation: Tsinghua University (Jianqiang Wang) 4D mmWave Radar for Autonomous Driving Perception: A Comprehensive Survey (24’TIV) Link: paper Affiliation: Beijing Institute of Technology (Lili Fan) A Survey of Deep Learning Based Radar and Vision Fusion for 3D Object Detection in Autonomous Driving (24’arXiv) waiting for updates……………….. Basic Knowledge What is 4D Radar? 3D object detection is able to obtain the position, size and orientation information of objects in 3D space, and is widely used in automatic driving perception, robot manipulation, and other applications. In 3D object detection, sensors such as LiDAR, RGB camera and depth camera are commonly used. In recent years, several works have been proposed to utilize 4D radar as a primary or secondary sensor to achieve 3D object detection. 4D radar, also known as 4D millimeter wave (mmWave) radar or 4D imaging radar. Compared to 3D radar, 4D radar not only obtains the distance, direction and relative velocity (Doppler velocity) of the target object, but also detects the height of the object. Due to its robustness against different weather conditions and lower cost, 4D radar is expected to replace low beam LiDAR in the future. This repo summarizes the 4D radar based 3D object detection methods and datasets. Different 4D Radar Data Representations PC: Point Cloud ADC: Analog-to-Digital Converter signal RT: Radar Tensor (include Range-Azimuth-Doppler Tensor, Range-Azimuth Tensor, Range-Doppler Tensor) Representative researchers Li Wang (Postdoctoral Fellow) and his co-leader Xinyu Zhang @Tsinghua University, authors of Dual Radar Bing Zhu @Beihang University Lin Yang @Shanghai Jiao Tong University Chris Xiaoxuan Lu @University College London (UCL) Zhixiong Ma @Chinese Institute for Brain Research (ex. Tongji University), the author of TJ4DRadSet Dataset and OmniHD-Scenes Dataset Zhiyu Xiang @Zhejiang University, the author of ZJUODset Dataset Yujeong Chae and his PhD Advisor Kuk-Jin Yoon @Korea Advanced Institute of Science and Technology (KAIST) Lili Fan @Beijing Institute of Technology Chenglu Wen @Xiamen university, the author of CMD Dataset and V2X-R Dataset

2025/1/3
articleCard.readMore

粗略的cs231n学习笔记

1 1.1 概述 助教老师讲了讲课程的重要性和整体内容。 1.2 历史背景 1.2.1 history of cv 5.4亿年前化石表明动物已经具备眼睛,物种大爆炸。 现在的视觉称为了最重要的感知能力。大脑中50%的神经细胞在处理视觉信息。 16世纪,第一台针孔理论相机。目前相机是最受欢迎的传感器之一。 人类开始研究动物视觉:电生理学研究,猫实验,看看是啥能刺激视觉中枢。 1966,麻省理工学院,视觉论文《THE SUMMER VISION PROJECT》,视觉信息被简化成简单的形状。 70年代,David Marr的书《VISION》,原始草图重建。 70年代,出现了广义圆柱体和图形结构,将复杂的视觉信息简单化。 80年代,基于简单图形进行识别和重建任务。 直接识别任务太难,先做分割任务。 2006,富士相机实时面部检测。 新世纪初,SIFT被提出。 机器学习出现,暴露问题:过拟合、模型维度高,不好泛化。建立大型数据集ImageNet。2009开始ImageNet组织目标检测竞赛,统一量化基准。2012卷积神经网络出现,获得冠军。 1.3 课程介绍 聚焦于图像分类问题,基于ImageNet挑战赛。拓展到目标检测、图片摘要 卷积神经网络CNN已经成为大赛的主流。2012年AlexNet出现,是一个7层的网络。2014VGG、GoogleNet。实际上CNN的雏形1998年就已经出现,LeCun大佬。后来用的多了,取决于: 算力提升 数据多了 现在视觉任务貌似偏向了目标检测,这并不只是视觉的主要内容,实际上还有分割、分类、3D理解等。举例: feifei博士期间,实验:人看图半秒即可描述一段话; 人看到图像上的东西会有笑的反应。 实际上是借助了已有知识去理解了图像。说明到这种程度cv还有很长路要走。 老师说他相信:CV Can Better Our Lives. 本课的老师:feifei, Justin, Serena, &so on 2 图像分类 2.1 数据驱动方法 需要的知识:Python+NumPy, Google Cloud 问题与挑战 图像分类是cv的core task,计算机给图像分配一个标签。但是计算机只能看到一堆像素数值,面临的问题就是“语义鸿沟”。比如给目标换一个角度拍摄、换一个同类的目不同的背景信息……像素数值会发生巨大变化,人眼识别是鲁棒的,机器也要做到这样。 我们的任务 希望训练时间长,检测时间短 传统方法 比如边缘检测 数据驱动的方法 收集数据与标签 训练(机器学习的过程) train 在新的图上评估/预测 predict 数据集举例 CIFAR10 10类别,5w训练图像,1w测试图像。32x32 px图像 用于比较图像相似性的损失函数 L1:曼哈顿距离 L2:欧氏距离 最近邻的问题 不好处理数据中的噪音,所以出现了K近邻,使用多数投票,分类边界变得平滑 2.2 KNN KNN原理:KNN算法(一) KNN算法原理 演示网站:http://vision.stanford.edu/teaching/cs231n-demos/knn/ 通过重构距离函数可以把KNN泛化到不同的数据类型上 L1依赖于坐标,向量的每个值有确定意义时,适合使用L1。否则可以两种都尝试一下,找到最好的。 超参设置 idea1:所有数据选择同一个参数,K越小在训练集上性能越好,但是到测试集上需要调大K。这样就会出现过拟合,过分的贴合训练数据,降低了泛化能力。 idea2:split data into train and test,选择不同参数,导致测试集很好,训练集不行了。 idea3:split data into train, val and test,train用一个超参,val和test用一个超参,选择val上最好的参数用于test idea4:交叉验证,传统机器学习常见,DL不咋用 学生提问1:val和test区别? 答:val是有标签的,通过在val上测试,与标签比较,修正算法的正确率,而test是没有标签的,用于观察预测结果或者实际应用。 提问2:test不能代表现实中的样本,咋办? 答:数据集是独立同分布的,现实不是,所以创建数据集的时候应该考虑随机性。 所以,KNN在图像分类上很少使用,原因: test时间长 距离很难判断像素差异(不好找损失函数) 维度灾难,难度指数增长 提问:绿点和蓝点表示啥? 答:代表不同类数据。维度越高,需要越多的数据点来填满空间,所以是指数倍增长。 2.3 线性分类 比如:输入图像经过模块f,输出十个数中的一个,代表十个类别中的一个。 深度学习的主要工作就是构建高性能的f。 线性分类器: 线性分类的模型简单,但是泛化能力差,只允许学习一个类型的一个模板。比如分类任务中,学习车的前脸,无法从车的侧面图判断是否是一辆车。 一个二维图像,经过特征提取后映射为高维空间中的一个点,只需在高维空间将点线性分类。而在低维空间中,两类是无法线性分开的。 3 损失函数和优化器 损失函数 来衡量我们对结果的不满意程度,当评分函数输出结果与真实结果之间差异越大,损失函数输出越大,反之越小。 我们对于预测训练集数据分类标签的情况总有一些不满意的,而损失函数就能将这些不满意的程度量化。 多类SVM SVM的损失函数想要SVM在正确分类上的得分始终比不正确分类上的得分高出一个边界值Δ。 多类SVM“想要”正确类别的分类分数比其他不正确分类类别的分数要高,而且至少高出delta的边界值。如果其他分类分数进入了红色的区域,甚至更高,那么就开始计算损失。如果没有这些情况,损失值为0。我们的目标是找到一些权重,它们既能够让训练集中的数据样例满足这些限制,也能让总的损失值尽可能地低。 正则化 我们希望能向某些特定的权重W添加一些偏好,对其他权重则不添加,以此来消除模糊性。这一点是能够实现的,方法是向损失函数增加一个正则化惩罚(regularization penalty)R(W)部分。 减轻模型复杂度,防止过拟合(over-fitting)。 Softmax 在Softmax分类器中,函数映射$f(x_i;W)=Wx_i$保持不变,但将这些评分值视为每个分类的未归一化的对数概率,并且将折叶损失(hinge loss)替换为交叉熵损失(cross-entropy loss)。公式如下: $$ L_i=−f{y_i}+log(∑je^{f_j}) $$ SVM和Softmax的比较 Softmax分类器为每个分类提供了“可能性”:SVM的计算是无标定的,而且难以针对所有分类的评分值给出直观解释。Softmax分类器则不同,它允许我们计算出对于所有分类标签的可能性。举个例子,针对给出的图像,SVM分类器可能给你的是一个[12.5, 0.6, -23.0]对应分类“猫”,“狗”,“船”。而softmax分类器可以计算出这三个标签的”可能性“是[0.9, 0.09, 0.01],这就让你能看出对于不同分类准确性的把握。 优化器 最优化 损失函数可以量化某个具体权重集W的质量。而最优化的目标就是找到能够最小化损失函数值的W的过程 。 参数更新需要有技巧地设置步长。也叫学习率。如果步长太小,进度稳定但是缓慢,如果步长太大,进度快但是可能有风险。 随机搜索:Acc=15.5% 随机尝试很多不同的权重,然后看其中哪个最好。每走一步都尝试几个随机方向,如果某个方向是向山下的,就向该方向走一步。 1 2 3 4 5 6 7 8 9 10 11 12 # 假设X_train的每一列都是一个数据样本(比如3073 x 50000) # 假设Y_train是数据样本的类别标签(比如一个长50000的一维数组) # 假设函数L对损失函数进行评价 bestloss = float("inf") # Python assigns the highest possible float value for num in xrange(1000): W = np.random.randn(10, 3073) * 0.0001 # generate random parameters loss = L(X_train, Y_train, W) # get the loss over the entire training set if loss < bestloss: # keep track of the best solution bestloss = loss bestW = W print 'in attempt %d the loss was %f, best %f' % (num, loss, bestloss) 随即本地搜索:Acc=21.4% 从一个随机W开始,然后生成一个随机的扰动δW ,只有当W+δW的损失值变低,我们才会更新。这个过程的具体代码如下: 1 2 3 4 5 6 7 8 9 10 W = np.random.randn(10, 3073) * 0.001 # 生成随机初始W bestloss = float("inf") for i in xrange(1000): step_size = 0.0001 Wtry = W + np.random.randn(10, 3073) * step_size loss = L(Xtr_cols, Ytr, Wtry) if loss < bestloss: W = Wtry bestloss = loss print 'iter %d loss is %f' % (i, bestloss) 跟随梯度 前两个策略中,我们是尝试在权重空间中找到一个方向,沿着该方向能降低损失函数的损失值。其实不需要随机寻找方向,因为可以直接计算出最好的方向,这就是从数学上计算出最陡峭的方向。这个方向就是损失函数的梯度(gradient)。在蒙眼徒步者的比喻中,这个方法就好比是感受我们脚下山体的倾斜程度,然后向着最陡峭的下降方向下山。 梯度下降 现在可以计算损失函数的梯度了,程序重复地计算梯度然后对参数进行更新,这一过程称为梯度下降,他的普通版本是这样的: 1 2 3 4 # 普通的梯度下降 while True: weights_grad = evaluate_gradient(loss_fun, data, weights) weights += - step_size * weights_grad # 进行梯度更新 随机梯度下降: 随机采样一部分训练集样本,计算梯度并实现下降过程。 4 反向传播与神经网络 反向传播 反向传播是利用链式法则递归计算表达式的梯度的方法。 导数与梯度 $$ f(x,y)=xy \to \frac {df}{dx}=y \quad \frac {df}{dy}=x $$ 牢记这些导数的意义:函数变量在某个点周围的极小区域内变化,而导数就是变量变化导致的函数在该方向上的变化率。 梯度∇f是偏导数的向量,所以有$∇f(x)=[\frac{∂f}{∂x},\frac{∂f}{∂y}]$ 链式法则 复合函数求导 $$ \displaystyle\frac{\partial f}{\partial x}=\frac{\partial f}{\partial q}\frac{\partial q}{\partial x} $$ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 设置输入值 x = -2; y = 5; z = -4 # 进行前向传播 q = x + y # q becomes 3 f = q * z # f becomes -12 # 进行反向传播: # 首先回传到 f = q * z dfdz = q # df/dz = q, 所以关于z的梯度是3 dfdq = z # df/dq = z, 所以关于q的梯度是-4 # 现在回传到q = x + y dfdx = 1.0 * dfdq # dq/dx = 1. 这里的乘法是因为链式法则 dfdy = 1.0 * dfdq # dq/dy = 1 前向传播从输入计算到输出(绿色),反向传播从尾部开始,根据链式法则递归地向前计算梯度(显示为红色),一直到网络的输入端。可以认为,梯度是从计算链路中回流。 sigmoid函数:$\sigma(x)=\frac{1}{1+e^{-x}}$ 一个计算实例 $$ \displaystyle f(x,y)=\frac{x+\sigma(y)}{\sigma(x)+(x+y)^2} $$ 1 2 3 4 5 6 7 8 9 10 11 12 x = 3 # 例子数值 y = -4 # 前向传播 sigy = 1.0 / (1 + math.exp(-y)) # 分子中的sigmoi #(1) num = x + sigy # 分子 #(2) sigx = 1.0 / (1 + math.exp(-x)) # 分母中的sigmoid #(3) xpy = x + y #(4) xpysqr = xpy**2 #(5) den = sigx + xpysqr # 分母 #(6) invden = 1.0 / den #(7) f = num * invden # 搞定! #(8) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # 回传 f = num * invden dnum = invden # 分子的梯度 #(8) dinvden = num #(8) # 回传 invden = 1.0 / den dden = (-1.0 / (den**2)) * dinvden #(7) # 回传 den = sigx + xpysqr dsigx = (1) * dden #(6) dxpysqr = (1) * dden #(6) # 回传 xpysqr = xpy**2 dxpy = (2 * xpy) * dxpysqr #(5) # 回传 xpy = x + y dx = (1) * dxpy #(4) dy = (1) * dxpy #(4) # 回传 sigx = 1.0 / (1 + math.exp(-x)) dx += ((1 - sigx) * sigx) * dsigx # Notice += !! See notes below #(3) # 回传 num = x + sigy dx += (1) * dnum #(2) dsigy = (1) * dnum #(2) # 回传 sigy = 1.0 / (1 + math.exp(-y)) dy += ((1 - sigy) * sigy) * dsigy #(1) # 完成! 嗷~~ 用向量化操作计算梯度 1 2 3 4 5 6 7 8 9 # 前向传播 W = np.random.randn(5, 10) X = np.random.randn(10, 3) D = W.dot(X) # 假设我们得到了D的梯度 dD = np.random.randn(*D.shape) # 和D一样的尺寸 dW = dD.dot(X.T) #.T就是对矩阵进行转置 dX = W.T.dot(dD) 神经网络简介 神经网络是将一些简单的函数以分层的方式堆叠起来,以组成更复杂的非线性函数。 一个三层的神经网络可以类比地看做$s=W3max(0,W2max(0,W1x))$,其中W1,W2,W3是需要进行学习的参数。 神经网络的结构 一些神经元的输出是另一些神经元的输入,通常神经网络模型中神经元是分层的。 神经元通过全连接层连接,层间神经元两两相连,但是层内神经元不连接; 分层的结构能够让神经网络高效地进行矩阵乘法和激活函数运算 讨论了更大网络总是更好的这一事实。然而更大容量的模型一定要和更强的正则化(比如更高的权重衰减)配合,否则它们就会过拟合。在后续章节中我们讲学习更多正则化的方法,尤其是dropout。 5 卷积神经网络 NN的结构是一系列的层将输入数据变换为输出数据。常规NN隐藏层都为全连接层,构建大网络时效率低下,容易过拟合。而CNN调整结构为卷积层、池化层、全连接层。 层 卷积层 (conv) 负责提取特征图片,卷积核为n*n矩阵,通常自己生成然后通过反向传播修正。 卷积核:卷积层的参数是有一些可学习的小卷积核集合构成的,卷积核尺寸为$kernel size\times kernel size\times num$(num是前一层的深度),前向传播时每个卷积核都与输入数据在宽高深三个维度做离散卷积运算。 特征图:又称为激活图,一个卷积核与输入数据卷积会生成一个二维激活图,每个卷积层上有多个卷积核也就有多个激活图,将激活图在深度方向上层叠起来就生成了输出数据。 局部连接:每个神经元只与输入数据的一个局部区域连接,该连接的空间大小叫做神经元的感受野(receptive field)。 参数 输入数据体的尺寸为$W_1\times H_1\times D_1$ 4个超参数:滤波器的数量K;滤波器的空间尺寸F;步长S;零填充数量P 输出数据体的尺寸为$W_2\times H_2\times D_2$,其中: $$ W_2=(W_1-F+2P)/S+1 $$ $$ H_2=(H_1-F+2P)/S+1 $$ $$ D_2=K $$ 由于参数共享,每个滤波器包含$F\cdot F\cdot D_1$个权重,卷积层一共有$F\cdot F\cdot D_1\cdot K$个权重和K个偏置。 在输出数据体中,第d个特征图(空间尺寸是$W_2\times H_2$),用第d个滤波器和输入数据进行有效卷积运算的结果(使用步长S),最后在加上第d个偏差。 对这些超参数,常见的设置是F=3,S=1,P=1。 激活层 将卷积层的结果做非线性映射。 池化层 负责降低特征图片维度,从而降低运算量,压缩数据和参数的量,用于减少过拟合。常用的有最大池化、均匀池化。 反向传播:回顾一下反向传播的内容,其中max(x,y)函数的反向传播可以简单理解为将梯度只沿最大的数回传。因此,在向前传播经过汇聚层的时候,通常会把池中最大元素的索引记录下来(有时这个也叫作道岔(switches)),这样在反向传播的时候梯度的路由就很高效。 全连接层 连接整个输入向量。在全连接层中,神经元对于前一层中的所有激活数据是全部连接的,这个常规神经网络中一样。 任何全连接层都可以被转化为卷积层,最大的局部等于全局。比如,一个K=4096的全连接层,输入数据体的尺寸是$7\times 7\times 512$,这个全连接层可以被等效地看做一个F=7,P=0,S=1,K=4096的卷积层。换句话说,就是将滤波器的尺寸设置为和输入数据体的尺寸一致,这样输出就变成$1\times 1\times 4096$,本质上和全连接层的输出是一样的。 结构 卷积神经网络通常是由三种层构成:卷积层,汇聚层(除非特别说明,一般就是最大值汇聚)和全连接层(简称FC) $$INPUT -> [[CONV -> RELU]\times N -> POOL?]\times M -> [FC -> RELU]\times K -> FC$$ $POOL?$指的是一个可选的汇聚层,通常0<=N<=3,M>=0,K>=0,通常K<3。 6 训练神经网络1 激活函数 建议:用ReLU非线性函数。注意设置好学习率,监控网络中死亡的神经元占的比例。如果单元死亡问题困扰你,就试试Leaky ReLU或者Maxout。 数据预处理 零中心化:它对数据中每个独立特征减去平均值,从几何上可以理解为在每个维度上都将数据云的中心都迁移到原点。而对于图像,更常用的是减去对应图像的均值而不是每个维度的均值,也可以在3个颜色通道上分别操作。理解:初始化时参数为0均值,线性分类器经过原点,能更快速地分类零中心的数据。 归一化(即标准化):数据在每一维度的数值范围都近似相等,通常有两种方式。第一种是先对数据做零中心化处理,然后每个维度都除以其标准差,相当于对每个维度上的数据做标准化。第二种方法是对每个维度都做归一化,使得每个维度的最大和最小值是1和-1。在图像处理中像素的数值范围几乎是一致的,归一化不是很必要。 PCA:过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维, 通常使用PCA降维过的数据训练线性分类器和神经网络会达到非常好的性能效果,同时还能节省时间和存储器空间。 白化:白化操作的输入是特征基准上的数据,然后对每个维度除以其特征值来对数值范围进行归一化。该变换的几何解释是:如果数据服从多变量的高斯分布,那么经过白化后,数据的分布将会是一个均值为零,且协方差相等的矩阵。 注意:任何预处理策略(比如数据均值)都只能在训练集数据上进行计算,算法训练完毕后再应用到验证集或者测试集上。在实际操作中,只会做零中心化处理。 参数初始化 不能将所有参数设为0, 因为如果网络中的每个神经元都计算出同样的输出,然后它们就会在反向传播中计算出同样的梯度,从而进行同样的参数更新,神经元之间就失去了不对称性的源头;从代价函数的角度来说, 参数初始化又不能太大,因此权重初始值要非常接近0又不能等于0。 小随机数初始化 过小的数值使得传播的数据分布在0处,那么在反向传播的时候就会计算出非常小的梯度, 出现梯度消失问题;过大的数值使得传播的数据分布在饱和区,同样出现梯度消失问题。 使用$1/\sqrt{n}$校准方差 随着输入数据量的增长, 随机初始化的神经元的输出数据的分布中的方差也在增大。可以推算出:$Var(s)=(nVar(w))Var(x)$,根据$Var(aX)=a^2Var(X)$, 只要在权重前面乘上系数$a=1/\sqrt{n}$就可以。而对于ReLU神经元,一半的数据分布被消减导致方差减半,应改为乘上系数$1/\sqrt{2.0/n}$。 稀疏初始化(Sparse initialization) 将所有权重矩阵设为0,但是为了打破对称性,每个神经元都同下一层固定数目的神经元随机连接,其权重数值由一个小的高斯分布生成。 偏置(biases)的初始化 通常将偏置初始化为0,这是因为随机小数值权重矩阵已经打破了对称性。对于ReLU非线性激活函数,用0.01这样的小数值常量作为所有偏置的初始值能让所有的ReLU单元一开始就激活,就能保存并传播一些梯度, 但是这样做是不是总是能提高算法性能并不清楚。 推荐是使用ReLU激活函数,并且使用w = np.random.randn(n) * np.sqrt(2.0/n)(Xavier init)来进行权重初始化 批量标准化BN 在网络的每一层之前都做预处理, 使得数据服从标准正态分布,将全连接层或卷积层与激活函数之间添加一个BatchNorm层, 使用了批量归一化的网络对于不好的初始值有更强的鲁棒性 由于BN操作也就是标准化是一个简单可求导的操作, 所以对于整个网络依然可以利用梯度下降法进行迭代优化。 批量归一化(Batch Normalization) 批量归一化可以理解为在网络的每一层之前都做预处理,只是这种操作以另一种方式与网络集成在了一起。搞定! 损失 数据损失是一个有监督学习问题,用于衡量分类算法的预测结果(即分类评分)和真实标签结果之间的一致性。公式为:$L=\frac{1}{N}\sum_iL_i$中,N是训练集数据的样本数,相当于对所有样本的数据损失求平均。 分类问题 每个样本数据具有唯一的真实标签 SVM分类器的折叶损失: $$L_i=\sum_{j neq y_i}max(0,f_j-f_{y_i}+1)$$ 有些学者的论文中指出平方折叶损失效果更好 Softmax分类器的交叉熵损失: $$L_i=-log(\frac{e^{f_{y_j}}}{\sum_j e^{f_j}})$$ 当类别的数目非常庞大的时候, 就需要使用 Hierarchical Softmax , Hierarchical Softmax将标签分解成一个树, 每个标签都表示成这个树上的一个路径,这个树的每个节点处都训练一个Softmax分类器来决策左树还是右树, 树的结构对于算法的最终结果影响很大,而且一般需要具体问题具体分析 属性分类 当$y_i$是一个二值向量,每个样本具有一个或多个属性,而且属性之间并不相互排斥。 1、对每个属性创建一个独立的二分类的分类器 $$L_i=\sum_j max(0,1−y_{ij}f_j)$$ 在上式中, $y_{ij}$表示第j个类别的第i个属性的真实值, $y_{ij}$的值为1或者-1 当该类别被正确预测并展示的时候,分值向量fjfj为正,其余情况为负 当一个正样本的得分小于+1,或者一个负样本得分大于-1的时候就会累计损失值 2、对每种属性训练一个独立的逻辑回归分类器 $$L_i=\sum_j y_{ij}log(\sigma(f_j))+(1−y_{ij})log(1-\sigma(f_j))$$ 回归问题 通常是计算预测值和真实值之间的损失, 然后用L2平方范式或L1范式度量差异。如果有多个数量被预测了,要对预测的所有维度的预测求和。 $$L_i=||f-y_i||^2_2$$ $$L_i=||f-y_i||_1=\sum_j|f_j-(y_i)_j|$$ 注意:L2损失要比Softmax损失优化起来困难很多, 因为L2要预测一个真实的确切值, 而Softmax是一种概率意义上的预测, 还有一点就是L2对于异常值来说会导致很大的局部梯度, 所以在回归问题中, 我们依然优先考虑可否转化为分类问题去解决, 比如如果对一个产品的星级进行预测,使用5个独立的分类器来对1-5星进行打分的效果一般比使用一个回归损失要好很多。分类还有一个额外优点,就是能给出关于回归的输出的分布,而不是一个简单的毫无把握的输出值。如果确信分类不适用,那么使用L2损失吧,但是一定要谨慎。 结构化预测 结构化损失是指标签可以是任意的结构,例如图表、树或者其他复杂物体的情况。通常这种情况还会假设结构空间非常巨大,不容易进行遍历。结构化SVM背后的基本思想就是在正确的结构$y_i$和得分最高的非正确结构之间画出一个边界。解决这类问题,并不是像解决一个简单无限制的最优化问题那样使用梯度下降就可以了,而是需要设计一些特殊的解决方案,这样可以有效利用对于结构空间的特殊简化假设。 7 训练神经网络2 Fancier optimization优化方法 训练神经网络的核心问题是对损失函数的优化问题。优化方法有:随机梯度下降法(Stochastic Gradient Descent,SGD),带动量的SGD,AdaGrad,RMSProp,Adam等等。 随机梯度下降的问题: 损失在一个方向很敏感,另一个方向的改变很小! 锯齿形状 参考:CS231N 学习笔记 Lecture7 训练神经网络 - 简书 (jianshu.com) 正则化 通过控制神经网络的容量来防止其过拟合 迁移学习 迁移学习(Transfer learning) 顾名思义就是把已训练好的模型参数迁移到新的模型来帮助新模型训练。 深度学习的模型可以划分为 训练 和 预测 两个阶段。 训练 分为两种策略:一种是白手起家从头搭建模型进行训练,一种是通过预训练模型进行训练。 预测 相对简单,直接用已经训练好的模型对数据集进行预测即可。 迁移学习有几种方式 1)Transfer Learning :冻结预训练模型的全部卷积层,只训练自己定制的全连接层。 2)Extract Feature Vector :先计算出预训练模型的卷积层对所有训练和测试数据的特征向量,然后抛开预训练模型,只训练自己定制的简配版全连接网络。 3)Fine-tune :冻结预训练模型的部分卷积层(通常是靠近输入的多数卷积层),训练剩下的卷积层(通常是靠近输出的部分卷积层)和全连接层。 第一种和第二种训练得到的模型本质上并没有什么区别,拿到新数据集,想要用预训练模型处理的时候,通常都会先用上面方法一或者方法二来看看预训练模型在新数据上的表现怎么样,摸个底。如果表现不错,还想看看能不能进一步提升,就可以试试Fine-tune,进一步解锁卷积层以继续训练模型。 8 深度学习软件 CPU&GPU (我看网上说最新的cs231n已经介绍TPU了) 深度学习用的GPU是Nvidia的。 框架 TF PyTorch 最近也在跟着小土堆二刷Pytorch入门,就先用这个框架吧,之前做毕业也在环境搭建上踩过坑了。 9 CNN案例 AlexNet AlexNet博客 VGG 深网络,小卷积核,定期池化 创新点: 使用了更多的卷积层,更多地使用3x3卷积核代替5x5卷积核(本质上是更大、更深的AlexNet) 采用了模块化设计:将多个卷积层组合成块,多个VGG块后连接全连接层,不同次数的重复块即可得到不同的架构VGG-16、11、19等,网络实现与管理更为方便简洁,有效减少代码量,奠定了今天的网络模型大多分为五个stage的雏形。 GoogLeNet 提升网络性能最直接的办法就是增加网络深度和宽度,这也就意味着巨量的参数。但是,巨量参数容易产生过拟合,也会大大增加计算量,因此GoogleNet设想在不提高参数的情况下,增加网络深度 创新: 设计出Inception块,使得在不增加参数数量的情况下,将网络变得更深 同NiN一样使用全局平均汇聚层,在传入全连接层之前,将每个通道的高和宽变成1,大大减少了展平后的参数数量。 训练时增加了两个辅助分类器(预测时去掉),使用网络得以更稳定的训练(现在有了更好的训练方法,这个特性或许不是必要的) ResNet 学习输入、输出之间的残差,即H ( x ) − x H(x)-xH(x)−x。X -> (H(X) - X) + X。其中X这一部分为直接的identity mapping,而H(X) - X则为有参网络层要学习的输入输出间残差。 增加网络层次时,减少损失函数的衰减、损失。 10 循环神经网络 RNN具有记忆功能,其输出与之前的状态和当前的输入有关,适合处理基于序列的数据。 网络传播机制 正向传播 网络在t时刻接收到输入$x_t$之后,隐藏层的值是$s_t$,输出值是$o_t$。关键一点是,$s_t$的值不仅仅取决于$x_t$,还取决于$s_{t-1}$。可以看出,循环神经网络的输出值$o_t$,是受前面历次输入值$x_t$、$x_{t-1}$、$x_{t-2}$、$x_{t-3}$、…影响的,这就是为什么循环神经网络可以往前看任意多个输入值的原因。 反向传播 同样利用链式法则,梯度沿两个方向传播,一个方向是其传递到上一层网络,另一个是方向是将其沿时间线传递到初始时刻,相比CNN过程更加复杂。 梯度爆炸和消失 RNN在训练中很容易发生梯度爆炸和梯度消失,这导致训练时梯度不能在较长序列中一直传递下去,从而使RNN无法捕捉到长距离的影响。 通常来说,梯度爆炸更容易处理一些。因为梯度爆炸的时候,我们的程序会收到NaN错误;也可以设置一个梯度阈值,当梯度超过这个阈值的时候可以直接截取。 梯度消失更难检测,而且也更难处理一些。总的来说,我们有三种方法应对梯度消失问题: 合理的初始化权重值。初始化权重,使每个神经元尽可能不要取极大或极小值,以躲开梯度消失的区域。 使用relu代替sigmoid和tanh作为激活函数。 使用其他结构的RNNs,比如长短时记忆网络(LTSM)和Gated Recurrent Unit(GRU) LSTM 为解决原始RNN无法处理长距离依赖的问题,长短时记忆网络(LSTM)采用两种状态:h(对短期的输入敏感)、c(保存长期的状态)

2022/8/16
articleCard.readMore

simulink仿真数字通信系统

前言 读了好几年通信工程起码要知道个最简单的通信系统模型吧。 最近时间比较充足,总结一下之前做的信息论与编码实验,回顾一下通信原理的信息论与编码的基本知识。 本实验搭建了完整的通信系统,进行信源编码和信道编码分别提高了有效性和可靠性。(其实我用的定长PCM,不太能提高有效性) 通信系统 设计了如下系统模块,先产生随机模拟信号,进行PCM编码(非均匀量化中使用A律13折线压缩),信道编码分别尝试使用了BCH编码和线性码,调制使用的是2FSK,经过高斯白噪声信道后进行相干解调(通信原理中尝试用simulink比较相干解调、非相干解调和最佳接收机,可参考我的GitHub),抽样判决后进行信道译码和信源译码,最后低通滤波得到模拟信号。 具体系统框图和调制解调子模块框图如下: 结果 比较了BCH、线性码的性能,用无信道编码的系统作为对照,结果如下: 相同信噪比条件下,信道编码可以有效降低系统的误码率,提高系统性能。 为了方便比较,BCH和线性分组码均采用3位编为6位的方式,但是实验中明显看出,BCH(6,3)编码与(6,3)线性分组编码相比,虽然编码效率一致,但是BCH(6,3)编码的性能更胜一筹,可能与线性分组码自定义的生成矩阵有关。 信道编码并不能降低信道的误码率,但能增加纠错能力,使得部分码元即便出现差错也能得到纠正。 除此之外,我还观察了不同信噪比下模拟信号的恢复情况,尤其是误码率为0时的系统,恢复效果如图: 由此可见,即便误码率为0,但是模拟信号也无法完全恢复,原因是抽样量化存在误差,且不可消除,由此也可以说明,PCM并不是一种无失真信源编码。 一些思考 1.信源编码之后的译码问题,就是哈夫曼编码这种变长编码,一旦发生错误,如何译码?比如一个4位码字的前三位错成了一个3位合法码字,而第四位又和下一组混合了,这种就导致后边的继续错下去,无法译码。 我们的实验中只是要求实现无失真的编码,即考虑信源编码的时候,认为信道是无错误,实际应用中哈夫曼编码并没有这么简单,实际中应用的信源编码都是针对某种业务特征采用的具体编码,哈夫曼编码可以说是一种编码思想,而不是实际应用中的一种编码标准。本实验要求使用定长编码,传输错误不会导致信源编码由于译码错误导致的错误积累。 2.Simulink仿真跟Matlab代码仿真最大的区别就是,Simulink是严格按照时间线执行的,然而在编码、信道传输过程中会出现时延,且译码是从0时刻开始,导致译码的时候出现严重差错。 观察各个模块延时的码元个数,在译码之前增加延时模块,使得第一个码到来时正好是第二个码组时刻。比如,在本系统中,信道编码后6个码为一组,而信道传输产生了两个码元时间的时延,所以在信道译码之前,再认为时延四个码元时间,抛弃第一组码,从第二组开始译码。 详见: liuzengyun/IHtest: 信息论与编码实验 (github.com)

2021/9/25
articleCard.readMore

基于开源的livego搭建直播服务器

参加的训练项目需要搭建自己的直播服务器,实现视频直播。 尝试了几种开源的直播服务器,包括srs、livego等,但是感觉各有利弊,srs延迟较高,livego延迟明显比较低,但是出现过一次go切片越界的问题(未解决)。现在从头梳理一下livego的搭建过程。 按照惯例先介绍livego:开源的简单高效的直播服务器! 安装和使用非常简单; 纯 Golang 编写,性能高,跨平台; 支持常用的传输协议、文件格式、编码格式; 详: https://github.com/gwuhaolin/livego 下载编译启动livego 首先,在我们的服务器上clone livego项目:git clone https://github.com/gwuhaolin/livego.git 。 检查是否安装go,如图我已安装。如果没有go的环境就先下载一个:yum install go 。 在livego目录下编译livego:go build。这里有个坑,就是go被墙了,无法使用命令,代理一下即可: go env -w GOPROXY=https://goproxy.cn (详),然后再编译就没问题了。 然后启动就可以了,在livego目录:./livego 执行二进制文件。启动成功如图。 访问 http://ip:8090/control/get?room=rov 获取一个名为rov(任取)的房间的串流密钥备用。别忘了换成自己服务器的ip! 使用OBS推流到服务器 下载OBS Studio: https://obsproject.com/ 配置OBS推流:打开软件设置,找到推流一栏,如下设置。标蓝的live是默认的appname,可以在服务器端配置文件中修改,不改也行。串流密钥填上刚才获取到的。 添加视频流来源:如图我添加了一个显示器采集,也就是录屏直播。 如果你的显示器采集出来是黑屏,那么这个坑我也踩过了。由于笔记本电脑有两块显卡,导致正在使用的和obs采集的不是一个,需要在英伟达控制面板修改obs这个应用的默认显卡。详情见连接: https://tieba.baidu.com/p/4962294600 开始推流: 正常推流的话会显示绿色的状态: 播放直播 使用vlc(自行下载)播放网络串流:rtmp://ip:1935/live/rov。标蓝的分别是appname和room。 然后就可以观看了!(我看我自己) 后记 这样用vlc播放rtmp串流肯定是不行的,况且就算用网页播放rtmp,由于flash已停用,也不太方便。 好在livego支持多种播放协议,包括flv、m3u8格式等,目前有两种想法: 用网页端使用哔哩哔哩开源的flv.js解析flv,使用H5 video播放; 安卓客户端解析m3u8播放。 再者,还要继续探索:如何降低延迟?如何实现串流的转发分发?如何实现权限拦截?等等……

2021/2/2
articleCard.readMore

EDA实验二 功能可调综合计时器

题目 设计一个可调的综合计时器。具体功能: 1、显示小时、分、秒,提供置零功能。显示在七段管或LCD屏幕上,可以考虑24/12小时模式切换功能。 2、能够对秒、分、小时进行分别修改,可以两位数整体修改或每位独立修改 3、整点报时功能,整点可以显示一定形式的LED来表示。 4、闹钟功能,设定特定时间,到时间以特定LED显示来显示闹钟。注意闹钟持续时间,也可以参考懒人闹钟模式。 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 module lab2(hex0,hex1,hex2,hex3,hex4,hex5,hex6,hex7,key,ledr,ledg,clk_50); input clk_50;//50MHz时钟 input[3:0] key;//四个按键 output reg[6:0] hex0,hex1,hex2,hex3,hex4,hex5,hex6,hex7;//七个数码管输出 output reg[17:0] ledr=18'b000000000000000000;//红灯,初始化为灭 output reg[8:0] ledg=9'b000000000;//绿灯,初始化为灭 reg[8:0] ztimer=0,ntimer=0;//计时器,控制灯亮的时间 reg[9:0] hour=0,minute=0,second=0,nhour=11,nminute=11,nsecond=11,th=0,tm=0,ts=0;//计时器和闹钟的时分秒 reg[5:0] state=0,zstate=0,nstate=0,temp=0,t1,t2,t3,t4,t5,t6;//1、切换时钟与闹钟 2、切换时钟调整时的时分秒 3、切换闹钟调整时的时分秒 divclk dc(clk_50,clk1);// always@(negedge key[2])//改state begin state=(state+1)%2; end always@(negedge key[1])//改zstate和nstate begin temp=state; if(temp==0)//如果在计时状态 begin zstate=(zstate+1)%4; end else//闹钟状态 begin nstate=(nstate+1)%4; end end always@(negedge key[0])//增加 begin t4=state; t5=zstate; t6=nstate; th=hour; tm=minute; ts=second; if(t4==0)//如果在计时状态 begin if(t5==1) begin if(th==23) th=0; else th=th+1; end if(t5==2) begin if(tm==59) tm=0; else tm=tm+1; end if(t5==3) begin if(ts==59) ts=0; else ts=ts+1; end end else//闹钟状态 begin if(t6==1) begin if(nhour==23) nhour=0; else nhour=nhour+1; end if(t6==2) begin if(nminute==59) nminute=0; else nminute=nminute+1; end if(t6==3) begin if(nsecond==59) nsecond=0; else nsecond=nsecond+1; end end end always@(posedge clk1,negedge key[3]) begin t1=state; t2=zstate; t3=nstate; if(!key[3])//按下置零 begin hour=0; minute=0; second=0; show(hour/10,hex7); show(hour%10,hex6); show(minute/10,hex5); show(minute%10,hex4); show(second/10,hex3); show(second%10,hex2); show(10,hex1); show(zstate+12,hex0); end else//clk1来了 begin if(t1==0) begin if(t2==0) begin //下面是正常的计时 if(second==59) begin second=0; if(minute==59) begin minute=0; if(hour==23) hour=0; else hour=hour+1; end else minute=minute+1; end else begin second=second+1; end show(hour/10,hex7); show(hour%10,hex6); show(minute/10,hex5); show(minute%10,hex4); show(second/10,hex3); show(second%10,hex2); show(10,hex1); show(12,hex0); //以上是正常的计时,以下是报时和闹钟 if(minute==0&&second==0) ztimer=59; else ztimer=0; if(hour==nhour&&minute==nminute&&second==nsecond) ntimer=59; else ntimer=0; if(ztimer>0) begin ledr=18'b111111111111111111;//亮红灯 ztimer=ztimer-1; end else ledr=18'b000000000000000000;//关红灯 if(ntimer>0) begin ledg=9'b111111111;//亮绿灯 ntimer=ntimer-1; end else ledg=9'b000000000; end else if(t2==1) begin hour=th; show(hour/10,hex7); show(hour%10,hex6); show(minute/10,hex5); show(minute%10,hex4); show(second/10,hex3); show(second%10,hex2); show(10,hex1); show(t2+12,hex0); end else if(t2==2) begin minute=tm; show(hour/10,hex7); show(hour%10,hex6); show(minute/10,hex5); show(minute%10,hex4); show(second/10,hex3); show(second%10,hex2); show(10,hex1); show(t2+12,hex0); end else if(t2==3) begin second=ts; show(hour/10,hex7); show(hour%10,hex6); show(minute/10,hex5); show(minute%10,hex4); show(second/10,hex3); show(second%10,hex2); show(10,hex1); show(t2+12,hex0); end end else if(t1==1) begin show(nhour/10,hex7); show(nhour%10,hex6); show(nminute/10,hex5); show(nminute%10,hex4); show(nsecond/10,hex3); show(nsecond%10,hex2); show(11,hex1); show(nstate+12,hex0); end end end task show; input reg[3:0] result; output reg[6:0] out; if(result==0) out=7'b1000000;// 显示0 else if(result==1) out=7'b1111001;// 显示1 else if(result==2) out=7'b0100100;// 显示2 else if(result==3) out=7'b0110000;// 显示3 else if(result==4) out=7'b0011001;// 显示4 else if(result==5) out=7'b0010010;// 显示5 else if(result==6) out=7'b0000010;// 显示6 else if(result==7) out=7'b1111000;// 显示7 else if(result==8) out=7'b0000000;// 显示8 else if(result==9) out=7'b0011000;// 显示9 else if(result==10)out=7'b0111111;// 显示- else if(result==11)out=7'b1110110;// 显示= else if(result==12)out=7'b1111111;// 显示“ ” else if(result==13)out=7'b0001001;// 显示H else if(result==14)out=7'b0001110;// 显示F else if(result==15)out=7'b0010010;// 显示S else out=7'b1111111;// 不显示 endtask endmodule module divclk(clk_50,clk1); input clk_50;// clk50:输入50MHz信号;reset:复位信号 output reg clk1=1; // clk1:新产生的1Hz信号 integer i=0; always@(posedge clk_50) begin if(i==25000000) begin i=0; clk1=~clk1; end else i=i+1; end endmodule 效果 ps: 1、使用倒数第二个数码管表示目前的工作模式,“-”表示工作在计时器模式,“=”表示工作在闹钟调整模式。 2、使用倒数第一个数码管表示目前正在修改的位数,“H”表示修改hour,“F”表示修改minute,“S”表示修改second。

2020/11/21
articleCard.readMore

EDA实验一 指令运算单元设计——第一次用FPGA开发板

题目 设计一个指令运算单元ALU,完成功能如下。 (1)操作类型1:将操作数1作为一个无符号二进制数,在七段管以十进制显示二进制序列等效值。 (2)操作类型2:实现操作数3、操作数4之间相加、减、乘的操作,在七段管以十/十六进制进制显示操作数和结果。操作数3和4为BCD码表示的2位十进制数(表示的值为00-99)。 实现代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 module lab1(sw,hex0,hex1,hex2,hex3,hex4,hex5,hex6,hex7); input[17:0] sw; output[6:0] hex0,hex1,hex2,hex3,hex4,hex5,hex6,hex7; reg[4:0] h7,h6,h5,h4,h3,h2,h1,h0; reg[15:0] o1,o2,s; reg[17:0] sw0; always@(*) begin if(sw[3:0]>9) sw0[3:0]=9; else sw0[3:0]=sw[3:0]; if(sw[7:4]>9) sw0[7:4]=9; else sw0[7:4]=sw[7:4]; if(sw[11:8]>9) sw0[11:8]=9; else sw0[11:8]=sw[11:8]; if(sw[15:12]>9) sw0[15:12]=9; else sw0[15:12]=sw[15:12]; if(sw[17:16]==0) begin h7=16; h6=16; h5=16; h0=sw[15:0]%10; h1=sw[15:0]/10%10; h2=sw[15:0]/100%10; h3=sw[15:0]/1000%10; h4=sw[15:0]/10000; show(h0,hex0); show(h1,hex1); show(h2,hex2); show(h3,hex3); show(h4,hex4); end else if(sw[17:16]==1) begin o1=sw0[15:12]*10+sw0[11:8]; o2=sw0[7:4]*10+sw0[3:0]; s=o1+o2; h7=sw0[15:12]; h6=sw0[11:8]; h5=sw0[7:4]; h0=s%10; h1=s/10%10; h2=s/100; h3=16; h4=sw0[3:0]; show(h0,hex0); show(h1,hex1); show(h2,hex2); show(h3,hex3); show(h4,hex4); show(h5,hex5); show(h6,hex6); show(h7,hex7); end else if(sw[17:16]==2) begin o1=sw0[15:12]*10+sw0[11:8]; o2=sw0[7:4]*10+sw0[3:0]; s=o1*o2; h7=sw0[15:12]; h6=sw0[11:8]; h5=sw0[7:4]; h0=s%10; h1=s/10%10; h2=s/100%10; h3=s/1000%10; h4=sw0[3:0]; show(h0,hex0); show(h1,hex1); show(h2,hex2); show(h3,hex3); show(h4,hex4); show(h5,hex5); show(h6,hex6); show(h7,hex7); end else if(sw[17:16]==3) begin o1=sw0[15:12]*10+sw0[11:8]; o2=sw0[7:4]*10+sw0[3:0]; if(o1>=o2) begin s=o1-o2; h7=sw0[15:12]; h6=sw0[11:8]; h5=sw0[7:4]; h0=s%10; h1=s/10%10; h2=s/100%10; h3=16; h4=sw0[3:0]; show(h0,hex0); show(h1,hex1); show(h2,hex2); show(h3,hex3); show(h4,hex4); show(h5,hex5); show(h6,hex6); show(h7,hex7); end else begin s=o2-o1; h7=sw0[15:12]; h6=sw0[11:8]; h5=sw0[7:4]; h0=s%10; h1=s/10%10; h2=s/100%10; h3=10; h4=sw0[3:0]; show(h0,hex0); show(h1,hex1); show(h2,hex2); show(h3,hex3); show(h4,hex4); show(h5,hex5); show(h6,hex6); show(h7,hex7); end end end task show; input reg[3:0] decc;// 输入,无符号二进制数 output reg[6:0] out;// 输出,7位二进制数值 if(decc==0) out=7'b1000000;// 七段管显示0 else if(decc==1) out=7'b1111001;// 七段管显示1 else if(decc==2) out=7'b0100100;// 七段管显示2 else if(decc==3) out=7'b0110000;// 七段管显示3 else if(decc==4) out=7'b0011001;// 七段管显示4 else if(decc==5) out=7'b0010010;// 七段管显示5 else if(decc==6) out=7'b0000010;// 七段管显示6 else if(decc==7) out=7'b1111000;// 七段管显示7 else if(decc==8) out=7'b0000000;// 七段管显示8 else if(decc==9) out=7'b0011000;// 七段管显示9 else if(decc==10)out=7'b0111111;// 七段管显示- else out=7'b1111111;// 七段管不显示 endtask endmodule 实现效果 十进制显示 加法 乘法 减法 减法

2020/11/15
articleCard.readMore

NodeMCU-ESP8266联网获取实时天气并使用lcd1602显示

实现效果 硬件准备 NodeMCU-ESP8266开发板 lcd1602显示屏(使用I2C总线) 杜邦线若干 可以联网的WiFi信号 软件环境 Arduino IDE 心知天气API(免费版够用) 连线:NodeMCU——I2C GPIO4——SDA GPIO5——SCL VIN——VCC GND——GND 这里这个连线还是很坑的。 供电之所以使用VIN而不使用3.3V,是因为VIN的供电是5V的,3.3V供电也不是不行,但是显示效果不太行,几乎看不清。 另外,之前网上看别人做lcd1602显示,都是连D3、D4两个脚,然后一直不管用,直到忍无可忍查了NodeMCU-ESP8266的管脚功能表,如下:(来源: https://tttapa.github.io/ ) GPIOFunctionStateRestrictions 0Boot mode select3.3VNo Hi-Z 1TX0-Not usable during Serial transmission 2Boot mode select TX13.3V (boot only)Don’t connect to ground at boot time Sends debug data at boot time 3RX0-Not usable during Serial transmission 4SDA (I²C)-- 5SCL (I²C)-- 6 - 11Flash connectionxNot usable, and not broken out 12MISO (SPI)-- 13MOSI (SPI)-- 14SCK (SPI)-- 15SS (SPI)0VPull-up resistor not usable 16Wake up from sleep-No pull-up resistor, but pull-down instead Should be connected to RST to wake up 开发过程 开发之前先去心知天气注册一个账户 ,申请一个免费的API,用来获取实时天气。 引入最基本的ESP8266WiFi库,先连接一个能上网的WiFi,使用ESP8266通过http请求获取信息,几秒钟请求一次,更新信息。返回的是一个JSON字符串,使用ArduinoJson库函数解析JSON,得到需要的具体数据。最后通过LiquidCrystal_I2C库将天气情况显示在LCD1602上。 代码与库 本项目: https://github.com/liuzengyun/esp8266_Weather ArduinoJSON库: https://github.com/bblanchon/ArduinoJson LiquidCrystal_I2C库:Arduino IDE中库管理中下载即可。

2020/9/13
articleCard.readMore

SSM框架:导出数据库内容到Excel表格

经常遇到一些网站,尤其是管理员后台,有一个导出数据的功能。 在做暑期作业的时候,正需要这个功能,想起了之前用过的POI,查了一些资料发现POI吃内存比较严重,正好国内阿里改进了POI,形成了EasyExcel,并且已经开源。 官方说明文档 https://www.yuque.com/easyexcel/doc/easyexcel 功能预览 前端通过按钮,向后端接口发送post请求,实现文件下载。 接口实现 导入Maven依赖 1 2 3 4 5 6 7 8 9 10 11 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.6</version> </dependency> <dependency> <groupId>org.projectlombok </groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> Mapper.xml 1 2 3 4 <select id="selectAll" resultMap="BaseResultMap"> select * from uusers </select> Mapper接口声明 1 2 3 public interface UusersMapper { List<Uusers> selectAll(); } Uusers表实体类 继承自com.alibaba.excel.metadata.BaseRowModel类,每个属性前添加@ExcelProperty注解,声明导出Excel的表头。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class Uusers extends BaseRowModel { @ExcelProperty(value = "id",index = 0 ) private Integer id; @ExcelProperty(value = "用户名",index = 1 ) private String username; @ExcelProperty(value = "密码",index = 2 ) private String password; @ExcelProperty(value = "身份",index = 3 ) private String identity; @ExcelProperty(value = "手机号",index = 4 ) private String phone; @ExcelProperty(value = "性别",index = 5 ) private String gender; @ExcelProperty(value = "姓名",index = 6 ) private String name; @ExcelProperty(value = "年龄",index = 7 ) private Integer age; @ExcelProperty(value = "邮箱",index = 8 ) private String email; } Service层 1 2 3 4 5 6 @Autowired private UusersMapper uusersMapper; @Override public List<Uusers> getAll() { return uusersMapper.selectAll(); } Controller层 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @RequestMapping("/downloadUsers") @ResponseBody public void downloadUsers(HttpServletResponse response) throws Exception { List<Uusers> list = uusersService.getAll(); ServletOutputStream out = response.getOutputStream(); ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, true); String fileName = "用户信息表"; Sheet sheet = new Sheet(1, 0,Uusers.class); //设置自适应宽度 sheet.setAutoWidth(Boolean.TRUE); // 第一个 sheet 名称 sheet.setSheetName("用户信息"); writer.write(list, sheet); //通知浏览器以附件的形式下载处理,设置返回头要注意文件名有中文 response.setHeader("Content-disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) + ".xlsx"); writer.finish(); response.setContentType("multipart/form-data"); response.setCharacterEncoding("utf-8"); out.flush(); out.close(); }

2020/8/20
articleCard.readMore

Java网络编程-TCP通信

概述 TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。 Java对基于TCP协议的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。 Java为客户端提供了Socket类,为服务器端提供了ServerSocket类。 接收端 创建服务器端的Socket对象(ServerSocket) : ServerSocket(int port) 监听客户端的连接,返回一个Socket对象 : Socket accept() 获取输入流,读数据: InputStream getInputStream() 释放资源 : void close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /* 接收数据的步骤 1. 创建服务器端的Socket对象(ServerSocket) 2. 获取输入流,读数据,并把数据显示在控制台上 3. 释放资源 */ public class ServerDemo { public static void main(String[] args) throws IOException { // 创建服务器端的Socket对象(ServerSocket) // ServerSocket(int port) 创建绑定到指定端口的服务器套接字 ServerSocket ss = new ServerSocket(9000); // Socket accept() 侦听要连接到此套接字并接受它 Socket accept = ss.accept(); // 获取输入流,读数据,并把数据显示在控制台上 InputStream is = accept.getInputStream(); byte[] bytes = new byte[1024]; int len = is.read(bytes); String s = new String(bytes, 0, len); System.out.println("数据是:" + s); // 释放资源 accept.close(); ss.close(); } } /* 先打开服务器,后打开客户端 */ 发送端 创建客户端的Socket对象(Socket) : Socket(String host, int port) 获取输出流,写数据 : OutputStream getOutputStream() 释放资源 : void close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import java.io.IOException; import java.io.OutputStream; import java.net.Socket; /* 发送数据的步骤 1. 创建客户端的Socket对象(Socket) 2. 获取输出流,写数据 3. 释放资源 */ public class ClientDemo { public static void main(String[] args) throws IOException { // 创建客户端的Socket对象(Socket) // Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号 // 可以写自己或者通网络下别人的IP地址 Socket socket = new Socket("192.168.1.63",9000); // 获取输出流,写数据 // OutputStream getOutputStream() 返回此套接字的输出流 OutputStream os = socket.getOutputStream(); os.write("hello world".getBytes()); // 释放资源 socket.close(); } }

2020/4/11
articleCard.readMore

我要这差分放大电路有何用?

从上一周开始,模电的学习迈进了差分放大电路的大门。模电本来就是一门我没怎么听懂的课程,连续学习几节课后,眼看着差分放大电路快要讲完了,笔记也做了不少,但总感觉没理解其中的道理。 所以今天先把进度停下来,查点资料,想一想为什么要引入差分放大电路这个东西,或者说是我们怎么一步一步从普通的晶体管放大电路转换到差分放大电路的。也算是理顺一下自己的学习思路,不至于越学越迷糊。 从普通的放大电路说起 在第二章设计普通的晶体管放大电路时,以共射放大为例,我们遇到了一个问题:静态工作点Q不稳定,导致交流信号无输入时,输出端出现“零点漂移”现象。 “在温度变化、三极管老化、电源电压波动等外部因素的影响下,将引起静态工作点的变动,严重时将使放大电路不能正常工作,其中影响最大的是温度的变化。” 我们把上述温度引起的零点漂移称为”温漂”,既然它的影响最大,那么我们接下来的工作主要聚焦于“如何抑制温漂”好了。 对于稳定工作点的技术,可以从元件、环境、电路改进方面入手,比如采取恒温措施、选择温度性能好的元件等,但是这里我们主要是介绍引入RE电阻进行负反馈调节的方法(因为我主要想说差分放大电路)。 这里就必须要搞明白温度变化是如何影响Q的。Q的变化主要得因于温度变化引起了IC的变化,其实这归根结底是因为温度变化对ICBO、UBE、β产生了影响。(具体是如何影响的,那就涉及晶体管原理了) 说到这里,其实我们的目标就已经很明确了,那就是尽量抑制温度变化引起的IC变化,从而保证静态工作点Q的稳定。 好了,RE可以出来了! 如上图,在晶体管的发射极加一个电阻RE,当IC变大时,RE上的压降也会变大,也就提高了发射极电位UE,由于分压偏置,基极电位UB几乎不变,所以UBE会大幅度下降,从而使IB下降,那么IC=βIB也自然会下降。如此一来,由于RE的负反馈调节作用,本来的IC变化又被拉回来了。 由此看来,RE的阻值仿佛越大越好,因为RE越大其对IC的负反馈调节越强,即抑制变化的作用越明显。但是,RE存在也造成了UCE的减小,那么在放大小信号的过程中,电路的动态范围会因此变窄(非线性失真);再者,RE如果太大,那么功耗也是一个不得不考虑的问题了。所以,RE的阻值应该适当选取。 静态情况下舒服了,那么动态呢? 以上讨论的是在静态分析过程中如何维持Q点稳定,方法是我们引进了发射极电阻RE。但是在动态分析过程中,RE暴露出了致命性的缺点,它会使得整个电路的放大性能降低(放大倍数减小)。 有问题总会有解决方法(这是个哲学问题,有时间拿出来单独说说!)。解决这个问题的方法是,我们给RE并联了一个旁路电容CE,这样在动态分析画出交流通路时,我们神奇的发现,RE被CE短路掉了,动态下电路又回到了原始的样子。 如此,既在静态下引入RE稳定了工作点,又不会因为RE的存在导致动态性能下降,真是可谓XXXX(想了几分钟没想出个合适的词,用“牛逼”又显得不太严谨)。 轮到多级放大电路了 多级放大电路同样也存在Q点不稳定导致的零点漂移现象,而且这里的零点漂移更致命了,因为后级还会把前级的漂移继续放大,这样下去那还了得? 多级放大电路中最常见的当属直接耦合的方式了。 当然了,问题也总会在我们猝不及防的时候出现(这也是个哲学问题,有时间一并探讨)。因为多级放大电路的集成化要求高,这里如果引入大个头的旁路电容CE来解决RE存在的缺点,显然不是一个聪明的选择;二来即使引入RE也还会存在Q点的微小波动,但是在多级放大电路中这种微小的波动也会被不断地放大。 到这里,我们再提出一个想法来消除零点漂移。试想,如果我们在输出端加一个电源,要求这个电源产生和原电路零点波动相同的电压,那么用原来的输出和此电源作差之后的结果作为输出,不就只保留了放大之后的小信号了嘛。 问题来了,这种电源怎么找呢?我们干脆也用一个相同的晶体管吧,与原来的晶体管呈镜像关系,毕竟相同的环境下零点就算是漂移也会漂得一个样,那么两个输出作差总会把漂移消除掉吧。我们给这样一种电路取个高大上的名字,就叫差分放大电路吧。 但是这样两个管子本身的零漂并没有得到抑制,两侧在大信号范围内作到完全抵消很困难。那就再加上RE抑制一下呗,这里原理和单管放大时一样。 (这里略去引入负电源-VE的过程,只抄一段笔记吧!) 负电源的作用: (1)补偿Re上的直流压降,保证信号动态工作范围。 (2)保证差分管导通,可以输出正负两个方向的信号。 (3)为Ia1、Ia提供偏置电流。 很明显又绕回来了,本来就是为了不引进CE而放弃了RE,但是这里又加进来了RE。仔细观察,神奇的事情出现了,动态下在两侧输入共模信号时,iRE=2iE,RE的负反馈作用出现了双倍的效果,降低了共模输入下放大倍数;而两侧差模输入时,由于iE1=-iE2,RE上不会有电流经过,当然也不会有压降了,那肯定也没有负反馈作用了。 很明显,在这个电路中:1.抑制了零点漂移;2.抑制了共模信号;3.放大了差模信号;4.提高了电路共模抑制比。 对于差分放大电路的引入过程,到这里也算是挺清楚了。至于差分放大电路的接法和进一步改进,那都是后话了。

2020/3/23
articleCard.readMore

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick Start Create a new post 1 $ hexo new "My New Post" More info: Writing Run server 1 $ hexo server More info: Server Generate static files 1 $ hexo generate More info: Generating Deploy to remote sites 1 $ hexo deploy More info: Deployment

2017/9/1
articleCard.readMore