dw = x * sigma 传上来的梯度

原先fc层的卷积是把grad与weight分块,然后两者做卷积

FC层这里

image-20210429163501900

fc_layer

grad weight 30x4096

fc_input 30x9216

detafc 30x4096

weight 4096x9216

30是就是batch_size我给改了

不过grad weight

image-20210429163428124

这里mm为矩阵乘法,.T为对后面的矩阵进行变换

现在需要把grad与

前一层层是256x3x3,输出也是256层,代表的是有256个filter。为了加速计算,需要考虑上一层与下一层的DSP分配。看下面这段程序。

with open("weight_conv5.coe","w") as f:
    f.write("memory_initialization_radix=2;\n")
    f.write("memory_initialization_vector =\n")
    for p in range(16):
        for k in range(128):
            for x in range(3):
                for y in range(3):
                    for i in range(16):
                        for j in range(2):
                            f.write(d2b((net_new.features[14].weight.data[2*k+j,16*p+i,x,y]*(2**8)).numpy()))
                    f.write(',\n')

其中存储的顺序是[2*k+j, 16*p+i, x, y]

循环最底层的是i和j,相当于取了两个filter的16个深度,然后是x与y,把这个3x3的filter完整地遍历,接下来是改变k,也就是找接下来两个filter,最后再增加深度。其中i的16是由上一层的输出决定的,2是决定下一层DSP的使用。

DSP分配回去看看这个基于FPGA的卷积神经网络实现(三)资源分配(1)_MasJilwei的博客-CSDN博客

这里关于缓存的计算是256*100*1这里的256*100指的是输入图片为256*100的矩形。

关于缓存的大小可以看这个图像卷积和池化操作后的特征图大小计算方法_ZJE-CSDN博客_卷积特征图大小计算

weight 和fconv5的存储方式对应verilog中DSP的分配

        net_new.features[14].weight.data = torch.round(net_new.features[14].weight.data*(2**net_new.features[14].lmd_shift))/(2**net_new.features[14].lmd_shift)
        # with open("weight_conv5.coe","w") as f:
        #     f.write("memory_initialization_radix=2;\n")
        #     f.write("memory_initialization_vector =\n")
        #     for p in range(16):
        #         for k in range(128):
        #             for x in range(3):
        #                 for y in range(3):
        #                     for i in range(16):
        #                         for j in range(2):
        #                             f.write(d2b((net_new.features[14].weight.data[2*k+j,16*p+i,x,y]*(2**8)).numpy()))
        #                     f.write(',\n')
        f_conv5 = F.conv2d(f_conv4_relu_q, net_new.features[14].weight, None, 1, 1)
        f_conv5_q = torch.round(f_conv5)
        f_conv5_relu = f_conv5_q.clamp(min=0)
        # with open("f_conv5.coe","w") as f:
        #     f.write("memory_initialization_radix=2;\n")
        #     f.write("memory_initialization_vector =\n")
        #     for k in range(13):
        #         for x in range(13):
        #            for y in range(128):
        #                 for i in range(2):
        #                     for j in range(2):
        #                         f.write(d2b(torch.round((f_conv5_relu.data[i,y*2+j,k,x]*(2**0))).numpy()))
        #                 f.write(',\n')
Last modification:May 19, 2021
恰饭环节