深度学习训练自己的数据集(车辆图像识别分类)

鉴于有很多人来询问我数据集(我翻箱倒柜找了一下= =放在这里了,有需要自取)

链接:https://pan.baidu.com/s/1Fjgs_MMiIDO9-wFKs6QJSg 
提取码:1efk 
复制这段内容后打开百度网盘手机App,操作更方便哦

 

一、实验目的

考核各位同学使用较小的模型和小规模的训练数据下的模型设计和训练的能力。需要同学充分利用迁移学习等方法,以解决训练数据少的问题,同时需要思考和解决深度学习中过拟合的问题。所提供的场景定义为比较单一的车辆场景,一定程度上平衡了难度系数。

 

二、实验内容

使用提供的2000张标注了的车辆场景分类信息的高分辨率图片,建立并训练模型,并将此模型运用于测试数据集的图像分类标注。

标签信息:

0,巴士,bus

1,出租车,taxi

2,货车,truck

3,家用轿车,family sedan

4,面包车,minibus

5,吉普车,jeep

6,运动型多功能车,SUV

7,重型货车,heavy truck

8,赛车,racing car

9,消防车,fire engine

三、实验内容

1、实验平台:

 WIN10+annaconda+tensorflow

安装教程:https://blog.csdn.net/qq_30611601/article/details/79067982

2、实验流程:

代码利用卷积网络完成一个图像分类的功能。训练完成后,模型保存在model文件中,可直接使用模型进行线上分类。同一个代码包括了训练和测试阶段,通过修改train参数为True和False控制训练和测试。显示实验结果,再根据结果做微小调整。

数据处理->导入相关库->配置信息->数据读取->定义placeholder(容器)->定义卷积网络(卷积和Pooling部分)->定义全连接部分->定义损失函数和优化器(这里有一个技巧,没有必要给Optimizer传递平均的损失,直接将未平均的损失函数传给Optimizer即可)->定义模型保存器/载入器->进入训练/测试执行阶段

3、实验代码

整体代码参考的如下网址:
https://blog.csdn.net/wills798/article/details/80890990

需要修改的两点:

1、由于参考代码训练的是32X32图片,而且图片名字也是标签名+序号,所以我们想要直接用的话,就必须做修改工作

    分为:rename、resize两个步骤

2、参考代码训练和测试的数据集是同一个,而我们这里有区分,所以要把源代码分为train.py,test.py

修改图片:

在项目根目录新建以下空文件夹

移入源数据(这里的测试集用的是val,用test还要修改代码懒得弄)

运行renas.py(注意,这里运行一次就可以了,因为运行完,默认将train内源数据删除)

运行结果:

代码:

#coding=utf-8
from PIL import Image
import os
import os.path
import glob

def rename(rename_path,outer_path,folderlist):
#列举文件夹
    for folder in folderlist:
        if os.path.basename(folder)=='bus':
            foldnum = 0
        elif os.path.basename(folder)=='taxi':
            foldnum = 1
        elif os.path.basename(folder)=='truck':
            foldnum = 2
        elif os.path.basename(folder)=='family sedan':
            foldnum = 3
        elif os.path.basename(folder)=='minibus':
            foldnum = 4
        elif os.path.basename(folder)=='jeep':
            foldnum = 5
        elif os.path.basename(folder)=='SUV':
            foldnum = 6
        elif os.path.basename(folder)=='heavy truck':
            foldnum = 7
        elif os.path.basename(folder)=='racing car':
            foldnum = 8
        elif os.path.basename(folder)=='fire engine':
            foldnum = 9 	
        inner_path = os.path.join(outer_path, folder) 
        total_num_folder = len(folderlist)       #文件夹的总数
        # print 'total have %d folders' % (total_num_folder)   #打印文件夹的总数
        filelist = os.listdir(inner_path)        #列举图片
        i = 0
        for item in filelist:
            total_num_file = len(filelist)       #单个文件夹内图片的总数
            if item.endswith('.jpg'):
                src = os.path.join(os.path.abspath(inner_path), item)           #原图的地址
                dst = os.path.join(os.path.abspath(rename_path), str(foldnum) + '_' + str(i) + '.jpg')        #新图的地址(这里可以把str(folder) + '_' + str(i) + '.jpg'改成你想改的名称)
            try:
                os.rename(src, dst)
                # print 'converting %s to %s ...' % (src, dst)
                i += 1
            except:
                continue
#训练集
rename_path1 = 'E:/Tensorflow-CNN-VehicleIdentification/renametrain'
outer_path1 = 'E:/Tensorflow-CNN-VehicleIdentification/train'
folderlist1 = os.listdir(r"E:/Tensorflow-CNN-VehicleIdentification/train")
rename(rename_path1,outer_path1,folderlist1)
print("train totally rename ! ! !")
#测试集
rename_path2 = 'E:/Tensorflow-CNN-VehicleIdentification/renametest'
outer_path2 = 'E:/Tensorflow-CNN-VehicleIdentification/val'
folderlist2 = os.listdir(r"E:/Tensorflow-CNN-VehicleIdentification/val")
rename(rename_path2,outer_path2,folderlist2)
print("test totally rename ! ! !")

#修改图片尺寸
def convertjpg(jpgfile,outdir,width=32,height=32):
    img=Image.open(jpgfile)
    img=img.convert('RGB')
    img.save(os.path.join(outdir,os.path.basename(jpgfile)))
    new_img=img.resize((width,height),Image.BILINEAR)   
    new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
#训练集
for jpgfile in glob.glob("E:/Tensorflow-CNN-VehicleIdentification/renametrain/*.jpg"):
    convertjpg(jpgfile,"E:/Tensorflow-CNN-VehicleIdentification/data")
print("train totally resize ! ! !")
#测试集
for jpgfile in glob.glob("E:/Tensorflow-CNN-VehicleIdentification/renametest/*.jpg"):
    convertjpg(jpgfile,"E:/Tensorflow-CNN-VehicleIdentification/test")

print("test totally resize ! ! !")

修改源代码:

train.py

#coding=utf-8

import os
#图像读取库
from PIL import Image
#矩阵运算库
import numpy as np
import tensorflow as tf


# 数据文件夹
data_dir = "E:/Tensorflow-CNN-VehicleIdentification/data"
# 训练还是测试True False
train = True
# 模型文件路径
model_path = "model/image_model"

# 从文件夹读取图片和标签到numpy数组中
# 标签信息在文件名中,例如1_40.jpg表示该图片的标签为1
def read_data(data_dir):
    datas = []
    labels = []
    fpaths = []
    for fname in os.listdir(data_dir):
        fpath = os.path.join(data_dir, fname)
        fpaths.append(fpath)
        image = Image.open(fpath)
        data = np.array(image) / 255.0
        label = int(fname.split("_")[0])
        datas.append(data)
        labels.append(label)

    datas = np.array(datas)
    labels = np.array(labels)

    print("shape of datas: {}\tshape of labels: {}".format(datas.shape, labels.shape))
    return fpaths, datas, labels


fpaths, datas, labels = read_data(data_dir)

# 计算有多少类图片
num_classes = len(set(labels))


# 定义Placeholder,存放输入和标签
datas_placeholder = tf.placeholder(tf.float32, [None, 32, 32, 3])
labels_placeholder = tf.placeholder(tf.int32, [None])

# 存放DropOut参数的容器,训练时为0.25,测试时为0
dropout_placeholdr = tf.placeholder(tf.float32)

# 定义卷积层, 20个卷积核, 卷积核大小为5,用Relu激活
conv0 = tf.layers.conv2d(datas_placeholder, 20, 5, activation=tf.nn.relu)
# 定义max-pooling层,pooling窗口为2x2,步长为2x2
pool0 = tf.layers.max_pooling2d(conv0, [2, 2], [2, 2])

# 定义卷积层, 40个卷积核, 卷积核大小为4,用Relu激活
conv1 = tf.layers.conv2d(pool0, 40, 4, activation=tf.nn.relu)
# 定义max-pooling层,pooling窗口为2x2,步长为2x2
pool1 = tf.layers.max_pooling2d(conv1, [2, 2], [2, 2])


# 定义卷积层, 60个卷积核, 卷积核大小为3,用Relu激活
conv2 = tf.layers.conv2d(pool0, 60, 3, activation=tf.nn.relu)
# 定义max-pooling层,pooling窗口为2x2,步长为2x2
pool2 = tf.layers.max_pooling2d(conv2, [2, 2], [2, 2])


# 将3维特征转换为1维向量
flatten = tf.layers.flatten(pool2)

# 全连接层,转换为长度为100的特征向量
fc = tf.layers.dense(flatten, 400, activation=tf.nn.relu)

# 加上DropOut,防止过拟合
dropout_fc = tf.layers.dropout(fc, dropout_placeholdr)

# 未激活的输出层
logits = tf.layers.dense(dropout_fc, num_classes)

predicted_labels = tf.arg_max(logits, 1)


# 利用交叉熵定义损失
losses = tf.nn.softmax_cross_entropy_with_logits(
    labels=tf.one_hot(labels_placeholder, num_classes),
    logits=logits
)
# 平均损失
mean_loss = tf.reduce_mean(losses)

# 定义优化器,指定要优化的损失函数
optimizer = tf.train.AdamOptimizer(learning_rate=1e-2).minimize(losses)
n=0

# 用于保存和载入模型
saver = tf.train.Saver()

with tf.Session() as sess:

    if train:
        print("训练模式")
        # 如果是训练,初始化参数
        sess.run(tf.global_variables_initializer())
        # 定义输入和Label以填充容器,训练时dropout为0.25
        train_feed_dict = {
            datas_placeholder: datas,
            labels_placeholder: labels,
            dropout_placeholdr: 0.5
        }
        for step in range(150):
            _, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)

            if step % 10 == 0:
                print("step = {}\tmean loss = {}".format(step, mean_loss_val))
        saver.save(sess, model_path)
        print("训练结束,保存模型到{}".format(model_path))
    else:
        print("测试模式")
        # 如果是测试,载入参数
        saver.restore(sess, model_path)
        print("从{}载入模型".format(model_path))
        # label和名称的对照关系
        label_name_dict = {
            0: "巴士",
            1: "出租车",
            2: "货车",
            3: "家用轿车",
            4: "面包车",
            5: "吉普车",
            6: "运动型多功能车",
            7: "重型货车",
            8: "赛车",
            9: "消防车"
        }
        # 定义输入和Label以填充容器,测试时dropout为0
        test_feed_dict = {
            datas_placeholder: datas,
            labels_placeholder: labels,
            dropout_placeholdr: 0
        }
        predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)
        # 真实label与模型预测label
        for fpath, real_label, predicted_label in zip(fpaths, labels, predicted_labels_val):
            # 将label id转换为label名
            real_label_name = label_name_dict[real_label]
            predicted_label_name = label_name_dict[predicted_label]
            print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))

       

test.py

#coding=utf-8

import os
#图像读取库
from PIL import Image
#矩阵运算库
import numpy as np
import tensorflow as tf


# 数据文件夹
data_dir = "E:/Tensorflow-CNN-VehicleIdentification/test"
# 训练还是测试True False
train = False
# 模型文件路径
model_path = "model/image_model"


# 从文件夹读取图片和标签到numpy数组中
# 标签信息在文件名中,例如1_40.jpg表示该图片的标签为1
def read_data(data_dir):
    datas = []
    labels = []
    fpaths = []
    for fname in os.listdir(data_dir):
        fpath = os.path.join(data_dir, fname)
        fpaths.append(fpath)
        image = Image.open(fpath)
        data = np.array(image) / 255.0
        label = int(fname.split("_")[0])
        datas.append(data)
        labels.append(label)

    datas = np.array(datas)
    labels = np.array(labels)

    print("shape of datas: {}\tshape of labels: {}".format(datas.shape, labels.shape))
    return fpaths, datas, labels


fpaths, datas, labels = read_data(data_dir)

# 计算有多少类图片
num_classes = len(set(labels))


# 定义Placeholder,存放输入和标签
datas_placeholder = tf.placeholder(tf.float32, [None, 32, 32, 3])
labels_placeholder = tf.placeholder(tf.int32, [None])

# 存放DropOut参数的容器,训练时为0.25,测试时为0
dropout_placeholdr = tf.placeholder(tf.float32)

# 定义卷积层, 20个卷积核, 卷积核大小为5,用Relu激活
conv0 = tf.layers.conv2d(datas_placeholder, 20, 5, activation=tf.nn.relu)
# 定义max-pooling层,pooling窗口为2x2,步长为2x2
pool0 = tf.layers.max_pooling2d(conv0, [2, 2], [2, 2])

# 定义卷积层, 40个卷积核, 卷积核大小为4,用Relu激活
conv1 = tf.layers.conv2d(pool0, 40, 4, activation=tf.nn.relu)
# 定义max-pooling层,pooling窗口为2x2,步长为2x2
pool1 = tf.layers.max_pooling2d(conv1, [2, 2], [2, 2])

# 定义卷积层, 60个卷积核, 卷积核大小为3,用Relu激活
conv2 = tf.layers.conv2d(pool0, 60, 3, activation=tf.nn.relu)
# 定义max-pooling层,pooling窗口为2x2,步长为2x2
pool2 = tf.layers.max_pooling2d(conv2, [2, 2], [2, 2])


# 将3维特征转换为1维向量
flatten = tf.layers.flatten(pool2)

# 全连接层,转换为长度为100的特征向量
fc = tf.layers.dense(flatten, 400, activation=tf.nn.relu)

# 加上DropOut,防止过拟合
dropout_fc = tf.layers.dropout(fc, dropout_placeholdr)

# 未激活的输出层
logits = tf.layers.dense(dropout_fc, num_classes)

predicted_labels = tf.arg_max(logits, 1)


# 利用交叉熵定义损失
losses = tf.nn.softmax_cross_entropy_with_logits(
    labels=tf.one_hot(labels_placeholder, num_classes),
    logits=logits
)
# 平均损失
mean_loss = tf.reduce_mean(losses)

# 定义优化器,指定要优化的损失函数
optimizer = tf.train.AdamOptimizer(learning_rate=1e-2).minimize(losses)

# 用于保存和载入模型
saver = tf.train.Saver()

with tf.Session() as sess:

    if train:
        print("训练模式")
        # 如果是训练,初始化参数
        sess.run(tf.global_variables_initializer())
        # 定义输入和Label以填充容器,训练时dropout为0.25
        train_feed_dict = {
            datas_placeholder: datas,
            labels_placeholder: labels,
            dropout_placeholdr: 0.5
        }
        for step in range(150):
            _, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)

            if step % 10 == 0:
                print("step = {}\tmean loss = {}".format(step, mean_loss_val))
        saver.save(sess, model_path)
        print("训练结束,保存模型到{}".format(model_path))
    else:
        print("测试模式")
        # 如果是测试,载入参数
        saver.restore(sess, model_path)
        print("从{}载入模型".format(model_path))
        # label和名称的对照关系
        label_name_dict = {
            0: "巴士",
            1: "出租车",
            2: "货车",
            3: "家用轿车",
            4: "面包车",
            5: "吉普车",
            6: "运动型多功能车",
            7: "重型货车",
            8: "赛车",
            9: "消防车"
        }
        # 定义输入和Label以填充容器,测试时dropout为0
        test_feed_dict = {
            datas_placeholder: datas,
            labels_placeholder: labels,
            dropout_placeholdr: 0
        }
        predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)
        # 真实label与模型预测label
        for fpath, real_label, predicted_label in zip(fpaths, labels, predicted_labels_val):
            # 将label id转换为label名
            real_label_name = label_name_dict[real_label]
            predicted_label_name = label_name_dict[predicted_label]
            print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))

        # 正确次数
        correct_number=0
        # 计算正确率
        for  fpath, real_label, predicted_label in zip(fpaths, labels, predicted_labels_val):
            if real_label==predicted_label:
                correct_number+=1

        correct_rate=correct_number/200
        print('正确率: {:.2%}'.format(correct_rate))
                

四、实验结果

dropout=0.25

 

drop=0.5

 

 

正确率不高,因为用的模型就是基础的神经网络,想要准确度更好,可以试试RESNET,DENSENET等迁移模型。

或者直接进pytorch官网https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html有现成的模型可以套

 

用于开发,评估和比较学习方法的数据收集 066c695f141f27ea881df8af5a827c99.jpg 7fe25c5c90c4f447fe3fa10adf4232cd.jpg 6739b35e5a470fdb37862fb2bc5251ef.jpg c1adb1337eba00e584e3704af99d291c.jpg cf042dd7addc3894b78063b90016ec03.jpg 1b9471eefb6f3951f127beb69ef5a584.jpg fb1e25b446c8174cc443c366a1d0e38b.jpg 5bbe28f7cf6ee6453caad79db64ba7c0.jpg 5d7514af404266c3f92efcee8662f640.jpg 9e37ae8bf11600a30afcd592d73a4be1.jpg 63f9f7dc8298317284bf7dbf2074b3ba.jpg 356d8576837338e82cf363d2dc7747c0.jpg 45242c276cd516adb93561503a2f6ed7.jpg a67cad73fd03d2d5cef3a81bf78ed0a3.jpg b2de8a56b1fbbee32afbe72d823f8a5a.jpg eafaa5fd38df370046f8b185488e7fa5.jpg f81a39ee4b311be9eb5aac2ba1cbaffd.jpg 2aeb7856890c8dc0e0b311077d386690.jpg 2b96ccd24db32c2c47581afde8d42722.jpg 7a9027a09a9149fd901f97630a052b29.jpg 395e11b1214a0308f6a6e7834cebc379.jpg 508bc40d51bc31a77507595e528155e9.jpg 7457b846fc17229e61aea790bab3c88a.jpg b9ea06b2cdf8e72dca0f415d1525d7d5.jpg b52fbc88bc83acea1b0d374ccb460178.jpg b62c7d59cd74dc1bc2eaa1b951cfd0a7.jpg f550965cf9cc6f07184923a32d728e94.jpg ff9974e9177a989100fae4b8c505cad5.jpg 7be124ec367694c948c57d1e09181775.jpg 050aab9a8a91dca8ed1e518ebf42ee0d.jpg 253df8c5a6ed19d8dcf26ea58c40094d.jpg 802716d5a05096b02621ad4eabf57812.jpg 62352815acbebb5bc9eebaf534d8f434.jpg a2fec0c55e7c73d27fac134b9074846e.jpg b8ebfa32f6ba5c7c50b63bc1c0108361.jpg b00473a9f517bbfc5923c95288b40ff2.jpg bec04a0e1662c9c23365eb3a9e12a1d7.jpg cd0e83983e36613ec5b154d2d6ddb0d1.jpg d6086634ce334fe82400a173f0028306.jpg e7299b9187f09e190127873fb0725e1c.jpg f4f7ec6332cab9c706e12fa8aaed4a6c.jpg ff1778ed14e5ac5be5217d410841750d.jpg 1fa59ad4144c5f668e92b8ab6a0043f8.jpg 3b6365d6ab144b660c0b477442782fa5.jpg 6f93c871d9b1469bec963639ea58fe82.jpg 84c8aadbabbeb753042593faffa4e376.jpg 90d9a803b25a78b4dc2dcdf4c85a4b70.jpg 386f1418e664eab461ea243e85c19d3c.jpg 627fcb8c133d1e30c067d31a92a79f02.jpg 766f0049a40eea217328d2975312d3e0.jpg 8189cbaa92299ea536be3ad23ddf1d00.jpg 0967287cbb2b14ed9dc1ec6a1a53b21d.jpg 093
评论 58
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值