Python中完成数据读取操作,比较常用的是Pillow和OpenCV、。注意:Image.open()读取的通道顺序是RGB,cv2.imread()读取的通道顺序为BGR。
from PIL import Image
# 读取图片
im =Image.open('lena.jpg’)
# 应用模糊滤镜:
im2 = im.filter(ImageFilter.BLUR)
#缩放原图
im.thumbnail((w//2, h//2))
im.save('thumbnail.jpg', 'jpeg')
from PIL.ImageFilter import BLUR,GaussianBlur #模糊滤波
这里提到模糊滤波是为后期的模型优化做准备,阿水的第一期分享中提到模糊优化,大概是因为OCR识别等图像识别中在图像特征提取之前经常通过smooth/blur来使图像噪声降低、在二值化之前通过smooth/blur把不必要的噪声去掉,以免影响对准确的对象的提取。
OpenCV在功能上比Pillow更加强大。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('lena.jpg',0)
edges = cv2.Canny(img, 100, 200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
这个说法并不准确,batch样本是为了训练模型,实际还是基于单体图像读取(这里使用PIL),封装成一个torch.utils.data.dataset的子类,然后将其传入torch.utils.data.DataLoader来创建一个读取小批量数据样本的DataLoader实例,完成batch样本提取。
import torch,glob
from PIL import Image
'''第一步 生成数据集'''
class SVHNDataset(torch.utils.data.dataset.Dataset):
def __init__(self,img_path,img_label,transform=None):
'''
Args:
img_path 单个图像路径
img_label 单个图像标签
transform 为图像增广做准备
'''
self.img_path = img_path
self.img_label = img_label
if transform is not None:
self.transform = transform
else:
self.transform = None
def __getitem__(self, index):
'''
Args:
index 图像序号
output:
img 单一图像特征序列
torch.from_numpy(np.array(lbl[:5])) 单一图像的定长字符标签
'''
# 读取图片并转换为RGB格式
img = Image.open(self.img_path[index]).convert('RGB')
if self.transform is not None:
img = self.transform(img)
# 将不定长的变迁转换成设置长度为5的定长字符串
lbl = np.array(self.img_label[index], dtype=np.int)
lbl = list(lbl) + (5 - len(lbl)) * [10]
return img, torch.from_numpy(np.array(lbl[:5]))
def __len__(self):
return len(self.img_path)
train_path = glob.glob('../input/train/*.png') #提取所有训练集png文件路径
train_path.sort() #路径排序
train_json = json.load(open('../input/train.json')) #读取训练集标签及边界框信息
train_label = [train_json[x]['label'] for x in train_json] #生成训练集标签
print(len(train_path), len(train_label))
dataset = SVHNDataset(train_path, train_label,transform=None) #定义训练数据集。
'''!!!这里transform=None应该会出错【待确认】,至少需要指定参数 transform = transforms.ToTensor() 使所有数据转换为 Tensor ,如果不进行转换则返回的是PIL图片。 transforms.ToTensor() 将尺寸为 (H x W x C) 且数据位于[0, 255]的PIL 图片或者数据类型为 np.uint8 的 NumPy 数组转换为尺寸为 (C x H x W) 且数据类型为 torch.float32 且位于[0.0, 1.0]的 Tensor 。'''
'''第二步 读取小批量'''
batch_size=40 #小批量样本量
shuffle=True #样本的读取顺序是随机的
train_loader = torch.utils.data.DataLoader(
dataset,
batch_size=batch_size,
shuffle=shuffle,
num_workers=0)
for i, (inputs, targets) in enumerate(train_loader):
print(inputs,targets) #inputs是随机读取的长度为batch_size的Tensor,其中每一个分别为各个图像的尺寸为 (C x H x W) 且数据类型为 torch.float32 且位于[0.0, 1.0]的 Tensor。
#targetss是对应的40个标签。
break
数据扩增(Data Augmentation)操作的目的是为了增加训练集的数量,缓解过拟合。
大规模数据集是成功应用深度神经网络的前提。图像增 广(image augmentation)技术通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模。图像增广的另一种解释是,随机改变训练样本可以降低模型对某些属性的依赖,从而提高模型的泛化能力。例如,我们可以对图像进行不同方式的裁剪,使感兴趣的物体出现在不同位置,从而减轻模型对物体出现位置的依赖性。我们也可以调整亮度、色彩等因素来降低模型对色彩的敏感度。可以说,在当年AlexNet的成功中,图像增⼴技术功不可没。
——《动手学深度学习》李沐
目前Baseline里用到transfrom的顺序依次是Resize、RandomCrop、ColorJitter、RandomRotation、ToTensor、Normalize。
这里存在一些问题,比如
transform类型 | 训练集 | 验证集 | 测试集 |
---|---|---|---|
Resize(size=(h, w)) | (64, 128) | (60, 120) | (64, 128) |
RandomCrop(size=(h, w)) | × | × | (60, 120) |
ColorJitter(brightness,contrast,saturation) | (0.3, 0.3, 0.2) | × | × |
RandomRotation(degrees) | 5 | × | × |
ToTensor() | √ | √ | √ |
Normalize(mean,std) | [0.485, 0.456, 0.406], [0.229, 0.224, 0.225] | [0.485, 0.456, 0.406], [0.229, 0.224, 0.225] | [0.485, 0.456, 0.406], [0.229, 0.224, 0.225] |
import torchvision.transforms as transforms
train_trans = transforms.Compose([
transforms.Resize((64, 128)),
transforms.ColorJitter(0.3, 0.3, 0.2),
transforms.RandomRotation(5),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
val_trans = transforms.Compose([
transforms.Resize((60, 120)),
# transforms.ColorJitter(0.3, 0.3, 0.2),
# transforms.RandomRotation(5),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
test_trans = transforms.Compose([
transforms.Resize((64, 128)),
transforms.RandomCrop((60, 120)),
# transforms.ColorJitter(0.3, 0.3, 0.2),
# transforms.RandomRotation(5),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
学到知识心里高兴。
动手学深度学习 PYTORCH 版(DEMO)
链接已各处贴上。
Have fun~
2020.5.23