最近在飞浆学习目标检测,教程先教了个检测黑白边界的案例。
w = np.array([1, 0, -1], dtype='float32')
w = w.reshape([1, 1, 1, 3])
img = np.ones([50,50], dtype='float32')
img[:, 30:] = 0.
x = img.reshape([1,1,50,50])
x = paddle.to_tensor(x)
这段代码先创建了一个二维数组,每行前30个数为1,后20个数为0,到这里都没问题。
但是在创建卷积算子并且开始做运算之后就报错,只输出了一段关于GPU和CUDA版本的信息
# 创建卷积算子,设置输入和输出通道数,卷积核大小,通过参数属性weight_attr用w初始化参数权重
conv = Conv2D(in_channels=1, out_channels=1, kernel_size=[1, 3],
weight_attr=paddle.ParamAttr(
initializer=Assign(value=w)))
y = conv(x)
out = y.numpy()
f = plt.subplot(121)
f.set_title('input image', fontsize=15)
plt.imshow(img, cmap='gray')
f = plt.subplot(122)
f.set_title('output featuremap', fontsize=15)plt.imshow(out.squeeze(), cmap='gray')
plt.show()
print(conv.weight)
print(conv.bias)
以下是完整代码
import matplotlib.pyplot as plt
import numpy as np
import paddle
from paddle.nn import Conv2D
from paddle.nn.initializer import Assign
# 假设白色区域像素值为1,黑色区域像素值为0。
# 创建初始化权重参数w,当且仅当卷积核处于黑白交界线上时,卷积计算的结果不为0,以此找出黑白交线
w = np.array([1, 0, -1], dtype='float32')
# 将权重参数调整成维度为[cout, cin, kh, kw]的卷积核形式
# 四个参数意思分别为输出图片的通道数,输入图片的通道数,卷积核的宽度,卷积核的长度
# 这里表示w被重塑为四维数组,其中一二三维度大小为1,四维度大小为3,w=[[[[ 1. 0. -1.]]]]
w = w.reshape([1, 1, 1, 3])
# 创建输入图片,图片左边的像素点取值为1,右边的像素点取值为0
img = np.ones([50,50], dtype='float32')
# 选取所有行的,第30列以及之后的元素,设置为0
img[:, 30:] = 0.
# 将图片形状调整为[N, C, H, W]的形式,N表示输入图片数量,C表示一张图片的通道数,HW表示图片的形状
x = img.reshape([1,1,50,50])
print(x)
# 将numpy.ndarray转化成paddle中的tensor,数据形式不变但支持在GPU上运行
x = paddle.to_tensor(x)
# 创建卷积算子,设置输入和输出通道数,卷积核大小,通过参数属性weight_attr用w初始化参数权重
conv = Conv2D(in_channels=1, out_channels=1, kernel_size=[1, 3],
weight_attr=paddle.ParamAttr(
initializer=Assign(value=w)))
# 使用卷积算子作用在输入图片上
y = conv(x)
# 将输出tensor转化为numpy.ndarray
out = y.numpy()
# print(out)
f = plt.subplot(121)
f.set_title('input image', fontsize=15)
plt.imshow(img, cmap='gray')
f = plt.subplot(122)
f.set_title('output featuremap', fontsize=15)
# 卷积算子Conv2D输出数据形状为[N, C, H, W]形式
# 此处N, C=1,输出数据形状为[1, 1, H, W],是4维数组
# 但是画图函数plt.imshow画灰度图时,只接受2维数组
# 通过numpy.squeeze函数将大小为1的维度消除
plt.imshow(out.squeeze(), cmap='gray')
plt.show()
# 查看卷积层的权重参数名字和数值
print(conv.weight)
# 参看卷积层的偏置参数名字和数值
print(conv.bias)
这个问题可能是由于PaddlePaddle环境设置或者版本不一致导致的。首先,你需要确认以下几点:
PaddlePaddle的版本是否正确:在PaddlePaddle 2.0以后的版本中,paddle.nn.Conv2D
是可用的。你可以通过print(paddle.__version__)
来检查你的PaddlePaddle版本。
CUDA和cuDNN的版本是否和PaddlePaddle支持的版本一致:PaddlePaddle需要依赖于CUDA和cuDNN来运行,不同版本的PaddlePaddle对应的CUDA和cuDNN版本是不同的。你可以参考PaddlePaddle的官方安装指南来确认你的CUDA和cuDNN的版本。
设备是否支持:确保你的设备支持CUDA,并且确保你已经正确安装了NVIDIA驱动。
另外,你可以尝试在创建paddle.to_tensor(x)
时指定设备,如下:
x = paddle.to_tensor(x, place=paddle.CPUPlace())
这样就可以在CPU上运行你的代码,而不需要依赖于GPU或CUDA。如果你的代码在CPU上运行正常,但是在GPU上运行失败,那么问题可能就出在GPU或CUDA上。
最后,你也可以试着将你的代码或者错误信息完整地复制并发表到PaddlePaddle的GitHub issues或者论坛中,那里有很多专业的开发者可以帮助你。
第一步: 拉取docker镜像
# 镜像名称
IMAGE="daocloud.io/neucrack/tensorflow-gpu-py3-jupyterlab"
# 拉取深度学习平台镜像
docker pull $IMAGE
# 测试,当日志出现gpu=True表示能成功使用GPU
docker run --gpus all -it --rm $IMAGE python -c "import tensorflow as tf; print('-----version:{}, gpu:{}, 1+2={}'.format(tf.__version__, tf.test.is_gpu_available(), tf.add(1, 2).numpy()) );"
第二步: 拉取本文代码,配置NNCASE,开启docker容器
git clone https://github.com/QiangZiBro/pytorch-k210
cd pytorch-k210/handpose_detection/maix_train
# 配置NNCASE
mkdir -p tools/ncc/ncc_v0.2 && cd tools/ncc/ncc_v0.2
wget https://github.com/kendryte/nncase/releases/download/v0.2.0-beta4/ncc_linux_x86_64.tar.xz
tar xvf ncc-linux-x86_64.tar.xz
cd ../../
上面的NNCASE只需要下载、解压即可,我们接下来使用Docker构建一个Linux虚拟容器环境,如下面命令开启环境:
# 开启容器
docker run --gpus all --name jupyterlab-gpu -it -p 8889:8889 -e USER_NAME=$USER -e USER_ID=`id -u $USER` -e GROUP_NAME=`id -gn $USER` -e GROUP_ID=`id -g $USER` -v `pwd`:/tf $IMAGE
开启容器后,有两种操作方式供选择
第一种,使用jupyter-notebook运行
第二种,直接进入容器内部
docker exec -it jupyterlab-gpu /bin/bash
# 在容器内部,建议切换到普通用户运行
su - yourname
cd /tf
这里笔者选用第二种方式。创建容器时,Docker自动在镜像里创建了一个和本机用户名相同的用户。在容器里运行程序时,强烈建议切换成普通用户运行,否则后期遇到权限问题还需要手动改权限。
第三步: 开启训练,使用Yolo V2算法数据集进行训练,具体操作方法为:
# 安装必备的包
pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
cd /handpose_detection/maix_train
# 初始化
python3 train.py init
# 开始训练
python3 train.py -t detector -d datasets/game train
运行上述命令即使用maix_train工具箱开始训练,这个程序能一键完成训练、参数转换、量化等功能
使用100个Epoch进行训练,得到的结果生成在out文件下。