def group_conv2d(x, weight, bias, stride, pad, groups):
n, c, h_in, w_in = x.shape
d, c_g, k, j = weight.shape
assert c // groups == c_g # 保证分组之后通道相同
x_pad = torch.zeros(n, c, h_in+2*pad, w_in+2*pad) # 对输入进行补零操作
if pad>0:
x_pad[:, :, pad:-pad, pad:-pad] = x
else:
x_pad = x
x_pad = x_pad.unfold(2, k, stride)
x_pad = x_pad.unfold(3, j, stride) # 按照滑动窗展开
h_pad, w_pad = x_pad.size(2), x_pad.size(3)
# 对输入按照通道分组
x_pad = x_pad.reshape(n, groups, -1, h_pad, w_pad, k, j)
# 对权重按照输出通道分组
weight = weight.reshape(groups, -1, c_g, k, j)
out = torch.einsum( # 按照滑动窗相乘,
'ngchwkj,gdckj->ngdhw', # 并将所有输入通道卷积结果累加
x_pad, weight)
# 再重新reshape成完整输出
out = out.reshape(n, d, out.size(3), out.size(4))
# 添加偏置值
out = out + bias.view(1, -1, 1, 1)
return out
自动化测试 —— 基于等价融合算子的深度学习框架差分测试技术
1. 深度学习框架选择 —— PyTorch
1.1 深度学习框架
深度学习框架的发展主要经历以下几个阶段
1.2 pytorch
pytorch是基于Torch的开源深度学习库,底层实现采用C++编写,支持GPU加速运算,由Facebook人工智能团队开发维护。pytorch支持动态计算图,计算图在运算过程中支持动态改变。
pytorch的主要特点:
1.3 深度学习算子库
深度神经网络:输入层、隐藏层、输出层
1.4 差分测试
2. 融合算子列表
2.1 基础算子
卷积算子
CNN中完整的卷积是对于两个4维张量进行操作。其中输入 X 尺寸大小为 N×C×H×W ,分别代表了批样本量(batch size),输入通道数(channel),输入长和宽。而卷积核尺寸大小为 D×C×K×K,分别代表输出通道数,输入通道数,和卷积核尺寸(kernel size)。 而在每个输出通道上由 C×K×K 的单个卷积核与 C×H×W 输入通道分别进行二维卷积,再累加在一起形成一个二维的输出(利用
torch.einsum
这个函数操作实现权重与输入的相乘并且相加)分组卷积:在进行卷积运算时,输入通道不全部参与计算,分割成为几组,每组内部进行正常卷积。需要对输入和权重进行一下reshape,都变成多组形式,然后每个组内进行相乘累加求和。
激活函数
激活函数是向神经网络中引入非线性因素,通过激活函数神经网络就可以拟合各种曲线。
激活函数主要分为饱和激活函数(Saturated Neurons)和非饱和函数(One-sided Saturations)
Batch Normalization(BN)
解决多层神经网络中间层的协方差偏移问题,在中间层的输入中实现类似于网络输入进行零均值化和方差归一化的操作
训练过程
测试过程
2.2 融合算子
在模型推理和训练中,BN层往往与其他层合并,以减少计算量
ensium:爱因斯坦求和约定,以简单的方式表示许多常见的多维线性代数数组运算
conv,bn:网络提速
conv,bn,relu:主流卷积神经网络模型中
Conv+BN+Relu
→ CBR融合conv,relu
linear,relu
bn,relu
3. 测试数据
测试数据见代码实现(在线下载测试数据集进行测试)
4. 差分测试
进行框架下算子融合前后的性能(速度、准确率)比较(见测试数据)
5. 总结