caffe代码阅读4:LayerRegistry的介绍与实现_caffe layerregistry-程序员宅基地

技术标签: caffe  

一、LayerRegistry的作用简介

LayerResistry的功能很简单,就是将类和对应的字符串类型放入到一个map当中去,以便灵活调用。主要就是注册类的功能

二、LayerRegistry类的详细介绍


1)构造函数和析构函数

构造函数 
[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. // 禁止实例化,因为该类都是静态函数,所以是私有的  
  2.   LayerRegistry() {}  

2)类型定义

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1.  // 函数指针Creator,返回的是Layer<Dtype>类型的指针  
  2. typedef shared_ptr<Layer<Dtype> > (*Creator)(const LayerParameter&);  
  3. // CreatorRegistry是字符串与对应的Creator的映射  
  4. typedef std::map<string, Creator> CreatorRegistry;  

3)成员函数

3-1 加入一个Creator到注册表

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. // 给定类型,以及函数指针,加入到注册表  
  2. static void AddCreator(const string& type, Creator creator) {  
  3.   CreatorRegistry& registry = Registry();  
  4.   CHECK_EQ(registry.count(type), 0)  
  5.       << "Layer type " << type << " already registered.";  
  6.   registry[type] = creator;  
  7. }  

3-2 给定层的类型,创建层

这个创建层在net.cpp中会用到,在初始化整个网络的时候会根据参数文件中的层的类型去创建该层的实例
[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. static shared_ptr<Layer<Dtype> > CreateLayer(const LayerParameter& param) {  
  2.   if (Caffe::root_solver()) {  
  3.     LOG(INFO) << "Creating layer " << param.name();  
  4.   }  
  5.   // 从参数中获得类型字符串  
  6.   const string& type = param.type();  
  7.   // 获得注册表指针  
  8.   CreatorRegistry& registry = Registry();  
  9.   // 测试是否查找到给定type的Creator  
  10.   CHECK_EQ(registry.count(type), 1) << "Unknown layer type: " << type  
  11.       << " (known types: " << LayerTypeListString() << ")";  
  12.   // 调用对应的层的Creator函数  
  13.   return registry[type](param);  
  14. }  

3-3 返回层的类型列表

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. static vector<string> LayerTypeList() {  
  2.   // 获得注册表  
  3.   CreatorRegistry& registry = Registry();  
  4.   vector<string> layer_types;  
  5.   // 遍历注册表压入layer_types字符串容器  
  6.   for (typename CreatorRegistry::iterator iter = registry.begin();  
  7.        iter != registry.end(); ++iter) {  
  8.     layer_types.push_back(iter->first);  
  9.   }  
  10.   return layer_types;  
  11. }  

3-4 返回一个string,就是把所有的类型都拼起来用逗号分隔形成一个字符串

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1.   static string LayerTypeListString() {  
  2.     vector<string> layer_types = LayerTypeList();  
  3.     string layer_types_str;  
  4.     for (vector<string>::iterator iter = layer_types.begin();  
  5.          iter != layer_types.end(); ++iter) {  
  6.       if (iter != layer_types.begin()) {  
  7.         layer_types_str += ", ";  
  8.       }  
  9.       layer_types_str += *iter;  
  10.     }  
  11.     return layer_types_str;  
  12.   }  
  13. };  

3-5 获取注册表(静态的,第一次的时候才new,以后都是直接return的)

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. // 产生一个CreatorRegistry映射的的实例赋值给g_registry_  
  2.   // 表示内部的注册表  
  3.   // 静态函数,第一次的时候会new然后return,其余时间都是return  
  4.   static CreatorRegistry& Registry() {  
  5.     static CreatorRegistry* g_registry_ = new CreatorRegistry();  
  6.     return *g_registry_;  
  7.   }  

3-6此外还定义了一个层注册器

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. // LayerRegisterer  
  2. // 自己定义层的注册器  
  3. // 以供后面的宏进行使用  
  4. template <typename Dtype>  
  5. class LayerRegisterer {  
  6.  public:  
  7.   // 层的注册器的构造函数  
  8.   LayerRegisterer(const string& type,  
  9.                   shared_ptr<Layer<Dtype> > (*creator)(const LayerParameter&)) {  
  10.     // LOG(INFO) << "Registering layer type: " << type;  
  11.     // 还是调用的层注册表中的加入Creator函数加入注册表  
  12.     LayerRegistry<Dtype>::AddCreator(type, creator);  
  13.   }  
  14. };  

三、其他:

为了方便作者还弄了个宏便于注册自己写的层类

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. #define REGISTER_LAYER_CREATOR(type, creator)                                  \  
  2.   static LayerRegisterer<float> g_creator_f_##type(#type, creator<float>);     \  
  3.   static LayerRegisterer<double> g_creator_d_##type(#type, creator<double>)    \  
  4. #define REGISTER_LAYER_CLASS(type)                                             \  
  5.   template <typename Dtype>                                                    \  
  6.   shared_ptr<Layer<Dtype> > Creator_##type##Layer(const LayerParameter& param) \  
  7.   {                                                                            \  
  8.     return shared_ptr<Layer<Dtype> >(new type##Layer<Dtype>(param));           \  
  9.   }                                                                            \  
  10.   REGISTER_LAYER_CREATOR(type, Creator_##type##Layer)  
下面对该宏进行详细解释:
[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. // 生成g_creator_f_type(type, creator<Dtype>)的两个函数 (double和float类型)  
  2. #define REGISTER_LAYER_CREATOR(type, creator)                                  \  
  3.   static LayerRegisterer<float> g_creator_f_##type(#type, creator<float>);     \  
  4.   static LayerRegisterer<double> g_creator_d_##type(#type, creator<double>)    \  
  5.   
  6. // 注册自己定义的类,类名为type,  
  7. // 假设比如type=bias,那么生成如下的代码  
  8. // 下面的函数直接调用你自己的类的构造函数生成一个类的实例并返回  
  9. // CreatorbiasLayer(const LayerParameter& param)  
  10. // 下面的语句是为你自己的类定义了LayerRegisterer<float>类型的静态变量g_creator_f_biasLayer(float类型,实际上就是把你自己的类的字符串类型和类的实例绑定到注册表)  
  11. // static LayerRegisterer<float> g_creator_f_biasLayer(bias, CreatorbiasLayer)  
  12. // 下面的语句为你自己的类定义了LayerRegisterer<double>类型的静态变量g_creator_d_biasLayer(double类型,实际上就是把你自己的类的字符串类型和类的实例绑定到注册表)  
  13. // static LayerRegisterer<double> g_creator_d_biasLayer(bias, CreatorbiasLayer)  
  14. #define REGISTER_LAYER_CLASS(type)                                             \  
  15.   template <typename Dtype>                                                    \  
  16.   shared_ptr<Layer<Dtype> > Creator_##type##Layer(const LayerParameter& param) \  
  17.   {                                                                            \  
  18.     return shared_ptr<Layer<Dtype> >(new type##Layer<Dtype>(param));           \  
  19.   }                                                                            \  
  20.   REGISTER_LAYER_CREATOR(type, Creator_##type##Layer)  

四、Layer_factory.cpp中的实现

首先给出卷积层的参数
[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. message ConvolutionParameter {  
  2.   optional uint32 num_output = 1; // The number of outputs for the layer  
  3.   optional bool bias_term = 2 [default = true]; // whether to have bias terms  
  4.   
  5.   // Pad, kernel size, and stride are all given as a single value for equal  
  6.   // dimensions in all spatial dimensions, or once per spatial dimension.  
  7.   repeated uint32 pad = 3; // The padding size; defaults to 0  
  8.   repeated uint32 kernel_size = 4; // The kernel size  
  9.   repeated uint32 stride = 6; // The stride; defaults to 1  
  10.   
  11.   // For 2D convolution only, the *_h and *_w versions may also be used to  
  12.   // specify both spatial dimensions.  
  13.   optional uint32 pad_h = 9 [default = 0]; // The padding height (2D only)  
  14.   optional uint32 pad_w = 10 [default = 0]; // The padding width (2D only)  
  15.   optional uint32 kernel_h = 11; // The kernel height (2D only)  
  16.   optional uint32 kernel_w = 12; // The kernel width (2D only)  
  17.   optional uint32 stride_h = 13; // The stride height (2D only)  
  18.   optional uint32 stride_w = 14; // The stride width (2D only)  
  19.   
  20.   optional uint32 group = 5 [default = 1]; // The group size for group conv  
  21.   
  22.   optional FillerParameter weight_filler = 7; // The filler for the weight  
  23.   optional FillerParameter bias_filler = 8; // The filler for the bias  
  24.   enum Engine {  
  25.     DEFAULT = 0;  
  26.     CAFFE = 1;  
  27.     CUDNN = 2;  
  28.   }  
  29.   optional Engine engine = 15 [default = DEFAULT];  
  30.   
  31.   // The axis to interpret as "channels" when performing convolution.  
  32.   // Preceding dimensions are treated as independent inputs;  
  33.   // succeeding dimensions are treated as "spatial".  
  34.   // With (N, C, H, W) inputs, and axis == 1 (the default), we perform  
  35.   // N independent 2D convolutions, sliding C-channel (or (C/g)-channels, for  
  36.   // groups g>1) filters across the spatial axes (H, W) of the input.  
  37.   // With (N, C, D, H, W) inputs, and axis == 1, we perform  
  38.   // N independent 3D convolutions, sliding (C/g)-channels  
  39.   // filters across the spatial axes (D, H, W) of the input.  
  40.   optional int32 axis = 16 [default = 1];  
  41.   
  42.   // Whether to force use of the general ND convolution, even if a specific  
  43.   // implementation for blobs of the appropriate number of spatial dimensions  
  44.   // is available. (Currently, there is only a 2D-specific convolution  
  45.   // implementation; for input blobs with num_axes != 2, this option is  
  46.   // ignored and the ND implementation will be used.)  
  47.   optional bool force_nd_im2col = 17 [default = false];  
  48. }  
注册卷积层、注册池化层、注册ReLU层注册Tanh层,注册python层(如果开始python绑定的话)
代码如下:
[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. // Make sure we include Python.h before any system header  
  2. // to avoid _POSIX_C_SOURCE redefinition  
  3. #ifdef WITH_PYTHON_LAYER  
  4. #include <boost/python.hpp>  
  5. #endif  
  6. #include <string>  
  7.   
  8. #include "caffe/layer.hpp"  
  9. #include "caffe/layer_factory.hpp"  
  10. #include "caffe/proto/caffe.pb.h"  
  11. #include "caffe/vision_layers.hpp"  
  12.   
  13. #ifdef WITH_PYTHON_LAYER  
  14. #include "caffe/python_layer.hpp"  
  15. #endif  
  16.   
  17. namespace caffe {  
  18.   
  19. // 写一个获取卷积层实例的函数  
  20. // Get convolution layer according to engine.  
  21. template <typename Dtype>  
  22. shared_ptr<Layer<Dtype> > GetConvolutionLayer(  
  23.     const LayerParameter& param) {  
  24.    // 从参数中获取是使用什么引擎进行计算CUDNN还是CAFFE还是DEFAULT  
  25.    // engine可从caffe.proto中看出是枚举类型的  
  26.   ConvolutionParameter_Engine engine = param.convolution_param().engine();  
  27.   if (engine == ConvolutionParameter_Engine_DEFAULT) {  
  28.     engine = ConvolutionParameter_Engine_CAFFE;  
  29. #ifdef USE_CUDNN  
  30.     engine = ConvolutionParameter_Engine_CUDNN;  
  31. #endif  
  32.   }  
  33.   if (engine == ConvolutionParameter_Engine_CAFFE) {  
  34.     //  直接初始化Caffe的卷积层  
  35.     return shared_ptr<Layer<Dtype> >(new ConvolutionLayer<Dtype>(param));  
  36. #ifdef USE_CUDNN  
  37.   } else if (engine == ConvolutionParameter_Engine_CUDNN) {  
  38.     // 初始化CUDNN的卷积层  
  39.     return shared_ptr<Layer<Dtype> >(new CuDNNConvolutionLayer<Dtype>(param));  
  40. #endif  
  41.   } else { // 否则就是出错了  
  42.     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";  
  43.   }  
  44. }  
  45. // 注册该卷积层,类型名为Convolution,获取卷积层的实例为GetConvolutionLayer函数  
  46. REGISTER_LAYER_CREATOR(Convolution, GetConvolutionLayer);  
  47.   
  48. // 获取池化层的实例,同卷积层的逻辑  
  49. // Get pooling layer according to engine.  
  50. template <typename Dtype>  
  51. shared_ptr<Layer<Dtype> > GetPoolingLayer(const LayerParameter& param) {  
  52.   PoolingParameter_Engine engine = param.pooling_param().engine();  
  53.   if (engine == PoolingParameter_Engine_DEFAULT) {  
  54.     engine = PoolingParameter_Engine_CAFFE;  
  55. #ifdef USE_CUDNN  
  56.     engine = PoolingParameter_Engine_CUDNN;  
  57. #endif  
  58.   }  
  59.   if (engine == PoolingParameter_Engine_CAFFE) {  
  60.     return shared_ptr<Layer<Dtype> >(new PoolingLayer<Dtype>(param));  
  61. #ifdef USE_CUDNN  
  62.   } else if (engine == PoolingParameter_Engine_CUDNN) {  
  63.     PoolingParameter p_param = param.pooling_param();  
  64.     if (p_param.pad() || p_param.pad_h() || p_param.pad_w() ||  
  65.         param.top_size() > 1) {  
  66.       LOG(INFO) << "CUDNN does not support padding or multiple tops. "  
  67.                 << "Using Caffe's own pooling layer.";  
  68.       return shared_ptr<Layer<Dtype> >(new PoolingLayer<Dtype>(param));  
  69.     }  
  70.     return shared_ptr<Layer<Dtype> >(new CuDNNPoolingLayer<Dtype>(param));  
  71. #endif  
  72.   } else {  
  73.     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";  
  74.   }  
  75. }  
  76.   
  77. // 注册池化层  
  78. REGISTER_LAYER_CREATOR(Pooling, GetPoolingLayer);  
  79.   
  80. // 注册ReLU层  
  81. // Get relu layer according to engine.  
  82. template <typename Dtype>  
  83. shared_ptr<Layer<Dtype> > GetReLULayer(const LayerParameter& param) {  
  84.   ReLUParameter_Engine engine = param.relu_param().engine();  
  85.   if (engine == ReLUParameter_Engine_DEFAULT) {  
  86.     engine = ReLUParameter_Engine_CAFFE;  
  87. #ifdef USE_CUDNN  
  88.     engine = ReLUParameter_Engine_CUDNN;  
  89. #endif  
  90.   }  
  91.   if (engine == ReLUParameter_Engine_CAFFE) {  
  92.     return shared_ptr<Layer<Dtype> >(new ReLULayer<Dtype>(param));  
  93. #ifdef USE_CUDNN  
  94.   } else if (engine == ReLUParameter_Engine_CUDNN) {  
  95.     return shared_ptr<Layer<Dtype> >(new CuDNNReLULayer<Dtype>(param));  
  96. #endif  
  97.   } else {  
  98.     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";  
  99.   }  
  100. }  
  101.   
  102. REGISTER_LAYER_CREATOR(ReLU, GetReLULayer);  
  103.   
  104. // 注册sigmoid层  
  105. // Get sigmoid layer according to engine.  
  106. template <typename Dtype>  
  107. shared_ptr<Layer<Dtype> > GetSigmoidLayer(const LayerParameter& param) {  
  108.   SigmoidParameter_Engine engine = param.sigmoid_param().engine();  
  109.   if (engine == SigmoidParameter_Engine_DEFAULT) {  
  110.     engine = SigmoidParameter_Engine_CAFFE;  
  111. #ifdef USE_CUDNN  
  112.     engine = SigmoidParameter_Engine_CUDNN;  
  113. #endif  
  114.   }  
  115.   if (engine == SigmoidParameter_Engine_CAFFE) {  
  116.     return shared_ptr<Layer<Dtype> >(new SigmoidLayer<Dtype>(param));  
  117. #ifdef USE_CUDNN  
  118.   } else if (engine == SigmoidParameter_Engine_CUDNN) {  
  119.     return shared_ptr<Layer<Dtype> >(new CuDNNSigmoidLayer<Dtype>(param));  
  120. #endif  
  121.   } else {  
  122.     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";  
  123.   }  
  124. }  
  125.   
  126. REGISTER_LAYER_CREATOR(Sigmoid, GetSigmoidLayer);  
  127.   
  128. // 注册softmax层  
  129. // Get softmax layer according to engine.  
  130. template <typename Dtype>  
  131. shared_ptr<Layer<Dtype> > GetSoftmaxLayer(const LayerParameter& param) {  
  132.   SoftmaxParameter_Engine engine = param.softmax_param().engine();  
  133.   if (engine == SoftmaxParameter_Engine_DEFAULT) {  
  134.     engine = SoftmaxParameter_Engine_CAFFE;  
  135. #ifdef USE_CUDNN  
  136.     engine = SoftmaxParameter_Engine_CUDNN;  
  137. #endif  
  138.   }  
  139.   if (engine == SoftmaxParameter_Engine_CAFFE) {  
  140.     return shared_ptr<Layer<Dtype> >(new SoftmaxLayer<Dtype>(param));  
  141. #ifdef USE_CUDNN  
  142.   } else if (engine == SoftmaxParameter_Engine_CUDNN) {  
  143.     return shared_ptr<Layer<Dtype> >(new CuDNNSoftmaxLayer<Dtype>(param));  
  144. #endif  
  145.   } else {  
  146.     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";  
  147.   }  
  148. }  
  149.   
  150. REGISTER_LAYER_CREATOR(Softmax, GetSoftmaxLayer);  
  151.   
  152. // 注册tanh层  
  153. // Get tanh layer according to engine.  
  154. template <typename Dtype>  
  155. shared_ptr<Layer<Dtype> > GetTanHLayer(const LayerParameter& param) {  
  156.   TanHParameter_Engine engine = param.tanh_param().engine();  
  157.   if (engine == TanHParameter_Engine_DEFAULT) {  
  158.     engine = TanHParameter_Engine_CAFFE;  
  159. #ifdef USE_CUDNN  
  160.     engine = TanHParameter_Engine_CUDNN;  
  161. #endif  
  162.   }  
  163.   if (engine == TanHParameter_Engine_CAFFE) {  
  164.     return shared_ptr<Layer<Dtype> >(new TanHLayer<Dtype>(param));  
  165. #ifdef USE_CUDNN  
  166.   } else if (engine == TanHParameter_Engine_CUDNN) {  
  167.     return shared_ptr<Layer<Dtype> >(new CuDNNTanHLayer<Dtype>(param));  
  168. #endif  
  169.   } else {  
  170.     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";  
  171.   }  
  172. }  
  173.   
  174. REGISTER_LAYER_CREATOR(TanH, GetTanHLayer);  
  175.   
  176. // 注册PYTHON层  
  177. #ifdef WITH_PYTHON_LAYER  
  178. template <typename Dtype>  
  179. shared_ptr<Layer<Dtype> > GetPythonLayer(const LayerParameter& param) {  
  180.   Py_Initialize();  
  181.   try {  
  182.     bp::object module = bp::import(param.python_param().module().c_str());  
  183.     bp::object layer = module.attr(param.python_param().layer().c_str())(param);  
  184.     return bp::extract<shared_ptr<PythonLayer<Dtype> > >(layer)();  
  185.   } catch (bp::error_already_set) {  
  186.     PyErr_Print();  
  187.     throw;  
  188.   }  
  189. }  
  190.   
  191. REGISTER_LAYER_CREATOR(Python, GetPythonLayer);  
  192. #endif  
  193.   
  194. // Layers that use their constructor as their default creator should be  
  195. // registered in their corresponding cpp files. Do not register them here.  
  196. }  // namespace caffe  

五、总结

作者还真是煞费苦心,弄了个宏,一下子就注册了类。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/boon_228/article/details/54909561

智能推荐

分包组包 北斗通信_一种基于北斗的低功耗双向非实时通信方法-程序员宅基地

文章浏览阅读474次。一种基于北斗的低功耗双向非实时通信方法【技术领域】[0001]本发明涉及一种基于北斗的低功耗双向非实时通信方法,属于北斗系统通信技术领域。【背景技术】[0002]北斗卫星系统具备的短报文通信功能在水文、气象、海洋、林业领域的遥测系统已经广泛应用。但鉴于目前北斗通讯终端的功耗较大,发信频度受限的问题,这些遥测系统在应用北斗卫星作为数据传输载体时,一般只实现了野外遥测站向数据采集中心站的单向传输功能,..._北斗双向通信

windows域名映射_windows域名映射文件-程序员宅基地

文章浏览阅读981次,点赞2次,收藏2次。windows域名映射_windows域名映射文件

C++程序打包_c++打包-程序员宅基地

文章浏览阅读1.9k次。首先我用的vs2017对现有的项目进行打包处理,当然首先的有打包的工具就是下图的这个vs小工具,找不到的话可以在工具中打开扩展与更新,在里面查找相应的工具名之后就是在项目上新建一个setup项目,前提是你已经安装了上面的那个小工具,之后就是对项目进行添加要输出的项目,设为主输出,然后再第二个文件上进行存放该项目的快捷方式,这个是在桌面的上的,而第三个文件夹是在开始菜单栏里添加的在其中加入所需要的依赖以及项目再进行生成就会出现项目的安装的exe文件在你生成的项目下..._c++打包

输入打开文件-程序员宅基地

文章浏览阅读86次。import fnmatch, osimport reyy = input('')def edd(user_name): def allFiles(root, patterns = '*', single_level = False, yield_folders = False): patterns = patterns.split(';') ..._输打开

Eplan教学视频合集-百度网盘-收集于网络_eplan教程 百度网盘-程序员宅基地

文章浏览阅读9.4k次,点赞5次,收藏18次。Eplan教学视频合集-百度网盘-收集于网络https://yun.baidu.com/s/1djYbk#list/path=%2Fhttps://pan.baidu.com/s/14DHLr31mLq2N8qbxd7vcbw //code:cva8https://yun.baidu.com/s/1qYfdJLM#list/path=%2Fhttps://yun.baidu.co..._eplan教程 百度网盘

keep-alive vue不起作用的原因_vue3+vite的keep-alive浏览器返回不生效-程序员宅基地

文章浏览阅读2w次。keep-alive 从列表页进入到详情页,再回到列表页,然后页面又重新请求,而不是直接读缓存里面的(ps:之前keep-alive用在项目中是可以起作用的,但是不知道为什么这两天就出现了这样的问题。就连activated,deactivated这两个钩子函数也是没有触发到) 具体代码如下 我尝试在项目中新建一个很简单的页面,也是没有效果。一开始以为是vue的版本过低导致的,看了一下v..._vue3+vite的keep-alive浏览器返回不生效

随便推点

elasticsearch-setup-passwords interactive_bash: elasticsearch-setup-passwords: command not f-程序员宅基地

文章浏览阅读2.6k次。elasticsearch-setup-passwords interactive[root@node-zwf ~]# su elasticsearch[elasticsearch@node-zwf root]$ cd /home/elasticsearch/elasticsearch-7.8.0/[elasticsearch@node-zwf elasticsearch-7.8.0]$ elasticsearch-setup-passwords interactiveba..._bash: elasticsearch-setup-passwords: command not found

学校公共计算机保用规定,湖南中医药大学涉密计算机和涉密移动存储介质保密管理规定...-程序员宅基地

文章浏览阅读922次。第一条为了进一步加强学校涉密计算机和涉密移动存储介质(移动硬盘、U盘、软盘、光盘、存储卡等)的安全保密工作,维护国家安全和利益,维护学校稳定和发展,结合我校工作实际,特制定本规定。第二条学校保密委员会负责全校涉密计算机、移动存储介质保密管理的指导、协调和监督工作。保密技术防范和管理工作由学校网络中心负责。第三条涉密计算机的日常管理制度(一)涉密计算机不得直接或间接接入国际互联网、校园网和其他公共信..._大学 涉密计算机安全保密策略

Vue.js复习_下列代码中,应用v-for指令遍历数组items-程序员宅基地

文章浏览阅读380次。Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载等⼀系列过程,称这是Vue的⽣命周期。_下列代码中,应用v-for指令遍历数组items

删除安装Google Chrome浏览器时捆绑安装的Google 文档、表格、幻灯片、Gmail、Google 云端硬盘、YouTube网址链接(Mac)_chrome自带的表格怎么删-程序员宅基地

文章浏览阅读5.2k次,点赞3次,收藏2次。Mac mini操作系统,安装完 Google Chrome 浏览器以后,单击 启动台 桌面左下角的“显示应用程序”,我们发现捆绑安装了。进入目录 /Users/用户名/Applications/Chrome 应用。那如何删除这些网址连接呢?,一个个单击打开,发现都是网址链接。已删除,干干净净,启动台回来了。进入或者删除整个文件夹。_chrome自带的表格怎么删

基于Java+SpringBoot+vue+elementui图书商城系统设计实现_图书商城后台管理系统设计与实现-程序员宅基地

文章浏览阅读3.9w次,点赞153次,收藏430次。主要功能包括管理员:首页、个人中心、图书分类管理、回收类别管理、新书榜管理、特价区管理、旧书回收管理、用户管理、订单评价管理、回收预约管理、图书回收管理、管理员管理、系统管理、订单管理。前台使用:首页、新书榜、特价区、旧书回收、公告资讯、个人中心、后台管理、购物车、客服。用户:首页、个人中心、订单评价管理、回收预约管理、图书回收管理、我的收藏管理、订单管理等功能。_图书商城后台管理系统设计与实现

【JZ2440笔记】裸机实验使用SDRAM_京累里101123-程序员宅基地

文章浏览阅读393次。S3C2440A 存储器控制器为访问外部存储的需要器提供了存储器控制信号。S3C2440A 包含以下特性:–大/小端(通过软件选择)–地址空间:每个 Bank 有 128M 字节(总共 1G/8 个 Bank)–大/小端(通过软件选择)–除了 BANK0(16/32 位)之外,其它全部 BANK 都可编程访问宽度(8/16/32 位)–总共 8 个存储器 Bank6 个存储器 Bank 为 ROM,SRAM 等其余 2 个存储器 Bank 为 ROM,SRAM,SDRAM 等–7 个固定的_京累里101123