视觉学习笔记8——暗网darknet的使用与cfg文件解析

系列文章目录



前言

darkent是个轻量级深度学习训练框架,用c和cuda编写,支持GPU加速。你可以理解为darknet和tensorflow, pytorch, caffe, mxnet一样,是用于跑模型的底层,像resnet、yolo是模型结构,是一种训练网络

darknet是YOLO作者自己写的一个深度学习框架(见YOLO原文2.2部分),后来在YOLO9000中又提了一个基于ResNet魔改的19层卷积网络,称为Darknet-19,在YOLOv3中又提了一个更深的Darknet-53,这两个都是用于提取特征的主干网络。像yolov2、v3、v4、v7都可以在Darknet框架上实现(yolov5是用pytorch)。其主要特点就是容易安装,没有任何依赖项(OpenCV都可以不用),移植性非常好,支持CPU与GPU两种计算方式。

采用底层C语言有利于运行效率的提高,对一些算法库依赖有利于减轻体量,移植性独立性好可以多用于嵌入式等小算力小成本板子(不包括训练)。

相比于TensorFlow与pytorch这些大框架来说,darknet并没有那么强大,但darknet也有自己的优势:
1.易于安装:在makefile里面选择自己需要的附加项(cuda,cudnn,opencv等)直接make即可,几分钟完成安装;
2.没有任何依赖项:整个框架都用C语言进行编写,可以不依赖任何库,连opencv作者都编写了可以对其进行替代的函数;
3.结构明晰,源代码查看、修改方便:其框架的基础文件都在src文件夹,而定义的一些检测、分类函数则在example文件夹,可根据需要直接对源代码进行查看和修改;
4.友好python接口:虽然darknet使用c语言进行编写,但是也提供了python的接口,通过python函数,能够使用python直接对训练好的.weight格式的模型进行调用;
5.易于移植:该框架部署到机器本地十分简单,且可以根据机器情况,使用cpu和gpu,特别是检测识别任务的本地端部署,darknet会显得异常方便。


一、NoMachine、FileZilla与服务器

一些非本文重点但会用到的:

NoMachine安装与使用
NoMachine用于远程连接服务器,前提是你的服务器允许外网连接。

FileZilla安装与使用
FileZilla用于本地与服务器连接进行文件传输,前提是你的服务器允许外网连接。

服务器使用多用户,避免影响主用户。


二、安装配置darknet

1、下载

github官网AB版

(很有暗网黑科技感的设计)
darknet魔法阵
darknet官网

2、编译

  1. 首先你要有自己的深度学习环境,具体环境安装配置可以参考我以前的博客去配置,再根据自己的配置环境,修改Makefile值
    在这里插入图片描述

问题一:NVCC问题

nvcc -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=[sm_50,compute_50] -gencode arch=compute_52,code=[sm_52,compute_52] -Iinclude/ -Isrc/ -DOPENCV pkg-config --cflags opencv -DGPU -I/usr/local/cuda/include/ -DCUDNN --compiler-options “-Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN” -c ./src/convolutional_kernels.cu -o obj/convolutional_kernels.o
/bin/sh: 1: nvcc: not found
Makefile:89: recipe for target ‘obj/convolutional_kernels.o’ failed
make: *** [obj/convolutional_kernels.o] Error 127

解决办法:

进入darknet目录,编辑Makefile,修改NVCC路径。
在这里插入图片描述

  1. 在darknet文件夹下执行命令
make
  1. 编译成功
    在这里插入图片描述

问题二:yolo_console_dll.cpp:(.text.startup+0x2ec)问题

make编译darknet时,报错

在函数‘main’中: yolo_console_dll.cpp:(.text.startup+0x2ec):对‘Detector::Detector(std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, int, int)’未定义的引用 collect2: error: ld returned 1 exit status Makefile:173: recipe for target 'uselib' failed make: *** [uselib] Error 1

解决办法:

借鉴#7654
进入Makefile文件

注释

#$(CPP) -std=c++11 $(COMMON) $(CFLAGS) -o $@ src/yolo_console_dll.cpp $(LDFLAGS) -L ./ -l:$(LIBNAMESO)

更改为

$(CPP) -std=c++11 $(COMMON) $(CFLAGS) -o $@ src/yolo_console_dll.cpp $(LDFLAGS) -L ./ $(LIBNAMESO)

三、数据集与模型准备

1、数据集下载

来源:第十五届中国计算机设计大赛智慧导盲组基线系统

结构:

WisdomGuide______annotations______train_list.txt
		     |			      |___val_list.txt
		     |			      |___instance_train.json
		     |			      |___instance_val.json
		     |_______train________JPEGImages___图片文件
 		     |                |___labels___标签文件
		     |________val________JPEGImages___图片文件
		                      |___labels___标签文件

修改数据集的分布,新建train、val、JPEGImages和labels文件夹,其中train是存放训练集,val存放测试集,JPEGImages放图片,labels放标签文件,train_list.txt是所有训练图片路径,val_list.txt是所有测试图片路径。这些文件的建立与分布是有规律有原因的,如果不想修改代码就用这个数据集格式。

注意对于图片文件夹JPEGImages和标签文件夹labels,如果想把图片和标签分开放在不同文件夹,那么对于的文件夹名称必须是JPEGImages和labels,如果想图片和标签混合放在同一个文件夹下那么就不要用这两名字。

train_list.txt、val_list.txt、标签txt文件由下面的脚本生成。

2、json转txt脚本和路径聚合脚本

json_txt.py:
更改成自己的路径


import os
import json
from tqdm import tqdm
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--json_path', default='/home/nh666/llw/ORB_FAR/WisdomGuide/annotations/instance_val.json', type=str, help="input: coco format(json)")
parser.add_argument('--save_path', default='/home/nh666/llw/ORB_FAR/WisdomGuide/annotations/val_txt', type=str, help="specify where to save the output dir of labels")
arg = parser.parse_args()


def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = box[0] + box[2] / 2.0
    y = box[1] + box[3] / 2.0
    w = box[2]
    h = box[3]

    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


if __name__ == '__main__':
    json_file = arg.json_path  # COCO Object Instance 类型的标注
    ana_txt_save_path = arg.save_path  # 保存的路径

    data = json.load(open(json_file, 'r'))
    if not os.path.exists(ana_txt_save_path):
        os.makedirs(ana_txt_save_path)

    id_map = {
    
    }  # coco数据集的id不连续!重新映射一下再输出!
    for i, category in enumerate(data['categories']):
        id_map[category['id']] = i

    # 通过事先建表来降低时间复杂度
    max_id = 0
    for img in data['images']:
        max_id = max(max_id, img['id'])
    # 注意这里不能写作 [[]]*(max_id+1),否则列表内的空列表共享地址
    img_ann_dict = [[] for i in range(max_id + 1)]
    for i, ann in enumerate(data['annotations']):
        img_ann_dict[ann['image_id']].append(i)

    for img in tqdm(data['images']):
        filename = img["file_name"]
        img_width = img["width"]
        img_height = img["height"]
        img_id = img["id"]
        head, tail = os.path.splitext(filename)
        ana_txt_name = head + ".txt"  # 对应的txt名字,与jpg一致
        f_txt = open(os.path.join(ana_txt_save_path, ana_txt_name), 'w')
        '''for ann in data['annotations']:
            if ann['image_id'] == img_id:
                box = convert((img_width, img_height), ann["bbox"])
                f_txt.write("%s %s %s %s %s\n" % (id_map[ann["category_id"]], box[0], box[1], box[2], box[3]))'''
        # 这里可以直接查表而无需重复遍历
        for ann_id in img_ann_dict[img_id]:
            ann = data['annotations'][ann_id]
            box = convert((img_width, img_height), ann["bbox"])
            f_txt.write("%s %s %s %s %s\n" % (id_map[ann["category_id"]], box[0], box[1], box[2], box[3]))
        f_txt.close()

path_synthesis.py:
更改成自己的路径

# -*- coding: utf-8 -*-
import time
import os
import shutil

# 获取所有文件路径集合

def readFilename(path, allfile):
    filelist = os.listdir(path)

    for filename in filelist:
        filepath = os.path.join(path, filename)
        if os.path.isdir(filepath):
            readFilename(filepath, allfile)
        else:
            allfile.append(filepath)
    return allfile


if __name__ == '__main__':
    # 文件夹路径
    path1 = "/home/nh666/llw/ORB_FAR/WisdomGuide/val"
    allfile1 = []
    allfile1 = readFilename(path1, allfile1)
    allname1 = []
    # 文件路径
    txtpath = "/home/nh666/llw/ORB_FAR/WisdomGuide/annotations/val_list.txt"
    for name in allfile1:
        print(name)
        file_cls = name.split("/")[-1].split(".")[-1]
        # 后缀名
        if file_cls == 'png':
            print(name.split("/")[-1])
            with open(txtpath, 'a+') as fp:
                fp.write("".join(name) + "\n")

3、文件修改

1. .names文件

复制一份darknet/data/voc.names文件并重命名为voc_blind.names,里面存放的是训练的类别,不过在训练时不会真的标注为什么什么东西,而是标注为01234序号,所以文件中的类别名的排序是很重要的,要对应你的标签txt文件。

在这里插入图片描述

2. .data文件

复制一份darknet/cfg/voc.data文件并重命名为voc_blind.data,里面存放的是classes类别数、train/valid数据集路径、names类别名路径、backup模型路径,需要根据自己的位置修改。
在这里插入图片描述

3. .cfg文件

前段日子yolov7发布了,发现darknet也有实现,本来打算用v7的,但是训练时发现训练不了,报错

 cuDNN status Error in: file: ./src/convolutional_kernels.cu : () : line: 555 : build time: Oct 26 2022 - 16:19:38 
 cuDNN Error: CUDNN_STATUS_BAD_PARAM
Darknet error location: ./src/dark_cuda.c, cudnn_check_error, line #204
cuDNN Error: CUDNN_STATUS_BAD_PARAM: Resource temporarily unavailable

解决思路:
主要有三种思路

  1. 更改CUDA和CUDNN版本,具体是哪些版本就不清楚了
  2. 训练时不使用-map命令,不计算mAP
  3. 更改调整batch和subdivisions的值,具体是多少就不清楚了

我选择在cfg里将batch和subdivisions更改为 64 解决了这个问题,这个更改似乎与你的训练硬件相关,比如单卡、多卡、cpu、gpu等。

batch=64
subdivisions=64  # changed from 16 to 64
width=416
height=416

至于CUDA和CUDNN的话,我查了一下github里的讨论区,似乎需要改cuDNN版本,但是我是在服务器训练,不能随便改,所以退而求次用yolov4。

4. yolov4-tiny.cfg

复制一份darknet/cfg/yolov4-tiny.cfg文件并重命名为yolov4_blind.cfg,更改设置:
subdivisions为8的倍数,如果 GPU 显存大 subdivisions 可以 填 8,显存小时可以填 32。
max_batches为最大训练次数,与样本数量无直接关系,建议是样本数×2000,避免拟合问题。
steps改为 max_batches 的 80% and 90%。

subdivisions=8
max_batches = 10000
steps=8000,9000

ctrl+F搜索“yolo”关键字,有几个改几个,继续更改:

filters=30 //公式计算(5+类别数)×3
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
classes=5

四、训练与测试

1、终端训练

单卡

进入darknet文件夹,进入终端,执行以下命令:

 sudo ./darknet detector train cfg/voc_blind.data cfg/yolov4_blind.cfg -map

训练结果map
在这里插入图片描述

多卡

先查询是否是多卡gpu

#静态查询
nvidia-smi  

 #动态查询 每10秒检查gpu使用情况
watch -n 10 nvidia-smi 

看看那些卡是没有被占用的,被占用说明有别人在训练啥的特别是在服务器上,别乱动别人的东西。

比如说我的是四卡,其中0,1卡GPU-Util占比为0%,那么就用0,1卡空闲。

sudo ./darknet detector train cfg/voc_blind.data cfg/yolov4_blind.cfg  -gpus 0,1 -map

多卡速度就是比单卡快

在这里插入图片描述
参数解释:

表格中会显示显卡的一些信息,第一行是版本信息,第二行是标题栏,第三行就是具体的显卡信息了,如果有多个显卡,会有多行,每一行的信息值对应标题栏对应位置的信息。

* GPU:编号,这里是012,3

* Fan:风扇转速,在0100%之间变动,第一个是32%

* Name:显卡名,这里都是GeForce

* Temp:显卡温度,第一个是55摄氏度

* Perf:性能状态,从P0到P12,P0性能最大,P12最小

* Persistence-M:持续模式的状态开关,该模式耗能大,但是启动新GPU应用时比较快,这里是off

* Pwr:能耗

* Bus-Id:GPU总线

* Disp.A:表示GPU的显示是否初始化

* Memory-Usage:显存使用率

* GPU-Util:GPU利用率,第一个是22%,第二个6%

* Compute M.:计算模式

需要注意的一点是显存占用率和GPU占用率是两个不一样的东西,类似于内存和CPU,两个指标的占用率不一定是互相对应的。

报错1

CUDA Error: out of memory
Darknet error location: ./src/dark_cuda.c, check_error, line #69
CUDA Error: out of memory: No such file or directory

意思就是内存不足,有两种可能要么就是你的GPU内存满了,可以用nvidia-smi看看,要么就是.cfg文件的batch和subdivisions值可能太大了,可以改为64>32>16>8>1等等。

2、模型保存

best 模型是在训练过程中取得最佳性能的模型。它通常是在验证集上取得最佳性能的模型。

final 模型是在训练过程结束时保存的模型。它通常是在完成训练后保存的最后一个模型。

last 模型是在训练过程中最后一次保存的模型。它通常是在训练过程中的某个时刻保存的模型,并不一定是最佳性能的模型。

因此,这三个模型代表了训练过程中不同时间保存的模型,可以用来比较模型的性能,并选择最佳模型进行推理。

在dackup下,其中它认为best是最佳的。
在这里插入图片描述

3、测试

1.图片测试

sudo ./darknet detector test cfg/voc_blind.data cfg/yolov4_blind.cfg backup/yolov4_blind_best.weights

运行后还会需要你去输入图片路径。
在这里插入图片描述

2.val验证

sudo ./darknet detector valid cfg/voc_blind.data cfg/yolov4_blind.cfg backup/yolov4_blind_best.weights

运行后会生成验证集val的验证文件。
在这里插入图片描述

3.实时检测

源码

在这里插入图片描述

五、cfg文件解读

以resnet50.cfg模型文件为例:

#darknet中用于定义网络结构的组件,它包含了一系列参数,用于指定网络的输入大小、batch大小、学习率等,还可以指定网络的类型和激活函数,以及指定网络的权重初始化方式。
[net]
# Training
#每次训练时,darknet将从训练数据集中抽取128个样本进行训练。
batch=128
#每次训练时,使用4个mini-batch,每个mini-batch的大小等于batch_size/4,这样可以提高训练速度和精度,训练时间可能会延长。
subdivisions=4

# Testing
# batch=1
# subdivisions=1

#样本数据设置
#输入图片的高度和宽度
height=256
width=256
#在图像预处理时,将图像裁剪为448x448像素大小。,可以提高网络的训练速度和准确率。
max_crop=448
#图像的通道数,即RGB图像的通道数
channels=3
#momentum梯度下降算法中的一个超参数,可以帮助模型更快地收敛。通过记录每次更新的梯度,在每次迭代时将其累积到当前梯度中来实现。
#每次更新梯度时,模型会将上一次梯度的90%累积到当前梯度中。
momentum=0.9
#学习率衰减系数,即每次训练后学习率会乘以衰减系数,以减小学习率,减少模型过拟合。
decay=0.0005

#训练方式设置
#在训练神经网络之前,使用1000个训练数据来初始化权重,以确保神经网络能够正确地从训练开始,前1000层的权重都将被设置为预训练的权重,而后面的层则被随机初始化。
burn_in=1000
#每次迭代模型时更新后参数与原参数之间的比例。0.1表示每次更新后参数与原参数之间的比例为10%。
learning_rate=0.1
#使用poly来调整学习率。,可以帮助模型更快地收敛。
#学习率优化策略,根据训练步骤的不同改变学习率,从而更有效地训练神经网络有效地提高模型的性能。
policy=poly
#表示使用的是ReLU激活函数,使用4倍的梯度下降加速训练。power越大,激活函数越陡峭,模型越容易收敛,但也可能会导致过拟合。
power=4
#神经网络训练的最大次数,1600000次表示训练过程将会运行1600000次
max_batches=1600000

#图像优化处理设置
#使用7个不同的角度(0°,45°,90°,135°,180°,225°,270°)来增强图像,以提高模型的鲁棒性。
angle=7
#hue=.1是图像的色调参数,表示色调偏移量为0.1,可以控制图像的色彩深浅,以及色彩组合的调整。
hue=.1
#色彩饱和度,它是影响图像色彩的一个参数,取值范围为[0,1],取值越大,图像的色彩饱和度越高。
saturation=.75
#图像的曝光度。它是一种图像增强技术,可以改变图像中每个像素的亮度,以改善模型的泛化能力。
exposure=.75
#图像的宽高比,aspect=.75表示要求输入的图像宽高比必须是0.75
aspect=.75

#卷积操作参数设置
#darknet中的一个层,它可以实现卷积操作,以提取图像的特征。卷积层是神经网络中最重要的层之一,它可以提取图像中的特征,并将它们传递给下一层。
[convolutional]
#启用batch normalization,这意味着每个卷积层都会在每次训练时进行规范化,以提高模型的准确性和效率。
batch_normalize=1
#每一次卷积过后的输出通道数,也就是卷积滤波器的数量。每一层卷积层都有一个卷积核,每个卷积核都会产生一个输出通道,filters=64表示每一层卷积层的卷积核个数和输出通道数为64。
filters=64
#卷积核尺寸
size=7
#每次卷积操作的步长为2,即每次卷积操作后,特征图的尺寸减少一半
stride=2
#在每一层卷积操作之前,先在输入图像的四周填充1个像素的边缘,这样可以避免边缘信息的损失。
pad=1
#Leaky ReLU激活函数,它允许一定程度的梯度流失,这有助于防止神经网络中出现的梯度消失问题,从而提高模型的准确性和精确性。
activation=leaky

#最大下采样池化层,用于提取图像中的最大值,以减少图像的尺寸,并保留最重要的特征,可以减少计算量,提高模型的准确性,并且可以防止过拟合。
[maxpool]
#卷积核尺寸为2
size=2
#每次卷积操作的步长为2,即每次卷积操作后,特征图的尺寸减少一半
stride=2

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
#线性激活函数,即没有任何激活函数。这意味着神经元的输出值与输入值之间没有任何变化,这种情况通常用于输出层,因为输出层通常需要线性激活函数来计算预测结果。这种激活函数可以有效地减少网络的复杂性,并可以保证网络的稳定性。
activation=linear

#残差网络中的一种融合做加法技术,它允许在相同层之间建立一条直接的路径,从而将输入信号直接传递到输出层。这样可以减少计算量,提高网络的性能。
[shortcut]
#从第四层开始,从而实现残差网络的特征提取。
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=3
stride=2
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky


# Conv 4
[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=3
stride=2
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=1024
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=1024
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=1024
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=1024
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=1024
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=1024
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

#Conv 5
[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=3
stride=2
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=2048
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=2048
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=2048
size=1
stride=1
pad=1
activation=linear

[shortcut]
from=-4
activation=leaky

[convolutional]
filters=1000
size=1
stride=1
pad=1
activation=linear

#均值池化层,它是一种特殊类型的池化层,可以将输入特征图的每个通道求均值,并将输出转换为1x1xC的特征图
[avgpool]

#激活函数,它将输入的任意实数值映射到0到1之间的概率值,用于分类问题。它可以将多个输入值映射到唯一的输出概率值,因此可以用于多类分类问题。
[softmax]
#使用的是单组卷积,即只有一个组卷积层,而不是多组卷积层。这种架构的网络在深度学习中被称为ResNet,它使用了残差连接来提升模型的准确率。
groups=1

#使用的是平方损失函数,该函数可以衡量预测值和实际值之间的差异,从而帮助模型改进。
[cost]
#使用SSE(Streaming SIMD Extensions)指令集来加速神经网络的计算。SSE是一种用于改善CPU的流水线性能的指令集,可以更有效地运行多个数学运算。
type=sse

猜你喜欢

转载自blog.csdn.net/qq_45848817/article/details/127529504