1、HelloWorld
最近有同学课设做的深度学习,但是他并不了解,所以我来帮他一起弄
我对GaitSet具体算法内容不了解,只参与了环境搭建和改一些简单bug的过程
在debug的过程中遇到了一些问题,现已全部解决并完美训练测试结束。
为了记录下收获,同时液能帮助到遇到同样问题的朋友,趁没忘赶紧写下这篇博文
我们使用的硬件配置为英伟达1660,i5处理器,16G内存
OS为Windows10,IDE为Pycharm 2020 社区版
2、环境搭建
CUDA、CuDnn、Pytorch都是和GitHub上作者给的版本一样
首先安装CUDA9.0,CuDnn7.0
然后在清华镜像源下安装anaconda,然后使用conda安装pytorch
这些流程都是固定套路,网上都有,也没有什么很复杂的地方,我就不写了
数据集的来源是[这里](),也是GitHub作者指定的
3、开始DEBUG
3、1 首先是图像预处理部分的问题
在GitHub上原作者给出的pretreatment.py代码是有些问题的,运行后只会生成相应文件夹但是不会有相应的图片出现,后来我们在网上找到了可以替代的预处理代码,代码中有一些小错误,经修正后确认可用,可以替代原作者的pretreatment.py代码
修正后代码如下:
'''
import os
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
def cut_image(path,cut_path,size):
'''
剪切图片
:param path: 输入图片路径
:param cut_path: 剪切图片后的输出路径
:param size: 要剪切的图片大小
:return:
'''
for (root,dirs,files) in os.walk(path):
temp = root.replace(path,cut_path)
if not os.path.exists(temp):
os.makedirs(temp)
for file in files:
image,flag = cut(Image.open(os.path.join(root,file)))
if not flag: Image.fromarray(image).convert('L').resize((size,size)).save(os.path.join(temp,file))
pass
def cut(image):
'''
通过找到人的最小最大高度与宽度把人的轮廓分割出来,、
因为原始轮廓图为二值图,因此头顶为将二值图像列相加后,形成一列后第一个像素值不为0的索引。
同理脚底为形成一列后最后一个像素值不为0的索引。
人的宽度也同理。
:param image: 需要裁剪的图片 N*M的矩阵
:return: temp:裁剪后的图片 size*size的矩阵。flag:是否是符合要求的图片
'''
image = np.array(image)
# 找到人的最小最大高度与宽度
height_min = (image.sum(axis=1)!=0).argmax()
height_max = ((image.sum(axis=1)!=0).cumsum()).argmax()
width_min = (image.sum(axis=0)!=0).argmax()
width_max = ((image.sum(axis=0)!=0).cumsum()).argmax()
head_top = image[height_min,:].argmax()
# 设置切割后图片的大小,为size*size,因为人的高一般都会大于宽
size=height_max-height_min
temp = np.zeros((size,size))
# 将width_max-width_min(宽)乘height_max-height_min(高,szie)的人的轮廓图,放在size*size的图片中央
# l = (width_max-width_min)//2
# r = width_max-width_min-l
# 以头为中心,将将width_max-width_min(宽)乘height_max-height_min(高,szie)的人的轮廓图,放在size*size的图片中央
l1 = head_top-width_min
r1 = width_max-head_top
# 若宽大于高,或头的左侧或右侧身子比要生成图片的一般要大。则此图片为不符合要求的图片
flag = False
if size<=width_max-width_min or size//2<r1 or size//2<l1:
flag = True
return temp,flag
# centroid = np.array([(width_max+width_min)/2,(height_max+height_min)/2],dtype='int')
temp[:,(size//2-l1):(size//2+r1)] = image[height_min:height_max,width_min:width_max ]
return temp,flag
def GEI(cut_path,data_path,size):
'''
生成步态能量图
:param cut_path: 剪切后的图片路径
:param data_path: 生成图片的路径
:param size: 生成能量图大小
:return:
'''
for (root,dirs,files) in os.walk(cut_path):
temp = root.replace(cut_path,data_path)
if not os.path.exists(temp):
os.makedirs(temp)
GEI = np.zeros([size,size])
if len(files)!=0:
for file in files:
GEI += Image.open(os.path.join(root,file)).convert('L')
GEI /= len(files)
Image.fromarray(GEI).convert('L').resize((size,size)).save(os.path.join(temp,'1.png'))
pass
if __name__=='__main__':
cut_image("C:\\Users\\China\\Desktop\\GaitDatas","C:\\Users\\China\\Desktop\\CutImage",126)
GEI("C:\\Users\\China\\Desktop\\CutImage","C:\\Users\\China\\Desktop\\GEIData",126)
ValueError: Object arrays cannot be loaded when allow_pickle=False
报错原因:自Numpy 1.16.3版本发行之后,函数 numpy.load() 和 numpy.lib.format.read_array() 采用allow_pickle关键字,现在默认为False
解决方法:降级Numpy 或者在numpy.load()参数中加一个allow_pickle=True
CUDA_EXTERN_FAILURE
这个好像是cuda版本和显卡之间的问题,没能解决,只能用CPU跑的
测试时报错
== 运行test.py文件查看模型准确率,但是出现如下:
ValueError: need at least one array to concatenate==
我看网上这个问题很多人都遇到了,我们当时也遇到了,后来我看了看代码,发现导入的测试集的数据为0,而训练集的数据量为8。最后发现是在data_loader.py中有一个pid_list变量,这个变量将从work/partition/下的.npy文件导入相关的测试集。而我和同学在跑整个数据集之前,为图省事,曾经跑过只有8个人的部分数据集,可能是在跑部分数据集的时候,就生成了.npy文件,而.npy文件再后来也没有自动更新,导致出现了问题。