先看笔记记录:
13:57 2026/7/11rtx2060显卡,已经把add放在leaky之后,learn rate:1e-05,时间: 20047.972656 ms
13:58 2026/7/11先做一个稳扎稳打的版本!train Classification result: 74.76% ok (used 49984 images)训练了25轮,方差正常,Test Classification result: 71.34% ok (used 9984 images)
14:04 2026/7/11与add放在leaky之前得分对比,mx550显卡,win10,cuda10.2,cudnn7.6,vs2015 c++,x64,release的配置,测试70.84分,40轮,,learn rate:1e-04(自己那个最好的6bn+2res版本)
14:07 2026/7/11rtx2060显卡,win10,cuda11.8,cudnn8.6,vs2019 c++,x64,release的配置,测试74.75分,60轮,train=98.12,,learn rate:1e-04(自己那个最好的6bn+2res版本)
14:10 2026/7/11,看样子,确实放leaky后效果好!
14:11 2026/7/11接下来测试,两个残差,第一个保持不变,升维降维在第二残差中,20轮,方差才调整好!25轮结束训练上了70分,测试才22分,为什么?lr从0.01开始,可以,从0.1开始,失败,0.001开始,失败,第一改变,第二不变,0.001失败!
这些个尝试做记录即可!最甲成绩产生,lr从0.01开始,两个残差,第一个保持不变,升维降维在第二残差中,20轮,方差才调整好!30轮结束训练上了81分,测试才75.46分,为什么?最后停止的lr=0.00001,保存一个版本!
下面看一下,一个奇葩的网络架构:象darknet,但保留了倔强的自己:
layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, 5, 64, 32, 32, 3, 1, 1));
layers.emplace_back(std::make_shared<BN>(cudnn, batch, 64, 32, 32));
layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, 64, 32, 32));
layers.emplace_back(std::make_shared<residualExt2>(cudnn, batch, 64, 32, 32));
layers.emplace_back(std::make_shared<MaxPool2D>(cudnn, batch, 64, 64, 32, 2, 2, 0, 2));
layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, 64, 128, 16, 16, 3, 1, 1));
layers.emplace_back(std::make_shared<BN>(cudnn, batch, 128, 16, 16));
layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, 128, 16, 16));
layers.emplace_back(std::make_shared<residualExt3>(cudnn, batch, 128, 16, 16));
layers.emplace_back(std::make_shared<MaxPool2D>(cudnn, batch, 128, 16, 16, 2, 2, 0, 2));
layers.emplace_back(std::make_shared<Linear>(cublas, batch, 128 * 64, 500));
// layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, 64, 500, 7, 7, 7, 1));
layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, 500, 1, 1));
layers.emplace_back(std::make_shared<Linear>(cublas, batch, 500, 10));//84->10
这个其实就是自己自学cudnn一步一趋走上来的最好架构:6bn+2res
不过不同的是,把leakyrelu放在了add前头,以及residualext3这个残差块使用了降维和升维,抄到了darknet的精髓!
so,我就看到了最奇葩的自己:residualext2,以前看再正常不过,现在看上去很奇葩!你看:
class residualExt2 :public Layer {//改进成先降维,再升维202607101844
public:
residualExt2(cudnnHandle_t& cudnn_, int batch_, int c, int h, int w) : cudnn(cudnn_), batch(batch_)
, _c(c), _h(h), _w(w) {
layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, _c, _c , _h, _w, 1, 1));
layers.emplace_back(std::make_shared<BN>(cudnn, batch, _c , _h, _w));
layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, _c , _h, _w)); //c3,6*12*12->>16*8*8
layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, _c , _c, _h, _w, 3, 1, 1));
layers.emplace_back(std::make_shared<BN>(cudnn, batch, _c, _h, _w));
layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, _c, _h, _w));//20260710收到darknet的启发1506
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());
//cudaMemcpy(input2, inputTemp, sizeof(float)*batch * 10, cudaMemcpyDeviceToDevice);
}
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;
//int NN = batch * 32 * 32 * 32;
residual_forward_kernel << <(NN + 255) / 256, 256 >> > (output, input, input2, NN);
// error_handling(cudaGetLastError());
// cudaMemcpy(input2, inputTemp, sizeof(float)*batch * 10, cudaMemcpyDeviceToDevice);
/*const float alpha = 1.0f, beta = 0.0f;
forward(input);*/
}
/*void forward2(float* inputtest)override {
input = inputtest;
const float alpha = 1.0f, beta = 0.0f;
forward(input);
}*/
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();
}
//float* d_residual = grad备用*X输入数据;//input2 = input_;
// float* d_residual = grad备用*input2;//input2 = input_;
int NN = batch * _c * _h * _w;
/*for (int i = 0; i <NN; i++)
{
d_residual[i] = grad备用[i]*input2[i];
}*/
int threads = 256;
int blocks = (NN + threads - 1) / threads;
//mulext << <blocks, threads >> >(NN, batch, _c, _h, _w, input2, _c, grad备用);
//// mul << <blocks, threads >> >(grad备用, input2, d_residual, NN);//c为输出=d_residual
//error_handling(cudaGetLastError());
//residual_backprop_kernel << <blocks, threads >> >(grad, grad_input, grad备用, NN);
//error_handling(cudaGetLastError());
//// cudaMemcpy(grad_input, grad, sizeof(float)*batch * 32 * 32 * 32, cudaMemcpyDeviceToDevice);
//使用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 3; }
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);
}
}
~residualExt2() {
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;
};
这个标红的卷积,最奇葩,1*1的卷积,通道数没改变,长宽没改变!相当于什么也没做!
他有什么用?很迷惑,我也很迷惑!搞不清楚,而且导致bn层调整达到20轮!
但是,训练30轮他出了最好成绩test=75.46分,怎么办?训练20秒一轮,太慢!
比我们模仿的最好的darknet,test=74分,高了1分,训练一轮10秒,这个要训练45轮!
所以,回过头再看自己的6bn+2res(老版本),这里头竟然使用了两次不改变无用的1*1卷积,奇葩吧!
自己的6bn+2res(老版本),训练60轮,竟然也有74分的好成绩!真不知是怎么调出来的!真是太执着了!缺点就是一旦增加bn层和残差层,就崩溃!
10:14 2026/7/12保持30轮结束训练上了81分,测试才75.46分,为什么?最后停止的lr=0.00001,训练40轮,没长进
rb均值: -0.0352130234,rb方差:14.262719154358
rb均值: 0.5891134143,rb方差:3.204290628433
rb均值: -1.9282523394,rb方差:8.068262100220
rb均值: -0.8606312275,rb方差:6.981663227081
rb均值: -2.4030439854,rb方差:2.754190444946
rb均值: 0.6570685506,rb方差:9.724234580994
rb均值: -0.8150371313,rb方差:16.746698379517
rb均值: -0.0482428670,rb方差:3.029548645020
rb均值: 0.8375898600,rb方差:0.933473646641
rb均值: 0.9689819813,rb方差:1.836101293564
rb均值: -0.6997777224,rb方差:1.324596047401
rb均值: 0.2050344050,rb方差:0.614533126354
rb均值: 0.2318822742,rb方差:0.435542941093
rb均值: -0.0076158936,rb方差:0.394294798374
rb均值: 0.0153729897,rb方差:0.341374099255
rb均值: 0.6515869498,rb方差:1.559036493301
rb均值: 0.1390019357,rb方差:0.334698855877
rb均值: 0.1457644105,rb方差:0.970378220081
rb均值: -0.8289402127,rb方差:0.380797654390
rb均值: -2.0809884071,rb方差:2.022989749908
rb均值: 0.6170504689,rb方差:0.770508885384
rb均值: 1.4031846523,rb方差:1.246126174927
rb均值: -0.1109440923,rb方差:0.845608353615
rb均值: 0.1443672031,rb方差:0.348062723875
rb均值: 1.0667506456,rb方差:0.801210224628
rb均值: 0.3589663208,rb方差:0.453858137131
rb均值: -0.0381050818,rb方差:0.499120354652
rb均值: 1.4912693501,rb方差:1.440005064011
rb均值: -0.4970279336,rb方差:0.521952271461
rb均值: 0.5457373261,rb方差:0.572612464428
rb均值: 0.3146187663,rb方差:0.444224238396
rb均值: -0.6239964962,rb方差:0.402716428041
rb均值: 0.6355765462,rb方差:1.099589228630
rb均值: 0.4786215723,rb方差:0.349409490824
rb均值: -0.5599699020,rb方差:0.436410307884
rb均值: 0.0414183438,rb方差:0.634363889694
rb均值: -0.3988341391,rb方差:0.477618366480
rb均值: -0.0810288638,rb方差:0.423269689083
rb均值: -1.0101382732,rb方差:0.520019650459
rb均值: -0.2167062461,rb方差:0.497478604317
时间: 19157.595703 ms
train Classification result: 82.33% ok (used 49984 images)
learn rate:1e-05
轮次:39
时间: 1790.764038 ms
Test Classification result: 75.34% ok (used 9984 images)