Author: volica

3,126  0

ResNet:网络复现

手画网络结构终归不如直接实现一遍搞得清楚,直接上网络结构代码,Res-152改良版(根据后续版本,残差块里的“卷积、批量归一化和激活”结构改成了“批量归一化、激活和卷积”) # Mxnet 实现 # 残差模块 class Residual(nn.Block): def __init__(self, num_channels, num_channels_out, use_1x1conv=False, strides=1, **kwargs): super(Residual, self).__init__(**kwargs) self.conv1 = nn.Conv2D(num_channels, kernel_size=1) self.conv2 = nn.Conv2D(num_channels, kernel_size=3, padding=1, strides=strides) self.conv3 = nn.Conv2D(num_channels, kernel_size=1) if use_1x1conv: self.conv4 = nn.Conv2D(num_channels, kernel_size=1, strides=strides) else: self.conv4 = None self.bn1 = nn.BatchNorm() self.bn2 = nn.BatchNorm() self.bn3 = nn.BatchNorm() def forward(self, X): Y = self.conv1(nd.relu(self.bn1(X))) Y = self.conv2(nd.relu(self.bn2(Y))) Y = self.conv3(nd.relu(self.bn3(Y))) if self.conv4: X = self.conv4(X) return nd.relu(Y + X) # 残差层 def resnet_block(num_channels, num_channels_out, num_residuals, first_block=False): blk = nn.Sequential() for i in range(num_residuals): if i == 0 and not first_block: blk.add(Residual(num_channels, num_channels_out, use_1x1conv=True, strides=2)) else: blk.add(Residual(num_channels, num_channels_out))...

5,234  2

SSD:网络结构

手画了一下网络结构,就一目了然了,六级输出组合起来就是最终的结果 发现的问题 虽然使用了多级结构,使网络对于小物体识别能力更强,但特征的表达能力似乎不够强。目前感觉在前景背景区分度较差,此外bbox定位不够精确,导致修改IOU参数或修改IOU逻辑均对结果提升不足。 在Default Boxes的定义上因为兼顾了小物体和大物体,当出现全图均为密集小物体时,高维Boxes回归后的结果偏差较大,影响了最终结果。

3,047  0

Faster RCNN: RPNs

网络结构 图像被缩放到最短边600像素,3通道 经过卷积网络(ZF模型、VGG16模型)。以ZF模型为例,每次卷积使用padding因此不改变图像尺寸,仅在pooling时长宽缩小一半,因此经过卷积网络后得到的Feature中,每个点对应原图16×16区域的信息 Feature进行共享,RPNs和ROI Pooling均使用此信息,RPNs由此信息产生Region Proposal(RP) RP与Feature通过ROI Pooling后产生N个特征图 计算每个特征图的分类和边框 RPNs 接收到的尺寸为50x38x256的Feature,经过3x3x512卷积变为50x38x512,然后进入两个不同分支 分类网络,首先经过1x1x18卷积层【18=(前景/背景)两个分类x9个Anchor】,然后通过softmax选出前景区域 回归网络,首先经过1x1x36卷积层【36=(x,y偏移量+w,h缩放量)四个变量x9个Anchor】汇总分类网络和回归网络的信息,得到RP RP总数量为50x38x9个,去除背景项后数量小于17100个,经过nms=0.7后数量约为2000+,取TopN作为输出(在文章中,N=300效果最优)

3,348  0

MCM2019-C题模型部分

总体思路是使用数据挖掘中的挖掘频繁项原理来挖掘毒品之间的关系、人口普查数据与毒品之间的关系。 以下是论文第二部分的主干。 Glossary & Symbols Glossary 数据立方体 data cube维 dimension分层 hierarchy hierarchy is a mapping sequence that maps the underlying conceptual set to a higher level频繁模式 frequent pattern关联规则 association rule支持度 support置信度 confidence提升度 lift出现频度 instances 频繁项集 frequent itemset Symbols 公式 confidence(A => B) = P(A|B) = support_count(AUB)/support_count(A) Model 1 1 Data Analysis The data in MCM_NFLIS_Data.xlsx can be abstracted as data cut with 4 dimension, the 4 demension are time, position, substance name and substance report number. In time dimension we have one hierarchy —— year, in position dimension we have two hierarchy —— state and county, in substance name dimension...

5,672  0

Fast RCNN: RoI Pooling 原理及代码

RoI Pooling 层 初始化参数 pooled_weight_ RoI池化层宽网格数(即论文中W=7) pooled_height_ RoI池化层高网格数(即论文中H=7) spatial_scale_ 从输入图像的坐标到特征图像坐标的缩放值 Forward函数流程 输入:(特征图data,位置信息rois) * Batch个 从Batch中取一张特征图datas的一个通道data,从此图对应的rois中取一个roi,得到(id,x,y,w,h) 缩放roi使其对应到特征图中位置(四舍五入为整数)得到(Rx,Ry,Rw,Rh) round(roi * spatial_scale_) 通过Rw,Rh得到每个bin的长宽BINw,BINh(四舍五入为整数) round(Rw / pooled_weight_) 遍历BIN中的特征值,将最大值作为输出,并记录此值对应在特征图的位置 示意图 Caffe代码 摘自 jiongnima //cpu前传函数 template <typename Dtype> void ROIPoolingLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const Dtype* bottom_data = bottom[0][/latex]gt;cpu_data();//bottom_data表示共享卷积层输出的特征图 const Dtype* bottom_rois = bottom[1][/latex]gt;cpu_data();//bottom_rois表示rois的信息,一共5维,第一维表示rois在训练batch中的图片索引,后四维表示rois的坐标信息 // Number of ROIs int num_rois = bottom[1][/latex]gt;num();//roi的总数 int batch_size = bottom[0][/latex]gt;num();//batch_size表示一次训练中输入的图片数量,因为roi并不是都存在于同一张图片上 int top_count = top[0][/latex]gt;count();//top_count表示top[0]的全部容量(N*C*H*W) Dtype* top_data = top[0][/latex]gt;mutable_cpu_data();//使用top_data指针索引top[0] caffe_set(top_count, Dtype(-FLT_MAX), top_data);//初始化top_data(即top[0]),将其初始值(共top_count个)置为最小值(-FLT_MAX) int* argmax_data = max_idx_.mutable_cpu_data();//使用argmax_data指针索引max_idx_ caffe_set(top_count, -1, argmax_data);//初始化argmax_data(即max_idx_),将其初始值(共top_count个)置为-1 // For each ROI R = [batch_index x1 y1 x2 y2]: max pool over R (rois的五维数据的说明) for (int n =...

2,276  0

多音字姓

static { FAMNAMES.put(Character.valueOf(‘仇’), "QIU"); FAMNAMES.put(Character.valueOf(‘柏’), "BO"); FAMNAMES.put(Character.valueOf(‘牟’), "MU"); FAMNAMES.put(Character.valueOf(‘颉’), "XIE"); FAMNAMES.put(Character.valueOf(‘解’), "XIE"); FAMNAMES.put(Character.valueOf(‘尉’), "YU"); FAMNAMES.put(Character.valueOf(‘奇’), "JI"); FAMNAMES.put(Character.valueOf(‘单’), "SHAN"); FAMNAMES.put(Character.valueOf(‘谌’), "SHEN"); FAMNAMES.put(Character.valueOf(‘乐’), "YUE"); FAMNAMES.put(Character.valueOf(‘召’), "SHAO"); FAMNAMES.put(Character.valueOf(‘朴’), "PIAO"); FAMNAMES.put(Character.valueOf(‘区’), "OU"); FAMNAMES.put(Character.valueOf(‘查’), "ZHA"); FAMNAMES.put(Character.valueOf(‘曾’), "ZENG"); FAMNAMES.put(Character.valueOf(‘缪’), "MIAO"); }

6,487  0

Cascade RCNN 笔记

Cascade RCNN 在训练时,以低IoU阀值进⾏训练会导致效果不好,因为会产⽣很多噪声框; 所以我们希望阈值尽量⾼,⽽IoU阀值设过⾼时,训练出的detector效果却有下降趋势,如下图所示。 因为阀值⾼时,每轮训练正样本会更少(指数级下降),detector易过拟合。 如下图所示,训练样本通过RPN产⽣的RP与标注所对⽐的IoU直⽅图,当IoU增加时,正样本呈指数级下降。 The red numbers are the positive percentage higher than the corresponding IoU threshold. ⽽如果训练和测试时使⽤不同阈值,即保持训练的阈值较低,只在测试时使⽤⾼阈值,detector得到的结果是次优的,称为inference-time mismatch. 下图可看出①在测试时使⽤更⼤阈值是次优的,即detector的AP会下降;②低阈值训练的detector对低IoU样本上提升好,⾼阈值detector对⾼IoU样本提升好。 那么如何在阈值适中的情况下训练出效果最好、界线最分明(bbox更准、分类预测值更⾼)的detector呢?我们发现: ⾸先,detector对IoU接近阈值的bbox效果最好,在阈值为0.7时,若输⼊的bbox也为0.7时提升最⼤,如下图所示。 其次,It suggests that the output of a detector trained with a certain IoU threshold is a good distribution to train the detector of the next higher IoU threshold. detector的输出是⼀个更加良好的分布,可以再进⾏训练。同时,在⼀个⽹络中进⾏⼀次cascade结构(串⾏使⽤多个不同阈值的detector)⽐Iterative BBox(串⾏使⽤同⼀个detector)效果好很多,且不会把⾼IoU的bbox回归到低IoU的位置。 如下图所示,IoU在0.9的bbox经过蓝⾊detector后会下降⾄0.86;分别使⽤蓝⾊、绿⾊、红⾊的detector⽐使⽤三次蓝⾊detector效果好。 关于提⾼阈值已有的⽅法 1. Iterative BBox Iterative bbox使⽤初始的bbox与卷积层输出结合进⾏计算,得到bbox和分类,将得到的bbox再次与卷积层输出结合,重新使⽤该detector进⾏计算,如此迭代多次后将最后的结果作为输出。其过程可以⽤如下公式描述。 他忽略了两个问题: ⾸先,当测试的阈值⼤于训练阈值时,detector效果会降低。 其次,bbox的分布在每次计算后都有巨⼤的变化,⽽每次使⽤相同的detector进⾏计算,并不⼀定会使bbox回归得更加精确。因为detector对于初始分布是最优的,对于再次迭代后的分布是次优的;另外对于与训练集的IoU已经⾮常⾼的bbox来说,再次计算之后可能回归到⼀个低IoU的位置。 2. Integral Loss Integral Loss使⽤初始的bbox与卷积层输出多个不同阈值下的bbox和分类。由于阈值越⾼,可使⽤的正样本越少,其训练出的detector越容易过拟合;且⾼阈值训练的detector也需要处理⼤量IoU低的bbox。所以Integral Loss对于⽹络效果来说,并没有什么提升。 3. 本⽂提出Cascade R-CNN 通过Iterative BBox可知道迭代使⽤同⼀个detector很难有更⼤的提升。本⽂提出的Cascade RCNN使⽤多个阈值越来越⾼的detector串联,得到了更好的效果。 ⾸先,在每次detector计算后,IoU⾼的bbox的分布都会提升,使得下⼀阶段更⾼阈值下正样本的数量得到保证。如下图所示。 其次,每经过⼀次detector,bbox都会变得更准确,更⾼的阈值可保证下⼀次回归效果更好。下图可以看出每次回归之后都会向⽬标框更接近。 损失计算 Bounding Box Regression Classification Cascaded Detection 对照实验(Ablation Experiments) IoU Thresholds By increasing the stage threshold u, the detector can be made...

8,741  0

Win10+VS2017+CUDA9.2+Python3.6下Caffe的本地编译安装

安装CUDA和CUDNN等 详见我之前的文章《Win10下安装Tensorflow 1.8 GPU版(CUDA9.2)》 捷径: 在Github上有位大神提供了windows下的编译包,可直接搜 happynear/caffe-windows ,按其教程安装即可happynear/caffe-windows是caffe的半官方windows版,虽然在文档中只支持Visual Studio 2015, CUDA 9.0,但略作修改即可支持VS2017、CUDA9.2的环境。 不走捷径,初试Caffe 首先从官网clone源码,遵循官网教程来安装 git clone https://github.com/BVLC/caffe.git cd caffe git checkout windows :: Edit any of the options inside build_win.cmd to suit your needs C:\Projects\caffe> scripts\build_win.cmd 不出意外,肯定报错。 VisioStudio2015/Common7/Tools/../../VC/vcvarsall.bat”‘不是内部或外部命令,也不是可运行的程序 CMake Error: Error: generator : Ninja 修改scripts/build_win.cmd 第五行if DEFINED APPVEYOR是Google的自动化集成,目测用不到,跳到70行,修改为下图所示: MSVC_VERSION=15 对应VS2017在下方会用到WITH_NINJA=0 NINJA在Windows下不好编译安装,因此不使用CPU_ONLY=0 如果编译CPU版本这里改为1PYTHON_VERSION=3 目前只支持3.6,为了使用Python3.6之后还有骚操作如果使用了Conda,从APPVEYOR部分把代码拷贝过来,修改路径;如果没有用Conda,只修改配置最后一句即可 在if %WITH_NINJA% EQU 0里添加VS2017的信息 修改environement for VS x64 如果使用CUDNN加速,还需要在修改cmake下的参数列表 至此,我们再次运行scripts/build_win.cmd如果运气不好的话,会在这里 ERROR: Build failed,此时可以在build/目录下运行 cmake ..然后和好运气的人一起到达下一个错误深入分析原因,会找到根源在 cmake/WindowsDownloadPrebuiltDependencies.cmake 因为预编译包里没有VS2017和Python3.6的属性。 编译依赖库caffe-builder Caffe在编译时会从网上下载依赖库caffe-builder,而目前只有VS2013/2015配python2.7/3.5环境的caffe-builder。 下载最新源码 https://github.com/willyd/caffe-builder/releases 修改build_v140_x64.cmd 如果编译失败,出现 CMake throws Error: could not load cache 应是缓存问题,清除缓存文件或把倒数第二行修改为 cmake .. 修改packages/protobuf/CmakeLists.txt 将protobuf包的Hash值从 14a532a7538551d5def317bfca41dace修改为 39d6a4fa549c0cce164aa3064b1492dc 修改packages/hdf5/CmakeLists.txt 将URL从 https://www.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8.16/src/CMkae-hdf5-1.8.16.zip 修改为 https://www.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8/hdf5-1.8.16/src/CMkae-hdf5-1.8.16.zip 运行build_v140_x64.cmd 然后进入 build_v140_x64 目录用VS2017启动 caffe-builder.sln...

16,231  9

Camera2 API预览图 YUV转RGB方法性能比较

Android5.0发布后,随着Camera2的兼容性不断提升,目前完全可以替代旧API的使用。而Camera2在调用方法、相机设置、图片获取等方面都变化很大。在实时预览图像获取时,通用的图片格式由 YUV_NV21 变为 YUV_420_888 ,因此在转换为Bitmap时出现了问题,由于Google并没有直接提供YUV2RGB的方法,因此网上代码鱼龙混杂,本文总结了几个高效的转换方法。 //Camera API public void onPreviewFrame(byte[] data, Camera camera){ YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null); } //Camera2 API public void onImageAvailable(ImageReader reader){ Image image = reader.acquireLatestImage(); } 原理 可以看出NV21和YUV很相似,因此由NV21[/latex]gt;RGB的时间与YUV[/latex]gt;RGB的时间相似。 JAVA直接转码 该方法实现简单,处理640×480预览图平均时间为33ms public void onImageAvailable(ImageReader reader) { Image image = reader.acquireLatestImage(); if (image == null) return; ByteArrayOutputStream outputbytes = new ByteArrayOutputStream(); ByteBuffer bufferY = image.getPlanes()[0].getBuffer(); byte[] data0 = new byte[bufferY.remaining()]; bufferY.get(data0); ByteBuffer bufferU = image.getPlanes()[1].getBuffer(); byte[] data1 = new byte[bufferU.remaining()]; bufferU.get(data1); ByteBuffer bufferV = image.getPlanes()[2].getBuffer(); byte[] data2 = new byte[bufferV.remaining()]; bufferV.get(data2); try { outputbytes.write(data0); outputbytes.write(data2); outputbytes.write(data1); } catch (IOException e) { e.printStackTrace(); } final...