这个文件是关于ros、linux指令,pytorch、python、onnx和相关problem的一些笔记
ROS && linux
**find: 在当前路径或指定的路径下递归地搜索文件或目录,并可以根据不同的条件进行过滤和匹配。**
```
find -name *.py find /home/dai/bev_lane_det-main -name models find /home/dai/bev_lane_det-main -mtime -1(查找最近修改的文件)
```
**locate:在系统的文件数据库中快速查找文件或目录,只要在路径中包含该文件或目录,就会返回这个路径,而不是实时搜索文件系统。常比 find 命令快速,但可能不会返回最新创建或修改的文件。**
```
都不带*,且无法加指定路径,它是自己全文搜索: locate single_camera_bev locate libprotoc
```
**whereis:查找系统中某个可执行程序,即命令的位置、源代码文件和帮助文档,也就是bin下的文件等等**
```
whereis ls
```
**which:查找系统中某个可执行程序,即命令的位置,也就是bin下的文件**
```
which ls
```
gnome-session-properties 开机自启
`catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3`
`src目录下:catkin_create_pkg sys_time roscpp rospy std_msgs`
**ros中的rospy使用虚拟环境、包的方法:**
```
#!/home/dai/anaconda3/envs/clrnet/bin/python
import sys
sys.path.append('/home/dai/anaconda3/clrnet/lib/python3.8/site-packages');
终端运行时要conda activate clrnet
其cmake中(不用excutable、target_link):
catkin_install_python(PROGRAMS
scripts/rstest.py
scripts/sub.py
scripts/tes.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
add_message_files( ##(ros_laneatt、robotyolo的cmake中有)
FILES
Xyz_Boundings.msg
Xyz_Boundings_List.msg
)
```
此时若是py:from rsyolo.msg import Xyz_Boundings 若是cpp:#include <rsyolo/Xyz_Boundings_List.h>(因为自己会生成devel下面的.h文件)
注意:回调函数原型中的指针参数:表示指向消息对象的指针,而不是对象地址的指针
cmake.. 生成makefile, make:在文件夹内构建,sudo make install,安装在系统内(好处: 为了好找,同时可以删除源码包了),有时候可以就安装文件夹内(不影响系统可多版本,cmake找的时候就: set (FCL_DIR "/home/dai/fcl-0.6.0")
include_directories(${FCL_DIR}/include)
link_directories(${FCL_DIR}/build/lib)
find_package(fcl REQUIRED)
)
grep -R "ContainerAllocator" /home/dai/ros_deploy_lanedec/ROS_LaneDetection/src/ROS_LaneATT/ | grep -v "<ContainerAllocator>" 搜索包含"ContainerAllocator"的行,然后过滤掉包含"<ContainerAllocator>"的行。
grep -rn "@TRANSFORMER" /home/dai/LATR-main/ 想查找文件中包含 "@transformer" 文本的文件
-r 选项表示递归搜索,它会搜索指定目录下的所有子目录。
-n 显示匹配得到的具体的行数
-l 选项表示仅列出包含匹配文本的文件的名称,而不显示匹配的具体行。
创建软链接: 可用于数据集等的链接,不用再复制过来了省了空间:
cd new_workspace/data/
ln -s /home/dai/bev_lane_det-main/dataset/apollo/data_splits/
find /etc -name passwd | ls -l |表示管道符,表示将find到的文件传入后面的指令中,通常不用|,因为不适配很多命令
find /etc -name passwd | xargs ls -l xargs:表示传递参数 传递到后面的命令中
grep :文本搜索工具,根据用户指定的"模式(过滤条件)"对目标文本逐行进行匹配检查,打印匹配到的行.
find /path | xargs grep "string" # 将find查找的所有文件 作为参数传递给 grep进行过滤字符串,也就是文字
sudo find / -iname "*opencv*"w : find ~/bevlanedet/ -iname 'apollo*' -i通常表示不区分大小写
netstat -apn | grep client 查看客户端网络连接状态
netstat -apn | grep port 查看端口的网络连接状态
nc 127.1 9527 创建虚拟的IP+port,给网络编程的创建cs模型用的
ps ajx: 查看后台进程
ifconfig
录屏 shift ctrl alt r
.rviz配置参数 是从Alpha 到 value的
查看rosbag坐标系: rostopic echo /velodyne_points | grep frame_id 要在rviz显示,各种class,也就是各种消息的frame_id要一致
//获取参数服务器上(也就是launch中或yaml中)的参数,获取到参数的值后赋值给后面的参数,如果没有,就对后面的参数使用默认值,eg:
private_nh.param("use_map", use_map, false);
rosparam set rosparam get 同上,即从参数服务器上get(赋给后面)或set(对该名字的参数值进行set)
<remap from="~map" to="/global_map"/> 重映射 话题、服务或参数名称 ~表示引用节点私有命名空间下的(也没啥)
对应的,/global_map表示全局命名空间,话题通常加/,不加则表示相对于节点的私有命名空间,则话题变为:/node/global_map(rostopic list 可以看出差别)
rosservice list:list; rosservice list -n :list(node); rosservice info service_name:information;
rosparam list
rostopic type topic_name rostopic list -v: list(node)
pkill 用于杀死一个进程,与 kill 不同的是它会杀死指定名字的所有进程 : pkill -f system_real_robot.launch
kill PID、kill -9 PID 根据id杀死进程,pkill更好用点
全编译:catkin_make -DCATKIN_WHITELIST_PACKAGES="" 出现复制别人文件编译时有问题的情况,需要:删掉上锁的cmakelists文件,再catkin_init_workspace
watch -d -n 0.1 nvidia-smi 观看gpu内存变化 -d表示对变化的进行高亮 、 -n 后为秒
firefox -profilemanager 打开firefox 设置打开firefox的profile
机器的 CPU 数量可通过命令 cat /proc/stat | grep cpu[0-9] -c 我的:16
locate xxx.h
pcl:gedit /usr/lib/x86_64-linux-gnu/cmake/pcl/PCLConfigVersion.cmake
pkg-config opencv4 --libs 库地址
pkg-config opencv4 --modversion 版本
torch.set_printoptions(threshold=np.inf)
np.set_printoptions(threshold=np.inf)
调用摄像头:直接 roslaunch usb_cam usb_cam-test.launch
运行命令 sudo nautilus 就可以打开一个具有管理员权限的文件管理器,然后就可以在不切换到管理员的条件下拷贝文件
tensorrt 安装到csdn收藏的tensorflow 处(tf还没有装)
ikuuu.org ./clash -d . chomd +x xxx chmod 777 xxx
chmod +x xxx ./clash -d .
uname -a 查看电脑架构
sudo su cp/mv 源文件 目标文件 unzip/zip filename.zip dpkg -i/-p filename find *.cpp find ???.cpp
rosnode list rostopic info
chmod 777 filename ping template<typename>T1 template<class T2,class t3> 实例化:Student<int,double>student1
vim: i编辑 :wq! 保存并强制退出 Vim 编辑器 :q! 不保存,且强制退出 Vim 编辑器 u:撤回 ctrl_r反撤回 dd ndd删除 y nyy 复制 p P粘贴 i 编辑 x删除
gcc: gcc -c filename 汇编 gcc filename.cpp -o hello ./hello 生成可执行
}
ffplay -autoexit w4.mp4
ctrl alt - vscode代码导航后返回 crtl shift left, pycharm代码导航后返回
返回进入此目录之前所在的目录 cd -
c++ : stoi: string型变量转换为int型变量 stol: string型变量转换为long型变量 stoul:string型变量转换为unsigned long型变量
stoll: string型变量转换为long long型变量(常用) stoull:string型变量转换为unsigned long long型变量 stof: string型变量转换为float stod: string型变量转换为double型变量(常用) stold:string型变量转换为long double型变量
deep-learning:
pip list | grep torch
kill -9 PID
torch==1.8.0
torchvision==0.9.0
prime-select query 查看目前的显卡使用模式
ls /usr/src | grep nvidia 查看已安装驱动版本信息
conda install pytorch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0 cudatoolkit=11.1 -c pytorch -c conda-forge
pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113 加cu对应到版本(不加cu就不行,就会安装其他版本cuda 如10.2)
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=11.3 -c pytorch
pip uninstall torch
#创建名为your_env_name的环境
conda create --name your_env_name
#创建制定python版本的环境
conda create --name your_env_name python=2.7
conda create --name your_env_name python=3.6
#创建包含某些包(如numpy,scipy)的环境
conda create --name your_env_name numpy scipy
#创建指定python版本下包含某些包的环境
conda create --name your_env_name python=3.6 numpy scipy
删除虚拟环境:
conda remove -n your_env_name --all
conda remove --name your_env_name --all
#查看--安装--更新--删除包
conda list:
conda search package_name# 查询包
conda install package_name
conda install package_name=1.5.0
conda update package_name
conda remove package_name
退出创建的虚拟环境
source deactivate your_env_name
#pycharm:
tensorboard --bind_all --logdir=tensorboard/laneatt_r34_tusimple 用tensorboard显示loss曲线 注意是/ 在ws下,后面是路径,因为tensorboard为2.3.0 所以加了--bind_all 才行
tensorboard --logdir=logs --port=6007 输出再制定端口下
{:04d}:保留4位整数,前面位补0。eg:34 - > 0034
Ctrl+Shift+Backspace 导航到最近编辑区域
import torch.cuda
print(torch.cuda.is_available())
print(torch.version.cuda)
print(torch.version)
print(torch.cuda.get_arch_list())
import torch
from torch.backends import cudnn
print(cudnn.is_available())
print(torch.backends.cudnn.version()) 查看torch下的cudnn版本 这是在安装cudatoolkit时默认对应的版本
print(torch.cuda.device_count())
ls -l /usr/local | grep cuda 查看该目录下有哪些cuda版本 ->表示软连接 ,表示当前使用的是cuda-11.3版本。
如果当前机器上安装了多个cuda版本,可以使用修改软链接的方式来修改系统使用的cuda版本,命令如下:sudo ln -snf/usr/local/cuda-8.0/usr/local/cuda(还是别用这个吧,还是在bashrc中修改) :这种应该cudnn不会变 还是用cuda中的 或者修改bashrc
cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2 查看系统cuda的cudnn版本
现存 cuda:11.3: cudnn:8.4.1
cuda-11.3: cudnn:8.4.1 不敢乱改为8.2.0
cuda-11.7:cudnn:8.4.1 听说向下兼容, 是不是可以conda install pytorch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0 cudatoolkit=11.1 -c pytorch -c conda-forge 试一试
好像是可以的
换成pip:pip install torch==1.8.0+cu111 torchvision==0.9.0+cu111 torchaudio==0.8.0 -f https://download.pytorch.org/whl/torch_stable.html
#python:
5-8:加载模型:
1:torch.save(model, "xx/xx/xx.pth") -> torch.load("xx/xx/xxx.pth") (这是模型结构+模型参数,所以内存大)一般不这个
2:torch.save(model.state_dict(), "xx/xx/xx.pth") (字典形式:模型参数) 推荐这个
-> model = .get_model(实例化模型)
model.load_state_dict(torch.load("xx/xx/xx.pth"))
fp16是指采用2字节(16位)进行编码存储的一种数据类型;同理fp32是指采用4字节(32位);
son.load()从json文件中读取数据
json.loads()将str类型的数据转换为dict类型 json->pythonz
json.dumps()将dict类型的数据转成str python->json
json.dump()将数据以json的数据类型写入文件中
read() 所有的数据一次性读取出来, data的数据类型是一个字符串
readline() 读取的是一行内容, 然后是带换行符的, 所有会有空行, 后续会说明如何去掉换行符"\n".
readlines() 读取的是一个列表, 注意换行符是包含在字符串的内容中
action='store_true': default的优先级更高,有default就看default。即默认就为default,指定如python test.py --save_predictions 就相反为false
无default时:默认即false,指定python test.py --save_predictions即相反为true
action='store_false' 默认值是True。需手动指定该参数,该参数才为False (相反)
torch.bmm(input1, input2) 只能三维 对后两位作矩阵运算
a[起点::步距] 当步距为负数时,则为倒叙。无起点时,则从start或end为起点(由正负判断) 三维b [..., 0] = b[:, :, 0] 表示 只要第0列的 b[..., 0, :] = b[:, 0] 表示只要第0行的
Image.open或cv.imread(这个不确定)还有load等,好像是这样 :同级目录可以直接读取,非同级就要相对读取,即使它在ws下也要相对读取,或者使用绝对路径
from和import都要从根开始 用.递进 from.XXX 即同级目录下 from.. 即上级目录下(最好使用绝对路径,即从ws开始from,不要用相对,问题多,相对是要在包里面才能这样写) 不要数字命名python文件 无法import import要么同级、要么ws根目录的文件(from同级需要加.) 若是文件夹下 需要新建空的init文件 表示package
import: 同级引用同级或ws下 ,相对有问题就换成ws下的路径(半绝对)
figure, axes = plt.subplots(num_rows, num_cols, figsize=figsize) 创建多个子图
train_loss_sum += loss.cpu().item() 得到一个batch的loss的和
不要同名复制 如(loss = loss(y_hat, y), loss.backward()) 容易出事
%d:int, %s:char, %.几f:float,保留几位小数
blockneck 瓶颈结构 getitem :p[k]
fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red'))
plt.rcParams['figure.figsize'] = figsize
plt.Rectangle
figure, axes = plt.subplots(num_rows, num_cols, figsize=figsize)
output_features = list(map(id, pretrain_net.fc.parameters()))
feature_params = filter(lambda p: id(p) not in output_features, pretrain_net.parameters()), id(p) not in output_features这个就是返回的
optimizer = optim.SGD([
{'params':feature_params},
{'params': pretrain_net.fc.parameters(), 'lr': 0.1}
], lr=0.01, weight_decay=0.001)
array = np.array(pairs)
base_anchors = np.stack([-ssw, -ssh, ssw, ssh], axis=1) / 2 # 列上拼接 、自动转换, rehsape、unsqueeze(错位相加、相乘)
shift_x, shift_y = np.meshgrid(shifts_x, shifts_y) # 生成图布内所有坐标点 分别得到x、y坐标
unsqueeze: 重要性,在对应相加相乘时,同即可,在错位相加相乘时,需不同 有返回 需要 = 接收 并且广播机制也是因为他,因为对+一,一已经降维,需要unsqueeze
torch.full 创建一个大小,值全为fill_value的张量。张量的dtype是从fill_value(可以是bool)推断出来.
torch.nonzero 返回非0的idx torch.nonzero(max_ious >= iou_threshold)
np.concatenate = torch.cat
uniques, counts = combined.unique(return_counts=True) non_keep = uniques[counts==1]
class_id[non_keep] = -1 class_id = class_id[all_id_sorted]
x2), dim=1), 一般dim=几,表示维度上的dim会进行变换或消失,如torch.max(a, dim=1)
iter(train_iter).next() iter列表迭代器 用next得到列表迭代其的第一个等
print(len(bbox.shape))
reduction='none':会输出一个形状为 (batch_size, num_classes) 的矩阵,表示每个样本的每个类别的损失
reduction='sum' 时,函数会对矩阵求和,输出一个标量,表示所有样本的损失之和
reduction='mean' 时,函数会对矩阵求平均,输出一个标量,表示一个batch中样本的平均损失
mae:平均绝对误差
l.mean().backward() # 一个batch的平均损失 反响传播只能以标量的隐式创建 所以有的需要mean
用Image 和 imread读到的图片数值在0-255之间 送入网络'通常'需要归一化处理:/255 -> np.array(img) (Image时) -> 然后转为tensor:torch.from_numpy(img), 如果只是show则都不用
空洞卷积 : dilation
nn.embedding: (num_embedding:输出个数, dim:维度) 该层只有一个参数 : .weight: 已标准化的参数 ,输入为离散的num_embedding(torch.arrange(num_embedding),输出得到还是原大小(num_embedding:输出个数, dim:维度),这也就是不同于linear的地方,linear:为输入为num_embedding个向量
zip([256] + [256] * 2, [256] * 2 + [4]); [1].append([2]),[1, [2]], 而[1] += [2],为[1, 2]
y / (y[:, -1:, :]) 运算(+ - * /)维度个数要相同 y[:, -1:, :]:三维 y[:, -1, :] 两维 y[:, -1:, :]其中-1:非常讲究 有冒号:则维度没有下降 -1:则其为1行 ,如果-2:, 2:, :2都不止为1
nn.conTranspose2d(in,out,k,p,s) :参数填写原来卷积con2d的参数即可(这句话错误,应根据后面这句话),如果不知道,需要自己计算:k=2p+s, (原x-k+2p)/s + 1 =现x
指定卷积核的权重(应该不算指定输出形状):conv.load_state_dict({'weight': K}) 其中conv = nn.Conv2d(in, out, k, bias=False) 则相应k应为:(out, in, k, k)
仅仅copy值:conv_trans.weight.data.copy_(bilinear) 不决定形状
math.ceil() 向上取整 round() 四舍五入
logger = logging.getLogger(name) logger.info() 输出是在logger 创建用logging.basicConfig logging.FileHandler .setLevel .setFormatter
x.repeat(2, 3, 4) 0维复制2两次 1维复制3次 2维复制4次(对应复制, 多余则往前不往后) x.repeat_interleave(3, 0) 将0维复制三次:[c, d] -> [c, c, d, d]
- 均匀分布 torch.nn.init.uniform_(tensor, a=0, b=1) 2. 正太分布torch.nn.init.normal_(tensor, mean=0, std=1) 3. 初始化为常数torch.nn.init.constant_(tensor, val) 4 预防一些参数过大或过小的情况,再保证输入输出的weight方差一样的情况下进行缩放,便于计算torch.nn.init.xavier_uniform_(tensor, gain=1.0)
FCN FPN FFN reg-loss 用的nn.smothloss :平滑loss:L1和L2 loss的结合
print(priors[:, 3].shape) :[192], print(priors[:, 2:3].shape :[192, 1], 这样是会保留多一个维度的
MACs模型复杂度(会根据输入变化),Params模型参数量(模型的固定量) code :/hfome/dai/LaneATT_lib_/unet_522.py 里面
装网络时,要self.net = nn.ModuleList()或者self.net = nn.Sequential(),不能用self.net = [] 来装
torch.gather(a=[[1, 2], [3, 4]], 0, b=[[0, 0], [1, 0]]),因为为0,所以后面b的数字表示行数,列数则由自身位置表示,即[0][0] = [0][0] =1,[1][0] = [1][0] = 3
np.where(inputs > thre):以array的形式返回n组坐标,每组代表一个维度,类似于meshgrid的返回
x = F.conv2d(x, weight=w, bias=b, stride=1, padding=0, groups=3)
is_cuda, x = x.to(torch.devide('cuda')) 要有返回接收才行,关于x.cuda还没有弄清楚,网络因为继承nn可以to(device), 创建的一般用device=device
去除tensor指定行列:a = a[:, torch.arange(a.size(1)) != 3]
dict 的 update方法:类似于list的extend方法,即尾接dict的元素
id = [5] list(map(student, id)),相当于把id的所含参数传入student这个类,进行实例化,但id要以list的方式传入
在tensor中取元素或tuple: 取元素:a[-2].item(), 取元素做tuple或list:a.tolist()[-2:]
assert expression, 'message ',一般是assert一个表达式,如assert a==b,用来判断表达式
assert len(kwargs) == 4, '参数必须是4个'
if 'name' not in kwargs:
raise ArgsError('缺少姓名参数') raise 则用来抛出指定异常
try-exception,表示try能走通不报错,就走,否则就会走exception的报错
try:
num1 = int(input("请输入被除数:"))
num2 = int(input("请输入除数:"))
result = num1 / num2
except ZeroDivisionError:
print("除数不能为0,请重新输入!") 总结:三者差距不大 特别是后两者,都用来抛出指定异常
math.isclose(a, b)、np.allclose(a, b) 判断a、b是不是几乎相等
with open('filename', 'r') as f: r:读文件 w:重写文本文件 wb:重写二进制文件 a:追加写文本文件
nn.Conv2d:类 接口,实例化和前向,F.conv2d(x...),函数接口,直接传入输入,得到输出,一般大写为类接口,小写为函数接口
x.numel() 、torch.numel(a) a的元素个数 元素数量
exit() 放在执行部分,可以不执行后续,类似于断点
仅当p为tensor或array时,可以p>0,从而输出T、F, list则不行
print(f'y = {y}') print('y = {}'.format(y)) 输出的方式 试着用前者 相比于print('y', y) 更加直观
@ :当@连接的两项为矩阵时:m×n)维×(n×y)维 =(m×y)维; @连接的两项一项为矩阵,一项为数组时(m×n)维×(1×n)维 =(1×m)维
clrnet:
使用指定的GPU及GPU显存 os.environ["CUDA_VISIBLE_DEVICES"]
','.join()以指定的字符(分隔符)连接生成一个新的字符
@property 将方法变成属性调用,调用时不加括号,并且它的属性类似私有属性,无法进行赋值,由构造函数就定好 def repr(self)当直接打印类的实例化对象时,系统将会自动调用该方法,输出对象的自我描述信息,用来告诉外界对象具有的状态信息 def str(self),好像和repr类似
@staticmethod:可以在不实例化的情况下从类中调用该方法,没有self参数,且无法用任何init的参数,就跟一个扎根在类中的外部函数一样。
@classmethod:可以在不实例化的情况下从类中调用该方法,没有self参数,但需要一个'cls'参数,且可以用类的属性,方法,可以用init的参数
eval :接收运行一个字符串表达式,返回表达式的结果值。一定是字符串 一定是表达式 因为eval本身没啥用 就是output一下
.pop 删除并返回字典或列表的一个元素 字典就返回指定key的value
inspect.isclass bool
构造的函数里的self. 也为构造的东西
一种采样方法, 类似放射变换:grid_sample((16, 64, 10, 25), (16, 192, 32, 2(必须为2)), align_corners=True) -> [16, 64, 192, 32] 输出其值来自于:输入input的(x,y)中 的四邻域插值得到的
*和**分别是用于tuple和dict的,都有两个场景,分别是作为打包参数和解包参数使用(详细csdn自己艘),就是拿出tuple的值和dic的value进行传入或取出
torch.set_printoptions(threshold=np.inf) 打印tensor防止省略,打印完整
img在dataloder时,经过totensor会自动走归一化的操作,即数据大小在0-1之间
import torchvision.transforms as t
1:归一化在totensor后面,2:如果用cv2读图片,要用transform就要先用ToPILImage转成pil的 3:如果Normalize了,可视化时你是无法恢复原来的样子的
trans_image = t.Compose([
t.ToPILImage(),
t.Resize((input_shape[0], input_shape[1])),
t.ToTensor(),
t.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))])
trans = trans_image(img)
转回去: ,因为ToTensor最自动除255归一,所以要* 255(好像不一定,要自己试),且要uint8无符号
trans = (trans * 255).permute(1, 2, 0)
trans = (trans.cpu().numpy()).astype('uint8')
trans1 = cv2.resize(trans, (1920, 1080)) # 会变糊
cv2.imshow('11', trans)
cv2.waitKey(5000)
canvas = np.expand_dims(canvas, axis=0).repeat(3, axis=0) 这个np的等价于 torch的expand
torch.set_printoptions(threshold=numpy.inf) 设置 将 tensor 完全显示 不省略
( 3, 144, 256) 和 (3) 相乘 result = tensor1 * tensor2[:, None, None] :是通道对应相乘, tensor1 * tensor2[None, None, :] :列维度对应相乘
a.size = [4,5,3] b.size = [4,5] a[b] = c c为[3] : mask = img[0] == i img[mask] = [255, 0, 0]
deploy:
onnx:
/home/dai/pytorch_deeplearining/code/moxingbushu_1.py (用图片等进行测试模型详见文件中, 算子转换详见4, 裁减onnx模型详见5)
netron(可视化onnx模型):https://netron.app/ pip install netron netron xxx.onnx
onnx转换和推理测试的工具trtexec 不明白如果一个指令就可以,为什么还要写这么多代码呢
trtexec --onnx=static.onnx --saveEngine=static.engine
trtexec --loadEngine=static.engine 测试推理
trtexec --loadEngine=static.engine --duration=1000 持续
trtexec --onnx=dynamic.onnx --minShapes=x:1x1x3x3 --optShapes=x:50x1x3x3 --maxShapes=x:100x1x3x3 动态batch
trtexec --loadEngine=dynamic.engine --shapes=x:100x1x3x3 测试推理
# 这里相当于要给一组输入,这个输入x的大小要和我们的输入大小要一致 让模型跑起来, 这也就解释了为什么要配对的原因
model = MODEL()
state_dict = torch.load('srcnn.pth')['state_dict']
model.load_state_dict(state_dict)
dynamic_axes={"input.0": {0:"batch"}, "input.1": {0:"batch"}, "output.0": {0:"batch"}}
torch.onnx.export(model, x, "srcnn.onnx", opset_version=11, # ONNX 算子集的版本
input_names=['input'], output_names=['output'],
dynamic_axes={'input': {0: 'batch0', 2: 'batch2', 3: 'batch3'},
"input.0": {0:"batch"}, "input.1": {0:"batch"}, "output.0": {0:"batch"},# 动态size的位置,关系输入着x要不要固定 但是一般只指定batch为动态
'output': {0: 'batch00', 2: 'batch22', 3: 'batch33'}})
export后跟一句用来保存尺寸变化用来可视化:onnx.save(onnx.shape_inference.infer_shapes(onnx.load("model.onnx")), "model.onnx")
ort_session = onnxruntime.InferenceSession("srcnn.onnx") # 用onnxruntime推理引擎测试 onnx模型
ort_output = ort_session.run(['output'], {'input': input_img})[0] # 后者为字典,且有'input',对因之前
onnx(不同于torch.onnx)的model有gragh计算图,计算图graph有node、input, output 等,之前torch.onnx.export(['input'], ['output']),这两个名称是对应后面的读取的
problem:
'builtin_function_or_method' object has no attribute 可能没给方法加括号
pycharm报错:无法下标:看看是不是size和shape的问题 需要换着使用size
关于pycharm一直indexing导致卡: File->Setting->Project->Project Structure->Exclude 一些文件夹 如dataset
pycharm run出现Empty suite: py文件不要用test为首进行命名。
RuntimeError: CUDA error: no kernel image is available for execution on the device:这是torch的cuda版本和nvcc的不对应,太低了,比如我的就不支持10的cudatoolkit
若出现model = model.to(device) 这一步卡吨的,可以换成pip进行安装的torch和cudatoolkit
绝对路径出现问题:
from lanenet_model import lanenet
ModuleNotFoundError: No module named 'lanenet_model'
在代码中加上: import sys
sys.path.append('/home/dai/lanenet-lane-detection-master/')
踩坑problem:测试时model.eval的效果没有model.train的效果好,或者说model.eval完全就没有效果了
原因:可能是训练反复设置model.eval、model.train,batch太小等的原因