学习TensrFlow 2 的随笔(不定时更新,互相学习)

利用已有图片创建TFRecords

建立不同的文件夹,包括train/test。各个文件夹再包含不同的类文件夹。

import os 
import tensorflow as tf 
from PIL import Image  
import matplotlib.pyplot as plt 
import numpy as np
 
#cwd='F:/TFdata/test'
cwd='F:/TFdata/train'
classes=['Steelframe','RCframeshearwall','RCframe','Woodstructure','Brickandconcrete','Masonrystructure']#咱们设定6类
writer= tf.io.TFRecordWriter("my_buildings_train.tfrecords") #要生成的文件
#writer= tf.io.TFRecordWriter("my_buildings_test.tfrecords") #要生成的文件

for index,name in enumerate(classes):
    class_path=cwd+'/'+name+'/'
    for img_name in os.listdir(class_path): 
        img_path=class_path+img_name #每一个图片的地址
        
        img=Image.open(img_path)
        img= img.resize((224,224))
        img=img.convert("RGB")#保证图像是3通道的
        #print(np.shape(img))
        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数据进行封装
        writer.write(example.SerializeToString())  #序列化为字符串
writer.close()

注意:分类时从0开始,否者会出现loss-nan。在图片处理中要进行RGB三通道规范化处理,防止出现多维不匹配。

读取TFRecord

import numpy as np
import tensorflow as tf
from tensorflow import keras
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
keras.backend.clear_session()
np.random.seed(25)
tf.random.set_seed(25)
feature_description={
    "label":tf.io.FixedLenFeature([],tf.int64),
    "img_raw":tf.io.FixedLenFeature([],tf.string),
    }
batch_size=8
dataset_train = tf.data.TFRecordDataset(["my_buildings_train.tfrecords"])
dataset_test = tf.data.TFRecordDataset(["my_buildings_test.tfrecords"])
def parse_examples (serialized_examples):
    s_example=tf.io.parse_example(serialized_examples, feature_description)
    img = tf.io.decode_raw(s_example['img_raw'],tf.uint8)/255
    img = tf.reshape(img, [224, 224, 3])
    label=tf.cast(s_example['label'], tf.int32)
    return img,label
parsed_train=dataset_train.shuffle(5000).map(parse_examples).batch(batch_size).prefetch(1)
parsed_test=dataset_test.shuffle(5000).map(parse_examples).batch(batch_size).prefetch(1)

注意:读取过程中重点是要搞清楚解译函数,就是tf.io.parse_example.函数最后的结果是一个2维的张量数组。然后对包含图片数据的‘img_raw’进行解译,得到图像数据。对‘label’解译得到标签。
打乱,映射,批次,预取一气呵成!!!

loss, accuracy, val_loss, val_accuracy的含义

loss:训练集损失值

accuracy:训练集准确率

val_loss:测试集损失值

val_accruacy:测试集准确率

以下5种情况可供参考:
train loss 不断下降,test loss不断下降,说明网络仍在学习;(最好的)
train loss 不断下降,test loss趋于不变,说明网络过拟合;(max pool或者正则化)
train loss 趋于不变,test loss不断下降,说明数据集100%有问题;(检查dataset)
train loss 趋于不变,test loss趋于不变,说明学习遇到瓶颈,需要减小学习率或批量数目;(减少学习率)
train loss 不断上升,test loss不断上升,说明网络结构设计不当,训练超参数设置不当,数据集经过清洗等问题。(最不好的情况)

转载于TensorFlow中loss与val_loss、accuracy和val_accuracy分别是什么含义

loss不变的原因分析

  • 数据本身的问题:可以尝试使用其他的数据处理方法,例如归一化(增加keras归一化标准层)或者正则化(避免过拟合dropout)。
  • 初始化权重问题:TF一般采用随机权重赋值,一般都很小接近于0,而且不同的随机种子效果不同(道听,亲测不管用)可以使用He初始化。
  • 学习率过大:设置的太高,训练就容易发散。一开始高会计算很快,但不会稳定,会在最优解震荡(使用学习率调度来动态的更新学习率)。
  • 非饱和激活函数:对于模型中的激活函数是饱和类型函数的情况,可能会造成激活函数饱和而梯度为0,继而模型无法进行参数更新(可以使用leaky ReLU, ELU, SELU来代替ReLU)。
  • 自身数据分配问题:每个分类的样本不同导致val_accuracy基本不变。

根据结果来调整模型(欠,过拟合)

过拟合情况的判断

  • 过拟合
    如果模型在训练数据集上的预测结果很好,但在测试数据集上的表现却并不理想,或者说两者有较大差距,那么我们有理由怀疑模型发生了过拟合现象。
  • 欠拟合
    如果模型不仅在训练数据集上的预测结果不好,而且在测试数据集上的表现也不理想,也就是说两者的表现都很糟糕,那么我们有理由怀疑模型发生了欠拟合现象。
  • 经验总结
    总的来说,就是观察loss, accuracy, val_loss, val_accuracy的大小。
    如果loss大,accuracy也比较小,说明是欠拟合,数据量少。增加数据量或者进行数据增强。
    如果loss小,accuracy大,但val_loss和val_accuracy要更好说明有可能过拟合。

欠拟合和过拟合的解决方法

  • 欠拟合
    1,增加原始数据(客观限制,比较难)。进行数据增强(移动,裁剪,旋转,缩放,水平翻转或者垂直翻转,或者其他转换函数)。
    2,采用迁移学习,解决数据不足问题

你可能感兴趣的:(TensorFlow学习总结,python,图像处理,深度学习)