用AlexNet实现路标分类

一、数据来源:

http://btsd.ethz.ch/shareddata/网站下载比利时交通图标。
( T e s t i n g Testing Testing 文件夹用于做训练集, T r a i n i n g Training Training文件夹用于检测):

二、数据前期处理

T e s t i n g Testing Testing文件夹中的 . p p m .ppm .ppm图片转化为 . j p g .jpg .jpg图片:
思路:遍历 T e s t i n g Testing Testing文件夹中各个子文件夹(每个子文件夹中是一种路标的不同图片)。利用PIL库中的函数打开个图片,将图片转化为模型所用的227×227格式后,转c成.jpg格式并存到另一文件夹中。在转存时利用os.path.exists函数来判断路径是否存在,返回的是False,再利用os.makedirs(path)函数来创建路径。

def change(path):
#将《切割好的图片》文件夹中的图片转化为AlexNet模型要求的图片大小
    for root,stdirs,filenames in os.walk(path):
    #遍历path路径对应的文件夹
        for stdir in stdirs:
        #遍历文件夹中的子文件夹
            i = 0
            dir1 = os.path.join(root,stdir)
            #获取子文件夹的路径
            #print('dir1:', dir1)
            #print('filenames:',filenames)
            for filename in os.listdir(dir1):
            #os.listdir:返回子文件夹中的图片目录
                try:
                    i+=1
                    dir2=os.path.join(dir1,filename)
                    #获取图片路径
                   # print('dir2:', dir2)
                    #print('*********')
                    img=Image.open(dir2)
                    #利用PIL库打开图片
                    x_s = 227
                    y_s = 227
                    out = img.resize((x_s, y_s), Image.ANTIALIAS)
                    #改变图片的大小;img.resize(1)
                    dir3_1=dir2.split('\\')[-2]
                    #将得到的图片地址分割,获取图片的文件夹名
                    #print('dir3_1',dir3_1)
                    dir3_2=r"C:\\Users\\abc\\Desktop\\test1\\"
                    os.path.join(dir3_2,dir3_1)
                    dir3_3 =dir3_2+dir3_1
                    folder = os.path.exists(dir3_3)
                    #os.path.exists:判断"dir3_3"的路径是否存在;若存在则返回True.
                    if not folder:
                        os.makedirs(dir3_3)
                        #递归的创建"dir3_3"对应的多级目录。即:若test1,dir3_1均不存在的话会自动创建
                    dir3=os.path.join(dir3_3,str(i)+'.jpg')
                    #dir3 = os.path.join(dir3_2, str(i) + '.jpg')
                    #print('dir3',dir3)
                    out.save(dir3)
                    #将图片按“dir3”的路径存储
                except:
                    print(dir2)
                    print('------')
               #使用try....except格式:当遇到.csv文件时跳过
                cv2.waitKey(0)

用到的函数:
(1)img.resize((width,height),Image.ANTIALIAS)

 img.resize((width,height),X)
    第二个参数X可以是:
     Image.NEAREST :低质量
     Image.BILINEAR:双线性
     Image.BICUBIC :三次样条插值
     Image.ANTIALIAS:高质量

(2)os.makedirs(C:\\path1\\path2\\path3)与os.makedir(C:\\path1\\path2\\path3)的区别

os.makedirs(C:\\path1\\path2\\path3):
创建多层目录。即:若path1,path2,path3均不存在,则依次创建path1,path2,path3目录
 os.makedir(C:\\path1\\path2\\path3):
仅创建路径中的最后一级目录,即:仅创建path3目录

三、数据集的获取,设置图片标签

'''
输入图片文件夹的路径
输出图片的路径列表和对应的标签列表
'''

def get_file(file_dir):
    images = []  
    # 每张图片的路径组成的列表
    temp = [] 
     # 保存文件夹路径
    for root, sub_folders, files in os.walk(file_dir):
    #各图片的名字保存在files中
        for name in files:
            images.append(os.path.join(root, name))
			#依次将各图片的路径保存在images列表中
        for name in sub_folders:
            temp.append(os.path.join(root, name))
            #依次将各子文件夹的路径保存在temp列表中

    labels = []  
    # 保存标签列表

    # 此时temp为根目录下所有文件夹的路径列表 一次取出一个文件夹 对文件夹里面的所有数据图片设置标签
    for one_folder in temp:
        n_img = len(os.listdir(one_folder)) 
         # 得到“one_folder”文件夹下的图片总数
        letter = one_folder.split('\\')[-1]  
        # 将子文件夹的路径按照“\\”分割 取出最后一个即:得到文件夹的名称

        # 标注数据集
        labels = np.append(labels, n_img * [int(letter)])


    temp = np.array([images, labels])  
    # 重新创建数组temp;将images 和 labels 做为一对键值对写入temp中
    temp = temp.transpose()  
    # 将temp转置
    np.random.shuffle(temp)  
    # 打乱数据集的顺序

    image_list = list(temp[:, 0]) 
     # 取出数组中的第一维 即:图片的路径列表
    label_list = list(temp[:, 1]) 
     # 取出数组中的第二维 即:图片的标签列表
    label_list = [int(float(i)) for i in label_list]

    return image_list, label_list

四、将图片地址的数据集转化为 T e n s o r F l o w TensorFlow TensorFlow 专用格式

'''
输入2.中获得的图片路径列表的对应的标签列表
输出两个张量:
'''
def get_batch(image_list, label_list, img_width, img_height, batch_size, capacity):
    """将图片地址的数据集转化为TensorFlow专用格式"""
    image = tf.cast(image_list, tf.string)
    #将列表转化为tensor,一个张量元素是一个字节数组
    label = tf.cast(label_list, tf.int64)
	#将列表转化为tensor,元素转化为64 位有符号整型
    input_queue = tf.train.slice_input_producer([image, label])
	#创建一个文件名队列,input_queue是文件名队列的名字
    label = input_queue[1]
    image_contents = tf.read_file(input_queue[0])
    #tf.read_file:读取图片
    image = tf.image.decode_jpeg(image_contents, channels=3)
	#将存储的".jpg"图像还原成一个三维矩阵.解码之后的结果为一个张量,在使用它的取值
	#之前需要明确调用运行的过程
    image = tf.image.resize_image_with_crop_or_pad(image, 227, 227)
    #将图片尺寸转化为227×227
    image = tf.image.per_image_standardization(image)
    image_batch, label_batch = tf.train.batch([image, label], batch_size=200, num_threads=64, capacity=300)
    label_batch = tf.reshape(label_batch, [batch_size])
    return image_batch, label_batch


# 输入文件路径 获得两个batch
x_train, y_train = get_file(r'C:\Users\abc\Desktop\test1')
image_batch, label_batch = get_batch(x_train, y_train, 227, 227, 200, 2048)

用到的函数:
(1). tf.train.slice_input_producer

tf.train.slice_input_producer 函数:(创建tf的文件名队列) 一种模型数据的排队输入方法。从tensor列表
[image, label]中按顺序或者随机取出一个tensor放入文件名队列。
(文件名队列存放的是参与训练的文件名,要训练N次,则文件名队列中就含有N个批次的所有文件名)
slice_input_producer(tensor_list, num_epochs=None, shuffle=True, seed=None,capacity=32, shared_name=None, name=None)
  • tensor_list:包含一系列tensor的列表,在 [image, label] 中有多少个图片,就应有多少个标签。
  • num_epochs:表示迭代次数,若未设置则表示无限次的便利tensor列表
  • shuffle: bool类型,设置是否打乱样本的顺序。一般情况下,如果shuffle=True,生成的样本顺序就被打乱了,在批处理的时候不需要再次打乱样本,使用 tf.train.batch函数就可以了;如果shuffle=False,就需要在批处理时候使用 tf.train.shuffle_batch函数打乱样本。
  • seed:整数(可选择),当shuffle=True时使用
  • capacity:tensor列表的容量
  • shared_name:可选参数,如果设置一个‘shared_name’,则在不同的上下文环境(Session)中可以通过这个名字共享生成的tensor。
  • name:设置操作的名称(可选)

(2). tf.image.resize_image_with_crop_or_pad

tf.image.resize_image_with_crop_or_pad(image, target_height, target_width):
通过集中裁剪图像或使用零均匀填充图像,将图像大小调整为目标宽度和高度,如果宽度或高度分别大于指定的
目标宽度或目标高度,则此操作将沿该维度集中裁剪。如果宽度或高度分别小于指定的目标宽度或目标高度,
则此操作沿该尺寸以黑色填充

(3). tf.image.per_image_standardization

tf.image.per_image_standardization(image):
图片标准化,将像素做处理

在这里插入图片描述

(4). tf.train.batch

tf.train.batch是一个tensor队列生成器,作用是按照给定的tensor顺序,把batch_size个tensor推送到文件队列,
作为训练一个batch的数据,等待tensor出队执行计算
`tf.train.batch(tensor,batch_size,num_thresds=1,capacity=32,enqueue_many=False,shapes=None, 
dynamic_pad=False,allow_smaller_final_batch=False,shared_name=None,name=None)
  • tensor:一个tensor列表或字典用来入队
  • batch_size:设置每次从队列中获取的出队数据的数量
  • num_threads:用来控制入队tensors线程的数量,如果num_threads大于1,则batch操作将是非确定性的,输出的batch可能会乱序
  • capacity:一个整数,用来设置队列中元素的最大数量
  • enqueue_many:在tensors中的tensor是否是单个样本
  • shapes:可选,每个样本的shape,默认是tensors的shape
  • dynamic_pad:Boolean值.允许输入变量的shape,出队后会自动填补维度,来保持与batch内的shapes相同
  • allow_samller_final_batch:可选,Boolean值,如果为True队列中的样本数量小于batch_size时,出队的数量会以最终遗留下来的样本进行出队,如果为Flalse,小于batch_size的样本不会做出队处理
  • shared_name:可选,通过设置该参数,可以对多个会话共享队列
  • name:可选,操作的名字

tf.train.batch与tf.train.slice_input_producer的区别:

tf.train.slice_input_producer用于创建tf的文件名队列,

推荐博客地址1
推荐博客地址2

tf.train.batch() 按顺序批量读取文件队列中的数据,将读取到的样例组织成batch批量数据的形式返回。

五、 使用 Batch_Normalization 正则化处理数据集

def batch_norm(inputs, is_training, is_conv_out=True, decay=0.999):
    scale = tf.Variable(tf.ones([inputs.get_shape()[-1]]))
    beta = tf.Variable(tf.zeros([inputs.get_shape()[-1]]))
    pop_mean = tf.Variable(tf.zeros(inputs.get_shape()[-1]), trainable=False)
    pop_var = tf.Variable(tf.ones(inputs.get_shape()[-1]), trainable=False)

    if is_training:
        if is_conv_out:
            batch_mean, batch_var = tf.nn.moments(inputs, [0, 1, 2])
            #tf.nn.moments()函数用于计算均值和方差

        else
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值