用LeNet训练好的模型识别自己的数字字符,应该在哪一层输出是哪个字符?

我的代码部分:
//加载网络和模型;
Net<float> net("./data/mnist-testdata/lenet_train_test.prototxt",TEST);
 net.CopyTrainedLayersFrom("./data/mnist-testdata/lenet_iter_10000.caffemodel");
//ip2层的输出好像就是预测的结果,再下一层就是accuracy层了。
const boost::shared_ptr<Blob<float> >& outputLayer = net.blob_by_name("ip2");

下面如何写将数据中的label和预测的字符结果输出呢?


Python的实现我调试成功了,代码贴出来,C++的感觉应该和这个差不多的方式,希望得到指点。谢谢。
import sys




#import cv2

#import Image

import matplotlib

matplotlib.rcParams['backend'] = "Qt4Agg"

import numpy as np

import lmdb

caffe_root = '/opt/caffe-master/'

sys.path.insert(0, caffe_root + 'python')

import caffe

MODEL_FILE = '/opt/caffe-master/examples/mnist/lenet.prototxt'

PRETRAINED ='/opt/caffe-master/examples/mnist/lenet_iter_10000.caffemodel'




net = caffe.Net(MODEL_FILE, PRETRAINED,caffe.TEST)




caffe.set_device(0)

caffe.set_mode_gpu()

#caffe.set_mode_cpu()

#Test self-made image

"""

img = caffe.io.load_image('./examples/images/two_g.jpg', color=False)

img = img.astype(np.uint8)

out = net.forward_all(data=np.asarray([img.transpose(2,0,1)]))

print out['prob'][0]

"""

db_path = '/opt/caffe-master/examples/mnist-test/num_val_lmdb'

lmdb_env = lmdb.open(db_path)

lmdb_txn = lmdb_env.begin()

lmdb_cursor = lmdb_txn.cursor()

count = 0

correct = 0

for key, value in lmdb_cursor:

print "Count:"

print count

count = count + 1

datum = caffe.proto.caffe_pb2.Datum()

datum.ParseFromString(value)

label = int(datum.label)

# image = image.transpose()

image = caffe.io.datum_to_array(datum)

image = image.astype(np.uint8)

out = net.forward_all(data=np.asarray([image]))

predicted_label = out['prob'][0].argmax(axis=0)

print out['prob']

if label == predicted_label:

correct = correct + 1

print("Label is class " + str(label) + ", predicted class is " + str(predicted_label))

print(str(correct) + " out of " + str(count) + " were classified correctly")
已邀请:

anmeng - 90后DL

赞同来自: OpenAI xinmiao alex68

自己顶一下,经过查找和尝试,解决啦问题。解答如下:
网络用的还是LeNet的lenet_train_test.prototxt,为了输出最终的预测结果,需要对这个配置文件进行修改,

(1)首先去掉loss/accuracy层;

(2)然后加入output层,类型是“ArgMax”;

(3)在预测的c++文件中,将预训练模型和网络配置文件加入到Net中,然后利用Net的blobs输出,将output层和label层输出来,这样就得到了预测结果和对应的label。
lenet_train_test.prototxt代码:

name: "LeNet"
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist-test/num_val_lmdb"
batch_size: 14
backend: LMDB
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "output"
type: "ArgMax"
bottom: "ip2"
top:"output"
include: { phase: TEST }
}
cpp文件:

#include <cstring>
#include <cstdlib>
#include <vector>
#include <string>
#include <iostream>
#include <stdio.h>
#include <assert.h>
#include "caffe/caffe.hpp"
#include "caffe/util/io.hpp"
#include "caffe/blob.hpp"
using namespace caffe;
using namespace std;
int main(int argc, char** argv)
{
LOG(INFO) << argv[0] << " [GPU] [Device ID]";
//Setting CPU or GPU
if (argc >= 2 && strcmp(argv[1], "GPU") == 0)
{
Caffe::set_mode(Caffe::GPU);
int device_id = 0;
if (argc == 3)
{
device_id = atoi(argv[2]);
}
Caffe::SetDevice(device_id);
LOG(INFO) << "Using GPU #" << device_id;
}
else
{
LOG(INFO) << "Using CPU";
Caffe::set_mode(Caffe::CPU);
}

// Load net
// Assume you are in Caffe master directory
Net<float> net("./data/mnist-testdata/lenet_train_test.prototxt",TEST);
// Assume you are already trained the lenet example.
net.CopyTrainedLayersFrom("./data/mnist-testdata/lenet_iter_10000.caffemodel");
float loss = 0.0;
vector<Blob<float>*> results = net.Forward(&loss);
LOG(INFO) << "Blob size: "<< net.input_blobs().size();
LOG(INFO) << "output size: "<< net.input_blobs().size();
LOG(INFO)<< "-------------";
LOG(INFO)<< " prediction : ";
// Get label
const boost::shared_ptr<Blob<float> >& labelLayer = net.blob_by_name("label");
const float* label_out = labelLayer->cpu_data();

// Get argmax results
const boost::shared_ptr<Blob<float> >& argmaxLayer = net.blob_by_name("output");

// Display results
LOG(INFO) << "---------------------------------------------------------------";
const float* argmaxs = argmaxLayer->cpu_data();
for (int i = 0; i < argmaxLayer->num(); i++)
{

LOG(INFO) << "num:"<< i << " label:" <<label_out[i] << " predict=" << argmaxs[i] ;
}
LOG(INFO)<< "-------------";
return 0;
}

运行:(用GPU模式)
make
./program  GPU 0

renhanchi

赞同来自:

楼主您好,跑了一下您分享的C++代码。有几点疑惑,希望您给解答一下。
1.我刚开始接触CNN,请问训练好后的.caffemodel里面有训练数据的label么?比如我用自行车和鸟的图片训练的,.caffemodel里会有自行车和鸟这两个标签么?
2.我想用我自己的测试集来检验训练模型。正常test跑下来是只输出accuracy和loss。但是我想知道我测试集每一张图片被分到哪一类。如果用您的C++代码,我要如何输入测试集呢?

lutingxiang

赞同来自:

楼主你好,我也在尝试用C++编写使用caffe模型的小程序,我是根据classification.cpp修改得到的,为了不用命令行,将main改为了WinMain函数,但是运行时出现了未知异常,不知道楼主知不知是什么原因,或者希望楼主提供一下可行的方案来通过窗口应用来使用已训练好的模型

要回复问题请先登录注册