Blog
blog's Introduction
blog's People
blog's Issues
面试记录
1. 智颜星球
(1) Softmax函数公式
import numpy as np
def softmax(x):
"""Compute softmax values for each sets of scores in x."""
# e_x = np.exp(x)
e_x = np.exp(x )
return e_x / e_x.sum()
if __name__ == '__main__':
x = np.array([-3, 2, -1, 0])
res = softmax(x )
print(res) # [0.0056533 0.83902451 0.04177257 0.11354962]
(2) C++中的多态
- C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
- 虚函数主要是为了实现子类函数重写父类函数的作用。
- 要实现多态,通常父类中的虚函数与子类中的函数的返回值类型、函数名和参数列表必须都相同的。
(3) 美学评价论文中loss和评价指标(srcc) 怎么计算的
- 预测概率的累加值减去真实值概率的累加值,累加是从batch维度累加,把这个值求平均。或者把这个值取平方,然后求均值,再开方。
- SRCC计算公式:
- r表示秩序,也就是按照x或者排序,如果按照x排序,就要把y对应的值重新调整顺序,然后计算y的秩序:
- 然后就可以按照公式计算x秩序的平均值和y秩序的平均值,最后带入公式计算srcc
x = [106, 97, 100, 101, 99, 103, 97, 113, 112, 110]
y = [7, 0, 27, 50, 28, 29, 20, 12, 6, 17]
x1 = np.array([1.5, 1.5, 3, 4, 5, 6, 7, 8, 9, 10],dtype='float64')
y1 = np.array([1, 6, 8, 7, 10, 9, 3, 5, 2, 4],dtype='float64')
# 表示x1和x2的平均值
x_mean = sum(x1)/len(x1)
y_mean = sum(y1)/len(y1)
son = sum((x1-x_mean)*(y1-y_mean))
mother = (sum((x1-x_mean)**2))**(0.5) * (sum((y1-y_mean)**2))**(0.5)
hand_srcc = son / mother
print("hand_srcc2=", hand_srcc)
2. 镁佳科技
(1) CNN的特点
- CNN主要包括卷积和池化,卷积的特点:局部感知、参数共享、多核。
- 局部感知:每个神经元只与上一层的部分神经元相连,没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。作用:降低网络参数,增加网络训练速度。
- 共享参数: 给定一个输入图像,用一个filter去扫这张图片,filter里面的数就是权重,这张图每个位置是被同样的filter扫的,所以权重是一样的,也就是共享。
- 池化下采样:对一块数据进行抽样或聚合,通过池化能够很好的聚合特征、降维来减少运算量。
(2) Transformer 和 Conformer
- Conformer是在Tranformer的基础上,引入CNN,来增强语音识别的效果。
- Transformer的大概结构:分为Encoder-Decoder架构:
- 在Encoder部分包含6个block,每个block由self-attention和FFN两层网络组成。
FFN由全连接层、激活函数和Layer Normalization组成,LN会将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛。 - Decoder部分和Encoder类似,包含两个Multi-Head Attention 层,第一个 Multi-Head Attention 层采用了 Masked 操作,最后有一个 Softmax 层。
- Conformer的大概结构:Conformer只改变了Transformer的Encoder部分。
- Conformer block是由FFN,self attention, 卷积三个Module组成的,其中每个Module上都用了残差。
(3) 聚类算法KNN、DBSCAN、k-means
KNN
K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类,就把该输入实例分类到这个类中。(这就类似于现实生活中少数服从多数的**)。
DBSCAN
- 核心对象:r领域内点的数量不小于minPts。比如随机从数据集中找一个点,以这个点为圆心画一个半径为r的圆,这个圆内点的数量大于等于minPts。
- 直接密度可达:如果一个点在这个圆圈内,而且这个点也是核心点,就说这个点到圆心点是直接密度可达。
- 密度可达:就是直接密度可达的“传播”。
- 算法流程
(1)扫描整个数据集,找到任意一个核心点,对该核心点进行扩充。扩充的方法是寻找从该核心点出发的所有密度相连的数据点(注意是密度相连)。遍历该核心点的 邻域内的所有核心点(因为边界点是无法扩充的),寻找与这些数据点密度相连的点,直到没有可以扩充的数据点为止。最后聚类成的簇的边界节点都是非核心数据点。
(2)重新扫描数据集(不包括之前寻找到的簇中的任何数据点),寻找没有被聚类的核心点,再重复上面的步骤,对该核心点进行扩充。
(3)直到数据集中没有新的核心点为止。数据集中没有包含在任何簇中的数据点就构成异常点。
- 算法优点:相比K-Means,DBSCAN 不需要预先声明聚类数量
- 算法缺点:高维数据计算慢;参数选择难
k-means
(4) 膨胀卷积是什么,如何解决膨胀后特征丢失的问题
- 空洞卷积就是在普通卷积核中间插0
- 使用空洞卷积一个关键原因就是可以增大感受野,这样在检测、分割任务中就能对大尺寸物体表现出较好的效果
- 空洞卷积中引入膨胀率 dilation_rate 的概念,膨胀率代表将原来的一个元素扩展到多少倍,扩展后的卷积核尺寸 = dilation_rate*(kernel_size - 1)+1
- 空洞卷积的缺陷主要体现在存在栅格效应
- 可以看到,连续使用三次r=2的空洞卷积会导致中间有很多空格,即很多像素没有利用到,这会导致出现栅格效应
- 解决:使用了不同膨胀因子的空洞卷积,这样就能有效解决空洞卷积网格效应的问题
(5) BN和LN的区别,什么时候用BN,什么时候用LN
- BN:对一个batch数据的每个channel进行Norm处理,因此在小batch上的效果较差。举个例子:该批次内有十张图片,每张图片有三个通道RGB,每张图片的高宽是 H、W,那么R通道的均值就是计算这十张图片R通道的像素数值总和再除以 10HW ,其他通道类似,方差的计算也类似。
- LN:对单个数据的指定维度进行Norm处理与batch无关。
- 想象成一个表格的话,BN就是对所有数据的同一列进行Norm处理,LN就是对一行数据的某几列进行Norm处理。
- LN是主要用于NLP领域的,针对一句话进行缩放的,且LN一般用在第三维度,如[batchsize, seq_len, dims]中的dims,一般为词向量的维度。这一维度各个特征的量纲应该相同,因此也不会遇到上面因为特征的量纲不同而导致的缩放问题。
(6) 训练模型时,如何让一部分参数更新,一部分参数冻结,tensor.detach()是什么
- 当我们再训练网络的时候可能希望保持一部分的网络参数不变,只对其中一部分的参数进行调整;或者值训练部分分支网络,并不让其梯度对主网络的梯度造成影响,这时候我们就需要使用detach()函数来切断一些分支的反向传播。
- 如果A网络的输出被喂给B网络作为输入, 如果我们希望在梯度反传的时候只更新B中参数的值,而不更新A中的参数值,这时候就可以使用detach()。
a = A(input)
a = a.deatch()
out = B(a)
loss = criterion(out, labels)
loss.backward()
- 如果想通过损失函数反向传播修改A网络的参数,但是不想修改B网络的参数,这个时候应该使用Tensor.requires_grad:
for param in B.parameters():
param.requires_grad = False
OCR标注、训练、测试全流程
PyTorch 多机多卡分布式训练
A. 机器环境搭建
1. 在服务器上拉取镜像 docker run -d -it --gpus=all --net=host --ipc=host --name=dp -e NVIDIA_DRIVER_CAPABILITIES=compute,utility -v /data:/data1 videosub:1.0 /bin/bash
2. 进入容器 docker exec -it dp /bin/bash
,进入 /data1 下新建文件夹 mkdir wangyin
3. 下载Anaconda,wget https://repo.anaconda.com/archive/Anaconda3-5.3.0-Linux-x86_64.sh
,这时候应该会报错找不到wget,所以下载wget:apt-get install -y wget
4. 然后执行下面两个命令:
chmod +x Anaconda3-5.3.0-Linux-x86_64.sh
./Anaconda3-5.3.0-Linux-x86_64.sh
5. 点击回车,输入yes,当看到下面的信息时,输入当前路径 ./data1/wangyin/
6. 继续点击回车和yes,检测是否安装成功,重新进入docker容器,然后输入 conda
7. 创建虚拟环境 conda create -n pd python=3.7
,进入环境 conda activate pytorch
,
下载CUDA 11.7版本的pytorch pip install torch==1.13.0+cu117 torchvision==0.14.0+cu117 torchaudio==0.13.0 --extra-index-url https://download.pytorch.org/whl/cu117
参考:
B. PyTorch 多机多卡分布式训练
1. 训练代码
import os
import torch
import torch.nn as nn
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP
import torchvision
import torchvision.transforms as transforms
import argparse
BATCH_SIZE = 64
EPOCHS = 5
class ToyModel(nn.Module):
def __init__(self):
super(ToyModel, self).__init__()
self.net1 = nn.Linear(10, 10)
self.relu = nn.ReLU()
self.net2 = nn.Linear(10, 5)
def forward(self, x):
return self.net2(self.relu(self.net1(x)))
def train(args):
local_rank = int(os.environ["LOCAL_RANK"]) + args.gpuid
rank = int(os.environ["RANK"])
torch.cuda.set_device(args.gpuid)
print(f"[{os.getpid()}] (rank = {rank}, local_rank = {local_rank}) training...")
# 1. define network
net = torchvision.models.resnet18(pretrained=False, num_classes=10)
model = net.cuda(local_rank)
ddp_model = nn.DataParallel(model, [local_rank], output_device=local_rank)
# 2. define dataloader
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
download=True, transform=transform)
train_sampler = torch.utils.data.distributed.DistributedSampler(
trainset,
rank=rank
)
train_loader = torch.utils.data.DataLoader(
trainset,
batch_size=BATCH_SIZE,
shuffle=False,
num_workers=0,
pin_memory=True,
sampler=train_sampler,
)
# 3. define loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(
ddp_model.parameters(),
lr=0.01 * 2,
momentum=0.9,
weight_decay=0.0001,
nesterov=True,
)
if rank == 0:
print(" ======= Training ======= \n")
# 4. start to train
total_step = len(train_loader)
ddp_model.train() # 标记为训练模式,推理时使用 net.eval()
for ep in range(1, EPOCHS + 1):
train_loss = correct = total = 0
# set sampler
train_loader.sampler.set_epoch(ep)
for idx, (inputs, targets) in enumerate(train_loader):
inputs, targets = inputs.cuda(local_rank), targets.cuda(local_rank)
outputs = ddp_model(inputs)
loss = criterion(outputs, targets)
optimizer.zero_grad() # 将梯度归零
loss.backward() # 反向传播计算得到每个参数的梯度值
optimizer.step() # 通过梯度下降执行一步参数更新,optimizer只负责通过梯度下降进行优化,而不负责产生梯度,梯度是tensor.backward()方法产生的。
train_loss += loss.item()
total += targets.size(0)
correct += torch.eq(outputs.argmax(dim=1), targets).sum().item()
# 输出loss 和 正确率
if (idx + 1) % 64 == 0 and rank == 0:
print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(
ep,
EPOCHS,
idx + 1,
total_step,
loss.item())
)
if rank == 0:
print("\n ======= Training Finished ======= \n")
def run():
parser = argparse.ArgumentParser()
parser.add_argument('-g', '--gpuid', default=2, type=int, metavar='N')
args = parser.parse_args()
env_dict = {
key: os.environ[key]
for key in ("MASTER_ADDR", "MASTER_PORT", "WORLD_SIZE", "LOCAL_WORLD_SIZE")
}
print(f"[{os.getpid()}] Initializing process group with: {env_dict}")
dist.init_process_group(backend="nccl")
train(args)
dist.destroy_process_group()
if __name__ == "__main__":
run()
2. 使用torchrun启动训练
在第一个机器上输入命令
torchrun --nproc_per_node=2 --nnodes=2 --node_rank=0 --master_addr="192.168.1.176" --master_port=1234 dp.py --gpuid=5
在第二个机器上输入命令
torchrun --nproc_per_node=2 --nnodes=2 --node_rank=1 --master_addr="192.168.1.176" --master_port=1234 dp.py --gpuid=1
--nproc_per_node=2
代表每个机器所用GPU的数量,--nnodes=2
代表一共有几个节点(机器),--node_rank=0
代表当前节点编号,--gpuid
代表从哪个gpu开始训练
3. 如果使用单机多卡训练,需要在代码中加入(也可以使用上面的代码)
from torch.nn.parallel import DistributedDataParallel as DDP
并且将
ddp_model = nn.DataParallel(model, [local_rank], output_device=local_rank)
改成
ddp_model = DDP(model, [local_rank], output_device=local_rank)
PP-Structure基于PaddleHub Serving的服务部署
1 推理模型下载
1.1 首先需要下载OCR检测和识别的包 ch_PP-OCRv3_det_infer
和ch_PP-OCRv3_rec_infer
,
并且在 /deploy/hubserving/
中的 ocr_det/
和 ocr_rec/
的 params.py 文件中配置对应的路径:
1.2 下载表格识别的包 en_ppstructure_mobile_v2.0_SLANet_infer
,注意要下载英文的这个包,
官网提供的中文包实测无法正常使用 PP-Structure 系列模型列表。
配置到相应的 structure_table/params.py
文件中
1.3 下载版面分析的包 picodet_lcnet_x1_0_fgd_layout_cdla_infer
,配置到相应的 structure_system/params.py
文件中。
2 启动服务
2.1 CUDA_VISIBLE_DEVICES=1 hub serving start -c config_struct_sys.json
2.2 http接口测试,官网的 tools/test_hubserving.py
代码有一些错误,
我进行了一些改动,主要是在 save_structure_res
函数中。
2.3 运行http接口测试代码 python http_demo.py
,记得上传图片到minio再进行测试。
OCR标注工具使用文档
配置Anaconda3环境
1. 下载 anaconda
文件下的 Anaconda3-2023.09-0-Windows-x86_64.exe
文件
2. 解压 ocr
文件,并放到 envs
文件中
3. 解压 .paddleocr
并放到 C/user/
下
4. 打开cmd,进入conda环境ocr:conda activate ocr
5. 运行:PPOCRLabel --lang ch
操作步骤
1. 打开文件夹:在菜单栏点击 “文件” - "打开目录" 选择待标记图片的文件夹
2. 自动标注:点击 ”自动标注“,使用PP-OCR超轻量模型对图片进行自动标注。
3. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”),用户可对当前图片中模型未检出的部分进行手动绘制标记框。点击键盘Q,则使用四点标注模式(或点击“编辑” - “四点标注”),用户依次点击4个点后,双击左键表示标注完成。
4. 标记框绘制完成后,用户点击 “确认”,检测框会先被预分配一个 “待识别” 标签。
5. 重新识别:将图片中的所有检测画绘制/调整完成后,点击 “重新识别”,PP-OCR模型会对当前图片中的所有检测框重新识别。
6. 内容更改:单击识别结果,对不准确的识别结果进行手动更改。
7. 确认标记:点击 “确认”,图片状态切换为 “√”,跳转至下一张。
8. 删除:点击 “删除图像”,图片将会被删除至回收站。
9. 导出结果:用户可以通过菜单中“文件-导出标记结果”手动导出,同时也可以点击“文件 - 自动导出标记结果”开启自动导出。手动确认过的标记将会被存放在所打开图片文件夹下的Label.txt中。在菜单栏点击 “文件” - "导出识别结果"后,会将此类图片的识别训练数据保存在crop_img文件夹下,识别标签保存在rec_gt.txt中。
标注完成后 会在放图片的文件夹中出现三个文件,其中label就是我们想要的信息。
参考 https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.7/PPOCRLabel/README_ch.md
Paddle-GPU环境配置
直接pip官网的环境会有很多问题,所以拉取docker镜像来完成环境配置
1. 官网拉取docker镜像 [link],我用的是CUDA11.2
2. 列出所有镜像,使用grep进行过滤:
docker images |grep paddle
3. 给镜像改名,这里给镜像改名后原来的还在,相当于复制了一份:
docker tag paddle:latest paddle_wy:latest
4. 改名后把本地目录挂载上去:
docker run -d -it --gpus=all --net=host --ipc=host --name=wy -e NVIDIA_DRIVER_CAPABILITIES=compute,utility -v /data:/data1 paddle_wy:latest /bin/bash
5. 开启并进入容器
docker start wy
docker exec -it wy /bin/bash
船舶轨迹异常检测&关键点检测代码说明文档
A. 船舶轨迹异常点检测
1. 运行代码路径 /data1/wangyin/ADetection/
docker环境 docker exec -it paddle3 /bin/bash
或者 docker exec -it paddle_wy4 /bin/bash
2. 所有接口都使用Flask进行封装,代码在 flask_demo.py
3. 异常检测的实现分为了两种,一种是基于聚类和密度的方法,一种是基于异常条件的方法
(1)基于聚类和密度的方法
-
LOF
接口实现在flask_demo.py
中的 def lof(),其中 n_neighbors 是LOF算法的超参数,表示每个数据点有n个最近的邻居。
upload_path 表示数据集文件路径,process_csv_ship() 函数用来做数据预处理。
toxy() 函数表示将经纬度投影为平面直角坐标,LOF() 函数实现了LOF算法,返回异常点的索引index。
gis_visualization() 函数作用是轨迹可视化,输入的参数 points 表示所有得轨迹点,ec_index 表示异常轨迹点。
-
COF
与LOF同理,两个超参数 contamination 和 n_neighbors,第一个表示异常值所占的比例,第二个表示近邻数量。
-
DBSCAN
该方法是基于聚类的,DBSCAN算法可以找到样本点的全部密集区域,并把这些密集区域当做一个一个的聚类簇。
两个超参数 eps 表示数据点的邻域半径,min_samples 表示邻域中数据对象数目阈值。
(2)基于异常条件的方法
- 船舶轨迹异常点分类判定
-
异常停止点
对于AIS 序列,如果第i个点的速度大于2节(1节=1海里/小时),且第i+1个点的坐标(E,N)、速度v、航向C数据均与第i个点相同,则第i+1个点为异常停止点:
-
异常加速点
船舶最大加速度 a_max 和最小加速度 a_min 为:
对于AIS序列,根据第i个点与第i+1个点的速度以及时间差,可以计算出两点之间的加速度。
若计算所得的加速度大于最大加速度或小于最小加速度,则判定第i+1个点为异常加速点:
-
异常漂移点
按照最大行程情况,船舶自i点开始,应先进行最大加速,到达某时刻 t_m 后最大减速,使得到达i+1点的速度恰好为 v_i+1 ,此时,船舶行程为:
轨迹中的第i+1个轨迹点为异常漂移点的规则为其与第i个轨迹点之间的直线距离大于 s_max,可表示如下:
-
异常转向点
船舶从轨迹点i到轨迹点i+1的最大转向角度 ω_max 应为转向速率在时间上的积分:
对于船舶轨迹中的一个轨迹点,若其与前一个轨迹点之间的转向角度大于 ω_max,则该轨迹点为异常转向点:
-
代码实现在 fourclass()
函数中
两个超参数 design_speed 和 L,分别表示船舶的设计速度(节)和长度(米)。
stopping_point()
用来计算异常停止点
acceleration_point()
用来计算异常加速点
drift_point()
用来计算异常漂移点
turning_point()
用来计算异常转向点
gis_visualization_for_abnormalKey()
函数用来可视化轨迹,输入原始轨迹点以及四个异常点的索引。
B. 船舶关键点检测
关键点检测主要使用凸包的方法
代码实现在 keypoints()
函数中
key_point_my()
函数实现了凸包算法,输入两个参数,一个是轨迹数据路径,另一个是数据排序依据(经度、纬度、最新时间)。函数返回关键点索引index。
gis_visualization4()
函数用来可视化轨迹,输入原始轨迹点以及关键点索引。
Paddle-NLP使用记录
通用信息抽取 UIE
1 实体抽取
1.1 进入docker环境 docker exec -it paddle3 /bin/bash
1.2 下载paddlenlp pip install paddlenlp -i https://mirror.baidu.com/pypi/simple
1.3 此时运行会报错,需要执行 pip install typing_extensions==4.7.1 --upgrade
1.4 运行代码 CUDA_VISIBLE_DEVICES=4 python v1.py
text = "2月8日上午北京冬奥会自由式滑雪女子大跳台决赛中**选手谷爱凌以188.25分获得金牌!"
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.