Ubuntu 14.04上使用CMake编译MXNet源码操作步骤(C++)
MXNet源码版本号为1.3.0,其它依赖库的版本号可参考:https://blog.csdn.net/fengbingchun/article/details/84997490
build.sh脚本内容为:
#! /bin/bashreal_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"data_dir="data"
if [ -d ${dir_name}/${data_dir} ]; thenrm -rf ${dir_name}/${data_dir}
filn -s ${dir_name}/./../../${data_dir} ${dir_name}new_dir_name=${dir_name}/build
mkdir -p ${new_dir_name}
cd ${new_dir_name}
echo "pos: ${new_dir_name}"
if [ "$(ls -A ${new_dir_name})" ]; thenecho "directory is not empty: ${new_dir_name}"#rm -r *
elseecho "directory is empty: ${new_dir_name}"
ficd -
# build openblas
echo "========== start build openblas =========="
openblas_path=${dir_name}/../../src/openblas
if [ -f ${openblas_path}/build/lib/libopenblas.so ]; thenecho "openblas dynamic library already exists without recompiling"
elsemkdir -p ${openblas_path}/buildcd ${openblas_path}/buildcmake -DBUILD_SHARED_LIBS=ON ..make
filn -s ${openblas_path}/build/lib/libopenblas* ${new_dir_name}
echo "========== finish build openblas =========="cd -
# build dmlc-core
echo "========== start build dmlc-core =========="
dmlc_path=${dir_name}/../../src/dmlc-core
if [ -f ${dmlc_path}/build/libdmlc.a ]; thenecho "dmlc static library already exists without recompiling"
elsemkdir -p ${dmlc_path}/buildcd ${dmlc_path}/buildcmake ..make
filn -s ${dmlc_path}/build/libdmlc.a ${new_dir_name}
echo "========== finish build dmlc-core =========="rc=$?
if [[ ${rc} != 0 ]]; thenecho "########## Error: some of thess commands have errors above, please check"exit ${rc}
ficd -
cd ${new_dir_name}
cmake ..
makecd -
CMakeLists.txt文件内容为:
PROJECT(MXNet_Test)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)# support C++11
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# support C++14, when gcc version > 5.1, use -std=c++14 instead of c++1y
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")IF(NOT CMAKE_BUILD_TYPE)SET(CMAKE_BUILD_TYPE "Release")SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O2")SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O2")
ELSE()SET(CMAKE_BUILD_TYPE "Debug")SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2")SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2")
ENDIF()
MESSAGE(STATUS "cmake build type: ${CMAKE_BUILD_TYPE}")MESSAGE(STATUS "cmake current source dir: ${CMAKE_CURRENT_SOURCE_DIR}")
SET(PATH_TEST_FILES ${CMAKE_CURRENT_SOURCE_DIR}/./../../demo/MXNet_Test)
SET(PATH_SRC_DMLC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/./../../src/dmlc-core)
SET(PATH_SRC_MSHADOW_FILES ${CMAKE_CURRENT_SOURCE_DIR}/./../../src/mshadow)
SET(PATH_SRC_OPENBLAS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/./../../src/openblas)
SET(PATH_SRC_MXNET_FILES ${CMAKE_CURRENT_SOURCE_DIR}/./../../src/mxnet)
SET(PATH_SRC_TVM_FILES ${CMAKE_CURRENT_SOURCE_DIR}/./../../src/tvm)
SET(PATH_SRC_DLPACK_FILES ${CMAKE_CURRENT_SOURCE_DIR}/./../../src/dlpack)
MESSAGE(STATUS "path test files: ${PATH_TEST_FILES}")# don't use opencv in mxnet
ADD_DEFINITIONS(-DMXNET_USE_OPENCV=0)
ADD_DEFINITIONS(-DMSHADOW_USE_F16C=0)SET(PATH_OPENCV /opt/opencv3.4.2)
IF(EXISTS ${PATH_OPENCV})MESSAGE(STATUS "Found OpenCV: ${PATH_OPENCV}")
ELSE()MESSAGE(FATAL_ERROR "Can not find OpenCV in ${PATH_OPENCV}")
ENDIF()# head file search path
INCLUDE_DIRECTORIES(${PATH_SRC_OPENBLAS_FILES}${PATH_SRC_OPENBLAS_FILES}/build # include openblas config.h${PATH_SRC_DLPACK_FILES}/include${PATH_SRC_MSHADOW_FILES}${PATH_SRC_DMLC_FILES}/include${PATH_SRC_TVM_FILES}/include${PATH_SRC_TVM_FILES}/nnvm/include${PATH_SRC_MXNET_FILES}/src${PATH_SRC_MXNET_FILES}/include${PATH_SRC_MXNET_FILES}/cpp-package/include${PATH_OPENCV}/include${PATH_TEST_FILES}
)# build mxnet dynamic library
SET(MXNET_SRC_LIST )# tvm
FILE(GLOB_RECURSE SRC_TVM_NNVM_C_API ${PATH_SRC_TVM_FILES}/nnvm/src/c_api/*.cc)
FILE(GLOB_RECURSE SRC_TVM_NNVM_CORE ${PATH_SRC_TVM_FILES}/nnvm/src/core/*.cc)
FILE(GLOB_RECURSE SRC_TVM_NNVM_PASS ${PATH_SRC_TVM_FILES}/nnvm/src/pass/*.cc)FILE(GLOB_RECURSE SRC_MXNET ${PATH_SRC_MXNET_FILES}/src/*.cc)LIST(APPEND MXNET_SRC_LIST${SRC_TVM_NNVM_C_API}${SRC_TVM_NNVM_CORE}${SRC_TVM_NNVM_PASS}${SRC_MXNET}
)
#MESSAGE(STATUS "mxnet src: ${MXNET_SRC_LIST}")ADD_LIBRARY(mxnet SHARED ${MXNET_SRC_LIST})# find opencv library
FIND_LIBRARY(opencv_core NAMES opencv_core PATHS ${PATH_OPENCV}/lib NO_DEFAULT_PATH)
FIND_LIBRARY(opencv_imgproc NAMES opencv_imgproc PATHS ${PATH_OPENCV}/lib NO_DEFAULT_PATH)
FIND_LIBRARY(opencv_highgui NAMES opencv_highgui PATHS ${PATH_OPENCV}/lib NO_DEFAULT_PATH)
FIND_LIBRARY(opencv_imgcodecs NAMES opencv_imgcodecs PATHS ${PATH_OPENCV}/lib NO_DEFAULT_PATH)
FIND_LIBRARY(opencv_video NAMES opencv_video PATHS ${PATH_OPENCV}/lib NO_DEFAULT_PATH)
FIND_LIBRARY(opencv_videoio NAMES opencv_videoio PATHS ${PATH_OPENCV}/lib NO_DEFAULT_PATH)
FIND_LIBRARY(opencv_objdetect NAMES opencv_objdetect PATHS ${PATH_OPENCV}/lib NO_DEFAULT_PATH)
FIND_LIBRARY(opencv_ml NAMES opencv_ml PATHS ${PATH_OPENCV}/lib NO_DEFAULT_PATH)
MESSAGE(STATUS "opencv libraries: ${opencv_core} ${opencv_imgproc} ${opencv_highgui} ${opencv_imgcodecs} ${opencv_video}" ${opencv_videoio} ${opencv_objdetect} ${opencv_ml})# find dep library
SET(DEP_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build CACHE PATH "dep library path")
MESSAGE(STATUS "dep library dir: ${DEP_LIB_DIR}")
LINK_DIRECTORIES(${DEP_LIB_DIR})# recursive query match files :*.cpp
FILE(GLOB_RECURSE TEST_CPP_LIST ${PATH_TEST_FILES}/*.cpp)
FILE(GLOB_RECURSE TEST_CC_LIST ${PATH_TEST_FILES}/*.cc)
MESSAGE(STATUS "test cpp list: ${TEST_CPP_LIST} ${TEST_C_LIST}")# build executable program
ADD_EXECUTABLE(MXNet_Test ${TEST_CPP_LIST} ${TEST_CC_LIST})
# add dependent library: static and dynamic
TARGET_LINK_LIBRARIES(MXNet_Testmxnet${DEP_LIB_DIR}/libdmlc.a${DEP_LIB_DIR}/libopenblas.sopthreadrt # undefined reference to shm_open${opencv_core}${opencv_imgproc}${opencv_highgui}${opencv_imgcodecs}${opencv_video}${opencv_videoio}${opencv_objdetect}${opencv_ml}
)
注:对源码有两处修改:
1. OpenBLAS注释掉common.h中的第681行;
2. dmlc-core再用CMake编译时,关闭OpenMP的支持,即将CMakeLists.txt中的第18行由ON调整为OFF.
以下是MNIST train的测试代码:
#include "funset.hpp"
#include <chrono>
#include <string>
#include <fstream>
#include <vector>
#include "mxnet-cpp/MxNetCpp.h"namespace {bool isFileExists(const std::string &filename)
{std::ifstream fhandle(filename.c_str());return fhandle.good();
}bool check_datafiles(const std::vector<std::string> &data_files)
{for (size_t index = 0; index < data_files.size(); index++) {if (!(isFileExists(data_files[index]))) {LG << "Error: File does not exist: " << data_files[index];return false;}}return true;
}bool setDataIter(mxnet::cpp::MXDataIter *iter, std::string useType, const std::vector<std::string> &data_files, int batch_size)
{if (!check_datafiles(data_files))return false;iter->SetParam("batch_size", batch_size);iter->SetParam("shuffle", 1);iter->SetParam("flat", 1);if (useType == "Train") {iter->SetParam("image", data_files[0]);iter->SetParam("label", data_files[1]);} else if (useType == "Label") {iter->SetParam("image", data_files[2]);iter->SetParam("label", data_files[3]);}iter->CreateDataIter();return true;
}} // namespace// mnist
/* reference: https://mxnet.incubator.apache.org/tutorials/c%2B%2B/basics.htmlmxnet_source/cpp-package/example/mlp_cpu.cpp
*/
namespace {mxnet::cpp::Symbol mlp(const std::vector<int> &layers)
{auto x = mxnet::cpp::Symbol::Variable("X");auto label = mxnet::cpp::Symbol::Variable("label");std::vector<mxnet::cpp::Symbol> weights(layers.size());std::vector<mxnet::cpp::Symbol> biases(layers.size());std::vector<mxnet::cpp::Symbol> outputs(layers.size());for (size_t i = 0; i < layers.size(); ++i) {weights[i] = mxnet::cpp::Symbol::Variable("w" + std::to_string(i));biases[i] = mxnet::cpp::Symbol::Variable("b" + std::to_string(i));mxnet::cpp::Symbol fc = mxnet::cpp::FullyConnected(i == 0 ? x : outputs[i - 1], weights[i], biases[i], layers[i]);outputs[i] = i == layers.size() - 1 ? fc : mxnet::cpp::Activation(fc, mxnet::cpp::ActivationActType::kRelu);}return mxnet::cpp::SoftmaxOutput(outputs.back(), label);
}} // namespaceint test_mnist_train()
{const int image_size = 28;const std::vector<int> layers{ 128, 64, 10 };const int batch_size = 100;const int max_epoch = 10;const float learning_rate = 0.1;const float weight_decay = 1e-2;#ifdef _MSC_VERstd::vector<std::string> data_files = { "E:/GitCode/MXNet_Test/data/mnist/train-images.idx3-ubyte","E:/GitCode/MXNet_Test/data/mnist/train-labels.idx1-ubyte","E:/GitCode/MXNet_Test/data/mnist/t10k-images.idx3-ubyte","E:/GitCode/MXNet_Test/data/mnist/t10k-labels.idx1-ubyte"};
#elsestd::vector<std::string> data_files = { "data/mnist/train-images.idx3-ubyte","data/mnist/train-labels.idx1-ubyte","data/mnist/t10k-images.idx3-ubyte","data/mnist/t10k-labels.idx1-ubyte"};#endifauto train_iter = mxnet::cpp::MXDataIter("MNISTIter");setDataIter(&train_iter, "Train", data_files, batch_size);auto val_iter = mxnet::cpp::MXDataIter("MNISTIter");setDataIter(&val_iter, "Label", data_files, batch_size);auto net = mlp(layers);mxnet::cpp::Context ctx = mxnet::cpp::Context::cpu(); // Use CPU for trainingstd::map<std::string, mxnet::cpp::NDArray> args;args["X"] = mxnet::cpp::NDArray(mxnet::cpp::Shape(batch_size, image_size*image_size), ctx);args["label"] = mxnet::cpp::NDArray(mxnet::cpp::Shape(batch_size), ctx);// Let MXNet infer shapes other parameters such as weightsnet.InferArgsMap(ctx, &args, args);// Initialize all parameters with uniform distribution U(-0.01, 0.01)auto initializer = mxnet::cpp::Uniform(0.01);for (auto& arg : args) {// arg.first is parameter name, and arg.second is the valueinitializer(arg.first, &arg.second);}// Create sgd optimizermxnet::cpp::Optimizer* opt = mxnet::cpp::OptimizerRegistry::Find("sgd");opt->SetParam("rescale_grad", 1.0 / batch_size)->SetParam("lr", learning_rate)->SetParam("wd", weight_decay);// Create executor by binding parameters to the modelauto *exec = net.SimpleBind(ctx, args);auto arg_names = net.ListArguments();// Start trainingfor (int iter = 0; iter < max_epoch; ++iter) {int samples = 0;train_iter.Reset();auto tic = std::chrono::system_clock::now();while (train_iter.Next()) {samples += batch_size;auto data_batch = train_iter.GetDataBatch();// Set data and labeldata_batch.data.CopyTo(&args["X"]);data_batch.label.CopyTo(&args["label"]);// Compute gradientsexec->Forward(true);exec->Backward();// Update parametersfor (size_t i = 0; i < arg_names.size(); ++i) {if (arg_names[i] == "X" || arg_names[i] == "label") continue;opt->Update(i, exec->arg_arrays[i], exec->grad_arrays[i]);}}auto toc = std::chrono::system_clock::now();mxnet::cpp::Accuracy acc;val_iter.Reset();while (val_iter.Next()) {auto data_batch = val_iter.GetDataBatch();data_batch.data.CopyTo(&args["X"]);data_batch.label.CopyTo(&args["label"]);// Forward pass is enough as no gradient is needed when evaluatingexec->Forward(false);acc.Update(data_batch.label, exec->outputs[0]);}float duration = std::chrono::duration_cast<std::chrono::milliseconds>(toc - tic).count() / 1000.0;LG << "Epoch: " << iter << " " << samples / duration << " samples/sec Accuracy: " << acc.Get();}#ifdef _MSC_VERstd::string json_file{ "E:/GitCode/MXNet_Test/data/mnist.json" };std::string param_file{"E:/GitCode/MXNet_Test/data/mnist.params"};
#elsestd::string json_file{ "data/mnist.json" };std::string param_file{"data/mnist.params"};
#endifnet.Save(json_file);mxnet::cpp::NDArray::Save(param_file, exec->arg_arrays);delete exec;MXNotifyShutdown();return 0;
}
执行结果如下:
GitHub:https://github.com/fengbingchun/MXNet_Test
相关文章:

十年公务员转行IT,自学AI三年,他淬炼出746页机器学习入门笔记
整理 | Jane 编辑 | Just 出品 | AI科技大本营(ID:rgznai100)近期,梁劲传来该笔记重大更新的消息。《机器学习——从入门到放弃》这本笔记的更新没有停止,在基于上一版的基础上丰富了近 200 页计算机视觉领域的知识内容…

Python实现五子棋人机对战 | CSDN博文精选
作者 | 吴小鹏 来源 | 数据札记倌(ID:Data_Groom)五子棋是常见的一款小游戏,五子棋问题是人工智能中的一个经典问题。这篇文章主要介绍了Python版本五子棋的实现代码,大家可以做个参考,与我的傻儿子对弈一下。简 述虽…

HTTPS协议简介
HTTPS(HyperText Transfer Protocol Secure, 超文本传输安全协议):是一种透过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换…

闭包回调的写法
初学swift,封装了NSURLSession的get请求,在请求成功闭包回调的时候程序崩溃了 然后在图中1,2,3位置加上惊叹号“!”,再把4,5,6的惊叹号去掉就闭包回调成功了

错误 1 “System.Data.DataRow.DataRow(System.Data.DataRowBuilder)”不可访问,因为它受保护级别限制...
new DataRow 的方式: DataTable pDataTable new DataTable();DataRow pRow new DataRow(); 正确的方式: DataRow pRowpDataTable.newRow(); 转载于:https://www.cnblogs.com/wangzianan/p/4034892.html

iOS 支付 [支付宝、银联、微信]
这是开头语 前不久做了一个项目,涉及到支付宝和银联支付,支付宝和银联都是业界的老大哥,文档、SDK都是很屌,屌的找不到,屌的看不懂,屌到没朋友(吐槽而已),本文将涉及到的…

base64开源库介绍及使用
网上有一些开源的base64编解码库的实现,下面介绍几个: cppcodec是一个仅包括头文件的C11库,用于编解码RFC 4648中指定的base64, base64url, base32, base32hex等,它的License为MIT,源码在https://github.com/tplgy/cp…

情感识别难?图神经网络创新方法大幅提高性能
作者 | Kevin Shen译者 | Monanfei出品 | AI科技大本营(ID: rgznai100)【导读】最近,深度学习在自然语言处理领域(NLP)取得了很大的进步。随着诸如 Attention 和 Transformers 之类新发明的出现,BERT 和 XL…

Java的学习之路(1)
学过C语言之后,尝试接触Java. 借博文来记录自己学习的过程. Test01:利用循环,输出整数1-999之和 1 //2 //循环计算1到999的整数之和并输出3 //4 package demo;5 6 public class Main {7 8 public static void main(String[] args) {9 int su…

Swift - 使用addSubview()方法将StoryBoard中的视图加载进来
使用 Storyboard 我们可以很方便地搭建好各种复杂的页面,同时通过 segue 连接可以轻松实现页面的跳转。但除了segue,我们还可以使用纯代码的方式实现Storyboard界面的跳转。 比如:使用 presentViewController() 方法将当前页面视图切换成新视…

这项技术厉害了!让旅行者 2 号从星际空间发首批数据!
立即购票:https://dwz.cn/z1jHouwE物联网作为信息系统向物理世界的延伸,极大地拓展了人类认知和控制物理世界的能力,被称为继计算机和互联网之后的世界信息产业的第三次浪潮,正在深刻地改变着人类的生存环境和生活方式。据最新报道…

Ubuntu 14.04上使用CMake编译MXNet源码操作步骤(Python)
MXNet源码版本号为1.3.0,其它依赖库的版本号可参考:https://blog.csdn.net/fengbingchun/article/details/84997490 。 为了通过编译源码支持python接口,这里在 https://blog.csdn.net/fengbingchun/article/details/85162936 的基础上对bui…

近段时间学习html和CSS的一些细碎总结
1、边框圆角属性:border-radius,取值能够是 百分比 / 自己定义长度,不能够取负值。假设是圆,将高度和宽度设置相等,而且将border-radius设置为100% 2、IE6,IE7,IE8,opera,…

Swift:闭包
[objc] view plaincopy print?/* 闭包(Closures) * 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。 * 在Swift中的闭包与C、OC中的blocks和其它编程语言(如Python)中的lambdas类似。 * 闭包…

Ubuntu下使用CMake编译OpenSSL源码操作步骤(C语言)
OpenSSL的版本为1.0.1g,在ubuntu下通过CMake仅编译c代码不包括汇编代码,脚本内容如下: build.sh内容: #! /bin/bashreal_path$(realpath $0) dir_namedirname "${real_path}" echo "real_path: ${real_path}, di…

从词袋到Transfomer,NLP十年突破史
作者 | Zelros AI译者 | 夕颜出品 | AI科技大本营(ID:rgznai100)【导读】通过 Kaggle 竞赛视角,观察 NLP 十年发展简史。根据上下文(这里指句子的最后一个词),“它”可以指“动物”或“街道”。图源 | Goog…

《千只鹤》--[日]川端康成
《千只鹤》,作者是川端康成 故事梗概: 三谷菊治的父亲是个著名的茶道师匠,他生前与一位叫栗本近子的女人有染,后来又 钟情于太田夫人,而且由于后者而疏远了前者,但前者仍出入于三谷家。在三谷先生去 世四年…
所有接口添加plist文件的写法 swift
第一步 建立plist文件 interface JMTConfigUtils : NSObject /** * 获取配置文件中友盟key * * return NSString */ - (NSString *)umengKey; /** * 微信AppId * * return NSString */ - (NSString *)wxAppId; /** * 微信appSecret * * return NSString */ - (NSString…

提高C++性能的编程技术笔记:标准模板库+测试代码
标准模板库(Standard Template Library, STL)是容器和通用算法的强效组合。 渐近复杂度:算法的渐近复杂度是对算法性能的近似估计。它是算法集到特定性能标准集的映射。如果需要对包含N个整数的向量的所有元素求和,那么每个整数必须且仅需检查一次&…

「创式纪」人工智能应用创新大赛启动,首次结合商业计划和机器学习
谈到人工智能,技术和应用场景成为了大家广泛关注的话题。技术的演进,是推动人工智能发展的核心,而广泛的场景应用,则是人工智能真正价值所在。现阶段,精准营销、信贷风控、人脸比对等为人熟知的AI,已经经过…

linux chattr命令
chattr 设置linux文件的属性 (参照man手册进行翻译,常用的属性都翻译过来,个人觉得很少用到的属性就没有翻译) 用法:chattr [ -RVf ] -[acdeijstuADST] files选项:-R 对目录进行递归处理-V 显示详细的输出-F 忽略…

swift 中高德地图随时读取坐标地点的写法
自己写的方法 不比比 自己能看懂就行 只用作自己学习swift的总结 import UIKit typealias block (String,String) ->() class MoveCarViewController: UIViewController,MAMapViewDelegate,AMapLocationManagerDelegate,AMapSearchDelegate,UITextFieldDelegate,UIAler…

万字干货 | Python后台开发的高并发场景优化解决方案
嘉宾 | 黄思涵 来源 | AI科技大本营在线公开课互联网发展到今天,规模变得越来越大,也对所有的后端服务提出了更高的要求。在平时的工作中,我们或多或少都遇到过服务器压力过大问题。针对该问题,本次公开课邀请到了金山办公AI平台研…

提高C++性能的编程技术笔记:引用计数+测试代码
引用计数(reference counting):基本思想是将销毁对象的职责从客户端代码转移到对象本身。对象跟踪记录自身当前被引用的数目,在引用计数达到零时自行销毁。换句话说,对象不再被使用时自行销毁。 引用计数和执行速度之间的关系是与上下文紧密…

如何提升 CSS 选择器的性能?
CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,所以优化选择器的原则是应尽量避免使用消耗更多匹配时间的选择器。而在这之前我们需要了解CSS选择器匹配的机制, 如子选择器规则: #header > a {font-weight:blod;} 我…

百度AI攻坚战:PaddlePaddle中国突围
作者 | 阿司匹林出品 | AI科技大本营(ID:rgznai100)2013年,百度开始研发深度学习框架PaddlePaddle,搜索、凤巢CTR预估上线DNN模型。2016年,在百度世界大会上,百度宣布PaddlePaddle开源ÿ…

提高C++性能的编程技术笔记:编码优化+测试代码
缓存:在现代处理器中,缓存经常与处理器中的数据缓存和指令缓存联系在一起。缓存主要用来存储使用频繁而且代价高昂的计算结果,这样就可以避免对这些结果的重复计算。如,循环内对常量表达式求值是一种常见的低性能问题。 预先计算…

Swift 中使用 SQLite——打开数据库
关于Swift中使用SQLite,接下来可能会分别从打开、增、删、改、查,几个方面来介绍SQLite的具体使用,这一篇重点介绍一下如何打开。 定义全局数据库访问句柄 /// 全局数据库访问句柄 private var db: COpaquePointer nil实现打开数据库函数 …

MVC中获取模型属性的Range和StringLength验证特性设置
MVC中的客户端及服务端模型验证信息都以ModelMetadata类型作为承载,在获得属性的ModelMetadata之后(还不知道怎么获取ModelMetadata的童鞋请自行恶补),我们可以轻松得到一些我们在模型中定义的特性,比如显示名称、是否…

以安装PyTorch为例说明Anaconda在Windows/Linux上的使用
在Windows10上配置完MXNet 1.3.0后,再配置PyTorch 1.0时,发现两者需要依赖的NumPy版本不一致,之前是通过pip安装NumPy,根据pip的版本不同,会安装不同版本的NumPy,使用起来很不方便,而且MXNet和P…