动量的好处与困扰(二,摸到pytorch尾灯!)

使用卷积层权重和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) {
Wi -= lr * dWi;
dWi *= 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--) {
layersi->backward(grad);
grad = layersi->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 (chengji0 >= 85)
{
起作用++;
lr = 0.0001;
if (起作用 >= 10)
{
lr = 0.00001;//这个78.32分,创纪录了
if(起作用 >= 16)
{
i = 100;//执行5次
}
}
}

相关推荐
2401_865261631 小时前
亦唐科技:推动人工智能与行业应用深度融合
人工智能·科技
白驹_过隙1 小时前
【大模型OCR落地终极排坑:OvisOCR2+vLLM从报错到批量稳定部署全过程】
人工智能·ocr·vllm
产品人卫朋1 小时前
从AGI阶梯看AI硬件:具身智能还很远,物理约束就在眼前
人工智能·机器人·产品经理·创业·ai硬件
清泓y1 小时前
AI_Agent工具调用知识点
人工智能·ai
苦猿的大模型日记1 小时前
Day40|Agent 实战模块起手——ReAct + 工具 + 记忆,从 0 写一个不靠 LangChain 的 30 行核心 Agent
人工智能
txg6661 小时前
机器人领域简报(2026年7月20日—27日)
人工智能·microsoft·机器人
AI新角度1 小时前
开源维护自动化:issue 分类与发布管理的机器人实践
人工智能
AI大模型-小华1 小时前
Codex 任务中断的真实成本:ChatGPT Plus 与 Pro 应该如何选择?
人工智能·chatgpt·ai编程·codex·chatgpt plus·chatgpt pro