语义分割学习笔记(三)——SegNet Upsample层解析
来源:互联网 发布:ip地址显示杭州阿里云 编辑:程序博客网 时间:2024/05/29 17:13
1 参数设置
message UpsampleParameter { // DEPRECATED. No need to specify upsampling scale factors when // exact output shape is given by upsample_h, upsample_w parameters. optional uint32 scale = 1 [default = 2]; // DEPRECATED. No need to specify upsampling scale factors when // exact output shape is given by upsample_h, upsample_w parameters. optional uint32 scale_h = 2; // DEPRECATED. No need to specify upsampling scale factors when // exact output shape is given by upsample_h, upsample_w parameters. optional uint32 scale_w = 3; // DEPRECATED. Specify exact output height using upsample_h. This // parameter only works when scale is 2 optional bool pad_out_h = 4 [default = false]; // DEPRECATED. Specify exact output width using upsample_w. This // parameter only works when scale is 2 optional bool pad_out_w = 5 [default = false]; optional uint32 upsample_h = 6; optional uint32 upsample_w = 7;}可设置参数为:
scale
scale_h scale_w
pad_out_h pad_out_w
upsample_h upsample_w
2 top层特征图大小计算
(1)先判断是否指定 upsample_hupsample_w,如果指定,大小为指定大小,否则(2)
(2)判断是否指定 scale_h, 如果未指定, scale_h_ = scale_w_ = scale,否则(3)
(3)scale_h_ = scale_h scale_w_=scale_w
只有scale_h_ = scale_w_ =2时,才可以指定pad_out_h,pad_out_w,否则错误,如果是(2)(3)则top特征图大小为:
upsample_h_ = bottom[0]->height() * scale_h_ - int(pad_out_h)
upsample_w_ = bottom[0]->width() * scale_w_ - int(pad_out_w)
3 源码
#include <algorithm>#include <cfloat>#include <vector>#include <iostream>#include "caffe/layers/upsample_layer.hpp"namespace caffe {template <typename Dtype>void UpsampleLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { UpsampleParameter upsample_param = this->layer_param_.upsample_param(); CHECK((upsample_param.has_upsample_h() && upsample_param.has_upsample_w()) || (!upsample_param.has_scale() && upsample_param.has_scale_h() && upsample_param.has_scale_w()) || (!upsample_param.has_scale_h() && !upsample_param.has_scale_w())) << "upsample_h & upsample_w are required, else (DEPRECATED) " << "scale OR scale_h & scale_w are required."; if (upsample_param.has_upsample_h() && upsample_param.has_upsample_w()) { upsample_h_ = upsample_param.upsample_h(); //根据upsample_h upsample_w参数设定 upsample_w_ = upsample_param.upsample_w(); CHECK_GT(upsample_h_, 1); CHECK_GT(upsample_w_, 1); } else { LOG(INFO) << "Params 'pad_out_{}_' are deprecated. Please declare upsample" << " height and width useing the upsample_h, upsample_w parameters."; if (!upsample_param.has_scale_h()) { //根据scale设定 没有scale_h直接根据scale设定 scale_h_ = scale_w_ = upsample_param.scale(); CHECK_GT(scale_h_, 1); } else { scale_h_ = upsample_param.scale_h(); scale_w_ = upsample_param.scale_w(); CHECK_GT(scale_h_, 1); CHECK_GT(scale_w_, 1); } pad_out_h_ = upsample_param.pad_out_h(); pad_out_w_ = upsample_param.pad_out_w(); CHECK(!pad_out_h_ || scale_h_ == 2) //只有scale_h scale_w=2时,才可以指定 << "Output height padding compensation requires scale_h == 2, otherwise " << "the output size is ill-defined."; CHECK(!pad_out_w_ || scale_w_ == 2) << "Output width padding compensation requires scale_w == 2, otherwise " << "the output size is ill-defined."; upsample_h_ = upsample_w_ = -1; // flag to calculate in Reshape }}template <typename Dtype>void UpsampleLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { CHECK_EQ(4, bottom[0]->num_axes()) << "Input must have 4 axes, " << "corresponding to (num, channels, height, width)"; CHECK_EQ(4, bottom[1]->num_axes()) << "Input mask must have 4 axes, " << "corresponding to (num, channels, height, width)"; CHECK_EQ(bottom[0]->num(), bottom[1]->num()); CHECK_EQ(bottom[0]->channels(), bottom[1]->channels()); CHECK_EQ(bottom[0]->height(), bottom[1]->height()); CHECK_EQ(bottom[0]->width(), bottom[1]->width()); if (upsample_h_ <= 0 || upsample_w_ <= 0) { upsample_h_ = bottom[0]->height() * scale_h_ - int(pad_out_h_); // upsample_h_ = height*scale-pad_out upsample_w_ = bottom[0]->width() * scale_w_ - int(pad_out_w_); } top[0]->Reshape(bottom[0]->num(), bottom[0]->channels(), upsample_h_, upsample_w_); channels_ = bottom[0]->channels(); height_ = bottom[0]->height(); width_ = bottom[0]->width();}template <typename Dtype>void UpsampleLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const Dtype* bottom_data = bottom[0]->cpu_data(); const Dtype* bottom_mask_data = bottom[1]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); // Initialize const int top_count = top[0]->count(); caffe_set(top_count, Dtype(0), top_data); // The main loop for (int n = 0; n < bottom[0]->num(); ++n) { for (int c = 0; c < channels_; ++c) { for (int i = 0; i < height_ * width_; ++i) { const int idx = static_cast<int>(bottom_mask_data[i]); if (idx >= upsample_h_ * upsample_w_) { // this can happen if the pooling layer that created the input mask // had an input with different size to top[0] LOG(FATAL) << "upsample top index " << idx << " out of range - " << "check scale settings match input pooling layer's " << "downsample setup"; } top_data[idx] = bottom_data[i]; } // compute offset bottom_data += bottom[0]->offset(0, 1); bottom_mask_data += bottom[1]->offset(0, 1); top_data += top[0]->offset(0, 1); } }}template <typename Dtype>void UpsampleLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) { if (propagate_down[0]) { const Dtype* top_diff = top[0]->cpu_diff(); const Dtype* bottom_mask_data = bottom[1]->cpu_data(); Dtype* bottom_diff = bottom[0]->mutable_cpu_diff(); const int bottom_count = bottom[0]->count(); caffe_set(bottom_count, Dtype(0), bottom_diff); // The main loop for (int n = 0; n < bottom[0]->num(); ++n) { for (int c = 0; c < channels_; ++c) { for (int i = 0; i < height_ * width_; ++i) { const int idx = static_cast<int>(bottom_mask_data[i]); if (idx >= height_ * width_ * scale_h_ * scale_w_) { // this can happen if the pooling layer that created // the input mask had an input with different size to top[0] LOG(FATAL) << "upsample top index " << idx << " out of range - " << "check scale settings match input pooling layer's downsample setup"; } bottom_diff[i] = top_diff[idx]; } // compute offset bottom_diff += bottom[0]->offset(0, 1); bottom_mask_data += bottom[1]->offset(0, 1); top_diff += top[0]->offset(0, 1); } } }}#ifdef CPU_ONLYSTUB_GPU(UpsampleLayer);#endifINSTANTIATE_CLASS(UpsampleLayer);REGISTER_LAYER_CLASS(Upsample);} // namespace caffe
阅读全文
0 0
- 语义分割学习笔记(三)——SegNet Upsample层解析
- 语义分割学习笔记(一)——SegNet 配置与训练
- 图像语义分割(2)- SegNet
- 语义分割SegNet
- 语义分割-2:segnet网络
- 【语义分割】[文章阅读]segNet
- 语义分割学习笔记(二)——Windows下 Lableme 配置
- 语义分割学习笔记(四)——ENet 训练问题
- Allegro学习笔记之3—电源层、地层分割
- 图像语义分割学习笔记~心得
- SegNet-基于深度学习的图像分割
- u-net segnet 学习笔记
- Segnet分割网络caffe教程(一)
- Segnet分割网络caffe教程(二)
- 深度学习语义分割
- 语义分割(semantic segmentation) 常用神经网络介绍对比-FCN SegNet U-net DeconvNet
- 语义分割(semantic segmentation) 常用神经网络介绍对比-FCN SegNet U-net DeconvNet
- 语义分割-- SegNet:A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation
- matlab中控制并口打标Failure to find requested data acquisition device: parallel.解决方案
- 三阶幻方
- ubuntu 安装搜狗输入法后,皮肤错乱解决办法【ubuntu16.04 x64】
- kubernetes minikube kubectl的安装 绝对良心
- JVM线程测试与java原子操作
- 语义分割学习笔记(三)——SegNet Upsample层解析
- @ResponseBody与response.getWriter .write()区别
- 10. php popen()
- 第七周 【项目5 -排队看病模拟】
- 第九周项目3—利用二叉树遍历思想解决问题
- leetcode刷题指南
- 启动VMware报错:无法连接 MKS: 套接字连接尝试次数太多;正在放弃。
- SQL语言——学习随手记20171102
- Known Notation ZOJ