使用卷积层权重和bias的动量参与!就这一句话:

scal_cpu << <(w_size + 255) / 256, 256 >> > (w_size, 0.98, _grad_weight, 1);

darknet版本从13秒一轮,上升到70秒一轮

自己的版本从14.5秒一轮,上升到83秒一轮!

怎么解决这个问题?想到一个办法:

bias的动量不影响速度,关键是weight的更新及动量的使用:

axpy_kernel << <(w_size + 255) / 256, 256 >> > (w_size, 0.0005f * _batch, _weight, 0, 1, _grad_weight, 0, 1);
        
sgd_update << <(w_size + 255) / 256, 256 >> > (_weight, _grad_weight, lr, w_size);//权重应该从这里取出来20251006        
        scal_cpu << <(w_size + 255) / 256, 256 >> > (w_size, 0.98, _grad_weight, 1);

我们定义了这样一个cuda函数:

__global__ void sgd_update_Wb(float* W,  float* dW, float lr, int n,float alpha) {
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    if (i < n) {
        W[i] -= lr * dW[i];
        dW[i] *= alpha  ;
    }
}

然后,我们把上面标红的三句话,变成2句话:

axpy_kernel << <(w_size + 255) / 256, 256 >> > (w_size, 0.0005f * _batch, _weight, 0, 1, _grad_weight, 0, 1);

sgd_update_Wb << <(w_size + 255) / 256, 256 >> > (_weight, _grad_weight, lr, w_size,0.98);

开始训练,13秒还是13秒,成绩有轻微下降,test=78.5左右,但是很稳定,0.001=lr从前训练到结束,我估计,pytorch正是找到了这样的版本

pytorch写程序,很乏味,但是你站在巨人肩上!

我们看看,残差块上升到3个!其他仍保持不变!

layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, 5, 64, 32, 32, 3, 1, 1));    
        layers.emplace_back(std::make_shared<residualExt3>(cudnn, batch, 64, 32, 32));
        

        layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, 64, 128, 32, 32, 3, 2, 1));
        layers.emplace_back(std::make_shared<residualExt3>(cudnn, batch, 128,16, 16));
        
        layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, 128, 256, 16, 16, 3, 2, 1));    
        layers.emplace_back(std::make_shared<residualbase>(cudnn, batch, 256, 8, 8));

        
    
        layers.emplace_back(std::make_shared<averPool2D>(cudnn, batch, 256, 8, 8, 2, 2, 0, 2));//改变202607120652


    


        layers.emplace_back(std::make_shared<Linear>(cublas, batch, 256 * 16, 500));    
        layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, 500, 1, 1));
        layers.emplace_back(std::make_shared<Linear>(cublas, batch, 500, 10));

rb均值: 2.8520965576,rb方差:5.221516132355
rb均值: 0.7169740200,rb方差:17.567085266113
时间: 16653.863281 ms
train Classification result: 94.09% ok (used 49984 images)
时间: 1431.917969 ms
Test Classification result: 72.36% ok (used 9984 images)
learn rate:0.0005
轮次:24
rb均值: 2.9761559963,rb方差:5.301302909851
rb均值: 0.7119024396,rb方差:17.910957336426
时间: 16553.474609 ms
train Classification result: 96.89% ok (used 49984 images)
时间: 1453.957031 ms
Test Classification result: 76.15% ok (used 9984 images)
learn rate:0.0001
轮次:25
rb均值: 3.0143072605,rb方差:5.408737182617
rb均值: 0.7610685825,rb方差:18.181289672852
时间: 16624.269531 ms
train Classification result: 98.70% ok (used 49984 images)
时间: 1432.275024 ms
Test Classification result: 76.00% ok (used 9984 images)
learn rate:0.0001
轮次:26
rb均值: 3.0526778698,rb方差:5.501682758331
rb均值: 0.7769252062,rb方差:18.443340301514
时间: 16711.599609 ms
train Classification result: 99.23% ok (used 49984 images)
时间: 1454.276978 ms
Test Classification result: 76.05% ok (used 9984 images)
learn rate:0.0001
轮次:27
rb均值: 3.0962934494,rb方差:5.609492301941
rb均值: 0.8027059436,rb方差:18.742258071899
时间: 16700.082031 ms
train Classification result: 99.57% ok (used 49984 images)
时间: 1444.345947 ms
Test Classification result: 76.02% ok (used 9984 images)
learn rate:0.0001
轮次:28
rb均值: 3.0906116962,rb方差:5.692352294922
rb均值: 0.8014982939,rb方差:19.029966354370
时间: 16730.179688 ms
train Classification result: 99.73% ok (used 49984 images)
时间: 1463.499023 ms
Test Classification result: 76.06% ok (used 9984 images)
learn rate:0.0001
轮次:29
rb均值: 3.1161377430,rb方差:5.783454895020
rb均值: 0.8241575956,rb方差:19.273908615112
时间: 16761.531250 ms
train Classification result: 99.85% ok (used 49984 images)
时间: 1464.786987 ms
Test Classification result: 75.93% ok (used 9984 images)
learn rate:0.0001
轮次:30
请按任意键继续. . .

class residualbase :public Layer {//改进成先降维,再升维202607101844
public:
    residualbase(cudnnHandle_t& cudnn_, int batch_, int c, int h, int w) : cudnn(cudnn_), batch(batch_)
        , _c(c), _h(h), _w(w) {


        //尝试残差,此处要记住输入X
        layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, _c, _c / 2, _h, _w, 1, 1));//128-64 , 16*16
        layers.emplace_back(std::make_shared<BN>(cudnn, batch, _c / 2, _h, _w));
        layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, _c / 2, _h, _w));          //
        layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, _c / 2, _c / 2, _h, _w, 3, 1, 1));//64-64 ,16*16
        layers.emplace_back(std::make_shared<BN>(cudnn, batch, _c / 2, _h, _w));
        layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, _c / 2, _h, _w));//20260710收到darknet的启发1506

        layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, _c / 2, _c, _h, _w, 3, 1, 1));//128-64-128,16*16
        layers.emplace_back(std::make_shared<BN>(cudnn, batch, _c, _h, _w));
        layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, _c, _h, _w));

        cudaMalloc(&output, batch * _c * _h * _w * sizeof(float));//输出32*32*32-----------------------显然输入也是32*32*32
        cudaMalloc(&input2, batch * _c * _h * _w * sizeof(float));
        cudaMalloc(&d_residual, batch * _c * _h * _w * sizeof(float));
        //    cudaMalloc(&output, batch * 10 * sizeof(float));//这里的10代表10个类,所以不能用
        cudaMalloc(&grad_input, batch * _c * _h * _w * sizeof(float));//反向和梯度计算不管!!!!!!!!!!!!!!
    }
    void forward(float* input_)override {
        input = input_;
        input2 = input_;
        for (const auto& l : layers) {
            l->forward(input);
            input = l->get_output();
        }

        int    NN = batch * _c * _h * _w;
        residual_forward_kernel << <(NN + 255) / 256, 256 >> > (output, input, input2, NN);
        error_handling(cudaGetLastError());

    }
    void forward2(float* input_)override {
        input = input_;
        input2 = input_; //batch = 1;
        for (const auto& l : layers) {
            l->forward2(input);
            input = l->get_output();
        }
        int    NN = batch * _c * _h * _w;
        residual_forward_kernel << <(NN + 255) / 256, 256 >> > (output, input, input2, NN);

    }

    void backward(float* grad_output)override {//梯度来自残差块后的relu,当前只有一个残差块!!!!!!!!!!!
        float* grad = grad_output;//要记住这个梯度,即备份一个
        float* grad备用 = grad_output;
        for (int i = layers.size() - 1; i >= 0; i--) {
            layers[i]->backward(grad);
            grad = layers[i]->get_grad_input();
        }


        int    NN = batch * _c * _h * _w;


        int threads = 256;
        int blocks = (NN + threads - 1) / threads;

        //使用yolo 的残差试一试,看两个bn有什么情况
        mul << <blocks, threads >> > (grad备用, input2, d_residual, NN);//c为输出=d_residual
        error_handling(cudaGetLastError());
        shortcut_gpu(batch, _w, _h, _c, d_residual, _w, _h, _c, grad);//虚线l.out_c=12,l.c=16,在这里是实线,l.out_c=16,l.c=16

        cudaMemcpy(grad_input, grad, sizeof(float) * NN, cudaMemcpyDeviceToDevice);
        error_handling(cudaGetLastError());//仍然是第二个bn层方差均值为零
    }
    int    getname() override { return 5; }
    float* get_output() override { return output; }
    float* get_grad_input() override { return grad_input; }
    void update(float lr) {
        for (const auto& l : layers) {
            l->update(lr);

        }
    }


    ~residualbase() {
        cudaFree(output);
        cudaFree(grad_input);
    }


private:
    //    cublasHandle_t &cublas;
    int  _c, _h, _w;
    cudnnHandle_t& cudnn;
    int batch;
    float* input, * output, * grad_input;
    float* input2;
    float* d_residual;
public:
    std::vector<std::shared_ptr<Layer>> layers;

};

当然,residualExt3还是比residualbase好的多!至少2分的差距!

lr调整如下:(2个残差块也如此)

if (hehe)
        {
            lr *= 0.1;
        }
        if (lr <= 0.001)lr = 0.001;
        
    
        if (chengji[0] >= 85)
        {
            起作用++;
            
            
            lr = 0.0001;
            if (起作用 >= 10)
            {
                
                lr = 0.00001;//这个78.32分,创纪录了
                if(起作用 >= 16)
                {
                    
                    i = 100;//执行5次
                }
            }
            
        }

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐