实现pytorch resnet18功能(五,总结,顺便实现yolov3 shortcut残差)

其实我前面四篇实现了三种残差:

1,out +=x,out =relu(out)

2,out =relu(out),out +=x

3,pytorch版本: (c**++ cudnn替代实现**)

class ResidualBlock(nn.Module):
def init(self, inchannel, outchannel, stride=1):
super(ResidualBlock, self).init()
self.left = nn.Sequential(
nn.Conv2d(inchannel, outchannel, kernel_size=3, stride=stride, padding=1, bias=False),
nn.BatchNorm2d(outchannel),
nn.ReLU(inplace=True),
nn.Conv2d(outchannel, outchannel, kernel_size=3, stride=1, padding=1, bias=False),
nn.BatchNorm2d(outchannel)
)
self.shortcut = nn.Sequential()
if stride != 1 or inchannel != outchannel:
self.shortcut = nn.Sequential(
nn.Conv2d(inchannel, outchannel, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(outchannel)
)

def forward(self, x):
out = self.left(x)
out += self.shortcut(x)
out = F.relu(out)
return out
------------------------------------------------

其实今天早上, 我顺便在虚线残差yolov3版本上,改了一个yolov3实线残差版本**,测试可以用!成绩略有下降!(或许是几种残差类混在一起用的缘故,或者是yolo有问题,这是我的直觉,反向传播中他用output,我用input,根据数学推导和查看cpu走过来的版本,应该是ds(s2.data))没关系,神经网络最有魅力的就是如此,只要不是致命错误,他是会出成绩,而且不会崩溃!学习优秀,保持自我,难度很大!神经网络和人的意识一样,轻易不会崩溃!这也是人生精髓所在!最难也在此,逻辑和情感在人生中处处熠熠生辉!享受这样的过程吧!能说清楚,就说清楚,说不清楚,就保持探索的乐趣!**

轮次:15
learn rate:0.0001
时间: 32458.498047 ms
train Classification result: 35.89% ok (used 49984 images)
时间: 2491.056885 ms
Test Classification result: 9.99% ok (used 9984 images)
轮次:16
learn rate:0.0001
时间: 32208.925781 ms
train Classification result: 38.80% ok (used 49984 images)
时间: 2488.377930 ms
Test Classification result: 10.02% ok (used 9984 images)
轮次:17
learn rate:0.0001
时间: 32884.285156 ms
train Classification result: 40.47% ok (used 49984 images)
时间: 2713.406982 ms
Test Classification result: 10.01% ok (used 9984 images)
轮次:18
learn rate:0.0001
时间: 32369.666016 ms
train Classification result: 42.47% ok (used 49984 images)
时间: 2754.810059 ms
Test Classification result: 9.99% ok (used 9984 images)
轮次:19
learn rate:0.0001
时间: 32076.615234 ms
train Classification result: 43.46% ok (used 49984 images)
时间: 2479.541016 ms
Test Classification result: 10.00% ok (used 9984 images)
轮次:20
learn rate:1e-05
时间: 32186.339844 ms
train Classification result: 45.74% ok (used 49984 images)
时间: 2490.629883 ms
Test Classification result: 65.30% ok (used 9984 images)
轮次:21
learn rate:1e-05
时间: 32510.169922 ms
train Classification result: 46.01% ok (used 49984 images)
时间: 2530.877930 ms
Test Classification result:
65.53**% ok (used 9984 images)
轮次:22
learn rate:1e-05
时间: 32729.812500 ms
train Classification result: 46.20% ok (used 49984 images)
时间: 2713.955078 ms
Test Classification result:** 65.52**% ok (used 9984 images)
轮次:23
learn rate:1e-05
时间: 32674.888672 ms
train Classification result: 46.23% ok (used 49984 images)
时间: 2521.415039 ms
Test Classification result: 64.38% ok (used 9984 images)**

class ShixianResidualyolo :public Layer {
public:
ShixianResidualyolo(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, 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 ));
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));
cudaMalloc(&input2, batch * _c * _h * _w * sizeof(float));

cudaMalloc(&d_residual, batch * _c * _h * _w * sizeof(float));
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();//这里的input与input2的nchw相同
}

int NN = batch * _c * _h * _w;
shortcut_gpu(batch, _w, _h, _c, input2, _w , _h , _c , input);
cudaMemcpy(output, input, sizeof(float) * NN, cudaMemcpyDeviceToDevice);
error_handling(cudaGetLastError());

}
void forward2(float* input_)override {//这里的虚线残差比lenet中复杂,w,h不一样,c也不一样!202609110724

input = input_;
input2 = input_;
for (const auto& l : layers) {
l->forward2(input);
input = l->get_output();
}
int NN = batch * _c * _h * _w ;

shortcut_gpu(batch, _w, _h, _c, input2, _w , _h , _c , input);
cudaMemcpy(output, input, sizeof(float) * NN, cudaMemcpyDeviceToDevice);
error_handling(cudaGetLastError());
}

void backward(float* grad_output)override {//虚线反向传播明天继续!202609101937,虚线和实线yolo v3残差块都已经实现202609130729
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();
}// batch, _c, _h , _w ,正路已经到达,

int NN = batch * _c * _h * _w ;

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

mul << <blocks, threads >> > (grad备用, output, d_residual, NN);//略有不同202609130730
error_handling(cudaGetLastError());
shortcut_gpu(batch, _w , _h , _c , d_residual, _w, _h, _c, grad);
cudaMemcpy(grad_input, grad, sizeof(float) * NN, cudaMemcpyDeviceToDevice);
error_handling(cudaGetLastError());
}
int getname() override { return 46; }
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);

}
}

~ShixianResidualyolo() {
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;

};

架构如下:

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

//第一残差开始

layers.emplace_back(std::make_shared<residualExt22>(cudnn, batch, 32, 32, 32));

//第二残差开始

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

layers.emplace_back(std::make_shared<residualExt22>(cudnn, batch, 64, 32, 32));

//第三残差开始,yolo虚线残差

//xuxianResidual

layers.emplace_back(std::make_shared<xuxianResidual2>(cudnn, batch, 64, 32, 32));

layers.emplace_back(std::make_shared<ShixianResidualyolo>(cudnn, batch, 128, 16, 16));// yolo实线残差

layers.emplace_back(std::make_shared<Conv2D>(cudnn, batch, 128, 256, 16, 16, 3, 1, 1));

layers.emplace_back(std::make_shared<residualExt22>(cudnn, batch, 256, 16, 16));

layers.emplace_back(std::make_shared<averPool2D>(cudnn, batch, 256, 16,16, 2, 2, 0, 2));

layers.emplace_back(std::make_shared<Linear>(cublas, batch, 256 * 64, 384));

layers.emplace_back(std::make_shared<BN>(cudnn, batch, 384, 1, 1));

layers.emplace_back(std::make_shared<LeakyRL>(cudnn, batch, 384, 1, 1));

layers.emplace_back(std::make_shared<Dropout>(cudnn, batch, 384, 1, 1));//=0.5

layers.emplace_back(std::make_shared<Linear>(cublas, batch, 384, 10));

昨天是初恋生日,送出了祝福!初恋是人生中最美好的!人生中应保持这种美好!今天骑车,突然明白,王安石游褒禅山记,只可远观不可亵玩也!初中真是初中!过了几十年,还是那样美好!

徐志摩也说:轻轻我,来了,正如我轻轻的走,我挥一挥衣袖,不带走一片云彩!

早上经过五门堰,看着河中那招摇的水草!美了几十年!颇有感慨!

一种得不到的美好,谁说你没得到呢?!

相关推荐
工业机器视觉设计和实现4 小时前
c++ cudnn模仿resnet18训练cifar10(70分)
cudnn微积分·虚线残差块实现
工业机器视觉设计和实现1 天前
实现pytorch resnet18功能(四,c++ cudnn)
cudnn微积分·虚线残差块实现·cifar10训练
工业机器视觉设计和实现3 天前
训练cifar100的临界点到来!(59.94分到来!)
cudnn微积分
工业机器视觉设计和实现19 天前
cudnn训练cifar100(摸到pytorch尾灯,54.94分)
cudnn微积分
工业机器视觉设计和实现1 个月前
再攻下1分!
人工智能·cudnn微积分
工业机器视觉设计和实现2 个月前
cifar10训练突破80分(三,摸到pytorch尾灯!)
人工智能·pytorch·cudnn微积分
工业机器视觉设计和实现2 个月前
动量的好处与困扰(二,摸到pytorch尾灯!)
人工智能·pytorch·cudnn微积分
工业机器视觉设计和实现2 个月前
cifar10测试79分是什么水平
cudnn微积分
工业机器视觉设计和实现2 个月前
yolo darknet的启示(残差相加放在leakrelu之后)
cudnn微积分