AnimateAnyone
AnimateAnyone是由阿里提出的一项技术,可以实现通过动作视频的驱动,能够令目标图片按照动作视频一样“动起来”。在这里介绍下项目上如何利用各个功能组件,实现这个模型的训练工作,以及发生的问题。接下来开始具体介绍实现方法。
一、数据准备
1. 批量数据处理
批量爬虫youtube中shorts存在的视频,并将视频结果保存到服务器中/root/scratch/backup/AnimateMaster/data
人工数据处理
数据通过人工进行处理,不定期会将数据整体进行迁移。
二、处理视频
视频上传
针对不同服务器之间,需要进行数据传输。
现在假设服务器a向服务器b传输数据。
访问权限获取
- 生成公钥
服务器a内部生成公钥。
参考:id_rsa生成
ssh-keygen
# 返回
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? n # 如果需要覆盖之前的文件y,n就是不覆盖
/root/.ssh/id_rsa就是生成路径
公钥所在位置:/root/.ssh/id_rsa.pub(为服务器a的公钥),点击打开可看到内容。
- 将公钥配置在服务器b中。
打开服务器b的/root/.ssh/authorized_keys,将服务器a中id_rsa.pub的公钥内容,输入至至服务器b中的authorized_keys文件中。之后,服务器a就拥有对服务器b的访问权限。
数据传输
服务器a文件夹路径:/Users/yanghaotian/Desktop/jz/大模型/lora/数据/20_cl/test
服务器b接收文件夹后放置路径 /root/scratch/backup/yht
传输方法(需要在服务器a进行输入): scp -r 服务器a要传输的文件夹路径 服务器b用户名称@服务器b的ip地址:服务器b需要放置的路径
# 文件级数据传输
scp -r /Users/yanghaotian/Desktop/jz/大模型/lora/数据/20_cl/test root@51.159.175.229:/root/scratch/backup/yht
#举例
scp -r /scratch root@51.159.175.229:/root/scratch/backup
将不同文件夹的数据放在一起
情况一(如果没有这类情况,可以不用)
- 当前文件分布情况。文件位置路径在/data/moore/data下。
- 先将Batch_4中result的文件合并在一起。
其中,每个batch文件里面results里是可以直接用的剪好了的视频,raw里面是原视频。
在任意位置创建文件,比如名称为data_process.py(一定要是.py结尾)
import os
import shutil
def move_large_files(source_dir, target_dir, file_size_threshold):
"""
将大于指定大小的文件从不同的子文件夹移动到目标文件夹。
:param source_dir: 源目录路径,包含多个子文件夹。
:param target_dir: 目标文件夹路径,用于存放大文件。
:param file_size_threshold: 文件大小阈值,只有大于这个值的文件会被移动。
"""
if not os.path.exists(target_dir):
os.makedirs(target_dir)
for root, dirs, files in os.walk(source_dir):
for file in files:
file_path = os.path.join(root, file)
if os.path.getsize(file_path) > file_size_threshold:
shutil.copy2(file_path, target_dir)
# 使用示例
# source_dir = '/path/to/your/source/directory' # 源目录路径
# target_dir = '/path/to/your/target/directory' # 目标目录路径
# 实际示例
source_dir = '/data/moore/data/Batch_4/results'
target_dir = '/data/moore/data/train_result'
file_size_threshold = 1024 # 文件大小阈值为10MB
move_large_files(source_dir, target_dir, file_size_threshold)
- 在终端找到data_process.py所在路径下,执行
python data_process.py
- 依次将其他batch中的文件夹合并,也都丢入/data/moore/data/train_result中。
批量姿态提取
1. moore方法
参考:moore模型训练部分
```bash
python tools/extract_dwpose_from_vid.py --video_root /path/to/your/video_dir
# 示例:
python tools/extract_dwpose_from_vid.py --video_root /data/moore/data/train_result
```
发生问题:
(1)内存爆满
解决方案:
extract_dwpose_from_vid.py中的dataworker调成4或者更小。
- 更改yaml文件,用job启动
# 1. 如果需要启动容器进去操作,首先启动无状态容器
export K8S_SA_NAME=gpu-k8s-sa
# 自己写的是
export BUCKET_NAME=pose_infomation
envsubst < gputrainpose.yaml | kubectl --namespace=gke-ai-namespace apply -f -
# 进容器内探查
kubectl -n gke-ai-namespace exec --stdin --tty trainpose-pod --container trainpose -- /bin/bash
# 2.jobprocessdata.yaml更改,仅在jobgputrainpose基础修改如下部分。
args: ["cd /data/moore; python tools/extract_dwpose_from_vid.py --video_root /data/moore/data/train_result;"]
# 启动job
envsubst < jobprocessdata.yaml | kubectl --namespace=gke-ai-namespace apply -f -
# 查看运行日志
kubectl logs -f jobs/trainpose-job trainpose -n gke-ai-namespace
2. musepose方法(使用这个方法)
由于musepose没有像moore一样有现场的批量pose提取,所以自己写了一个,使用方法如下
- 选择AA的环境(可选)
对于使用的服务器(ip:51.159.175.229)选择环境AA
conda activate AA
- 进入路径/root/scratch/MusePose(必须)
cd /root/scratch/MusePose
-
使用示例(讲解用的):python extract_dwpose_from_vid.py --video_root /root/Moore-AnimateAnyone/Batch_6/results/andy(替换成所需提取骨骼的视频文件夹)
-
挂在后台跑代码(服务器只要不关机,就一直跑)
# 代码挂起跑(例子)
nohup + python环境路径 + python脚本路径 + > + 日志路径 + 2>&1 &
# 例子1
python extract_dwpose_from_vid.py --video_root /root/Moore-AnimateAnyone/Batch_6/results/andy
# 例子1延伸
nohup /root/miniconda3/envs/AA/bin/python /root/scratch/MusePose/extract_dwpose_from_vid.py --video_root /root/scratch/Moore-AnimateAnyone/data/test > /root/scratch/Moore-AnimateAnyone/train_0827.log 2>&1 &
# 例子2
nohup /root/miniconda3/envs/AA/bin/python /root/scratch/MusePose/extract_dwpose_from_vid.py --video_root /root/scratch/Moore-AnimateAnyone/data/Batch_8 > /root/scratch/Moore-AnimateAnyone/nohup_0826_train_result.out 2>&1 &
# 注意!!!这个命令必须在/root/MusePose/下面跑
nohup /root/miniconda3/envs/AA/bin/python /root/MusePose/extract_dwpose_from_vid.py --video_root /root/scratch/Moore-AnimateAnyone/data/train_result > /root/scratch/Moore-AnimateAnyone/nohup_0813.out 2>&1 &
# 实时查看日志的最后50条数据
tail -fn 50 /root/scratch/Moore-AnimateAnyone/nohup_0813.out
# 关闭实时日志
ctrl和c同时按
# 最终检查处理的数据和原视频的数据数量是否一致
find . -type f | wc -l
- 解决cpu爆掉的问题(如果服务器资源有限才使用。)
原因分析:在运行脚本时对数据处理时间过长,cpu资源会一直损耗,最终导致cpu打满,服务器崩掉。
解决方案:后台代码跑一会儿就将他杀掉,然后重新跑。
# 查看进程
ps aux | grep python
# 返回结果 查看pid 比如这里5928就是pid
root 5928 664 9.7 22042296 9604500 pts/11 Sl 13:05 14:10 /root/miniconda3/envs/AA/bin/python /root/scratch/MusePose/extract_dwpose_from_vid.py --video_root /root/scratch/Moore-AnimateAnyone/data/Batch_8
# 杀掉进程
kill -9 5928
# 在此查看进程,就没有这个任务了
ps aux | grep python
-
数据信息维护(布置任务:将batch8进行骨骼提取完毕)
需要找到一个excel,在里面维护各个数据文件的意思
batch8是上上一周的(几号到几号) 多少个 所在路径
batch9是yp上一周处理的(几号到几号)多少个 所在路径
批量处理的的文件(处理了不同) -
extract_dwpose_from_vid.py脚本如下
-
其余方法与moore流程一样,不再重复介绍。
import concurrent.futures
import random
from pathlib import Path
import sys;
import numpy as np
import argparse
import torch
import copy
import cv2
import os
import moviepy.video.io.ImageSequenceClip
from pose.script.dwpose import DWposeDetector, draw_pose
from pose.script.util import size_calculate, warpAffine_kps
def process_single_video(video_path, detector, save_dir, args):
root_dir = args.video_root
relative_path = os.path.relpath(video_path, root_dir)
print(relative_path, video_path, root_dir)
out_path = os.path.join(save_dir, relative_path)
if os.path.exists(out_path):
return
output_dir = Path(os.path.dirname(os.path.join(save_dir, relative_path)))
if not output_dir.exists():
output_dir.mkdir(parents=True, exist_ok=True)
video = cv2.VideoCapture(video_path)
width= video.get(cv2.CAP_PROP_FRAME_WIDTH)
height= video.get(cv2.CAP_PROP_FRAME_HEIGHT)
# total_frame= video.get(cv2.CAP_PROP_FRAME_COUNT)
fps= video.get(cv2.CAP_PROP_FPS)
kps_results = []
for i in range(100000):
# print(i)
ret, frame_pil = video.read()
if frame_pil is None:
break
pose_img, pose_ori = detector(frame_pil, args.detect_resolution, args.image_resolution, output_type='cv2', return_pose_dict=True)
kps_results.append(pose_img)
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(kps_results, fps=fps)
os.makedirs(os.path.dirname(out_path), exist_ok=True)
clip.write_videofile(out_path, fps=fps)
def process_batch_videos(video_list, detector, root_dir, save_dir):
for i, video_path in enumerate(video_list):
print(f"Process {i}/{len(video_list)} video")
process_single_video(video_path, detector, root_dir, save_dir)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--video_root", type=str)
parser.add_argument(
"--save_dir", type=str, help="Path to save extracted pose videos"
)
parser.add_argument("-j", type=int, default=1, help="Num workers")
parser.add_argument('--detect_resolution', type=int, default=512, help='detect_resolution')
parser.add_argument('--image_resolution', type=int, default=720, help='image_resolution')
parser.add_argument("--yolox_config", type=str, default="./pose/config/yolox_l_8xb8-300e_coco.py")
parser.add_argument("--dwpose_config", type=str, default="./pose/config/dwpose-l_384x288.py")
parser.add_argument("--yolox_ckpt", type=str, default="./pretrained_weights/dwpose/yolox_l_8x8_300e_coco.pth")
parser.add_argument("--dwpose_ckpt", type=str, default="./pretrained_weights/dwpose/dw-ll_ucoco_384.pth")
args = parser.parse_args()
num_workers = args.j
if args.save_dir is None:
save_dir = args.video_root + "_dwpose"
else:
save_dir = args.save_dir
if not os.path.exists(save_dir):
os.makedirs(save_dir)
cuda_visible_devices = os.environ.get("CUDA_VISIBLE_DEVICES", "0")
gpu_ids = [int(id) for id in range(len(cuda_visible_devices.split(",")))]
print(f"avaliable gpu ids: {gpu_ids}")
# collect all video_folder paths
video_mp4_paths = set()
for root, dirs, files in os.walk(args.video_root):
for name in files:
if name.endswith(".mp4"):
video_mp4_paths.add(os.path.join(root, name))
video_mp4_paths = list(video_mp4_paths)
random.shuffle(video_mp4_paths)
# split into chunks,
batch_size = (len(video_mp4_paths) + num_workers - 1) // num_workers
print(f"Num videos: {len(video_mp4_paths)} {batch_size = }")
video_chunks = [
video_mp4_paths[i : i + batch_size]
for i in range(0, len(video_mp4_paths), batch_size)
]
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = []
for i, chunk in enumerate(video_chunks):
# init detector
gpu_id = gpu_ids[i % len(gpu_ids)]
detector = DWposeDetector(
det_config = args.yolox_config,
det_ckpt = args.yolox_ckpt,
pose_config = args.dwpose_config,
pose_ckpt = args.dwpose_ckpt,
keypoints_only=False
)
# torch.cuda.set_device(gpu_id)
detector = detector.to(f"cuda:{gpu_id}")
futures.append(
executor.submit(
process_batch_videos, chunk, detector, save_dir, args
)
)
for future in concurrent.futures.as_completed(futures):
future.result()
三、模型训练
1. 启动环境镜像(这里拿启动moore为例)
发现服务器里有镜像,直接启动镜像吧,实在不想在配置环境了
(1) 打开容器
具体介绍参考之前文档。
# 查看当前容器
docker ps
# 显示如下,# 存在CONTAINER ID 4c87ff4324e8
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c87ff4324e8 567185e860da "/bin/bash" 16 hours ago Up 16 hours dreamy_cohen
e5dd115e2b78 639c99b3 "/bin/bash" 9 days ago Up 8 days trusting_murdock
# 如果不存在CONTAINER ID 4c87ff4324e8,执行以下步骤
# 查看镜像
docker images
# 显示如下(找到名称为lingyun92888/train_pose对应的image id)
REPOSITORY TAG IMAGE ID CREATED SIZE
lingyun92888/train_pose 240806 567185e860da 8 days ago 17.8GB
# 启动容器
docker run -itd -v /root/scratch/Moore-AnimateAnyone:/workspace 567185e860da(上一步的对应image id)
# 再进行容器查看
docker ps
# 如果存在上一步image ID 对应的CONTAINER ID,则进入容器
docker exec -it 4c87ff4324e8(CONTAINER ID) bash
docker exec -it f37acb2670c5 bash
# 显示如下代表进入容器
root@4c87ff4324e8:/workspace
# 进入到指定位置 打开就是/workspace
cd /workspace
2. 生成位置json
这一步将训练视频和提取姿态的视频的位置信息放置在json文件中。运行代码后文件自动存储在./data/lmb_meta.json位置。
运行前提,视频文件已经全部进行骨骼处理,并有_dwpose结尾的文件夹存在
# 进入指定路径
python tools/extract_meta_info.py --root_path /data/moore/data/train_result --dataset_name anyone
# 相对路径 相对于/workspace
python tools/extract_meta_info.py --root_path data/test --dataset_name lmb
python tools/extract_meta_info.py --root_path ./data/test --dataset_name lmb
# 绝对路径
python tools/extract_meta_info.py --root_path /workspace/data/test --dataset_name lmb
(任何时候,输入全路径(绝对路径)都是不会错的 /workspace/data/test)
3. 修改配置文件(json)
stage1.yaml
- 修改yaml meta.json文件
方法一:手动改
直接打开configs/train/stage1.yaml
方法二:命令修改
vim configs/train/stage1.yaml
# 如果报错证明没有下载
bash: vim: command not found
# 下载vim
apt-get install vim
# 再次使用命令
vim configs/train/stage1.yaml
# 需要修改 点击i
# 修改完成 点击 esc
# 保存退出 :wq
# 修改上一步生成的anyone_meta
meta_paths:
- "./data/lmb_meta.json"
- 修改迭代次数
train_bs: 1 # 同时训练几个数据
max_train_steps: 100 # 训练多少次
stage2.yaml
位置在 configs/train/stage2.yaml
train_bs: 1 # 同时训练几个数据
max_train_steps: 100 # 训练多少次
meta_paths:
- "./data/lmb_meta.json"
# 最最最最重要的地方
stage1_ckpt_dir: './exp_output/stage1'
stage1_ckpt_step: 90 # 在阶段1训练完成后,会有在./exp_output/stage1 下产生一堆模型结果,模型结果中最大的迭代数就是第二阶段这个位置要选择的数
4. 跑训练代码
- 第一阶段训练代码
accelerate launch train_stage_1.py --config configs/train/stage1.yaml
# 后台跑代码 nohup + python环境路径 + python脚本路径 + > + 日志路径 + 2>&1 &
nohup accelerate launch train_stage_1.py --config configs/train/stage1.yaml > ./lmb.log 2>&1 &
- 第二阶段训练代码
accelerate launch train_stage_2.py --config configs/train/stage2.yaml
# 后台跑代码 nohup + python环境路径 + python脚本路径 + > + 日志路径 + 2>&1 &
nohup accelerate launch train_stage_2.py --config configs/train/stage2.yaml --config configs/train/stage1.yaml > ./lmb_0828.log 2>&1 &
六、k8s跑训练代码
- 执行job任务,跑代码
export K8S_SA_NAME=gpu-k8s-sa
# 自己写的是
export BUCKET_NAME=pose_infomation
envsubst < jobgputrainpose.yaml | kubectl --namespace=gke-ai-namespace apply -f -
# 查看运行日志
kubectl logs -f jobs/trainpose-job trainpose -n gke-ai-namespace
- 将最终的结果从google导入服务器中
在服务器到位置/root/python-storage/,具体才做流程看之前关于服务器和google之间的传输介绍
# 要求
python storage_download_file_requester_pays.py <BUCKET_NAME> <PROJECT_ID> <SOURCE_BLOB_NAME> <DESTINATION_FILE_NAME>
# 示例
python storage_download_file.py pose_infomation moore/exp_output/stage1/pose_guider-11890.pth /scratch/Moore-AnimateAnyone/pretrained_weights/pose_guider-11890.pth
python storage_download_file.py pose_infomation moore/exp_output/stage1/denoising_unet-11890.pth /scratch/Moore-AnimateAnyone/pretrained_weights/denoising_unet-11890.pth
python storage_download_file.py pose_infomation moore/exp_output/stage1/reference_unet-11890.pth /scratch/Moore-AnimateAnyone/pretrained_weights/reference_unet-11890.pth
python storage_download_file.py pose_infomation moore/exp_output/stage2/motion_module-9009.pth /scratch/Moore-AnimateAnyone/pretrained_weights/motion_module-9009.pth
七、模型测试效果
1.moore方法
- 参数选择
exp_output/stage1/中存在denoising_unet-1740.pth,pose_guider-1740.pth,reference_unet-1740.pth。
exp_output/stage2/中存在motion_module-1000.pth。以上模型替换moore之前的模型 - 模型下载,并将模型放到合适的位置上。
因为我训练的模型是在谷歌的gke上,所以觉得还是把模型拉到服务器上,测试的比较舒服。
具体方法在之前的文档《通过服务器将文件传输到google cloud》中进行过介绍。这里不再过多介绍,只介绍用到的内容。
# 1.身份认证
gcloud auth application-default login
# 2.拉取模型
python storage_download_file.py pose_infomation moore/exp_output/stage2/motion_module-1000.pth /scratch/motion_module-1000.pth
python storage_download_file.py pose_infomation moore/exp_output/stage1/denoising_unet-1740.pth /scratch/Moore-AnimateAnyone/pretrained_weights/denoising_unet-1740.pth
python storage_download_file.py pose_infomation moore/exp_output/stage1/pose_guider-1740.pth /scratch/Moore-AnimateAnyone/pretrained_weights/pose_guider-1740.pth
python storage_download_file.py pose_infomation moore/exp_output/stage1/reference_unet-1740.pth /scratch/Moore-AnimateAnyone/pretrained_weights/reference_unet-1740.pth
- 准备环境
发现服务器里有镜像,直接启动镜像吧,实在不想在配置环境了
(1) 打开容器
具体介绍参考之前文档。
# 查看当前容器
docker ps
# 显示如下,# 存在CONTAINER ID 4c87ff4324e8
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c87ff4324e8 567185e860da "/bin/bash" 16 hours ago Up 16 hours dreamy_cohen
e5dd115e2b78 639c99b3 "/bin/bash" 9 days ago Up 8 days trusting_murdock
# 如果不存在CONTAINER ID 4c87ff4324e8,执行以下步骤
# 查看镜像
docker images
# 显示如下
REPOSITORY TAG IMAGE ID CREATED SIZE
lingyun92888/train_pose 240806 567185e860da 8 days ago 17.8GB
# 启动容器
docker run -itd -v /root/scratch/Moore-AnimateAnyone:/workspace 567185e860da
# 如果不存在CONTAINER ID 4c87ff4324e8,进入容器
docker exec -it 4c87ff4324e8 bash
# 显示如下代表进入容器
root@4c87ff4324e8:/workspace
# 进入到指定位置 打开就是/workspace
cd /workspace
- 准备需要测试的数据
注意:选择的图片和视频一定要在/root/scratch/Moore-AnimateAnyone这个文件夹下面,如果没有,就手动移到这个文件夹下。
(1)找一个目标图片,记录下目标图片位置信息(/root/scratch/Moore-AnimateAnyone/lmb/images/test15.png)
(2)准备一个视频(/root/scratch/Moore-AnimateAnyone/Batch_6/results/verse/verse1/verse1_segment_00.mp4),处理为pose视频(/root/scratch/Moore-AnimateAnyone/Batch_6/results/verse/verse1/verse1_segment_00_kps.mp4)
# 注意路径中出现/root/scratch/Moore-AnimateAnyone在下面命令中替换.
# 示例 python tools/vid2pose.py --video_path /path/to/your/video.mp4
python tools/vid2pose.py --video_path ./Batch_6/results/verse/verse1/verse
1_segment_02.mp4
# python tools/vid2pose.py --video_path ./Batch_6/results/verse/verse1/verse1_segment_00.mp4
- 更改配置信息
自己建一个/root/scratch/Moore-AnimateAnyone/configs/prompts/animation0813.yaml文件
(1)换成自己的模型
(2)换成自己的数据
(3)整体文件(示例展示)test_cases: "./configs/inference/ref_images/anyone-11.png": - "./Batch_6/results/verse/verse1/verse1_segment_02_kps.mp4"
(4)开始生成结果# moore自训练模型第一次,参数比较一般 pretrained_base_model_path: "./pretrained_weights/stable-diffusion-v1-5/" pretrained_vae_path: "./pretrained_weights/sd-vae-ft-mse" image_encoder_path: "./pretrained_weights/image_encoder" denoising_unet_path: "./pretrained_weights/denoising_unet-1740.pth" reference_unet_path: "./pretrained_weights/reference_unet-1740.pth" pose_guider_path: "./pretrained_weights/pose_guider-1740.pth" motion_module_path: "./pretrained_weights/motion_module-1000.pth" inference_config: "./configs/inference/inference_v2.yaml" weight_dtype: 'fp16' test_cases: "./configs/inference/ref_images/anyone-11.png": -"./Batch_6/results/verse/verse1/verse1_segment_02_kps.mp4"
(5)查看结果python -m scripts.pose2vid --config ./configs/prompts/animation0813.yaml -W 512 -H 784 -L 64
可以在这个位置看到数据结果
/root/scratch/Moore-AnimateAnyone/output/20240813
实验结果记录介绍
方法选择 | 提取方法 | step1参数 | step2参数 | 产生模型 | 训练数据集 |
---|---|---|---|---|---|
moore | moore | max_train_steps: 2010, seed=12580 | 引用step1的1740的模型, seed=12580 | pose_guider-1740.pth,denoising_unet-1740.pth,motion_module-1000.pth,reference_unet-1740.pth | Batch7的1034个数据集 |
moore | moore | max_train_steps: 20000, seed=12580 | 引用step1的11890的模型, seed=12580 | denoising_unet-11890.pth,reference_unet-11890.pth,pose_guider-11890.pth,motion_module-9009.pth | Batch7的1034个数据集 |
moore | moore | max_train_steps: 30000, seed=12680 | 引用step1的29870的模型, seed=12680 | denoising_unet-29870.pth,reference_unet-29870.pth,pose_guider-29870.pth,motion_module-10000.pth | Batch7的1034个数据集 |
– | – | – | – |
待办
- 训练好的数据怎么应用,注意做好笔记
- 利用moore出一套完整流程
- 利用musepose方法出一套完整流程
- 探查怎么利用多卡gpu搞笑运转
- 再开几个多卡的gpu
- 看论文修改网络
- 找一些好的数据进行训练(教给实习生)
- 利用vscode调试容器
临时任务
训练数据增加
-
新增的文件夹中所有作者的视频导入一个空文件夹/data/moore/data/train_result_tmp(使用data_process.py)
-
对文件中的视频进行pose提取
python tools/extract_dwpose_from_vid.py --video_root /data/moore/data/train_result_tmp/
-
通过脚本(trans_data.py)将所有的pose视频导入之前已有的。
# 写一个导视频的脚本 import os import shutil def copy_files(source_folder, destination_folder): if not os.path.exists(destination_folder): os.makedirs(destination_folder) for filename in os.listdir(source_folder): source_file = os.path.join(source_folder, filename) destination_file = os.path.join(destination_folder, filename) if os.path.isfile(source_file): shutil.copy(source_file, destination_folder) print(f"Copied {source_file} to {destination_folder}") # 使用示例 source_folder = '/data/moore/data/train_result_tmp_dwpose' destination_folder = '/data/moore/data/train_result_dwpose' copy_files(source_folder, destination_folder)
-
核实训练数据两边数量一样
确保数据导来导去没有出错find . -type f | wc -l
-
重新生成训练视频位置json
python tools/extract_meta_info.py --root_path /data/moore/data/train_result --dataset_name anyone
桶存储的清理和恢复
桶存储中的训练结果因为占的空间太大了,所以清理了下,但是清理后发现还有用,需要进行恢复。
参考:桶存储的恢复
桶存储中训练模型的备份
# 修改训练文件的名称,训练后只保留最新的结果
mv 原文件名 新文件名
# 发生报错
mv: cannot move 'exp_output' to 'exp_output_0813': Too many open files
# 换一个方法备份,再复制成一个文件
cp -r exp_output exp_output_0813
rm -rf exp_output