从零开始学会如何利用自己的数据训练一个分类网络
下载地址如下:
animal:
http://www.robots.ox.ac.uk/~vgg/data/pets/
flower:
http://www.robots.ox.ac.uk/~vgg/data/flowers/
plane:
http://www.robots.ox.ac.uk/~vgg/data/airplanes_side/airplanes_side.tar
house:
http://www.robots.ox.ac.uk/~vgg/data/houses/houses.tar
guitar:
http://www.robots.ox.ac.uk/~vgg/data/guitars/guitars.tar
数据文档结构如下:
└── data
├── test
│ ├── animal
│ ├── flower
│ ├── guitar
│ ├── house
│ └── plane
└── train
├── animal
├── flower
├── guitar
├── house
└── plane
数量:以花为例,800+的图片,测试300+,训练500张。在剩下的不包含在test和train的图片中,每一类选择2张,共计10张图片作为demon测试图片。
格式:文件路径+标签
代码如下,注意修改路径:
import os
#定义Caffe根目录
caffe_root = 'E:/Caffe-windows/caffe-windows/'
#制作训练标签数据
i = 0 #标签
with open(caffe_root + 'models/my_models_recognition/labels/train.txt','w') as train_txt:
for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/train/'): #遍历文件夹
for dir in dirs:
for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/train/'+str(dir)): #遍历每一个文件夹中的文件
for file in files:
image_file = str(dir) + '\\' + str(file)
label = image_file + ' ' + str(i) + '\n' #文件路径+空格+标签编号+换行
train_txt.writelines(label) #写入标签文件中
i+=1 #编号加1
#制作测试标签数据
i=0 #标签
with open(caffe_root + 'models/my_models_recognition/labels/test.txt','w') as test_txt:
for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/test/'): #遍历文件夹
for dir in dirs:
for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/test/'+str(dir)): #遍历每一个文件夹中的文件
for file in files:
image_file = str(dir) + '\\' + str(file)
label = image_file + ' ' + str(i) + '\n' #文件路径+空格+标签编号+换行
test_txt.writelines(label) #写入标签文件中
i+=1#编号加1
print "成功生成文件列表"
参考这个博客
代码如下:
# convert_imageset路径
# 重新修改图片的分辨率位256\*256
# 打乱图片顺序shuffle
# 设置转换为lmdb格式
# 图片路径
# 图片标签
# lmdb文件的输出路径
./build/tools/convert_imageset --resize_height=256 --resize_width=256 --shuffle --backend="lmdb" models/classification_CNN/data/train models/classification_CNN/dlabels/train.txt models/classification_CNN/lmdb/train
# transform_param {
# mirror: true
# crop_size: 227
# mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"
# }
# mean pixel / channel-wise mean instead of mean image
transform_param {
crop_size: 227 # 传入的图片是256*256,现在在其中框出一个227*227的小图片 以此来增大训练集
mean_value: 104 # 通用均值
mean_value: 117
mean_value: 123
mirror: true # 镜像操作 扩大数据集
}
data_param {
source: "/home/weijian/caffe/models/classification_CNN/lmdb/train"
batch_size: 100
backend: LMDB
}
fc6
layer {
name: "fc6"
type: "InnerProduct"
bottom: "pool5"
top: "fc6"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 512 # 这里改成512
weight_filler {
type: "gaussian"
std: 0.005
}
bias_filler {
type: "constant"
value: 1
}
}
}
fc7
layer {
name: "fc7"
type: "InnerProduct"
bottom: "fc6"
top: "fc7"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 512 # 这里改成512
weight_filler {
type: "gaussian"
std: 0.005
}
bias_filler {
type: "constant"
value: 1
}
}
}
layer {
name: "fc8"
type: "InnerProduct"
bottom: "fc7"
top: "fc8"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 5 # 这里哟
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
net: "/home/weijian/caffe/models/classification_CNN/train_val.prototxt"
test_iter: 30 # 测试集一共1500张图片,Test layer的batch_size是50,则在测试的时候,需要迭代30次,即每30次完成一次对所有测试集的测试。
test_interval: 250 # 一共2500张训练图片,Train_layer的batch_size是100,则每250次iterration完成一次对所有训练图片的测试。实际上,也可以随便设置,200,210都可以。
lr_policy: "step"
gamma: 0.1
stepsize: 1000
display: 50
max_iter: 10000
momentum: 0.9
weight_decay: 0.0005
snapshot: 5000
snapshot_prefix: "/home/weijian/caffe/models/classification_CNN/caffenet_train"
solver_mode: GPU
vim train.sh
#!/usr/bin/env sh
set -e
log_path="logs/"
mkdir -p $log_path
save_model_path="caffemodel/"
mkdir -p $save_model_path
# training log
file_prefix="classification_CNN"
log_file=$(date -d "today" +"%Y-%m-%d-%H:%M:%S")
log_file=$log_path$file_prefix$log_file".log"
# caffe execute file path
caffe_bin="/home/weijian/caffe/build/tools/caffe"
# trainning
# $caffe_bin train --solver=solver.prototxt 2>&1 | tee -a $log_file
$caffe_bin train --solver=solver.prototxt 2>&1 | tee ./logs/classification_CNN.log
按照labels中的test.txt和train.txt的图片分类规则在labels文件夹中编辑label.txt,在test.txt和train.txt中,animal是0,guitar是1,以此类推,得到label.txt如下所示:
animal
guitar
flower
house
plane
vim testDemo.py
import caffe
import numpy as np
import matplotlib.pyplot as plt
import os
import PIL
from PIL import Image
import sys
#定义Caffe根目录
caffe_root = '/home/weijian/caffe/'
#网络结构描述文件
deploy_file = caffe_root+'models/classification_CNN/deploy.prototxt'
#训练好的模型
model_file = caffe_root+'models/classification_CNN/caffenet_train/solver_iter_10000.caffemodel'
#gpu模式
caffe.set_device(0) # 如果你有多个GPU,那么选择第一个
caffe.set_mode_gpu()
# caffe.set_mode_gpu()
#定义网络模型
net = caffe.Classifier(deploy_file, #调用deploy文件
model_file, #调用模型文件
channel_swap=(2,1,0), #caffe中图片是BGR格式,而原始格式是RGB,所以要转化
raw_scale=255, #python中将图片存储为[0, 1],而caffe中将图片存储为[0, 255],所以需要一个转换
image_dims=(227, 227)) #输入模型的图片要是227*227的图片
#分类标签文件
imagenet_labels_filename = caffe_root +'models/classification_CNN/labels/label.txt'
#载入分类标签文件
labels = np.loadtxt(imagenet_labels_filename, str)
#对目标路径中的图像,遍历并分类
for root,dirs,files in os.walk(caffe_root+'models/classification_CNN/demo_test_image/'):
for file in files:
#加载要分类的图片
image_file = os.path.join(root,file)
input_image = caffe.io.load_image(image_file)
#打印图片路径及名称
image_path = os.path.join(root,file)
print(image_path)
#显示图片
img=Image.open(image_path)
plt.imshow(img)
plt.axis('off')
plt.show()
#预测图片类别
prediction = net.predict([input_image])
print 'predicted class:',prediction[0].argmax()
# 输出概率最大的前5个预测结果
top_k = prediction[0].argsort()[::-1]
for node_id in top_k:
#获取分类名称
human_string = labels[node_id]
#获取该分类的置信度
score = prediction[0][node_id]
print('%s (score = %.5f)' % (human_string, score))
运行testDemo.py