nets[i] = load_network(cfgfile, weightfile, clear);

29 篇文章 1 订阅
27 篇文章 2 订阅
 nets[i] = load_network(cfgfile, weightfile, clear);

其函数主体如下所示

network *load_network(char *cfg, char *weights, int clear)
{
    network *net = parse_network_cfg(cfg);//通过cfg文件构建网络,其函数主体见下
    //若是存在权重文件且权重第一行不为0,则加载权重
    if(weights && weights[0] != 0)
    {
        load_weights(net, weights);
    }
    if(clear) (*net->seen) = 0;//若是clear不为0,则将*net->seen置为0
    return net;
}

parse_network_cfg函数主体

network *parse_network_cfg(char *filename)
{
    list *sections = read_cfg(filename);//将cfg文件保存到list链表中,与之前的读取保存data_cfg文件类似,具体函数见[博客](https://blog.csdn.net/m0_37799466/article/details/106018636)
    node *n = sections->front;//创建一个node指针指向node链表的首元结点
    if(!n) error("Config file has no sections");
    network *net = make_network(sections->size - 1);//为网络层分配空间,会去掉第一层net层,它保存的是训练参数,不是网络结构,具体过程查看博客[make_network函数主体](https://blog.csdn.net/m0_37799466/article/details/106025161)
    net->gpu_index = gpu_index;//保存GPU代号,用来记录第几个GPU
    size_params params;//声明一个size_params结构体;之后会用了保存训练参数
    /*size_params结构体
	typedef struct size_params{
    int batch;
    int inputs;
    int h;
    int w;
    int c;
    int index;
    int time_steps;
    network *net;
	} size_params;
	*/

    section *s = (section *)n->val;//定义一个section指针并令他指向第一个section结构体
    list *options = s->options;//定义一个list指针并令他指向list结构体
    if(!is_network(s)) error("First section must be [net] or [network]");
    parse_net_options(options, net);//初始化网络参数,具体参考[博客](https://blog.csdn.net/m0_37799466/article/details/106047533)
	//通过network结构体中保存的参数对param结构体进行初始化
    params.h = net->h;
    params.w = net->w;
    params.c = net->c;
    params.inputs = net->inputs;
    params.batch = net->batch;
    params.time_steps = net->time_steps;
    params.net = net;

    size_t workspace_size = 0;
    n = n->next;//令node指针指向第一层网络
    int count = 0;//用于之后的网络层计数
    free_section(s);//释放s指针,即释放指向[net]这一层的指针
    fprintf(stderr, "layer     filters    size              input                output\n");
    while(n){
        params.index = count;
        fprintf(stderr, "%5d ", count);
        s = (section *)n->val;//令指针s指向保存网络的section
        options = s->options;//令指针options指向保存网络层参数的list结构体
        layer l = {0};//定义网络层l并初始化为0
        LAYER_TYPE lt = string_to_layer_type(s->type);//通过s->type得到网络层名称,用于之后的网络设置,通过判断是哪一种网络来选择进入哪一种函数
        if(lt == CONVOLUTIONAL){
            l = parse_convolutional(options, params);//构建卷积网络层架构,具体参考[博客](https://blog.csdn.net/m0_37799466/article/details/106049733)
        }else if(lt == DECONVOLUTIONAL){
            l = parse_deconvolutional(options, params);
        }else if(lt == LOCAL){//定位层,具体参考[博客](https://blog.csdn.net/m0_37799466/article/details/106060660)
            l = parse_local(options, params);
        }else if(lt == ACTIVE){
            l = parse_activation(options, params);
        }else if(lt == LOGXENT){
            l = parse_logistic(options, params);
        }else if(lt == L2NORM){
            l = parse_l2norm(options, params);
        }else if(lt == RNN){
            l = parse_rnn(options, params);
        }else if(lt == GRU){
            l = parse_gru(options, params);
        }else if (lt == LSTM) {
            l = parse_lstm(options, params);
        }else if(lt == CRNN){
            l = parse_crnn(options, params);
        }else if(lt == CONNECTED){//全连接层,具体参考[博客](https://blog.csdn.net/m0_37799466/article/details/106080466)
            l = parse_connected(options, params);
        }else if(lt == CROP){
            l = parse_crop(options, params);
        }else if(lt == COST){
            l = parse_cost(options, params);
        }else if(lt == REGION){
            l = parse_region(options, params);
        }else if(lt == YOLO){
            l = parse_yolo(options, params);
        }else if(lt == ISEG){
            l = parse_iseg(options, params);
        }else if(lt == DETECTION){//检测层,具体见[博客](https://blog.csdn.net/m0_37799466/article/details/106081309)
            l = parse_detection(options, params);
        }else if(lt == SOFTMAX){
            l = parse_softmax(options, params);
            net->hierarchy = l.softmax_tree;
        }else if(lt == NORMALIZATION){
            l = parse_normalization(options, params);
        }else if(lt == BATCHNORM){
            l = parse_batchnorm(options, params);
        }else if(lt == MAXPOOL){//构建最大池化层架构,具体参考[博客](https://blog.csdn.net/m0_37799466/article/details/106060370)
            l = parse_maxpool(options, params);
        }else if(lt == REORG){
            l = parse_reorg(options, params);
        }else if(lt == AVGPOOL){
            l = parse_avgpool(options, params);
        }else if(lt == ROUTE){
            l = parse_route(options, params, net);
        }else if(lt == UPSAMPLE){
            l = parse_upsample(options, params, net);
        }else if(lt == SHORTCUT){
            l = parse_shortcut(options, params, net);
        }else if(lt == DROPOUT){//防止过拟合层,具体参考[博客](https://blog.csdn.net/m0_37799466/article/details/106076702)
            l = parse_dropout(options, params);
            l.output = net->layers[count-1].output;//将上一层的输出赋给此层输出
            l.delta = net->layers[count-1].delta;
#ifdef GPU
            l.output_gpu = net->layers[count-1].output_gpu;
            l.delta_gpu = net->layers[count-1].delta_gpu;
#endif
        }else{
            fprintf(stderr, "Type not recognized: %s\n", s->type);//若是不存在type,则输出没有此层
        }
        //设置每一层的各种参数
        l.clip = net->clip;
        l.truth = option_find_int_quiet(options, "truth", 0);
        l.onlyforward = option_find_int_quiet(options, "onlyforward", 0);
        l.stopbackward = option_find_int_quiet(options, "stopbackward", 0);
        l.dontsave = option_find_int_quiet(options, "dontsave", 0);
        l.dontload = option_find_int_quiet(options, "dontload", 0);
        l.numload = option_find_int_quiet(options, "numload", 0);
        l.dontloadscales = option_find_int_quiet(options, "dontloadscales", 0);
        l.learning_rate_scale = option_find_float_quiet(options, "learning_rate", 1);
        l.smooth = option_find_float_quiet(options, "smooth", 0);
        option_unused(options);//判断used内是否为0,若是为0则此层不能使用,used是在加载网络是修改的
        /*
        void option_unused(list *l)
		{
    		node *n = l->front;
    		while(n){
        		kvp *p = (kvp *)n->val;
        		if(!p->used){
            		fprintf(stderr, "Unused field: '%s = %s'\n", p->key, p->val);
        		}
        		n = n->next;
   	 		}
		}
        */
        net->layers[count] = l;//构建好的该层网络结构赋给第count层网络
        if (l.workspace_size > workspace_size) workspace_size = l.workspace_size;
        free_section(s);//释放s指针
        n = n->next;//令指针n指向下一个node结点,即指向下一层网络
        ++count;//计数加一
        if(n){//设置下一层网络的输入,即这一层输出
            params.h = l.out_h;
            params.w = l.out_w;
            params.c = l.out_c;
            params.inputs = l.outputs;
        }
    }
    free_list(sections);//释放指针
    layer out = get_network_output_layer(net);//设置网络层的输出,即检测层
    /*
    layer get_network_output_layer(network *net)
	{
    	int i;
    	for(i = net->n - 1; i >= 0; --i){
        	if(net->layers[i].type != COST) break;
    	}
    return net->layers[i];
	}
    */
    net->outputs = out.outputs;//设置好的网络输出接口
    net->truths = out.outputs;//令标签与网络输出接口一样
    //如果最后一层(即检测层)存在标签,则将net->truths设置为与最后一层标签数相同
    if(net->layers[net->n-1].truths) net->truths = net->layers[net->n-1].truths;
    net->output = out.output;//设置网络中net->output指针指向min_batch输出内存的入口地址
    net->input = calloc(net->inputs*net->batch, sizeof(float));//为min_batch输入分配内存,min_batchx448x448x3
    net->truth = calloc(net->truths*net->batch, sizeof(float));//为min_batch标签分配内存,与输出相同,s*s*(num*(4+1)+classes)
#ifdef GPU//定义了GPU,则运行下面代码
    net->output_gpu = out.output_gpu;
    net->input_gpu = cuda_make_array(net->input, net->inputs*net->batch);
    net->truth_gpu = cuda_make_array(net->truth, net->truths*net->batch);
#endif
    if(workspace_size){
        //printf("%ld\n", workspace_size);
#ifdef GPU
        if(gpu_index >= 0){
            net->workspace = cuda_make_array(0, (workspace_size-1)/sizeof(float)+1);
        }else {
            net->workspace = calloc(1, workspace_size);
        }
#else
        net->workspace = calloc(1, workspace_size);
#endif
    }
    return net;
}

LAYER_TYPE枚举类型

typedef enum {
    CONVOLUTIONAL,
    DECONVOLUTIONAL,
    CONNECTED,
    MAXPOOL,
    SOFTMAX,
    DETECTION,
    DROPOUT,
    CROP,
    ROUTE,
    COST,
    NORMALIZATION,
    AVGPOOL,
    LOCAL,
    SHORTCUT,
    ACTIVE,
    RNN,
    GRU,
    LSTM,
    CRNN,
    BATCHNORM,
    NETWORK,
    XNOR,
    REGION,
    YOLO,
    ISEG,
    REORG,
    UPSAMPLE,
    LOGXENT,
    L2NORM,
    BLANK
} LAYER_TYPE;

load_weights(net, weights);函数主题

void load_weights(network *net, char *filename)
{
    load_weights_upto(net, filename, 0, net->n);
}

load_weights_upto(net, filename, 0, net->n);函数主题

void load_weights_upto(network *net, char *filename, int start, int cutoff)
{
#ifdef GPU
    if(net->gpu_index >= 0){
        cuda_set_device(net->gpu_index);
    }
#endif
    fprintf(stderr, "Loading weights from %s...", filename);
    fflush(stdout);
    /*
    其功能是使用给定的模式mode打开filename所指向的文件。文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在error中。该函数位于C标准库<stdio.h>中。
    */
    FILE *fp = fopen(filename, "rb");
    if(!fp) file_error(filename);

    int major;
    int minor;
    int revision;
    /*
    size_t fread( void *buffer, size_t size, size_t count, FILE *stream );//C99前
	size_t fread( void *restrict buffer, size_t size, size_t count, FILE *restrict stream );//C99起
    从给定输入流stream读取最多count个对象到数组buffer中(相当于以对每个对象调用size次fgetc),把buffer当	作unsigned char数组并顺序保存结果。流的文件位置指示器前进读取的字节数。若出现错误,则流的文件位置指示器的位	置不确定。若没有完整地读入最后一个元素,则其值不确定。*/
    //fread函数的fp是流的入口地址不会变,但是流的文件位置指示器会前进读取的字节数,即相当于读过的不会再读
    //如下面代码示例,fp读完buffer里面4个元素后,流的文件位置指示器就会记录到这里,在读入buffer1时就会从这里开始读,但fp地址不会变
    /*
	#include <stdio.h>
	#include <string.h>
	#include<stdlib.h>


	int main()
	{
	FILE *fp;
	char c[] = "This is runoob";
	char buffer[20];
	char buffer1[20];
	//打开文件用于读写 
	fp = fopen("file.txt", "w+");

	//写入数据到文件 
	fwrite(c, strlen(c) + 1, 1, fp);

	//查找文件的开头 
	fseek(fp, 0, SEEK_SET);

	//读取并显示数据 
	fread(buffer, 4, 1, fp);
	printf("%p\n", fp);
	printf("%s\n", buffer);
	fread(buffer1, strlen(c) + 1, 1, fp);
	printf("%p\n", fp);
	printf("%s\n", buffer1);
	fclose(fp);
	system("pause");
	return(0);
	}
	*/

    //major = 0 minor = 1 revision = 0
    fread(&major, sizeof(int), 1, fp);
    fread(&minor, sizeof(int), 1, fp);
    fread(&revision, sizeof(int), 1, fp);
    if ((major*10 + minor) >= 2 && major < 1000 && minor < 1000){//含义不明
        fread(net->seen, sizeof(size_t), 1, fp);
    } else {
        int iseen = 0;
        fread(&iseen, sizeof(int), 1, fp);
        *net->seen = iseen;
    }
    int transpose = (major > 1000) || (minor > 1000);

    int i;
    //从start层开始到net->n与cutoff层逐层加载权重,默认start=0,即从第一层开始
    for(i = start; i < net->n && i < cutoff; ++i){
        layer l = net->layers[i];
        if (l.dontload) continue;//排除不想加载的网络层
        if(l.type == CONVOLUTIONAL || l.type == DECONVOLUTIONAL){
            load_convolutional_weights(l, fp);//加载卷积层或反卷积层权重
        }
        if(l.type == CONNECTED){
            load_connected_weights(l, fp, transpose);//加载全连接层权重
        }
        if(l.type == BATCHNORM){//加载批标准化权重
            load_batchnorm_weights(l, fp);
        }
        if(l.type == CRNN){
            load_convolutional_weights(*(l.input_layer), fp);
            load_convolutional_weights(*(l.self_layer), fp);
            load_convolutional_weights(*(l.output_layer), fp);
        }
        if(l.type == RNN){
            load_connected_weights(*(l.input_layer), fp, transpose);
            load_connected_weights(*(l.self_layer), fp, transpose);
            load_connected_weights(*(l.output_layer), fp, transpose);
        }
        if (l.type == LSTM) {
            load_connected_weights(*(l.wi), fp, transpose);
            load_connected_weights(*(l.wf), fp, transpose);
            load_connected_weights(*(l.wo), fp, transpose);
            load_connected_weights(*(l.wg), fp, transpose);
            load_connected_weights(*(l.ui), fp, transpose);
            load_connected_weights(*(l.uf), fp, transpose);
            load_connected_weights(*(l.uo), fp, transpose);
            load_connected_weights(*(l.ug), fp, transpose);
        }
        if (l.type == GRU) {
            if(1){
                load_connected_weights(*(l.wz), fp, transpose);
                load_connected_weights(*(l.wr), fp, transpose);
                load_connected_weights(*(l.wh), fp, transpose);
                load_connected_weights(*(l.uz), fp, transpose);
                load_connected_weights(*(l.ur), fp, transpose);
                load_connected_weights(*(l.uh), fp, transpose);
            }else{
                load_connected_weights(*(l.reset_layer), fp, transpose);
                load_connected_weights(*(l.update_layer), fp, transpose);
                load_connected_weights(*(l.state_layer), fp, transpose);
            }
        }
        if(l.type == LOCAL){//加载定位层权重
            int locations = l.out_w*l.out_h;//定位特征图尺寸大小
            int size = l.size*l.size*l.c*l.n*locations;//权重数量
            fread(l.biases, sizeof(float), l.outputs, fp);//从fp流中读取l.outputs个float类型大小的参数到l.biases中去,即对偏置赋值,会覆盖之前初始化的0
            fread(l.weights, sizeof(float), size, fp);从fp流中读取size个float类型大小的参数到l.weights中去,即对权重赋值,会覆盖之前的初始化值
#ifdef GPU//若是定义了GPU则运行下面代码,GPU运行的高效代码
            if(gpu_index >= 0){
                push_local_layer(l);
            }
#endif
        }
    }
    fprintf(stderr, "Done!\n");
    fclose(fp);
}

load_convolutional_weights(l, fp);//加载卷积层权重

void load_convolutional_weights(layer l, FILE *fp)
{
    if(l.binary){//这里基本都是0,所以不会执行,其中的函数也被注释了
        //load_convolutional_weights_binary(l, fp);
        //return;
    }
    if(l.numload) l.n = l.numload;//每层输出通道的数量,即输出特征图个数,这里基本都是0,不执行,即都加载
    int num = l.c/l.groups*l.n*l.size*l.size;//每层卷积层的权重参数数量
    fread(l.biases, sizeof(float), l.n, fp);//从fp流中读取l.n个float类型大小的参数到l.biases中去,即对偏置赋值,会覆盖之前初始化的0
    if (l.batch_normalize && (!l.dontloadscales)){//若是使用批标准化且加载scales时运行
        fread(l.scales, sizeof(float), l.n, fp);//从fp流中读取l.n个float类型大小的参数到l.scales中去
        fread(l.rolling_mean, sizeof(float), l.n, fp);//从fp流中读取l.n个float类型大小的参数到l.rolling_mean中去
        fread(l.rolling_variance, sizeof(float), l.n, fp);//从fp流中读取l.n个float类型大小的参数到l.rolling_variance中去
        if(0){
            int i;
            for(i = 0; i < l.n; ++i){
                printf("%g, ", l.rolling_mean[i]);
            }
            printf("\n");
            for(i = 0; i < l.n; ++i){
                printf("%g, ", l.rolling_variance[i]);
            }
            printf("\n");
        }
        if(0){
            fill_cpu(l.n, 0, l.rolling_mean, 1);
            fill_cpu(l.n, 0, l.rolling_variance, 1);
        }
        if(0){
            int i;
            for(i = 0; i < l.n; ++i){
                printf("%g, ", l.rolling_mean[i]);
            }
            printf("\n");
            for(i = 0; i < l.n; ++i){
                printf("%g, ", l.rolling_variance[i]);
            }
            printf("\n");
        }
    }
    fread(l.weights, sizeof(float), num, fp);//从fp流中读取num个float类型大小的参数到l.weights中去,即对权重赋值,会覆盖之前的初始化值
    //if(l.c == 3) scal_cpu(num, 1./256, l.weights, 1);
    if (l.flipped) {//权重转置
        transpose_matrix(l.weights, l.c*l.size*l.size, l.n);
    }
    //if (l.binary) binarize_weights(l.weights, l.n, l.c*l.size*l.size, l.weights);
#ifdef GPU//定义GPU则运行,但是好像没有定义下面函数,只是声明了,所以还是使用了CPU进行权重加载工作
    if(gpu_index >= 0){
        push_convolutional_layer(l);
    }
#endif
}

load_connected_weights(l, fp, transpose);//加载全连接层权重

void load_connected_weights(layer l, FILE *fp, int transpose)
{
    fread(l.biases, sizeof(float), l.outputs, fp);//从fp流中读取l.outputs个float类型大小的参数到l.biases中去,即对偏置赋值,会覆盖之前的初始化值
    fread(l.weights, sizeof(float), l.outputs*l.inputs, fp);//从fp流中读取l.outputs*l.inputs个float类型大小的参数到l.weights中去,即对权重赋值,会覆盖之前的初始化值
    if(transpose){//转置
        transpose_matrix(l.weights, l.inputs, l.outputs);
    }
    //printf("Biases: %f mean %f variance\n", mean_array(l.biases, l.outputs), variance_array(l.biases, l.outputs));
    //printf("Weights: %f mean %f variance\n", mean_array(l.weights, l.outputs*l.inputs), variance_array(l.weights, l.outputs*l.inputs));
    if (l.batch_normalize && (!l.dontloadscales)){//判断是否为批标准化且加载scales
        fread(l.scales, sizeof(float), l.outputs, fp);
        fread(l.rolling_mean, sizeof(float), l.outputs, fp);
        fread(l.rolling_variance, sizeof(float), l.outputs, fp);
        //printf("Scales: %f mean %f variance\n", mean_array(l.scales, l.outputs), variance_array(l.scales, l.outputs));
        //printf("rolling_mean: %f mean %f variance\n", mean_array(l.rolling_mean, l.outputs), variance_array(l.rolling_mean, l.outputs));
        //printf("rolling_variance: %f mean %f variance\n", mean_array(l.rolling_variance, l.outputs), variance_array(l.rolling_variance, l.outputs));
    }
#ifdef GPU//定义了GPU则运行下面代码
    if(gpu_index >= 0){
        push_connected_layer(l);
    }
#endif
}
请将如下的matlab代码转为python代码,注意使用pytorch框架实现,并对代码做出相应的解释:function [nets,errors]=BPMLL_train(train_data,train_target,hidden_neuron,alpha,epochs,intype,outtype,Cost,min_max) rand('state',sum(100clock)); if(nargin<9) min_max=minmax(train_data'); end if(nargin<8) Cost=0.1; end if(nargin<7) outtype=2; end if(nargin<6) intype=2; end if(nargin<5) epochs=100; end if(nargin<4) alpha=0.05; end if(intype==1) in='logsig'; else in='tansig'; end if(outtype==1) out='logsig'; else out='tansig'; end [num_class,num_training]=size(train_target); [num_training,Dim]=size(train_data); Label=cell(num_training,1); not_Label=cell(num_training,1); Label_size=zeros(1,num_training); for i=1:num_training temp=train_target(:,i); Label_size(1,i)=sum(temp==ones(num_class,1)); for j=1:num_class if(temp(j)==1) Label{i,1}=[Label{i,1},j]; else not_Label{i,1}=[not_Label{i,1},j]; end end end Cost=Cost2; %Initialize multi-label neural network incremental=ceil(rand100); for randpos=1:incremental net=newff(min_max,[hidden_neuron,num_class],{in,out}); end old_goal=realmax; %Training phase for iter=1:epochs disp(strcat('training epochs: ',num2str(iter))); tic; for i=1:num_training net=update_net_ml(net,train_data(i,:)',train_target(:,i),alpha,Cost/num_training,in,out); end cur_goal=0; for i=1:num_training if((Label_size(i)~=0)&(Label_size(i)~=num_class)) output=sim(net,train_data(i,:)'); temp_goal=0; for m=1:Label_size(i) for n=1:(num_class-Label_size(i)) temp_goal=temp_goal+exp(-(output(Label{i,1}(m))-output(not_Label{i,1}(n)))); end end temp_goal=temp_goal/(mn); cur_goal=cur_goal+temp_goal; end end cur_goal=cur_goal+Cost0.5(sum(sum(net.IW{1}.*net.IW{1}))+sum(sum(net.LW{2,1}.*net.LW{2,1}))+sum(net.b{1}.*net.b{1})+sum(net.b{2}.*net.b{2})); disp(strcat('Global error after ',num2str(iter),' epochs is: ',num2str(cur_goal))); old_goal=cur_goal; nets{iter,1}=net; errors{iter,1}=old_goal; toc; end disp('Maximum number of epochs reached, training process completed');
最新发布
05-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值