由于在配置直接使用网线进行的远程桌面连接时,操作太急,把弹出的提示框直接关掉了。 然后发现在网络管理中心,在同一张网卡、同一个网络下,多出了一个“未识别网络”。这玩意不但碍眼,还导致网络访问速度(甚至成功率)有一定的下降。

在经过长时间的网络搜寻之后,在这个帖子里获得了灵感。在该文中提到,提问者是由于在一张网卡上配置了两个网关,导致Windows会对经由每一个网关的网络连通性进行检测,若是数据包发错了路由,就会无法正常与服务器通讯,出现网络错误。

回想之前的操作过程中,由于急着修改IP地址,忘记网关没有修改了,然后Windows自动为其配置成了多网关模式,而这就导致了上述情况的发生,回去查看连接属性,果然有两个网关。先点选手动分配IP地址,然后删掉那个多余的网关,再重新切换回自动分配模式即可。

virtualenv的设计还是让人有些摸不着头脑的。。使用virtualenv命令配置好venv之后,实际上是相当于进行了安装的操作。安装的绝对路径被写入了文件中。有些版本(linux?)的venv使用的是.py脚本格式的pip,而新版Windows使用的似乎是exe文件。脚本格式的很好改,把VIRTUAL_ENV改为目标目录路径即可。Windows下exe格式的pip,把路径信息写在了文件末尾,因而需要使用WinHex一类的工具,在不破坏文件原本结构的情况下,对附加数据进行修改。对于easy_install也是一样的操作。

改编自 https://blog.csdn.net/Vipbinn/article/details/82978003 ->来源追踪:https://blog.csdn.net/chengshuhao1991/article/details/78545723

在通过TensorFlow中文社区TensorFly对TensorFlow框架进行了解的时候,对于入门的第一个例子进行了逐行的学习,对于数据的生成、表示,以及各个函数的作用有了一定的认识。其中reduce_mean()函数的定义和作用让我觉得很有意思,但又无法确认对其的理解,在网络上浏览了一些博客,发现有不少与我的理解是相同的,因此记录下来。

使用任意具有代码补全功能的IDE,在完成导入工作(即import tensorflow as tf)后,输入tf.reduce_,会得到大量reduce开头的函数补全提示,其中就包含reduce_mean()

文档中列出的所有操作为: reduce_all(...) 逻辑与 reduce_any(...) 逻辑或 reduce_euclidean_norm(...) 欧几里得范数(Euclidean norm of elements)->\sqrt{\sigma_{i=1}^{n} x_{i}^{2}} reduce_logsumexp(...) 如同名字,先取指数幂,求和后取对数 -> \log_{10} \sigma_{i=1}^{n} e^{x} reduce_max(...) 最大值 reduce_mean(...) 平均值 reduce_min(...) 最小值 reduce_prod(...) 乘积 reduce_std(...) 标准差 reduce_sum(...) 求和 reduce_variance(...) 方差

其中关于reduce_mean(),官方给出的解释如下:

tf.math.reduce_mean(
    input_tensor,
    axis=None,
    keepdims=None,
    name=None,
    reduction_indices=None,
    keep_dims=None
)

Reduces input_tensor along the dimensions given in axis. Unless keepdims is true, the rank of the tensor is reduced by 1 for each entry in axis. If keepdims is true, the reduced dimensions are retained with length 1.

If axis is None, all dimensions are reduced, and a tensor with a single element is returned.

其中,axis参数指定了计算过程中需要“降维”的维度,若是不传值的话,默认对全部维度采取降维操作,返回的是一个单独的值(维度为0),否则将按照指定的维度执行降维操作。而keepdims参数则用于申明要求在操作过程中不降低维度,由于各类reduce操作均属于聚合操作,因而该参数的实际含义为在计算完成后,为其保留一对方括号(即一个维度)。

咕果的开发团队把之前版本的参数名keep_dims改为了keepdims,所以如果使用的是比较老的版本的话,可能需要考虑改一下函数名= =(还算良心地没有直接去除对老参数名的支持)

在文档给出的例子中,使用输入张量

x = tf.constant(
  [[1., 1.],
   [2., 2.]]
)

对于两个常用参数(axis, keepdims)的测试,结果分别如下: 不传值的情况下:

>>> op = tf.reduce_mean(x)
>>> sess.run(op)
1.5

指定axis的情况下:

>>> op = tf.reduce_mean(x, axis = 0)
>>> sess.run(op)
array([1.5, 1.5], dtype=float32)

>>> op = tf.reduce_mean(x, axis = [1])
>>> sess.run(op)
array([1., 2.], dtype=float32)

>>> op = tf.reduce_mean(x, axis = [0, 1])
>>> sess.run(op)
1.5

指定keepdims=True,即保留维度的情况下:

>>> op = tf.reduce_mean(x, keepdims = True)
>>> sess.run(op)
array([[1.5]], dtype=float32)

>>> op = tf.reduce_mean(x, axis = [1], keepdims = True)
>>> sess.run(op)
array([[1.],
       [2.]], dtype=float32)

由此,两个常用参数与函数本身的作用就能够比较清晰地展示出来了。

那么,回到标题:既然都是聚合函数,为什么要在函数名前加一个reduce_前缀呢? 根据上文的描述,答案应该是比较清晰了:在进行了这些聚合操作之后,TensorFlow会默认将结果作为数据返回,也就是说,不论你的axis参数填了没,填了什么,在输入张量的至少某一个维度,一定会进行聚合操作,而聚合操作之后,数据合而为一,降低了输入张量的维度。而在英语中,reduce作为动词,有着减少,缩小(尺寸、数量、价格等)的意思,在此可以引申为在维度数量上的缩小。这样理解之后,看着函数名,对于其记忆和功能的推测就轻松多了。

  1. 图像的读取/展示/保存

    cv2.imread(file: str)
    cv2.imshow(windowName: str, data: numpy.ndarray) 
    cv2.imwrite(data: numpy.ndarray, file: str)

    其中cv2.imwrite需要与cv2.waitKey()以及cv2.destroyWindow(windowName)配合使用。

  2. 使用cv2.imshow函数时,可能出现的问题:src_depth != CV_16F && src_depth != CV_32S in function 'convertToShow' 就我个人而言,这是由于待展示的图像数据中使用了非法的数据格式造成的。在进行图像拼接并且加入自定义色块的时候,可使用numpy.asarray创建满足要求的图像数据,但是一定要记得指定数据类型dtype=np.uint8,否则虽然可以存储,但是在展示的时候无法通过数据类型检查。

  3. 图像拼接
    np.concatenate(data: tuple, axis=0)

    将需要拼接的图像在非拼接维度转化为相同的大小,然后指定拼接维度(axis)。默认为0,即正数第一个维度。 需要注意的是opencv和numpy所使用的坐标格式相反,numpy同数学矩阵一样以行作为第一坐标(即y值),列作为第二坐标(即x值),与图像,亦即通常使用的笛卡尔直角坐标系相反。

TensorFlow对于CUDA库的版本有着较为严格的要求,比如早期的TensorFlow1.10都不允许使用超过CUDA 9.0的版本。 好在现在版本放松了,允许使用指定范围内的CUDA进行编译。(然而还是有许多大神魔改编译配置,并且成功编译出了指定版本之外的环境组合,比如1.10+9.2) 但是随着TensorFlow在机器学习界的地位日益壮大,咕果公司也开始了夹带私货的行为。官方编译指导文档上,我们可以看见,从1.11.0开始,编译工具由cmake换成了自家的bazel

(个人观点) 在下认为,换个编译工具没问题,但起码Windows平台上要花点功夫。一个更加便捷的编译工具固然是好事,但是如果为使用该工具而附加的配置环境过于繁琐的话,不但不能吸引用户,甚至反过来还有劝退的效果。即便放开Windows平台不言,在Linux平台上的编译也有着不小的问题,仅仅是编译CPU版本的,不论是java平台,还是软件本身的问题,层出不穷。对自家的产品还有最高版本限制?这似乎是这个项目在于自家地位远远不够重要的表现,用户反倒要成为开发的主力军。 (bb结束)

编译的版本为1.13.2,为了使用cmake脚本,需要做以下改动:

  1. 添加tensorflow\core\util\version_info.cc,在改用bazel作为推荐生成工具之后,在对应位置下找不到该文件。但是文件内容经推断如下:

    /*  Generated by gen_git_source.py  */
    const char* tf_git_version() {return "b'1.13.2 Release'";}
    const char* tf_compiler_version() {return "1.13.2";}

    也可以从此看出,该文件由Python脚本自动生成,脚本位置位于tensorflow\tools\git\gen_git_source.py

  2. 编辑tensorflow\contrib\cmake\external\sqlite.cmake,由于在文章编写时链接已经失效,将18行改为
    set(sqlite_URL https://www.sqlite.org/2019/sqlite-amalgamation-3280000.zip)
  3. 若是使用了不低于第四代的Intel CPU,可以采用扩展指令集以提高性能。由于MSVC编译器只提供到SSE2 (2000)的支持,相比于受到支持、近年来开发的AVX2 (~2012)性能肯定不会优秀到哪里去,因而选择使用AVX2指令集进行编译。有的CMake只识别到AVX,需要到设定的编译目录中的CMakelists.txt中直接修改tensorflow_WIN_CPU_SIMD_OPTIONS对应的值为/arch:AVX2。(需要使用SSE4.2的可以使用Intel家的ICC编译器,自家CPU肯定有完美支持的)

正在编译中,已经出现了错误,等编译完后继续来补充

=====================================================

后续补充 编译失败了,好气。不想再编译这破玩意了,直接到github上预编译包得了。 https://github.com/fo40225/tensorflow-windows-wheel