之前一直都是使用scp远程拷贝文件,最大的麻烦在于它每次都是全量拷贝。没有使用rsync的原因是,这货在windows没有什么免费开源又原生的安装包——基于Cygwin的不算。

考虑到如今Docker镜像已经是大家的标配了,我们可以直接在本地构建一个工具箱镜像,然后在工具箱容器内跑rsync

FROM debian:latest

RUN apt-get update
RUN apt-get upgrade
RUN apt-get install -y openssh-client
RUN apt-get install -y wget curl git 
RUN apt-get install -y rsync

ENTRYPOINT [ "/bin/bash" ]

构建工具箱镜像,这个镜像是未来我们手头随时可用的百宝箱:

docker build -t newbiebox:0.1.0 .  

powershell中挂载本地.ssh目录,运行一个用完即删的容器:

docker run --rm --name newbiebox -it `
    -v C:/Users/stdunit/.ssh:/root/.ssh `
    -v C:\Users\stdunit\Desktop:/Desktop `
    newbiebox:0.1.0

这里挂载本地.ssh目录是因为rsync远程拷贝是基于ssh的,为了在容器内免密码登录远程服务器,需要把本地宿主上的.ssh私钥和密钥拷贝暴露给我们的容器。

如果是第一次挂载.ssh,可能需要修复一下这个目录下的读写权限——在windows下我们通常意识不到这个问题,但是Linux对权限检查比较严格。在容器内运行如下命令:

chmod 700 /root/.ssh             # 只有用户有访问权限
chmod 600 /root/.ssh/id_rsa      # 只有用户有读写权限
chmod 644 /root/.ssh/id_rsa.pub  # 让其他人可以读取
chmod 644 /root/.ssh/config      # 便客户端能读取配置文件

然后在容器内,使用rsync进行远程拷贝:

rsync -avz /Desktop/test-rsync/ username@remote-server:/dst/test-r

如果远程ssh的端口被改了,可以使用 -e "ssh -p 端口号"的形式:

rsync -e "ssh -p PORT" -avz /Desktop/test-rsync/ username@remote-server:/dst/test-r

上面的这两条指令是把本地文件同步到远程服务器,通过对调源路径和目标路径,可以实现把远程服务器的文件同步到本地:

rsync -e "ssh -p PORT" -avz user@remote-server:/path-to-backup /Desktop/backup/

OpenCV图像读取后,默认是预处理为HWC形状,而在PyTorch中,希望的是CHW形状; 另一方面,在通道顺序上,OpenCV默认是BGR的顺序,而在PyTorch的张量处理环节,我们一般希望的是RGB顺序。这里就涉及到了数据处理和转换。

OpenCV图像到PyTorch张量的转换

我们先模拟一个高度为2,宽度为3的彩色图像:

from torch import tensor

a = torch.randint(low=0, high=255, size=(2, 3, 3))

这里的a似于:

tensor([[[ 58, 223,  24], [ 35, 116, 249], [ 81, 220, 168]],
        [[242, 169, 149], [149,  87, 167], [165,  66,  88]]])

如果这个数据是从OpenCV读取过来,那么最内层通道顺序是BGR

为了得到RGB,我们可以将最内侧倒排一下:

b = a[:, :, [2,1,0]]

结果类似于:

tensor([[[ 24, 223,  58], [249, 116,  35], [168, 220,  81]],
        [[149, 169, 242], [167,  87, 149], [ 88,  66, 165]]])

但问题是,上面的张量形状是 (H,W,C),而在PyTorch中,我们期望的是(C,H,W)。现在我们将它拆分重排成RGB三个通道,其中每个通道都是一个2*3灰度图:

c = b.permute(2,0,1 )
print(c)

结果类似于:

tensor([
        # R通道
        [[ 24, 249, 168],
         [149, 167,  88]],         
        # G通道
        [[223, 116, 220],
         [169,  87,  66]],
        # B通道
        [[ 58,  35,  81],
         [242, 149, 165]]])

一个数据集加载示例

在《Modern Computer Vision》中,讲解了使用VGG16进行迁移学习,然后用于猫狗分类的示例。一方面VGG16预训练模型是在ImageNet数据集上训练得来的,其中所有图像都被缩放为 224 × 224 作为输入。为了充分利用预训练的权重,我们需要把训练的输入图像调整为相同大小。

阅读剩余部分

scikit-image 提供了一个match_template()函数,不过这个函数的定位并不是像VisionPro中的PMAlign(或者VisionMaster中的模板匹配),它不是一个端到端的工具,而是输出一个用模板滑过图像窗口形成的相关系数矩阵:即结果是一个矩阵,每个值表示在相应窗口位置时,模板与图像窗口的相关性。

这个函数的作用类似于我们手写一个人脸检测模块时,在第一阶段构建的人脸分类+滑动窗口的功能——即输出每个位置的得分,以表示每个区域是否存在人脸(或者存在人脸的概率)。但是随之而来的问题是,位置相近的窗口会有多个,但是它们都是同一个实体对象。这篇笔记组合了match_template()NMS算法,实现一个端到端的模板匹配功能。

实现对象

我们今天的实验对象是scikit-image官方的硬币示例:

image = data.coins()
coin = image[170:220, 75:130]

fig, ax = pyplot.subplots(1, 2)

ax0: axes.Axes = ax[0]
ax0.imshow(image, cmap='gray')
ax0.set_title("image")

ax1: axes.Axes = ax[1]
ax1.imshow(coin, cmap='gray')
ax1.set_title("template")

scikit-image模板匹配-截图1.PNG

阅读剩余部分

今天在使用sktime库的时候遇到了解码失败的问题:

from sktime.datasets import load_airline

报错类似于:

{
    "name": "UnicodeDecodeError",
    "message": "'gbk' codec can't decode byte 0xb8 in position 4507: illegal multibyte sequence",
    "stack": "---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
Cell In[19], line 1
----> 1 from sktime.datasets import load_airline

显然这是个编码问题,我第一时间检查了VSCode中的默认编码,确保是utf-8无误。

于是我怀疑大概率是程序编码出了问题,试了修改默认编码:

阅读剩余部分

DictVectorizer

考虑一个两列构成的输入数据:

citytemperature
New York70
San Francisco50

可以看到,这里第一列是一个类别特征,第二列是一个实数型特征。前面我们通过LabelBinarizer对标签进行one-hot编码,这里我们可以通过DictVectorizer实现对输入特征的自动one-hot编码:

阅读剩余部分