-
TensofFlow制作自己的数据集,并训练CNN网络
2018-08-09 20:37:13前面的几篇文章我们学习了使用...因此,在这里我们介绍如何使用TFrecords处理自己的数据集并训练CNN网络。我们以kaggle比赛中的猫狗大战数据集为例。 (1)下载并分类处理猫狗大战训练集 猫狗大战数据集下载链接...前面的几篇文章我们学习了使用Tensorflow搭建简单拟合神经网络、CNN、RNN和自编码等。但是在那些简单的例子里面我们都是使用的标准的MNIST数据集,而大部分时间我们更需要使用自己的数据集训练神经网络。因此,在这里我们介绍如何使用TFrecords处理自己的数据集并训练CNN网络。我们以kaggle比赛中的猫狗大战数据集为例。
(1)下载并分类处理猫狗大战训练集
猫狗大战数据集下载链接如下所示
https://pan.baidu.com/s/13hw4LK8ihR6-6-8mpjLKDA
密码:dmp4
下载后得到数据的训练集和测试集
在这里我们只需要训练集,训练集中包括猫狗图像25000张,数据太多了而且猫狗的图像都在一个文件夹中,只于图像的名字区分,很不利于我们制作训练集啊,因此我们写了一个简单的程序从训练集中取1000张图像,并将猫狗分别保存到文件夹内,对了为了方便大家单独新建个文件夹用于保存分类后的图像,可以参考下面代码中的路径。
import os import shutil #下载得到的训练集图像 image_path='/home/cyy/python_code/tensorflow/kaggle/train' #将猫狗分类保存的路径 train_path='/home/cyy/python_code/tensorflow/dog_cat_classification/data' image_list=os.listdir(image_path) #读取1000张猫狗图像,按照图像名字分别保存 for image_name in image_list[0:1000]: class_name=image_name[0:3] save_path=os.path.join(train_path,class_name) if not(os.path.exists(save_path)): os.mkdir(save_path) file_name=os.path.join(image_path,image_name) save_name=os.path.join(save_path,image_name) shutil.copyfile(file_name,save_name)
这样就将1000张猫狗图像分别保存到了两个文件夹中,如下图所示
(2)制作tfrecords文件
代码起名为make_own_data.py
tfrecord会根据你选择输入文件的类,自动给每一类打上同样的标签。代码如下:
import os import tensorflow as tf from PIL import Image import matplotlib.pyplot as plt import numpy as np #存放数据文件夹 data_path='/home/cyy/python_code/tensorflow/dog_cat_classification/data' classes={'dog','cat'}#两个类名 #保存的文件名 data_file=tf.python_io.TFRecordWriter('dog_and_cat_train.ftrecords') #分别读取两个类并生成索引 for index,class_name in enumerate(classes): class_path=os.path.join(data_path,class_name) #分别读取每个类下的图像 for im_name in os.listdir(class_path): image_path=os.path.join(class_path,im_name) img=Image.open(image_path) img=img.resize((128,128))#将图像resize成128*128 img_raw=img.tobytes()#生成二进制 example=tf.train.Example(features=tf.train.Features(feature={ 'label':tf.train.Feature(int64_list=tf.train.Int64List(value=[index])), 'img_raw':tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])) }))#example对象对label和image数据进行封装 data_file.write(example.SerializeToString())#序列化为字符串 data_file.close()
运行完后在代码目录下会生成文件如下所示:
(3)读取数据程序
将图片和标签读出,图片reshape为128x128x3。
读取代码单独作为一个文件,起名为ReadMyOwnData.py代码如下:
import tensorflow as tf def read_and_decode(filename):#读入tfrecords文件 filename_queue=tf.train.string_input_producer([filename]) reader=tf.TFRecordReader() _,serialized_example=reader.read(filename_queue)#生成一个queue队列 #将image数据和label数据读取出来放入features features=tf.parse_single_example(serialized_example,features={ 'label':tf.FixedLenFeature([],tf.int64), 'img_raw':tf.FixedLenFeature([],tf.string)}) img=tf.decode_raw(features['img_raw'],tf.uint8) img=tf.reshape(img,[128,128,3])#将图像reshape成128*128 img=tf.cast(img,tf.float32)*(1./255)-0.5#将image归一化 label=tf.cast(features['label'],tf.int32)#将label转化成int32 return(img,label)
(4)搭建CNN网络并完成训练
要把我们读取文件的ReadMyOwnData导入,网络进行两次卷积操作,两次最大池化,激活函数ReLU,全连接层,最后y_conv是softmax输出的二类问题。损失函数用交叉熵,优化算法Adam。
代码如下:
import tensorflow as tf import numpy as np import ReadMyOwnData batch_size=50 #定义初始化权重和偏置函数 def weight_variable(shape): return(tf.Variable(tf.random_normal(shape,stddev=0.01))) def bias_variable(shape): return(tf.Variable(tf.constant(0.1,shape=shape))) #定义输入数据和dropout占位符 X=tf.placeholder(tf.float32,[batch_size,128,128,3]) y_=tf.placeholder(tf.float32,[batch_size,1]) keep_pro=tf.placeholder(tf.float32) #搭建网络 def model(X,keep_pro): w1=weight_variable([5,5,3,32]) b1=bias_variable([32]) conv1=tf.nn.relu(tf.nn.conv2d(X,w1,strides=[1,1,1,1],padding='SAME')+b1) pool1=tf.nn.max_pool(conv1,ksize=[1,4,4,1],strides=[1,4,4,1],padding='SAME') w2=weight_variable([5,5,32,64]) b2=bias_variable([64]) conv2=tf.nn.relu(tf.nn.conv2d(pool1,w2,strides=[1,1,1,1],padding='SAME')+b2) pool2=tf.nn.max_pool(conv2,ksize=[1,4,4,1],strides=[1,4,4,1],padding='SAME') tensor=tf.reshape(pool2,[batch_size,-1]) dim=tensor.get_shape()[1].value w3=weight_variable([dim,1024]) b3=bias_variable([1024]) fc1=tf.nn.relu(tf.matmul(tensor,w3)+b3) h_fc1=tf.nn.dropout(fc1,keep_pro) w4=weight_variable([1024,2]) b4=bias_variable([2]) y_conv=tf.nn.softmax(tf.matmul(h_fc1,w4)+b4) return(y_conv) #定义网络,并设置损失函数和训练器 y_conv=model(X,keep_pro) cost=tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y_conv),reduction_indices=[1])) train_step=tf.train.AdamOptimizer(0.001).minimize(cost) #计算准确率 correct_prediction=tf.equal(tf.argmax(y_conv,1),tf.argmax(y_,1)) accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) #读取tfrecords数据 image,label=ReadMyOwnData.read_and_decode("dog_and_cat_train.ftrecords") #定义会话,并开始训练 with tf.Session() as sess: tf.global_variables_initializer().run() #定义多线程 coord=tf.train.Coordinator() threads=tf.train.start_queue_runners(coord=coord) #定义训练图像和标签 example=np.zeros((batch_size,128,128,3)) l=np.zeros((batch_size,1)) try: for i in range(20): #将数据存入example和l for epoch in range(batch_size): example[epoch],l[epoch]=sess.run([image,label]) #开始训练 sess.run(train_step,feed_dict={X:example,y_:l,keep_pro:0.5}) print('train step','%04d ' %(i+1),'Accuracy=',sess.run(accuracy,feed_dict={X:example,y_:l,keep_pro:0.5})) except tf.errors.OutOfRangeError: print('done!') finally: coord.request_stop() coord.join(threads)
输出结果如下所示(代码在Python3下运行,如果报错尝试删除中文注释):
我们训练了20次,这是20个batch输出的结果,我们可以看到因为网络搭建的比较简单所以结果并不是特别好,如果想要更好的结果需要搭建更复杂的网络,当然计算量也会加大。
-
python怎么导入数据集keras_python – 如何在训练MNIST数据集后使用keras中的cnn预测我自己的图像...
2020-12-08 23:27:27我已经制作了一个卷积神经网络来预测使用MNIST数据集的手写数字但是现在我被困在预测我自己的图像作为cnn的输入,我在训练cnn后保存了权重并且想用它来预测我自己的图像(注意:关心我的输入图像是28×28)码:new_...我已经制作了一个卷积神经网络来预测使用MNIST数据集的手写数字但是现在我被困在预测我自己的图像作为cnn的输入,我在训练cnn后保存了权重并且想用它来预测我自己的图像(注意:关心我的输入图像是28×28)
码:
new_mnist.py:
ap = argparse.ArgumentParser()
ap.add_argument("-s", "--save-model", type=int, default=-1,
help="(optional) whether or not model should be saved to disk")
ap.add_argument("-l", "--load-model", type=int, default=-1,
help="(optional) whether or not pre-trained model should be loaded")
ap.add_argument("-w", "--weights", type=str,
help="(optional) path to weights file")
args = vars(ap.parse_args())
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load data
print("[INFO] downloading data...")
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# reshape to be [samples][pixels][width][height]
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype('float32')
print(X_test.shape[0])
# normalize inputs from 0-255 to 0-1
X_train = X_train / 255
X_test = X_test / 255
# one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]
# build the model
print("[INFO] compiling model...")
model = LeNet.build(num_classes = num_classes,weightsPath = args["weights"] if args["load_model"] > 0 else None)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
if args["load_model"] < 0:
# Fit the model
print("[INFO] training...")
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=1, batch_size=200, verbose=2)
# Final evaluation of the model
print("[INFO] evaluating...")
scores = model.evaluate(X_test, y_test, verbose=0)
print("Baseline Error: %.2f%%" % (100-scores[1]*100))
elif args["load_model"] > 0:
im = imread("C:\\Users\\Divyesh\\Desktop\\mnist.png")
im = im/255
pr = model.predict_classes(im)
print(pr)
# check to see if the model should be saved to file
if args["save_model"] > 0:
print("[INFO] dumping weights to file...")
model.save_weights(args["weights"], overwrite=True)
lenet.py:
class LeNet:
@staticmethod
def build(num_classes,weightsPath = None):
# create model
model = Sequential()
model.add(Convolution2D(30, 5, 5, border_mode='valid', input_shape=(1, 28, 28), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(15, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
#model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
if weightsPath is not None:
model.load_weights(weightsPath)
return model
在new_mnist.py我调用了预测(im),其中im是28×28图像,但在运行此程序后,我收到错误:
ValueError: Error when checking : expected conv2d_1_input to have 4 dimensions, but got array with shape (28, 28)
救命!!!
-
Windows10下实现Faster R-cnn+Tensorflow+python且训练自己的数据集
2019-11-20 10:19:49-测试修改部分代码修改训练模型位置测试训练自己的数据集前言文件结构制作自己的数据集JPEGImages文件夹Annotations文件夹ImageSets文件夹其余两个文件夹不需要操作LabelImg标记大法插入链接与图片如何插入一段漂亮...文章目录
背景
为了满足项目中目标检测需要,而Faster R-CNN最大的亮点在于提出了一种有效定位目标区域的方法,然后按区域在特征图上进行特征索引,大大降低了卷积计算的时间消耗,所以速度上有了非常大的提升。并且准确率相对较高,所以博主准备采坑Faster R-cnn。本博文先采坑Faster R-cnn流程,即复现,然后针对自己的数据集,进行训练并测试,实现初步需要。
附本博文采用的源码地址:https://github.com/dBeker/Faster-RCNN-TensorFlow-Python3.
特别强调:此github项目也适用于python3.6。后文有相应操作
本文默认读者已经配置好了tensorflow-gpu环境,未配置的客官详见:https://blog.csdn.net/shangzhihaohao/article/details/89766368.小试牛刀–训练
基础操作
这一步骤根据github的Reademe部分向下进行:
1.安装必要的安装包:cython, python-opencv, easydict,通过pip命令安装在你的tensorflow-gpu环境下的python中
2.进入到data/coco/Python文件夹中打开命令窗口(即cmd)运行两个python文件,分别运行:python setup.py build_ext --inplace python setup.py build_ext install
这步可能会出现“error: Unable to find vcvarsall.bat”错误,因为源码是基于python3.5编译,而在python3.6下运行就会报错,所以必须在python3.6环境下重新编译。首先要安装Visual Studio2015,然后执行代码进行再次编译
python setup.py build_ext --inplace
这里可能还会有错误,具体我忘了,如果有错误评论区见~~~到这里基础操作告一段落
VOC_2007数据集
下载数据集参考:VOC_2007数据集.
在这里也给出具体操作流程:
1.打开某网页在地址栏分别输入http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar
将压缩包下载到相应文件夹下,我下载到了data文件夹下
2.将压缩包解压在data文件夹下的一个新建的文件夹并将文件夹重命名为VOCdevkit2007
此时文件结构为:
别问为什么把结构放上,问就是我之前好想看好想看结构,生怕自己错了,就是没有!!!(😭)下载模型
下载预训练模型VGG16网络和其他你感兴趣的网络,下载地址: https://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models.
在data文件夹下新建imagenet_weights文件夹,将下载好的网络放到此文件夹下。注意要将vgg_16.ckpt重命名为vgg16.ckpt
文件结构:
训练之前修改lib.config.config.py下的代码,在第30行的max_iters中将40000修改成10000,能节省点时间。此时可以运行train.py文件了,此处建议先修改lib.config.config.py下的代码tf.app.flags.DEFINE_integer(‘snapshot_iterations’, 5000, “Iteration to take snapshot”),将5000改成1000,这个意思是每迭代1000次存储一次模型。(config.py文件是定义默认参数的python文件,想调什么超参数一般都会在这个文件中)。不出意外的话,模型训练成功是时间的问题,最后训练出来的模型会存储在default\voc_2007_trainval\default文件夹下,如图:
惊心动魄–测试
修改部分代码
首先进入demo.py文件,修改几处代码:
1.39行的vgg16_faster_rcnn_iter_70000.ckpt修改为vgg16_faster_rcnn_iter_10000.ckpt
2.由于本文是复现VGG16模型,所以将demo.py的第108行原来默认的res101,改成我们现在用的vgg16。
3.110行的default='pascal_voc_0712’改为pascal_voc修改训练模型位置
在根目录下新建output/vgg16/voc_2007_trainval/default,将训练好的第10000次的模型放入此文件夹中,结构如图:
测试
运行demo.py,不出意外的话,出现很多个下图所示的画面:
为了使其显示在同一张图片上。只修改了demo.py文件中的vis_detections 与demo俩个函数中小小的一部分,代码如下def vis_detections(ax, class_name, dets, thresh=0.5): """Draw detected bounding boxes.""" inds = np.where(dets[:, -1] >= thresh)[0] if len(inds) == 0: return for i in inds: bbox = dets[i, :4] score = dets[i, -1] ax.add_patch( plt.Rectangle((bbox[0], bbox[1]), bbox[2] - bbox[0], bbox[3] - bbox[1], fill=False, edgecolor='red', linewidth=3.5) ) ax.text(bbox[0], bbox[1] - 2, '{:s} {:.3f}'.format(class_name, score), bbox=dict(facecolor='blue', alpha=0.5), fontsize=14, color='white') plt.axis('off') plt.tight_layout() plt.draw() def demo(sess, net, image_name): """Detect object classes in an image using pre-computed object proposals.""" # Load the demo image im_file = os.path.join(cfg.DATA_DIR, 'demo', image_name) im = cv2.imread(im_file) # Detect all object classes and regress object bounds timer = Timer() timer.tic() scores, boxes = im_detect(sess, net, im) timer.toc() print('Detection took {:.3f}s for {:d} object proposals'.format(timer.total_time, boxes.shape[0])) # Visualize detections for each class CONF_THRESH = 0.8 NMS_THRESH = 0.3 im = im[:, :, (2, 1, 0)] fig, ax = plt.subplots(figsize=(12, 12)) ax.imshow(im, aspect='equal') plt.ion() for cls_ind, cls in enumerate(CLASSES[1:]): cls_ind += 1 # because we skipped background cls_boxes = boxes[:, 4 * cls_ind:4 * (cls_ind + 1)] cls_scores = scores[:, cls_ind] dets = np.hstack((cls_boxes, cls_scores[:, np.newaxis])).astype(np.float32) keep = nms(dets, NMS_THRESH) dets = dets[keep, :] vis_detections(ax, cls, dets, thresh=CONF_THRESH)
至此,复现成功!
文章复现部分可能会遇到我没遇到过的情概况,也可能有一些我遇到过但是忘记写在博文里的问题,评论,我捞你。然后在将遗漏的问题补充到博文中。训练自己的数据集
前言
利用Faster R-cnn等深度网络训练自己的数据集一般都是将自己的数据格式修改成VOC2007的格式,之前在VOC_2007数据集中我们已经下载下来了。
文件结构
解压VOC2007数据集后可以看到VOC2007文件夹下有以下5个文件夹,分别是:
-
Annotations
该文件下存放的是xml格式的标签文件,每个xml文件都对应于JPEGImages文件夹的一张图片。XML前面部分声明图像数据来源,大小等元信息 -
JPEGImages
此文件夹下存放的是你数据集图片,包括训练和测试图片。格式必须是JPG格式,这个要特别注意!如果你打算使用VO2007格式生成数据,那么原始图像格式在采样时候请用JPG格式保存,这些图像的像素尺寸大小不一,但是横向图的尺寸大约在500375左右,纵向图的尺寸大约在375500左右,基本不会偏差超过100。(在之后的训练中,第一步就是将这些图片都resize到300300或是500500,所有原始图片不能离这个标准过远。 -
ImageSets
该文件夹下存放了三个文件,分别是Layout、Main、Segmentation。Layout中的txt文件表示包含Layout标注信息的图像文件名列表,Main文件夹中包含20个类别每个类别一个txt文件,每个txt文件都是包含该类别的图像文件名称列表,Segmentation则是包含语义分割信息图像文件的列表。在这里我们只用存放图像数据的Main文件,其他两个暂且不管。
Main文件夹下包含了每个分类的train.txt、val.txt和trainvaltxt、test.txt
train.txt表示是的训练数据集合
val.txt 表示验证集数据
trainval.txt表示训练与验证集数据
test.txt表示测试集数据
这些txt中的内容都差不多如下:
000005 -1
000007 -1
000009 1
000016 -1
000019 -1
前面的表示图像的name,后面的1代表正样本,-1代表负样本。
需要保证的是train和val两者没有交集,也就是训练数据和验证数据不能有重复,在选取训练数据的时候 ,也应该是随机产生的。- SegmentationClass文件和SegmentationObject
这两个文件都是与图像分割相关,跟本文无关,暂且不管。
制作自己的数据集
JPEGImages文件夹
1.清空JPEGImages文件夹下的原有图片数据,将自己项目或实验准备的图像数据放到该文件夹中(JPG格式),也可以后期通过代码改变图片存储格式。
2.resize:
在实际的应用中,这个数据集肯定是自己项目里面拍摄的。
首先,拍摄的图片可能分辨率太大,不利于训练,通过一顿操作把他们差不多缩小到跟voc数据集里的图片差不多大小。通过以下代码实现:# coding=utf-8 import os # 打开文件时需要 from PIL import Image import re Start_path = 'D:/1Aqilei/photos/' # 你的图片目录 width_max = 375 # 图片最大宽度 depth_max = 500 # 图片最大高度 list = os.listdir(Start_path) # print list count = 0 for pic in list: path = Start_path + pic print(path) im = Image.open(path) w, h = im.size print (w,h) #如果图片分辨率超过这个值,进行图片的等比例压缩 if w > width_max: print(pic) print("图片名称为" + pic + "图片被修改") h_new = width_max * h // w w_new = width_max count = count + 1 out = im.resize((w_new, h_new), Image.ANTIALIAS) new_pic = re.sub(pic[:-4], pic[:-4] , pic) # print new_pic new_path = Start_path + new_pic out.save(new_path) if h > depth_max: print(pic) print("图片名称为" + pic + "图片被修改") w_new = depth_max * w // h h_new = depth_max count = count + 1 out = im.resize((w_new, h_new), Image.ANTIALIAS) new_pic = re.sub(pic[:-4], pic[:-4] , pic) # print new_pic new_path = Start_path + new_pic out.save(new_path) print('END') count = str(count) print("共有" + count + "张图片尺寸被修改")
3.rename: 将图片重命名统一修改成0000001.jpg格式,代码如下:
import os path = "D:\\1Aqilei\\data" filelist = os.listdir(path) #该文件夹下所有的文件(包括文件夹) count=0 for file in filelist: Olddir = os.path.join(path, file) # 原来的文件路径 if os.path.isdir(Olddir): # 如果是文件夹则跳过 continue filename = os.path.splitext(file)[0] # 文件名 filetype = os.path.splitext(file)[1] # 文件扩展名 print(filename) Newdir = os.path.join(path, str(count).zfill(5) + filetype) # 用字符串函数zfill 以0补全所需位数 os.rename(Olddir, Newdir) # 重命名 count += 1 # os.path.splitext(“文件路径”) 分离文件名与扩展名;默认返回(fname,fextension)元组,可做分片操作 print ('END') count=str(count) print("共有"+count+"张图片尺寸被修改")
4.如果需要对数据进行其他预处理,都可以通过代码进行实现,但要注意的是,一定要把rename这一步骤放在最后进行!!!
Annotations文件夹
针对此文件夹,首先删除里面所有的xml文件,然后放入通过labelImg对JPEGImages文件夹中数据集标注后,自动产生的相应的xml文件。后面会有对数据集进行标注的具体讲解
ImageSets文件夹
针对此文件夹,首先删除Layout文件夹,Segmentation文件夹下的所有txt文件,(因为用不到,我不知道不删除会不会有影响,大家可以试一试,我个人认为不删也没有影响)然后针对Main文件夹,删除所有的txt文件,后面会详细介绍生成对应四个txt(还记得是那四个txt吗?)的详细操作以及代码。
其余两个文件夹不需要操作
LabelImg标记大法
想要训练自己的数据集,对数据集进行标注是重要且很烦的过程(对于特别大的数据集,急需解决大规模数据集标注的问题,如果有好的方法,评论或私信给博主!!不发牢骚了进入正题)
传送门:https://github.com/tzutalin/labelImg.
对于很多人第一次接触可能不会用(没错就是我),首先将直接download下来,解压到某个文件夹,然后进入改文件夹,直接运行labelImg.py就可以了然后类似这样:
具体细节怎么标注就不详细介绍了,请自行百度。(算了,贴出来)
有一点注意是:想改变标注文件夹位置
点击Menu/File中的Change default saved annotation folder这里。我们一般会将标注之后生成的对应图片的xml文件放到上面提到的Annotations文件夹中。生成txt文件
接下来要生成ImageSet/Main下的四个txt文件,分别是train.txt,val.txt,trainval_txt,text.txt,具体实现方法见下面代码:
# !/usr/bin/python # -*- coding: utf-8 -*- import os import random trainval_percent = 0.8 #trainval占整个数据集的百分比,剩下部分就是test所占百分比 train_percent = 0.7 # train占trainval的百分比,剩下部分就是val所占百分比 xmlfilepath = 'D:/1Aqilei---npupt/Faster-RCNN-TensorFlow-Python3-master/data/VOCdevkit2007/VOC2007/Annotations' txtsavepath = 'D:/1Aqilei---npupt/Faster-RCNN-TensorFlow-Python3-master/data\VOCdevkit2007/VOC2007/ImageSets/Main' total_xml = os.listdir(xmlfilepath) num = len(total_xml) list = range(num) tv = int(num * trainval_percent) tr = int(tv * train_percent) trainval = random.sample(list, tv) train = random.sample(trainval, tr) ftrainval = open(txtsavepath+'/trainval.txt', 'w') ftest = open(txtsavepath+'/test.txt', 'w') ftrain = open(txtsavepath+'/train.txt', 'w') fval = open(txtsavepath+'/val.txt', 'w') for i in list: name = total_xml[i][:-4] + '\n' if i in trainval: ftrainval.write(name) if i in train: ftrain.write(name) else: fval.write(name) else: ftest.write(name) ftrainval.close() ftrain.close() fval.close() ftest.close()
此代码是python代码,使用matlab代码请进入matalb代码生成txt文件,下载后更改下VOC2007txt.m中d 路径就能用了。
此时数据集制作完成。接下来的工作就快接近尾声了!修改代码–训练
1.进入 lib\datasets\pascal_voc.py中更改self._classes中的类别,注意,’'background’要保留,更改其余的类别。
2.进入lib/config/config.py中修改迭代次数30行的最大迭代次数,修改成你希望的次数;第44行修改迭代多少次保存一次模型,建议1000
3…在…\Faster-RCNN\data目录下,检查是否有个叫cache的文件夹,每次在训练模型前,清空这个文件夹里面的内容。
4.在开始训练之前,还需要把之前训练产生的模型以及cache删除掉
现在就可以进行训练了,激动吗??祈祷别出什么错误。
训练结束后,最后训练出来的模型会存储在default\voc_2007_trainval\default文件夹下。修改代码–测试
1.demo,py中更改self._classes中的类别,注意,’'background’要保留,更改其余的类别。
然后直接运行demo.py就可以啦!!
2.demo.py中main函数中将im_names中的内容替换成自己的测试图片。然后将Faster-RCNN-TensorFlow-Python3.5/data/demo中替换上相应的图片tensorboard进行可视化
训练结束后,根目录下会生成tensorboard文件夹,里面会有生成的log日志,文件结构如下
在命令行(gpu环境下)执行代码:tensorboard --logdir=tensorboard/vgg16/voc_2007_trainval/
logdir是日志文件的存在位置,执行结果如图:
然后代开浏览器(我的是谷歌浏览器)执行http://DESKTOP-SOOUC5J:6006结束语
文章的前半部分以及博文中的所有代码,博主亲测有效,博文后半部分,都是回忆部分。可能会有遗漏和错误。请大家在根据博文复现的时候遇到任何问题,请留言评论区,我会尽力解答,并把博文中遗漏的相关操作添加进去。
谢谢大家。多多指教!!!
过程中可能会遇到的问题及错误:
1.m = cv2.imread(roidb[i][‘image’]) KeyError
解决:
将Faster-RCNN-TensorFlow-Python3.5-master\data\cache文件夹中之前生成的文件模型删除。
因为会自己读取cache中的文本,导致训练出现错误。 -
-
制作自己的segnet数据集_夜间场景缺数据,如何进行语义分割?浙大提出基于GAN的高鲁棒夜间语义分割框架...
2020-11-22 01:04:46论文发表于2019年,地址为:https://arxiv.org/abs/1908.05868近年来,借助深度卷积神经网络(CNN),智能驾驶导航和安全监控取得了长足的进步。语义分割作为一种最先进的感知方法,在自动驾驶和安全...作者 | BBuf
单位 | 北京鼎汉技术有限公司 算法工程师(CV)
编辑 | 唐里浙大提出一种新的方法,通过将GAN和SOAT分割框架结合,实现对夜间图像也具有鲁棒的分割效果。
论文发表于2019年,地址为:https://arxiv.org/abs/1908.05868
近年来,借助深度卷积神经网络(CNN),智能驾驶导航和安全监控取得了长足的进步。语义分割作为一种最先进的感知方法,在自动驾驶和安全监控中具有广泛的应用前景。
当前,语义分割在标准场景(例如具有良好光照条件的白天场景)中表现出了高效的性能。但是,面对诸如夜间之类不利环境,语义分割会大大降低其准确性。造成此问题的主要原因之一是缺乏足够的夜间场景分割数据集。
在本文中,我们提出了一个使用生成对抗网络(GAN)来缓解将语义分割模型应用于夜间环境时的准确性下降。为了联系白天和夜晚的图像域,我们进行了关键的观察,与夜间环境下的数据相比,已经存在大量标准条件下的分割数据集如BBD,我们收集的ZJU等。
我们提出的基于GAN的夜间语义分割框架包括两种方法。在第一种方法中,GAN用于将夜间图像转换为白天,因此可以使用已经在白天数据集上训练的鲁棒模型来执行语义分割。第二种方法是,我们使用GAN将数据集中的白天图像转换为夜间图像,同时标签不变。所以,我们可以利用GAN合成夜间数据集,以产生在夜间条件下鲁棒性很好的模型。
在我们的实验中,第二种方法显著提高了模型在夜间图像上的分割性能,这可以使用IOU和ACC来评价。实验表明,性能还会随着数据集中合成夜间图像的比例变化而变化,其中最佳的比例对应于在白天和夜晚性能最高的模型。我们提出的方法不仅有助于智能车辆视觉感知的优化,而且可以应用于各种导航辅助系统。
1. 研究背景
诸如目标监测和语义分割之类的视觉任务始终是安全监控和自动驾驶的关键点。语义分割可以通过单个相机拍摄来完成不同的检测,使场景感知摆脱了复杂的多传感器融合。一些最新的方法如PSPNet,RefineNet,DeepLab和AcNet等以非常高的准确率执行语义分割任务。为了将语义分割应用于自动驾驶和安全监控,我们在先前的工作中提出了一个ERF-PSPNet[1],这是一种高精度的实时语义分割方法。
所有的这些感知算法均设计为可以在光照条件良好的白天拍摄的图像上运行。然而,户外应用很难逃脱恶劣的天气和照明条件。基于语义分割的计算机视觉系统尚未得到广泛应用的原因之一就是它不能处理环境不利条件。例如,基于可见光相机的语义分割模型在夜间表现不理想,原因就是在极弱的照度下,目标的结构,纹理和颜色特征会急剧变化。这些特征可能由于缺乏光照而消失,或者被干扰。因此,如何增强语义分割模型的鲁棒性成为计算机视觉领域的重要问题。在本文工作中,我们着重提高夜间语义分割的性能。
在本文中,我们提出了一个主框架如图Figure1所示,以克服语义分割模型从白天到晚上的精度急剧下降问题。受生成对抗网络的思想启发,夜间图像在前向推理过程中被转换为白天域的图像。换句话说,我们通过将部分白天图像转换为夜间图像来扩充原始的大规模语义分割数据集。在这些实验中,我们证明此方法提高了语义分割模型的鲁棒性。此外,我们还使用多模式立体视觉传感器来采集了浙江大学玉泉校区白天和夜晚的图像制作了数据集ZJU,设备被安放在一个仪表车上,如Figure2所示。
Figure 1
Figure 2
2. 相关工作
2.1 道路场景的语义理解
语义分割技术对于理解图像内容和感知目标位置很重要,并且该技术在自动驾驶领域也很关键。当前,大多数语义分割SOAT工作都是基于全卷积的端到端网络。受到SegNet的启发,语义分割模型通常采用编解码结构。编码器是经过训练可以对输入图像进行分类的CNN,解码器用于将编码器的输出上采样到和原始图像相同的大小。此外,有更多有效的语义分割网络被提出,我们的工作基于ERF-PSPNet,这是一种为导航辅助系统设计的最新语义分割网络。
2.2 模型适应
通常,CNN仅从训练数据域中学习特征,并且在不同的领域中可能表现会差很多。这也是为什么在白天训练的语义分割模型在夜间准确率会严重下降的原因。为了提高卷积神经网络的泛化能力,提出很多方法。最常见的是,使用诸如随机裁剪,随机旋转和翻转之类的数据增强技术去适应陌生域。在[29],[30]中已对合成数据的有效使用进行了初步的探索。[31]提出了另一种基于域适应的方法,用于将语义分割模型从合成图像适应到实际环境。[32,33]还提出了类似的方法来解决鲁棒的模糊场景解析。
2.3 图像风格转换
自动GoodFellow提出GAN之后,GAN就成为了最有前途的图像风格化方法。形式上,GAN同时包含两个模型:捕获关键分布的生成器G和估计样本来自训练数集而不是生成器的鉴别器D。尽管像Pix2Pix这样在风格转换上最先进的工作表现出众,但两个域中的训练数据都必须预先格式化为单个X/Y图像对,以保持紧密的像素相关性。最近提出的CycleGAN可以执行完整的转换过程,并省掉每张图像配对的过程,这很适合我们执行白天和夜晚的图像风格转换。
3. 方法
在我们的工作中提出了两种方法来缩小语义分割中白天和夜间图像之间的差距。这两种方法分别为将白天域图像转换为夜间域图像和夜间域图像转换为白天域图像。Figure1展示了我们的框架。我们训练一个CycleGAN来执行跨域转换。在第一种方法中,我们将夜间图像转换为白天图像,然后在白天图像上训练ERF-PSPNet。在第二种方法中,CycleGAN将训练集的部分白天图像转换为夜间图像,以扩展数据集的域覆盖范围。最后,我们用调整后的具有一定百分比的夜间图像的训练数据训练ERF-PSPNet,达到提高夜间语义分割模型性能的目的。
3.1 训练CycleGAN进行昼夜跨域转换
CycleGAN是一种在没有配对示例的情况下学习将图像从原域转换为目标域的方法,这符合我们的需求。CycleGAN包含两组GAN,每一组GAN又包含一个生成器和鉴别器。生成器和鉴别器进行图像风格转换,将图像从域X转换到域Y或者从域Y转换到域X。F和G代表了两个GAN,他们生成的内容分别为当前域图像的对立域图像。我们同时训练了G和F,并增加了循环一致性约束:
这种损失使未配对的图像风格转换成为可能。在我们的工作中,选取了BBD100K数据集6000张白天图像和6000张夜间图像作为两个图像域来训练CycleGAN。限于GPU的内存,我们将图像大小调整为480*270以训练CycleGAN。通过这种方式,我们获得了昼夜转换器。
3.2 在推理期间将图像转换为白天域
第一种选择是在推理的时候将夜间图像转换为白天图像。更具体的说,将摄像机获取的夜间图像用CycleGAN转换为合成的白天图像,这是语义分割更擅长处理的域。该方法不需要再次训练语义分割模型。换句话说,该方法的优势在于我们可以利用经过训练的ERF-PSPNet中的原始权重,该权重被证明在大多数数据集和实际场景中都是稳定的。此外,昼夜转换和分割过程是分开的,这使得调整更加容易。
但这种方法的缺点在于CycleGAN转换一张480*270的图像,前向推理花费的时间接近于1秒,这太慢了,并且语义分割系统也失去了实时性能。另外,CycleGAN合成的图像可能有一定偏差,例如可能将遥远的建筑物转换为树木。
3.3 产生夜间图像扩展数据集
第二种选择是将带有语义分割标签的BBD训练集中的部分白天图像转换为夜间图像。然后将带有合成夜间图像的数据集用来训练ERF-PSPNet损失函数。这个想法来自于缺乏精确分割的夜间数据集标签。
此方法的优点是对于训练模型,在推理过程中不会引入额外的计算。因此,ERF-PSPNet可以保留其实时的属性。在我们的实验中,我们探索了合成夜间图像的比例如何影响语义分割模型的准确性。此方法的缺点是重新训练模型的过程比较耗时,并且该模型可能并不总是对所有环境都具有鲁棒性。另外,我们必须将BBD100K数据集中的图像大小调整为480*270以训练GAN。这样GAN只能产生大小为480*270的图像。因此,我们必须将合成图像上采样到1280*720,然后再输入分割模型。这样的操作不可避免的会影响最终预测结果的准确性。
4. 结果
本文首先介绍了BDD数据集(BDD100K和BDD10K),ZJU数据集和Nighttime Driving test数据集。他们的图像分辨率,白天以及夜晚图像数量,标注信息如Table1所示:
Table 1
我们选择了BDD100K数据集中的6000张白天和黑夜图像训练CycleGAN。对于ERF-PSPNet,编码器部分在ImageNet上进行了预训练,所以ERF-PSPNet所有的训练任务都在解码器部分的训练中。第一种方法是在BDD10K上训练ERF-PSPNet。推理期间夜间图像用CycleGAN即时转换为白天域。在第二种方法中,使用BDD10K训练集中不同比例的图像来训练ERF-PSPNet。为了定量验证我们的方法,在BDD10K的验证集中使用32个带有分段注释的夜间图像和50个在Nighttime Driving test数据集中具有精确分段注释的夜间图像。Nighttime Driving test数据集中的图像样式类似于BDD10K,这使得在其上应用BDD训练的语义分割模型是合理的。最终,模型的实验表现如Table2所示:
Table 2
可以看到,使用本文的方法,模型在夜间图像的准确率得到了较大的提升。此外,本文还探索了第一种方法在拥有不同比例夜间图像的数据集上表现,如Figure7所示。
Figure 7
我们可以看到使用2000张合成的夜间图像的训练集得到的效果是最好的。然后在5000的时候曲线达到另外一个峰值,这个原因可能是5000是2000的对称数(总数是7000),并且该模型以互补的方式从白天图像中学习纹理信息,从夜晚图像中学习光照信息,但是此时白天的性能已经降低到了一个较低的水平。当所有图像均为夜间图像时,IOU甚至低于30%,这是因为合成图像中的纹理不等同于真实图像中的纹理。综上所述,使用2000张合成的夜间图像和5000张真实白天图像的训练集得到的效果是最好的。
5. 结论
在本文中,我们研究了夜间场景的图像语义分割问题。为了提高性能,通过CycleGAN训练双向昼夜转换器,提出了两种方法。在第一方法中,推理过程将夜间图像即时转换为白天图像,作为预处理步骤。在第二种方法中,将训练集的图像通过CycleGAN部分转换为夜间合成图像,从而提高了分割模型的鲁棒性。我们的实验在三个数据集上进行了测试,并证明了该方法的有效性。总而言之,我们的方法显著改善了夜间图像语义分割模型的性能,从而使诸如ERF-PSPNet之类的SOAT网络在夜间拥有较好的鲁棒性。
参考资料:
[1] Yang, K., Bergasa, L. M., Romera, E., Cheng, R., Chen, T., and Wang, K., “Unifying terrain awareness through real-time semantic segmentation,” in [2018 IEEE Intelligent Vehicles Symposium (IV)], 1033–1038, IEEE (June 2018).
[29] Sadat Saleh, F., Sadegh Aliakbarian, M., Salzmann, M., Petersson, L., and Alvarez, J. M., “Effective use of synthetic data for urban scene semantic segmentation,” in [Proceedings of the European Conference on Computer Vision (ECCV)], 84–100 (2018).
[30] Xu, Y., Wang, K., Yang, K., Sun, D., and Fu, J., “Semantic segmentation of panoramic images using a synthetic dataset,” in [Artificial Intelligence and Machine Learning in Defense Applications], International Society for Optics and Photonics (2019).
[31] Sankaranarayanan, S., Balaji, Y., Jain, A., Lim, S. N., and Chellappa, R., “Learning from synthetic data: Addressing domain shift for semantic segmentation,” in [2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition], 3752–3761, IEEE (2018).
[32] Dai, D. and Van Gool, L., “Dark model adaptation: Semantic image segmentation from daytime to nighttime,” in [2018 21st International Conference on Intelligent Transportation Systems (ITSC)], 3819–3824, IEEE (2018).
[33] Sakaridis, C., Dai, D., and Van Gool, L., “Semantic nighttime image segmentation with synthetic stylized data, gradual adaptation and uncertainty-aware evaluation,” arXiv preprint arXiv:1901.05946 (2019).
-
手势识别 雷达信号处理与卷积神经网络(1):构建自己的数据集
2018-10-19 15:45:58这里是**手势识别 雷达信号处理与卷积神经网络 (1)**,教你如何制作自己的数据集。 ” 我们经常使用开源数据集训练网络,那么当遇到特定的问题,没有合适的开源数据集时,如何获取并制作自己的数据集呢? -
带有TensorFlow的CNN-源码
2021-03-02 11:33:39使用图像数据集制作两个不同的CNN模型,例如基本的CNN模型和具有转移学习的CNN模型,并研究转移学习对CNN模型的性能的影响。 介绍 在本研讨会中,我将向您展示如何在有/没有转移学习和Inception的情况下构建卷积神经... -
基于caffe的CNN_训练+预测_思考记录(1)
2018-03-26 19:48:06训练与测试数据集的预处理与制作,对于CNN在训练时的loss值和预测时的准确度起着至关重要的作用,本节我来介绍如何对数据集进行预处理,并且制作相应的hdf5文件。以我最近的一个项目为例进行介绍,项目的主要内容是... -
用“Keras”11行代码构建CNN
2018-12-25 17:06:24我曾经演示过如何使用TensorFlow创建卷积神经网络(CNN)来对MNIST手写数字数据集进行分类。TensorFlow是一款精湛的工具,具有强大的功能和灵活性。然而,对于快速原型制作工作,可能显得有些麻烦。Kera... -
基于caffe的CNN_训练+预测_思考记录(2)
2018-03-27 19:43:51在对数据集进行预处理并且制作完成之后,便要开始训练数据集了,一般情况下CNN的搭建都是参考业内大牛的网络,或者在大牛的网络上进行细微的修改,所以对于大多数CNN使用者来说,搭建网络并非主要任务,最重要的是... -
Object_Detection_using_CNN.zip
2020-12-04 21:43:39在本系列文章中,我们将展示如何制作AI队列长度检测器。我们将从在自定义数据集上受过训练的从头开始实现一个简单的对象检测器开始,并以实时方式检测和跟踪对象(在我们的例子中为人类)。稍后,我们还将看到如何... -
基于像素梯度的深度学习:Pytorch:基于像素梯度的深度学习(HOG + CNN)-源码
2021-02-20 12:19:31Pytorch:基于像素梯度的深度学习(HOG +...通过使用MNIST数据集进行图像分类。 有关更多详细信息,请参见demo_mnist.py。 结果 火炬实施 如何在pytorch模型中实现像素渐变阵列。 步骤1:必要的模块 import numpy as n -
利用CNN处理基于人体行为识别TensorFlow实战(二)(搭建神经网络)
2018-12-17 11:49:35在上次我们已经学会了如何去制作数据集,并且学习到了一些处理数据的方法和工具,那么现在我们就学习如何去搭建一个神经网络,我们所有的代码都已经上传到了github上面,有需要的同学可以进行查阅,现在开始学习如何搭建... -
CNN(一)(1)——LeNet实战(英文+数字识别)
2020-08-19 09:53:54这在少数据集上,有着很好的性能。我根据这个特性。我准备收集一些英文和数字的数据。使用pytorch进行一个识别训练。看看最终的效果如何。 过程: 收集数据集 -> 分类 -> 搭建整个代码框架 -> 投入训练 -&... -
Python全栈数据工程师养成攻略.张宏伦(带详细书签).pdf
2018-12-26 17:59:495.3 实战:Diamonds 数据集探索 63 5.3.1 查看数据 63 5.3.2 价格和克拉 64 5.3.3 价格分布 64 5.3.4 纯净度分布 65 5.3.5 价格概率分布 65 5.3.6 不同切工下的价格分布 65 5.3.7 坐标变换 66 5.3.8 标题和... -
基于Pytorch的手写汉字识别
2020-07-31 16:29:54基于Pytorch的手写汉字识别说明数据集代码解析...这篇文章的代码是参照了另外一个大神的博客「Pytorch」CNN实现手写汉字识别(数据集制作,网络搭建,训练验证测试全部代码),非常感谢大神奉献的知识! 由于我是小白, -
Machine-Learning-Playbook:我有用的代码,程序,说明以及有关机器学习的更多内容的集合!...
2021-03-06 09:26:46密集的NN和多层感知器(基于MNIST和Fashion MNIST数据集) 接下来,我制作了一个 ,可以在MNIST上对手写数字进行分类,然后使用重做相同的项目。 我还制作了一个 ,可以区分Fashion MNIST数据集中的类。 卷积神经... -
基于OpenCV的路面质量检测的实现
2020-12-16 19:54:09为了测试这种方法,我们使用了我们制作的RTK数据集。 路面分类 该数据集[1]包含用低成本相机拍摄的图像,以及新兴国家常见的场景,其中包含未铺砌的道路和坑洼。路面类型是有关人或自动驾驶车辆应如何驾驶的重要... -
机器学习与计算机视觉入门项目——视频投篮检测(二)
2018-08-27 04:51:06在上一次的博客中,介绍了计算机视觉和机器学习的关系、篮球进球检测的基本问题和数据集的制作。这次的我们主要介绍如何从原始图像中提取有用的图像特征,以便应用于之后的分类器。 如下图所示,我们现在要做的是... -
《21个项目玩转深度学习:基于Tensorflow的实践详解》高清完整版.zip
2019-12-10 16:27:511.1 MNIST数据集 2 1.1.1 简介 2 1.1.2 实验:将MNIST数据集保存为图片 5 1.1.3 图像标签的独热(one-hot)表示 6 1.2 利用TensorFlow识别MNIST 8 1.2.1 Softmax回归 8 1.2.2 两层卷积网络分类 14 1.3 总结 18 ... -
【深度学习入门】mnist手写数字识别
2020-06-11 10:28:50可视化自己制作测试集验证 mnist是深度学习的“hello world”,谷歌、tensorflow官网都有详尽的教程介绍如何上手。之前的项目大多是在别人写好的框架上修改、发挥,理论上对原理算是熟悉的了,但是许多函数的理解... -
asp.net知识库
2015-06-18 08:45:45ADO.NET 2.0 大批量数据操作和多个动态的结果集 ADO.NET 2.0 异步处理 在ASP.NET中使用WINDOWS验证方式连接SQL SERVER数据库 改进ADO.Net数据库访问方式 ASP.NET 2.0 绑定高级技巧 简单实用的DataSet更新数据库的类+... -
Deep Learning Specialization对卷积神经网络 (CNN)、递归神经网络 (RNN)、长短期记忆 (LSTM) 等深度学习常用的网络结构、工具和知识都有涉及。 课程中也会有很多实操项目,帮助学生更好地应用自己学到的深度学习...
-
网管教程 从入门到精通软件篇.txt
2010-04-25 22:43:49CHR:字符集(字体文件) CHT:ChartViem文件;Harvard Graphics矢量文件 CIF:Adaptec CD 创建器 CD映像文件 CIL:Clip Gallery下载包 CIM:SimCity 2000文件 CIN:OS/2改变控制文件用于跟踪INI文件中的变化 ...