- 博客(53)
- 资源 (4)
- 收藏
- 关注

原创 fft快速傅里叶变换(二)
本文主要依据前面所写的文章请戳进行规律总结,便于后续的程序实现。这里仍然以8点fft进行分析,具体示意图如下:说明:(1)m代表某一级(N = 8时,一共可以分为m = 0,1,2三级),M表示一共有多少级(2)旋转因子记为:WNpW_{N}^{p}WNp,p是旋转因子指数(3)旋转因子的增量记为:k,比如在m级最后一级增量k总为1(4)B表示每个蝶形运算的输入数据的间隔由上图分析可知(1)每个蝶形运算中两个输入数据的间隔B = 2m2^{m}2m(2)有2m2^{m}2m个旋转因子(
2020-11-22 20:41:07
665
2

原创 fft快速傅里叶变换(一)
fft变换并不是什么新的算法,它只是为了加速dft运算的一种方法,dft的表达式如下:很显然求出N点的X(k)需要NN次复数乘法和N(N - 1)次复数加法;我们都知道实现一次复数乘法需要四次实数乘两次实数加,实现一次复数加法需要两次实数加;那么当N很大的时候,计算量就会相当的大。dft作为信号处理中最为常用的算法,这么大的计算量显然是不能在实际中得到很好的应用,为此fft就出现了;fft是如何进行的呢?下面将进行详细的介绍。1、基于时间的抽取(DIT)基2fft算法对于下式令N=xMN = x
2020-11-21 20:57:34
967
2

原创 精度(precision),召回率(recall),map
目标检测中经常会见到precision,recall,map三个指标用来评估一个模型的优劣,当然在很多其他的应用中也可以看到这三个指标的具体应用;因此很有必要对这三个指标进行详细的了解。在介绍这三个指标之前有必要先了解几个基本的术语:True positives,True negatives,False positives,False negative。大雁和飞机假设现有一个测试集,测试集中仅包含大雁和飞机两种目标,如图所示:假设分类的目标是:取出测试集中所有飞机图片,而非大雁图片现做如下定义:
2020-10-20 23:53:18
4498
3

原创 yolov3损失函数分析
yolov1到v3损失函数都是逐步修改而来,特别是v4,v5损失函数的改动对于目标检测的性能和效果具有较大的提升;当然v3相比v1,v2还是有不少提升的,这种性能提升不仅仅是损失函数所带来的,网络结构的修改和优化也具有比较可观的效果。本文主要讲解v3损失函数的设计,这里首先回顾下v1,v2:v1损失函数:v2的损失函数:v2只是在v1的基础上改动了box宽高的损失计算方式,即去除了w和h的根号:v3相对v2最大的改动就是分类的损失以及box置信度的损失改为了二分交叉熵:上式中S为网络输出层网
2020-10-19 22:39:12
6210
2

原创 yolov3读取数据
yolov3数据预处理这块基本是一些比较常用的数据处理手段,将读取的图片数据转换为rgb并乘以1/255进行归一化,将图像大小通过缩放和pad的方式转换为宽高相等的图像,且转换后图像的大小为32的整数倍;为什么要转换为32的整数倍呢??? 因为网络设计最大的stride为32,如果不为32的整数倍,那么网络前向的过程中有可能会出现奇数倍的数据宽高,那么上采用后的图像再和前面的网络层进行特征融合就会出现维度不匹配的现象,所以这就是为什么要设置为32的整数倍。下面就是yolov3数据预处理的代码实现impor
2020-10-11 17:46:31
633
1

原创 yolov3模型训练,测试,检测
前面几篇博客已经对yolov3的实现过程做了一个大概的分析与讲解,本文主要讲解v3的模型训练,测试,检测的实现;这部分更多的是对前面模块的组合实现,核心的实现还是数据的准备,加载,模型搭建,代价函数的求解。网络训练部分的实现:train.pyfrom __future__ import division from models import *from utils.logger import *from utils.utils import *from utils.datasets impor
2020-10-11 12:17:08
1145
3

原创 yolov3模型搭建
yolov3的网络结构也比较简单,基本就是一些模块的重复,本文主要基于yolov3-tiny进行讲解,具体的网络结构如下:对上图结合相应的.cfg文件进行对比分析,model.py里面实现了网络的构建,具体代码如下:from __future__ import division import torchimport torch.nn as nnimport torch.nn.functional as Ffrom torch.autograd import Variableimport n
2020-10-11 11:50:39
929
1

原创 yolov3制作自己的训练数据
coco数据集不仅可以用于做目标检测还可以用于进行语义分割,这里主要讲解基于yolov3进行目标检测的数据准备。由于coco数据集的标签信息是以.json的格式存储的,因此有必要转换为具体的格式来进行模型训练与评估。具体的实现方式如下:# -*- coding: utf-8 -*-"""Created on Tue Jul 2 11:41:44 2019@author: Administrator"""#from __feature__ import print_functionimport
2020-10-11 11:32:04
417
1

原创 yolov3实现理论
1、yolov3简介yolov3已经出来好久了,最近一直在做基于yolo系列的检测相关工作,并对相关的源码进行了研究与分析。yolov3并没有很大的创新,更多的是借鉴了最近两年一些网络构造技巧。不过不得不承认效果还是很赞的,在保持速度的前提下,提升了预测精度,尤其是小目标物体的检测相比v1、v2来说得到了较大的改善。yolov3的主要改进:调整了网络结构;利用多尺度特征进行目标检测;对象分类用logistic取代了softmax。2、网络结构以darknet-53为例,具体结构如下:其中re
2020-10-11 10:53:28
642
1

原创 pytorch模型量化尝试
pytorch现在已经支持模型量化,主要支持两种量化模式(qnnpack和fbgemm):qnnpack是基于tensor的模式,这种相当于一种全局量化模式;另外fbgemm是基于通道的模式,相比qnnpack,fbgemm是以及基于通道的局部量化模式;需要说明的是这两种模式主要是针对权重而言的,激活函数的量化都是一样的。这里给出一个量化示例,pytorch目前只支持8bit的量化。实现过程依然是承接前一篇博客而来,只是添加了量化部分而已,代码实现如下:import osimport torchim
2020-09-24 20:45:48
6966
12

原创 基于numpy实现的卷积,通道卷积,batchnorm前向过程(二)
我们通常在做一些验证的过程中需要自己手动实现神经网络的一些基础单元,但是自己一行行代码实现的代码往往执行过慢,好在我们可以借助numpy的矩阵操作实现这些基本单元。前面的文章可参考博文我手动实现了常规卷积,通道卷积,全连接的前向过程,结果正常,但是速度有些让人担忧。于是乎,又切换到numpy实现了一遍,代码基本上是github上的,自己看懂了过程稍微修改了下,速度还是很给力。原理这里不做讲解,在前一篇博文已经做了大概的讲解,这里主要给出代码的实现以及相关应用。为了采用矩阵运算,需要先将输入数据转换为向量,
2020-09-23 22:28:01
800

原创 python实现conv(卷积),dept_conv(通道卷积),batchnorm(批量归一化)的前向过程(一)
神经网络已经在各行各业都得到了普遍的应用,然而在工程落地以及一些验证过程中有必要自己实现一些常用的模块,比如卷积,池化,批量归一化等常规的神经网络模块。尽管现在都是各种调库的天下,自己在做相关工程发现了解和实现这些基本模块还是很有必要的,不仅加深自己的理解,更加容易工程落地。神经网络的基础这里就不过多介绍,直接上实现代码。卷积实现:输入数据排布[N,chin,dim_inh,dim_inw],权重的排布[chout,chin,kernelh,kernelw],输出数据排布[N,chout,dim_ou.
2020-09-23 21:02:02
3805
原创 麦克风阵列之一阶差分麦克风阵列
beamforming,一阶差分麦,differential mic array,音频处理,语音增强,麦克风阵列
2022-06-04 18:15:49
4479
3
原创 音频raw数据转wav数据
音频文件格式很多,常见的有raw,pcm,wav等,下面主要是raw数据转换为wav数据的实现,具体实现代码如下:def raw2wav(inf_str,outf_str,sampleRate = 44000): pcmfile = open(inf_str, 'rb') pcmdata = pcmfile.read() wavfile = wave.open(outf_str, 'wb') wavfile.setframerate(sampleRate) wav
2021-03-28 17:26:49
2315
原创 python 音频文件采样率转换
音频处理中经常会遇到各种采样率的文件,一般需要经过采样率的转换才能得到自己需要的采样率音频文件,下面提供一种音频转换方法,具体程序如下:def resample_rate(path,new_sample_rate = 16000): signal, sr = librosa.load(path, sr=None) wavfile = path.split('/')[-1] wavfile = wavfile.split('.')[0] file_name = wavfil
2021-03-22 09:56:56
5419
原创 深度学习vad人声检测之模型设计
本博文主要vad训练用到的模型结构,可以采用dnn之类网络,亦可以采用cnn网络实现,这里采用的实现方式是基于cnn的,网络架构在一定程度上影响这模型的精度,但是更多的是数据起着决定性的作用。实现过程也比较简单,直接上代码,具体实现如下:import torch.nn as nnimport mathimport torchfrom .dfsmn import DFSMN import numpy as npimport torch.nn.functional as Ffrom torch.a
2021-02-27 22:59:39
2210
原创 深度学习vad人声检测之训练数据加载
vad训练数据的特征在前面的博客已经准备好了,下面就是利用准备好的数据进行模型训练,训练主要包含了下面几个步骤:(1)加载数据(2)搭建模型(3)模型训练加载数据:主要是加载训练数据的特征和对应标签,具体实现如下:import torchfrom torch.utils import dataimport jsonimport osimport soundfile as sfimport numpy as npimport mathdef read_audio_file1(pat
2021-02-27 22:53:25
1276
原创 深度学习vad人声检测之特征生成
得到加噪合成数据后,下面就可以进行特征生成,本博文这里采用的是26维的mfcc特征,当然你也可以根据自己的需求选择不同的特征。准备好了数据,导入直接生成即可,注意这里分帧的方式要和标签制作一致,这里给出的程序当然是一致的。另外需要注意的就是数据均衡的问题,程序中也有体现,具体实现如下:# -*- coding: utf-8 -*-from python_speech_features import mfccimport scipy.io.wavfile as wavimport utilsimpo
2021-02-21 21:07:04
823
1
原创 深度学习vad人声检测之数据合成
vad的主要目的是检测声音(这里特指人声),实际环境当中,声音往往存在很多的噪声,即便人在说话的时候也会存在噪声;所以前面制作标签的干净数据需要加入噪声来合成含有噪声的音频数据,从而使得训练出来的模型对噪声更具鲁棒性。数据合成代码实现如下:audio_lib.py# -*- coding: utf-8 -*-"""@author: chkarada"""import osimport numpy as npimport soundfile as sfimport subprocessim
2021-02-21 20:54:16
1598
1
原创 深度学习vad人声检测之标签制作
深度学习几乎渗透到了各行各业,最火热的莫过于视觉算法。然而,音频相关的很多处理算法也逐渐被深度学习所浸润,vad作为音频前处理的一个操作得到了很广泛的应用,比较典型的vad检测算法是通过提取特征,构造高斯模型得到每段音频的概率来确认是人声还是噪声(包含了静默);尽管传统vad通过合理的设置参数也能取得可观的效果,但是在当下数据驱动时代,深度学习的效果要比传统vad算法胜任的多,当然这个前提是模型训练数据要足够的丰富。下面从深度学习的角度解析vad算法的实现,基于深度学习的vad实现并不困难,关键的部分就是
2021-02-21 20:37:40
3603
3
原创 pytorch conv1d
conv1d从命名就可以看出就是一维卷积,其具体函数接口如下(该内容直接摘自官网):import torchimport torch.nn as nnm = nn.Conv1d(16,33,3,stride = 2)input = torch.randn(20,16,50)output = m(input)print('output.shape = ',output.shape)output.shape = torch.Size([20, 33, 24])从上面理论和程序运行结果可理
2021-02-21 20:07:33
355
原创 JZ32 把数组排成最小的数
题目描述输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。解:拿到该题,自己的思路完全错了,看了下题解,恍然大悟,水平还是不够,参考了网友的思路:(1)将数组转为字符串;(2)对于字符串a和字符串b,比较a + b和b+a的大小,进行字符串排序;(3)对排序后的结果拼接即可。具体程序如下:class Solution {public: string s; st
2020-11-24 23:44:18
93
原创 JZ31 整数中1出现的次数
题目描述求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。解:最直接方法,遍历从1到n的数,依次进行排查1出现情况,实现程序如下:class Solution {public: int NumberOf1Between1AndN_Sol
2020-11-24 23:24:39
108
原创 JZ30 连续数组最大和
题目描述HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)解:该题目最容易想到的就是直接遍历寻找最大值,显然这并不是该
2020-11-23 23:41:56
152
原创 JZ26 二叉搜索树转换为一个排序的双向链表
题目描述输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。解:实质上就是对二叉树进行遍历,在遍历的基础上加入指针的指向;因为要求排序的双向链表,所以可以考虑中序遍历,具体过程分析如下:上图展示了部分过程,剩下的右子树依此类推;具体代码实现如下:/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x)
2020-11-15 20:10:13
86
原创 JZ25 对复杂链表进行深度拷贝
题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)解:该题目刚开始自己理解错了意思,参考了牛客的实现,发现思路还是挺简单的,主要通过在已有的链表中创建新的链表来完成该实现过程,具体实现过程分析如下:分析清楚了实现过程,代码实现还是相对容易的,具体代码如下:/*struct RandomListNode {
2020-11-15 19:44:39
141
原创 JZ24 打印出二叉树中结点值的和为输入整数的所有路径
题目描述输入一颗二叉树的根节点和一个整数,按字典序打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。解:该题目如果不考虑输入整数问题就是一个打印二叉树路径的问题,打印二叉树无非就是对树进行遍历;加入和某一整数相等的路径筛选只要做少许改动即可,具体程序实现如下,代码根据自己思想写的,可能有些冗余。/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *
2020-11-14 22:25:29
167
原创 JZ23 二叉搜索树的后序遍历
题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。解:该题目首先需要清楚二叉搜索树的概念,二叉搜索树:左子树小于根节点,右子树大于根节点;然后就是清楚后续遍历的概念:左子树 -> 右子树 -> 根节点;那么剩下的问题就比较容易分析了,具体分析过程如下:通过上图的分析,以最后一个数为根节点,依次进行递归划分就可以得出结论,具体程序实现如下:class Solution {public
2020-11-14 20:29:20
113
原创 JZ22 从上往下打印二叉树
题目描述从上往下打印出二叉树的每个节点,同层节点从左至右打印。解:从上往下打印,同层从左至右,这就是一个典型的树层遍历。层遍历可以通过队列的入队出队性质来进行打印。具体实现代码如下:/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { }};*/class Solution {p
2020-11-10 23:42:15
116
原创 JZ21 栈的压入、弹出
题目描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)解:push = {1,2,3,4,5}; pop = {4,5,3,2,1}(1) 借助辅助栈st,1,2,3由于不等于栈顶元素4依次入栈st,st = {1,2,3}(2) 4 = 4(
2020-11-09 23:20:17
201
原创 JZ20 栈的最小元素
题目描述定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。解:该题目中要求时间复杂度为O(1),那么就需要借助辅助栈来实现;一个栈用来push数据,另外一个栈用来push最小值。具体实现如下:class Solution {public: stack<int> vec1,vec2; void push(int value) { vec1.push(value); if(vec2.empty
2020-11-08 17:19:30
112
原创 JZ19 顺时针打印矩阵数字
题目描述输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.解:根据题目的意思,可以画图如下:矩阵的遍历可以分成几圈来进行遍历,对于这几圈之间有什么关系呢?仔细分析可以发现,只是坐标的范围在变化;不妨假设每一圈的坐标变化范围:left,top,right,bot;每一圈数字都可以分为顶
2020-11-08 16:01:48
224
原创 JZ18 二叉树的镜像
题目描述操作给定的二叉树,将其变换为源二叉树的镜像。遍历方式如上图所示,采用递归方式就比较容易实现代码,具体如下:/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { }};*/class Solution {public: void Mirror(TreeNode *
2020-11-08 12:02:05
85
原创 JZ17 树的子结构
题目描述输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)解:对树进行从根开始递归遍历,依次遍历左子树,右子树。如果根开始遍历存在该子树,则返回true;否则遍历左子树和右子树,如果左子树与该子树相等,则返回true;否则遍历右子树,如果右子树与该子树相等,则返回true;否则返回false。具体代码实现如下:/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *rig
2020-11-08 11:08:52
179
原创 JZ16
题目描述输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。解:两个链表合成一个链表,保持单调不减,可以建立两个指针指向两个链表遍历比较大小,再建立一个指针用来指向合并后的链表。具体实现如下:/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {public: Li
2020-11-08 00:01:50
323
原创 JZ15
输入一个链表,反转链表后,输出新链表的表头。示例1输入复制{1,2,3}返回值复制{3,2,1}解:链表反转,实质就是将链表各个结点的指针反转,可以想象链表的反转实现需要借助三个指针来实现,各自相邻指向具体的结点。实现过程如下:/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {public:
2020-11-07 21:56:23
177
原创 JZ14
题目描述输入一个链表,输出该链表中倒数第k个结点。解:最容易实现的方法就是遍历链表的长度,然后求出倒数第k个结点在顺序中是第几个结点。具体实现如下:/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {public: ListNode* FindKthToTail(ListNode* pListHead,
2020-11-07 21:07:02
129
原创 JZ13
题目描述输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。解:该题目最直接的方法就是开辟两个辅助数组,分别存储奇数和偶数,然后将两个辅助数组的内容复制到原数组中。能不能不采用辅助数组的方式实现呢?肯定是可以的,可以对原始数组进行遍历,遇到奇数就停下,将偶数整体往后挪动,奇数插入到前方;继续往后遍历直到结束。具体如下:图片来源牛客网网友,若有侵犯,通知删除。具体程序实现如下:clas
2020-11-07 17:45:54
123
python实现卷积,通道卷积
2020-09-23
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人