MedSAM 项目排坑记录

MedSAM 项目排坑记录

  • 任务
  • 排坑过程
    • 配置python环境
    • 测试
    • 构建docker
    • 模型训练
      • 数据预处理
    • 单GPU训练
    • 最后推理

任务

做一个课程大作业,需要进行CVPR2024年医疗影像分割赛题的打榜(CVPR 2024: SEGMENT ANYTHING IN MEDICAL IMAGES ON LAPTOP)。看到官方给了一个baseline,也就是这个MedSAM,决定先在我本地把这个baseline跑出来试试效果。

排坑过程

配置python环境

创建conda环境:

conda create -n MEDSAM python=3.10 -y
conda activate MEDSAM

安装pytorch:

pip3 install torch

中间竟然报错我磁盘空间没有了。害,存的数据集太多了。清理了一点,还有点暂时舍不得清理。主要是有一个去年上智能机器人课时候,跑SLAM算法大作业时下载的KITTI数据集和其他几个数据集,占了400多G空间,还有之前下载的HM3D数据集100多G。打算这两天把那个项目代码再跑一遍,上传到平台上,然后把本地的删除。以后可能还要下载很多数据集,打算下血本买个西数的p40 2T硬盘。正好我电脑有雷电4接口,能发挥硬盘宣称的2000M速度。

克隆项目:

git clone -b LiteMedSAM https://github.com/bowang-lab/MedSAM/

其中-b是指定分支branch。
安装项目包:

pip3 install -e .

据这个博客参考博客所说,这个命令就是将当前项目以软链接并且可修改的形式安装到当前python环境中,具体来说就是执行setup.py脚本。

然后经典报错:

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
rosdep 0.22.2 requires catkin-pkg>=0.4.0, which is not installed.
rosdistro 0.9.0 requires catkin-pkg, which is not installed.
rosinstall 0.7.8 requires catkin-pkg, which is not installed.
rosinstall-generator 0.1.23 requires catkin-pkg>=0.1.28, which is not installed.
rospkg 1.5.0 requires catkin-pkg, which is not installed.
rospkg 1.5.0 requires distro>=1.4.0; python_version >= "3.8", which is not installed.

安装就好:

pip3 install empy==3.3.4 rospkg pyyaml catkin_pkg

测试

先要下载模型参数。打开work_dir/LiteMedSAM这个目录,发现里面有个readme,点开其中的链接,从那个链接的谷歌云盘上下载下来,放到这个目录就行。

接着下载示例数据,从那个here点进去,下载三个谷歌云盘文件。然后把他们放到test_demo这个文件夹下面。

最后运行推理脚本:

python CVPR24_LiteMedSAM_infer.py -i test_demo/imgs/ -o test_demo/segs

结果为:
在这里插入图片描述
感觉跟没跑一样。
看代码:

if __name__ == '__main__':
    img_npz_files = sorted(glob(join(data_root, '*.npz'), recursive=True))
    print(img_npz_files)
    efficiency = OrderedDict()
    efficiency['case'] = []
    efficiency['time'] = []
    for img_npz_file in tqdm(img_npz_files):
        print('in')
        start_time = time()
        if basename(img_npz_file).startswith('3D'):
            MedSAM_infer_npz_3D(img_npz_file)
        else:
            MedSAM_infer_npz_2D(img_npz_file)
        end_time = time()
        efficiency['case'].append(basename(img_npz_file))
        efficiency['time'].append(end_time - start_time)
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print(current_time, 'file name:', basename(img_npz_file), 'time cost:', np.round(end_time - start_time, 4))
    efficiency_df = pd.DataFrame(efficiency)
    efficiency_df.to_csv(join(pred_save_dir, 'efficiency.csv'), index=False)

我打印出img_npz_files,发现是空列表。说明没读到文件啊。然后发现我是呆比:数据都没解压缩。解压后再运行:

python /home/lcy-magic/MedSAM/MedSAM/CVPR24_LiteMedSAM_infer.py -i /home/lcy-magic/MedSAM/MedSAM/test_demo/imgs/ -o test_demo/segs

解压后长这样
这回就好了:
在这里插入图片描述

构建docker

在MedSAM目录下运行:

docker build -f Dockerfile -t litemedsam .

会用很长时间。
测试docker。先给可执行权限:

sudo chmod -R 777 ./*

然后运行:

docker container run -m 8G --name litemedsam --rm -v $PWD/test_demo/imgs/:/workspace/inputs/ -v $PWD/test_demo/litemedsam-seg/:/workspace/outputs/ litemedsam:latest /bin/bash -c "sh predict.sh"

其中PWD这个环境变量是当前路径,所以也要在在MedSAM目录下运行。
成功:
在这里插入图片描述
保存docker为一个压缩文件:

docker save litemedsam | gzip -c > litemedsam.tar.gz

时间也比较漫长。成功:
在这里插入图片描述

最后运行:

python /home/lcy-magic/MedSAM/MedSAM/evaluation/compute_metrics.py -s test_demo/litemedsam-seg -g test_demo/gts -csv_dir ./metrics.csv

没问题

模型训练

数据预处理

首先模型参数咱已经有了,应该不用再下载了。但要下载数据。在他的demo dataset链接里,下载这个压缩包:
在这里插入图片描述
然后再MedSAM文件夹下新建data文件夹,把这个压缩包放过去解压缩。
数据处理那个指令太长了,写个shell脚本吧:

touch pre_CT_MR.sh
chmod 777 pre_CT_MR.sh
gedit pre_CT_MR.sh

写入以下语句(参考:参考博客):

#!/bin/bash

~/anaconda3/envs/MEDSAM/bin/python pre_CT_MR.py \
    -img_path data/FLARE22Train/images \
    -img_name_suffix _0000.nii.gz \
    -gt_path data/FLARE22Train/labels \
    -gt_name_suffix .nii.gz \
    -output_path data \
    -num_workers 4 \
    -prefix CT_Abd_ \
    -modality CT \
    -anatomy Abd \
    -window_level 40 \
    -window_width 400 \
    --save_nii

执行脚本:

./pre_CT_MR.sh

报错:

./pre-processing.sh: 行 3: activate: 没有那个文件或目录
Traceback (most recent call last):
  File "/home/lcy-magic/MedSAM/MedSAM/pre_CT_MR.py", line 12, in <module>
    import cc3d
ModuleNotFoundError: No module named 'cc3d'
./pre-processing.sh: 行 7: -img_name_suffix:未找到命令
./pre-processing.sh: 行 8: -gt_path:未找到命令
./pre-processing.sh: 行 9: -gt_name_suffix:未找到命令
./pre-processing.sh: 行 10: -output_path:未找到命令
./pre-processing.sh: 行 11: -num_workers:未找到命令
./pre-processing.sh: 行 12: -prefix:未找到命令
./pre-processing.sh: 行 13: -modality:未找到命令
./pre-processing.sh: 行 14: -anatomy:未找到命令
./pre-processing.sh: 行 15: -window_level:未找到命令
./pre-processing.sh: 行 16: -window_width:未找到命令
./pre-processing.sh: 行 17: --save_nii:未找到命令

那就安装cc3d:

pip3 install connected-components-3d

再运行,又报错:

usage: pre_CT_MR.py [-h] [-modality MODALITY] [-anatomy ANATOMY] [-img_name_suffix IMG_NAME_SUFFIX] [-gt_name_suffix GT_NAME_SUFFIX] [-img_path IMG_PATH]
                    [-gt_path GT_PATH] [-output_path OUTPUT_PATH] [-num_workers NUM_WORKERS] [-window_level WINDOW_LEVEL] [-window_width WINDOW_WIDTH]
                    [--save_nii]
pre_CT_MR.py: error: unrecognized arguments: -prefix CT_Abd_

查看python脚本可以发现,其他参数都是读取的,CT_Abd_参数是根据其他参数拼接得到的。而且结果和命令行给出的一致。那就不再需要命令行指定了。
在这里插入图片描述

于是我简单粗暴地把这一行删掉了,再运行没问题:
在这里插入图片描述
接下来做格式转换,照样改成shell脚本:

touch npz_to_npy.sh
chmod 777 npz_to_npy.sh
gedit npz_to_npy.sh

写入:

#!/bin/bash

~/anaconda3/envs/MEDSAM/bin/python npz_to_npy.py \
    -npz_dir data/MedSAM_train \
    -npy_dir data/npy \
    -num_workers 4

运行:

./npz_to_npy.sh

结果:
在这里插入图片描述
感觉是文件路径不对,看了下文件。果然,训练数据还在下一级目录。应该把脚本改成:

#!/bin/bash

~/anaconda3/envs/MEDSAM/bin/python npz_to_npy.py \
    -npz_dir data/MedSAM_train/CT_Abd \
    -npy_dir data/npy \
    -num_workers 4

再运行就没问题了:

Converting npz to npy: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 40/40 [00:05<00:00,  7.55it/s]

单GPU训练

同样,构建脚本:

touch train_one_gpu.sh
chmod 777 train_one_gpu.sh
gedit train_one_gpu.sh

写入:

#!/bin/bash

~/anaconda3/envs/MEDSAM/bin/python train_one_gpu.py \
    -data_root data/MedSAM_train/CT_Abd \
    -pretrained_checkpoint lite_medsam.pth \
    -work_dir work_dir \
    -num_workers 4 \
    -batch_size 4 \
    -num_epochs 10

# ~/anaconda3/envs/MEDSAM/bin/python train_one_gpu.py \
#     -data_root data/MedSAM_train/CT_Abd \
#     -resume work_dir/medsam_lite_latest.pth \
#     -work_dir work_dir \
#     -num_workers 4 \
#     -batch_size 4 \
#     -num_epochs 10

如果从lite_medsam开始微调就注释下面的,如果从上次中断的训练开始微调就注释上面的。
运行:

./train_one_gpu.sh

报错:

Pretained weights lite_medsam.pth not found, training from scratch
MedSAM Lite size: 9791300
Traceback (most recent call last):
  File "/home/lcy-magic/MedSAM/MedSAM/train_one_gpu.py", line 408, in <module>
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers, pin_memory=True)
  File "/home/lcy-magic/anaconda3/envs/MEDSAM/lib/python3.10/site-packages/torch/utils/data/dataloader.py", line 350, in __init__
    sampler = RandomSampler(dataset, generator=generator)  # type: ignore[arg-type]
  File "/home/lcy-magic/anaconda3/envs/MEDSAM/lib/python3.10/site-packages/torch/utils/data/sampler.py", line 143, in __init__
    raise ValueError(f"num_samples should be a positive integer value, but got num_samples={self.num_samples}")
ValueError: num_samples should be a positive integer value, but got num_samples=0

哦,他这个readme又写错了。现在训练用的是npy数据不是npz的。所以脚本应该改成:

#!/bin/bash

~/anaconda3/envs/MEDSAM/bin/python train_one_gpu.py \
    -data_root data/npy \
    -pretrained_checkpoint lite_medsam.pth \
    -work_dir work_dir \
    -num_workers 4 \
    -batch_size 4 \
    -num_epochs 10
    
# ~/anaconda3/envs/MEDSAM/bin/python train_one_gpu.py \
#     -data_root data/npy \
#     -resume work_dir/medsam_lite_latest.pth \
#     -work_dir work_dir \
#     -num_workers 4 \
#     -batch_size 4 \
#     -num_epochs 10

再次运行,报错:

torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 36.00 MiB. GPU 0 has a total capacity of 7.79 GiB of which 47.56 MiB is free. Including non-PyTorch memory, this process has 6.72 GiB memory in use. Of the allocated memory 6.42 GiB is allocated by PyTorch, and 123.97 MiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation.  See documentation for Memory Management  (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)

又没显存了。。。而且batch_size已经是4了,很小了。我试了下,只有改成1或者2我这里才不报错。这两天有空还是尝试把核显跟独显的功能分开吧,多省点显存。
但也会有新报错:

Traceback (most recent call last):
  File "/home/lcy-magic/MedSAM/MedSAM/train_one_gpu.py", line 443, in <module>
    loss.backward()
  File "/home/lcy-magic/anaconda3/envs/MEDSAM/lib/python3.10/site-packages/torch/_tensor.py", line 522, in backward
    torch.autograd.backward(
  File "/home/lcy-magic/anaconda3/envs/MEDSAM/lib/python3.10/site-packages/torch/autograd/__init__.py", line 266, in backward
    Variable._execution_engine.run_backward(  # Calls into the C++ engine to run the backward pass
RuntimeError: GET was unable to find an engine to execute this computation

也就是找不到反向传播的工具了。
什么原因呐?好像是显卡驱动问题,但有人说他重装一下torch就好了,我也打算这样先试一下参考issue:

pip uninstall torch
pip3 install torch torchvision

结果还是不行。我想我的torch是2.2.1的,这个项目要求是2.1.2的。我回退一下版本试试?

pip3 install torch==2.1.2 torchvision

再运行还是同样的错误。那应该就是我的驱动版本问题了。
检查驱动版本:
在这里插入图片描述
这个时候我发现我忽略了前面一大堆的报错信息:

Error: /usr/local/cuda/lib64/libcudnn_cnn_train.so.8: undefined symbol: _ZTIN10cask_cudnn14BaseKernelInfoE, version libcudnn_cnn_infer.so.8
Could not load library libcudnn_cnn_train.so.8. Error: /usr/local/cuda/lib64/libcudnn_cnn_train.so.8: undefined symbol: _ZTIN10cask_cudnn14BaseKernelInfoE, version libcudnn_cnn_infer.so.8

搜了一下这个,我就明白了。根据参考博客所说,应该是之前有个系统的cudnn,pip安装torch又有一个cudnn。指向错了,指到系统的了。反正我一般都用pip安装torch,不源码安装,我就把系统的cundnn删掉就好。我没有删,先按照博主所说,把bashrc那一行注释掉了:

#export CUDA_HOME=/usr/local/cuda
#export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${LD_LIBRARY_PATH}
#export PATH=${CUDA_HOME}/bin:${PATH}

也source了,但还是同样报错。我一怒之下,还是删了吧:

cd /usr/local/cuda/lib64
sudo rm -f libcudnn*
cd /usr/local/cuda/include
sudo rm -f cudnn*

再回去运行bash脚本,就没问题了:
在这里插入图片描述
慢慢等结果了。遛个弯回来,发现到epoch3时候报错终止了。报错很长,主要是这部分:

RuntimeError: main thread is not in main loop
Tcl_AsyncDelete: async handler deleted by the wrong thread

参照参考博客进行解决。修改为:

# from matplotlib import pyplot as plt
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt

还发现,那个sh还有个地址不对,应该把模型参数地址改为:

-pretrained_checkpoint work_dir/LiteMedSAM/lite_medsam.pth \

这次训练完成:
在这里插入图片描述

最后推理

老样子:

touch train_one_gpu.sh
chmod 777 train_one_gpu.sh
gedit train_one_gpu.sh

写入:

#!/bin/bash

~/anaconda3/envs/MEDSAM/bin/python inference_3D.py \
    -data_root data/MedSAM_test/CT_Abd \
    -pred_save_dir ./preds/CT_Abd \
    -medsam_lite_checkpoint_path work_dir/medsam_lite_latest.pth \
    -num_workers 4 \
    --save_overlay \
    -png_save_dir ./preds/CT_Abd_overlay \
    --overwrite

运行:

./inference_3D.sh

又报错报了一堆,提取最主要的:

Traceback (most recent call last):
  File "/home/lcy-magic/MedSAM/MedSAM/inference_3D.py", line 319, in <module>
    medsam_lite_model.load_state_dict(medsam_lite_checkpoint)
  File "/home/lcy-magic/anaconda3/envs/MEDSAM/lib/python3.10/site-packages/torch/nn/modules/module.py", line 2153, in load_state_dict
    raise RuntimeError('Error(s) in loading state_dict for {}:\n\t{}'.format(
RuntimeError: Error(s) in loading state_dict for MedSAM_Lite:
	Missing key(s) in state_dict:

和:

Unexpected key(s) in state_dict: "model", "epoch", "optimizer", "loss", "best_loss".

有missing key还有unexpected key,感觉像是整个文件搞错了,不是某一句的问题。
报错发生在medsam_lite_model.load_state_dict(medsam_lite_checkpoint)查看代码可以知道medsam_lite_checkpoint来自于bash脚本提供的-medsam_lite_checkpoint_path work_dir/medsam_lite_latest.pth \

查看发现缺失是有这个文件的。不知道具体错哪了,换成medsam_lite_best.pth也不对,换成work_dir/LiteMedSAM/lite_medsam.pth \就好了:
在这里插入图片描述

但这个应该是最初下载下来的,不是我训练的。在加载模型后打印一下看看:

medsam_lite_checkpoint = torch.load(medsam_lite_checkpoint_path, map_location='cpu')
print(medsam_lite_checkpoint.keys())

对于work_dir/medsam_lite_latest.pth \:

dict_keys(['model', 'epoch', 'optimizer', 'loss', 'best_loss'])

对于work_dir/LiteMedSAM/lite_medsam.pth \:
在这里插入图片描述
看到这个博客参考博客懂了,因为训练用的GPU,测试用的CPU,所以出的问题。改为:

medsam_lite_model.load_state_dict(medsam_lite_checkpoint,False)

就正常了。但这可能不是正确的解决办法。
测试一下:
这是之前的结果图:
在这里插入图片描述
我把save_overlay参数设为True,运行后:
在这里插入图片描述
似乎没啥问题。暂时先这样了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/437241.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flink实时数仓同步:切片表实战详解

一、背景 在大数据领域&#xff0c;初始阶段业务数据通常被存储于关系型数据库&#xff0c;如MySQL。然而&#xff0c;为满足日常分析和报表等需求&#xff0c;大数据平台采用多种同步方式&#xff0c;以适应这些业务数据的不同存储需求。 一项常见需求是&#xff0c;业务使用…

分布式事务-Seata

分布式事务:在分布式系统下,一个业务跨越多个服务或者数据源,每个服务都是一个分支事务,要保证所有分支事务最终一致,这样的事务就是分布式事务、 事务ACID原则 原子性&#xff1a;事务中的所有操作&#xff0c;要么全部成功&#xff0c;要么全部失败 一致性&#xff1a;要保…

go语言基础 -- 单元测试

go语言testing框架说明 go语言有自己的测试框架,封装在testing包中。 我们编写的测试案例通常都写在xxx_test.go文件中,比如我们写了个calc.go,对里面的函数进行测试,通常会写一个calc_test.go;testing框架会将_test.go结尾的文件引入;testing框架会在自己的main方法中执…

太阳能光伏电池的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 光伏电池的基本结构 4.2 光伏电池的工作原理 5.完整工程文件 1.课题概述 太阳能光伏电池的simulink建模与仿真.分析不同光照温度&#xff0c;光照强度下的光伏电池的U-I特性曲线以及P-V特性曲线。 …

车辆伤害VR安全教育培训复用性强

VR工地伤害虚拟体验是一种新兴的培训方式&#xff0c;它利用虚拟现实技术为参与者提供身临其境的体验。与传统的培训方式相比&#xff0c;VR工地伤害虚拟体验具有许多优势。 首先&#xff0c;VR工地伤害虚拟体验能够模拟真实的工作环境和事故场景&#xff0c;让参与者在安全的环…

C++ 路径问题

目录 例1 例2 例3 例4 例5 例6 例1 62. 不同路径 1.初始化 2.当前位置的条数&#xff0c;就是上面位置的条数 &#xff0c;加上其左边位置的条数&#xff0c;dp[i][j] dp[i - 1][j] dp[i][j - 1]; 参考代码 class Solution { public:int uniquePaths(int m, int n) …

静态时序分析:典型与非典型时序路径的约束详解(一)

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 时序路径是静态时序分析中的一个重要概念&#xff0c;了解时序路径能帮助设计者更好地编写SDC脚本&#xff0c;本文旨在详细介绍时序路径相关内容。 首先给出时序…

Git误操作补救错失:恢复误删的本地分支、将某个提交从一个分支复制到另一个分支

一、恢复误删的本地分支 作为一枚强迫症&#xff0c;没用的分支总是喜欢及时删删删删掉删掉统统删掉&#xff0c;结果今天发现有些分支还是应该保留。 比如&#xff0c;①前段时间切了个分支用来专门做图表&#xff0c;但因为需求还没有最终确定&#xff0c;已经上线了测试服而…

计网《一》|互联网结构发展史|标准化工作|互联网组成|性能指标|计算机网络体系结构

计网《一》| 概述 计算机网络在信息时代的作用什么是互联网呢&#xff1f;互联网有什么用呢&#xff1f;为什么互联网能为用户提供许多服务 互联网基础结构发展的三个阶段第一个阶段&#xff1a;第二阶段&#xff1a;第三个阶段&#xff1a; 互联网标准化的工作互联网的组成边缘…

Observer 模式

文章目录 &#x1f4a1;问题引入&#x1f4a1;概念&#x1f4a1;例子&#x1f4a1;总结 &#x1f4a1;问题引入 假设有一个在线商店系统&#xff0c;用户可以订阅商品的库存通知。当某个商品的库存数量发生变化时&#xff0c;系统会自动发送通知给所有订阅了该商品的用户。设计…

Android 13 WMS-动画流程

动画的类型如下 IntDef(flag true, prefix { "ANIMATION_TYPE_" }, value {ANIMATION_TYPE_NONE,ANIMATION_TYPE_APP_TRANSITION,ANIMATION_TYPE_SCREEN_ROTATION,ANIMATION_TYPE_DIMMER,ANIMATION_TYPE_RECENTS,ANIMATION_TYPE_WINDOW_ANIMATION,ANIMATION_TYPE_…

CentOS7.9基于Apache2.4+Php7.4+Mysql8.0架构部署Zabbix6.0LTS 亲测验证完美通过方案

前言: Zabbix 由 Alexei Vladishev 创建,目前由 Zabbix SIA 主导开发和支持。 Zabbix 是一个企业级的开源分布式监控解决方案。 Zabbix 是一款监控网络的众多参数以及服务器、虚拟机、应用程序、服务、数据库、网站、云等的健康和完整性的软件。 Zabbix 使用灵活的通知机制,…

云计算项目八:Harbor

部署企业私有镜像仓库Harbor 私有镜像仓库有许多优点&#xff1a; 节省网络带宽&#xff0c;针对于每个镜像不用每个人都去中央仓库上面去下载&#xff0c;只需要从私有仓库中下载即可提供镜像资源利用&#xff0c;针对于公司内部使用的镜像&#xff0c;推送到本地私有仓库中…

华硕AMD主板开启TPM2.0支持

目录 配置问题设置开启 Firmware TPM开启 Security Device Support保存设置 检查 配置 主板&#xff1a;TUF Gaming B550m-e Wifi   BIOS: 3402 问题 今天更新Win11&#xff0c;告诉我不支持 TPM 2.0&#xff0c;导致更新失败。   网上搜这个问题&#xff0c;基本只提供了…

selenium中ChromeDriver配置,一把过,并且教你伪装

最近正值毕业季&#xff0c;我之前不是写了个问卷星代码嘛&#xff0c;昨晚上有人凌晨1点加我&#xff0c;问我相关内容。 由于我之前C盘重装了一下&#xff0c;导致我很多东西空有其表&#xff0c;实际不能用&#xff0c;借此机会&#xff0c;向大家编写ChromeDriver配置&…

江苏某机场多座智慧公厕上线,黑科技满满打造标杆性机场智慧卫生间

在现代社会&#xff0c;智慧科技正在各个领域中得到广泛应用&#xff0c;机场也不例外。智慧机场是信息化程度、建设标准、功能要求最高的领域&#xff0c;智慧卫生间的建设要求同样是业界的最高标准。智慧公厕源头厂家广州中期科技有限公司&#xff0c;已经建设了浙江某机场、…

SICP解读指南:深度阅读 “计算机领域三巨头” 之一(文末送书)

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 书籍介绍1.1 SICP侧重点1.2 SICP章节介绍 二. 书籍推荐2.1 书籍介绍2.2 推…

边缘计算基础知识

目录 边缘计算简介任务卸载简介边缘存储系统 边缘计算简介 边缘计算是指利用靠近数据生成的网络边缘侧的设备&#xff08;如移动设备、基站、边缘服务器、边缘云等&#xff09;的计算能力和存储能力&#xff0c;使得数据和任务能够就近得到处理和执行。 一个典型的边缘计算系…

java集合(泛型数据结构)

1.泛型 1.1泛型概述 泛型的介绍 泛型是JDK5中引入的特性&#xff0c;它提供了编译时类型安全检测机制 泛型的好处 把运行时期的问题提前到了编译期间 避免了强制类型转换 泛型的定义格式 <类型>: 指定一种类型的格式.尖括号里面可以任意书写,一般只写一个字母.例如: …

这可能是最全的Web测试各个测试点,有这一篇就够了

前言 什么是Web测试&#xff1f; Web测试测试Web或Web应用程序的潜在错误。它是在上线前对基于网络的应用程序进行完整的测试。 Web测试检查 功能测试 易用性测试 接口测试 性能测试 安全测试 兼容性测试 1、功能测试 测试网页中的所有链接、数据库连接、网页中用于提交或从…