Caffe learns from scratch 3-mnist routines to test custom digital pictures

Test a custom handwritten number

The mnist data has been trained above, and the test data has also been tested, and the accuracy rate is about 99%. So if we want to measure a byte handwritten number by ourselves and see if it is accurate, how to use the caffemodel weight file.
Let's test a custom handwritten number below.
Use the model lenet_iter_10000.caffemodel to test the files needed for a single handwritten number:
(1) The picture to be tested (you can draw by yourself, or on the Internet); it should be noted that no matter what format it is, it must be converted to 28 *28-size black and white grayscale images, please use Baidu for the specific conversion method. You can download from this link if you don’t want to convert. Download link: https://pan.baidu.com/s/1Ck6l7bAncK2BpcqWXG67Dg Password: csig, these pictures are available online Turn around.
(2) deploy.prototxt (model description file);
(3) network.caffemodel (model weight file), in this case it is lenet_iter_10000.caffemodel
(4) labels.txt (label file), the profit is synset_words .txt file;
(5) mean.binaryproto (binary image average file);
(6) classification.bin (binary program name). Used in conjunction with the binary mean file, but different models with different mean files have different mean files, and this bin file is universal, that is, any model can be used for classification.
1. Prepare a customized picture.
Download the picture in the link and copy it to the caffe/examples/mnist/ directory.
2. Generate the deploy.prototxt file
The role of the deploy.prototxt file is similar to that of the lenet_train_test.prototxt file, or the former can be obtained by changing the latter. After being familiar with the principles and methods of generating files, we can make changes in the original training prototxt network file. Copy a copy of lenet_train_test.prototxt in the examples/mnist directory, modify it and save it to get deploy.prototxt as follows:

name: "LeNet"  
 
   
layer {  
  name:"data"  
 type: "Input"  
 top: "data"  
 input_param { shape: { dim: 1 dim: 1 dim: 28 dim: 28 } }  
}  
   
  
layer {  
  name:"conv1"  
 type: "Convolution"  
 bottom: "data"  
 top: "conv1"  
 convolution_param {  
   num_output: 20  
   kernel_size: 5  
   stride: 1  
   weight_filler {  
     type: "xavier"  
   }  
 }  
}  
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"  
 convolution_param {  
   num_output: 50  
   kernel_size: 5  
   stride: 1  
   weight_filler {  
     type: "xavier"  
   }  
 }  
}  
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"  
 inner_product_param {  
   num_output: 500  
   weight_filler {  
     type: "xavier"  
   }  
 }  
}  
layer {  
  name:"relu1"  
 type: "ReLU"  
 bottom: "ip1"  
 top: "ip1"  
}  
layer {  
  name:"ip2"  
 type: "InnerProduct"  
 bottom: "ip1"  
 top: "ip2"  
 inner_product_param {  
   num_output: 10  
   weight_filler {  
     type: "xavier"  
   }  
 }  
}  
   
 
layer {  
  name:"prob"  
 type: "Softmax"  
 bottom: "ip2"  
 top: "prob"  
}  

Of course, the deploy.prototxt file can also be automatically generated by means of code. The deploy file does not have the first data input layer, nor the final Accuracy layer, but at the end there is an extra layer of Softmax probability.
The deploy.py code is as follows;

# -*- coding: utf-8 -*-

from caffe  import layers as L,params as P,to_proto
root='/root/caffe/'
deploy=root+'examples/mnist/deploy.prototxt'    #文件保存路径

def create_deploy():
    #少了第一层,data层
    conv1=L.Convolution(name='conv1',bottom='data', kernel_size=5, stride=1,num_output=20, pad=0,weight_filler=dict(type='xavier'))
    pool1=L.Pooling(conv1,name='pool1',pool=P.Pooling.MAX, kernel_size=2, stride=2)
    conv2=L.Convolution(pool1, name='conv2',kernel_size=5, stride=1,num_output=50, pad=0,weight_filler=dict(type='xavier'))
    pool2=L.Pooling(conv2, name='pool2', pool=P.Pooling.MAX, kernel_size=2, stride=2)
    fc3=L.InnerProduct(pool2, name='ip1',num_output=500,weight_filler=dict(type='xavier'))
    relu3=L.ReLU(fc3, name='relu1',in_place=True)
    fc4 = L.InnerProduct(relu3, name='ip2',num_output=10,weight_filler=dict(type='xavier'))
    #最后没有accuracy层,但有一个Softmax层
    prob=L.Softmax(fc4, name='prob')
    return to_proto(prob)
def write_deploy():
    with open('deploy.prototxt', 'w+') as f:
        f.write('name:"LeNet"\n')
        f.write('layer {\n')
        f.write('name:"data"\n')
        f.write('type:"Input"\n')
        f.write('top:"data"\n')
        f.write('input_param { shape : {')
        f.write('dim:1 ')
        f.write('dim:1 ')
        f.write('dim:28 ')
        f.write('dim:28 ')
        f.write('} } }\n\n')
        f.write(str(create_deploy()))
if __name__ == '__main__':
    write_deploy()


3. network.caffemodel (model weight file)
network.caffemodel has been generated during training, in this case it is the lenet_iter_10000.caffemodel file.
4. Generate labels.txt label file
Create a new txt file in the current directory and name it synset_words.txt, the content inside is the content of the image of our training mnist, there are ten numbers from 0 to 9, then we create a label file with the following content :
Insert picture description here
5. Generate mean.binaryproto binary mean file.
Mean files are divided into binary mean files and python-type mean files.
The author of caffe provides us with a file compute_image_mean.cpp to calculate the mean, which is placed in the tools folder under the caffe root directory, and run the following command to generate the mean.binaryproto binary mean file.

build/tools/compute_image_mean  \
examples/mnist/mnist_train_lmdb \
examples/mnist/mean.binaryproto 

Insert picture description here
6. Use the classification.bin binary program to test
. There is a cpp_classification folder in the example folder, open it, and there is a cpp file named classification. This is the forward calculation that caffe provides to us by calling the classification network. Interface for classification results. It is this file that will get classification.bin in the command.
Use the following command to start testing a custom digital picture:

./build/examples/cpp_classification/classification.bin \
examples/mnist/deploy.prototxt \
examples/mnist/lenet_iter_10000.caffemodel \
examples/mnist/mean.binaryproto \
examples/mnist/synset_words.txt \
examples/mnist/picture/0.0.jpg  

Test result: It
Insert picture description here
can be seen that the 0 label output in test 0 corresponds to 1.0000, the 9 label output in test 9 corresponds to 1.0000, and the 2 label output in test 2 corresponds to 1.0000. The result is still very accurate.

Draw loss graph

In the process of the last mnist training, some training speed, learning rate, loss value, etc. were continuously printed. So is there a picture format that can more intuitively reflect the trend of loss and accuracy during the training process?
Of course there are, you need to write a pyton program loss.py. Refer to an example on the Internet:

# -*- coding: utf-8 -*-
import numpy as np #导入numpy库并命名为np,numpy支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
import matplotlib.pyplot as plt #导入matplotlib.pyplot库并命名为plt,Matplotlib 是 Python 的绘图库。 matplotlib可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案
import sys,os  #导入sys模块,sys模块包含了与Python解释器和它的环境有关的函数;导入os模块,os模块里面有环境变量的映射关系,目录等
caffe_root = '/root/caffe'
sys.path.insert(0,caffe_root+'python')  #sys.path为一个列表,用insert直接插到首位,插入python的环境变量
import caffe

caffe.set_mode_cpu() #设置caffe  cpu运行模式 
solver = caffe.SGDSolver('/root/caffe/examples/mnist/lenet_solver.prototxt') 
# 执行完上面的语句以后,网络的相应的权值与偏置会根据我们的定义进行赋值的

niter=1000  #迭代1000次
test_interval = 200  #200次测试一次
train_loss = np.zeros(niter) #1维,大小为1000的数组  
#np.zeros返回一个给定形状和类型的用0填充的数组,本例为array([ 0,  0,  0,  0,  0 ......]),长度是1000
test_acc = np.zeros(int(np.ceil(niter / test_interval)))#1维,大小为5的数组
#np.ceil() 计算大于等于该值的最小整数,本例niter / test_interval,np.ceil(5)是5

for it in range(niter):
	solver.step(1)
	# solver.net.forward() , solver.test_nets[0].forward() 和 solver.step(1) 区别和作用。
	#三个函数都是将批量大小(batch_size)的图片送到网络,
	#solver.net.forward() 和 solver.test_nets[0].forward() 是将batch_size个图片送到网络中去,只有前向传播(Forward Propagation,BP),solver.net.forward()作用于训练集,solver.test_nets[0].forward() 作用于测试集,一般用于获得测试集的正确率。
	#solver.step(1) 也是将batch_size个图片送到网络中去,不过 solver.step(1) 不仅有FP,而且还有反向传播(Back Propagation,BP)!这样就可以更新整个网络的权值(weights),同时得到该batch的loss。

	
	train_loss[it] = solver.net.blobs['loss'].data # 获取每一次迭代的loss值
	solver.test_nets[0].forward(start='conv1')   #表示从conv1开始,这样的话,data层不用传新的数据了。
	
	if it % test_interval == 0:
		acc=solver.test_nets[0].blobs['accuracy'].data  #获取test_interval整数倍时的准确率
		#solver.net.blobs为一个字典的数据类型,里面的key值为各个layer 的名字,value为caffe的blob块
		print 'Iteration',it,'testing...','accuracy:',acc
		test_acc[it // test_interval] = acc  #      //是整除运算符,取整数部分

print test_acc
_,ax1= plt.subplots()  
ax2= ax1.twinx()#matplotlib:次坐标轴ax2=ax1.twinx(),产生一个ax1的镜面坐标
ax1.plot(np.arange(niter),train_loss) 
ax2.plot(test_interval * np.arange(len(test_acc)),test_acc,'r')
ax1.set_xlabel('iteration')
ax1.set_ylabel('train loss')
ax2.set_ylabel('test accuracy')
plt.savefig("mnist_loss.png")
plt.show()


See above for detailed analysis of loss.py program.
Run drawing

python loss.py

After executing loss.py, I started training. Here I trained 1000 times and outputted a test 200 times.
The loss curve is as follows:

eog mnist_loss.png

Insert picture description here
As shown in the figure above, it can be seen that as the number of training increases, the loss shows a gradual convergent oscillation, the loss value shows a downward trend, and the accuracy rate continues to rise.

Remarks:
_,ax1= plt.subplots() Why is there _ at the beginning of this sentence, these two characters, I did not understand after checking the information, if you know, please let me know~

Guess you like

Origin blog.csdn.net/u014470361/article/details/100055017