2021年1月

1. 交流沟通使用金字塔结构,会更加容易。

各个主题之间只有纵向(向上或向下)和横向的关系,从最上面的总的思想向下进行细分。

2. 结构

2.1 纵向关系

通过纵向关系,可以引导文章形成 “疑问--回答” 式的对话。每一个方框就时一个思想,读者对这个思想产生的疑问在下一层中进行解答,并引出新的疑问,这样一层一层 “疑问 -- 回答”,直到最后的回答不会产生新的疑问为止。 为了吸引注意,不要再引起疑问之前,预先给出问题的答案。

例子: 购买经营权 将快速增长

市场份额大,零售竞争小

2.2 横向关系

演绎思想

  • 所有的人都会死
  • 苏格拉底时一个人
  • 因此苏格拉底会死。 第一个是对现象的表述,第二个是结论的主语或谓语,第三个是把第二个带入第一个,进行推演后的结果。

归纳思想

  • 法国进入波兰边境
  • 德国进入波兰边境
  • 俄国进入波兰边境
  • 波兰遭遇入侵 通过对前三个思想进行归纳,提取出逻辑上的共同点,得出最后的结论,这个就是归纳思想。

2.3 序言

文章的初始问题,即读者的第一个疑问,可以通过讲故事式的序言(前言,引言)确定初始问题。 文章为了吸引读者的注意,必须回答读者头脑中已有的问题,或者读者对事情进行短暂思考后会提出的问题。文章的引言可以通过追溯问题的起源和发展来给出这一问题。 序言的开头应当向读者说明背景的时间和地点,在这个背景中应当发生了某件事情,或冲突,使得读者提出你的文章将要回答的问题。 这就是典型的 背景 -- 冲突 -- 疑问 -- 回答,能够让读者和你站在同一位置去思考问题。

3. 构建金字塔

3.1 自上而下

  1. 提出主题
  2. 设想主要疑问
  3. 写出主要疑问的回答,或标注能够回答
  4. 说明背景
  5. 指出冲突
  6. 检查主要疑问和答案

例子: 大客户要求改变记账方式

  • 背景: 大客户建议改变记账方式
  • 冲突: 你们问我改建议是否可行
  • 疑问: 改建议是否可行 该建议式可行的 | | | 客户将向我们提供所需的全部信息, 将增加我们的现金流, 将减少我们的工作量

1. 首先使用命令 ssh-keygen -t rsa -C "your_email@example.com" -f ~/.ssh/github_id_rsa 来生成 github 的密钥。就是 github_id_rsa 和 github_id_rsa.pub

2. 创建或者修改 config 文件。 vim ~/.ssh/config

Host github
        HostName github.com
        User git
        IdentityFile ~/.ssh/github_id_rsa

注意上面如果没有 User git,那么使用 ssh -T github 会以当前的用户名来登录 github,但是正常情况下,当前 linux 的用户名和 github 的用户名不会一样,所以会错误。这里设置 user 以后,会以 git@github.com 来登录,这时候,就可以了,返回信息是: Hi ptz1986! You've successfully authenticated, but GitHub does not provide shell access.

3. git clone 可以使用简化的方式来操作。

git clone github:your_name/your_repo 相当于 git clone git@github.com:your_name/your_repo.git

4. gitee 也是类似

Host gitee
        HostName gitee.com
        User git
        PreferredAuthentications publickey
        IdentityFile ~/.ssh/gitee_id_rsa

ssh -T gitee 会提示 The authenticity of host 'gitee.com (180.97.125.228)' can't be established. 直接按 yes 就可以了,会自动向 known_hosts 里面添加 gitee 的内容,下次就不需要了。

5. 本地的 gitlab 也是类似

Host gitlab
        HostName xxx.xxx.xxx.xxx
        User gitlab
        IdentityFile ~/.ssh/id_rsa

注意这个 User 可以看你 git clone 时候,@ 前面的那个就是。

参考: https://zhuanlan.zhihu.com/p/31253789
https://blog.csdn.net/u012860695/article/details/88953802
https://www.cnblogs.com/okokabcd/p/9065534.html
https://www.jianshu.com/p/c30e1f787b92
https://gitee.com/help/articles/4229#article-header0
https://blog.csdn.net/M_WBCG/article/details/79156781

1. 先 git clone tensorflow 的仓库,可以在 github 也可以在 gitee, gitee 会比 github 慢一天左右。但是下载速度快多了。

git clone https://github.com/tensorflow/tensorflow.git
git clone https://gitee.com/mirrors/tensorflow.git

2. 确定环境里面有 g++, gcc, ar

3. 下载需要的依赖

./tensorflow/lite/tools/make/download_dependencies.sh

下载的依赖文件在 ./tensorflow/lite/tools/make/downloads 文件夹下面

4. 修改 Makefile

vim ./tensorflow/lite/tools/make/Makefile

把里面的

CXX := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}g++
CC := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}gcc
AR := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}ar

这三行,修改为对应的 g++, gcc, ar

4. 编译为库

./tensorflow/lite/tools/make/build_aarch64_lib.sh

生成的静态库文件在 tensorflow/lite/tools/make/gen/aarch64_armv8-a/lib/libtensorflow-lite.a

参考: https://tensorflow.google.cn/lite/guide/build_arm64?hl=zh-cn

5. 抽取 tflite 的头文件,并打包

cd tensorflow/tensorflow
find ./lite -name "*.h" | tar -cf headers.tar -T -

这个 headers.tar 里面包含了头文件和一些不需要的东西。 注意:有些头文件在 tensorflow/tensorflow/lite/tools/make/downloads 这个下载的包里面。比如说 flatbuffers,要把他们专门复制到相应的头文件夹下面。 include 头文件夹下面的组织形式

[xxx@localhost include]$ tree -L 3
.
├── downloads
│   └── include
│       └── flatbuffers
└── tensorflow
    └── lite
        ├── allocation.h
        ├── arena_planner.h
        ├── builtin_op_data.h
        ├── builtin_ops.h
        ├── c
        ├── context.h
        ├── context_util.h
        ├── core
        ├── delegates
        ├── error_reporter.h
        ├── examples
        ├── experimental
        ├── external_cpu_backend_context.h
        ├── graph_info.h
        ├── interpreter_builder.h
        ├── interpreter.h
        ├── java
        ├── kernels
        ├── memory_planner.h
        ├── micro
        ├── minimal_logging.h
        ├── model_builder.h
        ├── model.h
        ├── mutable_op_resolver.h
        ├── nnapi
        ├── op_resolver.h
        ├── optional_debug_tools.h
        ├── profiling
        ├── python
        ├── schema
        ├── simple_memory_arena.h
        ├── stderr_reporter.h
        ├── string_type.h
        ├── string_util.h
        ├── testing
        ├── tflite_with_xnnpack_optional.h
        ├── toco
        ├── tools
        ├── type_to_tflitetype.h
        ├── util.h
        └── version.h

20 directories, 26 files

参考: https://blog.csdn.net/shui123546yi/article/details/105410781

6. 把前面编译好的静态库也复制到 lib 文件夹下面。

7. 编写 cmake 文件

#注意:如果工程有依赖库的话,ADD_EXECUTABLE指令要放在LINK_DIRECTORIES指令之后,
#       不然会报错:Linking C executable main
#                   /usr/bin/ld: cannot find -lhello
#                   collect2: ld 返回 1

#1) 设置 cmake 的最低版本
cmake_minimum_required(VERSION 3.10)

#2) 设置 project 名称
project(tflite_test)

#3) 设置代码源文件列表
set(SRC_LIST main.cpp model.cpp)

#4) 增加头文件搜索路径,解决编译期间找不到头文件的问题
#COMMAND: INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dire1 dire2 ...)
#定义:向工程添加多个特定的头文件搜索路径,路径之间用空格分开,
#       如果路径中包含空格,可以使用双引号括起来
#       默认是追加到当前的头文件搜索路径之后,你可以用2种方式控制搜索路径的添加>方式
#       1)CMAKE_INCLUDE_DIRECTORIES_BEFORE 通过SET设置其为on,使用前置模式
#       2)通过AFTER或BEFORE参数,控制追加还是置前
include_directories("/usr/include/x86_64-linux-gnu")
include_directories("./include")
include_directories(".")
include_directories("./include/downloads/include")

#5) 增加库文件: 解决链接期间找不到调用外部接口的问题
#main.cpp:(.text+0x5): undefined reference to `HelloFunc()'
#collect2: error: ld returned 1 exit status

#6) 增加库文件搜索路径:解决链接期间找不到库文件的问题
#COMMAND: LINK_DIRECTORIES(dir1 dir2 ...)
#定义:添加非标准的共享库搜索路径
#/usr/bin/ld: cannot find -lhello
#collect2: error: ld returned 1 exit status
#好像相对路径会找不到库文件
link_directories("/usr/lib/x86_64-linux-gnu")
link_directories("./lib")

#7) 生成二进制文件
add_executable(${PROJECT_NAME} ${SRC_LIST})

#8) 链接库
#COMMAND: TARGET_LINK_LIBRARIES(target  library1
#                                <debug | optimized> library2
#                                ...)
#定义:用来为target添加需要链接的共享库
#TARGET_LINK_LIBRARIES(${PROJECT_NAME} hello) #链接动态库指令
#TARGET_LINK_LIBRARIES(${PROJECT_NAME} libhello.a)  #链接静态库指令
target_link_libraries(${PROJECT_NAME} PRIVATE tensorflow-lite pthread ${CMAKE_DL_LIBS})

注意:如果提示没有 undefined reference to dlopen ,undefined reference to pthread_create 别忘了在链接库里面添加 pthread ${CMAKE_DL_LIBS}

参考:

https://github.com/jiangxinyang227/nlp_tflite/blob/master/cpp_tflite/src/inference.cpp https://www.cnblogs.com/jiangxinyang/p/13215724.html https://github.com/tensorflow/tensorflow/tree/master/tensorflow https://tensorflow.google.cn/lite/microcontrollers/get_started https://www.cnblogs.com/vitoyeah/p/10273299.html https://github.com/gdyshi/model_deployment/blob/master/tflite/C%2B%2B/model.cc https://github.com/gdyshi/model_deployment/blob/master/tflite/C%2B%2B/example.cc https://github.com/gdyshi/model_deployment https://blog.csdn.net/chongtong/article/details/90379347 https://blog.csdn.net/chongtong/column/info/39386 https://blog.csdn.net/chongtong/article/details/95355814