tiny-cnn执行过程分析(MNIST)

2023-11-09

http://blog.csdn.net/fengbingchun/article/details/50573841中以MNIST为例对tiny-cnn的使用进行了介绍,下面对其执行过程进行分析:

支持两种损失函数:(1)、mean squared error(均方差);(2)、cross entropy(交叉熵)。在MNIST中使用的是mean squared error,代码段:

// mean-squared-error loss function for regression
class mse {
public:
    static float_t f(float_t y, float_t t) {
        return (y - t) * (y - t) / 2;
    }

    static float_t df(float_t y, float_t t) {
        return y - t;
    }
};
支持六种激活函数:(1)、tanh;(2)、sigmoid;(3)、softmax;(4)、rectifiedlinear(relu);(5)、leaky relu;(6)、identity。MNIST中使用的是tanh,代码段:

class tan_h : public function {
public:
    float_t f(const vec_t& v, size_t i) const override {
        const float_t ep = std::exp(v[i]);
        const float_t em = std::exp(-v[i]); 
        return (ep - em) / (ep + em);
    }

    // fast approximation of tanh (improve 2-3% speed in LeNet-5)
    /*float_t f(float_t x) const {
        const float_t x2 = x * x;
        x *= 1.0 + x2 * (0.1653 + x2 * 0.0097);
        return x / std::sqrt(1.0 + x * x);// invsqrt(static_cast<float>(1.0 + x * x));
    }*/

    float_t df(float_t y) const override { return 1.0 - sqr(y); }
    std::pair<float_t, float_t> scale() const override { return std::make_pair(-0.8, 0.8); }
设计CNN结构,用于MNIST,与LeNet-5结构相似,去除了F6层:

输入层Input:图像大小32*32,神经元数量32*32=1024,代码段:

    const int width = header.num_cols + 2 * x_padding;
    const int height = header.num_rows + 2 * y_padding;

    std::vector<uint8_t> image_vec(header.num_rows * header.num_cols);

    ifs.read((char*) &image_vec[0], header.num_rows * header.num_cols);

    dst.resize(width * height, scale_min);

    for (size_t y = 0; y < header.num_rows; y++)
      for (size_t x = 0; x < header.num_cols; x++)
        dst[width * (y + y_padding) + x + x_padding]
        = (image_vec[y * header.num_cols + x] / 255.0) * (scale_max - scale_min) + scale_min;
C1层:卷积窗大小5*5,输出特征图数量6,卷积窗种类6,输出特征图大小28*28,可训练参数5*5*6+6=156,神经元数量28*28*6=4704;

         S2层:卷积窗大小2*2,输出下采样图数量6,卷积窗种类6,输出下采样图大小14*14,可训练参数1*6+6=12,神经元数量14*14*6=1176;

         C3层:卷积窗大小5*5,输出特征图数量16,卷积窗种类16,输出特征图大小10*10,可训练参数6*16*5*5+16=2416,神经元数量10*10*16=1600;

         S4层:卷积窗大小2*2,输出下采样图数量16,卷积窗种类16,输出下采样图大小5*5,可训练参数1*16+16=32,神经元数量5*5*16=400;

         C5层:卷积窗大小5*5,输出特征图数量120,卷积窗种类120,输出特征图大小1*1,可训练参数5*5*16*120+120=48120,神经元数量1*120=120;

输出层Output:输出特征图数量10,卷积窗种类10,输出特征图大小1*1,可训练参数120*10+10=1210,神经元数量1*10=10。

原有MNIST图像大小为28*28,此处为32*32,上下左右各填补2个像素,填补的像素取值为-1,其它像素取值范围为[-1,1]。

权值和阈值(偏置)初始化:权值采用均匀随机数产生,阈值均赋0。

C1层权值,初始化范围[sqrt(6.0/(25+150)), sqrt(6.0/(25+150))];

S2层权值,初始化范围[sqrt(6.0/(4+1)), - sqrt(6.0/(4+1))];

C3层权值,初始化范围[sqrt(6.0/(150+400)), - sqrt(6.0/(150+400))];

S4层权值,初始化范围[sqrt(6.0/(4+1)), - sqrt(6.0/(4+1))];

C5层权值,初始化范围[sqrt(6.0/(400+3000)), - sqrt(6.0/(400+3000))];

输出层权值,初始化范围[sqrt(6.0/(120+10)),  -sqrt(6.0/(120+10))]。

前向传播:

C1层代码段:

        vec_t &a = a_[worker_index]; // w*x
        vec_t &out = output_[worker_index]; // output
        const vec_t &in = *(prev_out_padded_[worker_index]); // input
        
        std::fill(a.begin(), a.end(), (float_t)0.0);

        for_i(parallelize_, out_.depth_, [&](int o) {
            for (layer_size_t inc = 0; inc < in_.depth_; inc++) {
                if (!tbl_.is_connected(o, inc)) continue;

                const float_t *pw = &this->W_[weight_.get_index(0, 0, in_.depth_ * o + inc)];
                const float_t *pi = &in[in_padded_.get_index(0, 0, inc)];
                float_t *pa = &a[out_.get_index(0, 0, o)];

                for (layer_size_t y = 0; y < out_.height_; y++) {
                    for (layer_size_t x = 0; x < out_.width_; x++) {
                        const float_t * ppw = pw;
                        const float_t * ppi = pi + (y * h_stride_) * in_padded_.width_ + x * w_stride_;
                        float_t sum = (float_t)0.0;

                        // should be optimized for small kernel(3x3,5x5)
                        for (layer_size_t wy = 0; wy < weight_.height_; wy++) {
                            for (layer_size_t wx = 0; wx < weight_.width_; wx++) {
                                sum += *ppw++ * ppi[wy * in_padded_.width_ + wx];
                            }
                        }
                        pa[y * out_.width_ + x] += sum;
                    }
                }
            }

            if (!this->b_.empty()) {
                float_t *pa = &a[out_.get_index(0, 0, o)];
                float_t b = this->b_[o];
                std::for_each(pa, pa + out_.width_ * out_.height_, [&](float_t& f) { f += b; });
            }
        });

        for_i(parallelize_, out_size_, [&](int i) {
            out[i] = h_.f(a, i);
        });
S2层代码段:

        vec_t& a = a_[index];
     
        for_i(parallelize_, out_size_, [&](int i) {
            const wi_connections& connections = out2wi_[i];

            a[i] = 0.0;

            for (auto connection : connections)// 13.1%
                a[i] += W_[connection.first] * in[connection.second]; // 3.2%

            a[i] *= scale_factor_;
            a[i] += b_[out2bias_[i]];
        });

        for_i(parallelize_, out_size_, [&](int i) {
            output_[index][i] = h_.f(a, i);
        });

C3层、C5层代码段与C1层相同。

S4层代码段与S2层相同。

输出层代码段:

        vec_t &a = a_[index];
        vec_t &out = output_[index];

        for_i(parallelize_, out_size_, [&](int i) {
            a[i] = 0.0;
            for (layer_size_t c = 0; c < in_size_; c++) {
                a[i] += W_[c*out_size_ + i] * in[c];
            }

            if (has_bias_)
                a[i] += b_[i];
        });

        for_i(parallelize_, out_size_, [&](int i) {
            out[i] = h_.f(a, i);
        });
反向传播:

输出层代码段:

        vec_t delta(out_dim());
        const activation::function& h = layers_.tail()->activation_function();

        if (is_canonical_link(h)) {
            for_i(out_dim(), [&](int i){ delta[i] = out[i] - t[i]; });
        } else {
            vec_t dE_dy = gradient<E>(out, t);

            // delta = dE/da = (dE/dy) * (dy/da)
            for (size_t i = 0; i < out_dim(); i++) {
                vec_t dy_da = h.df(out, i);
                delta[i] = vectorize::dot(&dE_dy[0], &dy_da[0], out_dim());
            }
        }
C5层代码段:

        const vec_t& prev_out = prev_->output(index);
        const activation::function& prev_h = prev_->activation_function();
        vec_t& prev_delta = prev_delta_[index];
        vec_t& dW = dW_[index];
        vec_t& db = db_[index];

        for (layer_size_t c = 0; c < this->in_size_; c++) {
            // propagate delta to previous layer
            // prev_delta[c] += current_delta[r] * W_[c * out_size_ + r]
            prev_delta[c] = vectorize::dot(&curr_delta[0], &W_[c*out_size_], out_size_);
            prev_delta[c] *= prev_h.df(prev_out[c]);
        }

        for_(parallelize_, 0, (size_t)out_size_, [&](const blocked_range& r) {
            // accumulate weight-step using delta
            // dW[c * out_size + i] += current_delta[i] * prev_out[c]
            for (layer_size_t c = 0; c < in_size_; c++)
                vectorize::muladd(&curr_delta[r.begin()], prev_out[c], r.end() - r.begin(), &dW[c*out_size_ + r.begin()]);

            if (has_bias_) {
                for (int i = r.begin(); i < r.end(); i++)
                    db[i] += curr_delta[i];
            }
        });
S4层代码段:

        const vec_t& prev_out = *(prev_out_padded_[index]);
        const activation::function& prev_h = prev_->activation_function();
        vec_t* prev_delta = (pad_type_ == padding::same) ? &prev_delta_padded_[index] : &prev_delta_[index];
        vec_t& dW = dW_[index];
        vec_t& db = db_[index];

        std::fill(prev_delta->begin(), prev_delta->end(), (float_t)0.0);

        // propagate delta to previous layer
        for_i(in_.depth_, [&](int inc) {
            for (layer_size_t outc = 0; outc < out_.depth_; outc++) {
                if (!tbl_.is_connected(outc, inc)) continue;

                const float_t *pw = &this->W_[weight_.get_index(0, 0, in_.depth_ * outc + inc)];
                const float_t *pdelta_src = &curr_delta[out_.get_index(0, 0, outc)];
                float_t *pdelta_dst = &(*prev_delta)[in_padded_.get_index(0, 0, inc)];

                for (layer_size_t y = 0; y < out_.height_; y++) {
                    for (layer_size_t x = 0; x < out_.width_; x++) {
                        const float_t * ppw = pw;
                        const float_t ppdelta_src = pdelta_src[y * out_.width_ + x];
                        float_t * ppdelta_dst = pdelta_dst + y * h_stride_ * in_padded_.width_ + x * w_stride_;

                        for (layer_size_t wy = 0; wy < weight_.height_; wy++) {
                            for (layer_size_t wx = 0; wx < weight_.width_; wx++) {
                                ppdelta_dst[wy * in_padded_.width_ + wx] += *ppw++ * ppdelta_src;
                            }
                        }
                    }
                }
            }
        });

        for_i(parallelize_, in_padded_.size(), [&](int i) {
            (*prev_delta)[i] *= prev_h.df(prev_out[i]);
        });

        // accumulate dw
        for_i(in_.depth_, [&](int inc) {
            for (layer_size_t outc = 0; outc < out_.depth_; outc++) {

                if (!tbl_.is_connected(outc, inc)) continue;

                for (layer_size_t wy = 0; wy < weight_.height_; wy++) {
                    for (layer_size_t wx = 0; wx < weight_.width_; wx++) {
                        float_t dst = 0.0;
                        const float_t * prevo = &prev_out[in_padded_.get_index(wx, wy, inc)];
                        const float_t * delta = &curr_delta[out_.get_index(0, 0, outc)];

                        for (layer_size_t y = 0; y < out_.height_; y++) {
                            dst += vectorize::dot(prevo + y * in_padded_.width_, delta + y * out_.width_, out_.width_);
                        }
                        dW[weight_.get_index(wx, wy, in_.depth_ * outc + inc)] += dst;
                    }
                }
            }
        });

        // accumulate db
        if (!db.empty()) {
            for (layer_size_t outc = 0; outc < out_.depth_; outc++) {
                const float_t *delta = &curr_delta[out_.get_index(0, 0, outc)];
                db[outc] += std::accumulate(delta, delta + out_.width_ * out_.height_, (float_t)0.0);
            }
        }
C3层代码段:

        const vec_t& prev_out = prev_->output(index);
        const activation::function& prev_h = prev_->activation_function();
        vec_t& prev_delta = prev_delta_[index];

        for_(parallelize_, 0, (size_t)in_size_, [&](const blocked_range& r) {
            for (int i = r.begin(); i != r.end(); i++) {
                const wo_connections& connections = in2wo_[i];
                float_t delta = 0.0;

                for (auto connection : connections) 
                    delta += W_[connection.first] * current_delta[connection.second]; // 40.6%

                prev_delta[i] = delta * scale_factor_ * prev_h.df(prev_out[i]); // 2.1%
            }
        });

        for_(parallelize_, 0, weight2io_.size(), [&](const blocked_range& r) {
            for (int i = r.begin(); i < r.end(); i++) {
                const io_connections& connections = weight2io_[i];
                float_t diff = 0.0;

                for (auto connection : connections) // 11.9%
                    diff += prev_out[connection.first] * current_delta[connection.second];

                dW_[index][i] += diff * scale_factor_;
            }
        });

        for (size_t i = 0; i < bias2out_.size(); i++) {
            const std::vector<layer_size_t>& outs = bias2out_[i];
            float_t diff = 0.0;

            for (auto o : outs)
                diff += current_delta[o];    

            db_[index][i] += diff;
        } 
S2层、输入层代码段与S4层相同。

C1层代码段与C3层相同。

权值和偏置更新代码段:

    void update(const vec_t& dW, const vec_t& /*Hessian*/, vec_t &W) {
        vec_t& g = get<0>(W);

        for_i(W.size(), [&](int i) {
            g[i] += dW[i] * dW[i];
            W[i] -= alpha * dW[i] / (std::sqrt(g[i]) + eps);
        });
    }
对MNIST中的60000个训练样本,依次执行上面的操作,并更新权值和偏置。

每此循环执行完60000个训练样本,会对10000个测试样本,进行测试,获得识别率。

共迭代30次,然后将最终的权值、偏置等相关参数保持到指定的文件中。



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

tiny-cnn执行过程分析(MNIST) 的相关文章

  • 吴恩达老师深度学习视频课笔记:逻辑回归公式推导及C++实现

    逻辑回归 Logistic Regression 是一个二分分类算法 逻辑回归的目标是最小化其预测与训练数据之间的误差 为了训练逻辑回归模型中的参数w和b 需要定义一个成本函数 cost function 成本函数 cost functio
  • caffe源码 之 CPU与GPU数据同步类

    本文主要解析caffe源码文件 src caffe SycedMem cpp 该文件主要实现cpu与gpu的内存同步 先看SycedMem hpp中SycedMem的类定义 ifndef CAFFE SYNCEDMEM HPP define
  • [caffe]:检查失败:检查失败:hdf_blobs_[i]->shape(0) == num(200 vs. 6000)

    我有训练并将数据标记为 data mat 我有 200 个训练数据 包含 6000 个特征 标签为 1 1 已保存在 data mat 中 我正在尝试将数据转换为 hdf5 并使用以下命令运行 C affe load data mat hd
  • 谷歌 Deep Dream 艺术:如何在神经网络中选择一个层并对其进行增强

    我对 Google 最近发表的一篇博客文章感兴趣 该文章描述了nn创造艺术 我对一项技术特别感兴趣 在这种情况下 我们只需向网络提供任意图像或照片 然后让网络分析该图片 然后我们选择一个层并要求网络增强它检测到的任何内容 网络的每一层都处理
  • 解决类别不平衡:扩大对损失和 SGD 的贡献

    已添加对此问题的更新 我是比利时根特大学的研究生 我的研究是关于深度卷积神经网络的情感识别 我正在使用Caffe实施 CNN 的框架 最近我遇到了一个关于班级不平衡的问题 我正在使用大约 9216 个训练样本 5 被标记为阳性 1 其余样本
  • 如何修改批量归一化层(DeconvNet)以便能够与 caffe 一起运行?

    我想运行反卷积网络在我的数据上 但是它似乎是为另一个版本编写的caffe 有谁知道如何改变batch params Deconvnet 中的那个 layers bottom conv1 1 top conv1 1 name bn1 1 ty
  • 检查失败:mdb_status == 0 (2 vs. 0) 没有这样的文件或目录

    我在训练数据时收到以下错误 我已经尝试了互联网上给出的所有解决方案 但似乎没有一个对我有用 我已检查 lmdb 文件的路径和大小不为零 但问题仍然存在 我不知道如何解决这个问题 pooling I0411 12 42 53 114141 2
  • 用于 Caffe 的 Python 还是 Matlab?

    我将致力于在 Caffe 中实现 DQN 和 Google DeepMind 的最新扩展 为此 我将编写一个模拟器 代替 Atari 模拟器 来为代理创建培训体验 我的问题是 Matlab 或 Python 的 Caffe 接口中哪一个最成
  • 为 Caffe 生成 LMDB

    我正在尝试使用 caffe 我正在使用 python 包装器 构建用于显着性分析的深度学习模型 但我无法理解如何为此目的生成 lmdb 数据结构 我已经浏览了 Imagenet 和 mnist 示例 我明白我应该以以下格式生成标签 my t
  • Caffe 中的欧几里得损失层

    我目前正在尝试在 caffe 中实现我自己的损失层 在尝试这样做的同时 我使用其他层作为参考 然而 让我困惑的一件事是使用top 0 gt cpu diff in Backward cpu 我将使用EuclideanLossLayer作为参
  • Caffe 到 Tensorflow(Kaffe by Ethereon):TypeError:不应直接创建描述符,而只能从其父级检索

    我想使用 ethereon 的精彩包 caffe tensorflow 但遇到了中描述的相同问题这个已关闭的问题 https github com ethereon caffe tensorflow issues 10 当我运行该示例或尝试
  • Caffe:如何通过代码获取`solver.prototxt`参数?

    我想访问solver prototxt参数如base lr 基础学习率 或weight decay来自Python代码 有什么方法可以从solver net目的 谢谢 根据本教程 http nbviewer jupyter org gith
  • 如何更改CUDA版本

    我在编译修改后的caffe版本时遇到了这个错误 OpenCV static library was compiled with CUDA 7 5 support Please use the same version or rebuild
  • 未定义符号:_ZdlPvm

    我在用阿波罗咖啡 https github com Russell91 apollocaffe and 重新检查 https github com Russell91 ReInspect Apollocaffe在 c 库中并且Reinspe
  • 图像增强使性能变得更差[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在研究一个图像分割项目 并一直在尝试采用图像增强技术来增加训练集的大小 起初 我只是尝试使用水平翻转将图像尺寸放大一倍 但我发现性
  • 在caffe中定义新层时如何获取学习率或迭代次数

    我想当迭代次数达到一定次数时改变损失层中的损失计算方法 为了实现它 我认为我需要获取当前的学习率或迭代次数 然后我使用if短语选择是否改变损失计算方法 您可以添加一个成员变量咖啡类保存当前的学习率或迭代次数并在您想要的层中访问它 例如 要获
  • 如何在prototxt文件中写注释?

    我找不到如何写评论prototxt files 有没有办法在 prototxt 文件中添加注释 如何 Thanks 您可以通过添加评论 char 之后的行中的所有内容都是注释 layer name aLayerWithComments I
  • 如何在 CAFFE 的新网络中重复使用同一网络两次

    我有一个预训练的网络 我们称之为N 我想在新网络中使用两次 有人知道如何复制吗 然后我想为每个副本分配不同的学习率 例如 N1是第一个副本N N2是第二个副本N 新网络可能如下所示 N1 gt joint ip N2 gt layer 我知
  • 查找带有 Anaconda cmake 前缀的 boost-python3

    DLDR如何将 cmake 指向 boost python3 库 cmake 不会自动检测到它 我正在尝试建立caffe https github com BVLC caffe对于 Python 3 6 使用提供的 cmake 我的系统规格
  • Caffe,在层中设置自定义权重

    I have a network In one place I want to use concat As on this picture 不幸的是 该网络无法训练 为了理解为什么我想连续改变权重 这意味着 FC4096 中的所有值一开始都

随机推荐

  • ORACLE深入 第五章 Locking and Latching

    ORACLE深入 第五章 Locking and Latching Locks 在单用户系统 LOCKS是不需要的 在多用户系统 为了让多用户访问数据 修改数据 修改数据结构 就需要一个机制来保证大家的一致性修改 该用LOCK的时候就用LO
  • Selenium基础知识

    关于selenium你应该知道的 selenium是什么 一个自动化测试的工具 系统测试 测试阶段 单元测试 集成测试 系统测试 验收测试 自动化测试属于 系统测试 自动测试工具 自动化功能测试工具和自动化性能测试 selenium包括什么
  • Salary Changing【Codeforces 1251 D】【二分答案】

    Educational Codeforces Round 75 Rated for Div 2 D 题意 有N名员工和S元钱 然后我们想知道在每一名员工有薪资要求在 li ri 的情况下 我们如何在总共就S元钱的情况下做到员工薪资的中位数最
  • python爬虫 -- 12306登录刷票

    coding utf 8 from splinter browser import Browser from time import sleep import traceback Message phantomjs executable n
  • centos安装rocketmq

    centos安装rocketmq 1 下载rocketmq二进制包 2 解压二进制包 3 修改broker conf 4 修改runbroker sh和runserver sh的JVM参数 5 启动NameServer和Broker 6 安
  • Linux基础知识汇总,收藏

    对于嵌入式而言 大部分人的进阶路线 单片机 gt RTOS gt Linux 下面 针对有单片机 RTOS基础的同学 分享一份入门 Linux 的基础内容 下方超长干货预警 建议先收藏 再观看 Linux 基础 操作系统 操作系统 Oper
  • linux多线程编译

    include
  • 【教程】手把手教你用Clion进行STM32开发【如何优雅の进行嵌入式开发】

    通过Clion进行嵌入式开发 一 工具安装 1 安装Clion 因为众所周知的原因 Clion的安装就不解释了 有需要的同学自行检索 2 安装STM32CubeMX 正常去官网下载最新版的安装就行了 STM32CubeMX STM32Cub
  • LRC算法的Java实现

    项目中要用到 本来想拿来主义 结果没有找到合适的 所有自己写了一个 LRC具体算法如下 1 对需要校验的数据 2n个字符 两两组成一个16进制的数值求和 2 将模值按位取反 3 加1 Java代码实现 输入byte data 返回LRC校验
  • IDEA好用的两款Java代码质量审查插件

    IDEA好用的两款Java代码质量审查插件 两款Java代码质量审查插件 Alibaba代码规约插件 使用方式 SonarLint 使用方式 两款Java代码质量审查插件 Alibaba代码规约插件 SonarLint插件 Alibaba代
  • PCL 间接平差法拟合二维直线

    目录 一 算法原理 二 代码实现 三 结果展示 四 相关链接 一 算法原理 通过传统最小二乘法对点云数据进行二维直线拟合时 可将误差只归因于一个方向上 本文假设误差只存在于 y y y轴方向上 设点云拟合的二维直线方程为 y
  • Java-GUI初步理解

    什么是GUI GUI既图形用户界面 是一种以图形为主体的交互方式 主要包括AWT组件以及Swing组件以及容器 布局和事件相关的类接口 AWT是抽象窗口工具包的简称 其中有像窗口 按钮等组件 而Swing是基于AWT开发的 他的功能更加强大
  • ESP32+idf开发之WIFI通信入门(2)station网络连接

    ESP32 idf开发之WIFI通信入门 2 station网络连接 1 新建工程项目ctrl shift p 选择new project 输入项目名 选择合适项目路径 选择对应的开发板 此处选择自定义 target选择ESP32 moud
  • 数据库管理员DBA

    数据库管理员DBA什么是DBA 数据库管理员 英文是Database Administrator 简称DBA 这个职位对不同的人意味着不同的意义 一个小的软件开发工作室和一个分工高度明细的大公司相比 DBA的职责来得更加宽泛一些 一个公司
  • JVM-垃圾收集算法

    目录 1 分代收集理论 2 标记 清除算法 3 标记 复制算法 4 标记 整理算法 1 分代收集理论 分代思想也很简单 就是根据对象的生命周期将内存划分 然后进行分区管理 当前商业虚拟机的垃圾收集器大多数都遵循了 分代收集 Generati
  • 登录工程三:现代Web应用中的身份验证实践

    登录系统 首先 我们要为 登录 做一个简要的定义 令后续的讲述更准确 之前的两篇文章有意无意地混淆了 登录 与 身份验证 的说法 因为在本篇之前 不少 传统Web应用 都将对身份的识别看作整个登录的过程 很少出现像企业应用环境中那样复杂的情
  • 2023华为OD机试真题【开租建站】

    题目 当前IT部门支撑了子公司颗粒化业务 该部门需要实现为子公司快速开租建站的能力 建站是指在一个全新的环境部署一套IT服务 每个站点开站会由一系列部署任务项构成 每个任务项部署完成时间都是固定和相等的 设为1 部署任务项之间可能存在依赖
  • Excel:Excel中对特殊字符的转义和处理

    对引号转义 excel公式中用两个引号代表一个引号 abc abc 会得到abc abc abc 会得到字符串 abc 处理换行符 公式中如果需要字符串换行 这样写 换 CHAR 10 行 在单元格里输入换行符 用Alt Enter输入 在
  • pywinauto 使用

    Pywinauto是基于Python开发的 用于自动化测试的脚本模块 主要操作于Windows标准图形界面 它可以允许你很容易的发送鼠标 键盘动作给Windows的对话框和控件 其中 最主要功能为对windows标准控件的一系列动作可编程处
  • tiny-cnn执行过程分析(MNIST)

    在http blog csdn net fengbingchun article details 50573841中以MNIST为例对tiny cnn的使用进行了介绍 下面对其执行过程进行分析 支持两种损失函数 1 mean squared