关于深度卷积神经网络训练过程中一开始准确率就是1的问题

最近在利用DCNN模型训练自己的数据集,利用SS数据集进行测试,做二分类,结果刚开始训练模型的准确率就为1,后面也是这样,主要原因还是数据集打乱的还不够,不能只靠tensorflow的shuffle操作来打乱,最好先打乱顺序后制作好tfrecords文件,再用shuffle函数打乱一次。
主要步骤如下:
(1)找到SS标签文件
(2)制作TFRecords文件
(3)开始训练

关于制作TFRecords文件:

制作TFrecords文件代码如下:

import tensorflow as tf
# 7,8 -- 9,10 -- 11,12
from PIL import Image
import csv
import random

number_pic = 50000  # 空与非空的数量,保存相等

with open('/media/sj/Elements/S5_event_train.csv', 'r') as r:
    next(r)
    reader = csv.reader(r)
    images_list_null = []
    images_list_full = []

    writer = tf.python_io.TFRecordWriter('./train_SS_50.tfrecords')
    for row in reader:
        if row[8] == 'NA':
            images_list_null.append([row[7], 0])
        else:
            if row[8] != '':
                images_list_full.append([row[7], 1])

            else:
                print("skip null_8")

        if row[10] == 'NA':
            images_list_null.append([row[9], 0])

        else:
            if row[10] != '':
                images_list_full.append([row[9], 1])
            else:
                print("skip null_10")

        if row[12] == 'NA':
            images_list_null.append([row[11], 0])
        else:
            if row[12] != '':
                images_list_full.append([row[11], 1])
            else:
                print('skip null_12')
    print(len(images_list_null), len(images_list_full))

    good_null = []
    good_full = []
    # 将好的写入到列表
    for null in images_list_null:
        try:
            img = Image.open(null[0], "r")
            good_null.append(null)
        except:
            pass
    for full in images_list_full:
        try:
            img = Image.open(full[0], "r")
            good_full.append(full)
        except:
            pass
    print(len(good_null), len(good_full))
    filename = good_null[:number_pic] + good_full[:number_pic]
    random.shuffle(filename)
    m = 0
    j = 0
    if m < 6:
        for file in filename:
            if m == 1:
                img = file[0].transpose(Image.ROTATE_90)  # 旋转
                img = Image.open(img, "r")

            elif m == 2:
                img = file[0].transpose(Image.ROTATE_180)  # 旋转
                img = Image.open(img, "r")
            elif m == 3:
                img = file[0].transpose(Image.ROTATE_270)  # 旋转
                img = Image.open(img, "r")
            elif m == 4:
                img = file[0].transpose(Image.FLIP_TOP_BOTTOM)
                img = Image.open(img, "r")
            elif m == 5:
                img = file[0].transpose(Image.FLIP_LEFT_RIGHT)
                img = Image.open(img, "r")
            else:
                img = Image.open(file[0], "r")

            label = file[1]
            with open('./SS_50.csv', 'a+') as f:
                f_csv = csv.writer(f)
                f_csv.writerow([file[0],label])
            img_raw = img.tobytes()
            example = tf.train.Example(
                features=tf.train.Features(feature={
    
    
                    'path': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])),
                    'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[label])),

                }))
            writer.write(example.SerializeToString())  # 序列化为二进制格式

            if j == number_pic * 2:
                break
            j += 1

            print(j, m)

        m += 1

    print("successful")
    writer.close()

代码关键部分解释:

上面是从SS数据集里面的S5制作一个包含10万张照片的tfrecords文件,其中空照片5万,非空5万。制作平衡数据集。
(1)第一步先遍历csv文件读取相应的图片路径和标签名称,空标记为0,非空标记为1.

    for row in reader:
        if row[8] == 'NA':
            images_list_null.append([row[7], 0])
        else:
            if row[8] != '':
                images_list_full.append([row[7], 1])

            else:
                print("skip null_8")

        if row[10] == 'NA':
            images_list_null.append([row[9], 0])

        else:
            if row[10] != '':
                images_list_full.append([row[9], 1])
            else:
                print("skip null_10")

        if row[12] == 'NA':
            images_list_null.append([row[11], 0])
        else:
            if row[12] != '':
                images_list_full.append([row[11], 1])
            else:
                print('skip null_12')
    print(len(images_list_null), len(images_list_full))

(2)读取完成后,两个列表下面存在一损坏或者不存在的图片路径,需要检查并且从列表中删除,利用Image.open检查图片是否存在或者损坏,代码如下:

good_null = []
    good_full = []
    # 将好的写入到列表
    for null in images_list_null:
        try:
            img = Image.open(null[0], "r")
            good_null.append(null)
        except:
            pass
    for full in images_list_full:
        try:
            img = Image.open(full[0], "r")
            good_full.append(full)
        except:
            pass
    print(len(good_null), len(good_full))

(3)为了构建平衡数据集,可以通过列表截取的方式各取number_pic万张,最后合并并使用随机函数打乱顺序。

filename = good_null[:number_pic] + good_full[:number_pic]
    random.shuffle(filename)

(4)开始制作和写入tfrecords文件,如果数据不够,可以通过旋转,翻转等操作进行操作再写入。这里介绍几种方式。

m = 0
    j = 0
    if m < 6:
        for file in filename:
            if m == 1:
                img = file[0].transpose(Image.ROTATE_90)  # 逆时针旋转90
                img = Image.open(img, "r")

            elif m == 2:
                img = file[0].transpose(Image.ROTATE_180)  # 旋转180
                img = Image.open(img, "r")
            elif m == 3:
                img = file[0].transpose(Image.ROTATE_270)  # 旋转270
                img = Image.open(img, "r")
            elif m == 4:
                img = file[0].transpose(Image.FLIP_TOP_BOTTOM)#上下翻转
                img = Image.open(img, "r")
            elif m == 5:
                img = file[0].transpose(Image.FLIP_LEFT_RIGHT)#水平翻转
                img = Image.open(img, "r")
            else:
                img = Image.open(file[0], "r")

            label = file[1]
            with open('./SS_50.csv', 'a+') as f:
                f_csv = csv.writer(f)
                f_csv.writerow([file[0],label])
            img_raw = img.tobytes()
            example = tf.train.Example(
                features=tf.train.Features(feature={
    
    
                    'path': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])),
                    'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[label])),

                }))
            writer.write(example.SerializeToString())  # 序列化为二进制格式

            if j == number_pic * 2:
                break
            j += 1

            print(j, m)

        m += 1

(5)在进行训练时,每读取一个batch_size,就利用shuffle打乱一次。
(6)开始训练,我的训练结果如下:
在这里插入图片描述

注释:

关于数据集的制作和打乱的顺序,我也尝试过先写第一类,再写第二类,这样交替的写入数据集,但是也存在相同的问题,可能在前几轮下不会出现这样的问题,但是后面还是会出现,我怀疑是这样的数据分布的太有规律,所以最后迫不得已,先随机打乱再写入。这样的处理目前实验结果来看是最好的。缺点就是需要遍历csv文件,循环比较多,处理的有点慢,欢迎各位多加改进。

猜你喜欢

转载自blog.csdn.net/llsplsp/article/details/109059616