pip 安装包的时候,经常会碰到下载源码包速度太慢,反复重启的问题。有时候,挂代理效果也不明显。 这个时候,可以在一台电脑上把需要的包下载好,然后复制到目标电脑上,本地安装,这样就不会有太慢的问题了。 具体方法如下:

  1. 准备一台可以科学上网的电脑,选择 http 代理,全局。
  2. 在科学上网的电脑上,安装和目标机器相同版本的 python。
  3. 新建空目录,在目录路径打开命令行,pip download xyz,这样就把 xyz 这个包需要的包括依赖全部下载下来。
  4. 复制这个目录到目标机器。
  5. pip install --no-index --find-links=. xyz 这个是从本目录开始安装 xyz 的包。

如果碰到需要一次安装多个的,可以使用 requirements.txt

参考: https://www.pythonf.cn/read/20932 https://stackoverflow.com/questions/11091623/how-to-install-packages-offline https://blog.csdn.net/wangyaninglm/article/details/54177720 https://zhuanlan.zhihu.com/p/70065906

转自: https://blog.csdn.net/GUI1259802368/article/details/72737331?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

在算法中运用迭代器时,很可能会用到其相应型别,什么是相应型别?迭代器所指之物的型别便是其中之一。C++ 有函数模版推导机制,例如:

template<class I ,class T>
void  func_imp1(I iter, T t)
{
       T tmp;      // 这里解决了问题,T就是迭代器所指之物的型别,本例为int
};
template <class I>
inline  void func(I  iter)
{
       func_imp1(iter ,*iter);        // func 的工作全部移往 func_imp1
}
int main()
{
      int i;
      func(&i);
}

迭代器所指对象的型别。成为该迭代器的 value type。上述的参数型别推导虽然可用于value_type,但是当value type 必须用于函数的传回值,就束手无策了,毕竟函数的 “template 参数推导机制” 推而导之的只是参数,无法推导函数的返回值型别。

其他方法如声明内嵌型别似乎是个好主意,例如:

template<class T>
struct MyIter{
     typedef  T  value_type;   // 内嵌型别声明
     T* ptr;
     MyIter (T*  p=0): ptr(p){ }
     T& operator*() const {return  *ptr;}
      //....
};
template<class I>
typename I:: value_type
func(I ite)
{  return *ite;  }
//...
MyIter<int>ite(new  int(8));
cout<<func(ite);

注意:并不是所有的迭代器都是 class type。原生指针就不是!如果不是 class type,就无法为它定义内嵌型别。但是STL绝对必须接受原生指针作为一种迭代器,因此需要一种方法将上述的一般化概念针对特定情况做特殊化处理。

偏特化就可以做到,如下面一个class template:

template<typename T>
class  C {  ...  };          //这个泛化版本允许T为任何型别
很容易接受它有一个形式如下的 partial specialization:
template<typename T>
class C<T*>{  ...  };     //这个特化版本仅适用于“T为原生指针”的情况
                                   // “T为原生指针” 便是 “T为任何型别” 的一个更进一步的条件限制

下面这个 class template 专门用来 “萃取”迭代器的特性,而 value type正是迭代器的特性之一:

template<class I>
struct  iterator_traits{
    typedef  typename I::value_type     value_type;
};

这个所谓的 traits,其意义是,如果 I 定义有自己的 value_type,那么通过这个 traits 的作用,萃取出来的 value_type 就是 I:: value_type.换句换说,如果I定义有自己的 value type,先前那个 func() 可以改写成这样:

template<class I>
typename iterator_traits<I>::value_type
func(I  ite)
{ return  *ite; }

但是除了多一层间接性,又带来什么好处呢?好处是 traits 可以拥有特化版本。现在,我们令 iterator_traits 拥有一个 partial specializations 如下:

template<class  T>
struct  iterator_traits<T*>{           //偏特化版本------迭代器是个原生指针
    typedef   T  value_type;
};

最常用到的迭代器的相应型别有五种:value type,difference type,pointer,reference,iterator,iterator catagoly。如果你希望你所开发的容器能与STL水乳交融,一定要为你的容器的迭代器定义这五种相应型别。特性萃取机 traits 会很忠实的提取出来:

template<class  I>
struct  iterator_traits{
   typedef  typename  I:: iterator_category     iterator_category;
   typedef  typename  I:: value_type               value_type;
   typedef  typename  I:: difference_type       difference_type;
   typedef  typename  I:: pointer                     pointer;
   typedef  typename  I:: reference                 reference;
}; 

转自: https://blog.csdn.net/simahao/article/details/405455?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

本篇适合不熟悉这两个函数的读者

以前在使用stl的过程中发现bind1st和bind2nd这两个函数,当时不太理解什么意思,今天在网上查了一下相关资料发现竟然很简单,下面我就具体解释一下他们的用法。

bind1st和bind2nd函数用于将一个二元算子(binary functor,bf)转换成一元算子(unary functor,uf)。为了达到这个目的,它们需要两个参数:要转换的bf和一个值(v)。

可能这么解释以后大家还不是很清楚,那么就说点白话吧。我们在做比较的时候所写的表达式像 x > k ,x < k,这里的k是一个参数表示你程序里面的表达式要和k值去比较。上面这两个表达式对应的应该是bind2nd ,简单的理解就是把k作为比较表达式的第二个参数。如果使用bind1st则对应的表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。大家可能会注意到这里面没有=的比较,先别着急,后面将会说道如何实现=的比较。先举两个例子看看bind1st和bind2nd的用法。

int a[] = {1, 2, 100, 200};

std::vector< int> arr(a, a + 4);

// 移除所有小于100的元素
arr.erase( std::remove_if( arr.begin(),  arr.end(),
    std::bind2nd( std::less< int>(), 100)), arr.end());

这里的比较表达式相当于arr.value < 100

如果用bind1st则表达的意思就恰恰相反

// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(),  arr.end(),
    std::bind1st( std::less< int>(), 100)), arr.end());

这里的表达式相当于100 < arr.value

当然为了实现删除大于100的元素你同样可以使用bind2nd

// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(),  arr.end(),
    std::bind2nd( std::greater< int>(), 100)), arr.end());

前面说道=的比较,比如说x <= k怎么实现呢,std又提供了一个好东西not1,我们可以说 !(x > k) 和 x <= k是等价的,那么我们看看下面的表达式:

// 移除所有小于等于100的元素
arr.erase( std::remove_if( arr.begin(),  arr.end(),
    std::not1(std::bind2nd( std::greater< int>(), 100))), arr.end());

说明:not1是否定返回值是单目的函数,std中还有not2它是否定返回值是双目的函数

例子需要包含头文件

#include <vector>
#include <algorithm>
#include <functional>

安装

安装 xtensor 之前需要先安装依赖 xtl, https://github.com/xtensor-stack/xtl https://github.com/xtensor-stack/xtensor

进入 xtl 源码目录运行命令:

cmake -DCMAKE_INSTALL_PREFIX=/usr
sudo make install

进入 xtensor 源码目录运行命令:

cmake -DCMAKE_INSTALL_PREFIX=/usr
sudo make install

简单使用

工程目录下创建 compile.sh

#!/bin/bash 

mkdir -p build
pushd build
cmake ..
make
make install
popd

相应的 CMakeLists 文件中添加:

set(CMAKE_CXX_STANDARD 14)

如果工程还涉及到 opencv,那么需要添加

    find_package(OpenCV REQUIRED)
    include_directories(${OpenCV_INCLUDE_DIRS})
    link_directories(${OpenCV_LIBRARY_DIRS})

    target_link_libraries(${name} ${OpenCV_LIBS})

如果工程中用到 cjsonobject,需要添加

    include_directories("${PROJECT_SOURCE_DIR}/CJsonObject")

如果工程运行的时候,需要某些库文件,那么可以新建一个 run.sh,里面可以如下添加库,然后运行:

#!/bin/bash

export LD_LIBRARY_PATH=./tengine/linux-arm64-v8a/lib/

./build/install/bin/classification 

最近需要把一些 python 版本的程序转为 c++ 的程序。 python 中使用了很多 numpy 的调用,于是就再找 c++ 的实现。 找了一圈下来,发现最适合的可能就是 xtensor。 github: https://github.com/xtensor-stack/xtensor 使用: https://xtensor.readthedocs.io/en/latest/numpy.html

其他可选:

    The GNU Scientific Library is a GPL software written in C. Thus, it has a C-like allocation and way of programming (pointers, etc.). With the GSLwrap, you can have a C++ way of programming, while still using the GSL. GSL has a BLAS implementation, but you can use ATLAS instead of the default CBLAS, if you want even more performances.

    The boost/uBLAS library is a BSL library, written in C++ and distributed as a boost package. It is a C++-way of implementing the BLAS standard. uBLAS comes with a few linear algebra functions, and there is an experimental binding to ATLAS.

    eigen is a linear algebra library written in C++, distributed under the MPL2 license (starting from version 3.1.1) or LGPL3/GPL2 (older versions). It's a C++ way of programming, but more integrated than the two others (more algorithms and data structures are available). Eigen claim to be faster than the BLAS implementations above, while not following the de-facto standard BLAS API. Eigen does not seem to put a lot of effort on parallel implementation.

    Armadillo is LGPL3 library for C++. It has binding for LAPACK (the library used by numpy). It uses recursive templates and template meta-programming, which is a good point (I don't know if other libraries are doing it also?).

    xtensor is a C++ library that is BSD licensed. It offers A C++ API very similar to that of NumPy. See https://xtensor.readthedocs.io/en/latest/numpy.html for a cheat sheet.

参考: https://stackoverflow.com/questions/11169418/numpy-style-arrays-for-c https://github.com/dpilger26/NumCpp

1. torch.Tensor 生成一个 tensor 类型。

>>> import torch
>>> x=torch.Tensor([[1,2,3],[4,5,6]])
>>> x
tensor([[1., 2., 3.],
        [4., 5., 6.]])

参考: https://www.jianshu.com/p/314b6cfce1c3 https://pytorch-cn.readthedocs.io/zh/latest/package_references/Tensor/ https://blog.csdn.net/weixin_42018112/article/details/91383574

2. torch.nn.functional.softmax(input, dim=None, _stacklevel=3, dtype=None) 用于对设置的维度上的数进行收缩,让他的和为 1.

>>> import torch
>>> from torch import nn as nn
>>> input = torch.randn(2, 3, 4)
>>> input
tensor([[[-0.1335,  0.1574, -0.4618, -0.1629],
         [-1.1302, -0.2782,  0.2689,  1.4722],
         [ 1.8547,  3.0593,  1.7146, -0.4395]],

        [[-0.0102,  1.4679,  0.0138,  0.5245],
         [ 2.2345,  2.0089,  2.0074,  0.4197],
         [-1.4187, -0.0887,  0.9257,  0.2516]]])
>>> torch.nn.functional.softmax(input)
tensor([[[0.4692, 0.2124, 0.3833, 0.3346],
         [0.0334, 0.0922, 0.1495, 0.7413],
         [0.9635, 0.9588, 0.6876, 0.3338]],

        [[0.5308, 0.7876, 0.6167, 0.6654],
         [0.9666, 0.9078, 0.8505, 0.2587],
         [0.0365, 0.0412, 0.3124, 0.6662]]])
>>>
>>> torch.nn.functional.softmax(input, dim=0)
tensor([[[0.4692, 0.2124, 0.3833, 0.3346],
         [0.0334, 0.0922, 0.1495, 0.7413],
         [0.9635, 0.9588, 0.6876, 0.3338]],

        [[0.5308, 0.7876, 0.6167, 0.6654],
         [0.9666, 0.9078, 0.8505, 0.2587],
         [0.0365, 0.0412, 0.3124, 0.6662]]])
>>> torch.nn.functional.softmax(input, dim=1)
tensor([[[0.1153, 0.0504, 0.0841, 0.1452],
         [0.0426, 0.0326, 0.1746, 0.7447],
         [0.8421, 0.9171, 0.7413, 0.1101]],

        [[0.0936, 0.3415, 0.0923, 0.3757],
         [0.8835, 0.5866, 0.6779, 0.3383],
         [0.0229, 0.0720, 0.2298, 0.2860]]])
>>> torch.nn.functional.softmax(input, dim=2)
tensor([[[0.2482, 0.3320, 0.1788, 0.2410],
         [0.0479, 0.1122, 0.1939, 0.6460],
         [0.1885, 0.6287, 0.1638, 0.0190]],

        [[0.1232, 0.5403, 0.1262, 0.2103],
         [0.3626, 0.2894, 0.2889, 0.0591],
         [0.0487, 0.1843, 0.5081, 0.2589]]])

默认是对于第一维进行伸缩。 dim = 0, 0.4692 + 0.5308 = 1 dim = 1, 0.1153 + 0.0426 + 0.8421 = 1 dim = 2, 0.2482 + 0.3320 + 0.1788 + 0.2410 = 1

参考: https://blog.csdn.net/m0_46653437/article/details/111610571 https://pytorch.org/docs/master/nn.functional.html#torch.nn.functional.softmax https://blog.csdn.net/chengyq116/article/details/106893773

3. torch.clamp(input, min, max, *, out=None) → Tensor 用于限制数值的上限和下限,把所有数据限制在设定好的上下限之间。

>>> a = torch.randn(4)
>>> a
tensor([-1.7120,  0.1734, -0.0478, -0.0922])
>>> torch.clamp(a, min=-0.5, max=0.5)
tensor([-0.5000,  0.1734, -0.0478, -0.0922])

参考: https://pytorch.org/docs/stable/generated/torch.clamp.html

参考数目:

https://pytorch.apachecn.org/docs/1.0/tensors.html