matlab中net如何设定loss_【caffe-matlab】使用matlab训练caffe及绘制loss

本文介绍了如何在MATLAB中使用Caffe训练模型,特别是针对路径问题的解决方法和通过step命令实现训练过程中的loss与accuracy监控。通过调整prototxt文件,确保数据集路径正确,并使用MATLAB的Solver进行训练。同时,展示了如何在训练过程中实时绘制loss曲线,以便于观察模型训练效果。
摘要由CSDN通过智能技术生成

前言

此博客主要介绍如何利用matlab一步一步训练caffe模型,类似使用caffe.exe 的train命令。

国际惯例,参考博客:

抱怨一下:matlab的教程是真少哇,大牛们都跑去玩Python了。。。o(╯□╰)o,开更。。。。。。。。。

【注】所有专业说法请参考caffe官网以及其它大牛博客,博主写博客可能有点白话文且没那么咬文嚼字。

一、读入模型

先去caffe主页瞄一眼。。。。。得到一个讯息:

solver = caffe.Solver('./models/bvlc_reference_caffenet/solver.prototxt');这句话干什么的呢?读模型。

尝试一下,采用大家都有的mnist 中的solver,我采用了绝对路径,读者可采用相对路径,无影响

【注】我的solver可能修改了,前面有一篇博客介绍了修改内容和原因。贴一下下载地址:

lenet_solver1.prototxt:链接:http://pan.baidu.com/s/1qXWQrhy 密码:we0e

lenet_train_test1.prototxt:链接:http://pan.baidu.com/s/1miawrxQ 密码:ghxt

均值文件:链接:http://pan.baidu.com/s/1miFDNHe 密码:48az

下面用到的mnist_data:链接:http://pan.baidu.com/s/1bp62Enl 密码:royk

Google一下,感觉可能会有两个原因导致matlab未响应:一是dll没有链接到,就跟很多人出现caffe.set_mode_gpu()会直接未响应一样;二是prototxt内部错误。我不会说我折腾了一下午这个问题。

排除第一种情况,因为目前为止,使用caffe都是比较顺利的,dll问题可能性不大。那就是prototxt 路径问题了,去看prototxt是什么情况

net: "examples/mnist/lenet_train_test1.prototxt"

snapshot_prefix: "examples/mnist/lenet"与路径有关的两句话,我们的matlab程序文件夹是E:\CaffeDev\caffe-master\matlab\demo,与这个路径相差十万八千里。保险起见,我的解决方法是把mnist训练需要的东西全都复制丢到matlab程序文件夹了。如下:

mnist_data文件夹存的是mnist数据集的lmdb文件以及lenet.prototxt,不想动手制作的去上面下载,想动手自己做的,前面有博客介绍。

移动完毕,那就得改改prototxt里面的路径了:

lenet_solver1.prototxt

# The train/test net protocol buffer definition

net: "lenet_train_test1.prototxt"

# test_iter specifies how many forward passes the test should carry out.

# In the case of MNIST, we have test batch size 100 and 100 test iterations,

# covering the full 10,000 testing images.

test_iter: 100

# Carry out testing every 500 training iterations.

test_interval: 500

# The base learning rate, momentum and the weight decay of the network.

base_lr: 0.01

momentum: 0.9

weight_decay: 0.0005

# The learning rate policy

lr_policy: "inv"

gamma: 0.0001

power: 0.75

# Display every 100 iterations

display: 1

# The maximum number of iterations

max_iter: 10000

# snapshot intermediate results

snapshot: 5000

snapshot_prefix: "mnist_data/lenet"

# solver mode: CPU or GPU

solver_mode: CPUlenet_train_test1.prototxt 被修改部分

name: "LeNet"

layer {

name: "mnist"

type: "Data"

top: "data"

top: "label"

include {

phase: TRAIN

}

transform_param {

mean_file: "mean.binaryproto"

scale: 0.00390625

}

data_param {

source: "mnist_data/mnist_train_lmdb"

batch_size: 64

backend: LMDB

}

}

layer {

name: "mnist"

type: "Data"

top: "data"

top: "label"

include {

phase: TEST

}

transform_param {

mean_file: "mean.binaryproto"

scale: 0.00390625

}

data_param {

source: "mnist_data/mnist_test_lmdb"

batch_size: 100

backend: LMDB

}

}

再进行下一步操作之前,最好用bat测试一下是否能读取到这个prototxt并训练,排除这一步错误才能进行下步工作。 接下来再去读取模型:

addpath('..')

caffe.reset_all

solver = caffe.Solver('lenet_solver1.prototxt');显示一下:

>> solver

solver =

Solver with properties:

net: [1x1 caffe.Net]

test_nets: [1x1 caffe.Net]

二、训练模型

2.1、一次性训练模型

solver.solve();这里会有一个幌子,你会发现运行以后matlab跟待机一样,啥输出都没。我还以为出错,分析了一下上面solver读取的两个net:

模型的输入竟然是empty的,难道我们的lmdb数据没有读进去,然后尝试了leveldb,以及各种改leveldb的路径,比如添加“./”之类的,都不行。这时候便想到了一种可能性,模型载入是不读取数据的,只有在运行时候读取数据,但是solver的solve方法是一次性训练模型,没有任何输出,matlab可能已经在训练模型了。为了验证此想法,run→吃饭→回来→观察,果然在下面这个路径中发现了训练好的model

snapshot_prefix: "mnist_data/lenet"

为了避免这些模型是用空数据训练的,使用mnist的classification_demo测试一下,竟然手写数字都分类正确,这样便验证了我们的想法:solver.solve()是一次性训练数据,不会附带任何输出,matlab表现会如死机了。

2.2训练模型step-by-step

依旧去官网找:

意思是我们可以用step命令设置每次训练多少次以后,可以干一下别的事情,然后再训练。

好,卡壳了,设置完毕step为1表示我们想在每一次迭代都取出loss和accuracy,但是然后呢?怎么继续训练?找了很多教程都是Python的,受次启发,以及反复看caffe的官网,发现:

net.blobs('data').set_data(data);

net.forward_prefilled();

prob = net.blobs('prob').get_data();给出的解释简单翻译一下是:

net.forward函数接受n维的输入,输出output的blob的数据

net.forward_prefilled使用的则是使用在模型中已经存在的数据继续训练,并不接受任何输入,以及提供任何输出。

看完这两个解释,思考一下,用step设置训练1次停一下,那么我们的数据是否依旧在blob中存着呢?那么就可以使用net.forward_prefilled做继续训练的工作,尝试一下:

%训练

clear

clc

addpath('..')

caffe.reset_all

solver=caffe.Solver('lenet_solver1.prototxt');

loss=[];

accuracy=[];

for i=1:10000

disp('.')

solver.step(1);

iter=solver.iter();

solver.net.forward_prefilled

end果然输出了一堆“.”,想法正确,接下来就是取出每次迭代的loss和accuracy了,想都不用想,用blob,为了训练快点,我切换到GPU版本的caffe-windows去了,代码如下:

%训练

clear

clc

close all

format long %设置精度,caffe的损失貌似精度在小数点后面好几位

addpath('..')

caffe.reset_all%重设网络,否则载入两个网络会卡住

solver=caffe.Solver('lenet_solver1.prototxt'); %载入网络

loss=[];%记录相邻两个loss

accuracy=[];%记录相邻两个accuracy

hold on%画图用的

accuracy_init=0;

loss_init=0;

for i=1:10000

solver.step(1);%每迭代一次就取一次loss和accuracy

iter=solver.iter();

solver.net.forward_prefilled %每次取完loss和accuracy就进行下一次迭代训练

loss=solver.net.blobs('loss').get_data();%取训练集的loss

accuracy=solver.test_nets.blobs('accuracy').get_data();%取验证集的accuracy

%画loss折线图

x=[i-1,i];

y=[loss_init loss];

plot(x,y,'r-')

drawnow

loss_init=loss;

end

接下来我们便得到了实时的曲线图,每次迭代都有一个loss显示在折线图中。

附:读取日志文件的loss

如果使用的是dos窗口caffe -train命令训练,那么提取loss和accuracy就需要定向到caffe默认的日志文件去,找的方法很简单

按时间排序,找到最近的以caffe.exe开头的文件名称,用notepad++打开可以看到日志信息:

读文件的方法有很多,我用正则表达式去匹配loss信息:

先将这个记录log的文件拷贝出来,

%my loss

clear;

clc;

close all;

train_log_file = 'caffe.exe.BINGO-PC.Bingo.log.INFO.20160924-193528.13464' ;

train_interval = 100 ;

test_interval = 500 ;

[~, string_output] = dos(['type ' , train_log_file ]) ;

pat='1 = .*? loss';

o1=regexp(string_output,pat,'start');%用'start'参数指定输出o1为匹配正则表达式的子串的起始位置

o2=regexp(string_output,pat,'end');%用'start'参数指定输出o1为匹配正则表达式的子串的结束位置

o3=regexp(string_output,pat,'match');%用'match'参数指定输出o2为匹配正则表达式的子串

loss=zeros(1,size(o1,2));

for i=1:size(o1,2)

loss(i)=str2num(string_output(o1(i)+4:o2(i)-5));

end

plot(loss)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值