首页 AI Studio教育版 帖子详情
百度飞桨领航团图像分类学习笔记
收藏
快速回复
AI Studio教育版 文章课程答疑 601 1
百度飞桨领航团图像分类学习笔记
收藏
快速回复
AI Studio教育版 文章课程答疑 601 1

课程链接:https://aistudio.baidu.com/aistudio/course/introduce/11939?directly=1&shared=1

1.python 的call()方法
Python call()方法, Python 类中一个非常特殊的实例方法,即 call()。该方法的功能类似于在类中重载 () 运算符,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用。
class Worker:
  # 定义__call__方法
  def __call__(self, name, add):
      print("调用__call__()方法", name, add)


work = Worker()
work("PaddlePaddler", "http://aistudio.baidu.com")

2.图像基础知识
RGB
RBG
GRB
GBR
BGR
BRG
3.图片格式
3.1BMP格式
bmp格式没有压缩像素格式,存储在文件中时先有文件头、再图像头、后面就都是像素数据了,上下颠倒存储。 用windows自带的mspaint工具保存bmp格式时,可以发现有四种bmp可供选择:
单色: 一个像素只占一位,要么是0,要么是1,所以只能存储黑白信息
16色位图: 一个像素4位,有16种颜色可选
256色位图: 一个像素8位,有256种颜色可选
24位位图: 就是图(1)所示的位图,颜色可有2^24种可选,对于人眼来说完全足够了。

简单起见,只详细讨论最常见的24位图的bmp格式。
3.2JPEG格式
jpeg是有损压缩格式, 将像素信息用jpeg保存成文件再读取出来,其中某些像素值会有少许变化。在保存时有个质量参数可在[0,100]之间选择,参数越大图片就越保真,但图片的体积也就越大。一般情况下选择70或80就足够了。
jpeg没有透明信息。
jpeg比较适合用来存储相机拍出来的照片,这类图像用jpeg压缩后的体积比较小。其使用的具体算法核心是离散余弦变换、Huffman编码、算术编码等技术,有兴趣的同学可以在网上找一大堆资料,本文就不详细介绍了。
3.3PNG格式
png是一种无损压缩格式, 压缩大概是用行程编码算法。
png可以有透明效果。
png比较适合适量图,几何图。 比如本文中出现的这些图都是用png保存,比用joeg保存体积要小。
3.4GIF格式
上面提到的bmp,jpeg,png图片都只有一帧,而gif可以保存多帧图像,如图所示
3.4WebP编码
Webp是一种高效的图像编码方式,由谷歌推出,开源免费。其图像压缩效率相比jpg可以提升一倍性能。一般保存需要设置压缩因子。
4.常用库
4.1Numpy
Numpy对多维矩阵A的操作一般有:

A.shape #HWC

type(A) #numpy.array

A.dtype() #uint8,
float…

np.min(A), np.max(A) #最值
4.2 CV2
读取BGR,通道HWC,范围[0,255] ,类型uint8; 图像类型numpy.ndarray;
4.3 PIL,Pillow, Pillow-SIMD
读取RGB,通道HWC,范围[0,255],类型uint8;图像类型PngImageFile (np.array, Image.fromarray直接与numpy互相转换) 有.mode方法---rgb信息
4.4 Matplotlib
读取RGB,通道HWC,范围[0,1] ,类型float;图像类型numpy.ndarray
4.5Skimage
读取RGB,通道HWC,范围[0,255],类型uint8;图像类型numpy.ndarray 有.mode方法---rgb信息

 
5 用CV2进行数据增强方法
5.1缩放图片
缩放就是调整图片的大小,使用cv2.resize()函数实现缩放。可以按照比例缩放,也可以按照指定的大小缩放: 我们也可以指定缩放方法interpolation,更专业点叫插值方法,默认是INTER_LINEAR,全部可以参考:InterpolationFlags

缩放过程中有五种插值方式:

cv2.INTER_NEAREST 最近邻插值
cv2.INTER_LINEAR 线性插值
cv2.INTER_AREA 基于局部像素的重采样,区域插值
cv2.INTER_CUBIC 基于邻域4x4像素的三次插值
cv2.INTER_LANCZOS4 基于8x8像素邻域的Lanczos插值
In [57]


img = cv2.imread('cat.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 按照指定的宽度、高度缩放图片
res = cv2.resize(img, (400, 500))
# 按照比例缩放,如x,y轴均放大一倍
res2 = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR)
plt.imshow(res)
5.2平移图片

平移是用仿射变换函数cv2.warpAffine()实现的:

 


# 平移图片
import numpy as np
# 获得图片的高、宽
rows, cols = img.shape[:2]


# 定义平移矩阵,需要是numpy的float32类型
# x轴平移200,y轴平移500
M = np.float32([[1, 0, 100], [0, 1, 500]])
# 用仿射变换实现平移
dst = cv2.warpAffine(img, M, (cols, rows))
5.3 翻转图片
镜像翻转图片,可以用cv2.flip()函数: 其中,参数2 = 0:垂直翻转(沿x轴),参数2 > 0: 水平翻转(沿y轴),参数2 < 0: 水平垂直翻转。

 


dst = cv2.flip(img, -1)
plt.imshow(dst)

6.数据处理部分
6.1 label shuffling
 首先对原始的图像列表,按照标签顺序进行排序; 然后计算每个类别的样本数量,并得到样本最多的那个类别的样本数。 根据这个最多的样本数,对每类都产生一个随机排列的列表; 然后用每个类别的列表中的数对各自类别的样本数求余,得到一个索引值,从该类的图像中提取图像,生成该类的图像随机列表; 然后把所有类别的随机列表连在一起,做个Random Shuffling,得到最后的图像列表,用这个列表进行训练。

def labelShuffling(dataFrame, groupByName = 'class_num'):
    groupDataFrame = dataFrame.groupby(by=[groupByName])
    labels = groupDataFrame.size()
    print("length of label is ", len(labels))
    maxNum = max(labels)
    lst = pd.DataFrame()
    for i in range(len(labels)):
        print("Processing label  :", i)
        tmpGroupBy = groupDataFrame.get_group(i)
        createdShuffleLabels = np.random.permutation(np.array(range(maxNum))) % labels[i]
        print("Num of the label is : ", labels[i])
        lst=lst.append(tmpGroupBy.iloc[createdShuffleLabels], ignore_index=True)
        print("Done")
    # lst.to_csv('test1.csv', index=False)
    return lst

 

6.2 构建Dataset

class MyDataset(paddle.io.Dataset):

    """

    步骤一:继承paddle.io.Dataset类

    """

    def init(self, train_img_list, val_img_list,train_label_list,val_label_list, mode='train'):

        """

        步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集

        """

        super(MyDataset, self).init()

        self.img = []

        self.label = []

        # 借助pandas读csv的库

        self.train_images = train_img_list

        self.test_images = val_img_list

        self.train_label = train_label_list

        self.test_label = val_label_list

        if mode == 'train':

            # 读train_images的数据

            for img,la in zip(self.train_images, self.train_label):

                self.img.append('data/data71799/lemon_lesson/train_images/'+img)

                self.label.append(la)

        else:

            # 读test_images的数据

            for img,la in zip(self.train_images, self.train_label):

                self.img.append('data/data71799/lemon_lesson/train_images/'+img)

                self.label.append(la)


def load_img(self, image_path):
    # 实际使用时使用Pillow相关库进行图片读取即可,这里我们对数据先做个模拟
    image = Image.open(image_path).convert('RGB')
    return image

def __getitem__(self, index):
    """
    步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签)
    """
    image = self.load_img(self.img[index])
    label = self.label[index]
    # label = paddle.to_tensor(label)
    
    return data_transforms(image), paddle.nn.functional.label_smooth(label)

def __len__(self):
    """
    步骤四:实现__len__方法,返回数据集总数目
    """
    return len(self.img)



6.3 标签平滑(LSR)
  在分类问题中,一般最后一层是全连接层,然后对应one-hot编码,这种编码方式和通过降低交叉熵损失来调整参数的方式结合起来,会有一些问题。这种方式鼓励模型对不同类别的输出分数差异非常大,或者说模型过分相信他的判断,但是由于人工标注信息可能会出现一些错误。模型对标签的过分相信会导致过拟合。 标签平滑可以有效解决该问题,它的具体思想是降低我们对于标签的信任,例如我们可以将损失的目标值从1稍微降到0.9,或者将从0稍微升到0.1。总的来说,标签平滑是一种通过在标签y中加入噪声,实现对模型约束,降低模型过拟合程度的一种正则化方法。

 

0
收藏
回复
全部评论(1)
时间顺序
学习委员
#2 回复于2021-03

0
回复
在@后输入用户全名并按空格结束,可艾特全站任一用户